This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Accessing the entire RAM space on an AM335x based BeagleBone Black

I am writing a baremetal program that needs to control the entirety of the device's RAM. I started with the MMU code given in demoMain.c, copied that into my program, and I am using GCC to compile.

My current goal: Memset the entire region of memory to ensure that it is at a starting value that I choose, or to erase data that was stored there previously.

The problem is that I can only seem to access in the range of 0x80000000 through roughly 0x87FFFFFF. If I access outside of this range, my firmware goes to an abort handler. Anyone have any idea as to how I can address the full memory space for the chip?

The code I am using to set up the MMU is:

/* Definitions related to MMU Configuration. */
#define START_ADDR_DDR                  (0x80000000u)
#define START_ADDR_DEV                  (0x44000000u)
#define START_ADDR_OCMC                 (0x40300000u)
#define NUM_SECTIONS_DDR                (512u)
#define NUM_SECTIONS_DEV                (960u)
#define NUM_SECTIONS_OCMC               (1u)

#ifdef __TMS470__
#pragma DATA_ALIGN(PageTable, MMU_PAGETABLE_ALIGN_SIZE);
static volatile unsigned int PageTable[MMU_PAGETABLE_NUM_ENTRY];

#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=MMU_PAGETABLE_ALIGN_SIZE
static volatile unsigned int PageTable[MMU_PAGETABLE_NUM_ENTRY];

#elif defined(gcc)
static volatile unsigned int PageTable[MMU_PAGETABLE_NUM_ENTRY]
 __attribute__((aligned(MMU_PAGETABLE_ALIGN_SIZE)));

#else
#error "Unsupported Compiler.\r\n"

#endif


void _MMUConfigAndEnable(void)
{
    /*
    ** Define DDR memory region of AM335x. DDR can be configured as Normal
    ** memory with R/W access in user/privileged modes. The cache attributes
    ** specified here are,
    ** Inner - Write through, No Write Allocate
    ** Outer - Write Back, Write Allocate
    */
    REGION regionDdr = {
                        MMU_PGTYPE_SECTION, START_ADDR_DDR, NUM_SECTIONS_DDR,
                        MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                         MMU_CACHE_WB_WA),
                        MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                        (unsigned int*)PageTable
                       };
    /*
    ** Define OCMC RAM region of AM335x. Same Attributes of DDR region given.
    */
    REGION regionOcmc = {
                         MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,
                         MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                          MMU_CACHE_WB_WA),
                         MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                         (unsigned int*)PageTable
                        };

    /*
    ** Define Device Memory Region. The region between OCMC and DDR is
    ** configured as device memory, with R/W access in user/privileged modes.
    ** Also, the region is marked 'Execute Never'.
    */
    REGION regionDev = {
                        MMU_PGTYPE_SECTION, START_ADDR_DEV, NUM_SECTIONS_DEV,
                        MMU_MEMTYPE_DEVICE_SHAREABLE,
                        MMU_REGION_NON_SECURE,
                        MMU_AP_PRV_RW_USR_RW  | MMU_SECTION_EXEC_NEVER,
                        (unsigned int*)PageTable
                       };
                           // Define ROM region of AM335x. Same Attributes of DDR region given.
    REGION regionRom = {
                         MMU_PGTYPE_SECTION, START_ADDR_ROM, NUM_SECTIONS_ROM,
                         MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                          MMU_CACHE_WB_WA),
                         MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                         (unsigned int*)PageTable
                        };

    /* Initialize the page table and MMU */
    MMUInit((unsigned int*)PageTable);

    /* Map the defined regions */
    MMUMemRegionMap(&regionDdr);
    MMUMemRegionMap(&regionOcmc);
    MMUMemRegionMap(&regionDev);
	MMUMemRegionMap(&regionRom);
    /* Now Safe to enable MMU */
    MMUEnable((unsigned int*)PageTable);
}

For memset, I do something like.. 

PROGRAM_OFFSET = START_ADDR_DDR + 0x9000;

memset(PROGRAM_OFFSET, 0x0, 0x9E848000- 0x10000); // leave enough space in there for our program

The idea here is to set almost all of the rest of RAM, my understanding is that 0x9E848000 is the end of the memory addressable range (though verification of that would be helpful).

Thanks

  • I dug around more in the starterware code. In mmu.c there is a comment that says:

     *            Example Configuration: \n
     *              A 512MB RAM memory region starting at address 0x80000000 can be
     *              configured as shown below. The memory is to be cacheable, with
     *              Inner Cache - Write Through Write Allocate and Outer Cache -
     *              Write Back Write Allocate attributes. \n 
     *
     *              REGION regionRam = { MMU_PGTYPE_SECTION, \n
     *                                   0x80000000, \n
     *                                   512,  \n
     *                                   MMU_MEMTYPE_NORMAL_SHAREABLE 
     *                                     (MMU_CACHE_WT_NOWA, MMU_CACHE_WB_WA),\n
     *                                   MMU_REGION_NON_SECURE, \n
     *                                   MMU_AP_PRV_RW_USR_RW, \n
     *                                   (unsigned int*)pageTable};

    I changed my code to this, which appears to have fixed the issue. The main difference appears to be setting the memtype to shareable vs non-shareable.

    Does anyone have any insight into why this makes such a large difference here?

    Thanks