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.

RTOS/PROCESSOR-SDK-AM335X: Bare-metal access and MMU

Part Number: PROCESSOR-SDK-AM335X
Other Parts Discussed in Thread: AMIC110, SYSBIOS

Tool/software: TI-RTOS

Hello,

Can someone explain to me everything about the MMU and bare metal access?

Just kidding.

Can someone point me to some doc? Or some instruction?  I have the 5,000 page AM335x spruh73, as well as the ARM ref manual, various books...  But I am failing on getting bare metal access when using Sys/Bios.  I am using a BBB on CCS 7.2, with and without TI-RTOS

When it tries to access register 44e0 xxxx  it appears to give me a data bus interrupt.

Here's the issue:

Using older StarterWare, there are calls that initialize and enable the GPIO ports.  Specifically, GPIO1. I can see all the code that is run from reset until it gets into "main()", so I can see what is being done "under the covers" prior to attempting to access the GPIO port.  Everything works great. 

When I try to bring that same statement into a Sys/Bios project, it crashes. 

    HWREG(SOC_CM_PER_REGS + CM_PER_GPIO1_CLKCTRL) |=
          CM_PER_GPIO1_CLKCTRL_MODULEMODE_ENABLE;

In both cases, it is the first thing being executed in "main()".  I wrote it there to debug it.

