From 40b3d2e057d7f3e2b430b31d59ef153538b2fd72 Mon Sep 17 00:00:00 2001 From: morgan Date: Tue, 14 Nov 2023 15:01:27 +0800 Subject: [PATCH 1/4] Add interrupt exit support to interrupt_handler interrupt_handler: preserve registers and load them after $name2 fn interrupt_handler: allow $name2 fn to return --- libcortex_a9/src/lib.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/libcortex_a9/src/lib.rs b/libcortex_a9/src/lib.rs index aa847a3..e443bad 100644 --- a/libcortex_a9/src/lib.rs +++ b/libcortex_a9/src/lib.rs @@ -36,7 +36,9 @@ pub fn notify_spin_lock() { } #[macro_export] -/// Interrupt handler, which setup the stack and jump to actual interrupt handler. +/// Interrupt handler, which setup the stack and preserve registers before jumping to actual interrupt handler. +/// Registers r0-r12, PC, SP and CPSR are restored after the actual handler. +/// /// - `name` is the name of the interrupt, should be the same as the one defined in vector table. /// - `name2` is the name for the actual handler, should be different from name. /// - `stack0` is the stack for the interrupt handler when called from core0. @@ -44,8 +46,7 @@ pub fn notify_spin_lock() { /// - `body` is the body of the actual interrupt handler, should be a normal unsafe rust function /// body. /// -/// Note that the interrupt handler would use the same stack as normal programs by default, so -/// interrupt handlers should not return to normal program or it may corrupt the stack. +/// Note that the interrupt handler would use the same stack as normal programs by default. macro_rules! interrupt_handler { ($name:ident, $name2:ident, $stack0:ident, $stack1:ident, $body:block) => { #[link_section = ".text.boot"] @@ -54,19 +55,27 @@ macro_rules! interrupt_handler { pub unsafe extern "C" fn $name() -> ! { asm!( // setup SP, depending on CPU 0 or 1 + // and preserve registers + "SUB lr, lr, #4", + "STMFD sp!, {{r0-r12, lr}}", "mrc p15, #0, r0, c0, c0, #5", concat!("movw r1, :lower16:", stringify!($stack0)), concat!("movt r1, :upper16:", stringify!($stack0)), "tst r0, #3", concat!("movwne r1, :lower16:", stringify!($stack1)), concat!("movtne r1, :upper16:", stringify!($stack1)), + "mov r0, sp", "mov sp, r1", + "push {{r0, r1}}", // for stack alignment concat!("bl ", stringify!($name2)), + "pop {{r0, r1}}", + "mov sp, r0", + "LDMFD sp!, {{r0-r12, pc}}^", // caret ^ : copy SPSR to the CPSR options(noreturn) ); } #[no_mangle] - pub unsafe extern "C" fn $name2() -> ! $body + pub unsafe extern "C" fn $name2() $body }; } -- 2.44.1 From 8d204cf0eb28948bde0cbeda07aabad3e8a3c0af Mon Sep 17 00:00:00 2001 From: morgan Date: Tue, 14 Nov 2023 15:01:37 +0800 Subject: [PATCH 2/4] Add core0 interrupt return test --- experiments/src/main.rs | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/experiments/src/main.rs b/experiments/src/main.rs index 05e1f06..41278aa 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -56,19 +56,29 @@ extern "C" { static CORE1_RESTART: AtomicBool = AtomicBool::new(false); interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, { - if MPIDR.read().cpu_id() == 1{ - let mpcore = mpcore::RegisterBlock::mpcore(); - let mut gic = gic::InterruptController::gic(mpcore); - let id = gic.get_interrupt_id(); - if id.0 == 0 { - gic.end_interrupt(id); - asm::exit_irq(); - SP.write(&mut __stack1_start as *mut _ as u32); - asm::enable_irq(); - CORE1_RESTART.store(false, Ordering::Relaxed); - notify_spin_lock(); - main_core1(); - } + let mpcore = mpcore::RegisterBlock::mpcore(); + let mut gic = gic::InterruptController::gic(mpcore); + let id = gic.get_interrupt_id(); + match MPIDR.read().cpu_id(){ + 0 => { + if id.0 == 0 { + println!("Interrupting core0..."); + gic.end_interrupt(id); + return; + } + }, + 1 => { + if id.0 == 0 { + gic.end_interrupt(id); + asm::exit_irq(); + SP.write(&mut __stack1_start as *mut _ as u32); + asm::enable_irq(); + CORE1_RESTART.store(false, Ordering::Relaxed); + notify_spin_lock(); + main_core1(); + } + }, + _ => {} } stdio::drop_uart(); println!("IRQ"); @@ -134,6 +144,10 @@ pub fn main_core0() { ddr.memtest(); ram::init_alloc_ddr(&mut ddr); + info!("Send software interrupt to core0"); + interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core0.into()); + info!("Core0 returned from interrupt"); + boot::Core1::start(false); let core1_req = unsafe { &mut CORE1_REQ.0 }; -- 2.44.1 From c91c8cc6c3e1d0162666c37ba4233975a4865a22 Mon Sep 17 00:00:00 2001 From: morgan Date: Mon, 20 Nov 2023 12:13:49 +0800 Subject: [PATCH 3/4] use lower-case for asm --- libcortex_a9/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcortex_a9/src/lib.rs b/libcortex_a9/src/lib.rs index e443bad..00814a9 100644 --- a/libcortex_a9/src/lib.rs +++ b/libcortex_a9/src/lib.rs @@ -56,8 +56,8 @@ macro_rules! interrupt_handler { asm!( // setup SP, depending on CPU 0 or 1 // and preserve registers - "SUB lr, lr, #4", - "STMFD sp!, {{r0-r12, lr}}", + "sub lr, lr, #4", + "stmfd sp!, {{r0-r12, lr}}", "mrc p15, #0, r0, c0, c0, #5", concat!("movw r1, :lower16:", stringify!($stack0)), concat!("movt r1, :upper16:", stringify!($stack0)), @@ -70,7 +70,7 @@ macro_rules! interrupt_handler { concat!("bl ", stringify!($name2)), "pop {{r0, r1}}", "mov sp, r0", - "LDMFD sp!, {{r0-r12, pc}}^", // caret ^ : copy SPSR to the CPSR + "ldmfd sp!, {{r0-r12, pc}}^", // caret ^ : copy SPSR to the CPSR options(noreturn) ); } -- 2.44.1 From 63c604e336e4923d7da51077bc3b7a647b72ebab Mon Sep 17 00:00:00 2001 From: morgan Date: Mon, 20 Nov 2023 12:29:31 +0800 Subject: [PATCH 4/4] expand stack alignment docs --- libcortex_a9/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcortex_a9/src/lib.rs b/libcortex_a9/src/lib.rs index 00814a9..2f341d3 100644 --- a/libcortex_a9/src/lib.rs +++ b/libcortex_a9/src/lib.rs @@ -66,7 +66,7 @@ macro_rules! interrupt_handler { concat!("movtne r1, :upper16:", stringify!($stack1)), "mov r0, sp", "mov sp, r1", - "push {{r0, r1}}", // for stack alignment + "push {{r0, r1}}", // 2 registers are pushed to maintain 8 byte stack alignment concat!("bl ", stringify!($name2)), "pop {{r0, r1}}", "mov sp, r0", -- 2.44.1