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.

TMS320F28379D: using UniFlash to configure DCSM for the first time

Part Number: TMS320F28379D
Other Parts Discussed in Thread: UNIFLASH, CONTROLSUITE

Hello,

I am attempting to use UniFlash to configure the DCSM for the first time and I must being doing something wrong because after turning on the security I cannot reprogram or connect to the target even with the password values loaded. My error is probably something simple but before I brick another board I wanted to get feedback on my usage of the tool to minimize the number of boards I go through.

My goal is to turn on the DCSM in CPU1 with all flash sections and ram secured under zone 1. I am using the first zone block so I am leaving the link pointers all Fs. I am not attempting the exe only protection at this time and don't need the secure CRC generation feature. I am leaving the boot options/pins at defaults/boot to flash.

My understanding is that once the DCSM zone security is turned on you can still use UniFlash to re-program the part if you have the correct password values loaded and execute the password match flow properly (which I am assuming UniFlash can do if the proper password values are loaded and clicking the Unlock button).

Here is my sequence of events:

Create a .hex file from my .out file using hex2000. The created hex file does not have any OTP configuration linked in. I am looking to eventually do that following the Blinky with DCSM example project but first I wanted to figure out a basic method using UniFlash. I don't think this matters but my hex2000 command line is: hex2000.exe -romwidth=16 -memwidth=16 -i "%REL_PATH%Release\Production.out" -o "%REL_PATH%ProgrammingFiles\Production.hex"

On a device with DCSM in its default, blank state I can successfully program the hex file via "UniFlash using Program -> C28xx_CPU1 -> Load Image"

Once I program the image I then move to "Settings & Utilities -> C28xx_CPU1" and set the following:

Z1-LINKPOINTER1 (0x78000)(32 bits) 0xFFFFFFFF - leave all three link pointer copies at default so link pointer points to first zone block.
Z1-LINKPOINTER2 (0x78004)(32 bits) 0xFFFFFFFF
Z1-LINKPOINTER3 (0x78008)(32 bits) 0xFFFFFFFF

Z1-PSWDLOCK (0x78010)(32 bits) 0xFFFFFFFE - The Tech Reference Manual says any value other than 0xF / 0b1111 should lock the password so I picked 0xE or 0b1110.

Z1-CSMPSWD3 (0x5F016)(32 bits) 0x11111111 - These are not the actual password values I am using but I am programming all four locations to a non 0xFFFFFFFF and non zero value (TRM said all zeros is permanent lock)
Z1-CSMPSWD2 (0x5F014)(32 bits) 0x22222222
Z1-CSMPSWD1 (0x5F012)(32 bits) 0x33333333
Z1-CSMPSWD0 (0x5F010)(32 bits) 0x44444444

Z1-GRABSECT (0x5F01A)(32 bits) 0xFF555555 - All flash sectors to zone 1
Z1-GRABRAM (0x5F01C)(32 bits) 0xFFFF5555 - All ram to zone 1, not using CLA at this time so left that blank.

All the other settings on that page I have left at defaults.

After these values are loaded in the UniFlash fields on the "Settings & Utilities -> C28xx_CPU1" page I hit the "Program All Zone 1 Security Settings Button" which completes without an error.

After doing the above sequence I cycle power on the target and the go to the "Settings & Utilities -> C28xx_CPU1" page. Then I scroll down to the CSMPSWD section and click the unlock button. I am assuming this is the button that would execute the password match flow and unsecure the target so I an reprogram the board. When I hit  the unlock button I get and error: " [ERROR] C28xx_CPU1: Error connecting to the target: (Error -1156 @ 0x0) Device may be operating in low-power mode. Do you want to bring it out of this mode? Choose 'Yes' to force the device to wake up and retry the operation. Choose 'No' to retry the operation without waking the device. (Emulation package 8.2.0.00004)"

Blow is the UniFlash console output of the above sequence that leads to the error. In the sequence below I programmed the part twice to confirm the image was not programming OTP as I had previously copied over the Blinky with DCSM example files to experiment with.

