mirror of https://github.com/m-labs/artiq.git
dma: pass "uses_ddma" for non-remote recordings
This commit is contained in:
parent
b5d9062ba9
commit
918d30b900
|
@ -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)
|
||||
|
|
|
@ -371,7 +371,8 @@ extern fn dma_erase(name: &CSlice<u8>) {
|
|||
#[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<u8>) -> 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<u8>) -> 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)")
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ pub enum Message<'a> {
|
|||
DmaRetrieveReply {
|
||||
trace: Option<&'a [u8]>,
|
||||
duration: u64,
|
||||
uses_ddma: bool,
|
||||
},
|
||||
|
||||
DmaStartRemoteRequest {
|
||||
|
|
|
@ -17,6 +17,7 @@ pub mod remote_dma {
|
|||
Loaded,
|
||||
PlaybackEnded { error: u8, channel: u32, timestamp: u64 }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct RemoteTrace {
|
||||
trace: Vec<u8>,
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -146,9 +146,9 @@ fn host_write<W>(writer: &mut W, reply: host::Reply) -> Result<(), IoError<W::Wr
|
|||
pub fn kern_send(io: &Io, request: &kern::Message) -> Result<(), Error<SchedError>> {
|
||||
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,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue