diff --git a/src/libboard_artiq/src/drtio_routing.rs b/src/libboard_artiq/src/drtio_routing.rs index b3a0a2cd..c087f66c 100644 --- a/src/libboard_artiq/src/drtio_routing.rs +++ b/src/libboard_artiq/src/drtio_routing.rs @@ -55,7 +55,7 @@ impl fmt::Display for RoutingTable { } } -pub fn config_routing_table(default_n_links: usize, cfg: Config) -> RoutingTable { +pub fn config_routing_table(default_n_links: usize, cfg: &Config) -> RoutingTable { let mut ret = RoutingTable::default_master(default_n_links); if let Ok(data) = cfg.read("routing_table") { if data.len() == DEST_COUNT*MAX_HOPS diff --git a/src/runtime/src/comms.rs b/src/runtime/src/comms.rs index 06ff3314..39e36c55 100644 --- a/src/runtime/src/comms.rs +++ b/src/runtime/src/comms.rs @@ -21,6 +21,7 @@ use libcortex_a9::{semaphore::Semaphore, mutex::Mutex, sync_channel::{Sender, Re use futures::{select_biased, future::FutureExt}; use libasync::{smoltcp::{Sockets, TcpStream}, task}; use libconfig::{Config, net_settings}; +use libboard_artiq::drtio_routing; use crate::proto_async::*; use crate::kernel; @@ -28,7 +29,8 @@ use crate::rpc; use crate::moninj; use crate::mgmt; use crate::analyzer; - +use crate::rtio_mgt; +use crate::pl; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { @@ -387,8 +389,21 @@ pub fn main(timer: GlobalTimer, cfg: Config) { Sockets::init(32); + // before, mutex was on io, but now that io isn't used...? + let aux_mutex: Mutex = Mutex::new(false); + #[cfg(has_drtio)] + let drtio_routing_table = RefCell::new( + drtio_routing::config_routing_table(pl::csr::DRTIO.len(), &cfg)); + #[cfg(not(has_drtio))] + let drtio_routing_table = RefCell::new(drtio_routing::RoutingTable::default_empty()); + let up_destinations = RefCell::new([false; drtio_routing::DEST_COUNT]); + #[cfg(has_drtio_routing)] + drtio_routing::interconnect_disable_all(); + + rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer); + analyzer::start(); - moninj::start(timer); + moninj::start(timer, &aux_mutex, &drtio_routing_table); let control: Rc> = Rc::new(RefCell::new(kernel::Control::start())); let idle_kernel = Rc::new(cfg.read("idle").ok()); diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index d9630fb3..973afbe8 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -11,7 +11,6 @@ extern crate alloc; -use core::cell::RefCell; use log::{info, warn, error}; use libboard_zynq::{timer::GlobalTimer, mpcore, gic}; @@ -21,8 +20,8 @@ use nb; use void::Void; use embedded_hal::blocking::delay::DelayMs; use libconfig::Config; -use libcortex_a9::{l2c::enable_l2_cache, mutex::Mutex}; -use libboard_artiq::{logger, identifier_read, init_gateware, pl, drtio_routing}; +use libcortex_a9::l2c::enable_l2_cache; +use libboard_artiq::{logger, identifier_read, init_gateware, pl}; #[cfg(has_si5324)] use libboard_artiq::si5324; @@ -45,9 +44,10 @@ mod analyzer; mod irq; mod i2c; -fn init_rtio(timer: &mut GlobalTimer, cfg: &Config) { +fn init_rtio(timer: &mut GlobalTimer, _cfg: &Config) { + #[cfg(has_rtio_crg_clock_sel)] let clock_sel = - if let Ok(rtioclk) = cfg.read_str("rtioclk") { + if let Ok(rtioclk) = _cfg.read_str("rtioclk") { match rtioclk.as_ref() { "internal" => { info!("using internal RTIO clock"); @@ -175,7 +175,7 @@ pub fn main_core0() { i2c::init(); #[cfg(has_si5324)] si5324::setup(unsafe { (&mut i2c::I2C_BUS).as_mut().unwrap() }, - &SI5324_SETTINGS, si5324::Input::Ckin2, timer).expect("cannot initialize Si5324"); + &SI5324_SETTINGS, si5324::Input::Ckin2, &mut timer).expect("cannot initialize Si5324"); let cfg = match Config::new() { Ok(cfg) => cfg, @@ -185,20 +185,9 @@ pub fn main_core0() { } }; - // before, mutex was on io, but now that io isn't used...? - let aux_mutex: Mutex = Mutex::new(false); - #[cfg(has_drtio)] - let drtio_routing_table = RefCell::new( - drtio_routing::config_routing_table(pl::csr::DRTIO.len(), cfg)); - #[cfg(not(has_drtio))] - let drtio_routing_table = RefCell::new(drtio_routing::RoutingTable::default_empty()); - let up_destinations = RefCell::new([false; drtio_routing::DEST_COUNT]); - #[cfg(has_drtio_routing)] - drtio_routing::interconnect_disable_all(); #[cfg(has_drtio)] init_drtio(&mut timer); - rtio_mgt::startup(); init_rtio(&mut timer, &cfg); task::spawn(report_async_rtio_errors()); diff --git a/src/runtime/src/moninj.rs b/src/runtime/src/moninj.rs index 2c01ad9a..f6786f36 100644 --- a/src/runtime/src/moninj.rs +++ b/src/runtime/src/moninj.rs @@ -1,4 +1,4 @@ -use core::fmt; +use core::{fmt, cell::RefCell}; use alloc::collections::BTreeMap; use log::{debug, info, warn}; use void::Void; @@ -57,43 +57,47 @@ enum DeviceMessage { #[cfg(has_drtio)] mod remote_moninj { + use libboard_zynq::timer::GlobalTimer; + use libasync::task; use libboard_artiq::drtioaux; use crate::rtio_mgt::drtio; use libcortex_a9::mutex::Mutex; use log::error; - pub fn read_probe(aux_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, probe: u8) -> u32 { - let reply = drtio::aux_transact(aux_mutex, linkno, &drtioaux::Packet::MonitorRequest { + pub fn read_probe(aux_mutex: &Mutex, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, probe: i8) -> i32 { + let reply = task::block_on(drtio::aux_transact(aux_mutex, linkno, &drtioaux::Packet::MonitorRequest { destination: destination, - channel: channel, - probe: probe - }); + channel: channel as _, + probe: probe as _}, + timer)); match reply { - Ok(drtioaux::Packet::MonitorReply { value }) => return value, + Ok(drtioaux::Packet::MonitorReply { value }) => return value as i32, Ok(packet) => error!("received unexpected aux packet: {:?}", packet), Err(e) => error!("aux packet error ({})", e) } 0 } - pub fn inject(aux_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8, value: u8) { + pub fn inject(aux_mutex: &Mutex, _timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8, value: i8) { let _lock = aux_mutex.lock(); drtioaux::send(linkno, &drtioaux::Packet::InjectionRequest { destination: destination, - channel: channel, - overrd: overrd, - value: value + channel: channel as _, + overrd: overrd as _, + value: value as _ }).unwrap(); } - pub fn read_injection_status(aux_mutex: &Mutex, linkno: u8, destination: u8, channel: u16, overrd: u8) -> u8 { - let reply = drtio::aux_transact(aux_mutex, linkno, &drtioaux::Packet::InjectionStatusRequest { - destination: destination, - channel: channel, - overrd: overrd - }); + pub fn read_injection_status(aux_mutex: &Mutex, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8) -> i8 { + let reply = task::block_on(drtio::aux_transact(aux_mutex, + linkno, + &drtioaux::Packet::InjectionStatusRequest { + destination: destination, + channel: channel as _, + overrd: overrd as _}, + timer)); match reply { - Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value, + Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value as i8, Ok(packet) => error!("received unexpected aux packet: {:?}", packet), Err(e) => error!("aux packet error ({})", e) } @@ -132,29 +136,30 @@ mod local_moninj { #[cfg(has_drtio)] macro_rules! dispatch { - ($aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ + ($timer:ident, $aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ let destination = ($channel >> 16) as u8; - let channel = $channel as u16; - let hop = $routing_table.0[destination as usize][0]; + let channel = $channel; + let routing_table = $routing_table.borrow_mut(); + let hop = routing_table.0[destination as usize][0]; if hop == 0 { - local_moninj::$func(channel, $($param, )*) + local_moninj::$func(channel.into(), $($param, )*) } else { - let linkno = hop - 1; - remote_moninj::$func($aux_mutex, linkno, destination, channel, $($param, )*) + let linkno = hop - 1 as u8; + remote_moninj::$func($aux_mutex, $timer, linkno, destination, channel, $($param, )*) } }} } #[cfg(not(has_drtio))] macro_rules! dispatch { - ($aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ + ($timer:ident, $aux_mutex:ident, $routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{ let channel = $channel as u16; local_moninj::$func(channel, $($param, )*) }} } async fn handle_connection(stream: &TcpStream, timer: GlobalTimer, - _aux_mutex: &Mutex, _routing_table: &drtio_routing::RoutingTable) -> Result<()> { + _aux_mutex: &Mutex, _routing_table: &RefCell) -> Result<()> { if !expect(&stream, b"ARTIQ moninj\n").await? { return Err(Error::UnexpectedPattern); } @@ -210,13 +215,13 @@ async fn handle_connection(stream: &TcpStream, timer: GlobalTimer, let channel = read_i32(&stream).await?; let overrd = read_i8(&stream).await?; let value = read_i8(&stream).await?; - dispatch!(_aux_mutex, _routing_table, channel, inject, overrd, value); + dispatch!(timer, _aux_mutex, _routing_table, channel, inject, overrd, value); debug!("INJECT channel {}, overrd {}, value {}", channel, overrd, value); }, HostMessage::GetInjectionStatus => { let channel = read_i32(&stream).await?; let overrd = read_i8(&stream).await?; - let value = dispatch!(_aux_mutex, _routing_table, channel, read_injection_status, overrd); + let value = dispatch!(timer, _aux_mutex, _routing_table, channel, read_injection_status, overrd); write_i8(&stream, DeviceMessage::InjectionStatus.to_i8().unwrap()).await?; write_i32(&stream, channel).await?; write_i8(&stream, overrd).await?; @@ -226,7 +231,7 @@ async fn handle_connection(stream: &TcpStream, timer: GlobalTimer, }, _ = timeout_f => { for (&(channel, probe), previous) in probe_watch_list.iter_mut() { - let current = dispatch!(_aux_mutex, _routing_table, channel, read_probe, probe); + let current = dispatch!(timer, _aux_mutex, _routing_table, channel, read_probe, probe); if previous.is_none() || previous.unwrap() != current { write_i8(&stream, DeviceMessage::MonitorStatus.to_i8().unwrap()).await?; write_i32(&stream, channel).await?; @@ -236,7 +241,7 @@ async fn handle_connection(stream: &TcpStream, timer: GlobalTimer, } } for (&(channel, overrd), previous) in inject_watch_list.iter_mut() { - let current = dispatch!(_aux_mutex, _routing_table, channel, read_injection_status, overrd); + let current = dispatch!(timer, _aux_mutex, _routing_table, channel, read_injection_status, overrd); if previous.is_none() || previous.unwrap() != current { write_i8(&stream, DeviceMessage::InjectionStatus.to_i8().unwrap()).await?; write_i32(&stream, channel).await?; @@ -251,13 +256,13 @@ async fn handle_connection(stream: &TcpStream, timer: GlobalTimer, } } -pub fn start(timer: GlobalTimer) { +pub fn start(timer: GlobalTimer, aux_mutex: &'static Mutex, routing_table: &'static RefCell) { task::spawn(async move { loop { let stream = TcpStream::accept(1383, 2048, 2048).await.unwrap(); task::spawn(async move { info!("received connection"); - let result = handle_connection(&stream, timer).await; + let result = handle_connection(&stream, timer, aux_mutex, routing_table).await; match result { Err(Error::NetworkError(smoltcp::Error::Finished)) => info!("peer closed connection"), Err(error) => warn!("connection terminated: {}", error), diff --git a/src/runtime/src/rtio_mgt.rs b/src/runtime/src/rtio_mgt.rs index ed91c26b..3b389035 100644 --- a/src/runtime/src/rtio_mgt.rs +++ b/src/runtime/src/rtio_mgt.rs @@ -12,15 +12,16 @@ pub mod drtio { use embedded_hal::blocking::delay::DelayMs; use libasync::{task, delay}; - pub fn startup(aux_mutex: &Mutex, - routing_table: &RefCell, - up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>) { + pub fn startup(aux_mutex: &'static Mutex, + routing_table: &'static RefCell, + up_destinations: &'static RefCell<[bool; drtio_routing::DEST_COUNT]>, + timer: GlobalTimer) { let aux_mutex = aux_mutex.clone(); let routing_table = routing_table.clone(); let up_destinations = up_destinations.clone(); - task::spawn( async move { + task::spawn(async move { let routing_table = routing_table.borrow(); - link_thread(&aux_mutex, &routing_table, &up_destinations); + link_thread(&aux_mutex, &routing_table, &up_destinations, timer); }); } @@ -31,7 +32,7 @@ pub mod drtio { } } - async fn recv_aux_timeout(linkno: u8, timeout: u32, timer: GlobalTimer) -> Result { + async fn recv_aux_timeout(linkno: u8, timeout: u64, timer: GlobalTimer) -> Result { let max_time = timer.get_time() + Milliseconds(timeout); loop { if !link_rx_up(linkno).await { @@ -48,7 +49,7 @@ pub mod drtio { } } - pub async fn aux_transact(aux_mutex: &Mutex, linkno: u8, request: &drtioaux::Packet, + pub async fn aux_transact(aux_mutex: &Mutex, linkno: u8, request: &drtioaux::Packet, timer: GlobalTimer) -> Result { let _lock = aux_mutex.lock(); drtioaux::send(linkno, request).unwrap(); @@ -65,10 +66,10 @@ pub mod drtio { } } - async fn ping_remote(aux_mutex: &Mutex, linkno: u8, timer: GlobalTimer) -> u32 { + async fn ping_remote(aux_mutex: &Mutex, linkno: u8, timer: GlobalTimer) -> u32 { let mut count = 0; loop { - if !link_rx_up(linkno) { + if !link_rx_up(linkno).await { return 0 } count += 1; @@ -80,7 +81,7 @@ pub mod drtio { Ok(drtioaux::Packet::EchoReply) => { // make sure receive buffer is drained let draining_time = Milliseconds(200); - drain_buffer(linkno, draining_time).await; + drain_buffer(linkno, draining_time, timer).await; return count; } _ => {} @@ -88,7 +89,7 @@ pub mod drtio { } } - async fn sync_tsc(aux_mutex: &Mutex, linkno: u8, timer: GlobalTimer) -> Result<(), &'static str> { + async fn sync_tsc(aux_mutex: &Mutex, linkno: u8, timer: GlobalTimer) -> Result<(), &'static str> { let _lock = aux_mutex.lock(); unsafe { @@ -105,7 +106,7 @@ pub mod drtio { } } - async fn load_routing_table(aux_mutex: &Mutex, linkno: u8, routing_table: &drtio_routing::RoutingTable, + async fn load_routing_table(aux_mutex: &Mutex, linkno: u8, routing_table: &drtio_routing::RoutingTable, timer: GlobalTimer) -> Result<(), &'static str> { for i in 0..drtio_routing::DEST_COUNT { let reply = aux_transact(aux_mutex, linkno, &drtioaux::Packet::RoutingSetPath { @@ -119,7 +120,7 @@ pub mod drtio { Ok(()) } - async fn set_rank(aux_mutex: &Mutex, linkno: u8, rank: u8, timer: GlobalTimer) -> Result<(), &'static str> { + async fn set_rank(aux_mutex: &Mutex, linkno: u8, rank: u8, timer: GlobalTimer) -> Result<(), &'static str> { let reply = aux_transact(aux_mutex, linkno, &drtioaux::Packet::RoutingSetRank { rank: rank }, timer).await?; @@ -142,7 +143,7 @@ pub mod drtio { } } - async fn process_unsolicited_aux(aux_mutex: &Mutex, linkno: u8) { + async fn process_unsolicited_aux(aux_mutex: &Mutex, linkno: u8) { let _lock = aux_mutex.lock(); match drtioaux::recv(linkno) { Ok(Some(packet)) => warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet), @@ -191,7 +192,7 @@ pub mod drtio { up_destinations[destination as usize] } - async fn destination_survey(aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, + async fn destination_survey(aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, up_links: &[bool], up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>, timer: GlobalTimer) { @@ -213,7 +214,7 @@ pub mod drtio { }, timer).await; match reply { Ok(drtioaux::Packet::DestinationDownReply) => - destination_set_up(routing_table, up_destinations, destination, false), + destination_set_up(routing_table, up_destinations, destination, false).await, Ok(drtioaux::Packet::DestinationOkReply) => (), Ok(drtioaux::Packet::DestinationSequenceErrorReply { channel }) => error!("[DEST#{}] RTIO sequence error involving channel 0x{:04x}", destination, channel), @@ -247,7 +248,7 @@ pub mod drtio { } } - pub async fn link_thread(aux_mutex: &Mutex, + pub async fn link_thread(aux_mutex: &Mutex, routing_table: &drtio_routing::RoutingTable, up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>, timer: GlobalTimer) { @@ -258,7 +259,7 @@ pub mod drtio { if up_links[linkno as usize] { /* link was previously up */ if link_rx_up(linkno).await { - process_unsolicited_aux(aux_mutex, linkno, timer).await; + process_unsolicited_aux(aux_mutex, linkno).await; process_local_errors(linkno).await; } else { info!("[LINK#{}] link is down", linkno); @@ -275,10 +276,10 @@ pub mod drtio { if let Err(e) = sync_tsc(aux_mutex, linkno, timer).await { error!("[LINK#{}] failed to sync TSC ({})", linkno, e); } - if let Err(e) = load_routing_table(aux_mutex, linkno, routing_table).await { + if let Err(e) = load_routing_table(aux_mutex, linkno, routing_table, timer).await { error!("[LINK#{}] failed to load routing table ({})", linkno, e); } - if let Err(e) = set_rank(aux_mutex, linkno, 1).await { + if let Err(e) = set_rank(aux_mutex, linkno, 1 as u8, timer).await { error!("[LINK#{}] failed to set rank ({})", linkno, e); } info!("[LINK#{}] link initialization completed", linkno); @@ -294,7 +295,7 @@ pub mod drtio { } } - pub fn reset(aux_mutex: &Mutex, timer: GlobalTimer) { + pub fn reset(aux_mutex: &Mutex, mut timer: GlobalTimer) { for linkno in 0..csr::DRTIO.len() { unsafe { (csr::DRTIO[linkno].reset_write)(1); @@ -309,7 +310,7 @@ pub mod drtio { for linkno in 0..csr::DRTIO.len() { let linkno = linkno as u8; - if link_rx_up(linkno) { + if task::block_on(link_rx_up(linkno)) { let reply = task::block_on(aux_transact(aux_mutex, linkno, &drtioaux::Packet::ResetRequest, timer)); match reply { @@ -326,21 +327,22 @@ pub mod drtio { pub mod drtio { use super::*; - pub fn startup(_aux_mutex: &Mutex, _routing_table: &RefCell, - _up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>, _timer: GlobalTimer) {} - pub fn reset(_aux_mutex: &Mutex, _timer: GlobalTimer) {} + pub fn startup(_aux_mutex: &'static Mutex, _routing_table: &'static RefCell, + _up_destinations: &'static RefCell<[bool; drtio_routing::DEST_COUNT]>, _timer: GlobalTimer) {} + pub fn reset(_aux_mutex: &Mutex, mut _timer: GlobalTimer) {} } -pub fn startup(aux_mutex: &Mutex, - routing_table: &RefCell, - up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>, timer: GlobalTimer) { +pub fn startup(aux_mutex: &'static Mutex, + routing_table: &'static RefCell, + up_destinations: &'static RefCell<[bool; drtio_routing::DEST_COUNT]>, + timer: GlobalTimer) { drtio::startup(aux_mutex, routing_table, up_destinations, timer); unsafe { csr::rtio_core::reset_phy_write(1); } } -pub fn reset(aux_mutex: &Mutex, timer: GlobalTimer) { +pub fn reset(aux_mutex: &Mutex, timer: GlobalTimer) { unsafe { csr::rtio_core::reset_write(1); }