So, clearly and logically, Sys/Bios is doing something (or not doing something) that results in the instruction generating a databus error interrupt (at least, that's that appears to be happening). And it must be doing (or not doing) whatever that is inside the entry point "_c_int00"..   And I can see nothing significant in the StarterWare startup code that could affect have an affect on tghe direct register access.

I have no idea what Sys/Bios is doing under the covers before we even get to "main()" but what ever it is, I'm guessing I have to "undo" it.  And I 'm also guessing it has something to do with the memory management unit (CP15).

So I am asking...  What is a good tutorial/intro to the memory system, the virtual memory, the access controls to memory?  I have already been through a lot of the "ARM Architecture Reference Manual" (from the ARM group) and through a lot of "AM335x and AMIC110 Sitara™ Processors Technical Reference Manual" (SPRUH73).  So either there is a specific chapter I missed and need to study, or there perhaps is additional information somewhere?

I already did a search on TI E2E, and everything I found is 3-6 years old, which means it's useless for the current environment.

-CSW

  • The RTOS team have been notified. They will respond here.
  • And of course, they haven't responded.

    I have continued to dig, and have found the following:

    The Sys/Bios appears to initialize the 4096 MMU table entries with all invalid settings (bits [1:0] = 00) , with the exception of two entries:

    Location     Value
    0x80039008: 0x40201e0e
    0x8003900C: 0x40301e0e

    However, these entries are 1026 entries into the MMU translation table. (Table base = 0x80038000, this entry = 0x80039008) Is that correct?? Does the MMU table have to have entries that are in consecutive 1Meg blocks (since the MMU is configured for 1 meg segments)

    These values, as best as I can decipher, are setting access to segments 0x402 and 0x403 to:

    AP[2] AP[1:0] = 0 1 1 or full access
    Shared, Executable, ...

    However, these are not the locations for GPIO or control registers, They are in segments 0x44E00000, 0x4804C000, etc...

    So, using Sys/Bios, how is one supposed to obtain direct access with the way the MMU is set by default?  (I can get around this databus exception by simply disabling the MMU completely.)

    But why is Sys/Bios initializing the MMU in this way? And why are the segments which give access to the GPIO clocks and ports restricted with no access?

    Where is any of this documented in using Sys/Bios??

    -CSW

  • Hi Christopher,

    I think you will need to add the peripheral to the MMU table when using BIOS.  If you look in the BIOS cdoc for ti/sysbios/family/arm/a8/MMU, there should be an example of how to add a peripheral to the MMU table.  You can add the configuration to your .cfg file.  I hope that helps.

    Best regards,

    Janet

  • No.
    I discovered the peripheral table is there. It's the clock enable table that is not there.

    Nice big gaping hole in the SYS/BIOS architecture...

    (I have solved, it, and have been trying to post for 4 hours. The web site doesn't respond.... )
  • The alternate option, which I tried and also works, is to get the location of the MMU translation table, and add the entry you need in the correct location, then execute the assembler code to reload the table. The function I used is shown below, where I adapted a few Assembler calls from the older StarterWare.

    void MMUConfigure()
    tableBase = CP15GetTableBase() 

    WEBSITE IS CRAPPY ...   I CAN'T POST CODE.  IT HANGS FOREVER...


    Anyone is free to use this, modify it, fix it up... Whatever they need.

    -CSW

  • Well, it took weeks to solve my problem.
    I accomplished it by gathering books, searching ARM websites, reading people's blogs, searching the ARM documentation for the ARMv7 device, and absolutely no help from the TI forum. NONE. ZERO. ZIPPO. ZILCH.

    The problem is that the MMU is being initialize one way in one example, and is NOT being initialized the same in another Sys/Bios example.

    And nothing is explained about why Sys/Bios is doing that. Anywhere.

    I started adding my own assembler code, to pull various settings from the coprocessor, and running the examples in the debugger, so I could find the differences. I also had to try to go "backwards" up teh call stack to see what Sys/Bios was doing during the initialization before "main". I found out.

    Both examples use the short form, 1Meg section MMU translation table. Explanation of the tables can be found in the ARMx7 Architecture Reference Manual (ARM ARM), chapter B3, section 5. It's about 1300 pages into the doc.

    (Note that 4 Gig / 1 Meg per section is 4K sections, so there are 4K entries. Each "section" can be identified by its upper 12 bits, so memory location 0x44E0 00AC is in memory section 0x44E - makes the math rather easy)

    I discovered that not all tables are created equal.

    The first Sys/Bios example, made using the wizard, has the following sections marked accessible:

    0x402, 0x403, 0x480, 0x482

    Although this covers the GPIO registers located in segment 0x480, it does NOT permit access to the clock module peripherals located in section 0x44E.

    Let's reiterate that so it can sink in. The DEFAULT memory access allows the program to write to the GPIO registers, however, it does not allow the program to ENABLE the clock modules of those GPIO registers. In other words, attempting to actually use the GPIO results in a databus fault. Minus several thousand points for poor planning.

    These clock module memory locations are described in the TI doc spruh73, chapter 8, section 12

    The example that does work has additional sections defined as accessible. Specifically,

    0x44e 0x481 0x483 0x490 0x4A1 0x4A3 

    These are clock modules for peripherals (GPIO, serial communications, EDMA, Ethernet, PRU)

    How is the MMU table being set? Even more time spent digging into and reverse engineering what is going on because of no organized descriptions or support... It's done by the XDC tools, controlled by the CFG file, managed by a GUI that offers NO SUPPORT for controlling this information. Even DISABLING the "Add the MMU" on the configuration page doesn't disable the MMU. It seems to turn on the "Enable MMU" whenever it wants.

    Deep down in the guts of the CFG file, where is it not controlled by any part of the XGCONF fancy GUI, are a collection of MMU settings.

    Here is a segment of the Java code that apparently creates the MMU table:

    /* Define the base address of the 1 Meg page the peripheral resides in. */
    var peripheralBaseAddr = 0x44e00000;
    
    /* Configure the corresponding MMU page descriptor accordingly */
    Mmu.setFirstLevelDescMeta(peripheralBaseAddr, peripheralBaseAddr, peripheralAttrs);

    Oh look! There is the GPIO section. Overall, the various bits which are defined in the "ARM ARM" manual are set in the "peripheralAttrs", along with the base address.

    So, in summary, if you need access to memory, you need to hack the CFG file to get it to work right. And probably keep going back to it to be sure it sticks, since it appears to change the settings on its own.