From eb57b3b39397faaf4e247390e40505a9646c064b Mon Sep 17 00:00:00 2001 From: mwojcik Date: Thu, 24 Aug 2023 17:34:35 +0800 Subject: [PATCH] drtio: async messages become synchronous They are now a reply for DestinationStatusRequest. This prevents gateware errors and lost packets if the receiver is busy. --- artiq/firmware/runtime/analyzer.rs | 18 +-- artiq/firmware/runtime/kern_hwreq.rs | 137 ++++++++++++---------- artiq/firmware/runtime/main.rs | 6 +- artiq/firmware/runtime/moninj.rs | 55 +++++---- artiq/firmware/runtime/rtio_dma.rs | 24 ++-- artiq/firmware/runtime/rtio_mgt.rs | 163 +++++++++++++++------------ artiq/firmware/runtime/session.rs | 11 +- artiq/firmware/satman/main.rs | 68 +++++------ 8 files changed, 262 insertions(+), 220 deletions(-) diff --git a/artiq/firmware/runtime/analyzer.rs b/artiq/firmware/runtime/analyzer.rs index e7c555d76..fa62a535c 100644 --- a/artiq/firmware/runtime/analyzer.rs +++ b/artiq/firmware/runtime/analyzer.rs @@ -52,16 +52,18 @@ pub mod remote_analyzer { pub data: Vec } - pub fn get_data(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, - up_destinations: &Urc>) -> Result { + pub fn get_data(io: &Io, aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, + up_destinations: &Urc> + ) -> Result { // gets data from satellites and returns consolidated data let mut remote_data: Vec = Vec::new(); let mut remote_overflow = false; let mut remote_sent_bytes = 0; let mut remote_total_bytes = 0; - let data_vec = match drtio::analyzer_query(io, aux_mutex, ddma_mutex, routing_table, up_destinations) { + let data_vec = match drtio::analyzer_query( + io, aux_mutex, routing_table, up_destinations + ) { Ok(data_vec) => data_vec, Err(e) => return Err(e) }; @@ -83,7 +85,7 @@ pub mod remote_analyzer { -fn worker(stream: &mut TcpStream, _io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, +fn worker(stream: &mut TcpStream, _io: &Io, _aux_mutex: &Mutex, _routing_table: &drtio_routing::RoutingTable, _up_destinations: &Urc> ) -> Result<(), IoError> { @@ -97,7 +99,7 @@ fn worker(stream: &mut TcpStream, _io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mu #[cfg(has_drtio)] let remote = remote_analyzer::get_data( - _io, _aux_mutex, _ddma_mutex, _routing_table, _up_destinations); + _io, _aux_mutex, _routing_table, _up_destinations); #[cfg(has_drtio)] let (header, remote_data) = match remote { Ok(remote) => (Header { @@ -144,7 +146,7 @@ fn worker(stream: &mut TcpStream, _io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mu Ok(()) } -pub fn thread(io: Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, +pub fn thread(io: Io, aux_mutex: &Mutex, routing_table: &Urc>, up_destinations: &Urc>) { let listener = TcpListener::new(&io, 65535); @@ -159,7 +161,7 @@ pub fn thread(io: Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, disarm(); let routing_table = routing_table.borrow(); - match worker(&mut stream, &io, aux_mutex, ddma_mutex, &routing_table, up_destinations) { + match worker(&mut stream, &io, aux_mutex, &routing_table, up_destinations) { Ok(()) => (), Err(err) => error!("analyzer aborted: {}", err) } diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index b178d8e29..7fd0b379c 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -14,11 +14,14 @@ mod remote_i2c { use rtio_mgt::drtio; use sched::{Io, Mutex}; - 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 - }); + 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 { + destination: destination, + busno: busno + }); match reply { Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => { if succeeded { Ok(()) } else { Err("i2c basic reply error") } @@ -34,11 +37,14 @@ mod remote_i2c { } } - 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 - }); + 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 { + destination: destination, + busno: busno + }); match reply { Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => { if succeeded { Ok(()) } else { Err("i2c basic reply error") } @@ -54,11 +60,14 @@ mod remote_i2c { } } - 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 - }); + 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 { + destination: destination, + busno: busno + }); match reply { Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => { if succeeded { Ok(()) } else { Err("i2c basic reply error") } @@ -74,12 +83,15 @@ mod remote_i2c { } } - 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 - }); + 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 { + destination: destination, + busno: busno, + data: data + }); match reply { Ok(drtioaux::Packet::I2cWriteReply { succeeded, ack }) => { if succeeded { Ok(ack) } else { Err("i2c write reply error") } @@ -95,12 +107,15 @@ mod remote_i2c { } } - 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 - }); + 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 { + destination: destination, + busno: busno, + ack: ack + }); match reply { Ok(drtioaux::Packet::I2cReadReply { succeeded, data }) => { if succeeded { Ok(data) } else { Err("i2c read reply error") } @@ -116,13 +131,16 @@ mod remote_i2c { } } - 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, - mask: mask, - }); + 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 { + destination: destination, + busno: busno, + address: address, + mask: mask, + }); match reply { Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => { if succeeded { Ok(()) } else { Err("i2c basic reply error") } @@ -145,8 +163,10 @@ mod remote_spi { use rtio_mgt::drtio; use sched::{Io, Mutex}; - 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 { + 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 { destination: destination, busno: busno, flags: flags, @@ -169,8 +189,10 @@ mod remote_spi { } } - 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 { + 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 { destination: destination, busno: busno, data: data @@ -190,11 +212,13 @@ mod remote_spi { } } - 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 - }); + 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 { + destination: destination, + busno: busno + }); match reply { Ok(drtioaux::Packet::SpiReadReply { succeeded, data }) => { if succeeded { Ok(data) } else { Err(()) } @@ -214,7 +238,7 @@ mod remote_spi { #[cfg(has_drtio)] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_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,28 +246,27 @@ macro_rules! dispatch { $mod_local::$func(busno, $($param, )*) } else { let linkno = hop - 1; - $mod_remote::$func($io, $aux_mutex, $ddma_mutex, linkno, destination, busno, $($param, )*) + $mod_remote::$func($io, $aux_mutex, linkno, destination, busno, $($param, )*) } }} } #[cfg(not(has_drtio))] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_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, ddma_mutex); + rtio_mgt::reset(io, aux_mutex); kern_acknowledge() } @@ -259,47 +282,47 @@ pub fn process_kern_hwreq(io: &Io, aux_mutex: &Mutex, } &kern::I2cStartRequest { busno } => { - let succeeded = dispatch!(io, aux_mutex, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, start).is_ok(); + let succeeded = dispatch!(io, aux_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, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, restart).is_ok(); + let succeeded = dispatch!(io, aux_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, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, stop).is_ok(); + let succeeded = dispatch!(io, aux_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, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, write, data) { + match dispatch!(io, aux_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, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, read, ack) { + match dispatch!(io, aux_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, ddma_mutex, local_i2c, remote_i2c, _routing_table, busno, + let succeeded = dispatch!(io, aux_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, ddma_mutex, local_spi, remote_spi, _routing_table, busno, + let succeeded = dispatch!(io, aux_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, ddma_mutex, local_spi, remote_spi, _routing_table, busno, + let succeeded = dispatch!(io, aux_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, ddma_mutex, local_spi, remote_spi, _routing_table, busno, read) { + match dispatch!(io, aux_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 94cfd23c5..08367375a 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -210,17 +210,15 @@ 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, &ddma_mutex, &drtio_routing_table) }); + io.spawn(4096, move |io| { moninj::thread(io, &aux_mutex, &drtio_routing_table) }); } #[cfg(has_rtio_analyzer)] { let aux_mutex = aux_mutex.clone(); let drtio_routing_table = drtio_routing_table.clone(); let up_destinations = up_destinations.clone(); - let ddma_mutex = ddma_mutex.clone(); - io.spawn(8192, move |io| { analyzer::thread(io, &aux_mutex, &ddma_mutex, &drtio_routing_table, &up_destinations) }); + io.spawn(8192, move |io| { analyzer::thread(io, &aux_mutex, &drtio_routing_table, &up_destinations) }); } #[cfg(has_grabber)] diff --git a/artiq/firmware/runtime/moninj.rs b/artiq/firmware/runtime/moninj.rs index 88f6c6aaf..1ef6b4215 100644 --- a/artiq/firmware/runtime/moninj.rs +++ b/artiq/firmware/runtime/moninj.rs @@ -53,12 +53,14 @@ mod remote_moninj { use rtio_mgt::drtio; use sched::{Io, Mutex}; - 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 - }); + 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 { + destination: destination, + channel: channel, + probe: probe + }); match reply { Ok(drtioaux::Packet::MonitorReply { value }) => return value, Ok(packet) => error!("received unexpected aux packet: {:?}", packet), @@ -67,7 +69,8 @@ mod remote_moninj { 0 } - pub fn inject(io: &Io, aux_mutex: &Mutex, _ddma_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8, value: u8) { + pub fn inject(io: &Io, aux_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,12 +80,14 @@ mod remote_moninj { }).unwrap(); } - 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 - }); + 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 { + destination: destination, + channel: channel, + overrd: overrd + }); match reply { Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value, Ok(packet) => error!("received unexpected aux packet: {:?}", packet), @@ -94,7 +99,7 @@ mod remote_moninj { #[cfg(has_drtio)] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_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,21 +107,21 @@ macro_rules! dispatch { local_moninj::$func(channel, $($param, )*) } else { let linkno = hop - 1; - remote_moninj::$func($io, $aux_mutex, $ddma_mutex, linkno, destination, channel, $($param, )*) + remote_moninj::$func($io, $aux_mutex, linkno, destination, channel, $($param, )*) } }} } #[cfg(not(has_drtio))] macro_rules! dispatch { - ($io:ident, $aux_mutex:ident, $ddma_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ + ($io:ident, $aux_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, _ddma_mutex: &Mutex, _routing_table: &drtio_routing::RoutingTable, - mut stream: &mut TcpStream) -> Result<(), Error> { +fn connection_worker(io: &Io, _aux_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(); let mut next_check = 0; @@ -144,9 +149,10 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _routing_ let _ = inject_watch_list.remove(&(channel, overrd)); } }, - HostMessage::Inject { channel, overrd, value } => dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, inject, overrd, value), + HostMessage::Inject { channel, overrd, value } => dispatch!( + io, _aux_mutex, _routing_table, channel, inject, overrd, value), HostMessage::GetInjectionStatus { channel, overrd } => { - let value = dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, read_injection_status, overrd); + let value = dispatch!(io, _aux_mutex, _routing_table, channel, read_injection_status, overrd); let reply = DeviceMessage::InjectionStatus { channel: channel, overrd: overrd, @@ -163,7 +169,7 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _routing_ if clock::get_ms() > next_check { for (&(channel, probe), previous) in probe_watch_list.iter_mut() { - let current = dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, read_probe, probe); + let current = dispatch!(io, _aux_mutex, _routing_table, channel, read_probe, probe); if previous.is_none() || previous.unwrap() != current { let message = DeviceMessage::MonitorStatus { channel: channel, @@ -178,7 +184,7 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _routing_ } } for (&(channel, overrd), previous) in inject_watch_list.iter_mut() { - let current = dispatch!(io, _aux_mutex, _ddma_mutex, _routing_table, channel, read_injection_status, overrd); + let current = dispatch!(io, _aux_mutex, _routing_table, channel, read_injection_status, overrd); if previous.is_none() || previous.unwrap() != current { let message = DeviceMessage::InjectionStatus { channel: channel, @@ -199,19 +205,18 @@ fn connection_worker(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _routing_ } } -pub fn thread(io: Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, routing_table: &Urc>) { +pub fn thread(io: Io, aux_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, &ddma_mutex, &routing_table, &mut stream) { + match connection_worker(&io, &aux_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 c057edaeb..ce0fd4088 100644 --- a/artiq/firmware/runtime/rtio_dma.rs +++ b/artiq/firmware/runtime/rtio_dma.rs @@ -91,12 +91,12 @@ pub mod remote_dma { Ok(playback_state) } - pub fn erase(io: &Io, aux_mutex: &Mutex, routing_table: &RoutingTable, - ddma_mutex: &Mutex, id: u32) { + pub fn erase(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + routing_table: &RoutingTable, id: u32) { 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, ddma_mutex, routing_table, id, *destination) { + match drtio::ddma_send_erase(io, aux_mutex, routing_table, id, *destination) { Ok(_) => (), Err(e) => error!("Error erasing trace on DMA: {}", e) } @@ -104,12 +104,12 @@ pub mod remote_dma { unsafe { TRACES.remove(&id); } } - pub fn upload_traces(io: &Io, aux_mutex: &Mutex, routing_table: &RoutingTable, - ddma_mutex: &Mutex, id: u32) { + pub fn upload_traces(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + routing_table: &RoutingTable, id: u32) { 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, ddma_mutex, routing_table, id, *destination, trace.get_trace()) + match drtio::ddma_upload_trace(io, aux_mutex, routing_table, id, *destination, trace.get_trace()) { Ok(_) => trace.state = RemoteState::Loaded, Err(e) => error!("Error adding DMA trace on destination {}: {}", destination, e) @@ -117,8 +117,8 @@ pub mod remote_dma { } } - pub fn playback(io: &Io, aux_mutex: &Mutex, routing_table: &RoutingTable, - ddma_mutex: &Mutex, id: u32, timestamp: u64) { + pub fn playback(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + routing_table: &RoutingTable, id: u32, timestamp: u64) { // triggers playback on satellites let destinations = unsafe { let _lock = ddma_mutex.lock(io).unwrap(); @@ -133,7 +133,7 @@ pub mod remote_dma { continue; } } - match drtio::ddma_send_playback(io, aux_mutex, ddma_mutex, routing_table, id, *destination, timestamp) { + match drtio::ddma_send_playback(io, aux_mutex, routing_table, id, *destination, timestamp) { Ok(_) => (), Err(e) => error!("Error during remote DMA playback: {}", e) } @@ -152,15 +152,15 @@ pub mod remote_dma { }; } - pub fn destination_changed(io: &Io, aux_mutex: &Mutex, routing_table: &RoutingTable, - ddma_mutex: &Mutex, destination: u8, up: bool) { + pub fn destination_changed(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + routing_table: &RoutingTable, destination: u8, up: bool) { // update state of the destination, resend traces if it's up let _lock = ddma_mutex.lock(io).unwrap(); let traces_iter = unsafe { TRACES.iter_mut() }; 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, ddma_mutex, routing_table, *id, destination, trace.get_trace()) + match drtio::ddma_upload_trace(io, aux_mutex, routing_table, *id, destination, trace.get_trace()) { Ok(_) => trace.state = RemoteState::Loaded, Err(e) => error!("Error adding DMA trace on destination {}: {}", destination, e) diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index de1b3332c..0eb1679fc 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -61,23 +61,27 @@ pub mod drtio { } } - 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(); - 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 process_async_packets(io: &Io, ddma_mutex: &Mutex, packet: drtioaux::Packet + ) -> Option { + // returns None if an async packet has been consumed + match packet { + drtioaux::Packet::DmaPlaybackStatus { id, destination, error, channel, timestamp } => { + remote_dma::playback_done(io, ddma_mutex, id, destination, error, channel, timestamp); + None + }, + other => Some(other) } } - fn ping_remote(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, linkno: u8) -> u32 { + pub fn aux_transact(io: &Io, aux_mutex: &Mutex, linkno: u8, request: &drtioaux::Packet + ) -> Result { + let _lock = aux_mutex.lock(io).unwrap(); + drtioaux::send(linkno, request).unwrap(); + let reply = recv_aux_timeout(io, linkno, 200)?; + Ok(reply) + } + + fn ping_remote(io: &Io, aux_mutex: &Mutex, linkno: u8) -> u32 { let mut count = 0; loop { if !link_rx_up(linkno) { @@ -87,7 +91,7 @@ pub mod drtio { if count > 100 { return 0; } - let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::EchoRequest); + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::EchoRequest); match reply { Ok(drtioaux::Packet::EchoReply) => { // make sure receive buffer is drained @@ -123,10 +127,10 @@ pub mod drtio { } } - fn load_routing_table(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, + fn load_routing_table(io: &Io, aux_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, ddma_mutex, linkno, &drtioaux::Packet::RoutingSetPath { + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::RoutingSetPath { destination: i as u8, hops: routing_table.0[i] })?; @@ -137,10 +141,12 @@ pub mod drtio { Ok(()) } - 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 - })?; + 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 { + rank: rank + })?; if reply != drtioaux::Packet::RoutingAck { return Err("unexpected reply"); } @@ -229,45 +235,60 @@ 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, ddma_mutex, linkno, &drtioaux::Packet::DestinationStatusRequest { - destination: destination - }); - match reply { - Ok(drtioaux::Packet::DestinationDownReply) => { - destination_set_up(routing_table, up_destinations, destination, false); - remote_dma::destination_changed(io, aux_mutex, routing_table, ddma_mutex, destination, false); + loop { + let reply = aux_transact(io, aux_mutex, linkno, + &drtioaux::Packet::DestinationStatusRequest { + destination: destination + }); + if let Ok(reply) = reply { + let reply = process_async_packets(io, ddma_mutex, reply); + match reply { + Some(drtioaux::Packet::DestinationDownReply) => { + destination_set_up(routing_table, up_destinations, destination, false); + remote_dma::destination_changed(io, aux_mutex, ddma_mutex, routing_table, destination, false); + } + Some(drtioaux::Packet::DestinationOkReply) => (), + Some(drtioaux::Packet::DestinationSequenceErrorReply { channel }) => { + error!("[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); + unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR }; + } + Some(drtioaux::Packet::DestinationCollisionReply { channel }) => { + error!("[DEST#{}] RTIO collision involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); + unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION }; + } + Some(drtioaux::Packet::DestinationBusyReply { channel }) => { + error!("[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); + unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY }; + } + Some(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), + None => { + // continue asking until we get Destination...Reply or error out + // wait a bit not to overwhelm the receiver causing gateway errors + io.sleep(10).unwrap(); + continue; + } + } + } else { + error!("[DEST#{}] communication failed ({})", destination, reply.unwrap_err()); } - Ok(drtioaux::Packet::DestinationOkReply) => (), - Ok(drtioaux::Packet::DestinationSequenceErrorReply { channel }) => { - error!("[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); - unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR }; - } - Ok(drtioaux::Packet::DestinationCollisionReply { channel }) => { - error!("[DEST#{}] RTIO collision involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); - unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION }; - } - Ok(drtioaux::Packet::DestinationBusyReply { channel }) => { - error!("[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); - unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY }; - } - Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), - Err(e) => error!("[DEST#{}] communication failed ({})", destination, e) + break; } } else { destination_set_up(routing_table, up_destinations, destination, false); - remote_dma::destination_changed(io, aux_mutex, routing_table, ddma_mutex, destination, false); + remote_dma::destination_changed(io, aux_mutex, ddma_mutex, routing_table, destination, false); } } else { if up_links[linkno as usize] { - let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DestinationStatusRequest { - destination: destination - }); + let reply = aux_transact(io, aux_mutex, linkno, + &drtioaux::Packet::DestinationStatusRequest { + destination: destination + }); match reply { Ok(drtioaux::Packet::DestinationDownReply) => (), Ok(drtioaux::Packet::DestinationOkReply) => { destination_set_up(routing_table, up_destinations, destination, true); init_buffer_space(destination as u8, linkno); - remote_dma::destination_changed(io, aux_mutex, routing_table, ddma_mutex, destination, true); + remote_dma::destination_changed(io, aux_mutex, ddma_mutex, routing_table, destination, true); }, Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), Err(e) => error!("[DEST#{}] communication failed ({})", destination, e) @@ -299,17 +320,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, ddma_mutex, linkno); + let ping_count = ping_remote(&io, aux_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, ddma_mutex, linkno, routing_table) { + if let Err(e) = load_routing_table(&io, aux_mutex, linkno, routing_table) { error!("[LINK#{}] failed to load routing table ({})", linkno, e); } - if let Err(e) = set_rank(&io, aux_mutex, ddma_mutex, linkno, 1) { + if let Err(e) = set_rank(&io, aux_mutex, linkno, 1) { error!("[LINK#{}] failed to set rank ({})", linkno, e); } info!("[LINK#{}] link initialization completed", linkno); @@ -324,7 +345,7 @@ pub mod drtio { } } - pub fn reset(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex) { + pub fn reset(io: &Io, aux_mutex: &Mutex) { for linkno in 0..csr::DRTIO.len() { unsafe { (csr::DRTIO[linkno].reset_write)(1); @@ -340,7 +361,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, ddma_mutex, linkno, + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::ResetRequest); match reply { Ok(drtioaux::Packet::ResetAck) => (), @@ -351,8 +372,7 @@ pub mod drtio { } } - pub fn ddma_upload_trace(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, + 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; let mut i = 0; @@ -362,7 +382,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, ddma_mutex, linkno, + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::DmaAddTraceRequest { id: id, destination: destination, last: last, length: len as u16, trace: trace_slice}); match reply { @@ -376,12 +396,10 @@ pub mod drtio { Ok(()) } - - pub fn ddma_send_erase(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, + pub fn ddma_send_erase(io: &Io, aux_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, ddma_mutex, linkno, + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::DmaRemoveTraceRequest { id: id, destination: destination }); match reply { Ok(drtioaux::Packet::DmaRemoveTraceReply { succeeded: true }) => Ok(()), @@ -391,12 +409,11 @@ pub mod drtio { } } - pub fn ddma_send_playback(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, + pub fn ddma_send_playback(io: &Io, aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, id: u32, destination: u8, timestamp: u64) -> Result<(), &'static str> { let linkno = routing_table.0[destination as usize][0] - 1; - let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, &drtioaux::Packet::DmaPlaybackRequest{ - id: id, destination: destination, timestamp: timestamp }); + let reply = aux_transact(io, aux_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 }) => @@ -407,11 +424,10 @@ pub mod drtio { } #[cfg(has_rtio_analyzer)] - fn analyzer_get_data(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, destination: u8 - ) -> Result { + fn analyzer_get_data(io: &Io, aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, + destination: u8) -> Result { let linkno = routing_table.0[destination as usize][0] - 1; - let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::AnalyzerHeaderRequest { destination: destination }); let (sent, total, overflow) = match reply { Ok(drtioaux::Packet::AnalyzerHeader { @@ -425,7 +441,7 @@ pub mod drtio { if sent > 0 { let mut last_packet = false; while !last_packet { - let reply = aux_transact(io, aux_mutex, ddma_mutex, linkno, + let reply = aux_transact(io, aux_mutex, linkno, &drtioaux::Packet::AnalyzerDataRequest { destination: destination }); match reply { Ok(drtioaux::Packet::AnalyzerData { last, length, data }) => { @@ -447,14 +463,13 @@ pub mod drtio { } #[cfg(has_rtio_analyzer)] - pub fn analyzer_query(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, + pub fn analyzer_query(io: &Io, aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, up_destinations: &Urc> ) -> Result, &'static str> { let mut remote_buffers: Vec = Vec::new(); for i in 1..drtio_routing::DEST_COUNT { if destination_up(up_destinations, i as u8) { - remote_buffers.push(analyzer_get_data(io, aux_mutex, ddma_mutex, routing_table, i as u8)?); + remote_buffers.push(analyzer_get_data(io, aux_mutex, routing_table, i as u8)?); } } Ok(remote_buffers) @@ -542,9 +557,9 @@ pub fn startup(io: &Io, aux_mutex: &Mutex, io.spawn(4096, async_error_thread); } -pub fn reset(io: &Io, aux_mutex: &Mutex, ddma_mutex: &Mutex) { +pub fn reset(io: &Io, aux_mutex: &Mutex) { unsafe { csr::rtio_core::reset_write(1); } - drtio::reset(io, aux_mutex, ddma_mutex) + drtio::reset(io, aux_mutex) } diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 95b3ca28f..64e015038 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, ddma_mutex, routing_table, up_destinations, request)? { + if kern_hwreq::process_kern_hwreq(io, aux_mutex, routing_table, up_destinations, request)? { return Ok(false) } @@ -373,7 +373,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, if let Some(_id) = session.congress.dma_manager.record_start(name) { // replace the record #[cfg(has_drtio)] - remote_dma::erase(io, aux_mutex, routing_table, ddma_mutex, _id); + remote_dma::erase(io, aux_mutex, ddma_mutex, routing_table, _id); } kern_acknowledge() } @@ -385,7 +385,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, 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); + remote_dma::upload_traces(io, aux_mutex, ddma_mutex, routing_table, _id); } cache::flush_l2_cache(); kern_acknowledge() @@ -393,7 +393,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, &kern::DmaEraseRequest { name } => { #[cfg(has_drtio)] if let Some(id) = session.congress.dma_manager.get_id(name) { - remote_dma::erase(io, aux_mutex, routing_table, ddma_mutex, *id); + remote_dma::erase(io, aux_mutex, ddma_mutex, routing_table, *id); } session.congress.dma_manager.erase(name); kern_acknowledge() @@ -416,7 +416,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, } &kern::DmaStartRemoteRequest { id: _id, timestamp: _timestamp } => { #[cfg(has_drtio)] - remote_dma::playback(io, aux_mutex, routing_table, ddma_mutex, _id as u32, _timestamp as u64); + remote_dma::playback(io, aux_mutex, ddma_mutex, routing_table, _id as u32, _timestamp as u64); kern_acknowledge() } &kern::DmaAwaitRemoteRequest { id: _id } => { @@ -510,7 +510,6 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, } } } - request => unexpected!("unexpected request {:?} from kernel CPU", request) }.and(Ok(false)) }) diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 6eb1c7d9d..8226cbc33 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -109,37 +109,44 @@ fn process_aux_packet(_manager: &mut DmaManager, analyzer: &mut Analyzer, _repea let hop = 0; if hop == 0 { - let errors; - unsafe { - errors = csr::drtiosat::rtio_error_read(); - } - if errors & 1 != 0 { - let channel; + // async messages + if let Some(status) = _manager.check_state() { + info!("playback done, error: {}, channel: {}, timestamp: {}", status.error, status.channel, status.timestamp); + drtioaux::send(0, &drtioaux::Packet::DmaPlaybackStatus { + destination: *_rank, id: status.id, error: status.error, channel: status.channel, timestamp: status.timestamp })?; + } else { + let errors; unsafe { - channel = csr::drtiosat::sequence_error_channel_read(); - csr::drtiosat::rtio_error_write(1); + errors = csr::drtiosat::rtio_error_read(); } - drtioaux::send(0, - &drtioaux::Packet::DestinationSequenceErrorReply { channel })?; - } else if errors & 2 != 0 { - let channel; - unsafe { - channel = csr::drtiosat::collision_channel_read(); - csr::drtiosat::rtio_error_write(2); + if errors & 1 != 0 { + let channel; + unsafe { + channel = csr::drtiosat::sequence_error_channel_read(); + csr::drtiosat::rtio_error_write(1); + } + drtioaux::send(0, + &drtioaux::Packet::DestinationSequenceErrorReply { channel })?; + } else if errors & 2 != 0 { + let channel; + unsafe { + channel = csr::drtiosat::collision_channel_read(); + csr::drtiosat::rtio_error_write(2); + } + drtioaux::send(0, + &drtioaux::Packet::DestinationCollisionReply { channel })?; + } else if errors & 4 != 0 { + let channel; + unsafe { + channel = csr::drtiosat::busy_channel_read(); + csr::drtiosat::rtio_error_write(4); + } + drtioaux::send(0, + &drtioaux::Packet::DestinationBusyReply { channel })?; } - drtioaux::send(0, - &drtioaux::Packet::DestinationCollisionReply { channel })?; - } else if errors & 4 != 0 { - let channel; - unsafe { - channel = csr::drtiosat::busy_channel_read(); - csr::drtiosat::rtio_error_write(4); + else { + drtioaux::send(0, &drtioaux::Packet::DestinationOkReply)?; } - drtioaux::send(0, - &drtioaux::Packet::DestinationBusyReply { channel })?; - } - else { - drtioaux::send(0, &drtioaux::Packet::DestinationOkReply)?; } } @@ -643,13 +650,6 @@ pub extern fn main() -> i32 { error!("aux packet error: {}", e); } } - if let Some(status) = dma_manager.check_state() { - info!("playback done, error: {}, channel: {}, timestamp: {}", status.error, status.channel, status.timestamp); - if let Err(e) = drtioaux::send(0, &drtioaux::Packet::DmaPlaybackStatus { - destination: rank, id: status.id, error: status.error, channel: status.channel, timestamp: status.timestamp }) { - error!("error sending DMA playback status: {}", e); - } - } } drtiosat_reset_phy(true);