Hello,
We have written a custom boot that setups and runs on core 0 on the P2020 processor. Our boot shall enable the second core and simply put it in an infinite loop but we are having problems getting it to run correctly.
Setup
The execution of core 0 is as follows:
- Core 0 is setup and configured. A LAW is setup for the complete RAM.
- Defines a 4096 byte area at end of RAM (starting at 0x3FFFF000) to use as boot page for CPU 1, and copies the CPU 1 start up code to that area., see code below.
- Updates the boot page translation register (Reset_BPTR)
- Boot page translation is enabled by setting EN bit to 1
- Translation address is set to the boot page start address shifted 12 bits.
- Write to register ECM_EEBPCR to set bit CPU1_EN to enable core 1
- Currently core 0 then enters an infinite loop doing nothing.
The setup for core 1 performs initialisations in the StartSecondaryCpu assembly function. For example a TLB entry, stack pointer and interrupt registers are setup. See attached code.
Output
The boot was programmed and the boot was executed normally. Thereafter, the programmed boot was debugged with CodeWarrior and the CodeWarrior TAP. Performing an attach it was possible to connect to both cores of the P2020 processor.
We have verified for Core 0 that:
- The Reset_BPTR register is set to: 0x8003ffff
- Th ECM_EEBPCR register value goes from 0x01000000 to 0x03000000
- The instructions for assembly function StartSecondaryCpu was successfully copied to the BootPageAddress
Continuing core 0 then runs into an infinite loop as intended.
When attaching to Core 1 and pausing, we see that it is stuck at instructions at 0xFFFFF114, from cleanup_glue() reent.c35 0x00000000, see attached image. This address 0xFFFFF114 is part of the default boot ROM which we do not want to exectue from. Core 1 should be stuck in an infinite loop as part of the StartSecondaryCpu assembly function but it is not. While core 1 is paused with the debugger the following was observed:
- Reading the memory for the core 1 stack pointer showed it had been initialized.
- Looking at the TLB entry registers showed that it was setup as intended.
- IVPR, IVOR registers updated correctly
Thus seemingly the setup code for core 1, in StartSecondaryCpu assembly function, is being run.

Setup code running on core 0
#define SET_BIT_REG32(bit) (uint32_t)(1UL << (31UL - (bit)))
#define BPTR_BOOT_PAGE_SHIFT 12U
#define Reset_BPTR_EN_BIT 0U
#define HwMemMap_Ccsr_ECM_EEBPCR ((uint32_t) 0x000001010UL)
#define ECM_EEBPCR_CPU1_EN_BIT 6U
/* Calculate the boot start page address */
uint32_t BootPageSize = 4096;
uint32_t BootPageStartAddress = 0x40000000; /* 0x40000000 */
uint32_t BootPageAddress = BootPageStartAddress - BootPageSize;
/* Copy boot. */
memcpy ((void *) BootPageAddress, &StartSecondaryCpu, BootPageSize);
/* Setup Reset_BPTR register
- The boot page translation enable is set to 1
- The translation for boot page is set to the BootPageAddress shifted 12
*/
Data = ((uint32_t)BootPageAddress >> BPTR_BOOT_PAGE_SHIFT) | SET_BIT_REG32(Reset_BPTR_EN_BIT);
HwMemMap_WriteCcsrReg (HwMemMap_Ccsr_Reset_BPTR, Data);
/* Start core 1 by setting bit CPU1_EN in ECM_EEBPCR register */
HwMemMap_ReadCcsrReg (HwMemMap_Ccsr_ECM_EEBPCR, &Data);
HwMemMap_WriteCcsrReg (HwMemMap_Ccsr_ECM_EEBPCR, Data | (SET_BIT_REG32(ECM_EEBPCR_CPU1_EN_BIT)) );
Code for core 1
FUNC_START StartSecondaryCpu
.align 12
__secondary_cpu:
/* Enable MCHK and debug */
lis r3, 0x0200
ori r3, r3, 0x1200
mtmsr r3
/* Manage L1 Caches */
li r3, 0x2
mtspr 0x3F2,r3 /* invalidate d-cache */
mtspr 0x3F3,r3 /* invalidate i-cache */
/* Setup TLB */
lis r5, 0x1000 /* entry's index */
ori r5, r5, 0x0000
mtspr MAS0, r5
lis r5, 0xC000 /* entry valid and protected */
ori r5, r5, 0x0a00 /* size (4^TSIZE KiB) */
mtspr MAS1, r5
lis r5, 0x0000 /* effective page number */
ori r5, r5, 0x0008 /* write-through | cache inhibited | mem coherency | guarded | endianness */
mtspr MAS2, r5
lis r5, 0x0000 /* real page number */
ori r5, r5, 0x003f /* user permissions */
mtspr MAS3, r5
tlbwe
msync
isync
/* Setup stack */
lis r1, _stack_addr_cpu1@ha
addi r1, r1, _stack_addr_cpu1@l
/* Prepare a terminating stack record. */
stwu r1, -16(r1) /* e500 required SP to always be 16-byte aligned */
li r0, 0x0000 /* load up r0 with 0x00000000 */
stw r0, 0(r1) /* SysVr4 EABI Supp indicated that initial back chain word should be null */
li r0, -1 /* load up r0 with 0xFFFFFFFF */
stw r0, 4(r1) /* Make an illegal return address of 0xFFFFFFFF */
/* Interrupts */
lis r3, 0x3E00 /* 0x3E000000 16 MSB */
addi r3, r3, 0x0000 /* 0x3E000000 16 LSB */
mtspr IVPR, r3
lis r4, 0x0000
lis r5, 0x0000
ori r4, r5, 0x0100
mtspr IVOR0, r4
… /* [repeating] */
ori r4, r5, 0x1900
mtspr IVOR35, r4
/* Put the second cpu in an infinite loop */
loop_inf:
b loop_inf
/* Fill in the empty space. The actual reset vector is the last word of the page */
__secondary_cpu_end:
.space 4092 - (__secondary_cpu_end - __secondary_cpu)
__secondary_reset_vector:
b __secondary_cpu
Question
What are we missing in the setup for enabling core 1 and getting it to run correectly?
Thank you for your time!