mirror of https://github.com/m-labs/artiq.git
repeater: handle async packets on forwarding
This commit is contained in:
parent
7a50afd9a9
commit
86c6d11ed4
|
@ -104,13 +104,13 @@ pub fn cricon_read() -> RtioMaster {
|
|||
|
||||
#[cfg(has_drtio_routing)]
|
||||
macro_rules! forward {
|
||||
($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr) => {{
|
||||
($router:expr, $routing_table:expr, $destination:expr, $rank:expr, $self_destination:expr, $repeaters:expr, $packet:expr) => {{
|
||||
let hop = $routing_table.0[$destination as usize][$rank as usize];
|
||||
if hop != 0 {
|
||||
let repno = (hop - 1) as usize;
|
||||
if repno < $repeaters.len() {
|
||||
if $packet.expects_response() {
|
||||
return $repeaters[repno].aux_forward($packet);
|
||||
return $repeaters[repno].aux_forward($packet, $router, $routing_table, $rank, $self_destination);
|
||||
} else {
|
||||
let res = $repeaters[repno].aux_send($packet);
|
||||
// allow the satellite to parse the packet before next
|
||||
|
@ -126,7 +126,7 @@ macro_rules! forward {
|
|||
|
||||
#[cfg(not(has_drtio_routing))]
|
||||
macro_rules! forward {
|
||||
($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr) => {}
|
||||
($router:expr, $routing_table:expr, $destination:expr, $rank:expr, $self_destination:expr, $repeaters:expr, $packet:expr) => {}
|
||||
}
|
||||
|
||||
fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmgr: &mut KernelManager,
|
||||
|
@ -201,7 +201,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
let repno = hop - 1;
|
||||
match _repeaters[repno].aux_forward(&drtioaux::Packet::DestinationStatusRequest {
|
||||
destination: destination
|
||||
}) {
|
||||
}, router, _routing_table, *rank, *self_destination) {
|
||||
Ok(()) => (),
|
||||
Err(drtioaux::Error::LinkDown) => drtioaux::send(0, &drtioaux::Packet::DestinationDownReply)?,
|
||||
Err(e) => {
|
||||
|
@ -255,7 +255,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
|
||||
drtioaux::Packet::MonitorRequest { destination: _destination, channel, probe } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let value;
|
||||
#[cfg(has_rtio_moninj)]
|
||||
unsafe {
|
||||
|
@ -272,7 +272,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
drtioaux::send(0, &reply)
|
||||
},
|
||||
drtioaux::Packet::InjectionRequest { destination: _destination, channel, overrd, value } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
#[cfg(has_rtio_moninj)]
|
||||
unsafe {
|
||||
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
||||
|
@ -282,7 +282,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
Ok(())
|
||||
},
|
||||
drtioaux::Packet::InjectionStatusRequest { destination: _destination, channel, overrd } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let value;
|
||||
#[cfg(has_rtio_moninj)]
|
||||
unsafe {
|
||||
|
@ -298,22 +298,22 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
},
|
||||
|
||||
drtioaux::Packet::I2cStartRequest { destination: _destination, busno } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = i2c::start(busno).is_ok();
|
||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||
}
|
||||
drtioaux::Packet::I2cRestartRequest { destination: _destination, busno } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = i2c::restart(busno).is_ok();
|
||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||
}
|
||||
drtioaux::Packet::I2cStopRequest { destination: _destination, busno } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = i2c::stop(busno).is_ok();
|
||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||
}
|
||||
drtioaux::Packet::I2cWriteRequest { destination: _destination, busno, data } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
match i2c::write(busno, data) {
|
||||
Ok(ack) => drtioaux::send(0,
|
||||
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
||||
|
@ -322,7 +322,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
}
|
||||
drtioaux::Packet::I2cReadRequest { destination: _destination, busno, ack } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
match i2c::read(busno, ack) {
|
||||
Ok(data) => drtioaux::send(0,
|
||||
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }),
|
||||
|
@ -331,25 +331,25 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
}
|
||||
drtioaux::Packet::I2cSwitchSelectRequest { destination: _destination, busno, address, mask } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = i2c::switch_select(busno, address, mask).is_ok();
|
||||
drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||
}
|
||||
|
||||
drtioaux::Packet::SpiSetConfigRequest { destination: _destination, busno, flags, length, div, cs } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok();
|
||||
drtioaux::send(0,
|
||||
&drtioaux::Packet::SpiBasicReply { succeeded: succeeded })
|
||||
},
|
||||
drtioaux::Packet::SpiWriteRequest { destination: _destination, busno, data } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = spi::write(busno, data).is_ok();
|
||||
drtioaux::send(0,
|
||||
&drtioaux::Packet::SpiBasicReply { succeeded: succeeded })
|
||||
}
|
||||
drtioaux::Packet::SpiReadRequest { destination: _destination, busno } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
match spi::read(busno) {
|
||||
Ok(data) => drtioaux::send(0,
|
||||
&drtioaux::Packet::SpiReadReply { succeeded: true, data: data }),
|
||||
|
@ -359,7 +359,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
|
||||
drtioaux::Packet::AnalyzerHeaderRequest { destination: _destination } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let header = analyzer.get_header();
|
||||
drtioaux::send(0, &drtioaux::Packet::AnalyzerHeader {
|
||||
total_byte_count: header.total_byte_count,
|
||||
|
@ -369,7 +369,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
|
||||
drtioaux::Packet::AnalyzerDataRequest { destination: _destination } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
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 {
|
||||
|
@ -380,7 +380,7 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}
|
||||
|
||||
drtioaux::Packet::DmaAddTraceRequest { source, destination, id, status, length, trace } => {
|
||||
forward!(_routing_table, destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, destination, *rank, *self_destination, _repeaters, &packet);
|
||||
*self_destination = destination;
|
||||
let succeeded = dmamgr.add(source, id, status, &trace, length as usize).is_ok();
|
||||
router.send(drtioaux::Packet::DmaAddTraceReply {
|
||||
|
@ -388,19 +388,19 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}, _routing_table, *rank, *self_destination)
|
||||
}
|
||||
drtioaux::Packet::DmaAddTraceReply { source, destination: _destination, id, succeeded } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
dmamgr.ack_upload(kernelmgr, source, id, succeeded, router, *rank, *self_destination, _routing_table);
|
||||
Ok(())
|
||||
}
|
||||
drtioaux::Packet::DmaRemoveTraceRequest { source, destination: _destination, id } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let succeeded = dmamgr.erase(source, id).is_ok();
|
||||
router.send(drtioaux::Packet::DmaRemoveTraceReply {
|
||||
destination: source, succeeded: succeeded
|
||||
}, _routing_table, *rank, *self_destination)
|
||||
}
|
||||
drtioaux::Packet::DmaPlaybackRequest { source, destination: _destination, id, timestamp } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
// no DMA with a running kernel
|
||||
let succeeded = !kernelmgr.is_running() && dmamgr.playback(source, id, timestamp).is_ok();
|
||||
router.send(drtioaux::Packet::DmaPlaybackReply {
|
||||
|
@ -408,27 +408,27 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
}, _routing_table, *rank, *self_destination)
|
||||
}
|
||||
drtioaux::Packet::DmaPlaybackReply { destination: _destination, succeeded } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
if !succeeded {
|
||||
kernelmgr.ddma_nack();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
drtioaux::Packet::DmaPlaybackStatus { source: _, destination: _destination, id, error, channel, timestamp } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
dmamgr.remote_finished(kernelmgr, id, error, channel, timestamp);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
drtioaux::Packet::SubkernelAddDataRequest { destination, id, status, length, data } => {
|
||||
forward!(_routing_table, destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, destination, *rank, *self_destination, _repeaters, &packet);
|
||||
*self_destination = destination;
|
||||
let succeeded = kernelmgr.add(id, status, &data, length as usize).is_ok();
|
||||
drtioaux::send(0,
|
||||
&drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded })
|
||||
}
|
||||
drtioaux::Packet::SubkernelLoadRunRequest { source, destination: _destination, id, run } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let mut succeeded = kernelmgr.load(id).is_ok();
|
||||
// allow preloading a kernel with delayed run
|
||||
if run {
|
||||
|
@ -445,18 +445,18 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
_routing_table, *rank, *self_destination)
|
||||
}
|
||||
drtioaux::Packet::SubkernelLoadRunReply { destination: _destination, succeeded } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
// received if local subkernel started another, remote subkernel
|
||||
kernelmgr.subkernel_load_run_reply(succeeded, *self_destination);
|
||||
Ok(())
|
||||
}
|
||||
drtioaux::Packet::SubkernelFinished { destination: _destination, id, with_exception, exception_src } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
kernelmgr.remote_subkernel_finished(id, with_exception, exception_src);
|
||||
Ok(())
|
||||
}
|
||||
drtioaux::Packet::SubkernelExceptionRequest { destination: _destination } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
let mut data_slice: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_PAYLOAD_MAX_SIZE];
|
||||
let meta = kernelmgr.exception_get_slice(&mut data_slice);
|
||||
drtioaux::send(0, &drtioaux::Packet::SubkernelException {
|
||||
|
@ -466,14 +466,14 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||
})
|
||||
}
|
||||
drtioaux::Packet::SubkernelMessage { source, destination: _destination, id, status, length, data } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
kernelmgr.message_handle_incoming(status, length as usize, id, &data);
|
||||
router.send(drtioaux::Packet::SubkernelMessageAck {
|
||||
destination: source
|
||||
}, _routing_table, *rank, *self_destination)
|
||||
}
|
||||
drtioaux::Packet::SubkernelMessageAck { destination: _destination } => {
|
||||
forward!(_routing_table, _destination, *rank, _repeaters, &packet);
|
||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||
if kernelmgr.message_ack_slice() {
|
||||
let mut data_slice: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
||||
if let Some(meta) = kernelmgr.message_get_slice(&mut data_slice) {
|
||||
|
|
|
@ -186,10 +186,31 @@ impl Repeater {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn aux_forward(&self, request: &drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
||||
pub fn aux_forward(&self, request: &drtioaux::Packet, router: &mut Router,
|
||||
routing_table: &drtio_routing::RoutingTable, rank: u8,
|
||||
self_destination: u8) -> Result<(), drtioaux::Error<!>> {
|
||||
self.aux_send(request)?;
|
||||
let reply = self.recv_aux_timeout(200)?;
|
||||
drtioaux::send(0, &reply).unwrap();
|
||||
loop {
|
||||
let reply = self.recv_aux_timeout(200)?;
|
||||
match reply {
|
||||
// async/locally requested packets to be consumed or routed
|
||||
// these may come while a packet would be forwarded
|
||||
drtioaux::Packet::DmaPlaybackStatus { .. } |
|
||||
drtioaux::Packet::SubkernelFinished { .. } |
|
||||
drtioaux::Packet::SubkernelMessage { .. } |
|
||||
drtioaux::Packet::SubkernelMessageAck { .. } |
|
||||
drtioaux::Packet::SubkernelLoadRunReply { .. } |
|
||||
drtioaux::Packet::SubkernelException { .. } |
|
||||
drtioaux::Packet::DmaAddTraceReply { .. } |
|
||||
drtioaux::Packet::DmaPlaybackReply { .. } => {
|
||||
router.route(reply, routing_table, rank, self_destination);
|
||||
}
|
||||
_ => {
|
||||
drtioaux::send(0, &reply).unwrap();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue