diff --git a/cortex-a-rt/src/lib.rs b/cortex-a-rt/src/lib.rs index 4a6cc09..22b3919 100644 --- a/cortex-a-rt/src/lib.rs +++ b/cortex-a-rt/src/lib.rs @@ -436,7 +436,7 @@ core::arch::global_asm!( b done not_thumb: // Subtract 4 from LR (ARM mode) - subs lr, lr, #4 + subs lr, lr, #4 done: // state save from compiled code srsfd sp!, {und_mode} @@ -552,25 +552,26 @@ core::arch::global_asm!( .global _default_start .type _default_start, %function _default_start: - // only allow cpu0 through for initialization // Read MPIDR - mrc p15,0,r1,c0,c0,5 + mrc p15, 0, r1, c0, c0, 5 // Extract CPU ID bits. For single-core systems, this should always be 0 - and r1, r1, #0x3 - cmp r1, #0 - beq initialize - wait_loop: + mov r2, #0xFFFF + and r1, r1, r2 + cmp r1, #0 + beq 1f + 0: wfe // When Core 0 emits a SEV, the other cores will wake up. - // Load CPU ID, we are CPU0 - mrc p15,0,r0,c0,c0,5 + // Load CPU ID. + mrc p15, 0, r0, c0, c0, 5 // Extract CPU ID bits. - and r0, r0, #0x3 + mov r2, #0xFFFF + and r0, r0, r2 bl boot_core // Should never returns, loop permanently here. - b . - initialize: + b . + 1: // Set up stacks. ldr r0, =_stack_top // Set stack pointer (right after) and mask interrupts for for UND mode (Mode 0x1B) diff --git a/cortex-r-rt/CHANGELOG.md b/cortex-r-rt/CHANGELOG.md index 7deeca6..aff860d 100644 --- a/cortex-r-rt/CHANGELOG.md +++ b/cortex-r-rt/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] +## Changed + +- Entry point renamed from `kmain` to `boot_core`. `boot_core` expects one argument + which will be the CPU ID. + ## Added - Added ABT und UND mode stack setup. diff --git a/cortex-r-rt/src/lib.rs b/cortex-r-rt/src/lib.rs index 3312eda..244980e 100644 --- a/cortex-r-rt/src/lib.rs +++ b/cortex-r-rt/src/lib.rs @@ -34,13 +34,13 @@ //! //! ### Functions //! -//! * `kmain` - the `extern "C"` entry point to your application. +//! * `boot_core` - the `extern "C"` entry point to your application. //! //! Expected prototype: //! //! ```rust //! #[unsafe(no_mangle)] -//! extern "C" fn kmain() -> !; +//! extern "C" fn boot_core(cpu_id: u32) -> !; //! ``` //! //! * `_svc_handler` - an `extern "C"` function to call when an SVC Exception @@ -130,7 +130,7 @@ //! //! * `_vector_table` - the start of the interrupt vector table //! * `_default_start` - the default Reset handler, that sets up some stacks and -//! calls an `extern "C"` function called `kmain`. +//! calls an `extern "C"` function called `boot_core`. //! * `_asm_default_fiq_handler` - an FIQ handler that just spins //! * `_asm_default_handler` - an exception handler that just spins //! * `_asm_svc_handler` - assembly language trampoline for SVC Exceptions that @@ -369,7 +369,7 @@ core::arch::global_asm!( tst r4, {t_bit} // If not in Thumb mode, branch to not_thumb beq not_thumb - subs lr, lr, #2 + subs lr, lr, #2 b done not_thumb: // Subtract 4 from LR (ARM mode) @@ -399,7 +399,7 @@ done: .type _asm_default_prefetch_handler, %function _asm_default_prefetch_handler: // Subtract 4 from the stored LR, see p.1212 of the ARMv7-A architecture manual. - subs lr, lr, #4 + subs lr, lr, #4 // state save from compiled code srsfd sp!, {abt_mode} "#, @@ -424,7 +424,7 @@ done: .type _asm_default_abort_handler, %function _asm_default_abort_handler: // Subtract 8 from the stored LR, see p.1214 of the ARMv7-A architecture manual. - subs lr, lr, #8 + subs lr, lr, #8 // state save from compiled code srsfd sp!, {abt_mode} "#, @@ -480,7 +480,7 @@ macro_rules! fpu_enable { // Start-up code for Armv7-R (and Armv8-R once we've left EL2) // -// We set up our stacks and `kmain` in system mode. +// We set up our stacks and `boot_core` in system mode. core::arch::global_asm!( r#" .section .text.startup @@ -549,7 +549,10 @@ core::arch::global_asm!( b 0b 1: // Jump to application - bl kmain + // Load CPU ID, we are CPU0 + ldr r0, =0x0 + // Jump to application + bl boot_core // In case the application returns, loop forever b . .size _el1_start, . - _el1_start @@ -615,6 +618,27 @@ core::arch::global_asm!( .global _default_start .type _default_start, %function _default_start: + // only allow cpu0 through for initialization + // Read MPIDR + mrc p15, 0, r1, c0, c0, 5 + // Extract CPU ID bits by reading affinity level 0. + // For single-core systems, this should always be 0. + mov r2, #0xFFFF + and r1, r1, r2 + cmp r1, #0 + beq 1f + 0: + wfe + // When Core 0 emits a SEV, the other cores will wake up. + // Load CPU ID. + mrc p15, 0, r0, c0, c0, 5 + // Extract CPU ID bits. + mov r2, #0xFFFF + and r0, r0, r2 + bl boot_core + // Should never returns, loop permanently here. + b . + 1: ldr pc, =_el1_start .size _default_start, . - _default_start "# @@ -625,7 +649,7 @@ core::arch::global_asm!( // There's only one Armv8-R CPU (the Cortex-R52) and the FPU is mandatory, so we // always enable it. // -// We boot into EL2, set up a stack pointer, and run `kmain` in EL1. +// We boot into EL2, set up a stack pointer, and run `boot_core` in EL1. #[cfg(arm_architecture = "v8-r")] core::arch::global_asm!( r#" @@ -635,6 +659,27 @@ core::arch::global_asm!( .global _default_start .type _default_start, %function _default_start: + // only allow cpu0 through for initialization + // Read MPIDR + mrc p15, 0, r1, c0, c0, 5 + // Extract CPU ID bits by reading affinity level 0. + // For single-core systems, this should always be 0. + mov r2, #0xFFFF + and r1, r1, r2 + cmp r1, #0 + beq 1f + 0: + wfe + // When Core 0 emits a SEV, the other cores will wake up. + // Load CPU ID + mrc p15, 0, r0, c0, c0, 5 + // Extract CPU ID bits. + mov r2, #0xFFFF + and r0, r0, r2 + bl boot_core + // Should never returns, loop permanently here. + b . + 1: // Are we in EL2? If not, skip the EL2 setup portion mrs r0, cpsr and r0, r0, 0x1F @@ -651,10 +696,10 @@ core::arch::global_asm!( orr r0, r0, r1 mcr p15, 4, r0, c1, c0, 1 // Program the SPSR - enter system mode (0x1F) in Arm mode with IRQ, FIQ masked - mov r0, {sys_mode} - msr spsr_hyp, r0 - adr r0, 1f - msr elr_hyp, r0 + mov r0, {sys_mode} + msr spsr_hyp, r0 + adr r0, 1f + msr elr_hyp, r0 dsb isb eret diff --git a/examples/mps3-an536/src/bin/generic_timer.rs b/examples/mps3-an536/src/bin/generic_timer.rs index 4d19b59..b78d336 100644 --- a/examples/mps3-an536/src/bin/generic_timer.rs +++ b/examples/mps3-an536/src/bin/generic_timer.rs @@ -12,13 +12,17 @@ use semihosting::println; /// /// It is called by the start-up code in `cortex-m-rt`. #[no_mangle] -pub extern "C" fn kmain() { - main(); - semihosting::process::exit(0); +pub extern "C" fn boot_core(cpu_id: u32) -> ! { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } } /// Let's test some timers! -fn main() { +fn main() -> ! { use cortex_ar::generic_timer::{El1PhysicalTimer, El1VirtualTimer, GenericTimer}; let cntfrq = cortex_ar::register::Cntfrq::read().0; println!("cntfrq = {:.03} MHz", cntfrq as f32 / 1_000_000.0); @@ -64,4 +68,5 @@ fn main() { timer.countdown() as i32 ); } + semihosting::process::exit(0) } diff --git a/examples/mps3-an536/src/bin/gic.rs b/examples/mps3-an536/src/bin/gic.rs index ef8b331..d32d5c2 100644 --- a/examples/mps3-an536/src/bin/gic.rs +++ b/examples/mps3-an536/src/bin/gic.rs @@ -24,13 +24,18 @@ const GICR_BASE_OFFSET: usize = 0x0010_0000usize; /// /// It is called by the start-up code in `cortex-m-rt`. #[no_mangle] -pub extern "C" fn kmain() { - main(); +pub extern "C" fn boot_core(cpu_id: u32) -> ! { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } } /// The main function of our Rust application. /// -/// Called by [`kmain`]. +/// Called by [boot_core]. fn main() -> ! { // Get the GIC address by reading CBAR let periphbase = cortex_ar::register::ImpCbar::read().periphbase(); diff --git a/examples/mps3-an536/src/bin/hello.rs b/examples/mps3-an536/src/bin/hello.rs index 52b27d4..7161d70 100644 --- a/examples/mps3-an536/src/bin/hello.rs +++ b/examples/mps3-an536/src/bin/hello.rs @@ -12,13 +12,18 @@ use semihosting::println; /// /// It is called by the start-up code in `cortex-m-rt`. #[no_mangle] -pub extern "C" fn kmain() { - main(); +pub extern "C" fn boot_core(cpu_id: u32) -> ! { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } } /// The main function of our Rust application. /// -/// Called by [`kmain`]. +/// Called by [boot_core]. fn main() -> ! { let x = 1.0f64; let y = x * 2.0; diff --git a/examples/mps3-an536/src/bin/registers.rs b/examples/mps3-an536/src/bin/registers.rs index 97ae37c..7051330 100644 --- a/examples/mps3-an536/src/bin/registers.rs +++ b/examples/mps3-an536/src/bin/registers.rs @@ -12,13 +12,18 @@ use semihosting::println; /// /// It is called by the start-up code in `cortex-m-rt`. #[no_mangle] -pub extern "C" fn kmain() { - main(); +pub extern "C" fn boot_core(cpu_id: u32) -> ! { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } } /// The entry-point to the Rust application. /// -/// Called by [`kmain`]. +/// Called by [boot_core]. pub fn main() -> ! { chip_info(); #[cfg(arm_architecture = "v7-r")] diff --git a/examples/mps3-an536/src/bin/svc.rs b/examples/mps3-an536/src/bin/svc.rs index 2483692..ae18081 100644 --- a/examples/mps3-an536/src/bin/svc.rs +++ b/examples/mps3-an536/src/bin/svc.rs @@ -12,13 +12,18 @@ use semihosting::println; /// /// It is called by the start-up code in `cortex-m-rt`. #[no_mangle] -pub extern "C" fn kmain() { - main(); +pub extern "C" fn boot_core(cpu_id: u32) -> ! { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } } /// The main function of our Rust application. /// -/// Called by [`kmain`]. +/// Called by [boot_core]. pub fn main() -> ! { let x = 1; let y = x + 1; diff --git a/examples/versatileab/reference/hello-armv7a-none-eabi.out b/examples/versatileab/reference/hello-armv7a-none-eabi.out index 04a1a27..e632548 100644 --- a/examples/versatileab/reference/hello-armv7a-none-eabi.out +++ b/examples/versatileab/reference/hello-armv7a-none-eabi.out @@ -3,7 +3,7 @@ PANIC: PanicInfo { message: I am an example panic, location: Location { file: "src/bin/hello.rs", - line: 19, + line: 30, col: 5, }, can_unwind: true, diff --git a/examples/versatileab/reference/hello-armv7r-none-eabi.out b/examples/versatileab/reference/hello-armv7r-none-eabi.out index 04a1a27..e632548 100644 --- a/examples/versatileab/reference/hello-armv7r-none-eabi.out +++ b/examples/versatileab/reference/hello-armv7r-none-eabi.out @@ -3,7 +3,7 @@ PANIC: PanicInfo { message: I am an example panic, location: Location { file: "src/bin/hello.rs", - line: 19, + line: 30, col: 5, }, can_unwind: true, diff --git a/examples/versatileab/reference/hello-armv7r-none-eabihf.out b/examples/versatileab/reference/hello-armv7r-none-eabihf.out index 04a1a27..e632548 100644 --- a/examples/versatileab/reference/hello-armv7r-none-eabihf.out +++ b/examples/versatileab/reference/hello-armv7r-none-eabihf.out @@ -3,7 +3,7 @@ PANIC: PanicInfo { message: I am an example panic, location: Location { file: "src/bin/hello.rs", - line: 19, + line: 30, col: 5, }, can_unwind: true, diff --git a/examples/versatileab/reference/svc-armv7a-none-eabi.out b/examples/versatileab/reference/svc-armv7a-none-eabi.out index b6eabfe..a1221eb 100644 --- a/examples/versatileab/reference/svc-armv7a-none-eabi.out +++ b/examples/versatileab/reference/svc-armv7a-none-eabi.out @@ -6,7 +6,7 @@ PANIC: PanicInfo { message: I am an example panic, location: Location { file: "src/bin/svc.rs", - line: 22, + line: 33, col: 5, }, can_unwind: true, diff --git a/examples/versatileab/reference/svc-armv7r-none-eabi.out b/examples/versatileab/reference/svc-armv7r-none-eabi.out index b6eabfe..a1221eb 100644 --- a/examples/versatileab/reference/svc-armv7r-none-eabi.out +++ b/examples/versatileab/reference/svc-armv7r-none-eabi.out @@ -6,7 +6,7 @@ PANIC: PanicInfo { message: I am an example panic, location: Location { file: "src/bin/svc.rs", - line: 22, + line: 33, col: 5, }, can_unwind: true, diff --git a/examples/versatileab/reference/svc-armv7r-none-eabihf.out b/examples/versatileab/reference/svc-armv7r-none-eabihf.out index b6eabfe..a1221eb 100644 --- a/examples/versatileab/reference/svc-armv7r-none-eabihf.out +++ b/examples/versatileab/reference/svc-armv7r-none-eabihf.out @@ -6,7 +6,7 @@ PANIC: PanicInfo { message: I am an example panic, location: Location { file: "src/bin/svc.rs", - line: 22, + line: 33, col: 5, }, can_unwind: true, diff --git a/examples/versatileab/src/bin/abt-exception.rs b/examples/versatileab/src/bin/abt-exception.rs index 864bcd5..c56d53c 100644 --- a/examples/versatileab/src/bin/abt-exception.rs +++ b/examples/versatileab/src/bin/abt-exception.rs @@ -11,10 +11,21 @@ use versatileab as _; use semihosting::println; -versatileab::entry_point!(); - static COUNTER: AtomicU32 = AtomicU32::new(0); +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code in the runtime crate. +#[no_mangle] +pub extern "C" fn boot_core(cpu_id: u32) { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } +} + /// The main function of our Rust application. #[export_name = "main"] #[allow(unreachable_code)] diff --git a/examples/versatileab/src/bin/hello.rs b/examples/versatileab/src/bin/hello.rs index aade0db..98e8d31 100644 --- a/examples/versatileab/src/bin/hello.rs +++ b/examples/versatileab/src/bin/hello.rs @@ -8,7 +8,18 @@ use versatileab as _; use semihosting::println; -versatileab::entry_point!(); +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code in the runtime crate. +#[no_mangle] +pub extern "C" fn boot_core(cpu_id: u32) { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } +} /// The main function of our Rust application. #[export_name = "main"] diff --git a/examples/versatileab/src/bin/prefetch-exception.rs b/examples/versatileab/src/bin/prefetch-exception.rs index 9b1866f..e33c061 100644 --- a/examples/versatileab/src/bin/prefetch-exception.rs +++ b/examples/versatileab/src/bin/prefetch-exception.rs @@ -11,10 +11,21 @@ use versatileab as _; use semihosting::println; -versatileab::entry_point!(); - static COUNTER: AtomicU32 = AtomicU32::new(0); +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code in the runtime crate. +#[no_mangle] +pub extern "C" fn boot_core(cpu_id: u32) { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } +} + /// The main function of our Rust application. #[export_name = "main"] fn main() -> ! { diff --git a/examples/versatileab/src/bin/registers.rs b/examples/versatileab/src/bin/registers.rs index 0e0db57..bb7d2b4 100644 --- a/examples/versatileab/src/bin/registers.rs +++ b/examples/versatileab/src/bin/registers.rs @@ -8,7 +8,18 @@ use versatileab as _; use semihosting::println; -versatileab::entry_point!(); +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code in the runtime crate. +#[no_mangle] +pub extern "C" fn boot_core(cpu_id: u32) { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } +} /// The entry-point to the Rust application. /// diff --git a/examples/versatileab/src/bin/svc.rs b/examples/versatileab/src/bin/svc.rs index 54c9dc1..82c8540 100644 --- a/examples/versatileab/src/bin/svc.rs +++ b/examples/versatileab/src/bin/svc.rs @@ -8,7 +8,18 @@ use versatileab as _; use semihosting::println; -versatileab::entry_point!(); +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code. +#[no_mangle] +pub extern "C" fn boot_core(cpu_id: u32) { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } +} /// The main function of our Rust application. #[export_name = "main"] diff --git a/examples/versatileab/src/bin/undef-exception.rs b/examples/versatileab/src/bin/undef-exception.rs index b98eca8..b152866 100644 --- a/examples/versatileab/src/bin/undef-exception.rs +++ b/examples/versatileab/src/bin/undef-exception.rs @@ -10,10 +10,21 @@ use versatileab as _; use semihosting::println; -versatileab::entry_point!(); - static COUNTER: AtomicU32 = AtomicU32::new(0); +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code in the runtime crate. +#[no_mangle] +pub extern "C" fn boot_core(cpu_id: u32) { + match cpu_id { + 0 => { + main(); + } + _ => panic!("unexpected CPU ID {}", cpu_id), + } +} + /// The main function of our Rust application. #[export_name = "main"] fn main() -> ! { diff --git a/examples/versatileab/src/lib.rs b/examples/versatileab/src/lib.rs index 0ecabf0..d931296 100644 --- a/examples/versatileab/src/lib.rs +++ b/examples/versatileab/src/lib.rs @@ -11,34 +11,6 @@ use cortex_r_rt as _; #[cfg(arm_architecture = "v8-r")] compile_error!("This example/board is not compatible with the ARMv8-R architecture"); -#[macro_export] -macro_rules! entry_point { - () => { - /// The entry-point to the Rust application. - /// - /// It is called by the start-up code in `cortex-m-rt`. - #[no_mangle] - #[cfg(arm_profile = "r")] - pub extern "C" fn kmain() { - main(); - } - - /// The entry-point to the Rust application. - /// - /// It is called by the start-up code in `cortex-a-rt`. - #[no_mangle] - #[cfg(arm_profile = "a")] - pub extern "C" fn boot_core(cpu_id: u32) { - match cpu_id { - 0 => { - main(); - } - _ => panic!("unexpected CPU ID {}", cpu_id), - } - } - }; -} - /// Called when the application raises an unrecoverable `panic!`. /// /// Prints the panic to the console and then exits QEMU using a semihosting