I am developing a simple kernel for Raspberry Pi 3B intended to run basic tasks on all four cores. However, it appears that only the primary core is running kernel_init, and the other cores never start. Here’s the relevant part of my code:
.globl _start
_start:
mrs x0, mpidr_el1
and x0, x0,#0xFF // Check processor id
cbz x0, el1_entry // Hang for all non-primary CPU
b proc_hang
proc_hang:
wfe
b proc_hang
el1_entry:
adr x0, bss_begin
adr x1, bss_end
sub x1, x1, x0
bl memzero
mov sp, #LOW_MEMORY
// Initialize and start secondary cores on Raspberry Pi 3
ldr x1, =start_core_1 // Address to jump to for secondary cores
ldr x2, =0xE0 // Mailbox register for Core 1
str x1, [x2]
ldr x1, =start_core_2 // Address to jump to for secondary cores
ldr x2, =0xE8 // Mailbox register for Core 2
str x1, [x2]
ldr x1, =start_core_3 // Address to jump to for secondary cores
ldr x2, =0xF0 // Mailbox register for Core 3
str x1, [x2]
sev // Send event to wake up all cores
bl kernel_init
b proc_hang // should never come here
start_core_1:
ldr x1, =LOW_MEMORY
ldr x2, =PAGE_SIZE
add sp, x1, x2 // sp = LOW_MEMORY + PAGE_SIZE
bl kernel_init
b start_core_1
start_core_2:
ldr x1, =LOW_MEMORY
ldr x2, =PAGE_SIZE
add sp, x1, x2, lsl #1 // sp = LOW_MEMORY + 2*PAGE_SIZE
bl kernel_init
b start_core_2
start_core_3:
ldr x1, =LOW_MEMORY
ldr x2, =PAGE_SIZE
mov x3, #3
mul x2, x2, x3 // x2 = 3 * PAGE_SIZE
add sp, x1, x2 // sp = LOW_MEMORY + 3*PAGE_SIZE
bl kernel_init
b start_core_3
extern "C" void kernel_init(void)
{
uart_init();
init_printf(0, putc);
printf("processor ID: %dn", get_core_number());
while (1)
{
uart_send(uart_recv());
}
}
.global get_core_number
get_core_number:
mrs x0, MPIDR_EL1 // Read MPIDR_EL1 into x0
and x0, x0, #0xff // Check processor id
ret // Return, with the result in x0
Despite writing to the correct mailbox registers to wake up the secondary cores, the UART output shows only “processor ID: 0”, and it seems like the secondary core-specific code never starts running. Based on my understanding of multicore programming, the output should be something like this if all of the cores are running:
processor ID: 0
processor ID: 2
processor ID: 1
processor ID: 3 (in random order of course)
I have tried setting different stack pointers for each core, as seen in the initialization code for start_core_X, but still, only the primary core seems active.
What I have tried is just doing something like this:
_start:
adr x0, bss_begin
adr x1, bss_end
sub x1, x1, x0
bl memzero
mov sp, #LOW_MEMORY
bl kernel_init
With this setup, I expected all cores to execute kernel_init as there’s no logic to differentiate between cores (like checking MPIDR_EL1 to filter out non-primary cores). However, it seems that only the primary core is executing kernel_init, based on the output I’m getting:
processor ID: 0
Any insights or suggestions on why this is happening or how to ensure all cores run the initialization code would be greatly appreciated!