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.

TDA2: Configuring First and Second Level MMU Tables

Part Number: TDA2

Hello,

We're working with the TDA2x and currently using starterware_01_05_xx_xx. We want to configure the two A15 MMUs to manage different sections of DDR with different rules. Our goal is to have both A15 cores run in parallel and use cache for their instructions but not use cache for data. Both A15 cores can access each other's data space and so we want to disable cache for data spaces so that all updates are made directly to DDR. We understand this is achievable through the use of MMU descriptor tables. 

If that's correct then we'd like to configure the MMU to place all instructions into one section of DDR and place all variables in other sections of DDR. We have examples available to us both in the latest PDK and older starterware examples but these examples only cover First-Level descriptor tables. Since these tables span a large range they don't provide the granularity to do what we need. Second-level descriptor tables seem to be what we need but we can't find any examples on how to program them using starterware or PDK functions. Can you provide any examples on how to achieve the following layout assignment for DDR?

0x8000.0000 - 0x85FF.FFFF                     - Instructions 1 for A15_0

0x8600.0000 - 0x86FF.FFFF                     - variable section 1 for A15_0

0x8700.0000 - 0x8AFF.FFFF                     - Instructions 2 for A15_1

0x8B00.0000 - 0x8FFF.FFFF                     - variable section 2 for A15_1

We're primarily working with starterware_01_05_xx_xx package and would prefer examples that use the functions available to that package. Any examples would be greatly appreciated. 

