diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 4c629b22a..042f3b429 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -484,18 +484,23 @@ extern "C-unwind" fn subkernel_load_run(id: u32, destination: u8, run: bool) { extern "C-unwind" fn subkernel_await_finish(id: u32, timeout: i64) { send(&SubkernelAwaitFinishRequest { id: id, timeout: timeout }); - recv!(SubkernelAwaitFinishReply { status } => { - match status { - SubkernelStatus::NoError => (), - SubkernelStatus::IncorrectState => raise!("SubkernelError", - "Subkernel not running"), - SubkernelStatus::Timeout => raise!("SubkernelError", - "Subkernel timed out"), - SubkernelStatus::CommLost => raise!("SubkernelError", - "Lost communication with satellite"), - SubkernelStatus::OtherError => raise!("SubkernelError", - "An error occurred during subkernel operation"), - SubkernelStatus::Exception(e) => unsafe { crate::eh_artiq::raise(e) }, + recv(move |request| { + if let SubkernelAwaitFinishReply = request { } + else if let SubkernelError(status) = request { + match status { + SubkernelStatus::IncorrectState => raise!("SubkernelError", + "Subkernel not running"), + SubkernelStatus::Timeout => raise!("SubkernelError", + "Subkernel timed out"), + SubkernelStatus::CommLost => raise!("SubkernelError", + "Lost communication with satellite"), + SubkernelStatus::OtherError => raise!("SubkernelError", + "An error occurred during subkernel operation"), + SubkernelStatus::Exception(e) => unsafe { crate::eh_artiq::raise(e) }, + } + } else { + send(&Log(format_args!("unexpected reply: {:?}\n", request))); + loop {} } }) } @@ -513,24 +518,28 @@ extern fn subkernel_send_message(id: u32, is_return: bool, destination: u8, extern "C-unwind" fn subkernel_await_message(id: i32, timeout: i64, tags: &CSlice, min: u8, max: u8) -> u8 { send(&SubkernelMsgRecvRequest { id: id, timeout: timeout, tags: tags.as_ref() }); - recv!(SubkernelMsgRecvReply { status, count } => { - match status { - SubkernelStatus::NoError => { - if count < &min || count > &max { - raise!("SubkernelError", - "Received less or more arguments than expected"); - } - *count + recv(move |request| { + if let SubkernelMsgRecvReply { count } = request { + if count < &min || count > &max { + raise!("SubkernelError", + "Received less or more arguments than expected"); } - SubkernelStatus::IncorrectState => raise!("SubkernelError", - "Subkernel not running"), - SubkernelStatus::Timeout => raise!("SubkernelError", - "Subkernel timed out"), - SubkernelStatus::CommLost => raise!("SubkernelError", - "Lost communication with satellite"), - SubkernelStatus::OtherError => raise!("SubkernelError", - "An error occurred during subkernel operation"), - SubkernelStatus::Exception(e) => unsafe { crate::eh_artiq::raise(e) }, + *count + } else if let SubkernelError(status) = request { + match status { + SubkernelStatus::IncorrectState => raise!("SubkernelError", + "Subkernel not running"), + SubkernelStatus::Timeout => raise!("SubkernelError", + "Subkernel timed out"), + SubkernelStatus::CommLost => raise!("SubkernelError", + "Lost communication with satellite"), + SubkernelStatus::OtherError => raise!("SubkernelError", + "An error occurred during subkernel operation"), + SubkernelStatus::Exception(e) => unsafe { crate::eh_artiq::raise(e) }, + } + } else { + send(&Log(format_args!("unexpected reply: {:?}\n", request))); + loop {} } }) // RpcRecvRequest should be called `count` times after this to receive message data diff --git a/artiq/firmware/libproto_artiq/drtioaux_proto.rs b/artiq/firmware/libproto_artiq/drtioaux_proto.rs index a2e51ca65..ec1c36686 100644 --- a/artiq/firmware/libproto_artiq/drtioaux_proto.rs +++ b/artiq/firmware/libproto_artiq/drtioaux_proto.rs @@ -123,8 +123,8 @@ pub enum Packet { SubkernelLoadRunRequest { source: u8, destination: u8, id: u32, run: bool }, SubkernelLoadRunReply { destination: u8, succeeded: bool }, SubkernelFinished { destination: u8, id: u32, with_exception: bool, exception_src: u8 }, - SubkernelExceptionRequest { destination: u8 }, - SubkernelException { last: bool, length: u16, data: [u8; SAT_PAYLOAD_MAX_SIZE] }, + SubkernelExceptionRequest { source: u8, destination: u8 }, + SubkernelException { destination: u8, last: bool, length: u16, data: [u8; MASTER_PAYLOAD_MAX_SIZE] }, SubkernelMessage { source: u8, destination: u8, id: u32, status: PayloadStatus, length: u16, data: [u8; MASTER_PAYLOAD_MAX_SIZE] }, SubkernelMessageAck { destination: u8 }, } @@ -367,14 +367,17 @@ impl Packet { exception_src: reader.read_u8()? }, 0xc9 => Packet::SubkernelExceptionRequest { + source: reader.read_u8()?, destination: reader.read_u8()? }, 0xca => { + let destination = reader.read_u8()?; let last = reader.read_bool()?; let length = reader.read_u16()?; - let mut data: [u8; SAT_PAYLOAD_MAX_SIZE] = [0; SAT_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])?; Packet::SubkernelException { + destination: destination, last: last, length: length, data: data @@ -663,12 +666,14 @@ impl Packet { writer.write_bool(with_exception)?; writer.write_u8(exception_src)?; }, - Packet::SubkernelExceptionRequest { destination } => { + Packet::SubkernelExceptionRequest { source, destination } => { writer.write_u8(0xc9)?; + writer.write_u8(source)?; writer.write_u8(destination)?; }, - Packet::SubkernelException { last, length, data } => { + Packet::SubkernelException { destination, last, length, data } => { writer.write_u8(0xca)?; + writer.write_u8(destination)?; writer.write_bool(last)?; writer.write_u16(length)?; writer.write_all(&data[0..length as usize])?; @@ -693,18 +698,20 @@ impl Packet { pub fn routable_destination(&self) -> Option { // only for packets that could be re-routed, not only forwarded match self { - Packet::DmaAddTraceRequest { destination, .. } => Some(*destination), - Packet::DmaAddTraceReply { destination, .. } => Some(*destination), - Packet::DmaRemoveTraceRequest { destination, .. } => Some(*destination), - Packet::DmaRemoveTraceReply { destination, .. } => Some(*destination), - Packet::DmaPlaybackRequest { destination, .. } => Some(*destination), - Packet::DmaPlaybackReply { destination, .. } => Some(*destination), - Packet::SubkernelLoadRunRequest { destination, .. } => Some(*destination), - Packet::SubkernelLoadRunReply { destination, .. } => Some(*destination), - Packet::SubkernelMessage { destination, .. } => Some(*destination), - Packet::SubkernelMessageAck { destination, .. } => Some(*destination), - Packet::DmaPlaybackStatus { destination, .. } => Some(*destination), - Packet::SubkernelFinished { destination, .. } => Some(*destination), + Packet::DmaAddTraceRequest { destination, .. } => Some(*destination), + Packet::DmaAddTraceReply { destination, .. } => Some(*destination), + Packet::DmaRemoveTraceRequest { destination, .. } => Some(*destination), + Packet::DmaRemoveTraceReply { destination, .. } => Some(*destination), + Packet::DmaPlaybackRequest { destination, .. } => Some(*destination), + Packet::DmaPlaybackReply { destination, .. } => Some(*destination), + Packet::SubkernelLoadRunRequest { destination, .. } => Some(*destination), + Packet::SubkernelLoadRunReply { destination, .. } => Some(*destination), + Packet::SubkernelMessage { destination, .. } => Some(*destination), + Packet::SubkernelMessageAck { destination, .. } => Some(*destination), + Packet::SubkernelExceptionRequest { destination, .. } => Some(*destination), + Packet::SubkernelException { destination, .. } => Some(*destination), + Packet::DmaPlaybackStatus { destination, .. } => Some(*destination), + Packet::SubkernelFinished { destination, .. } => Some(*destination), _ => None } } diff --git a/artiq/firmware/libproto_artiq/kernel_proto.rs b/artiq/firmware/libproto_artiq/kernel_proto.rs index a9ff0eac3..31aece5c4 100644 --- a/artiq/firmware/libproto_artiq/kernel_proto.rs +++ b/artiq/firmware/libproto_artiq/kernel_proto.rs @@ -12,12 +12,11 @@ pub const KSUPPORT_HEADER_SIZE: usize = 0x74; #[derive(Debug)] pub enum SubkernelStatus<'a> { - NoError, Timeout, IncorrectState, CommLost, - OtherError, Exception(eh::eh_artiq::Exception<'a>), + OtherError, } #[derive(Debug)] @@ -107,10 +106,11 @@ pub enum Message<'a> { SubkernelLoadRunRequest { id: u32, destination: u8, run: bool }, SubkernelLoadRunReply { succeeded: bool }, SubkernelAwaitFinishRequest { id: u32, timeout: i64 }, - SubkernelAwaitFinishReply { status: SubkernelStatus<'a> }, + SubkernelAwaitFinishReply, SubkernelMsgSend { id: u32, destination: Option, count: u8, tag: &'a [u8], data: *const *const () }, SubkernelMsgRecvRequest { id: i32, timeout: i64, tags: &'a [u8] }, - SubkernelMsgRecvReply { status: SubkernelStatus<'a>, count: u8 }, + SubkernelMsgRecvReply { count: u8 }, + SubkernelError(SubkernelStatus<'a>), Log(fmt::Arguments<'a>), LogSlice(&'a str) diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index de16b47cb..3ed892d2a 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -119,17 +119,19 @@ pub mod drtio { }, // (potentially) routable packets drtioaux::Packet::DmaAddTraceRequest { destination, .. } | - drtioaux::Packet::DmaAddTraceReply { destination, .. } | - drtioaux::Packet::DmaRemoveTraceRequest { destination, .. } | - drtioaux::Packet::DmaRemoveTraceReply { destination, .. } | - drtioaux::Packet::DmaPlaybackRequest { destination, .. } | - drtioaux::Packet::DmaPlaybackReply { destination, .. } | - drtioaux::Packet::SubkernelLoadRunRequest { destination, .. } | - drtioaux::Packet::SubkernelLoadRunReply { destination, .. } | - drtioaux::Packet::SubkernelMessage { destination, .. } | - drtioaux::Packet::SubkernelMessageAck { destination, .. } | - drtioaux::Packet::DmaPlaybackStatus { destination, .. } | - drtioaux::Packet::SubkernelFinished { destination, .. } => { + drtioaux::Packet::DmaAddTraceReply { destination, .. } | + drtioaux::Packet::DmaRemoveTraceRequest { destination, .. } | + drtioaux::Packet::DmaRemoveTraceReply { destination, .. } | + drtioaux::Packet::DmaPlaybackRequest { destination, .. } | + drtioaux::Packet::DmaPlaybackReply { destination, .. } | + drtioaux::Packet::SubkernelLoadRunRequest { destination, .. } | + drtioaux::Packet::SubkernelLoadRunReply { destination, .. } | + drtioaux::Packet::SubkernelMessage { destination, .. } | + drtioaux::Packet::SubkernelMessageAck { destination, .. } | + drtioaux::Packet::SubkernelExceptionRequest { destination, .. } | + drtioaux::Packet::SubkernelException { destination, .. } | + drtioaux::Packet::DmaPlaybackStatus { destination, .. } | + drtioaux::Packet::SubkernelFinished { destination, .. } => { if *destination == 0 { false } else { @@ -612,9 +614,9 @@ pub mod drtio { let mut remote_data: Vec = Vec::new(); loop { let reply = aux_transact(io, aux_mutex, ddma_mutex, subkernel_mutex, routing_table, linkno, - &drtioaux::Packet::SubkernelExceptionRequest { destination: destination })?; + &drtioaux::Packet::SubkernelExceptionRequest { source: 0, destination: destination })?; match reply { - drtioaux::Packet::SubkernelException { last, length, data } => { + drtioaux::Packet::SubkernelException { destination: 0, last, length, data } => { remote_data.extend(&data[0..length as usize]); if last { return Ok(remote_data);