Compare commits

...

6 Commits

Author SHA1 Message Date
mwojcik 735b2ce1f9 fx 2023-11-02 14:50:36 +08:00
mwojcik b99e97267d subkernel: improve stability,
fix exception on awaiting message
2023-11-02 14:49:53 +08:00
mwojcik b76f634686 drtio: increase robustness for longer payloads 2023-11-02 14:48:52 +08:00
morgan 4a34777b97 refactor i2c, io_expander, task under the same cfg 2023-10-25 11:52:04 +08:00
morgan 43e4527392 fix kasli-soc demo compilation warning 2023-10-25 11:45:13 +08:00
Sebastien Bourdeauducq a08a42c954 flake: update dependencies 2023-10-20 17:46:37 +08:00
10 changed files with 191 additions and 101 deletions

View File

@ -11,11 +11,11 @@
"src-pythonparser": "src-pythonparser" "src-pythonparser": "src-pythonparser"
}, },
"locked": { "locked": {
"lastModified": 1697013694, "lastModified": 1697537883,
"narHash": "sha256-jmr+pFeyV0+nUbFY8/g2Aw4kU06i5CG0XhLobI8vUR8=", "narHash": "sha256-GfadmYHFkczltX+rPf08YpAHjYa/31ZmmVD578BcFow=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "f7abc156cbc0a371452148d11436e5f241798092", "rev": "b168f0bb4be1697ff100475c20ee304dcc31fcc2",
"revCount": 8569, "revCount": 8573,
"type": "git", "type": "git",
"url": "https://github.com/m-labs/artiq.git" "url": "https://github.com/m-labs/artiq.git"
}, },
@ -103,11 +103,11 @@
"mozilla-overlay_3": { "mozilla-overlay_3": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1690536331, "lastModified": 1695805681,
"narHash": "sha256-aRIf2FB2GTdfF7gl13WyETmiV/J7EhBGkSWXfZvlxcA=", "narHash": "sha256-1ElPLD8eFfnuIk0G52HGGpRtQZ4QPCjChRlEOfkZ5ro=",
"owner": "mozilla", "owner": "mozilla",
"repo": "nixpkgs-mozilla", "repo": "nixpkgs-mozilla",
"rev": "db89c8707edcffefcd8e738459d511543a339ff5", "rev": "6eabade97bc28d707a8b9d82ad13ef143836736e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -118,11 +118,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1696697597, "lastModified": 1697226376,
"narHash": "sha256-q26Qv4DQ+h6IeozF2o1secyQG0jt2VUT3V0K58jr3pg=", "narHash": "sha256-cumLLb1QOUtWieUnLGqo+ylNt3+fU8Lcv5Zl+tYbRUE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5a237aecb57296f67276ac9ab296a41c23981f56", "rev": "898cb2064b6e98b8c5499f37e81adbdf2925f7c5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -147,11 +147,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1693473454, "lastModified": 1697528004,
"narHash": "sha256-kr8Ur6JNW/xVRHdPn3ou980IAxg/n+f3ZQBHuJ1uaC4=", "narHash": "sha256-FFa2MbhAJEjwY58uOs0swvgymfjubHyWba6Q0X6CbB0=",
"owner": "m-labs", "owner": "m-labs",
"repo": "sipyco", "repo": "sipyco",
"rev": "5467dcf9738673ab9a49e6f2377bda7c551b5f90", "rev": "c0a7ed350ccfb85474217057fc47b3f258ca8d99",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -234,11 +234,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1693479539, "lastModified": 1697795161,
"narHash": "sha256-MppR7yxs3cjG7tQc82vX0MhyN71CJL2QWkM65F5hrFU=", "narHash": "sha256-p89w9eoFJ2VFTDZ5Mrv5vsH0E1Ko9z1C6Ett281hCHg=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "c15b54f92b3d4e125ae47a0dce7abe4b2bc9e054", "rev": "be672ab662d8134ee11412a651864824f6483d4a",
"revCount": 628, "revCount": 630,
"type": "git", "type": "git",
"url": "https://git.m-labs.hk/m-labs/zynq-rs" "url": "https://git.m-labs.hk/m-labs/zynq-rs"
}, },

View File

@ -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])?;
} }

View File

@ -19,7 +19,7 @@ pub mod drtioaux;
#[cfg(has_drtio)] #[cfg(has_drtio)]
pub mod drtioaux_async; pub mod drtioaux_async;
pub mod drtioaux_proto; pub mod drtioaux_proto;
#[cfg(feature = "target_kasli_soc")] #[cfg(all(feature = "target_kasli_soc", has_drtio))]
pub mod io_expander; pub mod io_expander;
pub mod logger; pub mod logger;
#[cfg(has_drtio)] #[cfg(has_drtio)]

View File

@ -458,6 +458,20 @@ async fn handle_run_kernel(
Err(SubkernelError::Timeout) => (kernel::SubkernelStatus::Timeout, 0), Err(SubkernelError::Timeout) => (kernel::SubkernelStatus::Timeout, 0),
Err(SubkernelError::IncorrectState) => (kernel::SubkernelStatus::IncorrectState, 0), Err(SubkernelError::IncorrectState) => (kernel::SubkernelStatus::IncorrectState, 0),
Err(SubkernelError::CommLost) => (kernel::SubkernelStatus::CommLost, 0), Err(SubkernelError::CommLost) => (kernel::SubkernelStatus::CommLost, 0),
Err(SubkernelError::SubkernelException) => {
error!("Exception in subkernel");
// just retrieve the exception
let status = subkernel::await_finish(aux_mutex, routing_table, timer, id, timeout)
.await
.unwrap();
match stream {
None => (),
Some(stream) => {
write_chunk(stream, &status.exception.unwrap()).await?;
}
}
(kernel::SubkernelStatus::OtherError, 0)
}
Err(_) => (kernel::SubkernelStatus::OtherError, 0), Err(_) => (kernel::SubkernelStatus::OtherError, 0),
}; };
control control

View File

