runtime/comms: restart core1 before kernel load.
This commit is contained in:
parent
fa00ab211d
commit
d58a3ef12c
@ -26,7 +26,7 @@ log_buffer = { version = "1.2" }
|
||||
libm = { version = "0.2", features = ["unstable"] }
|
||||
|
||||
libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||
libsupport_zynq = { default-features = false, features = ["alloc_core", "dummy_irq_handler"], git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||
libsupport_zynq = { default-features = false, features = ["alloc_core"], git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||
libcortex_a9 = { git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||
libasync = { git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||
libregister = { git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||
|
@ -232,6 +232,7 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc<RefCell<kern
|
||||
|
||||
async fn load_kernel(buffer: Vec<u8>, control: &Rc<RefCell<kernel::Control>>, stream: Option<&TcpStream>) -> Result<()> {
|
||||
let mut control = control.borrow_mut();
|
||||
control.restart();
|
||||
control.tx.async_send(kernel::Message::LoadRequest(buffer)).await;
|
||||
let reply = control.rx.async_recv().await;
|
||||
match reply {
|
||||
|
46
src/runtime/src/irq.rs
Normal file
46
src/runtime/src/irq.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use libboard_zynq::{gic, mpcore, println, stdio};
|
||||
use libcortex_a9::{
|
||||
asm,
|
||||
regs::{MPIDR, SP},
|
||||
};
|
||||
use libregister::{RegisterR, RegisterW};
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
extern "C" {
|
||||
static mut __stack1_start: u32;
|
||||
fn main_core1() -> !;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -2,6 +2,9 @@ use libcortex_a9::sync_channel::{Sender, Receiver};
|
||||
use libsupport_zynq::boot::Core1;
|
||||
|
||||
use super::{CHANNEL_0TO1, CHANNEL_1TO0, Message};
|
||||
use crate::irq::restart_core1;
|
||||
|
||||
use core::mem::{forget, replace};
|
||||
|
||||
pub struct Control {
|
||||
pub tx: Sender<'static, Message>,
|
||||
@ -34,5 +37,13 @@ impl Control {
|
||||
rx: core0_rx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restart(&mut self) {
|
||||
restart_core1();
|
||||
let (core0_tx, core0_rx) = get_channels();
|
||||
// dangling pointer here, so we forget it
|
||||
forget(replace(&mut self.tx, core0_tx));
|
||||
forget(replace(&mut self.rx, core0_rx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ mod panic;
|
||||
mod logger;
|
||||
mod mgmt;
|
||||
mod analyzer;
|
||||
mod irq;
|
||||
|
||||
fn init_gateware() {
|
||||
// Set up PS->PL clocks
|
||||
|
Loading…
Reference in New Issue
Block a user