updated zynq-rs and IRQ handling

exception
pca006132 2021-01-28 12:56:54 +08:00
parent c2a6fb72f7
commit bb65074254
5 changed files with 40 additions and 45 deletions

View File

@ -20,7 +20,7 @@ let
name = "firmware"; name = "firmware";
src = ./src; src = ./src;
cargoSha256 = "1h6zm7kq1f24kyjgmmmq7b9jydvs23glsrfij6s86nlwbhd5xrcb"; cargoSha256 = "1d84yknyizbxgsqj478339fxcyvxq9pzdv0ljrwrgmzgfynqmssj";
nativeBuildInputs = [ nativeBuildInputs = [
pkgs.gnumake pkgs.gnumake

14
src/Cargo.lock generated
View File

@ -56,7 +56,7 @@ checksum = "3748f82c7d366a0b4950257d19db685d4958d2fa27c6d164a3f069fec42b748b"
[[package]] [[package]]
name = "core_io" name = "core_io"
version = "0.1.20200410" 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 = [ dependencies = [
"memchr", "memchr",
] ]
@ -186,7 +186,7 @@ dependencies = [
[[package]] [[package]]
name = "libasync" name = "libasync"
version = "0.0.0" 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 = [ dependencies = [
"embedded-hal", "embedded-hal",
"libcortex_a9", "libcortex_a9",
@ -198,7 +198,7 @@ dependencies = [
[[package]] [[package]]
name = "libboard_zynq" name = "libboard_zynq"
version = "0.0.0" 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 = [ dependencies = [
"bit_field", "bit_field",
"embedded-hal", "embedded-hal",
@ -223,7 +223,7 @@ dependencies = [
[[package]] [[package]]
name = "libconfig" name = "libconfig"
version = "0.1.0" 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 = [ dependencies = [
"core_io", "core_io",
"fatfs", "fatfs",
@ -234,7 +234,7 @@ dependencies = [
[[package]] [[package]]
name = "libcortex_a9" name = "libcortex_a9"
version = "0.0.0" 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 = [ dependencies = [
"bit_field", "bit_field",
"libregister", "libregister",
@ -250,7 +250,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]] [[package]]
name = "libregister" name = "libregister"
version = "0.0.0" 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 = [ dependencies = [
"bit_field", "bit_field",
"vcell", "vcell",
@ -260,7 +260,7 @@ dependencies = [
[[package]] [[package]]
name = "libsupport_zynq" name = "libsupport_zynq"
version = "0.0.0" 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 = [ dependencies = [
"cc", "cc",
"compiler_builtins", "compiler_builtins",

View File

@ -69,4 +69,18 @@ SECTIONS
. += 0x20000; . += 0x20000;
__stack0_start = .; __stack0_start = .;
} > SDRAM } > 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
} }

View File

@ -1,10 +1,10 @@
use libboard_zynq::{gic, mpcore, println, stdio}; use libboard_zynq::{gic, mpcore, println, stdio};
use libcortex_a9::{ use libcortex_a9::{
asm, asm, interrupt_handler,
regs::{MPIDR, SP}, regs::MPIDR,
spin_lock_yield, notify_spin_lock spin_lock_yield, notify_spin_lock
}; };
use libregister::{RegisterR, RegisterW}; use libregister::RegisterR;
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
extern "C" { extern "C" {
@ -14,50 +14,31 @@ extern "C" {
static CORE1_RESTART: AtomicBool = AtomicBool::new(false); static CORE1_RESTART: AtomicBool = AtomicBool::new(false);
#[link_section = ".text.boot"] interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
#[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() {
if MPIDR.read().cpu_id() == 1 { if MPIDR.read().cpu_id() == 1 {
let mpcore = mpcore::RegisterBlock::mpcore(); let mpcore = mpcore::RegisterBlock::mpcore();
let mut gic = gic::InterruptController::gic(mpcore); let mut gic = gic::InterruptController::gic(mpcore);
let id = gic.get_interrupt_id(); let id = gic.get_interrupt_id();
if id.0 == 0 { if id.0 == 0 {
gic.end_interrupt(id); 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(); asm::exit_irq();
SP.write(v); asm!("b core1_restart");
asm::enable_irq();
CORE1_RESTART.store(false, Ordering::Relaxed);
notify_spin_lock();
main_core1();
} }
} }
stdio::drop_uart(); stdio::drop_uart();
println!("IRQ"); println!("IRQ");
loop {} 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() { pub fn restart_core1() {
let mut interrupt_controller = gic::InterruptController::gic(mpcore::RegisterBlock::mpcore()); let mut interrupt_controller = gic::InterruptController::gic(mpcore::RegisterBlock::mpcore());

View File

@ -3,6 +3,6 @@ let
in in
pkgs.fetchgit { pkgs.fetchgit {
url = "https://git.m-labs.hk/M-Labs/zynq-rs.git"; url = "https://git.m-labs.hk/M-Labs/zynq-rs.git";
rev = "6e6612bc3e12e50b4f6e61cde47100c3d4ab982a"; rev = "78d58d17ec7906a6cadd1678576939d20612cf8f";
sha256 = "14hj77n9g2zack6sjgs7337j8yq9r3jrpdsmc62kmxfbbmy8jhlg"; sha256 = "1y74i7j9kawhlq22zyicjsxldx9f7h4i22yabw1z4qga19zv6qjd";
} }