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.

66AK2L06: Try to implement BIOS's memory protect to protect shared memory region

Part Number: 66AK2L06
Other Parts Discussed in Thread: SYSBIOS

Tools version: ti-cgt-c6000_8.3.3

Shared memory location (MSMC): 0x0C03B000 

I am going to load program into the above mentioned memory section and I wanted to protect it using ti.sysbios.family.c64p.MemoryProtect

- Is it appropriate to use ti.sysbios.family.c64p.MemoryProtect?

- If ti.sysbios.family.c64p.MemoryProtect is appropriate, here is what I have implemented:

In the .cfg file:

...
var ExceptionDSP = xdc.useModule('ti.sysbios.family.c64p.Exception');
var MemoryProtect = xdc.useModule('ti.sysbios.family.c64p.MemoryProtect');
...
Program.global.sharedMemoryProgramStart= 0x0C03B000;
Program.global.sharedMemoryProgramLen= 4000;
...
...
ExceptionDSP.enablePrint = true;
Hwi.enableException = true;
ExceptionDSP.exceptionHook = '&ExceptionHandler';
ExceptionDSP.enableExternalMPC = true;
...

In the DSP function .c file:

...
volatile UINT32 perm;
BOOL mpFlag
perm = MemoryProtect_MPPA_UX | MemoryProtect_MPPA_UR | MemoryProtect_MPPA_SX | MemoryProtect_MPPA_SR | MemoryProtect_MPPA_LOCAL;
mpFlag=MemoryProtect_setPA((Ptr)(sharedMemoryProgramStart), sharedMemoryProgramLen, (UInt32)perm);

