From 918d30b90072d4c1afbdf17215f24d15edc09e62 Mon Sep 17 00:00:00 2001 From: mwojcik Date: Fri, 14 Apr 2023 14:41:34 +0800 Subject: [PATCH] dma: pass "uses_ddma" for non-remote recordings --- artiq/coredevice/dma.py | 16 +++++++------- artiq/firmware/ksupport/lib.rs | 21 ++++++++++--------- artiq/firmware/libproto_artiq/kernel_proto.rs | 1 + artiq/firmware/runtime/rtio_dma.rs | 6 ++++++ artiq/firmware/runtime/session.rs | 14 ++++++++++--- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/artiq/coredevice/dma.py b/artiq/coredevice/dma.py index ff4aa01cb..9868b7fdd 100644 --- a/artiq/coredevice/dma.py +++ b/artiq/coredevice/dma.py @@ -25,11 +25,11 @@ def dma_erase(name: TStr) -> TNone: raise NotImplementedError("syscall not simulated") @syscall -def dma_retrieve(name: TStr) -> TTuple([TInt64, TInt32]): +def dma_retrieve(name: TStr) -> TTuple([TInt64, TInt32, TBool]): raise NotImplementedError("syscall not simulated") @syscall -def dma_playback(timestamp: TInt64, ptr: TInt32) -> TNone: +def dma_playback(timestamp: TInt64, ptr: TInt32, enable_ddma: TBool) -> TNone: raise NotImplementedError("syscall not simulated") @@ -101,24 +101,24 @@ class CoreDMA: def playback(self, name): """Replays a previously recorded DMA trace. This function blocks until the entire trace is submitted to the RTIO FIFOs.""" - (advance_mu, ptr) = dma_retrieve(name) - dma_playback(now_mu(), ptr) + (advance_mu, ptr, uses_ddma) = dma_retrieve(name) + dma_playback(now_mu(), ptr, uses_ddma) delay_mu(advance_mu) @kernel def get_handle(self, name): """Returns a handle to a previously recorded DMA trace. The returned handle is only valid until the next call to :meth:`record` or :meth:`erase`.""" - (advance_mu, ptr) = dma_retrieve(name) - return (self.epoch, advance_mu, ptr) + (advance_mu, ptr, uses_ddma) = dma_retrieve(name) + return (self.epoch, advance_mu, ptr, uses_ddma) @kernel def playback_handle(self, handle): """Replays a handle obtained with :meth:`get_handle`. Using this function is much faster than :meth:`playback` for replaying a set of traces repeatedly, but incurs the overhead of managing the handles onto the programmer.""" - (epoch, advance_mu, ptr) = handle + (epoch, advance_mu, ptr, uses_ddma) = handle if self.epoch != epoch: raise DMAError("Invalid handle") - dma_playback(now_mu(), ptr) + dma_playback(now_mu(), ptr, uses_ddma) delay_mu(advance_mu) diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 6693b7196..0c949f2b2 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -371,7 +371,8 @@ extern fn dma_erase(name: &CSlice) { #[repr(C)] struct DmaTrace { duration: i64, - address: i32 + address: i32, + uses_ddma: bool, } #[unwind(allowed)] @@ -379,11 +380,12 @@ extern fn dma_retrieve(name: &CSlice) -> DmaTrace { let name = str::from_utf8(name.as_ref()).unwrap(); send(&DmaRetrieveRequest { name: name }); - recv!(&DmaRetrieveReply { trace, duration } => { + recv!(&DmaRetrieveReply { trace, duration, uses_ddma } => { match trace { Some(bytes) => Ok(DmaTrace { address: bytes.as_ptr() as i32, - duration: duration as i64 + duration: duration as i64, + uses_ddma: uses_ddma, }), None => Err(()) } @@ -396,7 +398,7 @@ extern fn dma_retrieve(name: &CSlice) -> DmaTrace { #[cfg(has_rtio_dma)] #[unwind(allowed)] -extern fn dma_playback(timestamp: i64, ptr: i32) { +extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { assert!(ptr % 64 == 0); unsafe { @@ -406,7 +408,9 @@ extern fn dma_playback(timestamp: i64, ptr: i32) { csr::cri_con::selected_write(1); csr::rtio_dma::enable_write(1); #[cfg(has_drtio)] - send(&DmaStartRemoteRequest { id: ptr as i32, timestamp: timestamp }); + if _uses_ddma { + send(&DmaStartRemoteRequest { id: ptr as i32, timestamp: timestamp }); + } while csr::rtio_dma::enable_read() != 0 {} csr::cri_con::selected_write(0); @@ -429,22 +433,19 @@ extern fn dma_playback(timestamp: i64, ptr: i32) { } #[cfg(has_drtio)] - { + if _uses_ddma { send(&DmaAwaitRemoteRequest { id: ptr as i32 }); recv!(&DmaAwaitRemoteReply { timeout, error, channel, timestamp } => { if timeout { - println!("timeout\n"); raise!("DMAError", "Error running DMA on satellite device, timed out waiting for results"); } if error & 1 != 0 { - println!("rtio underflow from ddma\n"); raise!("RTIOUnderflow", "RTIO underflow at channel {rtio_channel_info:0}, {1} mu", channel as i64, timestamp as i64, 0); } if error & 2 != 0 { - println!("rtio destun from ddma\n"); raise!("RTIODestinationUnreachable", "RTIO destination unreachable, output, at channel {rtio_channel_info:0}, {1} mu", channel as i64, timestamp as i64, 0); @@ -455,7 +456,7 @@ extern fn dma_playback(timestamp: i64, ptr: i32) { #[cfg(not(has_rtio_dma))] #[unwind(allowed)] -extern fn dma_playback(_timestamp: i64, _ptr: i32) { +extern fn dma_playback(_timestamp: i64, _ptr: i32, _uses_ddma: bool) { unimplemented!("not(has_rtio_dma)") } diff --git a/artiq/firmware/libproto_artiq/kernel_proto.rs b/artiq/firmware/libproto_artiq/kernel_proto.rs index e723ea2f5..cc17147cd 100644 --- a/artiq/firmware/libproto_artiq/kernel_proto.rs +++ b/artiq/firmware/libproto_artiq/kernel_proto.rs @@ -34,6 +34,7 @@ pub enum Message<'a> { DmaRetrieveReply { trace: Option<&'a [u8]>, duration: u64, + uses_ddma: bool, }, DmaStartRemoteRequest { diff --git a/artiq/firmware/runtime/rtio_dma.rs b/artiq/firmware/runtime/rtio_dma.rs index 517d1d10b..c057edaeb 100644 --- a/artiq/firmware/runtime/rtio_dma.rs +++ b/artiq/firmware/runtime/rtio_dma.rs @@ -17,6 +17,7 @@ pub mod remote_dma { Loaded, PlaybackEnded { error: u8, channel: u32, timestamp: u64 } } + #[derive(Debug, Clone)] struct RemoteTrace { trace: Vec, @@ -169,7 +170,12 @@ pub mod remote_dma { } } } + } + pub fn has_remote_traces(io: &Io, ddma_mutex: &Mutex, id: u32) -> bool { + let _lock = ddma_mutex.lock(io).unwrap(); + let trace_list = unsafe { TRACES.get(&id).unwrap() }; + !trace_list.is_empty() } } diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index f99f08ae6..95b3ca28f 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -146,9 +146,9 @@ fn host_write(writer: &mut W, reply: host::Reply) -> Result<(), IoError Result<(), Error> { match request { &kern::LoadRequest(_) => debug!("comm->kern LoadRequest(...)"), - &kern::DmaRetrieveReply { trace, duration } => { + &kern::DmaRetrieveReply { trace, duration, uses_ddma } => { if trace.map(|data| data.len() > 100).unwrap_or(false) { - debug!("comm->kern DmaRetrieveReply {{ trace: ..., duration: {:?} }}", duration) + debug!("comm->kern DmaRetrieveReply {{ trace: ..., duration: {:?}, uses_ddma: {} }}", duration, uses_ddma) } else { debug!("comm->kern {:?}", request) } @@ -400,9 +400,17 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, } &kern::DmaRetrieveRequest { name } => { session.congress.dma_manager.with_trace(name, |trace, duration| { + #[cfg(has_drtio)] + let uses_ddma = match trace { + Some(trace) => remote_dma::has_remote_traces(io, aux_mutex, trace.as_ptr() as u32), + None => false + }; + #[cfg(not(has_drtio))] + let uses_ddma = false; kern_send(io, &kern::DmaRetrieveReply { trace: trace, - duration: duration + duration: duration, + uses_ddma: uses_ddma, }) }) }