From 4495f6035e244c70b10cf04da9c9a8a0fc6b3309 Mon Sep 17 00:00:00 2001 From: mwojcik Date: Fri, 17 Nov 2023 10:52:31 +0800 Subject: [PATCH] master: support source parameters --- artiq/firmware/runtime/kernel.rs | 10 +++--- artiq/firmware/runtime/rtio_mgt.rs | 33 ++++++++--------- artiq/firmware/satman/dma.rs | 26 +++++++------- artiq/firmware/satman/kernel.rs | 37 ++++++++++++------- artiq/firmware/satman/main.rs | 57 ++++++++++++++++-------------- 5 files changed, 91 insertions(+), 72 deletions(-) diff --git a/artiq/firmware/runtime/kernel.rs b/artiq/firmware/runtime/kernel.rs index a308e6c1c..124b17f19 100644 --- a/artiq/firmware/runtime/kernel.rs +++ b/artiq/firmware/runtime/kernel.rs @@ -103,7 +103,7 @@ pub mod subkernel { pub enum FinishStatus { Ok, CommLost, - Exception + Exception(u8) // exception source } #[derive(Debug, PartialEq, Clone, Copy)] @@ -216,7 +216,7 @@ pub mod subkernel { Ok(()) } - pub fn subkernel_finished(io: &Io, subkernel_mutex: &Mutex, id: u32, with_exception: bool) { + pub fn subkernel_finished(io: &Io, subkernel_mutex: &Mutex, id: u32, with_exception: bool, exception_src: u8) { // called upon receiving DRTIO SubkernelRunDone let _lock = subkernel_mutex.lock(io).unwrap(); let subkernel = unsafe { SUBKERNELS.get_mut(&id) }; @@ -226,7 +226,7 @@ pub mod subkernel { if subkernel.state == SubkernelState::Running { subkernel.state = SubkernelState::Finished { status: match with_exception { - true => FinishStatus::Exception, + true => FinishStatus::Exception(exception_src), false => FinishStatus::Ok, } } @@ -266,9 +266,9 @@ pub mod subkernel { Ok(SubkernelFinished { id: id, comm_lost: status == FinishStatus::CommLost, - exception: if status == FinishStatus::Exception { + exception: if let FinishStatus::Exception(dest) = status { Some(drtio::subkernel_retrieve_exception(io, aux_mutex, - routing_table, subkernel.destination)?) + routing_table, dest)?) } else { None } }) }, diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index 44661e822..1e17ab63d 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -104,11 +104,11 @@ pub mod drtio { remote_dma::playback_done(io, ddma_mutex, id, destination, error, channel, timestamp); None }, - drtioaux::Packet::SubkernelFinished { id, with_exception } => { - subkernel::subkernel_finished(io, subkernel_mutex, id, with_exception); + drtioaux::Packet::SubkernelFinished { id, destination: 0, with_exception, exception_src } => { + subkernel::subkernel_finished(io, subkernel_mutex, id, with_exception, exception_src); None }, - drtioaux::Packet::SubkernelMessage { id, destination: from, status, length, data } => { + drtioaux::Packet::SubkernelMessage { id, source: 0, destination: from, status, length, data } => { subkernel::message_handle_incoming(io, subkernel_mutex, id, status, length as usize, &data); // acknowledge receiving part of the message drtioaux::send(linkno, @@ -456,10 +456,10 @@ pub mod drtio { partition_data(trace, |slice, status, len: usize| { let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::DmaAddTraceRequest { - id: id, destination: destination, status: status, length: len as u16, trace: *slice})?; + id: id, source: 0, destination: destination, status: status, length: len as u16, trace: *slice})?; match reply { - drtioaux::Packet::DmaAddTraceReply { succeeded: true } => Ok(()), - drtioaux::Packet::DmaAddTraceReply { succeeded: false } => Err(Error::DmaAddTraceFail(destination)), + drtioaux::Packet::DmaAddTraceReply { destination: 0, succeeded: true } => Ok(()), + drtioaux::Packet::DmaAddTraceReply { destination: 0, succeeded: false } => Err(Error::DmaAddTraceFail(destination)), packet => Err(Error::UnexpectedPacket(packet)), } }) @@ -469,10 +469,10 @@ pub mod drtio { id: u32, destination: u8) -> Result<(), Error> { let linkno = routing_table.0[destination as usize][0] - 1; let reply = aux_transact(io, aux_mutex, linkno, - &drtioaux::Packet::DmaRemoveTraceRequest { id: id, destination: destination })?; + &drtioaux::Packet::DmaRemoveTraceRequest { id: id, source: 0, destination: destination })?; match reply { - drtioaux::Packet::DmaRemoveTraceReply { succeeded: true } => Ok(()), - drtioaux::Packet::DmaRemoveTraceReply { succeeded: false } => Err(Error::DmaEraseFail(destination)), + drtioaux::Packet::DmaRemoveTraceReply { destination: 0, succeeded: true } => Ok(()), + drtioaux::Packet::DmaRemoveTraceReply { destination: 0, succeeded: false } => Err(Error::DmaEraseFail(destination)), packet => Err(Error::UnexpectedPacket(packet)), } } @@ -481,10 +481,10 @@ pub mod drtio { id: u32, destination: u8, timestamp: u64) -> Result<(), Error> { let linkno = routing_table.0[destination as usize][0] - 1; let reply = aux_transact(io, aux_mutex, linkno, - &drtioaux::Packet::DmaPlaybackRequest{ id: id, destination: destination, timestamp: timestamp })?; + &drtioaux::Packet::DmaPlaybackRequest{ id: id, source: 0, destination: destination, timestamp: timestamp })?; match reply { - drtioaux::Packet::DmaPlaybackReply { succeeded: true } => Ok(()), - drtioaux::Packet::DmaPlaybackReply { succeeded: false } => + drtioaux::Packet::DmaPlaybackReply { destination: 0, succeeded: true } => Ok(()), + drtioaux::Packet::DmaPlaybackReply { destination: 0, succeeded: false } => Err(Error::DmaPlaybackFail(destination)), packet => Err(Error::UnexpectedPacket(packet)), } @@ -559,10 +559,10 @@ pub mod drtio { id: u32, destination: u8, run: bool) -> Result<(), Error> { let linkno = routing_table.0[destination as usize][0] - 1; let reply = aux_transact(io, aux_mutex, linkno, - &drtioaux::Packet::SubkernelLoadRunRequest{ id: id, destination: destination, run: run })?; + &drtioaux::Packet::SubkernelLoadRunRequest{ id: id, source: 0, destination: destination, run: run })?; match reply { - drtioaux::Packet::SubkernelLoadRunReply { succeeded: true } => Ok(()), - drtioaux::Packet::SubkernelLoadRunReply { succeeded: false } => + drtioaux::Packet::SubkernelLoadRunReply { destination: 0, succeeded: true } => Ok(()), + drtioaux::Packet::SubkernelLoadRunReply { destination: 0, succeeded: false } => Err(Error::SubkernelRunFail(destination)), packet => Err(Error::UnexpectedPacket(packet)), } @@ -595,7 +595,8 @@ pub mod drtio { partition_data(message, |slice, status, len: usize| { let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::SubkernelMessage { - destination: destination, id: id, status: status, length: len as u16, data: *slice})?; + source: 0, destination: destination, + id: id, status: status, length: len as u16, data: *slice})?; match reply { drtioaux::Packet::SubkernelMessageAck { .. } => Ok(()), packet => Err(Error::UnexpectedPacket(packet)), diff --git a/artiq/firmware/satman/dma.rs b/artiq/firmware/satman/dma.rs index 277e27927..6b9ea3f70 100644 --- a/artiq/firmware/satman/dma.rs +++ b/artiq/firmware/satman/dma.rs @@ -33,7 +33,7 @@ struct Entry { #[derive(Debug)] pub struct Manager { - entries: BTreeMap, + entries: BTreeMap<(u8, u32), Entry>, state: ManagerState, currentid: u32 } @@ -52,30 +52,30 @@ impl Manager { } } - pub fn add(&mut self, id: u32, status: PayloadStatus, trace: &[u8], trace_len: usize) -> Result<(), Error> { + pub fn add(&mut self, source: u8, id: u32, status: PayloadStatus, trace: &[u8], trace_len: usize) -> Result<(), Error> { if status.is_first() { - self.entries.remove(&id); + self.entries.remove(&(source, id)); } - let entry = match self.entries.get_mut(&id) { + let entry = match self.entries.get_mut(&(source, id)) { Some(entry) => { if entry.complete { // replace entry - self.entries.remove(&id); - self.entries.insert(id, Entry { + self.entries.remove(&(source, id)); + self.entries.insert((source, id), Entry { trace: Vec::new(), padding_len: 0, complete: false }); - self.entries.get_mut(&id).unwrap() + self.entries.get_mut(&(source, id)).unwrap() } else { entry } }, None => { - self.entries.insert(id, Entry { + self.entries.insert((source, id), Entry { trace: Vec::new(), padding_len: 0, complete: false }); - self.entries.get_mut(&id).unwrap() + self.entries.get_mut(&(source, id)).unwrap() }, }; entry.trace.extend(&trace[0..trace_len]); @@ -102,19 +102,19 @@ impl Manager { Ok(()) } - pub fn erase(&mut self, id: u32) -> Result<(), Error> { - match self.entries.remove(&id) { + pub fn erase(&mut self, source: u8, id: u32) -> Result<(), Error> { + match self.entries.remove(&(source, id)) { Some(_) => Ok(()), None => Err(Error::IdNotFound) } } - pub fn playback(&mut self, id: u32, timestamp: u64) -> Result<(), Error> { + pub fn playback(&mut self, source: u8, id: u32, timestamp: u64) -> Result<(), Error> { if self.state != ManagerState::Idle { return Err(Error::PlaybackInProgress); } - let entry = match self.entries.get(&id){ + let entry = match self.entries.get(&(source, id)){ Some(entry) => entry, None => { return Err(Error::IdNotFound); } }; diff --git a/artiq/firmware/satman/kernel.rs b/artiq/firmware/satman/kernel.rs index 850a126a0..33b5ed0bb 100644 --- a/artiq/firmware/satman/kernel.rs +++ b/artiq/firmware/satman/kernel.rs @@ -128,6 +128,7 @@ struct Session { kernel_state: KernelState, log_buffer: String, last_exception: Option, + source: u8, // which destination requested running the kernel messages: MessageManager } @@ -147,7 +148,9 @@ pub struct Manager { pub struct SubkernelFinished { pub id: u32, - pub with_exception: bool + pub with_exception: bool, + pub exception_source: u8, + pub source: u8 } pub struct SliceMeta { @@ -288,6 +291,7 @@ impl Session { kernel_state: KernelState::Absent, log_buffer: String::new(), last_exception: None, + source: 0, messages: MessageManager::new() } } @@ -369,12 +373,13 @@ impl Manager { unsafe { self.cache.unborrow() } } - pub fn run(&mut self, id: u32) -> Result<(), Error> { + pub fn run(&mut self, source: u8, id: u32) -> Result<(), Error> { info!("starting subkernel #{}", id); if self.session.kernel_state != KernelState::Loaded || self.current_id != id { self.load(id)?; } + self.session.source = source; self.session.kernel_state = KernelState::Running; cricon_select(RtioMaster::Kernel); @@ -477,7 +482,7 @@ impl Manager { } } - pub fn process_kern_requests(&mut self, rank: u8) { + pub fn process_kern_requests(&mut self, destination: u8) { if !self.is_running() { return; } @@ -490,26 +495,34 @@ impl Manager { self.session.kernel_state = KernelState::Absent; unsafe { self.cache.unborrow() } self.session.last_exception = Some(exception); - self.last_finished = Some(SubkernelFinished { id: self.current_id, with_exception: true }) + self.last_finished = Some(SubkernelFinished { + source: self.session.source, id: self.current_id, with_exception: true, exception_source: destination + }) }, Err(e) => { error!("Error while running processing external messages: {:?}", e); self.stop(); self.runtime_exception(e); - self.last_finished = Some(SubkernelFinished { id: self.current_id, with_exception: true }) + self.last_finished = Some(SubkernelFinished { + source: self.session.source, id: self.current_id, with_exception: true, exception_source: destination + }) } } - match self.process_kern_message(rank) { + match self.process_kern_message(destination) { Ok(Some(with_exception)) => { - self.last_finished = Some(SubkernelFinished { id: self.current_id, with_exception: with_exception }) + self.last_finished = Some(SubkernelFinished { + source: self.session.source, id: self.current_id, with_exception: with_exception, exception_source: destination + }) }, Ok(None) | Err(Error::NoMessage) => (), Err(e) => { error!("Error while running kernel: {:?}", e); self.stop(); self.runtime_exception(e); - self.last_finished = Some(SubkernelFinished { id: self.current_id, with_exception: true }) + self.last_finished = Some(SubkernelFinished { + source: self.session.source, id: self.current_id, with_exception: true, exception_source: destination + }) } } } @@ -543,7 +556,7 @@ impl Manager { } } - fn process_kern_message(&mut self, rank: u8) -> Result, Error> { + fn process_kern_message(&mut self, destination: u8) -> Result, Error> { // returns Ok(with_exception) on finish // None if the kernel is still running kern_recv(|request| { @@ -559,7 +572,7 @@ impl Manager { }, } - if process_kern_hwreq(request, rank)? { + if process_kern_hwreq(request, destination)? { return Ok(None) } @@ -759,7 +772,7 @@ fn pass_message_to_kernel(message: &Message, tags: &[u8]) -> Result<(), Error> { Ok(()) } -fn process_kern_hwreq(request: &kern::Message, rank: u8) -> Result { +fn process_kern_hwreq(request: &kern::Message, self_destination: u8) -> Result { match request { &kern::RtioInitRequest => { unsafe { @@ -774,7 +787,7 @@ fn process_kern_hwreq(request: &kern::Message, rank: u8) -> Result // only local destination is considered "up" // no access to other DRTIO destinations kern_send(&kern::RtioDestinationStatusReply { - up: destination == rank }) + up: destination == self_destination }) } &kern::I2cStartRequest { busno } => { diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 1856c56b2..dbe4b08d4 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -104,7 +104,7 @@ macro_rules! forward { fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmgr: &mut KernelManager, _repeaters: &mut [repeater::Repeater], _routing_table: &mut drtio_routing::RoutingTable, _rank: &mut u8, - packet: drtioaux::Packet) -> Result<(), drtioaux::Error> { + self_destination: &mut u8, packet: drtioaux::Packet) -> Result<(), drtioaux::Error> { // In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels, // and u16 otherwise; hence the `as _` conversion. match packet { @@ -138,13 +138,14 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg } else if let Some(subkernel_finished) = kernelmgr.get_last_finished() { info!("subkernel {} finished, with exception: {}", subkernel_finished.id, subkernel_finished.with_exception); drtioaux::send(0, &drtioaux::Packet::SubkernelFinished { - id: subkernel_finished.id, with_exception: subkernel_finished.with_exception + destination: subkernel_finished.source, id: subkernel_finished.id, + with_exception: subkernel_finished.with_exception, exception_src: *self_destination })?; } else if kernelmgr.message_is_ready() { let mut data_slice: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; let meta = kernelmgr.message_get_slice(&mut data_slice).unwrap(); drtioaux::send(0, &drtioaux::Packet::SubkernelMessage { - destination: destination, id: kernelmgr.get_current_id().unwrap(), + source: *self_destination, destination: 0, id: kernelmgr.get_current_id().unwrap(), status: meta.status, length: meta.len as u16, data: data_slice })?; } else { @@ -370,33 +371,35 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg }) } - drtioaux::Packet::DmaAddTraceRequest { destination: _destination, id, status, length, trace } => { - forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - let succeeded = dmamgr.add(id, status, &trace, length as usize).is_ok(); + drtioaux::Packet::DmaAddTraceRequest { source, destination, id, status, length, trace } => { + forward!(_routing_table, destination, *_rank, _repeaters, &packet); + *self_destination = destination; + let succeeded = dmamgr.add(source, id, status, &trace, length as usize).is_ok(); drtioaux::send(0, - &drtioaux::Packet::DmaAddTraceReply { succeeded: succeeded }) + &drtioaux::Packet::DmaAddTraceReply { destination: source, succeeded: succeeded }) } - drtioaux::Packet::DmaRemoveTraceRequest { destination: _destination, id } => { + drtioaux::Packet::DmaRemoveTraceRequest { source, destination: _destination, id } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - let succeeded = dmamgr.erase(id).is_ok(); + let succeeded = dmamgr.erase(source, id).is_ok(); drtioaux::send(0, - &drtioaux::Packet::DmaRemoveTraceReply { succeeded: succeeded }) + &drtioaux::Packet::DmaRemoveTraceReply { destination: source, succeeded: succeeded }) } - drtioaux::Packet::DmaPlaybackRequest { destination: _destination, id, timestamp } => { + drtioaux::Packet::DmaPlaybackRequest { source, destination: _destination, id, timestamp } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); // no DMA with a running kernel - let succeeded = !kernelmgr.is_running() && dmamgr.playback(id, timestamp).is_ok(); + let succeeded = !kernelmgr.is_running() && dmamgr.playback(source, id, timestamp).is_ok(); drtioaux::send(0, - &drtioaux::Packet::DmaPlaybackReply { succeeded: succeeded }) + &drtioaux::Packet::DmaPlaybackReply { destination: source, succeeded: succeeded }) } - drtioaux::Packet::SubkernelAddDataRequest { destination: _destination, id, status, length, data } => { - forward!(_routing_table, _destination, *_rank, _repeaters, &packet); + drtioaux::Packet::SubkernelAddDataRequest { destination, id, status, length, data } => { + forward!(_routing_table, destination, *_rank, _repeaters, &packet); + *self_destination = destination; let succeeded = kernelmgr.add(id, status, &data, length as usize).is_ok(); drtioaux::send(0, &drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded }) } - drtioaux::Packet::SubkernelLoadRunRequest { destination: _destination, id, run } => { + drtioaux::Packet::SubkernelLoadRunRequest { source, destination: _destination, id, run } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); let mut succeeded = kernelmgr.load(id).is_ok(); // allow preloading a kernel with delayed run @@ -405,11 +408,11 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg // cannot run kernel while DDMA is running succeeded = false; } else { - succeeded |= kernelmgr.run(id).is_ok(); + succeeded |= kernelmgr.run(source, id).is_ok(); } } drtioaux::send(0, - &drtioaux::Packet::SubkernelLoadRunReply { succeeded: succeeded }) + &drtioaux::Packet::SubkernelLoadRunReply { destination: source, succeeded: succeeded }) } drtioaux::Packet::SubkernelExceptionRequest { destination: _destination } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); @@ -421,11 +424,11 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg data: data_slice, }) } - drtioaux::Packet::SubkernelMessage { destination, id: _id, status, length, data } => { - forward!(_routing_table, destination, *_rank, _repeaters, &packet); + drtioaux::Packet::SubkernelMessage { source, destination: _destination, id: _id, status, length, data } => { + forward!(_routing_table, _destination, *_rank, _repeaters, &packet); kernelmgr.message_handle_incoming(status, length as usize, &data); drtioaux::send(0, &drtioaux::Packet::SubkernelMessageAck { - destination: destination + destination: source }) } drtioaux::Packet::SubkernelMessageAck { destination: _destination } => { @@ -434,7 +437,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg let mut data_slice: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; if let Some(meta) = kernelmgr.message_get_slice(&mut data_slice) { drtioaux::send(0, &drtioaux::Packet::SubkernelMessage { - destination: *_rank, id: kernelmgr.get_current_id().unwrap(), + source: *self_destination, destination: 0, id: kernelmgr.get_current_id().unwrap(), status: meta.status, length: meta.len as u16, data: data_slice })? } else { @@ -453,11 +456,12 @@ 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], - routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8) { + routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8, + destination: &mut u8) { let result = drtioaux::recv(0).and_then(|packet| { if let Some(packet) = packet { - process_aux_packet(dma_manager, analyzer, kernelmgr, repeaters, routing_table, rank, packet) + process_aux_packet(dma_manager, analyzer, kernelmgr, repeaters, routing_table, rank, destination, packet) } else { Ok(()) } @@ -670,6 +674,7 @@ pub extern fn main() -> i32 { } let mut routing_table = drtio_routing::RoutingTable::default_empty(); let mut rank = 1; + let mut destination = 1; let mut hardware_tick_ts = 0; @@ -715,7 +720,7 @@ pub extern fn main() -> i32 { drtiosat_process_errors(); process_aux_packets(&mut dma_manager, &mut analyzer, &mut kernelmgr, &mut repeaters, - &mut routing_table, &mut rank); + &mut routing_table, &mut rank, &mut destination); for rep in repeaters.iter_mut() { rep.service(&routing_table, rank); } @@ -738,7 +743,7 @@ pub extern fn main() -> i32 { error!("aux packet error: {}", e); } } - kernelmgr.process_kern_requests(rank); + kernelmgr.process_kern_requests(destination); } drtiosat_reset_phy(true);