Thank you.

  • Hi,

    A15 has separate I-cache at L1 level (called L1P). L2 is a unified cache and there is L1D cache also.
    So you can enable only Instruction/Program Cache.

    Regards,
    Rishabh
  • Hello Rishabh,

    Thank you for your reply. I'd like to run the software setup by you using the provided starteware_01_05_xx_xx MMU A15 example as a reference.

    In that example it immediately checks if cache is enabled and if not then it first invalidates all L1D and L1I space and then enables all cache types. So we would just need to change this to enable L1I instead? Example below.
    /* In case cache is disabled, invalidate and enable it */
    if (CACHE_A15_TYPE_ALL != cacheEnabled)
    {
    CACHEA15InvalidateL1DAll();
    CACHEA15InvalidateL1IAll();
    CACHEA15Enable(CACHE_A15_TYPE_L1I);
    }


    In software we would then configure and enable MMU just like in the example with the difference being that we will not disable it until power-off. Is the code change above all we need to do to follow your suggestion to ensure the data is not cached and only a15 instruction is cached into L1D? When we ultimately run this example on two A15 cores at same time, what changes if any need to be made to the example software w.r.t cache/mmu? I believe it's just the MAIR Attr Index value should be 0-3 for one A15 core and 4-7 for the second A15 core. Is that correct or are there other field to modify as well? We also modify the example to include mailbox messages to synchronize accessing shared data in DDR between two A15s.

    Can you share the difference between L1I and L2I? I see there's also the option to enable All I-cache (CACHE_A15_TYPE_ALLI) but it groups L1I and L2I. It doesn't look to include any D-cache.

    Thank you.
  • Hello Rishabh,

    We tried the above and only enabled CACHE_A15_TYPE_L1I. When doing that software takes as long to execute as when no cache is enabled. However enabling CACHE_A15_TYPE_ALLI, which per comments includes L1I and L2I, we see software execute as fast as when all I-cache and D-cache is enabled but we also see memory coherency issues. So it seems not just instructions are being cached. 

    Is there anything else then that needs to be done when enabling I-cache only?

    Thank you.

  • Hi,

    The statement "I believe it's just the MAIR Attr Index value should be 0-3 for one A15 core and 4-7 for the second A15 core" is not true.
    You don't need to do anything to L1D or L2 cache.
    I would suggest you to go through ARM documentation to understand A15 cache architecture.

    Regards,
    Rishabh
  • Hello Rishabh,

    Thank you for your suggestion, I am trying to go through the A15 documentation but there's quite a lot of it. Any help narrowing down what to look for would be greatly appreciated.

    Regarding: "The statement "I believe it's just the MAIR Attr Index value should be 0-3 for one A15 core and 4-7 for the second A15 core" is not true."

    The intent was to use MAIR0 for one a15 core and MAIR1 for the other a15 core. If I misunderstood how to use the two Memory Attribute Indirection Registers could you provide an example of how to configure MMU on both A15 cores so that they work with the L1 I-cache? The starterware provided function (MMUA15Enable(&gMmuTable); ) seems to enable the single MPU_MMU so what if any coordination needs to occur between the two cores prior to one enabling the MPU_MMU? It didn't seem that both cores should run that enable function or do they need to?

    You mention not using L1D or L2. As I stated in my followup post, when only enabling L1I the software executes at about the same speed as when no cache is enabled. So am I missing any steps for enabling just L1I? I am using the following functions:

    // CACHEA15InvalidateL1DAll(); //// needed? have ran tests with and without, same results.
    CACHEA15InvalidateL1IAll();
    CACHEA15Enable(CACHE_A15_TYPE_L1I);

    // Initialize MMU module
    MMUA15Init();
    // Set MAIR to inner and outer cacheable
    MMUA15SetMAIR(&gMmuTable, MMU_A15_ATTR_INDEX_2, 0xFF);
    // Initialize descriptor attributes
    MMUA15InitDescAttrs(&gAttrs);
    // Set level one descriptor attributes
    gAttrs.descriptorType = MMU_A15_DESCRIPTOR_TYPE_BLOCK;
    gAttrs.attrIndx = MMU_A15_ATTR_INDEX_2;
    gAttrs.nonSecure = MMU_A15_NON_SECURE_ENABLE;
    gAttrs.accPerm = MMU_A15_ACC_PERM_RW_ANY_PL; // Read Write at any PL
    // Set level one descriptor
    virtualAddr = 0x80000000, phyAddr = 0x80000000;
    MMUA15SetFirstLevelDesc(&gMmuTable, virtualAddr, phyAddr, &gAttrs);
    virtualAddr = 0xc0000000, phyAddr = 0x80000000;
    MMUA15SetFirstLevelDesc(&gMmuTable, virtualAddr, phyAddr, &gAttrs);

    // Set level one descriptor attributes
    MMUA15SetMAIR(&gMmuTable, MMU_A15_ATTR_INDEX_3, 0x00);
    gAttrs.descriptorType = MMU_A15_DESCRIPTOR_TYPE_BLOCK;
    gAttrs.attrIndx = MMU_A15_ATTR_INDEX_3;
    gAttrs.nonSecure = MMU_A15_NON_SECURE_ENABLE;
    gAttrs.accPerm = MMU_A15_ACC_PERM_RW_ANY_PL; // Read Write at any PL
    virtualAddr = 0x0, phyAddr = 0x0;
    MMUA15SetFirstLevelDesc(&gMmuTable, virtualAddr, phyAddr, &gAttrs);
    virtualAddr = 0x40000000, phyAddr = 0x40000000;
    MMUA15SetFirstLevelDesc(&gMmuTable, virtualAddr, phyAddr, &gAttrs);

    MMUA15Enable(&gMmuTable);




    BTW the reason I asked about L2I was because I saw in the TRM that "the processor cores can be kept cache-coherent with each
    other and with the L2 cache." This seems like a useful feature but I haven't seen any details on how to do that.

    Thank you.
  • Hi,

    You should read "Chapter B3 Virtual Memory System Architecture (VMSA)" of armv7-a-r-manual.pdf.
    RBL already enables I-cache. I will get back to you with details on what exactly you need to do.

    Regards,
    Rishabh
  • Hi,

    RBL already enable I cache for A15 core 0.
    So all you need to do is enable I cache for A15 Core 1.
    You can call the API CACHEA15Enable(CACHE_A15_TYPE_L1I) from A15 Core 1.
    You don't need to call any other cache APIs.
    You can set MMU as per your requirements.

    Regards,
    Rishabh
  • Thanks Rishabh. I had done this earlier but didn't see any performance difference from when I don't enable I-cache only.

    Thank you.
  • Hi,

    I guess you are not able to see as I cache is already enabled on Core 0.
    Just run the same code with I cache disabled and you will see lot of performance deterioration.
    I had validated the performance improvement using same MMU example.

    Regards,
    Rishabh