diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index 952a18439..b178d8e29 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -14,8 +14,8 @@ mod remote_i2c { use rtio_mgt::drtio; use sched::{Io, Mutex}; - pub fn start(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result<(), &'static str> { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cStartRequest { + pub fn start(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result<(), &'static str> { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::I2cStartRequest { destination: destination, busno: busno }); @@ -34,8 +34,8 @@ mod remote_i2c { } } - pub fn restart(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result<(), &'static str> { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cRestartRequest { + pub fn restart(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result<(), &'static str> { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::I2cRestartRequest { destination: destination, busno: busno }); @@ -54,8 +54,8 @@ mod remote_i2c { } } - pub fn stop(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result<(), &'static str> { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cStopRequest { + pub fn stop(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result<(), &'static str> { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::I2cStopRequest { destination: destination, busno: busno }); @@ -74,8 +74,8 @@ mod remote_i2c { } } - pub fn write(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, data: u8) -> Result { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cWriteRequest { + pub fn write(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, data: u8) -> Result { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::I2cWriteRequest { destination: destination, busno: busno, data: data @@ -95,8 +95,8 @@ mod remote_i2c { } } - pub fn read(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, ack: bool) -> Result { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cReadRequest { + pub fn read(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, ack: bool) -> Result { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::I2cReadRequest { destination: destination, busno: busno, ack: ack @@ -116,8 +116,8 @@ mod remote_i2c { } } - pub fn switch_select(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, address: u8, mask: u8) -> Result<(), &'static str> { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::I2cSwitchSelectRequest { + pub fn switch_select(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, address: u8, mask: u8) -> Result<(), &'static str> { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::I2cSwitchSelectRequest { destination: destination, busno: busno, address: address, @@ -145,8 +145,8 @@ mod remote_spi { use rtio_mgt::drtio; use sched::{Io, Mutex}; - pub fn set_config(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::SpiSetConfigRequest { + pub fn set_config(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::SpiSetConfigRequest { destination: destination, busno: busno, flags: flags, @@ -169,8 +169,8 @@ mod remote_spi { } } - pub fn write(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, data: u32) -> Result<(), ()> { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::SpiWriteRequest { + pub fn write(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8, data: u32) -> Result<(), ()> { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::SpiWriteRequest { destination: destination, busno: busno, data: data @@ -190,8 +190,8 @@ mod remote_spi { } } - pub fn read(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::SpiReadRequest { + pub fn read(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, busno: u8) -> Result { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::SpiReadRequest { destination: destination, busno: busno }); @@ -214,7 +214,7 @@ mod remote_spi { #[cfg(has_drtio)] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{ let destination = ($busno >> 16) as u8; let busno = $busno as u8; let hop = $routing_table.0[destination as usize][0]; @@ -222,27 +222,28 @@ macro_rules! dispatch { $mod_local::$func(busno, $($param, )*) } else { let linkno = hop - 1; - $mod_remote::$func($io, $aux_mutex, linkno, destination, busno, $($param, )*) + $mod_remote::$func($io, $aux_mutex, $ddma_mutex, linkno, destination, busno, $($param, )*) } }} } #[cfg(not(has_drtio))] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident,$mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{ let busno = $busno as u8; $mod_local::$func(busno, $($param, )*) }} } pub fn process_kern_hwreq(io: &Io, aux_mutex: &Mutex, + ddma_mutex: &Mutex, _routing_table: &drtio_routing::RoutingTable, _up_destinations: &Urc>, request: &kern::Message) -> Result> { match request { &kern::RtioInitRequest => { info!("resetting RTIO"); - rtio_mgt::reset(io, aux_mutex); + rtio_mgt::reset(io, aux_mutex, ddma_mutex); kern_acknowledge() } @@ -258,47 +259,47 @@ pub fn process_kern_hwreq(io: &Io, aux_mutex: &Mutex, } &kern::I2cStartRequest { busno } => { - let succeeded = dispatch!(io, aux_mutex, local_i2c, remote_i2c, _routing_table, busno, start).is_ok(); + let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, start).is_ok(); kern_send(io, &kern::I2cBasicReply { succeeded: succeeded }) } &kern::I2cRestartRequest { busno } => { - let succeeded = dispatch!(io, aux_mutex, local_i2c, remote_i2c, _routing_table, busno, restart).is_ok(); + let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, restart).is_ok(); kern_send(io, &kern::I2cBasicReply { succeeded: succeeded }) } &kern::I2cStopRequest { busno } => { - let succeeded = dispatch!(io, aux_mutex, local_i2c, remote_i2c, _routing_table, busno, stop).is_ok(); + let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, stop).is_ok(); kern_send(io, &kern::I2cBasicReply { succeeded: succeeded }) } &kern::I2cWriteRequest { busno, data } => { - match dispatch!(io, aux_mutex, local_i2c, remote_i2c, _routing_table, busno, write, data) { + match dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, write, data) { Ok(ack) => kern_send(io, &kern::I2cWriteReply { succeeded: true, ack: ack }), Err(_) => kern_send(io, &kern::I2cWriteReply { succeeded: false, ack: false }) } } &kern::I2cReadRequest { busno, ack } => { - match dispatch!(io, aux_mutex, local_i2c, remote_i2c, _routing_table, busno, read, ack) { + match dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, read, ack) { Ok(data) => kern_send(io, &kern::I2cReadReply { succeeded: true, data: data }), Err(_) => kern_send(io, &kern::I2cReadReply { succeeded: false, data: 0xff }) } } &kern::I2cSwitchSelectRequest { busno, address, mask } => { - let succeeded = dispatch!(io, aux_mutex, local_i2c, remote_i2c, _routing_table, busno, + let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, switch_select, address, mask).is_ok(); kern_send(io, &kern::I2cBasicReply { succeeded: succeeded }) } &kern::SpiSetConfigRequest { busno, flags, length, div, cs } => { - let succeeded = dispatch!(io, aux_mutex, local_spi, remote_spi, _routing_table, busno, + let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_spi, remote_spi, _routing_table, busno, set_config, flags, length, div, cs).is_ok(); kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) }, &kern::SpiWriteRequest { busno, data } => { - let succeeded = dispatch!(io, aux_mutex, local_spi, remote_spi, _routing_table, busno, + let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_spi, remote_spi, _routing_table, busno, write, data).is_ok(); kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) } &kern::SpiReadRequest { busno } => { - match dispatch!(io, aux_mutex, local_spi, remote_spi, _routing_table, busno, read) { + match dispatch!(io, aux_mutex, ddma_mutex, local_spi, remote_spi, _routing_table, busno, read) { Ok(data) => kern_send(io, &kern::SpiReadReply { succeeded: true, data: data }), Err(_) => kern_send(io, &kern::SpiReadReply { succeeded: false, data: 0 }) } diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 5c54aeffa..994c9dfc0 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -204,8 +204,9 @@ fn startup() { #[cfg(any(has_rtio_moninj, has_drtio))] { let aux_mutex = aux_mutex.clone(); + let ddma_mutex = ddma_mutex.clone(); let drtio_routing_table = drtio_routing_table.clone(); - io.spawn(4096, move |io| { moninj::thread(io, &aux_mutex, &drtio_routing_table) }); + io.spawn(4096, move |io| { moninj::thread(io, &aux_mutex, &ddma_mutex, &drtio_routing_table) }); } #[cfg(has_rtio_analyzer)] io.spawn(4096, analyzer::thread); diff --git a/artiq/firmware/runtime/moninj.rs b/artiq/firmware/runtime/moninj.rs index 36d4bbb47..88f6c6aaf 100644 --- a/artiq/firmware/runtime/moninj.rs +++ b/artiq/firmware/runtime/moninj.rs @@ -53,8 +53,8 @@ mod remote_moninj { use rtio_mgt::drtio; use sched::{Io, Mutex}; - pub fn read_probe(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, probe: u8) -> u64 { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::MonitorRequest { + pub fn read_probe(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, probe: u8) -> u64 { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::MonitorRequest { destination: destination, channel: channel, probe: probe @@ -67,7 +67,7 @@ mod remote_moninj { 0 } - pub fn inject(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8, value: u8) { + pub fn inject(io: &Io, aux_mutex: &Mutex, _ddma_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8, value: u8) { let _lock = aux_mutex.lock(io).unwrap(); drtioaux::send(linkno, &drtioaux::Packet::InjectionRequest { destination: destination, @@ -77,8 +77,8 @@ mod remote_moninj { }).unwrap(); } - pub fn read_injection_status(io: &Io, aux_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8) -> u8 { - let reply = drtio::aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::InjectionStatusRequest { + pub fn read_injection_status(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8) -> u8 { + let reply = drtio::aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::InjectionStatusRequest { destination: destination, channel: channel, overrd: overrd @@ -94,7 +94,7 @@ mod remote_moninj { #[cfg(has_drtio)] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ let destination = ($channel >> 16) as u8; let channel = $channel as u16; let hop = $routing_table.0[destination as usize][0]; @@ -102,20 +102,20 @@ macro_rules! dispatch { local_moninj::$func(channel, $($param, )*) } else { let linkno = hop - 1; - remote_moninj::$func($io, $aux_mutex, linkno, destination, channel, $($param, )*) + remote_moninj::$func($io, $aux_mutex, $ddma_mutex, linkno, destination, channel, $($param, )*) } }} } #[cfg(not(has_drtio))] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ let channel = $channel as u16; local_moninj::$func(channel, $($param, )*) }} } -fn connection_worker(io: &Io, _aux_mutex: &Mutex, _routing_table: &drtio_routing::RoutingTable, +fn connection_worker(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _routing_table: &drtio_routing::RoutingTable, mut stream: &mut TcpStream) -> Result<(), Error> { let mut probe_watch_list = BTreeMap::new(); let mut inject_watch_list = BTreeMap::new(); @@ -144,9 +144,9 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _routing_table: &drtio_routing let _ = inject_watch_list.remove(&(channel, overrd)); } }, - HostMessage::Inject { channel, overrd, value } => dispatch!(io, _aux_mutex, _routing_table, channel, inject, overrd, value), + HostMessage::Inject { channel, overrd, value } => dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, inject, overrd, value), HostMessage::GetInjectionStatus { channel, overrd } => { - let value = dispatch!(io, _aux_mutex, _routing_table, channel, read_injection_status, overrd); + let value = dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, read_injection_status, overrd); let reply = DeviceMessage::InjectionStatus { channel: channel, overrd: overrd, @@ -163,7 +163,7 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _routing_table: &drtio_routing if clock::get_ms() > next_check { for (&(channel, probe), previous) in probe_watch_list.iter_mut() { - let current = dispatch!(io, _aux_mutex, _routing_table, channel, read_probe, probe); + let current = dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, read_probe, probe); if previous.is_none() || previous.unwrap() != current { let message = DeviceMessage::MonitorStatus { channel: channel, @@ -178,7 +178,7 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _routing_table: &drtio_routing } } for (&(channel, overrd), previous) in inject_watch_list.iter_mut() { - let current = dispatch!(io, _aux_mutex, _routing_table, channel, read_injection_status, overrd); + let current = dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, read_injection_status, overrd); if previous.is_none() || previous.unwrap() != current { let message = DeviceMessage::InjectionStatus { channel: channel, @@ -199,18 +199,19 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _routing_table: &drtio_routing } } -pub fn thread(io: Io, aux_mutex: &Mutex, routing_table: &Urc>) { +pub fn thread(io: Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, routing_table: &Urc>) { let listener = TcpListener::new(&io, 2047); listener.listen(1383).expect("moninj: cannot listen"); loop { let aux_mutex = aux_mutex.clone(); + let ddma_mutex = ddma_mutex.clone(); let routing_table = routing_table.clone(); let stream = listener.accept().expect("moninj: cannot accept").into_handle(); io.spawn(16384, move |io| { let routing_table = routing_table.borrow(); let mut stream = TcpStream::from_handle(&io, stream); - match connection_worker(&io, &aux_mutex, &routing_table, &mut stream) { + match connection_worker(&io, &aux_mutex, &ddma_mutex, &routing_table, &mut stream) { Ok(()) => {}, Err(err) => error!("moninj aborted: {}", err) } diff --git a/artiq/firmware/runtime/rtio_dma.rs b/artiq/firmware/runtime/rtio_dma.rs index d388d9bfc..517d1d10b 100644 --- a/artiq/firmware/runtime/rtio_dma.rs +++ b/artiq/firmware/runtime/rtio_dma.rs @@ -95,7 +95,7 @@ pub mod remote_dma { let _lock = ddma_mutex.lock(io).unwrap(); let destinations = unsafe { TRACES.get(&id).unwrap() }; for destination in destinations.keys() { - match drtio::ddma_send_erase(io, aux_mutex, routing_table, id, *destination) { + match drtio::ddma_send_erase(io, aux_mutex, ddma_mutex, routing_table, id, *destination) { Ok(_) => (), Err(e) => error!("Error erasing trace on DMA: {}", e) } @@ -108,7 +108,7 @@ pub mod remote_dma { let _lock = ddma_mutex.lock(io); let traces = unsafe { TRACES.get_mut(&id).unwrap() }; for (destination, mut trace) in traces { - match drtio::ddma_upload_trace(io, aux_mutex, routing_table, id, *destination, trace.get_trace()) + match drtio::ddma_upload_trace(io, aux_mutex, ddma_mutex, routing_table, id, *destination, trace.get_trace()) { Ok(_) => trace.state = RemoteState::Loaded, Err(e) => error!("Error adding DMA trace on destination {}: {}", destination, e) @@ -132,7 +132,7 @@ pub mod remote_dma { continue; } } - match drtio::ddma_send_playback(io, aux_mutex, routing_table, ddma_mutex, id, *destination, timestamp) { + match drtio::ddma_send_playback(io, aux_mutex, ddma_mutex, routing_table, id, *destination, timestamp) { Ok(_) => (), Err(e) => error!("Error during remote DMA playback: {}", e) } @@ -159,7 +159,7 @@ pub mod remote_dma { for (id, dest_traces) in traces_iter { if let Some(trace) = dest_traces.get_mut(&destination) { if up { - match drtio::ddma_upload_trace(io, aux_mutex, routing_table, *id, destination, trace.get_trace()) + match drtio::ddma_upload_trace(io, aux_mutex, ddma_mutex, routing_table, *id, destination, trace.get_trace()) { Ok(_) => trace.state = RemoteState::Loaded, Err(e) => error!("Error adding DMA trace on destination {}: {}", destination, e) @@ -223,8 +223,7 @@ impl Manager { let mut local_trace = Vec::new(); let mut _remote_traces: BTreeMap> = BTreeMap::new(); - #[cfg(has_drtio)] - if _enable_ddma { + if _enable_ddma & cfg!(has_drtio) { let mut trace = Vec::new(); mem::swap(&mut self.recording_trace, &mut trace); trace.push(0); diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index 15a67be75..964c5dc02 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -62,14 +62,23 @@ pub mod drtio { } } - pub fn aux_transact(io: &Io, aux_mutex: &Mutex, - linkno: u8, request: &drtioaux::Packet) -> Result { + pub fn aux_transact(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + linkno: u8, request: &drtioaux::Packet ) -> Result { let _lock = aux_mutex.lock(io).unwrap(); drtioaux::send(linkno, request).unwrap(); - recv_aux_timeout(io, linkno, 200) + loop { + let reply = recv_aux_timeout(io, linkno, 200); + match reply { + Ok(drtioaux::Packet::DmaPlaybackStatus { id, destination, error, channel, timestamp }) => { + remote_dma::playback_done(io, ddma_mutex, id, destination, error, channel, timestamp); + }, + Ok(packet) => return Ok(packet), + Err(e) => return Err(e) + } + } } - fn ping_remote(io: &Io, aux_mutex: &Mutex, linkno: u8) -> u32 { + fn ping_remote(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8) -> u32 { let mut count = 0; loop { if !link_rx_up(linkno) { @@ -79,7 +88,7 @@ pub mod drtio { if count > 100 { return 0; } - let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::EchoRequest); + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::EchoRequest); match reply { Ok(drtioaux::Packet::EchoReply) => { // make sure receive buffer is drained @@ -115,10 +124,10 @@ pub mod drtio { } } - fn load_routing_table(io: &Io, aux_mutex: &Mutex, linkno: u8, routing_table: &drtio_routing::RoutingTable) - -> Result<(), &'static str> { + fn load_routing_table(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + linkno: u8, routing_table: &drtio_routing::RoutingTable) -> Result<(), &'static str> { for i in 0..drtio_routing::DEST_COUNT { - let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::RoutingSetPath { + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::RoutingSetPath { destination: i as u8, hops: routing_table.0[i] })?; @@ -129,8 +138,8 @@ pub mod drtio { Ok(()) } - fn set_rank(io: &Io, aux_mutex: &Mutex, linkno: u8, rank: u8) -> Result<(), &'static str> { - let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::RoutingSetRank { + fn set_rank(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8, rank: u8) -> Result<(), &'static str> { + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::RoutingSetRank { rank: rank })?; if reply != drtioaux::Packet::RoutingAck { @@ -221,7 +230,7 @@ pub mod drtio { let linkno = hop - 1; if destination_up(up_destinations, destination) { if up_links[linkno as usize] { - let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::DestinationStatusRequest { + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DestinationStatusRequest { destination: destination }); match reply { @@ -251,7 +260,7 @@ pub mod drtio { } } else { if up_links[linkno as usize] { - let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::DestinationStatusRequest { + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DestinationStatusRequest { destination: destination }); match reply { @@ -291,17 +300,17 @@ pub mod drtio { /* link was previously down */ if link_rx_up(linkno) { info!("[LINK#{}] link RX became up, pinging", linkno); - let ping_count = ping_remote(&io, aux_mutex, linkno); + let ping_count = ping_remote(&io, aux_mutex, ddma_mutex, linkno); if ping_count > 0 { info!("[LINK#{}] remote replied after {} packets", linkno, ping_count); up_links[linkno as usize] = true; if let Err(e) = sync_tsc(&io, aux_mutex, linkno) { error!("[LINK#{}] failed to sync TSC ({})", linkno, e); } - if let Err(e) = load_routing_table(&io, aux_mutex, linkno, routing_table) { + if let Err(e) = load_routing_table(&io, aux_mutex, ddma_mutex, linkno, routing_table) { error!("[LINK#{}] failed to load routing table ({})", linkno, e); } - if let Err(e) = set_rank(&io, aux_mutex, linkno, 1) { + if let Err(e) = set_rank(&io, aux_mutex, ddma_mutex, linkno, 1) { error!("[LINK#{}] failed to set rank ({})", linkno, e); } info!("[LINK#{}] link initialization completed", linkno); @@ -316,7 +325,7 @@ pub mod drtio { } } - pub fn reset(io: &Io, aux_mutex: &Mutex) { + pub fn reset(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex) { for linkno in 0..csr::DRTIO.len() { unsafe { (csr::DRTIO[linkno].reset_write)(1); @@ -332,7 +341,7 @@ pub mod drtio { for linkno in 0..csr::DRTIO.len() { let linkno = linkno as u8; if link_rx_up(linkno) { - let reply = aux_transact(io, aux_mutex, linkno, + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::ResetRequest); match reply { Ok(drtioaux::Packet::ResetAck) => (), @@ -343,7 +352,7 @@ pub mod drtio { } } - pub fn ddma_upload_trace(io: &Io, aux_mutex: &Mutex, + pub fn ddma_upload_trace(io: &Io, aux_mutex: &Mutex, ddma_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; @@ -354,7 +363,7 @@ pub mod drtio { let last = i + len == trace.len(); trace_slice[..len].clone_from_slice(&trace[i..i+len]); i += len; - let reply = aux_transact(io, aux_mutex, linkno, + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DmaAddTraceRequest { id: id, destination: destination, last: last, length: len as u16, trace: trace_slice}); match reply { @@ -369,45 +378,35 @@ pub mod drtio { } - pub fn ddma_send_erase(io: &Io, aux_mutex: &Mutex, + pub fn ddma_send_erase(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, id: u32, destination: u8) -> Result<(), &'static str> { let linkno = routing_table.0[destination as usize][0] - 1; - let reply = aux_transact(io, aux_mutex, linkno, + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DmaRemoveTraceRequest { id: id, destination: destination }); match reply { Ok(drtioaux::Packet::DmaRemoveTraceReply { succeeded: true }) => Ok(()), Ok(drtioaux::Packet::DmaRemoveTraceReply { succeeded: false }) => Err("satellite DMA erase error"), - Ok(_) => Err("adding trace failed, unexpected aux packet"), + Ok(_) => Err("erasing trace failed, unexpected aux packet"), Err(_) => Err("erasing trace failed, aux error") } } - pub fn ddma_send_playback(io: &Io, aux_mutex: &Mutex, + pub fn ddma_send_playback(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, - ddma_mutex: &Mutex, id: u32, destination: u8, timestamp: u64) -> Result<(), &'static str> { + id: u32, destination: u8, timestamp: u64) -> Result<(), &'static str> { let linkno = routing_table.0[destination as usize][0] - 1; - let _lock = aux_mutex.lock(io).unwrap(); - drtioaux::send(linkno, &drtioaux::Packet::DmaPlaybackRequest{ - id: id, destination: destination, timestamp: timestamp }).unwrap(); - loop { - let reply = recv_aux_timeout(io, linkno, 200); - match reply { - Ok(drtioaux::Packet::DmaPlaybackReply { succeeded: true }) => { return Ok(()) }, - Ok(drtioaux::Packet::DmaPlaybackReply { succeeded: false }) => { - return Err("error on DMA playback request") }, - // in case we received status from another destination - // but we want to get DmaPlaybackReply anyway, thus the loop - Ok(drtioaux::Packet::DmaPlaybackStatus { id, destination, error, channel, timestamp }) => { - remote_dma::playback_done(io, ddma_mutex, id, destination, error, channel, timestamp); - }, - Ok(_) => { return Err("received unexpected aux packet while DMA playback") }, - Err(_) => { return Err("aux error on DMA playback") } - } + let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DmaPlaybackRequest{ + id: id, destination: destination, timestamp: timestamp }); + match reply { + Ok(drtioaux::Packet::DmaPlaybackReply { succeeded: true }) => return Ok(()), + Ok(drtioaux::Packet::DmaPlaybackReply { succeeded: false }) => + return Err("error on DMA playback request"), + Ok(_) => return Err("received unexpected aux packet during DMA playback"), + Err(_) => return Err("aux error on DMA playback") } } - } #[cfg(not(has_drtio))] @@ -418,7 +417,7 @@ pub mod drtio { _routing_table: &Urc>, _up_destinations: &Urc>, _ddma_mutex: &Mutex) {} - pub fn reset(_io: &Io, _aux_mutex: &Mutex) {} + pub fn reset(_io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex) {} } static mut SEEN_ASYNC_ERRORS: u8 = 0; @@ -501,9 +500,9 @@ pub fn startup(io: &Io, aux_mutex: &Mutex, io.spawn(4096, async_error_thread); } -pub fn reset(io: &Io, aux_mutex: &Mutex) { +pub fn reset(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex) { unsafe { csr::rtio_core::reset_write(1); } - drtio::reset(io, aux_mutex) + drtio::reset(io, aux_mutex, ddma_mutex) } diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 04ef42864..2096dcc94 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -349,7 +349,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, kern_recv_dotrace(request); - if kern_hwreq::process_kern_hwreq(io, aux_mutex, routing_table, up_destinations, request)? { + if kern_hwreq::process_kern_hwreq(io, aux_mutex, ddma_mutex, routing_table, up_destinations, request)? { return Ok(false) } @@ -384,7 +384,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, &kern::DmaRecordStop { duration, enable_ddma } => { let _id = session.congress.dma_manager.record_stop(duration, enable_ddma, io, ddma_mutex); #[cfg(has_drtio)] - { + if enable_ddma { remote_dma::upload_traces(io, aux_mutex, routing_table, ddma_mutex, _id); } cache::flush_l2_cache();