runtime/comms: restart core1 before kernel load.

core0-buffer
pca006132 2020-08-04 10:17:19 +08:00
parent fa00ab211d
commit d58a3ef12c
5 changed files with 60 additions and 1 deletions

View File

@ -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" }

View File

@ -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
View 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();
}
}

View File

@ -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));
}
}

View File

@ -40,6 +40,7 @@ mod panic;
mod logger;
mod mgmt;
mod analyzer;
mod irq;
fn init_gateware() {
// Set up PS->PL clocks