master: runtime fixes per compiler's requests

drtio_port
mwojcik 2021-09-24 14:15:33 +02:00
parent 94ecc48d5d
commit 6dbd817d3e
5 changed files with 92 additions and 81 deletions

View File

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

View File

@ -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<bool> = 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<RefCell<kernel::Control>> = Rc::new(RefCell::new(kernel::Control::start()));
let idle_kernel = Rc::new(cfg.read("idle").ok());

View File

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

View File

@ -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<bool>, 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<bool>, _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<bool>, 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<bool>, _routing_table: &RefCell<drtio_routing::RoutingTable>) -> 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<bool>, routing_table: &'static RefCell<drtio_routing::RoutingTable>) {
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),

View File

@ -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<drtio_routing::RoutingTable>,
up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>) {
pub fn startup(aux_mutex: &'static Mutex<bool>,
routing_table: &'static RefCell<drtio_routing::RoutingTable>,
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<drtioaux::Packet, &'static str> {
async fn recv_aux_timeout(linkno: u8, timeout: u64, timer: GlobalTimer) -> Result<drtioaux::Packet, &'static str> {
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<bool>, linkno: u8, request: &drtioaux::Packet,
timer: GlobalTimer) -> Result<drtioaux::Packet, &'static str> {
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<bool>, 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<bool>, 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<bool>, 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<bool>, 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<bool>, 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<bool>, 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<bool>,
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<bool>, 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<drtio_routing::RoutingTable>,
_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<bool>, _routing_table: &'static RefCell<drtio_routing::RoutingTable>,
_up_destinations: &'static RefCell<[bool; drtio_routing::DEST_COUNT]>, _timer: GlobalTimer) {}
pub fn reset(_aux_mutex: &Mutex<bool>, mut _timer: GlobalTimer) {}
}
pub fn startup(aux_mutex: &Mutex,
routing_table: &RefCell<drtio_routing::RoutingTable>,
up_destinations: &RefCell<[bool; drtio_routing::DEST_COUNT]>, timer: GlobalTimer) {
pub fn startup(aux_mutex: &'static Mutex<bool>,
routing_table: &'static RefCell<drtio_routing::RoutingTable>,
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<bool>, timer: GlobalTimer) {
unsafe {
csr::rtio_core::reset_write(1);
}