From bb65074254088c2055a2f172db2f838e5874e456 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 28 Jan 2021 12:56:54 +0800 Subject: [PATCH] updated zynq-rs and IRQ handling --- default.nix | 2 +- src/Cargo.lock | 14 ++++++------ src/runtime/link.x | 14 ++++++++++++ src/runtime/src/irq.rs | 51 +++++++++++++----------------------------- zynq-rs.nix | 4 ++-- 5 files changed, 40 insertions(+), 45 deletions(-) diff --git a/default.nix b/default.nix index 6e174c56..b36cf3f6 100644 --- a/default.nix +++ b/default.nix @@ -20,7 +20,7 @@ let name = "firmware"; src = ./src; - cargoSha256 = "1h6zm7kq1f24kyjgmmmq7b9jydvs23glsrfij6s86nlwbhd5xrcb"; + cargoSha256 = "1d84yknyizbxgsqj478339fxcyvxq9pzdv0ljrwrgmzgfynqmssj"; nativeBuildInputs = [ pkgs.gnumake diff --git a/src/Cargo.lock b/src/Cargo.lock index 9f5a70df..9c21bf8c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -56,7 +56,7 @@ checksum = "3748f82c7d366a0b4950257d19db685d4958d2fa27c6d164a3f069fec42b748b" [[package]] name = "core_io" version = "0.1.20200410" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "memchr", ] @@ -186,7 +186,7 @@ dependencies = [ [[package]] name = "libasync" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "embedded-hal", "libcortex_a9", @@ -198,7 +198,7 @@ dependencies = [ [[package]] name = "libboard_zynq" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "bit_field", "embedded-hal", @@ -223,7 +223,7 @@ dependencies = [ [[package]] name = "libconfig" version = "0.1.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "core_io", "fatfs", @@ -234,7 +234,7 @@ dependencies = [ [[package]] name = "libcortex_a9" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "bit_field", "libregister", @@ -250,7 +250,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libregister" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "bit_field", "vcell", @@ -260,7 +260,7 @@ dependencies = [ [[package]] name = "libsupport_zynq" version = "0.0.0" -source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#6e6612bc3e12e50b4f6e61cde47100c3d4ab982a" +source = "git+https://git.m-labs.hk/M-Labs/zynq-rs.git#78d58d17ec7906a6cadd1678576939d20612cf8f" dependencies = [ "cc", "compiler_builtins", diff --git a/src/runtime/link.x b/src/runtime/link.x index 0a6f853f..1f148a8f 100644 --- a/src/runtime/link.x +++ b/src/runtime/link.x @@ -69,4 +69,18 @@ SECTIONS . += 0x20000; __stack0_start = .; } > SDRAM + + .irq_stack1 (NOLOAD) : ALIGN(8) + { + __irq_stack1_end = .; + . += 0x100; + __irq_stack1_start = .; + } > SDRAM + + .irq_stack0 (NOLOAD) : ALIGN(8) + { + __irq_stack0_end = .; + . += 0x100; + __irq_stack0_start = .; + } > SDRAM } diff --git a/src/runtime/src/irq.rs b/src/runtime/src/irq.rs index 0b9df77b..c821abe0 100644 --- a/src/runtime/src/irq.rs +++ b/src/runtime/src/irq.rs @@ -1,10 +1,10 @@ use libboard_zynq::{gic, mpcore, println, stdio}; use libcortex_a9::{ - asm, - regs::{MPIDR, SP}, + asm, interrupt_handler, + regs::MPIDR, spin_lock_yield, notify_spin_lock }; -use libregister::{RegisterR, RegisterW}; +use libregister::RegisterR; use core::sync::atomic::{AtomicBool, Ordering}; extern "C" { @@ -14,50 +14,31 @@ extern "C" { static CORE1_RESTART: AtomicBool = AtomicBool::new(false); -#[link_section = ".text.boot"] -#[no_mangle] -#[naked] -pub unsafe extern "C" fn IRQ() { - asm!( - // setup SP, depending on CPU 0 or 1 - "mrc p15, #0, r0, c0, c0, #5", - "movw r1, :lower16:__stack0_start", - "movt r1, :upper16:__stack0_start", - "tst r0, #3", - "movwne r1, :lower16:__stack1_start", - "movtne r1, :upper16:__stack1_start", - "mov sp, r1", - "bl __IRQ", - options(noreturn) - ); -} - -#[no_mangle] -pub unsafe extern "C" fn __IRQ() { +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); - // save the SP and set it back after exiting IRQ - // exception unwinding expect to unwind from this function, as this is not the entrance - // function, maybe to IRQ which cannot further unwind... - // if we set the SP to __stack1_start, interesting exceptions would be triggered when - // we try to unwind the stack... - let v = SP.read(); asm::exit_irq(); - SP.write(v); - asm::enable_irq(); - CORE1_RESTART.store(false, Ordering::Relaxed); - notify_spin_lock(); - main_core1(); + asm!("b core1_restart"); } } stdio::drop_uart(); println!("IRQ"); loop {} -} +}); + +// This is actually not an interrupt handler, just use the macro for convenience. +// This function would be called in normal mode (instead of interrupt mode), the outer naked +// function wrapper is to tell libunwind to stop when it reaches here. +interrupt_handler!(core1_restart, core1_restart_impl, __stack0_start, __stack1_start, { + asm::enable_irq(); + CORE1_RESTART.store(false, Ordering::Relaxed); + notify_spin_lock(); + main_core1(); +}); pub fn restart_core1() { let mut interrupt_controller = gic::InterruptController::gic(mpcore::RegisterBlock::mpcore()); diff --git a/zynq-rs.nix b/zynq-rs.nix index 2eba9153..a843370b 100644 --- a/zynq-rs.nix +++ b/zynq-rs.nix @@ -3,6 +3,6 @@ let in pkgs.fetchgit { url = "https://git.m-labs.hk/M-Labs/zynq-rs.git"; - rev = "6e6612bc3e12e50b4f6e61cde47100c3d4ab982a"; - sha256 = "14hj77n9g2zack6sjgs7337j8yq9r3jrpdsmc62kmxfbbmy8jhlg"; + rev = "78d58d17ec7906a6cadd1678576939d20612cf8f"; + sha256 = "1y74i7j9kawhlq22zyicjsxldx9f7h4i22yabw1z4qga19zv6qjd"; }