@ -8,14 +8,14 @@
#[macro_use] #[macro_use]
extern crate alloc; extern crate alloc;
#[cfg(feature = "target_kasli_soc")] #[cfg(all(feature = "target_kasli_soc", has_drtio))]
use core::cell::RefCell; use core::cell::RefCell;
use ksupport; use ksupport;
use libasync::task; use libasync::task;
#[cfg(has_drtio_eem)] #[cfg(has_drtio_eem)]
use libboard_artiq::drtio_eem; use libboard_artiq::drtio_eem;
#[cfg(feature = "target_kasli_soc")] #[cfg(all(feature = "target_kasli_soc", has_drtio))]
use libboard_artiq::io_expander; use libboard_artiq::io_expander;
use libboard_artiq::{identifier_read, logger, pl}; use libboard_artiq::{identifier_read, logger, pl};
use libboard_zynq::{gic, mpcore, timer::GlobalTimer}; use libboard_zynq::{gic, mpcore, timer::GlobalTimer};
@ -38,7 +38,7 @@ mod rtio_mgt;
#[cfg(has_drtio)] #[cfg(has_drtio)]
mod subkernel; mod subkernel;
#[cfg(feature = "target_kasli_soc")] #[cfg(all(feature = "target_kasli_soc", has_drtio))]
async fn io_expanders_service( async fn io_expanders_service(
i2c_bus: RefCell<&mut libboard_zynq::i2c::I2c>, i2c_bus: RefCell<&mut libboard_zynq::i2c::I2c>,
io_expander0: RefCell<io_expander::IoExpander>, io_expander0: RefCell<io_expander::IoExpander>,
@ -93,15 +93,11 @@ pub fn main_core0() {
info!("gateware ident: {}", identifier_read(&mut [0; 64])); info!("gateware ident: {}", identifier_read(&mut [0; 64]));
ksupport::i2c::init(); ksupport::i2c::init();
#[cfg(feature = "target_kasli_soc")] #[cfg(all(feature = "target_kasli_soc", has_drtio))]
let i2c_bus = unsafe { (ksupport::i2c::I2C_BUS).as_mut().unwrap() };
#[cfg(feature = "target_kasli_soc")]
let (mut io_expander0, mut io_expander1);
#[cfg(feature = "target_kasli_soc")]
{ {
io_expander0 = io_expander::IoExpander::new(i2c_bus, 0).unwrap(); let i2c_bus = unsafe { (ksupport::i2c::I2C_BUS).as_mut().unwrap() };
io_expander1 = io_expander::IoExpander::new(i2c_bus, 1).unwrap(); let mut io_expander0 = io_expander::IoExpander::new(i2c_bus, 0).unwrap();
let mut io_expander1 = io_expander::IoExpander::new(i2c_bus, 1).unwrap();
io_expander0 io_expander0
.init(i2c_bus) .init(i2c_bus)
.expect("I2C I/O expander #0 initialization failed"); .expect("I2C I/O expander #0 initialization failed");
@ -115,6 +111,11 @@ pub fn main_core0() {
io_expander1.set(1, 1, false); io_expander1.set(1, 1, false);
io_expander0.service(i2c_bus).unwrap(); io_expander0.service(i2c_bus).unwrap();
io_expander1.service(i2c_bus).unwrap(); io_expander1.service(i2c_bus).unwrap();
task::spawn(io_expanders_service(
RefCell::new(i2c_bus),
RefCell::new(io_expander0),
RefCell::new(io_expander1),
));
} }
let cfg = match Config::new() { let cfg = match Config::new() {
@ -135,11 +136,5 @@ pub fn main_core0() {
task::spawn(ksupport::report_async_rtio_errors()); task::spawn(ksupport::report_async_rtio_errors());
#[cfg(feature = "target_kasli_soc")]
task::spawn(io_expanders_service(
RefCell::new(i2c_bus),
RefCell::new(io_expander0),
RefCell::new(io_expander1),
));
comms::main(timer, cfg); comms::main(timer, cfg);
} }

View File

@ -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,
}, },

View File

@ -1,7 +1,8 @@
use alloc::{collections::BTreeMap, rc::Rc, vec::Vec}; use alloc::{collections::BTreeMap, rc::Rc, vec::Vec};
use libasync::task; use libasync::task;
use libboard_artiq::{drtio_routing::RoutingTable, drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE}; use libboard_artiq::{drtio_routing::RoutingTable,
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE}};
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer}; use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
use libcortex_a9::mutex::Mutex; use libcortex_a9::mutex::Mutex;
use log::error; use log::error;
@ -28,6 +29,7 @@ pub enum Error {
Timeout, Timeout,
IncorrectState, IncorrectState,
SubkernelNotFound, SubkernelNotFound,
SubkernelException,
CommLost, CommLost,
DrtioError(&'static str), DrtioError(&'static str),
} }
@ -123,11 +125,13 @@ pub async fn subkernel_finished(id: u32, with_exception: bool) {
// called upon receiving DRTIO SubkernelRunDone // called upon receiving DRTIO SubkernelRunDone
// may be None if session ends and is cleared // may be None if session ends and is cleared
if let Some(subkernel) = SUBKERNELS.async_lock().await.get_mut(&id) { if let Some(subkernel) = SUBKERNELS.async_lock().await.get_mut(&id) {
subkernel.state = SubkernelState::Finished { if subkernel.state == SubkernelState::Running {
status: match with_exception { subkernel.state = SubkernelState::Finished {
true => FinishStatus::Exception, status: match with_exception {
false => FinishStatus::Ok, true => FinishStatus::Exception,
}, false => FinishStatus::Ok,
},
}
} }
} }
} }
@ -220,13 +224,27 @@ static MESSAGE_QUEUE: Mutex<Vec<Message>> = Mutex::new(Vec::new());
// currently under construction message(s) (can be from multiple sources) // currently under construction message(s) (can be from multiple sources)
static CURRENT_MESSAGES: Mutex<BTreeMap<u32, Message>> = Mutex::new(BTreeMap::new()); static CURRENT_MESSAGES: Mutex<BTreeMap<u32, Message>> = Mutex::new(BTreeMap::new());
pub async fn message_handle_incoming(id: u32, last: bool, length: usize, data: &[u8; MASTER_PAYLOAD_MAX_SIZE]) { pub async fn message_handle_incoming(
id: u32,
status: PayloadStatus,
length: usize,
data: &[u8; MASTER_PAYLOAD_MAX_SIZE],
) {
// called when receiving a message from satellite // called when receiving a message from satellite
if SUBKERNELS.async_lock().await.get(&id).is_none() { {
// do not add messages for non-existing or deleted subkernels let subkernel_lock = SUBKERNELS.async_lock().await;
return; let subkernel = subkernel_lock.get(&id);
if subkernel.is_none() || subkernel.unwrap().state != SubkernelState::Running {
// do not add messages for non-existing or deleted subkernels
return;
}
} }
let mut current_messages = CURRENT_MESSAGES.async_lock().await; let mut current_messages = CURRENT_MESSAGES.async_lock().await;
if status.is_first() {
current_messages.remove(&id);
}
match current_messages.get_mut(&id) { match current_messages.get_mut(&id) {
Some(message) => message.data.extend(&data[..length]), Some(message) => message.data.extend(&data[..length]),
None => { None => {
@ -240,7 +258,7 @@ pub async fn message_handle_incoming(id: u32, last: bool, length: usize, data: &
); );
} }
}; };
if last { if status.is_last() {
// when done, remove from working queue // when done, remove from working queue
MESSAGE_QUEUE MESSAGE_QUEUE
.async_lock() .async_lock()
@ -269,6 +287,15 @@ pub async fn message_await(id: u32, timeout: u64, timer: GlobalTimer) -> Result<
} }
} }
} }
match SUBKERNELS.async_lock().await.get(&id).unwrap().state {
SubkernelState::Finished {
status: FinishStatus::CommLost,
} => return Err(Error::CommLost),
SubkernelState::Finished {
status: FinishStatus::Exception,
} => return Err(Error::SubkernelException),
_ => (),
}
task::r#yield().await; task::r#yield().await;
} }
Err(Error::Timeout) Err(Error::Timeout)

View File

@ -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();

View File

@ -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,
}, },

View File

@ -8,7 +8,7 @@ use core_io::{Error as IoError, Write};
use cslice::AsCSlice; use cslice::AsCSlice;
use io::{Cursor, ProtoWrite}; use io::{Cursor, ProtoWrite};
use ksupport::{eh_artiq, kernel, rpc}; use ksupport::{eh_artiq, kernel, rpc};
use libboard_artiq::{drtioaux_proto::{MASTER_PAYLOAD_MAX_SIZE, SAT_PAYLOAD_MAX_SIZE}, use libboard_artiq::{drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE, SAT_PAYLOAD_MAX_SIZE},
pl::csr}; pl::csr};
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer}; use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
use libcortex_a9::sync_channel::Receiver; use libcortex_a9::sync_channel::Receiver;
@ -133,24 +133,23 @@ pub struct SubkernelFinished {
pub struct SliceMeta { pub struct SliceMeta {
pub len: u16, pub len: u16,
pub last: bool, pub status: PayloadStatus,
} }
macro_rules! get_slice_fn { macro_rules! get_slice_fn {
($name:tt, $size:expr) => { ($name:tt, $size:expr) => {
pub fn $name(&mut self, data_slice: &mut [u8; $size]) -> SliceMeta { pub fn $name(&mut self, data_slice: &mut [u8; $size]) -> SliceMeta {
if self.data.len() == 0 { let first = self.it == 0;
return SliceMeta { len: 0, last: true };
}
let len = min($size, self.data.len() - self.it); let len = min($size, self.data.len() - self.it);
let last = self.it + len == self.data.len(); let last = self.it + len == self.data.len();
let status = PayloadStatus::from_status(first, last);
data_slice[..len].clone_from_slice(&self.data[self.it..self.it + len]); data_slice[..len].clone_from_slice(&self.data[self.it..self.it + len]);
self.it += len; self.it += len;
SliceMeta { SliceMeta {
len: len as u16, len: len as u16,
last: last, status: status,
} }
} }
}; };
@ -175,8 +174,11 @@ impl MessageManager {
} }
} }
pub fn handle_incoming(&mut self, last: bool, length: usize, data: &[u8; MASTER_PAYLOAD_MAX_SIZE]) { pub fn handle_incoming(&mut self, status: PayloadStatus, length: usize, data: &[u8; MASTER_PAYLOAD_MAX_SIZE]) {
// called when receiving a message from master // called when receiving a message from master
if status.is_first() {
self.in_buffer = None;
}
match self.in_buffer.as_mut() { match self.in_buffer.as_mut() {
Some(message) => message.data.extend(&data[..length]), Some(message) => message.data.extend(&data[..length]),
None => { None => {
@ -186,7 +188,7 @@ impl MessageManager {
}); });
} }
}; };
if last { if status.is_last() {
// when done, remove from working queue // when done, remove from working queue
self.in_queue.push_back(self.in_buffer.take().unwrap()); self.in_queue.push_back(self.in_buffer.take().unwrap());
} }
@ -218,7 +220,7 @@ impl MessageManager {
return None; return None;
} }
let meta = self.out_message.as_mut()?.get_slice_master(data_slice); let meta = self.out_message.as_mut()?.get_slice_master(data_slice);
if meta.last { if meta.status.is_last() {
// clear the message slot // clear the message slot
self.out_message = None; self.out_message = None;
// notify kernel with a flag that message is sent // notify kernel with a flag that message is sent
@ -265,10 +267,10 @@ impl<'a> Manager<'_> {
} }
} }
pub fn add(&mut self, id: u32, last: bool, data: &[u8], data_len: usize) -> Result<(), Error> { pub fn add(&mut self, id: u32, status: PayloadStatus, data: &[u8], data_len: usize) -> Result<(), Error> {
let kernel = match self.kernels.get_mut(&id) { let kernel = match self.kernels.get_mut(&id) {
Some(kernel) => { Some(kernel) => {
if kernel.complete { if kernel.complete || status.is_first() {
// replace entry // replace entry
self.kernels.remove(&id); self.kernels.remove(&id);
self.kernels.insert( self.kernels.insert(
@ -296,7 +298,7 @@ impl<'a> Manager<'_> {
}; };
kernel.library.extend(&data[0..data_len]); kernel.library.extend(&data[0..data_len]);
kernel.complete = last; kernel.complete = status.is_last();
Ok(()) Ok(())
} }
@ -325,11 +327,16 @@ impl<'a> Manager<'_> {
Ok(()) Ok(())
} }
pub fn message_handle_incoming(&mut self, last: bool, length: usize, slice: &[u8; MASTER_PAYLOAD_MAX_SIZE]) { pub fn message_handle_incoming(
&mut self,
status: PayloadStatus,
length: usize,
slice: &[u8; MASTER_PAYLOAD_MAX_SIZE],
) {
if !self.running() { if !self.running() {
return; return;
} }
self.session.messages.handle_incoming(last, length, slice); self.session.messages.handle_incoming(status, length, slice);
} }
pub fn message_get_slice(&mut self, slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> Option<SliceMeta> { pub fn message_get_slice(&mut self, slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> Option<SliceMeta> {
@ -378,7 +385,10 @@ impl<'a> Manager<'_> {
pub fn exception_get_slice(&mut self, data_slice: &mut [u8; SAT_PAYLOAD_MAX_SIZE]) -> SliceMeta { pub fn exception_get_slice(&mut self, data_slice: &mut [u8; SAT_PAYLOAD_MAX_SIZE]) -> SliceMeta {
match self.session.last_exception.as_mut() { match self.session.last_exception.as_mut() {
Some(exception) => exception.get_slice_sat(data_slice), Some(exception) => exception.get_slice_sat(data_slice),
None => SliceMeta { len: 0, last: true }, None => SliceMeta {
len: 0,
status: PayloadStatus::FirstAndLast,
},
} }
} }