I am getting false when I print out the mpFlag so I don't think I am doing this correctly? I also purposely read and write back the same value to try to trigger the exception but it also did not trigger. Any suggestions?

  • Hi,

    Please refer to: https://processors.wiki.ti.com/index.php/MemoryProtectionOnKeystoneDevices#:~:text=Memory%20protection%20on%20the%20KeyStone,the%20permissions%20and%20capturing%20violations.

    It explains that L1D, L1P and L2 memory protection is controlled by MPPA registers. However, MSMC is controlled by MPAX.

    The Sysbios user guide: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/6_76_01_12/exports/bios_6_76_01_12/docs/cdoc/ti/sysbios/family/c64p/MemoryProtect.html#set.X.M.C.Region  

    The Bool MemoryProtect_setPA(Ptr addr, SizeT size, UInt32 paMask); calls into MemoryProtect_writePA() which accesses the MPPA register, this will not work MSMC (shared L2).

    What you need to use is: Bool MemoryProtect_setXMCRegion(Int8 id, Ptr baseAddr, MemoryProtect_RegionSize size, Ptr rAddr35_12, UInt32 paMask);

    Regards, Eric

  • MemoryProtect_setXMCRegion() is not available for sysbios 6.75 so I tried to write to the regs directly:

    volatile UINT32* ptrMpax;
    volatile UINT32 *ptrVal;
    UINT32 value;
    UINT32 value2;
    UINT32 tempVal;

    perm = MemoryProtect_MPPA_UX | MemoryProtect_MPPA_UR | MemoryProtect_MPPA_SX | MemoryProtect_MPPA_SR; //even if we are using MPAX, these defines are still ok to use

    //Configure the region to protect: XMPAXL10 regs (10 is an arbitrary pick)
    value=(UINT32)(0xC03B0<<12) + 0x13;
    ptrMpax=(UINT32*)0x08000050;
    *ptrMpax=value;
    ptrMpax=(UINT32*)0x08000054;
    value2 = (UINT32)(0xC03B00<<8) + perm;
    *ptrMpax=value2;

    //read and write to protected region to try to cause an error
    ptrVal=(UINT32*)sharedMemoryProgramStart;
    tempVal=*ptrVal;
    *ptrVal=tempVal;

    //reading XMPFAR, XMPFSR
    ptrMpax=(UINT32*)0x08000200;
    value = *ptrMpax;
    ptrMpax=(UINT32*)0x08000204;
    value2 = *ptrMpax;

    I got 0x08000050 from XMPFAR and 0x110 from XMPFSR. Seems like it was complaining about the write to XMPAXL10 reg??

  • Hi,

    I thought offset 0x50 is MPAXL, it is replacement address with permission. offset 0x54 is MPAXH, it is 32-bit address + segment size. You did the opposite way, please double check.

    Also, there shouldn't be any issue to write to 0x0800_0050, you can juts try to change it in CCS memory window.

    Regards, Eric

  • You are correct! I did mixed up the XMPAXL and XMPAXH. I fixed the issue and still saw the same problem I mentioned earlier. Note that this code was run on our actual target platform without JTAG support so I could not manipulate the registers easily through CCS.

    volatile UINT32* ptrMpax;
    volatile UINT32 *ptrVal;
    UINT32 value;
    UINT32 value2;
    UINT32 tempVal;

    perm = MemoryProtect_MPPA_UX | MemoryProtect_MPPA_UR | MemoryProtect_MPPA_SX | MemoryProtect_MPPA_SR; //even if we are using MPAX, these defines are still ok to use

    //Configure the region to protect: XMPAXH/L10 regs (10 is an arbitrary pick)
    value=(UINT32)(0xC03B0<<12) + 0x13;
    ptrMpax=(UINT32*)0x08000054;
    *ptrMpax=value;
    ptrMpax=(UINT32*)0x08000050;
    value2 = (UINT32)(0xC03B00<<8) + perm;
    *ptrMpax=value2;

    //reading XMPFAR, XMPFSR
    ptrMpax=(UINT32*)0x08000200;
    value = *ptrMpax;
    ptrMpax=(UINT32*)0x08000204;
    value2 = *ptrMpax;

    value is 0x8000054 for XMPFAR
    value2 is 0x00000110 for XMPFCR
    Seems like there is some kind of fault when I wrote to the XMPAXH10 register??

  • How are you running your program? The MPAX is inside C66X corepac and should be able to access from C66X CPU.

    - Eric

  • The program is part of a larger DSP binary that resides on the 2-MB shared memory within location 0x0C03B000 to 0x0C03B000 + 0x0001ce20. The binary is downloaded/run by ARM using mpm_load() and mpm_run().

  • Hi,

    When using MPM, the code is downloaded from Linux to DSP core then let DSP core run. I am not aware of any restriction to write access to corepac registers. Did read work? Did another MPAX pair work? 

    Regards, Eric

  • I think I have managed to program the regs correctly to protect the memory segments according to the permission type(no read) I specified. First problem I saw was the Fault Address register (XMPFAR) did not show the address that was purposely read using my test code to violate the set permission. Probably you can point me to what I did wrong:

    #define XMAPXL2 (0x08000010)
    #define XMAPXH2 (0x08000014)
    UINT32 tempVal,valueH,valueL;
    volatile UINT32* ptrMpaxL;
    volatile UINT32* ptrMpaxH;

    //=====================================================
    // Set Permission BADDR=0x0C03C, RADDR=0x00C03C
    // 0000 1100 0000 0011 11xx xxxx xxxx xxxx
    // SEGSZ=0x0D (01101b),PERM=0x0D (001101b)
    //=====================================================

    reqMsg->param1 = 0x0C03
    reqMsg->param2 = 0xC00D //16K segment
    reqMsg->param3 = 0x00C0
    reqMsg->param4 = 0x3C0D // No supervisor write/read
    // No user write

    perm = (UINT32)reqMsg->param3;
    perm = (perm<<16)+(UINT32)(reqMsg->param4);
    perm = perm + 0x80; //why 0x80 ???

    segz = (UINT32)(reqMsg->param1);
    segz = (segz<<16)+(UINT32)reqMsg->param2;

    ptrMpaxH = (UINT32*)XMAPXH2;
    ptrMpaxL = (UINT32*)XMAPXL2;
    valueH = segz;
    *ptrMpaxH= valueH;
    valueL = perm;
    *ptrMpaxL= valueL;

    //=====================================================
    // Read memory (addr: 0x0C03C004)
    // 0000 1100 0000 0011 11xx xxxx xxxx xxxx
    //=====================================================
    reqMsg->param1 = 0x0C03
    reqMsg->param2 = 0xC004

    value = (UINT32)reqMsg->param1;
    value = (value<<16)+(UINT32)(reqMsg->param2);

    ptrVal=(UINT32*)value;
    tempVal=*ptrVal; //read memory

    //=====================================================
    // Read XMPFAR and XMPFSR
    //=====================================================
    ptrMpaxL=(UINT32*)0x08000200;
    value = *ptrMpaxL;
    ptrMpaxH=(UINT32*)0x08000204;
    value2 = *ptrMpaxH;


    The value read at location (0x0C03C004) is zero which is
    expected since I set it to no read and that location has
    non-zero value but the XMPFAR did not show the addr violation of
    0x0C03C004?? Instead it shows all zeros for XMPFAR and XMPFSR??

  • Hi,

    I found following info from: 

    MSMC Controller[edit]

    The MSMC controller has the following monitoring capabilities:

    • MPAX units at SMS and SES control memory protection for non-CorePac system master accesses to SL2 and external memory
    • Protection checks when a master tries to program some other master’s segment registers

    From the Keystone II MSMC use guide: https://www.ti.com/lit/ug/spruhj6/spruhj6.pdf

    2.1.2.2 System MSMC SRAM Access Slave Interface (SMS) The SMS interface handles accesses to MSMC SRAM that originate from a system master that is not a C66x or ARM CorePac. Accesses from masters in the system to MSMC configuration registers are also expected to be presented at this interface. Any accesses from the SMS interface that do not address the MSMC SRAM or configuration registers result in an addressing error returned to the requesting master.

    In you test case, you used a CPU (this is corepac master) to access MSMC, this will not generate access violation.

    Regards, Eric

  • Based on your statement above, accessing the MSMC using DSP Core will not trigger access violation which is what I saw. Based on my experiments, I could still protect it by configuring access permission to various memory segments using XMAPXL and XMAPXH. Is that a correct observation?

  • Hi,

    Yes, the MSMC is protected from non-Core master access.

    Regards, Eric

  • My previous question was I was using DSP Core 0 (this is a Core master access, right?) for my test to write to write-protected MSMC memory (I protected it using XMPAXH and XMPAXL). After I protected it, I could not write to it, is that the correct observation?

  • Hi,

    Somehow the info I provided yesterday was not correct. Below is my test code on DSP core 0:

    #define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y)
    #define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x))

    void main(void) {

    unsigned int x;

    DEVICE_REG32_W(0x0c000000, 0x12345678);   //I wrote a pattern to MSMC

    x = DEVICE_REG32_R(0x0c000000);  //I read it back, it is correct

    //I programmed the MSMC starting from 0x0c00_0000 no read/write/execute with 2MB using MPAX pair 3

    DEVICE_REG32_W(0x08000018, 0x00C00000);
    DEVICE_REG32_W(0x0800001C, 0x0C000014);

    //I also knew XMPFAR and XMPFSR are 0 at this point

    DEVICE_REG32_W(0x0c000100, 0xaaaaaaaa); //I write MSMC again

    Here I saw the: 

    0x08000200 XMC_xmpfar

    0x08000200 0C000100  ========>This address changes to what address I try to write
    0x08000204 XMC_xmpfsr
    0x08000204 00000110 ====> indicating a local supervisor write
    0x08000208 XMC_xmpfcr

    x = DEVICE_REG32_R(0x0c000000);  =======>Here I readback 0

    }

    It looks to me corepac can also generate correct access violation. In the past I used CCS memory window directly change the registers and address, I didn't see the violation. But with code running on the core, it has violation reported. 

    So my observation is that:

    1. Once the region is access protected, you can't write/read again (same as your observation)

    2. However, the access from the same corepac will generate access violation and recorded in XMPFAR/FSR (you didn't ?)

    3. From other core masters (e..g core 1), I can still access the protected region because itself MPAX allows it.

    My test is on 66AK2H device, the MSMC should be the same as 66AK2L. 

    Sorry for the info yesterday, let me know your observation, especially on #2.

    Regards, Eric

  • Eric, thank you for running a quick test. FYI - One difference I saw from your test and mine was that on the 66AK2L, bit 7 (a reserve bit) on the permission bits for XMPAXL has to be set, if not I will get a fault on the XMPFAR and XMPFSR registers (based on my past experiments). Initial readings from all the XMPAXL [1 to 15] registers show that this bit is set for some strange reason.

  • Hi,

    Bit 7 of MPAXL is  non-secure. At the power on, it is forced to 1 on non-secure devices, or cleared to 0 on secure devices. On my K2H for the test, it is 1, non-secure device.

    At the moment of power on reset:

    0x08000000 000000BF 0000001E 800000BF 8000001E
    0x08000010 121010FF 2101000B 00C400FF 0C400014

    DEVICE_REG32_W(0x0c000000, 0x12345678);

    x = DEVICE_REG32_R(0x0c000000);

    DEVICE_REG32_W(0x08000018, 0x00C00000);
    DEVICE_REG32_W(0x0800001C, 0x0C000014);

    Here it changed to:

    0x08000000 000000BF 0000001E 800000BF 8000001E
    0x08000010 121010FF 2101000B 00C00080 0C000014

    DEVICE_REG32_W(0x0c000100, 0xaaaaaaaa);

    0x08000200 0C000100 00000110 00000000 00000000 

    Are you running a secure K2L or not? Who set the bit 7? It is set by system and read-only? What is the value after power on reset? Your application can change it 0 or 1? Please clarify you observation: bit 7 setting, if you have XMPFAR and XMPFSR  error recorded or not? at what step you have error recorded? If you have the error record before the test, can you use XMPFCR=1 to clear those?

    Regards, Eric 

  • Here are my answer to your questions:

    -Are you running a secure K2L or not? Non-secure

    -Who set the bit 7? The DSP code does not set that bit 7. Looks like it cannot be overwritten (I tried)

    -What is the value after power on reset? 0x0000001E at location 0x08000004, 0x000000BF at location 0x08000000, 

                                                                    0x8000001E at location 0x0800000C, 0x08000008 at location 0x800000BF

                        my own setting:=======>  0x0C03C00D at location 0x08000014, 0x00C03C80 at location 0x08000010 

                               no read/write/execute

    -Your application can change it 0 or 1? My code can write 0 or 1 to bit 7, retried it again, no error either case, always read back 1

    -Please clarify you observation: bit 7 setting, if you have XMPFAR and XMPFSR  error recorded or not? No, looks like my previous observation does not match what I am seeing now. Currently, setting bit 7 does not impact anything

    -At what step you have error recorded? If you have the error record before the test, can you use XMPFCR=1 to clear those? I have seen a fault in XMPFAR and XMPFSR when I removed all permissions starting 0x0c000000 using 1MB segments because other entities were writing to it (not sure if it was DSP or ARM) . Need to do more tests tomorrow. My code was corrupted and I had to reboot, could not clear it because of that.  

                         

  • Hi,

    Good to know that your K2L is also non-secure device and bit 7 is set and read-only. This is the same as my K2H. 

    Your test is Linux running on ARM and downloading DSP code. Is it possible to not boot Linux and just use DSP in no-boot mode? Then you can run DSP program directly to see if any access violation recorded in XMPFAR and XMPFSR? Either your SYSBIOS code or my sample code should work for this testing and they are straightforward.

    Regards, Eric

  • Hi,

    Any update? Did you find out why you can't trigger access violation from a core master?

    Regards, Eric

  • Hi Eric,

    Regarding your previous question, the DSP is currently in a product and soldering a JTAG header to download DSP code directly is a little difficult. I am talking to the DSP through a test manager managed by Host, so not running the ARM cannot be easily done. 

    Are there any registers I can read to find out what is going on?

    Or I can try to revive the TI 66AK2L06 based EVM board we used during the early phase of the project and run your code and compare the differences between the EVM and the product. Might be a long shot since I am not really sure what to look for.

  • Hi,

    I see, you are debugging on a product without JTAG access. I don't see difference you load a DSP image from Linux and run vs directly run on DSP. But it is good if you can find an EVM for easier debug.You only need to change the dip switch to no-boot mode and power it on for the trial.

    >>>>Are there any registers I can read to find out what is going on?>>> I am not aware of registers capturing why violation didn't trigger.

    Regards, Eric

  • I will get an EVM and try it out with the no-boot mode. Thanks!