diff --git a/experiments/Cargo.toml b/experiments/Cargo.toml index 3a7794c..b152431 100644 --- a/experiments/Cargo.toml +++ b/experiments/Cargo.toml @@ -16,5 +16,5 @@ embedded-hal = "0.2" libregister = { path = "../libregister" } libcortex_a9 = { path = "../libcortex_a9" } libboard_zynq = { path = "../libboard_zynq" } -libsupport_zynq = { path = "../libsupport_zynq" } +libsupport_zynq = { path = "../libsupport_zynq", default-features = false, features = ["panic_handler"]} libasync = { path = "../libasync" } diff --git a/experiments/src/main.rs b/experiments/src/main.rs index f53e6db..3cb04e5 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -1,6 +1,7 @@ #![no_std] #![no_main] #![feature(const_in_array_repeat_expressions)] +#![feature(naked_functions)] extern crate alloc; @@ -14,7 +15,7 @@ use libboard_zynq::{ self as zynq, clocks::source::{ArmPll, ClockSource, IoPll}, clocks::Clocks, - print, println, + print, println, stdio, mpcore, gic, smoltcp::{ @@ -28,22 +29,65 @@ use libcortex_a9::{ mutex::Mutex, sync_channel::{Sender, Receiver}, sync_channel, + regs::{MPIDR, SP}, + asm }; -use libregister::RegisterR; +use libregister::{RegisterR, RegisterW}; use libsupport_zynq::{ boot, ram, }; use log::{info, warn}; +use core::sync::atomic::{AtomicBool, Ordering}; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; static mut CORE1_REQ: (Sender, Receiver) = sync_channel!(usize, 10); static mut CORE1_RES: (Sender, Receiver) = sync_channel!(usize, 10); +extern "C" { + static mut __stack1_start: u32; +} + +static CORE1_RESTART: AtomicBool = AtomicBool::new(false); + +#[link_section = ".text.boot"] +#[no_mangle] +#[naked] +pub unsafe extern "C" fn IRQ() { + if MPIDR.read().cpu_id() == 1{ + let mpcore = mpcore::RegisterBlock::new(); + let mut gic = gic::InterruptController::new(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); + asm::sev(); + main_core1(); + } + } + stdio::drop_uart(); + println!("IRQ"); + loop {} +} + +pub fn restart_core1() { + let mut interrupt_controller = gic::InterruptController::new(mpcore::RegisterBlock::new()); + CORE1_RESTART.store(true, Ordering::Relaxed); + interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core1.into()); + while CORE1_RESTART.load(Ordering::Relaxed) { + asm::wfe(); + } +} + #[no_mangle] pub fn main_core0() { // zynq::clocks::CpuClocks::enable_io(1_250_000_000); println!("\nzc706 main"); + let mut interrupt_controller = gic::InterruptController::new(mpcore::RegisterBlock::new()); + interrupt_controller.enable_interrupts(); // ps7_init::apply(); libboard_zynq::stdio::drop_uart(); @@ -147,12 +191,9 @@ pub fn main_core0() { let core1_req = unsafe { &mut CORE1_REQ.0 }; let core1_res = unsafe { &mut CORE1_RES.1 }; - let mut interrupt_controller = gic::InterruptController::new(mpcore::RegisterBlock::new()); - interrupt_controller.enable_interrupts(); task::block_on(async { for i in 0..10 { - // this interrupt would cause core1 to reset. - interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core1.into()); + restart_core1(); core1_req.async_send(i).await; let j = core1_res.async_recv().await; println!("{} -> {}", i, j); diff --git a/libsupport_zynq/Cargo.toml b/libsupport_zynq/Cargo.toml index aff8b8b..ad215d1 100644 --- a/libsupport_zynq/Cargo.toml +++ b/libsupport_zynq/Cargo.toml @@ -9,8 +9,9 @@ edition = "2018" target_zc706 = ["libboard_zynq/target_zc706"] target_cora_z7_10 = ["libboard_zynq/target_cora_z7_10"] panic_handler = [] +dummy_irq_handler = [] -default = ["panic_handler"] +default = ["panic_handler", "dummy_irq_handler"] [dependencies] r0 = "1" diff --git a/libsupport_zynq/src/abort.rs b/libsupport_zynq/src/abort.rs index be68c79..7429bd2 100644 --- a/libsupport_zynq/src/abort.rs +++ b/libsupport_zynq/src/abort.rs @@ -1,12 +1,6 @@ -use libregister::{RegisterR, RegisterW}; -use libcortex_a9::regs::{DFSR, MPIDR, SP}; -use libcortex_a9::asm; -use libboard_zynq::{println, stdio, gic, mpcore}; - -extern "C" { - fn main_core1(); - static mut __stack1_start: u32; -} +use libregister::RegisterR; +use libcortex_a9::regs::{DFSR, MPIDR}; +use libboard_zynq::{println, stdio}; #[link_section = ".text.boot"] #[no_mangle] @@ -59,19 +53,8 @@ pub unsafe extern "C" fn ReservedException() { #[link_section = ".text.boot"] #[no_mangle] #[naked] +#[cfg(feature = "dummy_irq_handler")] pub unsafe extern "C" fn IRQ() { - if MPIDR.read().cpu_id() == 1{ - let mpcore = mpcore::RegisterBlock::new(); - let mut gic = gic::InterruptController::new(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(); - main_core1(); - } - } stdio::drop_uart(); println!("IRQ"); loop {}