forked from M-Labs/artiq-zynq
drtio: increase robustness for longer payloads
This commit is contained in:
parent
4a34777b97
commit
b76f634686
@ -19,6 +19,46 @@ impl From<IoError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum PayloadStatus {
|
||||||
|
Middle = 0,
|
||||||
|
First = 1,
|
||||||
|
Last = 2,
|
||||||
|
FirstAndLast = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for PayloadStatus {
|
||||||
|
fn from(value: u8) -> PayloadStatus {
|
||||||
|
match value {
|
||||||
|
0 => PayloadStatus::Middle,
|
||||||
|
1 => PayloadStatus::First,
|
||||||
|
2 => PayloadStatus::Last,
|
||||||
|
3 => PayloadStatus::FirstAndLast,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PayloadStatus {
|
||||||
|
pub fn is_first(self) -> bool {
|
||||||
|
self == PayloadStatus::First || self == PayloadStatus::FirstAndLast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_last(self) -> bool {
|
||||||
|
self == PayloadStatus::Last || self == PayloadStatus::FirstAndLast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_status(first: bool, last: bool) -> PayloadStatus {
|
||||||
|
match (first, last) {
|
||||||
|
(true, true) => PayloadStatus::FirstAndLast,
|
||||||
|
(true, false) => PayloadStatus::First,
|
||||||
|
(false, true) => PayloadStatus::Last,
|
||||||
|
(false, false) => PayloadStatus::Middle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum Packet {
|
pub enum Packet {
|
||||||
EchoRequest,
|
EchoRequest,
|
||||||
@ -159,7 +199,7 @@ pub enum Packet {
|
|||||||
DmaAddTraceRequest {
|
DmaAddTraceRequest {
|
||||||
destination: u8,
|
destination: u8,
|
||||||
id: u32,
|
id: u32,
|
||||||
last: bool,
|
status: PayloadStatus,
|
||||||
length: u16,
|
length: u16,
|
||||||
trace: [u8; MASTER_PAYLOAD_MAX_SIZE],
|
trace: [u8; MASTER_PAYLOAD_MAX_SIZE],
|
||||||
},
|
},
|
||||||
@ -192,7 +232,7 @@ pub enum Packet {
|
|||||||
SubkernelAddDataRequest {
|
SubkernelAddDataRequest {
|
||||||
destination: u8,
|
destination: u8,
|
||||||
id: u32,
|
id: u32,
|
||||||
last: bool,
|
status: PayloadStatus,
|
||||||
length: u16,
|
length: u16,
|
||||||
data: [u8; MASTER_PAYLOAD_MAX_SIZE],
|
data: [u8; MASTER_PAYLOAD_MAX_SIZE],
|
||||||
},
|
},
|
||||||
@ -228,7 +268,7 @@ pub enum Packet {
|
|||||||
SubkernelMessage {
|
SubkernelMessage {
|
||||||
destination: u8,
|
destination: u8,
|
||||||
id: u32,
|
id: u32,
|
||||||
last: bool,
|
status: PayloadStatus,
|
||||||
length: u16,
|
length: u16,
|
||||||
data: [u8; MASTER_PAYLOAD_MAX_SIZE],
|
data: [u8; MASTER_PAYLOAD_MAX_SIZE],
|
||||||
},
|
},
|
||||||
@ -391,14 +431,14 @@ impl Packet {
|
|||||||
0xb0 => {
|
0xb0 => {
|
||||||
let destination = reader.read_u8()?;
|
let destination = reader.read_u8()?;
|
||||||
let id = reader.read_u32()?;
|
let id = reader.read_u32()?;
|
||||||
let last = reader.read_bool()?;
|
let status = PayloadStatus::from(reader.read_u8()?);
|
||||||
let length = reader.read_u16()?;
|
let length = reader.read_u16()?;
|
||||||
let mut trace: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
let mut trace: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
||||||
reader.read_exact(&mut trace[0..length as usize])?;
|
reader.read_exact(&mut trace[0..length as usize])?;
|
||||||
Packet::DmaAddTraceRequest {
|
Packet::DmaAddTraceRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
id: id,
|
id: id,
|
||||||
last: last,
|
status: status,
|
||||||
length: length as u16,
|
length: length as u16,
|
||||||
trace: trace,
|
trace: trace,
|
||||||
}
|
}
|
||||||
@ -432,14 +472,14 @@ impl Packet {
|
|||||||
0xc0 => {
|
0xc0 => {
|
||||||
let destination = reader.read_u8()?;
|
let destination = reader.read_u8()?;
|
||||||
let id = reader.read_u32()?;
|
let id = reader.read_u32()?;
|
||||||
let last = reader.read_bool()?;
|
let status = PayloadStatus::from(reader.read_u8()?);
|
||||||
let length = reader.read_u16()?;
|
let length = reader.read_u16()?;
|
||||||
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
||||||
reader.read_exact(&mut data[0..length as usize])?;
|
reader.read_exact(&mut data[0..length as usize])?;
|
||||||
Packet::SubkernelAddDataRequest {
|
Packet::SubkernelAddDataRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
id: id,
|
id: id,
|
||||||
last: last,
|
status: status,
|
||||||
length: length as u16,
|
length: length as u16,
|
||||||
data: data,
|
data: data,
|
||||||
}
|
}
|
||||||
@ -482,14 +522,14 @@ impl Packet {
|
|||||||
0xcb => {
|
0xcb => {
|
||||||
let destination = reader.read_u8()?;
|
let destination = reader.read_u8()?;
|
||||||
let id = reader.read_u32()?;
|
let id = reader.read_u32()?;
|
||||||
let last = reader.read_bool()?;
|
let status = PayloadStatus::from(reader.read_u8()?);
|
||||||
let length = reader.read_u16()?;
|
let length = reader.read_u16()?;
|
||||||
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
let mut data: [u8; MASTER_PAYLOAD_MAX_SIZE] = [0; MASTER_PAYLOAD_MAX_SIZE];
|
||||||
reader.read_exact(&mut data[0..length as usize])?;
|
reader.read_exact(&mut data[0..length as usize])?;
|
||||||
Packet::SubkernelMessage {
|
Packet::SubkernelMessage {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
id: id,
|
id: id,
|
||||||
last: last,
|
status: status,
|
||||||
length: length as u16,
|
length: length as u16,
|
||||||
data: data,
|
data: data,
|
||||||
}
|
}
|
||||||
@ -713,14 +753,14 @@ impl Packet {
|
|||||||
Packet::DmaAddTraceRequest {
|
Packet::DmaAddTraceRequest {
|
||||||
destination,
|
destination,
|
||||||
id,
|
id,
|
||||||
last,
|
status,
|
||||||
trace,
|
trace,
|
||||||
length,
|
length,
|
||||||
} => {
|
} => {
|
||||||
writer.write_u8(0xb0)?;
|
writer.write_u8(0xb0)?;
|
||||||
writer.write_u8(destination)?;
|
writer.write_u8(destination)?;
|
||||||
writer.write_u32(id)?;
|
writer.write_u32(id)?;
|
||||||
writer.write_bool(last)?;
|
writer.write_u8(status as u8)?;
|
||||||
// trace may be broken down to fit within drtio aux memory limit
|
// trace may be broken down to fit within drtio aux memory limit
|
||||||
// will be reconstructed by satellite
|
// will be reconstructed by satellite
|
||||||
writer.write_u16(length)?;
|
writer.write_u16(length)?;
|
||||||
@ -771,14 +811,14 @@ impl Packet {
|
|||||||
Packet::SubkernelAddDataRequest {
|
Packet::SubkernelAddDataRequest {
|
||||||
destination,
|
destination,
|
||||||
id,
|
id,
|
||||||
last,
|
status,
|
||||||
data,
|
data,
|
||||||
length,
|
length,
|
||||||
} => {
|
} => {
|
||||||
writer.write_u8(0xc0)?;
|
writer.write_u8(0xc0)?;
|
||||||
writer.write_u8(destination)?;
|
writer.write_u8(destination)?;
|
||||||
writer.write_u32(id)?;
|
writer.write_u32(id)?;
|
||||||
writer.write_bool(last)?;
|
writer.write_u8(status as u8)?;
|
||||||
writer.write_u16(length)?;
|
writer.write_u16(length)?;
|
||||||
writer.write_all(&data[0..length as usize])?;
|
writer.write_all(&data[0..length as usize])?;
|
||||||
}
|
}
|
||||||
@ -822,14 +862,14 @@ impl Packet {
|
|||||||
Packet::SubkernelMessage {
|
Packet::SubkernelMessage {
|
||||||
destination,
|
destination,
|
||||||
id,
|
id,
|
||||||
last,
|
status,
|
||||||
data,
|
data,
|
||||||
length,
|
length,
|
||||||
} => {
|
} => {
|
||||||
writer.write_u8(0xcb)?;
|
writer.write_u8(0xcb)?;
|
||||||
writer.write_u8(destination)?;
|
writer.write_u8(destination)?;
|
||||||
writer.write_u32(id)?;
|
writer.write_u32(id)?;
|
||||||
writer.write_bool(last)?;
|
writer.write_u8(status as u8)?;
|
||||||
writer.write_u16(length)?;
|
writer.write_u16(length)?;
|
||||||
writer.write_all(&data[0..length as usize])?;
|
writer.write_all(&data[0..length as usize])?;
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,10 @@ pub mod drtio {
|
|||||||
use ksupport::{resolve_channel_name, ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR,
|
use ksupport::{resolve_channel_name, ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR,
|
||||||
SEEN_ASYNC_ERRORS};
|
SEEN_ASYNC_ERRORS};
|
||||||
use libasync::{delay, task};
|
use libasync::{delay, task};
|
||||||
use libboard_artiq::{drtioaux::Error, drtioaux_async, drtioaux_async::Packet,
|
use libboard_artiq::{drtioaux::Error,
|
||||||
drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE};
|
drtioaux_async,
|
||||||
|
drtioaux_async::Packet,
|
||||||
|
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE}};
|
||||||
use libboard_zynq::time::Milliseconds;
|
use libboard_zynq::time::Milliseconds;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
|
|
||||||
@ -61,11 +63,11 @@ pub mod drtio {
|
|||||||
Packet::SubkernelMessage {
|
Packet::SubkernelMessage {
|
||||||
id,
|
id,
|
||||||
destination: from,
|
destination: from,
|
||||||
last,
|
status,
|
||||||
length,
|
length,
|
||||||
data,
|
data,
|
||||||
} => {
|
} => {
|
||||||
subkernel::message_handle_incoming(id, last, length as usize, &data).await;
|
subkernel::message_handle_incoming(id, status, length as usize, &data).await;
|
||||||
// acknowledge receiving part of the message
|
// acknowledge receiving part of the message
|
||||||
let _lock = aux_mutex.async_lock().await;
|
let _lock = aux_mutex.async_lock().await;
|
||||||
drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: from })
|
drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: from })
|
||||||
@ -463,7 +465,7 @@ pub mod drtio {
|
|||||||
reply_handler_f: HandlerF,
|
reply_handler_f: HandlerF,
|
||||||
) -> Result<(), &'static str>
|
) -> Result<(), &'static str>
|
||||||
where
|
where
|
||||||
PacketF: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], bool, usize) -> Packet,
|
PacketF: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], PayloadStatus, usize) -> Packet,
|
||||||
HandlerF: Fn(&Packet) -> Result<(), &'static str>,
|
HandlerF: Fn(&Packet) -> Result<(), &'static str>,
|
||||||
{
|
{
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
@ -474,10 +476,12 @@ pub mod drtio {
|
|||||||
} else {
|
} else {
|
||||||
data.len() - i
|
data.len() - i
|
||||||
} as usize;
|
} as usize;
|
||||||
|
let first = i == 0;
|
||||||
let last = i + len == data.len();
|
let last = i + len == data.len();
|
||||||
slice[..len].clone_from_slice(&data[i..i + len]);
|
slice[..len].clone_from_slice(&data[i..i + len]);
|
||||||
i += len;
|
i += len;
|
||||||
let packet = packet_f(&slice, last, len);
|
let status = PayloadStatus::from_status(first, last);
|
||||||
|
let packet = packet_f(&slice, status, len);
|
||||||
let reply = aux_transact(aux_mutex, linkno, &packet, timer).await?;
|
let reply = aux_transact(aux_mutex, linkno, &packet, timer).await?;
|
||||||
reply_handler_f(&reply)?;
|
reply_handler_f(&reply)?;
|
||||||
}
|
}
|
||||||
@ -498,10 +502,10 @@ pub mod drtio {
|
|||||||
aux_mutex,
|
aux_mutex,
|
||||||
timer,
|
timer,
|
||||||
trace,
|
trace,
|
||||||
|slice, last, len| Packet::DmaAddTraceRequest {
|
|slice, status, len| Packet::DmaAddTraceRequest {
|
||||||
id: id,
|
id: id,
|
||||||
destination: destination,
|
destination: destination,
|
||||||
last: last,
|
status: status,
|
||||||
length: len as u16,
|
length: len as u16,
|
||||||
trace: *slice,
|
trace: *slice,
|
||||||
},
|
},
|
||||||
@ -655,10 +659,10 @@ pub mod drtio {
|
|||||||
aux_mutex,
|
aux_mutex,
|
||||||
timer,
|
timer,
|
||||||
data,
|
data,
|
||||||
|slice, last, len| Packet::SubkernelAddDataRequest {
|
|slice, status, len| Packet::SubkernelAddDataRequest {
|
||||||
id: id,
|
id: id,
|
||||||
destination: destination,
|
destination: destination,
|
||||||
last: last,
|
status: status,
|
||||||
length: len as u16,
|
length: len as u16,
|
||||||
data: *slice,
|
data: *slice,
|
||||||
},
|
},
|
||||||
@ -742,10 +746,10 @@ pub mod drtio {
|
|||||||
aux_mutex,
|
aux_mutex,
|
||||||
timer,
|
timer,
|
||||||
message,
|
message,
|
||||||
|slice, last, len| Packet::SubkernelMessage {
|
|slice, status, len| Packet::SubkernelMessage {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
id: id,
|
id: id,
|
||||||
last: last,
|
status: status,
|
||||||
length: len as u16,
|
length: len as u16,
|
||||||
data: *slice,
|
data: *slice,
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use alloc::{collections::btree_map::BTreeMap, vec::Vec};
|
use alloc::{collections::btree_map::BTreeMap, vec::Vec};
|
||||||
|
|
||||||
use libboard_artiq::pl::csr;
|
use libboard_artiq::{drtioaux_proto::PayloadStatus, pl::csr};
|
||||||
use libcortex_a9::cache::dcci_slice;
|
use libcortex_a9::cache::dcci_slice;
|
||||||
|
|
||||||
const ALIGNMENT: usize = 64;
|
const ALIGNMENT: usize = 64;
|
||||||
@ -50,10 +50,10 @@ impl Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, id: u32, last: bool, trace: &[u8], trace_len: usize) -> Result<(), Error> {
|
pub fn add(&mut self, id: u32, status: PayloadStatus, trace: &[u8], trace_len: usize) -> Result<(), Error> {
|
||||||
let entry = match self.entries.get_mut(&id) {
|
let entry = match self.entries.get_mut(&id) {
|
||||||
Some(entry) => {
|
Some(entry) => {
|
||||||
if entry.complete {
|
if entry.complete || status.is_first() {
|
||||||
// replace entry
|
// replace entry
|
||||||
self.entries.remove(&id);
|
self.entries.remove(&id);
|
||||||
self.entries.insert(
|
self.entries.insert(
|
||||||
@ -83,7 +83,7 @@ impl Manager {
|
|||||||
};
|
};
|
||||||
entry.trace.extend(&trace[0..trace_len]);
|
entry.trace.extend(&trace[0..trace_len]);
|
||||||
|
|
||||||
if last {
|
if status.is_last() {
|
||||||
entry.trace.push(0);
|
entry.trace.push(0);
|
||||||
let data_len = entry.trace.len();
|
let data_len = entry.trace.len();
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ fn process_aux_packet(
|
|||||||
&drtioaux::Packet::SubkernelMessage {
|
&drtioaux::Packet::SubkernelMessage {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
id: kernel_manager.get_current_id().unwrap(),
|
id: kernel_manager.get_current_id().unwrap(),
|
||||||
last: meta.last,
|
status: meta.status,
|
||||||
length: meta.len as u16,
|
length: meta.len as u16,
|
||||||
data: data_slice,
|
data: data_slice,
|
||||||
},
|
},
|
||||||
@ -494,12 +494,12 @@ fn process_aux_packet(
|
|||||||
drtioaux::Packet::DmaAddTraceRequest {
|
drtioaux::Packet::DmaAddTraceRequest {
|
||||||
destination: _destination,
|
destination: _destination,
|
||||||
id,
|
id,
|
||||||
last,
|
status,
|
||||||
length,
|
length,
|
||||||
trace,
|
trace,
|
||||||
} => {
|
} => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
let succeeded = dma_manager.add(id, last, &trace, length as usize).is_ok();
|
let succeeded = dma_manager.add(id, status, &trace, length as usize).is_ok();
|
||||||
drtioaux::send(0, &drtioaux::Packet::DmaAddTraceReply { succeeded: succeeded })
|
drtioaux::send(0, &drtioaux::Packet::DmaAddTraceReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::DmaRemoveTraceRequest {
|
drtioaux::Packet::DmaRemoveTraceRequest {
|
||||||
@ -527,12 +527,12 @@ fn process_aux_packet(
|
|||||||
drtioaux::Packet::SubkernelAddDataRequest {
|
drtioaux::Packet::SubkernelAddDataRequest {
|
||||||
destination: _destination,
|
destination: _destination,
|
||||||
id,
|
id,
|
||||||
last,
|
status,
|
||||||
length,
|
length,
|
||||||
data,
|
data,
|
||||||
} => {
|
} => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer);
|
||||||
let succeeded = kernel_manager.add(id, last, &data, length as usize).is_ok();
|
let succeeded = kernel_manager.add(id, status, &data, length as usize).is_ok();
|
||||||
drtioaux::send(0, &drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded })
|
drtioaux::send(0, &drtioaux::Packet::SubkernelAddDataReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::SubkernelLoadRunRequest {
|
drtioaux::Packet::SubkernelLoadRunRequest {
|
||||||
@ -562,7 +562,7 @@ fn process_aux_packet(
|
|||||||
drtioaux::send(
|
drtioaux::send(
|
||||||
0,
|
0,
|
||||||
&drtioaux::Packet::SubkernelException {
|
&drtioaux::Packet::SubkernelException {
|
||||||
last: meta.last,
|
last: meta.status.is_last(),
|
||||||
length: meta.len,
|
length: meta.len,
|
||||||
data: data_slice,
|
data: data_slice,
|
||||||
},
|
},
|
||||||
@ -571,12 +571,12 @@ fn process_aux_packet(
|
|||||||
drtioaux::Packet::SubkernelMessage {
|
drtioaux::Packet::SubkernelMessage {
|
||||||
destination,
|
destination,
|
||||||
id: _id,
|
id: _id,
|
||||||
last,
|
status,
|
||||||
length,
|
length,
|
||||||
data,
|
data,
|
||||||
} => {
|
} => {
|
||||||
forward!(_routing_table, destination, *_rank, _repeaters, &packet, timer);
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet, timer);
|
||||||
kernel_manager.message_handle_incoming(last, length as usize, &data);
|
kernel_manager.message_handle_incoming(status, length as usize, &data);
|
||||||
drtioaux::send(
|
drtioaux::send(
|
||||||
0,
|
0,
|
||||||
&drtioaux::Packet::SubkernelMessageAck {
|
&drtioaux::Packet::SubkernelMessageAck {
|
||||||
@ -596,7 +596,7 @@ fn process_aux_packet(
|
|||||||
&drtioaux::Packet::SubkernelMessage {
|
&drtioaux::Packet::SubkernelMessage {
|
||||||
destination: *_rank,
|
destination: *_rank,
|
||||||
id: kernel_manager.get_current_id().unwrap(),
|
id: kernel_manager.get_current_id().unwrap(),
|
||||||
last: meta.last,
|
status: meta.status,
|
||||||
length: meta.len as u16,
|
length: meta.len as u16,
|
||||||
data: data_slice,
|
data: data_slice,
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user