2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-27 20:28:25 +08:00

satman: support remote drtio instruction for core mgmt

This commit is contained in:
occheung 2024-08-26 17:40:43 +08:00
parent e57d18a41f
commit 05578b282e
2 changed files with 159 additions and 4 deletions

View File

@ -21,6 +21,7 @@ use board_artiq::si5324;
use board_artiq::si549; use board_artiq::si549;
#[cfg(soc_platform = "kasli")] #[cfg(soc_platform = "kasli")]
use board_misoc::irq; use board_misoc::irq;
use board_misoc::spiflash;
use board_artiq::{spi, drtioaux, drtio_routing}; use board_artiq::{spi, drtioaux, drtio_routing};
#[cfg(soc_platform = "efc")] #[cfg(soc_platform = "efc")]
use board_artiq::ad9117; use board_artiq::ad9117;
@ -30,6 +31,7 @@ use board_artiq::drtio_eem;
use riscv::register::{mcause, mepc, mtval}; use riscv::register::{mcause, mepc, mtval};
use dma::Manager as DmaManager; use dma::Manager as DmaManager;
use kernel::Manager as KernelManager; use kernel::Manager as KernelManager;
use mgmt::Manager as CoreManager;
use analyzer::Analyzer; use analyzer::Analyzer;
#[global_allocator] #[global_allocator]
@ -41,6 +43,7 @@ mod dma;
mod analyzer; mod analyzer;
mod kernel; mod kernel;
mod cache; mod cache;
mod mgmt;
fn drtiosat_reset(reset: bool) { fn drtiosat_reset(reset: bool) {
unsafe { unsafe {
@ -129,7 +132,7 @@ macro_rules! forward {
($router:expr, $routing_table:expr, $destination:expr, $rank:expr, $self_destination:expr, $repeaters:expr, $packet:expr) => {} ($router:expr, $routing_table:expr, $destination:expr, $rank:expr, $self_destination:expr, $repeaters:expr, $packet:expr) => {}
} }
fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmgr: &mut KernelManager, fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmgr: &mut KernelManager, coremgr: &mut CoreManager,
_repeaters: &mut [repeater::Repeater], _routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8, _repeaters: &mut [repeater::Repeater], _routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8,
router: &mut routing::Router, self_destination: &mut u8, packet: drtioaux::Packet router: &mut routing::Router, self_destination: &mut u8, packet: drtioaux::Packet
) -> Result<(), drtioaux::Error<!>> { ) -> Result<(), drtioaux::Error<!>> {
@ -495,6 +498,105 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
Ok(()) Ok(())
} }
drtioaux::Packet::CoreMgmtGetLogRequest { destination: _destination, .. } |
drtioaux::Packet::CoreMgmtClearLogRequest { destination: _destination } |
drtioaux::Packet::CoreMgmtSetLogLevelRequest {destination: _destination, .. } => {
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::CoreMgmtNack)
}
drtioaux::Packet::CoreMgmtSetUartLogLevelRequest { 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::CoreMgmtNack)
}
drtioaux::Packet::CoreMgmtConfigReadRequest {
destination: _destination,
length,
key,
} => {
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
let mut value_slice = [0; SAT_PAYLOAD_MAX_SIZE];
let key_slice = &key[..length as usize];
if !key_slice.is_ascii() {
error!("invalid key");
drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack)
} else {
let key = core::str::from_utf8(key_slice).unwrap();
if coremgr.fetch_config_value(key).is_ok() {
let meta = coremgr.get_config_value_slice(&mut value_slice);
drtioaux::send(
0,
&drtioaux::Packet::CoreMgmtConfigReadReply {
length: meta.len as u16,
last: meta.status.is_last(),
value: value_slice,
},
)
} else {
drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack)
}
}
}
drtioaux::Packet::CoreMgmtConfigReadContinue {
destination: _destination,
} => {
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
let mut value_slice = [0; SAT_PAYLOAD_MAX_SIZE];
let meta = coremgr.get_config_value_slice(&mut value_slice);
drtioaux::send(
0,
&drtioaux::Packet::CoreMgmtConfigReadReply {
length: meta.len as u16,
last: meta.status.is_last(),
value: value_slice,
},
)
}
drtioaux::Packet::CoreMgmtConfigWriteRequest { destination: _destination, length, last, data } => {
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
coremgr.add_data(&data, length as usize);
let mut succeeded = true;
if last {
succeeded = coremgr.write_config().is_ok();
debug!("Write succeeded: {}", succeeded);
coremgr.clear_data();
}
if succeeded {
drtioaux::send(0, &drtioaux::Packet::CoreMgmtAck)
} else {
drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack)
}
}
drtioaux::Packet::CoreMgmtConfigRemoveRequest { destination: _destination, length, key } => {
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
let key = core::str::from_utf8(&key[..length as usize]).unwrap();
let succeeded = config::remove(key)
.map_err(|err| warn!("error on removing config: {:?}", err))
.is_ok();
if succeeded {
drtioaux::send(0, &drtioaux::Packet::CoreMgmtAck)
} else {
drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack)
}
}
drtioaux::Packet::CoreMgmtRebootRequest { destination: _destination } => {
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
drtioaux::send(0, &drtioaux::Packet::CoreMgmtAck)?;
warn!("restarting");
unsafe { spiflash::reload(); }
}
_ => { _ => {
warn!("received unexpected aux packet"); warn!("received unexpected aux packet");
Ok(()) Ok(())
@ -503,13 +605,13 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
} }
fn process_aux_packets(dma_manager: &mut DmaManager, analyzer: &mut Analyzer, fn process_aux_packets(dma_manager: &mut DmaManager, analyzer: &mut Analyzer,
kernelmgr: &mut KernelManager, repeaters: &mut [repeater::Repeater], kernelmgr: &mut KernelManager, coremgr: &mut CoreManager, repeaters: &mut [repeater::Repeater],
routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8, router: &mut routing::Router, routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8, router: &mut routing::Router,
destination: &mut u8) { destination: &mut u8) {
let result = let result =
drtioaux::recv(0).and_then(|packet| { drtioaux::recv(0).and_then(|packet| {
if let Some(packet) = packet.or_else(|| router.get_local_packet()) { if let Some(packet) = packet.or_else(|| router.get_local_packet()) {
process_aux_packet(dma_manager, analyzer, kernelmgr, process_aux_packet(dma_manager, analyzer, kernelmgr, coremgr,
repeaters, routing_table, rank, router, destination, packet) repeaters, routing_table, rank, router, destination, packet)
} else { } else {
Ok(()) Ok(())
@ -834,6 +936,7 @@ pub extern fn main() -> i32 {
let mut dma_manager = DmaManager::new(); let mut dma_manager = DmaManager::new();
let mut analyzer = Analyzer::new(); let mut analyzer = Analyzer::new();
let mut kernelmgr = KernelManager::new(); let mut kernelmgr = KernelManager::new();
let mut coremgr = CoreManager::new();
cricon_select(RtioMaster::Drtio); cricon_select(RtioMaster::Drtio);
drtioaux::reset(0); drtioaux::reset(0);
@ -843,7 +946,7 @@ pub extern fn main() -> i32 {
while drtiosat_link_rx_up() { while drtiosat_link_rx_up() {
drtiosat_process_errors(); drtiosat_process_errors();
process_aux_packets(&mut dma_manager, &mut analyzer, process_aux_packets(&mut dma_manager, &mut analyzer,
&mut kernelmgr, &mut repeaters, &mut routing_table, &mut kernelmgr, &mut coremgr, &mut repeaters, &mut routing_table,
&mut rank, &mut router, &mut destination); &mut rank, &mut router, &mut destination);
for rep in repeaters.iter_mut() { for rep in repeaters.iter_mut() {
rep.service(&routing_table, rank, destination, &mut router); rep.service(&routing_table, rank, destination, &mut router);

View File

@ -0,0 +1,52 @@
use alloc::vec::Vec;
use routing::{Sliceable, SliceMeta};
use board_misoc::config;
use io::{Cursor, ProtoRead, ProtoWrite};
use proto_artiq::drtioaux_proto::SAT_PAYLOAD_MAX_SIZE;
type Result<T> = core::result::Result<T, ()>;
pub struct Manager {
current_payload: Cursor<Vec<u8>>,
last_value: Sliceable,
}
impl Manager {
pub fn new() -> Manager {
Manager {
current_payload: Cursor::new(Vec::new()),
last_value: Sliceable::new(0, Vec::new()),
}
}
pub fn fetch_config_value(&mut self, key: &str) -> Result<()> {
config::read(key, |result| result.map(
|value| self.last_value = Sliceable::new(0, value.to_vec())
)).map_err(|_err| warn!("read error: no such key"))
}
pub fn get_config_value_slice(&mut self, data_slice: &mut [u8; SAT_PAYLOAD_MAX_SIZE]) -> SliceMeta {
self.last_value.get_slice_sat(data_slice)
}
pub fn add_data(&mut self, data: &[u8], data_len: usize) {
self.current_payload.write_all(&data[..data_len]).unwrap();
}
pub fn clear_data(&mut self) {
self.current_payload.get_mut().clear();
self.current_payload.set_position(0);
}
pub fn write_config(&mut self) -> Result<()> {
let key = self.current_payload.read_string().map_err(
|err| error!("error on reading key: {:?}", err))?;
let value = self.current_payload.read_bytes().unwrap();
config::write(&key, &value).map_err(|err| {
error!("error on writing config: {:?}", err);
})
}
}