diff --git a/artiq/coredevice/drtio_dbg.py b/artiq/coredevice/drtio_dbg.py new file mode 100644 index 000000000..9ff06bc19 --- /dev/null +++ b/artiq/coredevice/drtio_dbg.py @@ -0,0 +1,22 @@ +from artiq.language.core import syscall +from artiq.language.types import TTuple, TInt32, TInt64, TNone + + +@syscall(flags={"nounwind", "nowrite"}) +def drtio_get_channel_state(channel: TInt32) -> TTuple([TInt32, TInt64]): + raise NotImplementedError("syscall not simulated") + + +@syscall(flags={"nounwind", "nowrite"}) +def drtio_reset_channel_state(channel: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall(flags={"nounwind", "nowrite"}) +def drtio_get_fifo_space(channel: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall(flags={"nounwind", "nowrite"}) +def drtio_get_packet_counts() -> TTuple([TInt32, TInt32]): + raise NotImplementedError("syscall not simulated") diff --git a/artiq/firmware/libksupport/api.rs b/artiq/firmware/libksupport/api.rs index 5ca10b15a..c987de59a 100644 --- a/artiq/firmware/libksupport/api.rs +++ b/artiq/firmware/libksupport/api.rs @@ -106,6 +106,11 @@ static mut API: &'static [(&'static str, *const ())] = &[ api!(rtio_input_timestamp = ::rtio::input_timestamp), api!(rtio_input_data = ::rtio::input_data), + api!(drtio_get_channel_state = ::rtio::drtio_dbg::get_channel_state), + api!(drtio_reset_channel_state = ::rtio::drtio_dbg::reset_channel_state), + api!(drtio_get_fifo_space = ::rtio::drtio_dbg::get_fifo_space), + api!(drtio_get_packet_counts = ::rtio::drtio_dbg::get_packet_counts), + api!(i2c_start = ::i2c_start), api!(i2c_stop = ::i2c_stop), api!(i2c_write = ::i2c_write), diff --git a/artiq/firmware/libksupport/lib.rs b/artiq/firmware/libksupport/lib.rs index eb2423136..e986daf85 100644 --- a/artiq/firmware/libksupport/lib.rs +++ b/artiq/firmware/libksupport/lib.rs @@ -47,8 +47,6 @@ macro_rules! artiq_raise { }); } -mod rtio; - use core::{mem, ptr, slice, str}; use std::io::Cursor; use libc::{c_char, size_t}; @@ -91,6 +89,7 @@ macro_rules! println { #[path = "../runtime/rpc_queue.rs"] mod rpc_queue; +mod rtio; #[no_mangle] #[lang = "panic_fmt"] diff --git a/artiq/firmware/libksupport/rtio.rs b/artiq/firmware/libksupport/rtio.rs index b7e8cafd0..2ba2d619f 100644 --- a/artiq/firmware/libksupport/rtio.rs +++ b/artiq/firmware/libksupport/rtio.rs @@ -183,3 +183,36 @@ pub fn log(timestamp: i64, data: &[u8]) { #[cfg(not(has_rtio_log))] pub fn log(_timestamp: i64, _data: &[u8]) {} + +pub mod drtio_dbg { + use ::send; + use ::recv; + use kernel_proto::*; + + + #[repr(C)] + pub struct ChannelState(i32, i64); + + pub extern fn get_channel_state(channel: i32) -> ChannelState { + send(&DRTIOChannelStateRequest { channel: channel as u32 }); + recv!(&DRTIOChannelStateReply { fifo_space, last_timestamp } + => ChannelState(fifo_space as i32, last_timestamp as i64)) + } + + pub extern fn reset_channel_state(channel: i32) { + send(&DRTIOResetChannelStateRequest { channel: channel as u32 }) + } + + pub extern fn get_fifo_space(channel: i32) { + send(&DRTIOGetFIFOSpaceRequest { channel: channel as u32 }) + } + + #[repr(C)] + pub struct PacketCounts(i32, i32); + + pub extern fn get_packet_counts() -> PacketCounts { + send(&DRTIOPacketCountRequest); + recv!(&DRTIOPacketCountReply { tx_cnt, rx_cnt } + => PacketCounts(tx_cnt as i32, rx_cnt as i32)) + } +} diff --git a/artiq/firmware/runtime/kernel_proto.rs b/artiq/firmware/runtime/kernel_proto.rs index c4699b708..d631a7fd5 100644 --- a/artiq/firmware/runtime/kernel_proto.rs +++ b/artiq/firmware/runtime/kernel_proto.rs @@ -32,6 +32,13 @@ pub enum Message<'a> { RTIOInitRequest, + DRTIOChannelStateRequest { channel: u32 }, + DRTIOChannelStateReply { fifo_space: u16, last_timestamp: u64 }, + DRTIOResetChannelStateRequest { channel: u32 }, + DRTIOGetFIFOSpaceRequest { channel: u32 }, + DRTIOPacketCountRequest, + DRTIOPacketCountReply { tx_cnt: u32, rx_cnt: u32 }, + RunFinished, RunException { exception: Exception<'a>, diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index ed25ea03b..4f828e9b4 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -177,3 +177,55 @@ pub fn init_core() { } drtio::init() } + +#[cfg(has_drtio)] +pub mod drtio_dbg { + use board::csr; + + pub fn get_channel_state(channel: u32) -> (u16, u64) { + unsafe { + csr::drtio::chan_sel_override_write(channel as u16); + csr::drtio::chan_sel_override_en_write(1); + let fifo_space = csr::drtio::o_dbg_fifo_space_read(); + let last_timestamp = csr::drtio::o_dbg_last_timestamp_read(); + csr::drtio::chan_sel_override_en_write(0); + (fifo_space, last_timestamp) + } + } + + pub fn reset_channel_state(channel: u32) { + unsafe { + csr::drtio::chan_sel_override_write(channel as u16); + csr::drtio::chan_sel_override_en_write(1); + csr::drtio::o_reset_channel_status_write(1); + csr::drtio::chan_sel_override_en_write(0); + } + } + + pub fn get_fifo_space(channel: u32) { + unsafe { + csr::drtio::chan_sel_override_write(channel as u16); + csr::drtio::chan_sel_override_en_write(1); + csr::drtio::o_get_fifo_space_write(1); + csr::drtio::chan_sel_override_en_write(0); + } + } + + pub fn get_packet_counts() -> (u32, u32) { + unsafe { + csr::drtio::update_packet_cnt_write(1); + (csr::drtio::packet_cnt_tx_read(), csr::drtio::packet_cnt_rx_read()) + } + } +} + +#[cfg(not(has_drtio))] +pub mod drtio_dbg { + pub fn get_channel_state(_channel: u32) -> (u16, u64) { (0, 0) } + + pub fn reset_channel_state(_channel: u32) {} + + pub fn get_fifo_space(_channel: u32) {} + + pub fn get_packet_counts() -> (u32, u32) { (0, 0) } +} diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index cceab0500..5168dd9dc 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -384,6 +384,24 @@ fn process_kern_message(waiter: Waiter, kern_acknowledge() } + &kern::DRTIOChannelStateRequest { channel } => { + let (fifo_space, last_timestamp) = rtio_mgt::drtio_dbg::get_channel_state(channel); + kern_send(waiter, &kern::DRTIOChannelStateReply { fifo_space: fifo_space, + last_timestamp: last_timestamp }) + } + &kern::DRTIOResetChannelStateRequest { channel } => { + rtio_mgt::drtio_dbg::reset_channel_state(channel); + kern_acknowledge() + } + &kern::DRTIOGetFIFOSpaceRequest { channel } => { + rtio_mgt::drtio_dbg::get_fifo_space(channel); + kern_acknowledge() + } + &kern::DRTIOPacketCountRequest => { + let (tx_cnt, rx_cnt) = rtio_mgt::drtio_dbg::get_packet_counts(); + kern_send(waiter, &kern::DRTIOPacketCountReply { tx_cnt: tx_cnt, rx_cnt: rx_cnt }) + } + &kern::WatchdogSetRequest { ms } => { let id = try!(session.watchdog_set.set_ms(ms) .map_err(|()| io_error("out of watchdogs")));