From ffcf79b74e62b81d18ec9a7f10e22e398ff1d6d0 Mon Sep 17 00:00:00 2001 From: occheung Date: Wed, 2 Oct 2024 10:58:13 +0800 Subject: [PATCH] satman: support coremgmt logging --- artiq/firmware/satman/main.rs | 47 +++++++++++++++++++++++++++++------ artiq/firmware/satman/mgmt.rs | 42 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 55cf7b65f..ca0253e04 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -501,19 +501,50 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg Ok(()) } - drtioaux::Packet::CoreMgmtGetLogRequest { destination: _destination, .. } | - drtioaux::Packet::CoreMgmtClearLogRequest { destination: _destination } | - drtioaux::Packet::CoreMgmtSetLogLevelRequest {destination: _destination, .. } => { + drtioaux::Packet::CoreMgmtGetLogRequest { destination: _destination, clear } => { forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet); - error!("RISC-V satellite devices do not support buffered logging"); - drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) + let mut data_slice = [0; SAT_PAYLOAD_MAX_SIZE]; + if let Ok(meta) = coremgr.log_get_slice(&mut data_slice, clear) { + drtioaux::send( + 0, + &drtioaux::Packet::CoreMgmtGetLogReply { + last: meta.status.is_last(), + length: meta.len as u16, + data: data_slice, + }, + ) + } else { + drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) + } } - drtioaux::Packet::CoreMgmtSetUartLogLevelRequest { destination: _destination, .. } => { + drtioaux::Packet::CoreMgmtClearLogRequest { destination: _destination } => { forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet); - error!("RISC-V satellite devices has fixed UART log level fixed at TRACE"); - drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) + drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: mgmt::clear_log().is_ok() }) + } + drtioaux::Packet::CoreMgmtSetLogLevelRequest {destination: _destination, log_level } => { + forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet); + + if let Ok(level_filter) = mgmt::byte_to_level_filter(log_level) { + info!("changing log level to {}", level_filter); + log::set_max_level(level_filter); + drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: true }) + } else { + drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) + } + } + drtioaux::Packet::CoreMgmtSetUartLogLevelRequest { destination: _destination, log_level } => { + forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet); + + if let Ok(level_filter) = mgmt::byte_to_level_filter(log_level) { + info!("changing UART log level to {}", level_filter); + logger_artiq::BufferLogger::with(|logger| + logger.set_uart_log_level(level_filter)); + drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: true }) + } else { + drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) + } } drtioaux::Packet::CoreMgmtConfigReadRequest { destination: _destination, diff --git a/artiq/firmware/satman/mgmt.rs b/artiq/firmware/satman/mgmt.rs index ad0526b0d..9ad6f203a 100644 --- a/artiq/firmware/satman/mgmt.rs +++ b/artiq/firmware/satman/mgmt.rs @@ -5,14 +5,39 @@ use crc::crc32; use routing::{Sliceable, SliceMeta}; use board_artiq::drtioaux; use board_misoc::{mem, config, spiflash}; +use log::LevelFilter; +use logger_artiq::BufferLogger; use io::{Cursor, ProtoRead, ProtoWrite}; use proto_artiq::drtioaux_proto::SAT_PAYLOAD_MAX_SIZE; +pub fn clear_log() -> Result<(), ()> { + BufferLogger::with(|logger| { + let mut buffer = logger.buffer()?; + Ok(buffer.clear()) + }).map_err(|()| error!("error on clearing log buffer")) +} + +pub fn byte_to_level_filter(level_byte: u8) -> Result { + Ok(match level_byte { + 0 => LevelFilter::Off, + 1 => LevelFilter::Error, + 2 => LevelFilter::Warn, + 3 => LevelFilter::Info, + 4 => LevelFilter::Debug, + 5 => LevelFilter::Trace, + lv => { + error!("unknown log level: {}", lv); + return Err(()); + } + }) +} + pub struct Manager { config_payload: Cursor>, image_payload: Cursor>, last_value: Sliceable, + last_log: Sliceable, } impl Manager { @@ -21,6 +46,7 @@ impl Manager { config_payload: Cursor::new(Vec::new()), image_payload: Cursor::new(Vec::new()), last_value: Sliceable::new(0, Vec::new()), + last_log: Sliceable::new(0, Vec::new()), } } @@ -30,6 +56,22 @@ impl Manager { )).map_err(|_err| warn!("read error: no such key")) } + pub fn log_get_slice(&mut self, data_slice: &mut [u8; SAT_PAYLOAD_MAX_SIZE], consume: bool) -> Result { + // Populate buffer if depleted + if self.last_log.at_end() { + BufferLogger::with(|logger| { + let mut buffer = logger.buffer()?; + self.last_log = Sliceable::new(0, buffer.extract().as_bytes().to_vec()); + if consume { + buffer.clear(); + } + Ok(()) + }).map_err(|()| error!("error on getting log buffer"))?; + } + + Ok(self.last_log.get_slice_satellite(data_slice)) + } + pub fn get_config_value_slice(&mut self, data_slice: &mut [u8; SAT_PAYLOAD_MAX_SIZE]) -> SliceMeta { self.last_value.get_slice_satellite(data_slice) }