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.

TMDXIDK437X: Peripheral address in MMU

Part Number: TMDXIDK437X

Hello.

I apologize for repeated questions, I have already raised a similar topic here.

https://e2e.ti.com/support/processors/f/791/t/881329

Unfortunately for me the question has not been completely closed. I read the documents that Frank advised me. Understanding how MMU works has become better but not quite.

I could not answer the question for myself on what principle the addresses of peripheral modules are assigned. In different examples, it looks different.

For example, let take UART_BasicExample_idkAM437x_armExampleProject. In cfg file we see:

/* ================ Cache and MMU configuration ================ */

var Cache = xdc.useModule('ti.sysbios.family.arm.a9.Cache');
Cache.enableCache = true;
Cache.configureL2Sram = false;//DDR build

var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
Mmu.enableMMU = true;


/* Force peripheral section to be NON cacheable strongly-ordered memory */
var peripheralAttrs = {
type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
tex: 0,
bufferable : false, // bufferable
cacheable : false, // cacheable
shareable : false, // shareable
noexecute : true, // not executable
};

/* Define the base address of the 1 Meg page the peripheral resides in. */
var peripheralBaseAddr = 0x44DF2800;          <------------------------------------------------- CM_WKUP 0x44DF_2800 0x44DF_3FFF Clock Module Wakeup Registers from Table 2-2. L4_WKUP Memory Map

/* Configure the corresponding MMU page descriptor accordingly */
Mmu.setFirstLevelDescMeta(peripheralBaseAddr,
peripheralBaseAddr,
peripheralAttrs);

Now for an example let take NIMU_ICSS_BasicExample_idkAM437x_wSoCLib_armExampleproject, and in cfg file we see:


var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
Mmu.enableMMU = true;
/* Force peripheral section to be NON cacheable sssh://git@bitbucket.itg.ti.com/processor-sdk/processor-pdk-packages.gittrongly-ordered memory */
var peripheralAttrs = {
type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
tex: 0,
bufferable : false, // bufferable
cacheable : false, // cacheable
shareable : false, // shareable
noexecute : true, // not executable
};

/* Define the base address of the 1 Meg page the peripheral resides in. */
var peripheralBaseAddr = 0x40300000;    <-------------------------------  OCMCRAM 0x4030_0000 0x4033_FFFF 256KB 32-bit Ex/R/W [2] – L3 OCMC SRAM Table 2-1. L3 Memory Map

/* Configure the corresponding MMU page descriptor accordingly */
Mmu.setFirstLevelDescMeta(peripheralBaseAddr,
peripheralBaseAddr,
peripheralAttrs);

/* Define the base address of the 1 Meg page the peripheral resides in. */
var peripheralBaseAddr = 0x44D00000;    <------------------------------- Reserved 0x44D0_0000 0x44D0_3FFF 16KB  Table 2-2. L4_WKUP Memory Map

/* Configure the corresponding MMU page descriptor accordingly */
Mmu.setFirstLevelDescMeta(peripheralBaseAddr,
peripheralBaseAddr,
peripheralAttrs);


/* Define the base address of the 1 Meg page the peripheral resides in. */
var peripheralBaseAddr = 0x54400000;    <------------------------------ PRU_ICSS1 0x5440_0000 0x547F_FFFF 4MB PRU-ICSS1 Instruction/Data/Control Space [4] Table 2-1. L3 Memory Map (continued)

/* Configure the corresponding MMU page descriptor accordingly */
Mmu.setFirstLevelDescMeta(peripheralBaseAddr,
peripheralBaseAddr,
peripheralAttrs);

By what principle are values ​​assigned to a variable  peripheralBaseAddr? Why in some examples there are three, in some one? And why in example UART_BasicExample_idkAM437x var peripheralBaseAddr = 0x44DF2800? If I write var peripheralBaseAddr = 0x44DF0000 (PRCM 0x44DF_0000 0x44DF_FFFF 64KB Module Table 2-2. L4_WKUP Memory Map), the example work too.

