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.

Setting MC Shared Memory non cachable doesn't work

Hello,

having read several examples for setting the MC Shared memory non cacheable (e.g. the powerpoint of this thread http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/164833.aspx or http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/158374.aspx and the example in gel-files and cppi), I'm not able to get a simple example working. I'm working with a EVM-C6678 and try to set a region of 1 MB starting at 0x0C10000 non cachable (mapping it to 0xE0000000). Purpose is to use this region for all cores without thinking about the cache.

Every core (as every core has its own MPAX Registers) setup the MPAX / MAR registers:

#define XMC_BASE_ADDR (0x08000000)
#define MAPPED_VIRTUAL_ADDRESS  0xE0000000
#define XMPAX3_L     (*(int*) (XMC_BASE_ADDR + 0x00000018))
#define XMPAX3_H     (*(int*) (XMC_BASE_ADDR + 0x0000001C))

XMPAX3_H = 0x00E00013;  // Logical base + segment size
XMPAX3_L = 0x0000C1FF;  // Physical replace + permissions
CACHE_setMemRegionInfo(MAPPED_VIRTUAL_ADDRESS >> 24, 0, 0);

Setting variables on the cores, I'm not able to see the corresponding values on every core. Disabling the whole L1-Cache on every core (see below), everything works fine. What's wrong in the configuration?

Cache_Size sCache;
Cache_getSize(&sCache);
sCache.l1dSize = Cache_L1Size_0K;
Cache_setSize(&sCache);

