forked from M-Labs/artiq
satman: support remote drtio instruction for core mgmt
This commit is contained in:
parent
aa0fecbb73
commit
259c5a2dc5
|
@ -21,6 +21,7 @@ use board_artiq::si5324;
|
|||
use board_artiq::si549;
|
||||
#[cfg(soc_platform = "kasli")]
|
||||
use board_misoc::irq;
|
||||
use board_misoc::spiflash;
|
||||
use board_artiq::{spi, drtioaux, drtio_routing};
|
||||
#[cfg(soc_platform = "efc")]
|
||||
use board_artiq::ad9117;
|
||||
|
@ -30,6 +31,7 @@ use board_artiq::drtio_eem;
|
|||
use riscv::register::{mcause, mepc, mtval};
|
||||
use dma::Manager as DmaManager;
|
||||
use kernel::Manager as KernelManager;
|
||||
use mgmt::Manager as CoreManager;
|
||||
use analyzer::Analyzer;
|
||||
|
||||
#[global_allocator]
|
||||
|
@ -41,6 +43,7 @@ mod dma;
|
|||
mod analyzer;
|
||||
mod kernel;
|
||||
mod cache;
|
||||
mod mgmt;
|
||||
|
||||
fn drtiosat_reset(reset: bool) {
|
||||
unsafe {
|
||||
|
@ -129,7 +132,7 @@ macro_rules! forward {
|
|||
($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,
|
||||
router: &mut routing::Router, self_destination: &mut u8, packet: drtioaux::Packet
|
||||
) -> Result<(), drtioaux::Error<!>> {
|
||||
|
@ -489,6 +492,105 @@ 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, .. } => {
|
||||
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");
|
||||
Ok(())
|
||||
|
@ -497,13 +599,13 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
|
||||
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,
|
||||
destination: &mut u8) {
|
||||
let result =
|
||||
drtioaux::recv(0).and_then(|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)
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -823,6 +925,7 @@ pub extern fn main() -> i32 {
|
|||
let mut dma_manager = DmaManager::new();
|
||||
let mut analyzer = Analyzer::new();
|
||||
let mut kernelmgr = KernelManager::new();
|
||||
let mut coremgr = CoreManager::new();
|
||||
|
||||
cricon_select(RtioMaster::Drtio);
|
||||
drtioaux::reset(0);
|
||||
|
@ -832,7 +935,7 @@ pub extern fn main() -> i32 {
|
|||
while drtiosat_link_rx_up() {
|
||||
drtiosat_process_errors();
|
||||
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);
|
||||
for rep in repeaters.iter_mut() {
|
||||
rep.service(&routing_table, rank, destination, &mut router);
|
||||
|
|
|
@ -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);
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue