forked from M-Labs/artiq
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:
parent
d0b8818688
commit
8984f5104a
|
@ -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)?;
|
||||||
|
if exception.message.len() == usize::MAX {
|
||||||
|
// exception with host string
|
||||||
write_exception_string(writer, &exception.message)?;
|
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})
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() }
|
||||||
|
|
Loading…
Reference in New Issue