Move RTIO errors formatting to the session_proto

This would be closer to the artiq-zynq implementation

Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
Egor Savkin 2023-03-30 16:35:00 +08:00 committed by Sébastien Bourdeauducq
parent d0b8818688
commit 8984f5104a
3 changed files with 38 additions and 47 deletions

View File

@ -1,10 +1,14 @@
use core::str::Utf8Error; use core::{str, str::Utf8Error, slice};
use alloc::vec::Vec; use alloc::{vec::Vec, format, collections::BTreeMap, string::String};
use eh::eh_artiq::{Exception, StackPointerBacktrace}; use eh::eh_artiq::{Exception, StackPointerBacktrace};
use cslice::CSlice; use cslice::CSlice;
use io::{Read, ProtoRead, Write, ProtoWrite, Error as IoError, ReadStringError}; use io::{Read, ProtoRead, Write, ProtoWrite, Error as IoError, ReadStringError};
pub type DeviceMap = BTreeMap<u32, String>;
static mut RTIO_DEVICE_MAP: Option<DeviceMap> = None;
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub enum Error<T> { pub enum Error<T> {
#[fail(display = "incorrect magic")] #[fail(display = "incorrect magic")]
@ -190,7 +194,14 @@ impl<'a> Reply<'a> {
for exception in exceptions.iter() { for exception in exceptions.iter() {
let exception = exception.as_ref().unwrap(); let exception = exception.as_ref().unwrap();
writer.write_u32(exception.id as u32)?; writer.write_u32(exception.id as u32)?;
write_exception_string(writer, &exception.message)?; if exception.message.len() == usize::MAX {
// exception with host string
write_exception_string(writer, &exception.message)?;
} else {
let msg = str::from_utf8(unsafe { slice::from_raw_parts(exception.message.as_ptr(), exception.message.len()) }).unwrap()
.replace("{rtio_channel_info:0}", &format!("0x{:04x}:{}", exception.param[0], resolve_channel_name(exception.param[0] as u32)));
write_exception_string(writer, unsafe { &CSlice::new(msg.as_ptr(), msg.len()) })?;
}
writer.write_u64(exception.param[0] as u64)?; writer.write_u64(exception.param[0] as u64)?;
writer.write_u64(exception.param[1] as u64)?; writer.write_u64(exception.param[1] as u64)?;
writer.write_u64(exception.param[2] as u64)?; writer.write_u64(exception.param[2] as u64)?;
@ -226,3 +237,20 @@ impl<'a> Reply<'a> {
Ok(()) Ok(())
} }
} }
pub fn set_device_map(device_map: DeviceMap) {
unsafe { RTIO_DEVICE_MAP = Some(device_map); }
}
fn _resolve_channel_name(channel: u32, device_map: &Option<DeviceMap>) -> String {
if let Some(dev_map) = device_map {
match dev_map.get(&channel) {
Some(val) => val.clone(),
None => String::from("unknown")
}
} else { String::from("unknown") }
}
pub fn resolve_channel_name(channel: u32) -> String {
_resolve_channel_name(channel, unsafe{&RTIO_DEVICE_MAP})
}

View File

@ -1,5 +1,3 @@
use alloc::collections::BTreeMap;
use alloc::string::String;
use core::cell::RefCell; use core::cell::RefCell;
use urc::Urc; use urc::Urc;
use board_misoc::{csr, config}; use board_misoc::{csr, config};
@ -9,12 +7,11 @@ use board_artiq::drtio_routing;
use sched::Io; use sched::Io;
use sched::Mutex; use sched::Mutex;
use io::{Cursor, ProtoRead}; use io::{Cursor, ProtoRead};
use session_proto::{DeviceMap, resolve_channel_name, set_device_map};
const ASYNC_ERROR_COLLISION: u8 = 1 << 0; const ASYNC_ERROR_COLLISION: u8 = 1 << 0;
const ASYNC_ERROR_BUSY: u8 = 1 << 1; const ASYNC_ERROR_BUSY: u8 = 1 << 1;
const ASYNC_ERROR_SEQUENCE_ERROR: u8 = 1 << 2; const ASYNC_ERROR_SEQUENCE_ERROR: u8 = 1 << 2;
static mut RTIO_DEVICE_MAP: BTreeMap<u32, String> = BTreeMap::new();
#[cfg(has_drtio)] #[cfg(has_drtio)]
pub mod drtio { pub mod drtio {
use super::*; use super::*;
@ -451,8 +448,8 @@ fn async_error_thread(io: Io) {
} }
} }
fn read_device_map() -> BTreeMap<u32, String> { fn read_device_map() -> DeviceMap {
let mut device_map: BTreeMap<u32, String> = BTreeMap::new(); let mut device_map: DeviceMap = DeviceMap::new();
config::read("device_map", |value: Result<&[u8], config::Error>| { config::read("device_map", |value: Result<&[u8], config::Error>| {
let mut bytes = match value { let mut bytes = match value {
Ok(val) => if val.len() > 0 { Cursor::new(val) } else { Ok(val) => if val.len() > 0 { Cursor::new(val) } else {
@ -477,22 +474,11 @@ fn read_device_map() -> BTreeMap<u32, String> {
device_map 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})
}
pub fn startup(io: &Io, aux_mutex: &Mutex, pub fn startup(io: &Io, aux_mutex: &Mutex,
routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>, up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
ddma_mutex: &Mutex) { ddma_mutex: &Mutex) {
unsafe { RTIO_DEVICE_MAP = read_device_map(); } set_device_map(read_device_map());
drtio::startup(io, aux_mutex, routing_table, up_destinations, ddma_mutex); drtio::startup(io, aux_mutex, routing_table, up_destinations, ddma_mutex);
unsafe { unsafe {
csr::rtio_core::reset_phy_write(1); csr::rtio_core::reset_phy_write(1);

View File

@ -1,4 +1,4 @@
use core::{mem, str, cell::{Cell, RefCell}, fmt::Write as FmtWrite, slice}; use core::{mem, str, cell::{Cell, RefCell}, fmt::Write as FmtWrite};
use alloc::{vec::Vec, string::String}; use alloc::{vec::Vec, string::String};
use byteorder::{ByteOrder, NativeEndian}; use byteorder::{ByteOrder, NativeEndian};
use cslice::CSlice; use cslice::CSlice;
@ -12,7 +12,7 @@ use rtio_clocking;
use rtio_dma::Manager as DmaManager; use rtio_dma::Manager as DmaManager;
#[cfg(has_drtio)] #[cfg(has_drtio)]
use rtio_dma::remote_dma; use rtio_dma::remote_dma;
use rtio_mgt::{get_async_errors, resolve_channel_name}; use rtio_mgt::get_async_errors;
use cache::Cache; use cache::Cache;
use kern_hwreq; use kern_hwreq;
use board_artiq::drtio_routing; use board_artiq::drtio_routing;
@ -484,29 +484,6 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex,
session.kernel_state = KernelState::Absent; session.kernel_state = KernelState::Absent;
unsafe { session.congress.cache.unborrow() } unsafe { session.congress.cache.unborrow() }
let exceptions_with_channel: Vec<Option<eh::eh_artiq::Exception>> = exceptions.iter()
.map(|exception| {
if let Some(exn) = exception {
if exn.message.len() == usize::MAX { // host string
Some(exn.clone())
} else {
let msg = str::from_utf8(unsafe { slice::from_raw_parts(exn.message.as_ptr(), exn.message.len()) })
.unwrap()
.replace("{rtio_channel_info:0}", &format!("0x{:04x}:{}", exn.param[0], resolve_channel_name(exn.param[0] as u32)));
Some(eh::eh_artiq::Exception {
id: exn.id,
file: exn.file,
line: exn.line,
column: exn.column,
function: exn.function,
message: unsafe { CSlice::new(msg.as_ptr(), msg.len()) },
param: exn.param,
})
}
} else { None }
})
.collect();
match stream { match stream {
None => { None => {
error!("exception in flash kernel"); error!("exception in flash kernel");
@ -517,7 +494,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex,
}, },
Some(ref mut stream) => { Some(ref mut stream) => {
host_write(stream, host::Reply::KernelException { host_write(stream, host::Reply::KernelException {
exceptions: &exceptions_with_channel, exceptions: exceptions,
stack_pointers: stack_pointers, stack_pointers: stack_pointers,
backtrace: backtrace, backtrace: backtrace,
async_errors: unsafe { get_async_errors() } async_errors: unsafe { get_async_errors() }