From 8984f5104a7c443661010a6f2c5acad2485e19de Mon Sep 17 00:00:00 2001 From: Egor Savkin Date: Thu, 30 Mar 2023 16:35:00 +0800 Subject: [PATCH] Move RTIO errors formatting to the session_proto This would be closer to the artiq-zynq implementation Signed-off-by: Egor Savkin --- .../firmware/libproto_artiq/session_proto.rs | 34 +++++++++++++++++-- artiq/firmware/runtime/rtio_mgt.rs | 22 +++--------- artiq/firmware/runtime/session.rs | 29 ++-------------- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/artiq/firmware/libproto_artiq/session_proto.rs b/artiq/firmware/libproto_artiq/session_proto.rs index 523331416..d4277c26c 100644 --- a/artiq/firmware/libproto_artiq/session_proto.rs +++ b/artiq/firmware/libproto_artiq/session_proto.rs @@ -1,10 +1,14 @@ -use core::str::Utf8Error; -use alloc::vec::Vec; +use core::{str, str::Utf8Error, slice}; +use alloc::{vec::Vec, format, collections::BTreeMap, string::String}; use eh::eh_artiq::{Exception, StackPointerBacktrace}; use cslice::CSlice; use io::{Read, ProtoRead, Write, ProtoWrite, Error as IoError, ReadStringError}; +pub type DeviceMap = BTreeMap; + +static mut RTIO_DEVICE_MAP: Option = None; + #[derive(Fail, Debug)] pub enum Error { #[fail(display = "incorrect magic")] @@ -190,7 +194,14 @@ impl<'a> Reply<'a> { for exception in exceptions.iter() { let exception = exception.as_ref().unwrap(); 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[1] as u64)?; writer.write_u64(exception.param[2] as u64)?; @@ -226,3 +237,20 @@ impl<'a> Reply<'a> { 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) -> 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}) +} diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index f0aad09b8..6b864c128 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -1,5 +1,3 @@ -use alloc::collections::BTreeMap; -use alloc::string::String; use core::cell::RefCell; use urc::Urc; use board_misoc::{csr, config}; @@ -9,12 +7,11 @@ use board_artiq::drtio_routing; use sched::Io; use sched::Mutex; use io::{Cursor, ProtoRead}; +use session_proto::{DeviceMap, resolve_channel_name, set_device_map}; const ASYNC_ERROR_COLLISION: u8 = 1 << 0; const ASYNC_ERROR_BUSY: u8 = 1 << 1; const ASYNC_ERROR_SEQUENCE_ERROR: u8 = 1 << 2; -static mut RTIO_DEVICE_MAP: BTreeMap = BTreeMap::new(); - #[cfg(has_drtio)] pub mod drtio { use super::*; @@ -451,8 +448,8 @@ fn async_error_thread(io: Io) { } } -fn read_device_map() -> BTreeMap { - let mut device_map: BTreeMap = BTreeMap::new(); +fn read_device_map() -> DeviceMap { + let mut device_map: DeviceMap = DeviceMap::new(); config::read("device_map", |value: Result<&[u8], config::Error>| { let mut bytes = match value { Ok(val) => if val.len() > 0 { Cursor::new(val) } else { @@ -477,22 +474,11 @@ fn read_device_map() -> BTreeMap { device_map } -fn _resolve_channel_name(channel: u32, device_map: &BTreeMap) -> 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, routing_table: &Urc>, up_destinations: &Urc>, 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); unsafe { csr::rtio_core::reset_phy_write(1); diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 2096dcc94..f99f08ae6 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -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 byteorder::{ByteOrder, NativeEndian}; use cslice::CSlice; @@ -12,7 +12,7 @@ use rtio_clocking; use rtio_dma::Manager as DmaManager; #[cfg(has_drtio)] use rtio_dma::remote_dma; -use rtio_mgt::{get_async_errors, resolve_channel_name}; +use rtio_mgt::get_async_errors; use cache::Cache; use kern_hwreq; use board_artiq::drtio_routing; @@ -484,29 +484,6 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, session.kernel_state = KernelState::Absent; unsafe { session.congress.cache.unborrow() } - let exceptions_with_channel: Vec> = 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 { None => { error!("exception in flash kernel"); @@ -517,7 +494,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, }, Some(ref mut stream) => { host_write(stream, host::Reply::KernelException { - exceptions: &exceptions_with_channel, + exceptions: exceptions, stack_pointers: stack_pointers, backtrace: backtrace, async_errors: unsafe { get_async_errors() }