Best Regards,
Bernd

  • Hi,

    It seems the addresses are not correctly coded. To obtain the same thing, that is in my case remapping 128K from 0x0C000000 to 0xF0000000, RW, I wrote:

    XMAPX3_L = 0x00C000F6

    XMAPX3_H= 0xF0000010

    As per sprugw0a, para.7.3.1, logical RADDR (0xF0000000) bit31:8 must be written in MPAX_L bit 31:8, while the physical BADDR (0x0C000000) correspont to 0:0x0C000000 (the first zero is to identify the MCSM in the core internal 36bits addressing)

    This is my (almost incomplete) routine:

    struct pax_t{
      unsigned long low;
      unsigned long high;
    };

    #define PAX ((volatile struct pax_t*)0x08000000)

    static void pax_remap(unsigned int priority, unsigned long virtual, unsigned long physical, unsigned long size_kbytes)
    {
      const unsigned int perm=0xF6; //cannot execute  (0xFF=all permission)
      unsigned long size=size_kbytes>>2;
      unsigned int k=0x0A;
      for(; size; size=size>>1)
        ++k;
      unsigned long pax_h=virtual|k;
      unsigned long pax_l=0;
      if (physical>=0x80000000)
      {
        pax_l|=0x80000000;
        physical=physical & 0x0FFFFFFF;
      }
      pax_l=pax_l|(((physical>>12)<<8)|perm);

      PAX[priority].high=pax_h;
      PAX[priority].low=pax_l;
    }

  • Hello Alberto,

    thanks for your reply. I'm just reading once again the adress decoding to understand my mistakes. Beside this, I just typed a simple example with your configuration and also with enabling L1-cache on every core. Disable the cache direct works, mapping with MPAX doesn't work.

    May you can try to execute my example? I suggest there's still a mistake in my configuration, but I'm unable to find something.

    Best Regards,
    Bernd

    Simple Test.zip
  • Hi,

    I haven't run your examples, but looking at the map file a can see that your shared variable is mapped at 0x0CXXXXXX, that is it still mapped on a cacheabe address. To go un-cached, you have to use the logical address set-up in the PAX register, that is 0xFxxxxxxx. After the PAX setup-up, your memory is accessible at two address at the same time:

    • original one (0x0C...), always L2 memory cacheable
    • the new one (0xF....), now an L3 memory where you can control the cachability via MAR register.

    Just as a test, since you know that uiTestCacheCore0 is at 0x0c000004, try using:

    volatile uint32_t* const uiTestCacheCore0_remapped = 0xF0000004;

    ...

    *uiTestCacheCore0_remapped = ....;

    It should work. If you disable L1 cache, you can verify that *uiTestCacheCore0_remapped and uiTestCacheCore0  are really the same physical location.

    I'm not familiar with XDC and SYS/BIOS configuration (I don't use it), but I suppose you have to map your shared region to 0xF0000000 somewhere in your configuration files.

    The new shared segment should be an unitialized segment, since prior to the PAX remapping the memory at 0xF0000000 could not exist (EVM has 512M only) and the C prologue cannot to fill it with zero.

  • Hi Bernd,

    you can find an example on how to use the MPAX here:

    http://processors.wiki.ti.com/index.php/Software_Transactional_Memory

    The link to the code is on the bottom of the page.

    Kind regards,

    one and zero

  • Hello together,

    thanks for your suggestions and examples, I'll have a closer look at it on monday. But I've another question.

    Maybe you can clarify the about address (de-) coding. I'm very confused about a lot of examples all doing not the same. Reading the CorePac UG I supposed that the BADDR is meant to be the Base address in the 32-Bit-CorePac Memory and the RADDR is meant to be the logical address in the 36-Bit-Physical Memory. But this isn't always in the examples, see below.

    So the example from Alberto and also the example from the Software Transactional Memory is identical to the PDK-sample, this is consistent. But I wonder why the BADDR is related to address in the physical memory and the RADDR is related to the CorePac address. This isn't described in such a way in the CorePac UG.

    Best Regards,
    Bernd


    ---> 1) Sample from CorePac UserGuide Page 7-10 (Figure 7.7) <---
    -Mapping 4 KB from Physical CorePac Address 0xC0007000 to 0x50042000
    => XMPAX-High: 0xC0007 | 00 | B
    => XMPAX-Low:  0x050042 | FF                              => Here everything is how I understood

    ---> 2) Sample from pdk_C6678_1_0_0_17\packages\ti\drv\cppi\example\sample\sample.c <---
    -Mapping 1 MB from Physical CorePac Address 0x0C000000 to 0x81000000
    => XMPAX-High: 0x81000 | 0 | 13
    => XMPAX-Low:  0x00C000 | FF                              => Here the BADDR seems to be the Physical 36-Bit and the RADDR the CorePac 32-Bit

    ---> 3) Sample fromCCS5.1.1.00028\ccsv5\ccs_base\emulation\boards\evmc6678l\gel\evmc6678l.gel <---
    => XMPAX-High: 0x21000 | 00 | B
    => XMPAX-Low:  0x1000000 | FF
    -This should do a mapping of 4 KB from ? to ?

    ---> 4) Example von Alberto <---
    -Mapping 1 MB from Physical CorePac Address 0x0C000000 to 0xF0000000
    => XMPAX-High: 0xF0000 | 0 | 10
    => XMPAX-Low:  0x00C000 | F6                              => Here the BADDR seems to be the Physical 36-Bit and the RADDR the CorePac 32-Bit

  • Hello,

    having read your examples tested your suggestions, everything works fine. Mistake was that the Shared memory has to be mapped into the mapped region; now the definitions (see below) works.

    Now there's only the open question why the BADDR and RADDR are not used as defined in the UG (see example 1) in the note above), maybe you can clarify this issue.

    Best Regards,
    Bernd

    #define XMC_BASE_ADDR (0x08000000)
    #define MAPPED_VIRTUAL_ADDRESS  0x80000000
    #define XMPAX3_L     (*(int*) (XMC_BASE_ADDR + 0x00000018))
    #define XMPAX3_H     (*(int*) (XMC_BASE_ADDR + 0x0000001C))

        XMPAX3_H = 0x80000013;  // BADDR + segment size
        XMPAX3_L = 0x00C000FF;  // RADDR + permissions
        CACHE_setMemRegionInfo(128, 0, 0);

        OR

        CSL_XMC_XMPAXH mpaxh;
        CSL_XMC_XMPAXL mpaxl;

        // set shared l2 non-cacheable and non-prefetchable
        CACHE_setMemRegionInfo(128, 0, 0);
        mpaxh.segSize = 0x13;
        mpaxh.bAddr = 0x80000;
        mpaxl.ux = mpaxl.uw = mpaxl.ur = mpaxl.sx = mpaxl.sw = mpaxl.sr = 1;
        mpaxl.rAddr = 0x00C000;
        CSL_XMC_setXMPAXH(3, &mpaxh);
        CSL_XMC_setXMPAXL(3, &mpaxl);

  • I just wanted to second that Alberto's code example worked very well, together with Bernd's CACHE_setMemRegionInfo invocation, which, if placed within Alberto's function, would be invoked as:

    CACHE_setMemRegionInfo(virtual >> 24, 0, 0)

    I agree that the language in the manual is confusing. This discussion helped a lot.