UniFlash console log:
[10/3/2019, 5:15:49 PM] [INFO] C28xx_CPU1: GEL Output: Memory Map Initialization Complete
[10/3/2019, 5:15:49 PM] [INFO] C28xx_CPU1: If erase/program (E/P) operation is being done on one core, the other core should not execute from shared-RAM (SR) as they are used for the E/P code. Also, CPU1 will be halted to determine SR ownership for the CPU which will run the Flash Plugin code, after which CPU1 will be set to run its application. User code execution from SR could commence after both flash banks are programmed.
[10/3/2019, 5:16:00 PM] [SUCCESS] Program Load completed successfully.
[10/3/2019, 5:16:06 PM] [INFO] C28xx_CPU1: GEL Output: Memory Map Initialization Complete
[10/3/2019, 5:16:17 PM] [SUCCESS] Program Load completed successfully.
[10/3/2019, 5:22:29 PM] [INFO] C28xx_CPU1: GEL Output: Memory Map Initialization Complete
[10/3/2019, 5:22:29 PM] [INFO] C28xx_CPU1: Performing Security Operation...
[10/3/2019, 5:22:29 PM] [INFO] C28xx_CPU1: Programming LINKPOINTER registers...
[10/3/2019, 5:22:30 PM] [INFO] C28xx_CPU1: Calculated Link Pointer Offset: 0x20
[10/3/2019, 5:22:30 PM] [INFO] C28xx_CPU1: Programming OTPSECLOCK registers...
[10/3/2019, 5:22:31 PM] [INFO] C28xx_CPU1: Programming OTPBOOTCTRL registers...
[10/3/2019, 5:22:32 PM] [INFO] C28xx_CPU1: Programming password...
[10/3/2019, 5:22:33 PM] [INFO] C28xx_CPU1: Programming EXEONLYGRABProgram registers...
[10/3/2019, 5:22:34 PM] [SUCCESS] C28xx_CPU1: Operation completed successfully. -->At this point I power cycle the target. Log continues below when I attempt to unlock the target.
[10/3/2019, 5:23:02 PM] [ERROR] C28xx_CPU1: Error connecting to the target: (Error -1156 @ 0x0) Device may be operating in low-power mode. Do you want to bring it out of this mode? Choose 'Yes' to force the device to wake up and retry the operation. Choose 'No' to retry the operation without waking the device. (Emulation package 8.2.0.00004)

I am using Code Composer Studio  Version: 9.1.0.00010 with the XDS200USB JTAG cable. For CCS "check for updates" reports no updates found so I think the dev tools are all at the latest version.

UniFlash is Version: 5.1.0.2397 (downloaded last week).

I have also tried only programming the password values, password lock, grabram, and grabsect values using the UniFlash buttons for each of those fields independently and leaving all other values unprogrammed and got the same result.

For hardware the boot mode select pins (GPIO72 and GPIO84) are pulled high via pull ups (Get/Flash boot mode). The target hardware is a custom control board but the DSP hardware as far as power supplies, JTAG, reset supervior IC, PCB layout, etc... are basically the TI reference design.

My next step is to read up again on the boot pins and boot modes and how the OTP ECC works to see if I am not handling those properly but presently the boot mode setup is all at the default value and I have not changed any ECC settings from defaults.

If anybody out there sees something I am doing wrong I would be very grateful for any corrections of suggestions. Thanks for your time.

Also here are some confirmation of understanding items:

As a DCSM newbie I have read through the DCSM section in the TRM a few times and  searched forum post here. Here are some key points I have learned so far. Please let me know if I am wrong on any of these as it will help me figure out the problem (and future problems). I will also correct or delete any incorrect statements so I don't confuse people.

-Programming all zeros as your password values is probably not what you want to do - once this is done the device is permanently locked.

-You may think if you lock all the memory in one zone that there will be no memory access problems to worry about. This is not the case because shared RAM (GSx) and M0/M1 cannot be secured. Also you can not copy data from secure flash to non secure ram (I think). This means that if you have a ramfuncs section running of GSx RAM or non secured local RAM you will have a problem at run time when you try to copy the ramfuncs from secure flash to unsecure ram. Ramfuncs should be in secure ram if the ramfuncs flash is secure.

