3434//!
3535//! ### Functions
3636//!
37- //! * `kmain ` - the `extern "C"` entry point to your application.
37+ //! * `boot_core ` - the `extern "C"` entry point to your application.
3838//!
3939//! Expected prototype:
4040//!
4141//! ```rust
4242//! #[unsafe(no_mangle)]
43- //! extern "C" fn kmain( ) -> !;
43+ //! extern "C" fn boot_core(cpu_id: u32 ) -> !;
4444//! ```
4545//!
4646//! * `_svc_handler` - an `extern "C"` function to call when an SVC Exception
130130//!
131131//! * `_vector_table` - the start of the interrupt vector table
132132//! * `_default_start` - the default Reset handler, that sets up some stacks and
133- //! calls an `extern "C"` function called `kmain `.
133+ //! calls an `extern "C"` function called `boot_core `.
134134//! * `_asm_default_fiq_handler` - an FIQ handler that just spins
135135//! * `_asm_default_handler` - an exception handler that just spins
136136//! * `_asm_svc_handler` - assembly language trampoline for SVC Exceptions that
@@ -480,7 +480,7 @@ macro_rules! fpu_enable {
480480
481481// Start-up code for Armv7-R (and Armv8-R once we've left EL2)
482482//
483- // We set up our stacks and `kmain ` in system mode.
483+ // We set up our stacks and `boot_core ` in system mode.
484484core:: arch:: global_asm!(
485485 r#"
486486 .section .text.startup
@@ -549,7 +549,10 @@ core::arch::global_asm!(
549549 b 0b
550550 1:
551551 // Jump to application
552- bl kmain
552+ // Load CPU ID, we are CPU0
553+ ldr r0, =0x0
554+ // Jump to application
555+ bl boot_core
553556 // In case the application returns, loop forever
554557 b .
555558 .size _el1_start, . - _el1_start
@@ -615,6 +618,27 @@ core::arch::global_asm!(
615618 .global _default_start
616619 .type _default_start, %function
617620 _default_start:
621+ // only allow cpu0 through for initialization
622+ // Read MPIDR
623+ mrc p15,0,r1,c0,c0,5
624+ // Extract CPU ID bits by reading affinity level 0.
625+ // For single-core systems, this should always be 0.
626+ mov r2, #0xFFFF
627+ and r1, r1, r2
628+ cmp r1, #0
629+ beq 1f
630+ 0:
631+ wfe
632+ // When Core 0 emits a SEV, the other cores will wake up.
633+ // Load CPU ID.
634+ mrc p15,0,r0,c0,c0,5
635+ // Extract CPU ID bits.
636+ mov r2, #0xFFFF
637+ and r0, r0, r2
638+ bl boot_core
639+ // Should never returns, loop permanently here.
640+ b .
641+ 1:
618642 ldr pc, =_el1_start
619643 .size _default_start, . - _default_start
620644 "#
@@ -625,7 +649,7 @@ core::arch::global_asm!(
625649// There's only one Armv8-R CPU (the Cortex-R52) and the FPU is mandatory, so we
626650// always enable it.
627651//
628- // We boot into EL2, set up a stack pointer, and run `kmain ` in EL1.
652+ // We boot into EL2, set up a stack pointer, and run `boot_core ` in EL1.
629653#[ cfg( arm_architecture = "v8-r" ) ]
630654core:: arch:: global_asm!(
631655 r#"
@@ -635,6 +659,27 @@ core::arch::global_asm!(
635659 .global _default_start
636660 .type _default_start, %function
637661 _default_start:
662+ // only allow cpu0 through for initialization
663+ // Read MPIDR
664+ mrc p15,0,r1,c0,c0,5
665+ // Extract CPU ID bits by reading affinity level 0.
666+ // For single-core systems, this should always be 0.
667+ mov r2, #0xFFFF
668+ and r1, r1, r2
669+ cmp r1, #0
670+ beq 1f
671+ 0:
672+ wfe
673+ // When Core 0 emits a SEV, the other cores will wake up.
674+ // Load CPU ID
675+ mrc p15, 0, r0, c0, c0, 5
676+ // Extract CPU ID bits.
677+ mov r2, #0xFFFF
678+ and r0, r0, r2
679+ bl boot_core
680+ // Should never returns, loop permanently here.
681+ b .
682+ 1:
638683 // Are we in EL2? If not, skip the EL2 setup portion
639684 mrs r0, cpsr
640685 and r0, r0, 0x1F
@@ -651,10 +696,10 @@ core::arch::global_asm!(
651696 orr r0, r0, r1
652697 mcr p15, 4, r0, c1, c0, 1
653698 // Program the SPSR - enter system mode (0x1F) in Arm mode with IRQ, FIQ masked
654- mov r0, {sys_mode}
655- msr spsr_hyp, r0
656- adr r0, 1f
657- msr elr_hyp, r0
699+ mov r0, {sys_mode}
700+ msr spsr_hyp, r0
701+ adr r0, 1f
702+ msr elr_hyp, r0
658703 dsb
659704 isb
660705 eret
0 commit comments