According to SPRUGY5C (DSP Bootloader),
"The user should always provide the logic to populate the boot magic address of the
secondary CorePacs and also wake up the secondary CorePacs by triggering an IPC
interrupt for each of the secondary CorePacs. These portions will be executed only by
CorePac0."
So in my core0 code I run:
// in all cores void entryProxy(void ) { _c_int00(); } #endif #define CORE_X_ENTRY_ADDR(x) ((Uint32)(&entryProxy) | ((0x7 & x) << 24)) #define CORE_X_MAGIC_ADDR(x) (0x1087FFFC|(x<<24)) #define IPCGR(n) (0x02620240 + 4*n) #define IPCAR(n) (0x02620280 + 4*n) #define MAGIC_BOOT_KEYWORD_LOC 0x11800000 #define MAGIC_BOOT_KEYWORD 0xCACA0000 // in core0 /*set kicker reigsters */ *((volatile Uint32*)(0x02620038)) = 0x83e70b13; // KICK0, see tms320c6678.pdf *((volatile Uint32*)(0x0262003C)) = 0x95a4f1e0; // KICK1, see tms320c6678.pdf *((volatile Uint32*)(MAGIC_BOOT_KEYWORD_LOC))=MAGIC_BOOT_KEYWORD; for (int i=1; i<8; i++) { // compute magic address where jump-to address is written volatile uint32_t* const coreMagicAddr = (volatile uint32_t*)CORE_X_MAGIC_ADDR(i); SYSTEM_LOG("core %d magic address:0x%08x, and entry address :0x%08x\n", i, coreMagicAddr,CORE_X_ENTRY_ADDR(i)); // write the jump-to into the magic address *coreMagicAddr = CORE_X_ENTRY_ADDR(i); //compute the IPC register, which will wake up the core volatile uint32_t* const ipcgr = (volatile uint32_t*)IPCGR(i); SYSTEM_LOG("IPCGR%d address is 0x%08x\n", i, ipcgr); *ipcgr = 0x11; // wake up the core bootLog_logEvent(BL_EVENT_CORE_RELEASED, i, 0); }
This works to wake cores 1-7 *most* of the time. My problem is that some of the time some cores do not wake, most commonly cores 6 & 7 do not wake, but it can happen to any core.
I determine if cores wake in multiple different ways including semaphoring, logging, and using IPCGR/IPCAR's source field to set and reset a source bit (bit 4).
int main(int argc, char *argv[]) { // Clear the IPCGR/IPCAR SRCS/SRCSS bit of the interrupt that woke core1-7 if (0 != platform_get_coreid()) { volatile uint32_t* const ipcar = (volatile uint32_t*)IPCAR(platform_get_coreid()); *ipcar = 0x10; // writing '1' clears the bit }
I have also have a loop that tries every 0.5 sec to try to write the magic address again and issue a new IPC to a core that has not woken, but that still does not resolve my issue with occasional unwoken cores.
How can I reliably wake cores 1 to 7?
Thanks,
Katia