-You probably want your stack in unsecure ram so any function call can use the stack. If your stack was in secure ram and a function in unsecured flash was called that function would not be able to access the stack. If you had an array of function pointers in unsecured memory that gets called they would also have a problem if the stack was in secure ram.

-If you turn on the exe only option on the flash where your ramfunc are linked you will need to use the built in SafeCopy function TI provides. If the exe only is turned on you cannot read from that flash section into RAM even if its being done from within the same secure zone which is why the SaveCopy function is provided.

-There are two security zones. The dual zone would allow you to lock your code/IP under one zone and the leave RAM/Flash open for a third party to develop on and then the third party could use the other zone to lock their IP. If you are a single developer and simply want to lock down all memory you really only need to use one zone.

-Each core of the dual core F28379D part has its own DCSM. If you want both cores secured you need to configure both DCSMs. Turning on security in CPU1 does not secure CPU2.

-The DCSM OTP values can only be written once but some values (password , grab RAM/Sect, and exe only settings) have 30 copies in the OTP memory. These would be useful if you want to change to a different set after programming an initial set. Which of the 30 zone blocks is used is picked by the LINKPOINTER. The first zone block will be used by default if link pointer is all Fs. To select the second zone block you would set bit zero in the link pointer to zero. To select the third zone block you would set bit one to zero and so on for the reset of the zone blocks up to block 30 via bit 29.

-There are three copies of LINKPOINTER which should all be set to the same value. Three copies are used because the LINKPOINTER is not ECC memory protected.

-Even if you write all Fs to an OTP value the corresponding ECC will be written for that blank value (except link pointer). This means you if you write all 0xFFs you will not be able to go back later and write a non 0xFF value because the ECC will have been previously written and it won't be  the same for your new value.

-If you are going to link in OTP configuration to your project follow the example in the Blinky with DCSM example project which you get with the controlSUITE install. The example project is under device_support in the folder structure. The OTP sections are intentionally split up to avoid reserved areas. If you write to those reserved areas it creates an error. Also when you are ready to attempt actual programming of the OTP remember to comment out the type = DSECT option in the 2837xD_dscm_lnk_cpu1.cmd file. type = DSECT is a dummy load option which will prevent the section from being linked in. Finally if you use any zone block other than the default first zone block (pointed to if link pointer is all Fs) you will have to update the origin of DCSM_ZSEL_Z1_Px to the zone you are using, each zone is 0x10 long.    

-There is DCSM memory in OTP and also DCSM related registers in the cpu RAM registers. Any configuration you want to set should be programmed into the OTP memory. The cpu RAM registers are there to view what is in OTP memory. The RAM regs get updated when the OTP is accessed. The DCSM ram registers also have some status values related to the DCSM (like state of secured or not secured) and the password key values used to unlock the target are written to the CPU registers (Zx_CSMKEY0 to ZxCSMKEY3).

  • If you didn't lost your password, I think you didn't brick your device, unless.. The problem is you need to switch boot mode using boot mode pins from Get/Flash to Wait. This is little annoying and I don't remember where in the docs it is specified, but you need to Wait to unsecure.

    Z1-PSWDLOCK (0x78010)(32 bits) 0xFFFFFFFE - The Tech Reference Manual says any value other than 0xF / 0b1111 should lock the password so I picked 0xE or 0b1110.

    Unfortunately it is not quite true. I also tried to toggle just single bit and some fragments of password stayed visible after lock to anyone, and some other parts of password read as all zeros. Since you can't change PSWDLOCK, unit security is less secure permanently. Value 0x00000000 seems doing its task well, whole password reads as all 0's when secured.

    You wrote a lot, please try switching boot mode to Wait and reattempt unlock.  

  • Hello EK,

    Thanks for the advice. You were right. I switched boot mode select pins to wait mode (0b10, GPIO72 high, GPIO84 low) and then I was able to unlock in UniFlash and reprogram. Luckily I have those boot pins on DIP switches so it will not be a hassle to add that step to the programming manual for my production deliverables.

    Following up on your note about what value to write to the password lock to really make it work: I was going to connect with the emulator and see what the values look like with the 0xFFFFFFFE lock. The target did not connect so I could not do that. I think I have to modify a gel file with the password values and then it will work. If I can figure that out and I can still update this post after marking it solved I will confirm what you were seeing.

    Thank you for your help. Really appreciate it.

  • Follow up on the password lock. It looks like a value of 0xFFFFFFFE is working as expected for me.

    What I did to check this was first get the emulator working again with the secured target. To do that I modified the gel file (at C:\ti\ccs901\ccs\ccs_base\emulation\gel\f28379d_cpu1.gel ) with the following statements at the bottom of the SetupDCSM() function (after the dummy reads of the selected zone block).  In this example I am using dummy key values, not my real keys.

        //write password key to unlock the device
        *(unsigned long *)0x0005F010 = 0x11111111;      //Zone1 CSMKey 0
        *(unsigned long *)0x0005F012 = 0x22222222;      //Zone1 CSMKey 1
        *(unsigned long *)0x0005F014 = 0x33333333;      //Zone1 CSMKey 2
        *(unsigned long *)0x0005F016 = 0x44444444;      //Zone1 CSMKey 3

    Then I added some debug gel instructions to print out the password values in OTP memory before and after the gel file unlocked the target. Note that the address are for the first zone block.

    Added this at the start of the OnReset() gel function before I unlock the target:
        GEL_TextOut( "reading zone1 CSM keys prior to unlocking device\n");
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x78028);
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x7802A);
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x7802C);
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x7802E);

    Added this after the target unlock:
        GEL_TextOut( "reading zone1 CSM keys after unlocking device\n");
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x78028);
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x7802A);
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x7802C);
        GEL_TextOut( "Zone1 CSMKey 0 = %x\n",,,,, *(unsigned long *)0x7802E);

    From that test the password reads back all zeros before unlock, then after unlocking you can see the password.

    The console output was as follows:

    C28xx_CPU1: GEL Output: reading zone1 CSM keys prior to unlocking device
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x00000000
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x00000000
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x00000000
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x00000000
    C28xx_CPU1: GEL Output: reading zone1 CSM keys after unlocking device
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x11111111
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x22222222
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x33333333
    C28xx_CPU1: GEL Output: Zone1 CSMKey 0 = 0x44444444

    From my test it looks like a 0xFFFFFFFE password lock works ok.

    Anyway thanks again for your help on the boot mode issue. Next step for me is to write it all down and they try setting DCSM OTP via the image instead of using UniFlash to make it easier for production programming.

  • Hi,

    This is little annoying and I don't remember where in the docs it is specified, but you need to Wait to unsecure.

    It is mentioned in section "3.13.1.1 Emulation Code Security Logic (ECSL)" of TRM.

    Follow up on the password lock. It looks like a value of 0xFFFFFFFE is working as expected for me.

    Yes, that should work.

    Regards,

    Vivek Singh

  • Hi,

    Regarding password. Password lock doesn't engage zone security, it only locks password OTP readout! So yes, any value in password lock should seem as working for you, it doesn't affect zone security, you need to password unlock to reprogram. But what about reading passwords from locations at 0x78000?

    As it is told in Z1_OTPLOCK register description, PSWDLOCK field is loaded from Z1_PSWDLOCK[7:4] bits. It is told that when all four bits are ones 1111  CSM password locations are not protected and be read from debugger. Since your balue 0xFFFFFFFE has all four bits set, you should see your password in Wait boot mode while not password unlocked. Regarding what I said is not true, I meant clearing just one out of four bits. I tried once programming passwordlock value as 0xFFFFFFEF, result while zone is secured you can see in attached picture, visible to user password fragments are hidden using MS Paint. After that I always program password lock to 0x00000000, at least all four bits [7:4] should be cleared, I'm sure.

    Regards