What should be guided when it is necessary to assign an address?

  • Hi Kiselev,

    Let me review these examples and get back with you.

    Regards,
    Frank

  • Hi Kiselev,

    I was able to take a look at these examples. Thanks for your patience.

    >> And why in example UART_BasicExample_idkAM437x var peripheralBaseAddr = 0x44DF2800?

    0x44DF2800 is the base address of CM_WKUP. CM_WKUP, which contains PRCM_CM_WKUP_UART0_CLKCTRL. This register is written by Board_init() to enable the UART clocks. The intent of the MMU configuration is to configure the peripheral registers in CM_WKUP as cacheable, strongly-ordered memory (vs. normal, cacheable memory) for proper operation. Note the memory region could also be configured as Device memory, and the application should still behave correctly. Please see: 

    • ARM Cortex-A Series v4.0 Programmer's guide (DEN0013D_cortex_a_series_PG.pdf), 9.6.2 Memory types
    • <BIOS>/docs/cdoc/ti/sysbios/family/arm/a8/Mmu.html

    >> If I write var peripheralBaseAddr = 0x44DF0000 (PRCM 0x44DF_0000 0x44DF_FFFF 64KB Module Table 2-2. L4_WKUP Memory Map), the example work too

    When the MMU performs a translation, the top 12 bits of the requested virtual address act as the index into the translation table. The top 12 bits of the virtual addresses 0x44DF0000 & 0x44DF2800 are the same, i.e. 0x44D are the top 12 bits for both virtual addresses. Thus both addresses map to the same 1 MB page in the L1 translation table. See DEN0013D_cortex_a_series_PG.pdf, 9.4 First level address translation.

    Higher resolution virtual to physical address mapping (and memory type, permissions, etc.) could used with L2 translation. If L2 translation is used, the page size is 4 KB vs. 1 MB for L1 translation. In this case a 4 KB page base address and range which includes CM_WKUP would be:

    L1 1MB page: 0x44DF_2000 -> 0x44DF_2FFF, CM_WKUP: 0x44DF_2800 -> ‭0x44DF_2FA7‬

    This would provide more protection against spurious accesses to register outside CM_WKUP, but note PRM_WKUP is still included in this range. The downsides of using higher resolution address translation include:

    • for larger page size, more likely that a TLB hit will occur on any access and so there will be fewer translation table walks to slow external memory
    • each L2 translation table requires 1KB of memory

    Please see:

    • DEN0013D_cortex_a_series_PG.pdf, 9.5 Level 2 translation tables
    • DEN0013D_cortex_a_series_PG.pdf, 9.3 Choice of page sizes
    • <BIOS>/docs/cdoc/ti/sysbios/family/arm/a8/Mmu.html

    >> Why in some examples there are three, in some one?

    NIMU_ICSS_BasicExample_idkAM437x_wSoCLib_armExampleproject requires three L1 translation table entries (1 MB pages) for the registers and memory used by the application. The MMU will generate exceptions without these translation table entries when when CPU attempts R/W access to addresses in these pages.

    The L1 translation table entry at base addres 0x40300000 is for OCMCRAM (On-Chip L3 RAM). It's not clear to me why this is being configured as strongly-ordered memory. Perhaps this application requires this configuration, but typically OCMCRAM should be configured as Normal memory with some cache/sharing policy. Possibly the performance of this example is less than it would if the OCMCRAM was configured at Normal, Cacheable memory.

    >> By what principle are values ​​assigned to a variable  peripheralBaseAddr?
    >> What should be guided when it is necessary to assign an address?

    Addresses should be assigned based on memory & memory-mapped registers used by the application. The addresses are for MMU translation table entries:

    • L1 translation, 20-bit aligned address. Page should contain required registers / memory.
    • L2 translation, 12-bit aligned address. Page should contain required registers / memory.

    Each page must also provide proper configuration for memory access permissions, memory types, and cache/sharing. Please see DEN0013D_cortex_a_series_PG.pdf, Ch 9: The Memory Management Unit.

    Regards,
    Frank

  • Hello, Frank.

    Thank you for the detailed answer. In general, there is more clarity. Practice will show, perhaps there will be more questions.

    Regards,

    Kiselev.