diff --git a/artiq/firmware/libproto_artiq/drtioaux_proto.rs b/artiq/firmware/libproto_artiq/drtioaux_proto.rs index 94f26dca7..4a962f6fe 100644 --- a/artiq/firmware/libproto_artiq/drtioaux_proto.rs +++ b/artiq/firmware/libproto_artiq/drtioaux_proto.rs @@ -14,8 +14,11 @@ impl From> for Error { } } -pub const DMA_TRACE_MAX_SIZE: usize = /*max size*/512 - /*CRC*/4 - /*packet ID*/1 - /*trace ID*/4 - /*last*/1 -/*length*/2; -pub const ANALYZER_MAX_SIZE: usize = /*max size*/512 - /*CRC*/4 - /*packet ID*/1 - /*last*/1 - /*length*/2; +// maximum size of arbitrary payloads +// used by satellite -> master analyzer, subkernel exceptions +pub const SAT_PAYLOAD_MAX_SIZE: usize = /*max size*/512 - /*CRC*/4 - /*packet ID*/1 - /*last*/1 - /*length*/2; +// used by DDMA, subkernel program data (need to provide extra ID and destination) +pub const MASTER_PAYLOAD_MAX_SIZE: usize = SAT_PAYLOAD_MAX_SIZE - /*destination*/1 - /*ID*/4; #[derive(PartialEq, Debug)] pub enum Packet { @@ -61,9 +64,9 @@ pub enum Packet { AnalyzerHeaderRequest { destination: u8 }, AnalyzerHeader { sent_bytes: u32, total_byte_count: u64, overflow_occurred: bool }, AnalyzerDataRequest { destination: u8 }, - AnalyzerData { last: bool, length: u16, data: [u8; ANALYZER_MAX_SIZE]}, + AnalyzerData { last: bool, length: u16, data: [u8; SAT_PAYLOAD_MAX_SIZE]}, - DmaAddTraceRequest { destination: u8, id: u32, last: bool, length: u16, trace: [u8; DMA_TRACE_MAX_SIZE] }, + DmaAddTraceRequest { destination: u8, id: u32, last: bool, length: u16, trace: [u8; MASTER_PAYLOAD_MAX_SIZE] }, DmaAddTraceReply { succeeded: bool }, DmaRemoveTraceRequest { destination: u8, id: u32 }, DmaRemoveTraceReply { succeeded: bool }, @@ -215,7 +218,7 @@ impl Packet { 0xa3 => { let last = reader.read_bool()?; let length = reader.read_u16()?; - let mut data: [u8; ANALYZER_MAX_SIZE] = [0; ANALYZER_MAX_SIZE]; + let mut data: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE]; reader.read_exact(&mut data[0..length as usize])?; Packet::AnalyzerData { last: last, @@ -229,7 +232,7 @@ impl Packet { let id = reader.read_u32()?; let last = reader.read_bool()?; let length = reader.read_u16()?; - let mut trace: [u8; DMA_TRACE_MAX_SIZE] = [0; DMA_TRACE_MAX_SIZE]; + let mut trace: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; reader.read_exact(&mut trace[0..length as usize])?; Packet::DmaAddTraceRequest { destination: destination, diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index 3ead188b5..f643fafd5 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -17,7 +17,7 @@ pub mod drtio { use super::*; use alloc::vec::Vec; use drtioaux; - use proto_artiq::drtioaux_proto::DMA_TRACE_MAX_SIZE; + use proto_artiq::drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE; use rtio_dma::remote_dma; #[cfg(has_rtio_analyzer)] use analyzer::remote_analyzer::RemoteBuffer; @@ -372,28 +372,36 @@ pub mod drtio { } } - pub fn ddma_upload_trace(io: &Io, aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, - id: u32, destination: u8, trace: &Vec) -> Result<(), &'static str> { - let linkno = routing_table.0[destination as usize][0] - 1; + fn partition_data(data: &[u8], send_f: F) -> Result<(), &'static str> + where F: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], bool, usize) -> Result<(), &'static str> { let mut i = 0; - while i < trace.len() { - let mut trace_slice: [u8; DMA_TRACE_MAX_SIZE] = [0; DMA_TRACE_MAX_SIZE]; - let len: usize = if i + DMA_TRACE_MAX_SIZE < trace.len() { DMA_TRACE_MAX_SIZE } else { trace.len() - i } as usize; - let last = i + len == trace.len(); - trace_slice[..len].clone_from_slice(&trace[i..i+len]); + while i < data.len() { + let mut slice: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE]; + let len: usize = if i + MASTER_PAYLOAD_MAX_SIZE < data.len() { MASTER_PAYLOAD_MAX_SIZE } else { data.len() - i } as usize; + let last = i + len == data.len(); + slice[..len].clone_from_slice(&data[i..i+len]); i += len; + send_f(&slice, last, len)?; + } + Ok(()) + } + + pub fn ddma_upload_trace(io: &Io, aux_mutex: &Mutex, + routing_table: &drtio_routing::RoutingTable, + id: u32, destination: u8, trace: &[u8]) -> Result<(), &'static str> { + let linkno = routing_table.0[destination as usize][0] - 1; + partition_data(trace, |slice, last, len: usize| { let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::DmaAddTraceRequest { - id: id, destination: destination, last: last, length: len as u16, trace: trace_slice}); + id: id, destination: destination, last: last, length: len as u16, trace: *slice}); match reply { - Ok(drtioaux::Packet::DmaAddTraceReply { succeeded: true }) => (), - Ok(drtioaux::Packet::DmaAddTraceReply { succeeded: false }) => { - return Err("error adding trace on satellite"); }, - Ok(_) => { return Err("adding DMA trace failed, unexpected aux packet"); }, - Err(_) => { return Err("adding DMA trace failed, aux error"); } + Ok(drtioaux::Packet::DmaAddTraceReply { succeeded: true }) => Ok(()), + Ok(drtioaux::Packet::DmaAddTraceReply { succeeded: false }) => + Err("error adding trace on satellite"), + Ok(_) => Err("adding DMA trace failed, unexpected aux packet"), + Err(_) => Err("adding DMA trace failed, aux error") } - } - Ok(()) + }) } pub fn ddma_send_erase(io: &Io, aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, diff --git a/artiq/firmware/satman/analyzer.rs b/artiq/firmware/satman/analyzer.rs index e2a43ba22..72f9e8c2b 100644 --- a/artiq/firmware/satman/analyzer.rs +++ b/artiq/firmware/satman/analyzer.rs @@ -1,6 +1,6 @@ use core::cmp::min; use board_misoc::{csr, cache}; -use proto_artiq::drtioaux_proto::ANALYZER_MAX_SIZE; +use proto_artiq::drtioaux_proto::SAT_PAYLOAD_MAX_SIZE; const BUFFER_SIZE: usize = 512 * 1024; @@ -86,10 +86,10 @@ impl Analyzer { } } - pub fn get_data(&mut self, data_slice: &mut [u8; ANALYZER_MAX_SIZE]) -> AnalyzerSliceMeta { + pub fn get_data(&mut self, data_slice: &mut [u8; SAT_PAYLOAD_MAX_SIZE]) -> AnalyzerSliceMeta { let data = unsafe { &BUFFER.data[..] }; let i = (self.data_pointer + self.sent_bytes) % BUFFER_SIZE; - let len = min(ANALYZER_MAX_SIZE, self.data_len - self.sent_bytes); + let len = min(SAT_PAYLOAD_MAX_SIZE, self.data_len - self.sent_bytes); let last = self.sent_bytes + len == self.data_len; if i + len >= BUFFER_SIZE { diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index c524483fc..4384e68d3 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -17,8 +17,7 @@ use board_artiq::si5324; use board_artiq::{spi, drtioaux}; #[cfg(soc_platform = "efc")] use board_artiq::ad9117; -use board_artiq::drtio_routing; -use proto_artiq::drtioaux_proto::ANALYZER_MAX_SIZE; +use proto_artiq::drtioaux_proto::{SAT_PAYLOAD_MAX_SIZE, MASTER_PAYLOAD_MAX_SIZE}; #[cfg(has_drtio_eem)] use board_artiq::drtio_eem; use riscv::register::{mcause, mepc, mtval}; @@ -328,7 +327,7 @@ fn process_aux_packet(_manager: &mut DmaManager, analyzer: &mut Analyzer, _repea drtioaux::Packet::AnalyzerDataRequest { destination: _destination } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - let mut data_slice: [u8; ANALYZER_MAX_SIZE] = [0; ANALYZER_MAX_SIZE]; + let mut data_slice: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE]; let meta = analyzer.get_data(&mut data_slice); drtioaux::send(0, &drtioaux::Packet::AnalyzerData { last: meta.last,