Support channel names in RTIO errors

Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
Egor Savkin 2022-12-12 17:35:07 +08:00
parent 8e0229d265
commit 527189ab6a
7 changed files with 75 additions and 29 deletions

View File

@ -423,7 +423,7 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
#[cfg(has_drtio_routing)]
drtio_routing::interconnect_disable_all();
rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer);
rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer, &cfg);
analyzer::start();
moninj::start(timer, aux_mutex, drtio_routing_table);

View File

@ -434,6 +434,7 @@ macro_rules! artiq_raise {
($name:expr, $message:expr, $param0:expr, $param1:expr, $param2:expr) => ({
use cslice::AsCSlice;
let name_id = $crate::eh_artiq::get_exception_id($name);
let message_cl = $message.clone();
let exn = $crate::eh_artiq::Exception {
id: name_id,
file: file!().as_c_slice(),
@ -441,7 +442,7 @@ macro_rules! artiq_raise {
column: column!(),
// https://github.com/rust-lang/rfcs/pull/1719
function: "(Rust function)".as_c_slice(),
message: $message.as_c_slice(),
message: message_cl.as_c_slice(),
param: [$param0, $param1, $param2]
};
#[allow(unused_unsafe)]

View File

@ -2,6 +2,7 @@ use crate::{
pl::csr,
artiq_raise,
rtio,
rtio_mgt::resolve_channel_name,
};
use alloc::{vec::Vec, string::String, boxed::Box};
use cslice::CSlice;
@ -198,12 +199,12 @@ pub extern fn dma_playback(timestamp: i64, ptr: i32) {
csr::rtio_dma::error_write(1);
if error & 1 != 0 {
artiq_raise!("RTIOUnderflow",
"RTIO underflow at {0} mu, channel {1}",
format!("RTIO underflow at channel {}:{}, {{0}} mu", channel, resolve_channel_name(channel as u32)),
timestamp as i64, channel as i64, 0);
}
if error & 2 != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, output, at {0} mu, channel {1}",
format!("RTIO destination unreachable, output, at {{0}} mu, channel {}:{}", channel, resolve_channel_name(channel as u32)),
timestamp as i64, channel as i64, 0);
}
}

View File

@ -9,6 +9,7 @@
#![feature(naked_functions)]
#![feature(asm)]
#[macro_use]
extern crate alloc;
use log::{info, warn, error};
@ -70,16 +71,16 @@ async fn report_async_rtio_errors() {
unsafe {
let errors = pl::csr::rtio_core::async_error_read();
if errors & ASYNC_ERROR_COLLISION != 0 {
error!("RTIO collision involving channel {}",
pl::csr::rtio_core::collision_channel_read());
let channel = pl::csr::rtio_core::collision_channel_read();
error!("RTIO collision involving channel {}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32));
}
if errors & ASYNC_ERROR_BUSY != 0 {
error!("RTIO busy error involving channel {}",
pl::csr::rtio_core::busy_channel_read());
let channel = pl::csr::rtio_core::busy_channel_read();
error!("RTIO busy error involving channel {}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32));
}
if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 {
error!("RTIO sequence error involving channel {}",
pl::csr::rtio_core::sequence_error_channel_read());
let channel = pl::csr::rtio_core::sequence_error_channel_read();
error!("RTIO sequence error involving channel {}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32));
}
SEEN_ASYNC_ERRORS = errors;
pl::csr::rtio_core::async_error_write(errors);

View File

@ -5,6 +5,7 @@ use crate::artiq_raise;
use core::sync::atomic::{fence, Ordering};
use crate::pl::csr;
use crate::rtio_mgt::resolve_channel_name;
pub const RTIO_O_STATUS_WAIT: i32 = 1;
pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
@ -87,12 +88,12 @@ unsafe fn process_exceptional_status(channel: i32, status: i32) {
}
if status & RTIO_O_STATUS_UNDERFLOW != 0 {
artiq_raise!("RTIOUnderflow",
"RTIO underflow at {0} mu, channel {1}, slack {2} mu",
timestamp, channel as i64, timestamp - get_counter());
format!("RTIO underflow at channel {}:{}, {{1}} mu, slack {{2}} mu", channel, resolve_channel_name(channel as u32)),
channel as i64, timestamp, timestamp - get_counter());
}
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, output, at {0} mu, channel {1}",
format!("RTIO destination unreachable, output, at {{0}} mu, channel {}:{}", channel, resolve_channel_name(channel as u32)),
timestamp, channel as i64, 0);
}
}
@ -176,7 +177,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
@ -184,7 +185,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
@ -214,12 +215,12 @@ pub extern fn input_data(channel: i32) -> i32 {
if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
@ -249,12 +250,12 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD
if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}

View File

@ -4,6 +4,7 @@ use cslice::CSlice;
use crate::artiq_raise;
use crate::pl::csr;
use crate::rtio_mgt::resolve_channel_name;
pub const RTIO_O_STATUS_WAIT: u8 = 1;
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2;
@ -72,12 +73,12 @@ unsafe fn process_exceptional_status(channel: i32, status: u8) {
}
if status & RTIO_O_STATUS_UNDERFLOW != 0 {
artiq_raise!("RTIOUnderflow",
"RTIO underflow at {0} mu, channel {1}, slack {2} mu",
timestamp, channel as i64, timestamp - get_counter());
format!("RTIO underflow at channel {}:{}, {{1}} mu, slack {{2}} mu", channel, resolve_channel_name(channel as u32)),
channel as i64, timestamp, timestamp - get_counter());
}
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, output, at {0} mu, channel {1}",
format!("RTIO destination unreachable, output, at {{0}} mu, channel {}:{}", channel, resolve_channel_name(channel as u32)),
timestamp, channel as i64, 0);
}
}
@ -120,7 +121,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
@ -128,7 +129,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
@ -148,12 +149,12 @@ pub extern fn input_data(channel: i32) -> i32 {
if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
@ -173,7 +174,7 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD
if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
@ -181,7 +182,7 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
channel as i64, 0, 0);
}

