soft panic first in panic, more generic

pull/199/head
mwojcik 2022-09-02 14:08:52 +08:00
parent 3d6b80b94d
commit 3ba6555bb0
3 changed files with 57 additions and 22 deletions

View File

@ -17,13 +17,13 @@ use libboard_zynq::{
},
timer::GlobalTimer,
};
#[cfg(feature = "target_kasli_soc")]
use libboard_zynq::error_led::ErrorLED;
use libcortex_a9::{semaphore::Semaphore, mutex::Mutex, sync_channel::{Sender, Receiver}};
use futures::{select_biased, future::FutureExt};
use libasync::{smoltcp::{Sockets, TcpStream}, task};
use libconfig::{Config, net_settings};
use libboard_artiq::drtio_routing;
#[cfg(feature = "target_kasli_soc")]
use libboard_zynq::error_led::ErrorLED;
use crate::proto_async::*;
use crate::kernel;
@ -86,6 +86,7 @@ enum Reply {
static CACHE_STORE: Mutex<BTreeMap<String, Vec<i32>>> = Mutex::new(BTreeMap::new());
static DMA_RECORD_STORE: Mutex<BTreeMap<String, (Vec<u8>, i64)>> = Mutex::new(BTreeMap::new());
static mut MGMT_STARTED: bool = false;
async fn write_header(stream: &TcpStream, reply: Reply) -> Result<()> {
stream.send_slice(&[0x5a, 0x5a, 0x5a, 0x5a, reply.to_u8().unwrap()]).await?;
@ -442,6 +443,9 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
}
mgmt::start(cfg);
unsafe {
MGMT_STARTED = true;
}
task::spawn(async move {
let connection = Rc::new(Semaphore::new(1, 1));
@ -494,17 +498,11 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
}
pub fn soft_panic_setup(timer: GlobalTimer, cfg: Config, reason: &'static str) {
pub fn soft_panic_main(timer: GlobalTimer, cfg: Config) -> ! {
let net_addresses = net_settings::get_addresses(&cfg);
info!("network addresses: {}", net_addresses);
error!("There has been an error configuring the device: {}. Only mgmt interface will be available.", reason);
#[cfg(feature = "target_kasli_soc")]
{
let mut err_led = ErrorLED::error_led();
err_led.toggle(true);
}
let eth = zynq::eth::Eth::eth0(net_addresses.hardware_addr.0.clone());
const RX_LEN: usize = 64;
// Number of transmission buffers (minimum is two because with
@ -544,6 +542,13 @@ pub fn soft_panic_setup(timer: GlobalTimer, cfg: Config, reason: &'static str) {
mgmt::start(cfg);
//getting eth settings disables the LED - need enable it here
#[cfg(feature = "target_kasli_soc")]
{
let mut err_led = ErrorLED::error_led();
err_led.toggle(true);
}
Sockets::run(&mut iface, || {
Instant::from_millis(timer.get_time().0 as i32)
});

View File

@ -122,8 +122,8 @@ pub fn main_core0() {
};
task::spawn(report_async_rtio_errors());
match rtio_clocking::init(&mut timer, &cfg) {
Ok(()) => { comms::main(timer, cfg); }
Err(reason) => { comms::soft_panic_setup(timer, cfg, reason); }
};
}
rtio_clocking::init(&mut timer, &cfg).expect("Could not set up RTIO PLL");
comms::main(timer, cfg);
}

View File

@ -3,19 +3,26 @@ use libregister::RegisterR;
use libcortex_a9::regs::MPIDR;
use unwind::backtrace;
#[cfg(feature = "target_kasli_soc")]
use libboard_zynq::error_led::ErrorLED;
use crate::comms::soft_panic_main;
use libboard_zynq::timer::GlobalTimer;
use libconfig::Config;
static mut PANICKED: [bool; 2] = [false; 2];
static mut SOFT_PANICKED: bool = false;
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
let id = MPIDR.read().cpu_id() as usize;
print!("Core {} ", id);
unsafe {
if PANICKED[id] {
println!("nested panic!");
loop {}
}
PANICKED[id] = true;
#[cfg(feature = "target_kasli_soc")]
{
let mut err_led = ErrorLED::error_led();
err_led.toggle(true);
}
let soft_panicked = unsafe { SOFT_PANICKED };
print!("panic at ");
if let Some(location) = info.location() {
print!("{}:{}:{}", location.file(), location.line(), location.column());
@ -27,6 +34,18 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
} else {
println!("");
}
unsafe {
if PANICKED[id] && (SOFT_PANICKED || id == 1) {
println!("nested panic!");
loop {}
}
SOFT_PANICKED = true;
PANICKED[id] = true;
}
if !soft_panicked && id == 0 {
soft_panic();
}
println!("Backtrace: ");
let _ = backtrace(|ip| {
// Backtrace gives us the return address, i.e. the address after the delay slot,
@ -34,6 +53,17 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
print!("{:#08x} ", ip - 2 * 4);
});
println!("\nEnd backtrace");
loop {}
}
fn soft_panic() -> ! {
let timer = GlobalTimer::start();
let cfg = match Config::new() {
Ok(cfg) => cfg,
Err(_) => {
Config::new_dummy()
}
};
soft_panic_main(timer, cfg);
}