Support channel names in RTIO errors #209

Merged
sb10q merged 3 commits from esavkin/artiq-zynq:1697-rtiomap into master 2023-01-09 12:35:56 +08:00
7 changed files with 75 additions and 29 deletions
Showing only changes of commit 527189ab6a - Show all commits

View File

@ -423,7 +423,7 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
#[cfg(has_drtio_routing)] #[cfg(has_drtio_routing)]
drtio_routing::interconnect_disable_all(); 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(); analyzer::start();
moninj::start(timer, aux_mutex, drtio_routing_table); 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) => ({ ($name:expr, $message:expr, $param0:expr, $param1:expr, $param2:expr) => ({
use cslice::AsCSlice; use cslice::AsCSlice;
let name_id = $crate::eh_artiq::get_exception_id($name); let name_id = $crate::eh_artiq::get_exception_id($name);
let message_cl = $message.clone();
let exn = $crate::eh_artiq::Exception { let exn = $crate::eh_artiq::Exception {
id: name_id, id: name_id,
file: file!().as_c_slice(), file: file!().as_c_slice(),
@ -441,7 +442,7 @@ macro_rules! artiq_raise {
column: column!(), column: column!(),
// https://github.com/rust-lang/rfcs/pull/1719 // https://github.com/rust-lang/rfcs/pull/1719
function: "(Rust function)".as_c_slice(), function: "(Rust function)".as_c_slice(),
message: $message.as_c_slice(), message: message_cl.as_c_slice(),
param: [$param0, $param1, $param2] param: [$param0, $param1, $param2]
}; };
#[allow(unused_unsafe)] #[allow(unused_unsafe)]

View File

@ -2,6 +2,7 @@ use crate::{
pl::csr, pl::csr,
artiq_raise, artiq_raise,
rtio, rtio,
rtio_mgt::resolve_channel_name,
}; };
use alloc::{vec::Vec, string::String, boxed::Box}; use alloc::{vec::Vec, string::String, boxed::Box};
use cslice::CSlice; use cslice::CSlice;
@ -198,12 +199,12 @@ pub extern fn dma_playback(timestamp: i64, ptr: i32) {
csr::rtio_dma::error_write(1); csr::rtio_dma::error_write(1);
if error & 1 != 0 { if error & 1 != 0 {
artiq_raise!("RTIOUnderflow", 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); timestamp as i64, channel as i64, 0);
} }
if error & 2 != 0 { if error & 2 != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); timestamp as i64, channel as i64, 0);
} }
} }

View File

@ -9,6 +9,7 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(asm)] #![feature(asm)]
#[macro_use]
extern crate alloc; extern crate alloc;
use log::{info, warn, error}; use log::{info, warn, error};
@ -70,16 +71,16 @@ async fn report_async_rtio_errors() {
unsafe { unsafe {
let errors = pl::csr::rtio_core::async_error_read(); let errors = pl::csr::rtio_core::async_error_read();
if errors & ASYNC_ERROR_COLLISION != 0 { if errors & ASYNC_ERROR_COLLISION != 0 {
error!("RTIO collision involving channel {}", let channel = pl::csr::rtio_core::collision_channel_read();
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 { if errors & ASYNC_ERROR_BUSY != 0 {
error!("RTIO busy error involving channel {}", let channel = pl::csr::rtio_core::busy_channel_read();
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 { if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 {
error!("RTIO sequence error involving channel {}", let channel = pl::csr::rtio_core::sequence_error_channel_read();
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; SEEN_ASYNC_ERRORS = errors;
pl::csr::rtio_core::async_error_write(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 core::sync::atomic::{fence, Ordering};
use crate::pl::csr; use crate::pl::csr;
use crate::rtio_mgt::resolve_channel_name;
pub const RTIO_O_STATUS_WAIT: i32 = 1; pub const RTIO_O_STATUS_WAIT: i32 = 1;
pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2; 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 { if status & RTIO_O_STATUS_UNDERFLOW != 0 {
artiq_raise!("RTIOUnderflow", artiq_raise!("RTIOUnderflow",
"RTIO underflow at {0} mu, channel {1}, slack {2} mu", format!("RTIO underflow at channel {}:{}, {{1}} mu, slack {{2}} mu", channel, resolve_channel_name(channel as u32)),
timestamp, channel as i64, timestamp - get_counter()); channel as i64, timestamp, timestamp - get_counter());
} }
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 { if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); 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 { if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow", 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); channel as i64, 0, 0);
} }
if status & RTIO_I_STATUS_WAIT_EVENT != 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 { if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); channel as i64, 0, 0);
} }
@ -214,12 +215,12 @@ pub extern fn input_data(channel: i32) -> i32 {
if status & RTIO_I_STATUS_OVERFLOW != 0 { if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow", 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); channel as i64, 0, 0);
} }
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); 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 { if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow", 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); channel as i64, 0, 0);
} }
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); channel as i64, 0, 0);
} }

View File

@ -4,6 +4,7 @@ use cslice::CSlice;
use crate::artiq_raise; use crate::artiq_raise;
use crate::pl::csr; use crate::pl::csr;
use crate::rtio_mgt::resolve_channel_name;
pub const RTIO_O_STATUS_WAIT: u8 = 1; pub const RTIO_O_STATUS_WAIT: u8 = 1;
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2; 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 { if status & RTIO_O_STATUS_UNDERFLOW != 0 {
artiq_raise!("RTIOUnderflow", artiq_raise!("RTIOUnderflow",
"RTIO underflow at {0} mu, channel {1}, slack {2} mu", format!("RTIO underflow at channel {}:{}, {{1}} mu, slack {{2}} mu", channel, resolve_channel_name(channel as u32)),
timestamp, channel as i64, timestamp - get_counter()); channel as i64, timestamp, timestamp - get_counter());
} }
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 { if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); 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 { if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow", 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); channel as i64, 0, 0);
} }
if status & RTIO_I_STATUS_WAIT_EVENT != 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 { if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); channel as i64, 0, 0);
} }
@ -148,12 +149,12 @@ pub extern fn input_data(channel: i32) -> i32 {
if status & RTIO_I_STATUS_OVERFLOW != 0 { if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow", 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); channel as i64, 0, 0);
} }
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); 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 { if status & RTIO_I_STATUS_OVERFLOW != 0 {
artiq_raise!("RTIOOverflow", 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); channel as i64, 0, 0);
} }
if status & RTIO_I_STATUS_WAIT_EVENT != 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 { if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
artiq_raise!("RTIODestinationUnreachable", 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); channel as i64, 0, 0);
} }

View File

@ -1,8 +1,15 @@
use core::cell::RefCell; use core::cell::RefCell;
use alloc::rc::Rc; use alloc::rc::Rc;
use alloc::collections::BTreeMap;
use alloc::string::String;
use libboard_zynq::timer::GlobalTimer; use libboard_zynq::timer::GlobalTimer;
use libboard_artiq::{pl::csr, drtio_routing}; use libboard_artiq::{pl::csr, drtio_routing};
use libcortex_a9::mutex::Mutex; 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)] #[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))] #[cfg(not(has_drtio))]
pub mod drtio { pub mod drtio {
use super::*; use super::*;
@ -346,7 +385,9 @@ pub mod drtio {
pub fn startup(aux_mutex: &Rc<Mutex<bool>>, pub fn startup(aux_mutex: &Rc<Mutex<bool>>,
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>, routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>, 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); drtio::startup(aux_mutex, routing_table, up_destinations, timer);
unsafe { unsafe {
csr::rtio_core::reset_phy_write(1); csr::rtio_core::reset_phy_write(1);