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;
|
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<!>> {
|
||||||
|
@ -489,6 +492,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(())
|
||||||
|
@ -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,
|
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(())
|
||||||
|
@ -823,6 +925,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);
|
||||||
|
@ -832,7 +935,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);
|
||||||
|
|
|
@ -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