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.
Hello!
We have developed a solution that includes a bootloader and application for the F28379D device. Now we want to protect the flash memory readings, so we have activated the Zone 1 protection to all memories (FLASH and RAM) for both CPUs.
The problem we have now is on the bootloader. We are not able to enable the bootloader on CPU2. I will explain briefly the boot sequence:
This was working perfectly until we lock the memories.
Now we are able to flash CPU1 successfully (we have included the unlock sequence inside code) but when CPU1 runs CPU2, it looks like that this one is not started properly. We don't have too much information because we cannot debug the CPUs if they are protected. We, we can debug CPU1, but not CPU2.
Is it the DCSM affecting to the IPC peripheral? Is there any specific boot sequence for CPU2 if the protections are enabled?
Thank you
I can't confirm if it is working or not. If I debug de CPU2, I must to unlock it before debugging, so the result of the unlocking sequence is always OK. This is the first function I call in the main for both CPUs:
uint16_t u16Err = BOARD_OK; uint32_t u32Password0, u32Password1, u32Password2, u32Password3; EALLOW; /* TI recommended dummy read sequence */ u32Password0 = DcsmZ1Regs.Z1_CSMKEY0; u32Password1 = DcsmZ1Regs.Z1_CSMKEY1; u32Password2 = DcsmZ1Regs.Z1_CSMKEY2; u32Password3 = DcsmZ1Regs.Z1_CSMKEY3; /* * Forcing to use password variables to * avoid compilation warning */ u32Password0 = p32Data[0]; u32Password1 = p32Data[1]; u32Password2 = p32Data[2]; u32Password3 = p32Data[3]; /* Unlock the device */ DcsmZ1Regs.Z1_CSMKEY0 = u32Password0; DcsmZ1Regs.Z1_CSMKEY1 = u32Password1; DcsmZ1Regs.Z1_CSMKEY2 = u32Password2; DcsmZ1Regs.Z1_CSMKEY3 = u32Password3; EDIS; /* Check lock status */ if (DcsmZ1Regs.Z1_CR.bit.UNSECURE == 0) { u16Err = BOARD_LOCKED; } return u16Err;
I'm pointing to IPC because in the CPU2 boot sequence where the IPCBOOTMODE is chosen, the ti example code set the IPC flags to 0x80000001. I have modified this flag to indicate to CPU2 if it must load the bootloader or the application for example:
Before locking the memories, this was working perfectly. I suspect that the problem could be that the CPU2 is always trying to run the application (now an empty one).
What I see is once the cpu2 must take control of the bootloader, the communications are KO.
The other option I have in mind is the mapping of the peripherals. Could they be affected by the memory protection?
Hi,
The other option I have in mind is the mapping of the peripherals. Could they be affected by the memory protection?
No that is not impacted by memory protection.
Have you tested the same code before enabling the security and did it work fine?
Regards
Vivek Singh
Hi,
Vivek Singh said:Have you tested the same code before enabling the security and did it work fine?
Yes, it works fine without protection. With protection only works CPU1. So I'm doing something wrong during transition between CPU1 and CPU2. Both CPU executes exactly the same unlocking sequence.
Both CPUs are locked with the same password and zone
Did you check if you are able to unlock the CPU2 by entering the KEYs manually into CCS register view?
Yes, I have the same behaviour.
I did this:
CPU1 has been written but CPU2 is locked. I'm not sure if this test is valid because usually when I connect to both CPUs to the debugger, I have an initialisation function that checks the status of the CPUs:
case CPU_1: /* If CPU2 has already booted, return a fail to let the application * know that something is out of the ordinary. */ if ((IpcRegs.IPCBOOTSTS & (uint32_t)0xF) == C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK) { u16Ret = 1; } if (u16Ret == 0) { /* Wait until CPU02 control system boot ROM is ready to receive * CPU01 to CPU02 INT1 interrupts. */ while ((IpcRegs.IPCBOOTSTS & C2_BOOTROM_BOOTSTS_SYSTEM_READY ) != C2_BOOTROM_BOOTSTS_SYSTEM_READY ) { } while ((IpcRegs.IPCFLG.bit.IPC0 == (uint16_t)1) || (IpcRegs.IPCFLG.bit.IPC31 == (uint16_t)1)) { } /** Boot up CPU2 from FLASH */ IpcRegs.IPCBOOTMODE = (uint32_t)0xB; /* CPU01 To CPU02 IPC Command Register */ IpcRegs.IPCSENDCOM = BROM_IPC_EXECUTE_BOOTMODE_CMD; /* CPU01 to CPU02 IPC flag register */ IpcRegs.IPCSET.all = (uint32_t)0x8F0F0F01UL; } break; case CPU_2: IpcRegs.IPCSET.all = (uint32_t)0x55555555UL; break;
Usually the first check gives an error because CPU2 is booted up from the debugger so it is already running. To over come that, when the CPUs are not locked, before running the application I reset boths CPUs and then run the application, then is CPU1 who wakes up CPU2. The problem when CPUs are locked is that I cannot reset the CPUs before running because I loose the access to the memory.
Yes, I'm able to read Flash from both CPUs and I saw I can debug CPU1 even if the flash is locked. So the password on CPU2 via register view is working. I also saw the bit unsecure to 1 after writing the password.
I have tried to debug the bootloader. I was connected to both CPUs, CPU2 is in reset until CPU1 wakes it up. When CPUs reaches the IPC instructions to wake up CPU2, this is what I see:
Hello
The code is executed from secure memory if I'm not wrong. Both CPUs have the same secure flash sections and RAM memory in the same secure zone.
I cannot share our code completely, but there is attached a non-functional project. It builds but it probably do nothing because the serial protocol is removed. However you can hard-code the SerialBootProcess function to force any of the 4 cases I left which are the main functions accessing to the flash.boot_test.zip