forked from M-Labs/zynq-rs
libsupport_zynq/abort: moved core1 restart code to user code.
This commit is contained in:
parent
02a2c4d1e3
commit
7d38c53c18
@ -16,5 +16,5 @@ embedded-hal = "0.2"
|
|||||||
libregister = { path = "../libregister" }
|
libregister = { path = "../libregister" }
|
||||||
libcortex_a9 = { path = "../libcortex_a9" }
|
libcortex_a9 = { path = "../libcortex_a9" }
|
||||||
libboard_zynq = { path = "../libboard_zynq" }
|
libboard_zynq = { path = "../libboard_zynq" }
|
||||||
libsupport_zynq = { path = "../libsupport_zynq" }
|
libsupport_zynq = { path = "../libsupport_zynq", default-features = false, features = ["panic_handler"]}
|
||||||
libasync = { path = "../libasync" }
|
libasync = { path = "../libasync" }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(const_in_array_repeat_expressions)]
|
#![feature(const_in_array_repeat_expressions)]
|
||||||
|
#![feature(naked_functions)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ use libboard_zynq::{
|
|||||||
self as zynq,
|
self as zynq,
|
||||||
clocks::source::{ArmPll, ClockSource, IoPll},
|
clocks::source::{ArmPll, ClockSource, IoPll},
|
||||||
clocks::Clocks,
|
clocks::Clocks,
|
||||||
print, println,
|
print, println, stdio,
|
||||||
mpcore,
|
mpcore,
|
||||||
gic,
|
gic,
|
||||||
smoltcp::{
|
smoltcp::{
|
||||||
@ -28,22 +29,65 @@ use libcortex_a9::{
|
|||||||
mutex::Mutex,
|
mutex::Mutex,
|
||||||
sync_channel::{Sender, Receiver},
|
sync_channel::{Sender, Receiver},
|
||||||
sync_channel,
|
sync_channel,
|
||||||
|
regs::{MPIDR, SP},
|
||||||
|
asm
|
||||||
};
|
};
|
||||||
use libregister::RegisterR;
|
use libregister::{RegisterR, RegisterW};
|
||||||
use libsupport_zynq::{
|
use libsupport_zynq::{
|
||||||
boot, ram,
|
boot, ram,
|
||||||
};
|
};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
|
const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
|
||||||
|
|
||||||
static mut CORE1_REQ: (Sender<usize>, Receiver<usize>) = sync_channel!(usize, 10);
|
static mut CORE1_REQ: (Sender<usize>, Receiver<usize>) = sync_channel!(usize, 10);
|
||||||
static mut CORE1_RES: (Sender<usize>, Receiver<usize>) = sync_channel!(usize, 10);
|
static mut CORE1_RES: (Sender<usize>, Receiver<usize>) = 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]
|
#[no_mangle]
|
||||||
pub fn main_core0() {
|
pub fn main_core0() {
|
||||||
// zynq::clocks::CpuClocks::enable_io(1_250_000_000);
|
// zynq::clocks::CpuClocks::enable_io(1_250_000_000);
|
||||||
println!("\nzc706 main");
|
println!("\nzc706 main");
|
||||||
|
let mut interrupt_controller = gic::InterruptController::new(mpcore::RegisterBlock::new());
|
||||||
|
interrupt_controller.enable_interrupts();
|
||||||
// ps7_init::apply();
|
// ps7_init::apply();
|
||||||
libboard_zynq::stdio::drop_uart();
|
libboard_zynq::stdio::drop_uart();
|
||||||
|
|
||||||
@ -147,12 +191,9 @@ pub fn main_core0() {
|
|||||||
|
|
||||||
let core1_req = unsafe { &mut CORE1_REQ.0 };
|
let core1_req = unsafe { &mut CORE1_REQ.0 };
|
||||||
let core1_res = unsafe { &mut CORE1_RES.1 };
|
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 {
|
task::block_on(async {
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
// this interrupt would cause core1 to reset.
|
restart_core1();
|
||||||
interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core1.into());
|
|
||||||
core1_req.async_send(i).await;
|
core1_req.async_send(i).await;
|
||||||
let j = core1_res.async_recv().await;
|
let j = core1_res.async_recv().await;
|
||||||
println!("{} -> {}", i, j);
|
println!("{} -> {}", i, j);
|
||||||
|
@ -9,8 +9,9 @@ edition = "2018"
|
|||||||
target_zc706 = ["libboard_zynq/target_zc706"]
|
target_zc706 = ["libboard_zynq/target_zc706"]
|
||||||
target_cora_z7_10 = ["libboard_zynq/target_cora_z7_10"]
|
target_cora_z7_10 = ["libboard_zynq/target_cora_z7_10"]
|
||||||
panic_handler = []
|
panic_handler = []
|
||||||
|
dummy_irq_handler = []
|
||||||
|
|
||||||
default = ["panic_handler"]
|
default = ["panic_handler", "dummy_irq_handler"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
r0 = "1"
|
r0 = "1"
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
use libregister::{RegisterR, RegisterW};
|
use libregister::RegisterR;
|
||||||
use libcortex_a9::regs::{DFSR, MPIDR, SP};
|
use libcortex_a9::regs::{DFSR, MPIDR};
|
||||||
use libcortex_a9::asm;
|
use libboard_zynq::{println, stdio};
|
||||||
use libboard_zynq::{println, stdio, gic, mpcore};
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn main_core1();
|
|
||||||
static mut __stack1_start: u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[link_section = ".text.boot"]
|
#[link_section = ".text.boot"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -59,19 +53,8 @@ pub unsafe extern "C" fn ReservedException() {
|
|||||||
#[link_section = ".text.boot"]
|
#[link_section = ".text.boot"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[naked]
|
#[naked]
|
||||||
|
#[cfg(feature = "dummy_irq_handler")]
|
||||||
pub unsafe extern "C" fn IRQ() {
|
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();
|
stdio::drop_uart();
|
||||||
println!("IRQ");
|
println!("IRQ");
|
||||||
loop {}
|
loop {}
|
||||||
|
Loading…
Reference in New Issue
Block a user