View File

@ -1,8 +1,15 @@
use core::cell::RefCell;
use alloc::rc::Rc;
use alloc::collections::BTreeMap;
use alloc::string::String;
use libboard_zynq::timer::GlobalTimer;
use libboard_artiq::{pl::csr, drtio_routing};
use libcortex_a9::mutex::Mutex;
use libconfig::Config;
use io::{Cursor, ProtoRead};
use log::error;
static mut RTIO_DEVICE_MAP: BTreeMap<u32, String> = BTreeMap::new();
#[cfg(has_drtio)]
@ -332,6 +339,38 @@ pub mod drtio {
}
}
fn read_device_map(cfg: &Config) -> BTreeMap<u32, String> {
let mut device_map: BTreeMap<u32, String> = BTreeMap::new();
let _ = cfg.read("device_map").and_then(|raw_bytes| {
let mut bytes_cr = Cursor::new(raw_bytes);
let size = bytes_cr.read_u32().unwrap();
for _ in 0..size {
let channel = bytes_cr.read_u32().unwrap();
let device_name = bytes_cr.read_string().unwrap();
if let Some(old_entry) = device_map.insert(channel, device_name.clone()) {
error!("conflicting entries for channel {}: `{}` and `{}`",
channel, old_entry, device_name);
}
}
Ok(())
} ).or_else(|err| {
error!("read_device_map: error reading `device_map` from config: {}", err);
Err(err)
});
device_map
}
fn _resolve_channel_name(channel: u32, device_map: &BTreeMap<u32, String>) -> String {
match device_map.get(&channel) {
Some(val) => val.clone(),
None => String::from("unknown")
}
}
pub fn resolve_channel_name(channel: u32) -> String {
_resolve_channel_name(channel, unsafe{&RTIO_DEVICE_MAP})
}
#[cfg(not(has_drtio))]
pub mod drtio {
use super::*;
@ -346,7 +385,9 @@ pub mod drtio {
pub fn startup(aux_mutex: &Rc<Mutex<bool>>,
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
timer: GlobalTimer) {
timer: GlobalTimer,
cfg: &Config) {
unsafe { RTIO_DEVICE_MAP = read_device_map(cfg); }
drtio::startup(aux_mutex, routing_table, up_destinations, timer);
unsafe {
csr::rtio_core::reset_phy_write(1);