Compare commits
5 Commits
14fa038118
...
3abe9caadb
Author | SHA1 | Date |
---|---|---|
mwojcik | 3abe9caadb | |
mwojcik | 0a19f8fb89 | |
mwojcik | a30c7d1f3a | |
mwojcik | 2d10503c20 | |
mwojcik | 92a29051f7 |
32
flake.lock
32
flake.lock
|
@ -11,11 +11,11 @@
|
||||||
"src-pythonparser": "src-pythonparser"
|
"src-pythonparser": "src-pythonparser"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1710303235,
|
"lastModified": 1714013217,
|
||||||
"narHash": "sha256-0rIfVoL8RInAQSDVfjpLdMqIYdnVsA8DdMk2+aqvwrM=",
|
"narHash": "sha256-P0pVHTSgAkTYWFPjddcPhufe5oH8mjJAsxG8x8mo4NA=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "master",
|
||||||
"rev": "c4323e1179aa0b9c9b4c135f894f267715cf2391",
|
"rev": "7204feae1f504e4a1dcd54b95c59e8f36c62b701",
|
||||||
"revCount": 8727,
|
"revCount": 8776,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/m-labs/artiq.git"
|
"url": "https://github.com/m-labs/artiq.git"
|
||||||
},
|
},
|
||||||
|
@ -118,11 +118,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1707347730,
|
"lastModified": 1711668574,
|
||||||
"narHash": "sha256-0etC/exQIaqC9vliKhc3eZE2Mm2wgLa0tj93ZF/egvM=",
|
"narHash": "sha256-u1dfs0ASQIEr1icTVrsKwg2xToIpn7ZXxW3RHfHxshg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6832d0d99649db3d65a0e15fa51471537b2c56a6",
|
"rev": "219951b495fc2eac67b1456824cc1ec1fd2ee659",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -147,11 +147,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1701572254,
|
"lastModified": 1708937641,
|
||||||
"narHash": "sha256-ixq8dlpyOytDr+d/OmW8v1Ioy9V2G2ibOlNj8GFDSq4=",
|
"narHash": "sha256-Hkb9VYFzFgkYxfbh4kYcDSn7DbMUYehoQDeTALrxo2Q=",
|
||||||
"owner": "m-labs",
|
"owner": "m-labs",
|
||||||
"repo": "sipyco",
|
"repo": "sipyco",
|
||||||
"rev": "cceac0df537887135f99aa6b1bdd82853f16b4d6",
|
"rev": "4a28b311ce0069454b4e8fe1e6049db11b9f1296",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -234,11 +234,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1709785588,
|
"lastModified": 1711358419,
|
||||||
"narHash": "sha256-2Pik/AP05ZKOrCfsXVZfdRijAWSyya9mrNTXzljFskM=",
|
"narHash": "sha256-LzetYaLsnov9pHVWSCTSowXUAXkxemAa61CIMY98xsc=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "master",
|
||||||
"rev": "7c58c0cf434f37504c62caa03c2c0d6b863da9bf",
|
"rev": "195a21fe78e4dde1fd705cb2899ab5d2763ae037",
|
||||||
"revCount": 641,
|
"revCount": 643,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.m-labs.hk/m-labs/zynq-rs"
|
"url": "https://git.m-labs.hk/m-labs/zynq-rs"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
"""Auxiliary controller, common to satellite and master"""
|
"""Auxiliary controller, common to satellite and master"""
|
||||||
|
|
||||||
from artiq.gateware.drtio.aux_controller import Transmitter, Receiver
|
from artiq.gateware.drtio.aux_controller import (max_packet, aux_buffer_count,
|
||||||
|
Transmitter, Receiver)
|
||||||
from migen.fhdl.simplify import FullMemoryWE
|
from migen.fhdl.simplify import FullMemoryWE
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
from migen_axi.interconnect.sram import SRAM
|
from migen_axi.interconnect.sram import SRAM
|
||||||
from migen_axi.interconnect import axi
|
from migen_axi.interconnect import axi
|
||||||
|
|
||||||
max_packet = 1024
|
|
||||||
|
|
||||||
class _DRTIOAuxControllerBase(Module):
|
class _DRTIOAuxControllerBase(Module):
|
||||||
def __init__(self, link_layer):
|
def __init__(self, link_layer):
|
||||||
|
@ -27,12 +27,12 @@ class DRTIOAuxControllerAxi(_DRTIOAuxControllerBase):
|
||||||
tx_sdram_if = SRAM(self.transmitter.mem, read_only=False)
|
tx_sdram_if = SRAM(self.transmitter.mem, read_only=False)
|
||||||
rx_sdram_if = SRAM(self.receiver.mem, read_only=True)
|
rx_sdram_if = SRAM(self.receiver.mem, read_only=True)
|
||||||
aw_decoder = axi.AddressDecoder(self.bus.aw,
|
aw_decoder = axi.AddressDecoder(self.bus.aw,
|
||||||
[(lambda a: a[log2_int(max_packet)] == 0, tx_sdram_if.bus.aw),
|
[(lambda a: a[log2_int(max_packet*aux_buffer_count)] == 0, tx_sdram_if.bus.aw),
|
||||||
(lambda a: a[log2_int(max_packet)] == 1, rx_sdram_if.bus.aw)],
|
(lambda a: a[log2_int(max_packet*aux_buffer_count)] == 1, rx_sdram_if.bus.aw)],
|
||||||
register=True)
|
register=True)
|
||||||
ar_decoder = axi.AddressDecoder(self.bus.ar,
|
ar_decoder = axi.AddressDecoder(self.bus.ar,
|
||||||
[(lambda a: a[log2_int(max_packet)] == 0, tx_sdram_if.bus.ar),
|
[(lambda a: a[log2_int(max_packet*aux_buffer_count)] == 0, tx_sdram_if.bus.ar),
|
||||||
(lambda a: a[log2_int(max_packet)] == 1, rx_sdram_if.bus.ar)],
|
(lambda a: a[log2_int(max_packet*aux_buffer_count)] == 1, rx_sdram_if.bus.ar)],
|
||||||
register=True)
|
register=True)
|
||||||
# unlike wb, axi address decoder only connects ar/aw lanes,
|
# unlike wb, axi address decoder only connects ar/aw lanes,
|
||||||
# the rest must also be connected!
|
# the rest must also be connected!
|
||||||
|
@ -82,4 +82,4 @@ class DRTIOAuxControllerBare(_DRTIOAuxControllerBase):
|
||||||
return self.receiver.mem.get_port(write_capable=False)
|
return self.receiver.mem.get_port(write_capable=False)
|
||||||
|
|
||||||
def get_mem_size(self):
|
def get_mem_size(self):
|
||||||
return max_packet
|
return max_packet*aux_buffer_count
|
||||||
|
|
|
@ -74,12 +74,15 @@ where F: FnOnce(&[u8]) -> Result<T, Error> {
|
||||||
let linkidx = linkno as usize;
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
||||||
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u32;
|
let read_ptr = (DRTIOAUX[linkidx].aux_read_pointer_read)() as usize;
|
||||||
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
|
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2 + read_ptr * 0x400) as *mut u32;
|
||||||
// work buffer to accomodate axi burst reads
|
// work buffer to accomodate axi burst reads
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
// buffer at maximum proto packet size, not maximum gateware supported size
|
||||||
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, len as isize);
|
// to minimize copying time
|
||||||
let result = f(&buf[0..len]);
|
const LEN: usize = 512;
|
||||||
|
let mut buf: [u8; LEN] = [0; LEN];
|
||||||
|
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, LEN as isize);
|
||||||
|
let result = f(&buf);
|
||||||
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
||||||
Ok(Some(result?))
|
Ok(Some(result?))
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,15 +103,15 @@ pub fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
||||||
|
|
||||||
let mut reader = Cursor::new(buffer);
|
let mut reader = Cursor::new(buffer);
|
||||||
|
|
||||||
let checksum_at = buffer.len() - 4;
|
let packet = Packet::read_from(&mut reader)?;
|
||||||
|
let padding = (12 - (reader.position() % 8)) % 8;
|
||||||
|
let checksum_at = reader.position() + padding;
|
||||||
let checksum = crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at]);
|
let checksum = crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at]);
|
||||||
reader.set_position(checksum_at);
|
reader.set_position(checksum_at);
|
||||||
if reader.read_u32()? != checksum {
|
if reader.read_u32()? != checksum {
|
||||||
return Err(Error::CorruptedPacket);
|
return Err(Error::CorruptedPacket);
|
||||||
}
|
}
|
||||||
reader.set_position(0);
|
Ok(packet)
|
||||||
|
|
||||||
Ok(Packet::read_from(&mut reader)?)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +133,9 @@ where F: FnOnce(&mut [u8]) -> Result<usize, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
||||||
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
||||||
let len = DRTIOAUX_MEM[linkno].size / 2;
|
|
||||||
// work buffer, works with unaligned mem access
|
// work buffer, works with unaligned mem access
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
let len = f(&mut buf[0..len])?;
|
let len = f(&mut buf)?;
|
||||||
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
|
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
|
||||||
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
||||||
(DRTIOAUX[linkno].aux_tx_write)(1);
|
(DRTIOAUX[linkno].aux_tx_write)(1);
|
||||||
|
|
|
@ -38,12 +38,15 @@ where F: FnOnce(&[u8]) -> Result<T, Error> {
|
||||||
let linkidx = linkno as usize;
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
|
||||||
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u32;
|
let read_ptr = (DRTIOAUX[linkidx].aux_read_pointer_read)() as usize;
|
||||||
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
|
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2 + read_ptr * 0x400) as *mut u32;
|
||||||
// work buffer to accomodate axi burst reads
|
// work buffer to accomodate axi burst reads
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
// buffer at maximum proto packet size, not maximum gateware supported size
|
||||||
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, len as isize);
|
// to minimize required copying time
|
||||||
let result = f(&buf[0..len]);
|
const LEN: usize = 512;
|
||||||
|
let mut buf: [u8; LEN] = [0; LEN];
|
||||||
|
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, LEN as isize);
|
||||||
|
let result = f(&buf);
|
||||||
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
|
||||||
Ok(Some(result?))
|
Ok(Some(result?))
|
||||||
} else {
|
} else {
|
||||||
|
@ -64,15 +67,15 @@ pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
||||||
|
|
||||||
let mut reader = Cursor::new(buffer);
|
let mut reader = Cursor::new(buffer);
|
||||||
|
|
||||||
let checksum_at = buffer.len() - 4;
|
let packet = Packet::read_from(&mut reader)?;
|
||||||
|
let padding = (12 - (reader.position() % 8)) % 8;
|
||||||
|
let checksum_at = reader.position() + padding;
|
||||||
let checksum = crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at]);
|
let checksum = crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at]);
|
||||||
reader.set_position(checksum_at);
|
reader.set_position(checksum_at);
|
||||||
if reader.read_u32()? != checksum {
|
if reader.read_u32()? != checksum {
|
||||||
return Err(Error::CorruptedPacket);
|
return Err(Error::CorruptedPacket);
|
||||||
}
|
}
|
||||||
reader.set_position(0);
|
Ok(packet)
|
||||||
|
|
||||||
Ok(Packet::read_from(&mut reader)?)
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -103,10 +106,9 @@ where F: FnOnce(&mut [u8]) -> Result<usize, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = block_async!(tx_ready(linkno)).await;
|
let _ = block_async!(tx_ready(linkno)).await;
|
||||||
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
|
||||||
let len = DRTIOAUX_MEM[linkno].size / 2;
|
|
||||||
// work buffer, works with unaligned mem access
|
// work buffer, works with unaligned mem access
|
||||||
let mut buf: [u8; 1024] = [0; 1024];
|
let mut buf: [u8; 1024] = [0; 1024];
|
||||||
let len = f(&mut buf[0..len])?;
|
let len = f(&mut buf)?;
|
||||||
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
|
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
|
||||||
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
|
||||||
(DRTIOAUX[linkno].aux_tx_write)(1);
|
(DRTIOAUX[linkno].aux_tx_write)(1);
|
||||||
|
|
|
@ -89,8 +89,6 @@ pub enum Packet {
|
||||||
RoutingSetRank {
|
RoutingSetRank {
|
||||||
rank: u8,
|
rank: u8,
|
||||||
},
|
},
|
||||||
RoutingRetrievePackets,
|
|
||||||
RoutingNoPackets,
|
|
||||||
RoutingAck,
|
RoutingAck,
|
||||||
|
|
||||||
MonitorRequest {
|
MonitorRequest {
|
||||||
|
@ -325,8 +323,6 @@ impl Packet {
|
||||||
rank: reader.read_u8()?,
|
rank: reader.read_u8()?,
|
||||||
},
|
},
|
||||||
0x32 => Packet::RoutingAck,
|
0x32 => Packet::RoutingAck,
|
||||||
0x33 => Packet::RoutingRetrievePackets,
|
|
||||||
0x34 => Packet::RoutingNoPackets,
|
|
||||||
|
|
||||||
0x40 => Packet::MonitorRequest {
|
0x40 => Packet::MonitorRequest {
|
||||||
destination: reader.read_u8()?,
|
destination: reader.read_u8()?,
|
||||||
|
@ -602,8 +598,6 @@ impl Packet {
|
||||||
writer.write_u8(rank)?;
|
writer.write_u8(rank)?;
|
||||||
}
|
}
|
||||||
Packet::RoutingAck => writer.write_u8(0x32)?,
|
Packet::RoutingAck => writer.write_u8(0x32)?,
|
||||||
Packet::RoutingRetrievePackets => writer.write_u8(0x33)?,
|
|
||||||
Packet::RoutingNoPackets => writer.write_u8(0x34)?,
|
|
||||||
|
|
||||||
Packet::MonitorRequest {
|
Packet::MonitorRequest {
|
||||||
destination,
|
destination,
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub mod remote_analyzer {
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) -> Result<RemoteBuffer, &'static str> {
|
) -> Result<RemoteBuffer, drtio::Error> {
|
||||||
// gets data from satellites and returns consolidated data
|
// gets data from satellites and returns consolidated data
|
||||||
let mut remote_data: Vec<u8> = Vec::new();
|
let mut remote_data: Vec<u8> = Vec::new();
|
||||||
let mut remote_error = false;
|
let mut remote_error = false;
|
||||||
|
|
|
@ -58,10 +58,11 @@ mod remote_moninj {
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::rtio_mgt::drtio;
|
use crate::rtio_mgt::{drtio, drtio::Error as DrtioError};
|
||||||
|
|
||||||
pub async fn read_probe(
|
pub async fn read_probe(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
|
@ -71,6 +72,7 @@ mod remote_moninj {
|
||||||
let reply = drtio::aux_transact(
|
let reply = drtio::aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&drtioaux_async::Packet::MonitorRequest {
|
&drtioaux_async::Packet::MonitorRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
channel: channel as _,
|
channel: channel as _,
|
||||||
|
@ -82,8 +84,8 @@ mod remote_moninj {
|
||||||
match reply {
|
match reply {
|
||||||
Ok(drtioaux_async::Packet::MonitorReply { value }) => return value as i64,
|
Ok(drtioaux_async::Packet::MonitorReply { value }) => return value as i64,
|
||||||
Ok(packet) => error!("received unexpected aux packet: {:?}", packet),
|
Ok(packet) => error!("received unexpected aux packet: {:?}", packet),
|
||||||
Err("link went down") => {
|
Err(DrtioError::LinkDown) => {
|
||||||
debug!("link is down");
|
warn!("link is down");
|
||||||
}
|
}
|
||||||
Err(e) => error!("aux packet error ({})", e),
|
Err(e) => error!("aux packet error ({})", e),
|
||||||
}
|
}
|
||||||
|
@ -92,6 +94,7 @@ mod remote_moninj {
|
||||||
|
|
||||||
pub async fn inject(
|
pub async fn inject(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
|
_routing_table: &drtio_routing::RoutingTable,
|
||||||
_timer: GlobalTimer,
|
_timer: GlobalTimer,
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
|
@ -115,6 +118,7 @@ mod remote_moninj {
|
||||||
|
|
||||||
pub async fn read_injection_status(
|
pub async fn read_injection_status(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
|
@ -124,6 +128,7 @@ mod remote_moninj {
|
||||||
let reply = drtio::aux_transact(
|
let reply = drtio::aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&drtioaux_async::Packet::InjectionStatusRequest {
|
&drtioaux_async::Packet::InjectionStatusRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
channel: channel as _,
|
channel: channel as _,
|
||||||
|
@ -135,8 +140,8 @@ mod remote_moninj {
|
||||||
match reply {
|
match reply {
|
||||||
Ok(drtioaux_async::Packet::InjectionStatusReply { value }) => return value as i8,
|
Ok(drtioaux_async::Packet::InjectionStatusReply { value }) => return value as i8,
|
||||||
Ok(packet) => error!("received unexpected aux packet: {:?}", packet),
|
Ok(packet) => error!("received unexpected aux packet: {:?}", packet),
|
||||||
Err("link went down") => {
|
Err(DrtioError::LinkDown) => {
|
||||||
debug!("link is down");
|
warn!("link is down");
|
||||||
}
|
}
|
||||||
Err(e) => error!("aux packet error ({})", e),
|
Err(e) => error!("aux packet error ({})", e),
|
||||||
}
|
}
|
||||||
|
@ -183,7 +188,7 @@ macro_rules! dispatch {
|
||||||
local_moninj::$func(channel.into(), $($param, )*)
|
local_moninj::$func(channel.into(), $($param, )*)
|
||||||
} else {
|
} else {
|
||||||
let linkno = hop - 1 as u8;
|
let linkno = hop - 1 as u8;
|
||||||
remote_moninj::$func($aux_mutex, $timer, linkno, destination, channel, $($param, )*).await
|
remote_moninj::$func($aux_mutex, $routing_table, $timer, linkno, destination, channel, $($param, )*).await
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use libboard_artiq::{drtio_routing, pl::csr};
|
use libboard_artiq::{drtio_routing, drtio_routing::RoutingTable, pl::csr};
|
||||||
use libboard_zynq::timer::GlobalTimer;
|
use libboard_zynq::timer::GlobalTimer;
|
||||||
use libcortex_a9::mutex::Mutex;
|
use libcortex_a9::mutex::Mutex;
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
pub mod drtio {
|
pub mod drtio {
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
use embedded_hal::blocking::delay::DelayMs;
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
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,
|
use libboard_artiq::{drtioaux::Error as DrtioError,
|
||||||
drtioaux_async,
|
drtioaux_async,
|
||||||
drtioaux_async::Packet,
|
drtioaux_async::Packet,
|
||||||
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE}};
|
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE}};
|
||||||
|
@ -23,9 +24,44 @@ pub mod drtio {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{analyzer::remote_analyzer::RemoteBuffer, rtio_dma::remote_dma, subkernel};
|
use crate::{analyzer::remote_analyzer::RemoteBuffer, rtio_dma::remote_dma, subkernel};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
pub enum Error {
|
||||||
|
Timeout,
|
||||||
|
AuxError,
|
||||||
|
LinkDown,
|
||||||
|
UnexpectedReply,
|
||||||
|
DmaAddTraceFail(u8),
|
||||||
|
DmaEraseFail(u8),
|
||||||
|
DmaPlaybackFail(u8),
|
||||||
|
SubkernelAddFail(u8),
|
||||||
|
SubkernelRunFail(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::Timeout => write!(f, "timed out"),
|
||||||
|
Error::AuxError => write!(f, "aux packet error"),
|
||||||
|
Error::LinkDown => write!(f, "link down"),
|
||||||
|
Error::UnexpectedReply => write!(f, "unexpected reply"),
|
||||||
|
Error::DmaAddTraceFail(dest) => write!(f, "error adding DMA trace on satellite #{}", dest),
|
||||||
|
Error::DmaEraseFail(dest) => write!(f, "error erasing DMA trace on satellite #{}", dest),
|
||||||
|
Error::DmaPlaybackFail(dest) => write!(f, "error playing back DMA trace on satellite #{}", dest),
|
||||||
|
Error::SubkernelAddFail(dest) => write!(f, "error adding subkernel on satellite #{}", dest),
|
||||||
|
Error::SubkernelRunFail(dest) => write!(f, "error on subkernel run request on satellite #{}", dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DrtioError> for Error {
|
||||||
|
fn from(_error: DrtioError) -> Self {
|
||||||
|
Error::AuxError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn startup(
|
pub fn startup(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
routing_table: &Rc<RefCell<RoutingTable>>,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) {
|
) {
|
||||||
|
@ -43,128 +79,104 @@ pub mod drtio {
|
||||||
unsafe { (csr::DRTIO[linkno].rx_up_read)() == 1 }
|
unsafe { (csr::DRTIO[linkno].rx_up_read)() == 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn link_has_async_ready(linkno: u8) -> bool {
|
async fn process_async_packets(linkno: u8, routing_table: &RoutingTable, packet: Packet) -> Option<Packet> {
|
||||||
let linkno = linkno as usize;
|
match packet {
|
||||||
let async_ready;
|
Packet::DmaPlaybackStatus {
|
||||||
unsafe {
|
id,
|
||||||
async_ready = (csr::DRTIO[linkno].async_messages_ready_read)() == 1;
|
source,
|
||||||
(csr::DRTIO[linkno].async_messages_ready_write)(1);
|
destination: 0,
|
||||||
}
|
error,
|
||||||
async_ready
|
channel,
|
||||||
}
|
timestamp,
|
||||||
|
} => {
|
||||||
async fn process_async_packets(
|
remote_dma::playback_done(id, source, error, channel, timestamp).await;
|
||||||
aux_mutex: &Mutex<bool>,
|
None
|
||||||
linkno: u8,
|
}
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
Packet::SubkernelFinished {
|
||||||
timer: GlobalTimer,
|
id,
|
||||||
) {
|
destination: 0,
|
||||||
if link_has_async_ready(linkno).await {
|
with_exception,
|
||||||
loop {
|
exception_src,
|
||||||
let reply = aux_transact(aux_mutex, linkno, &Packet::RoutingRetrievePackets, timer).await;
|
} => {
|
||||||
if let Ok(packet) = reply {
|
subkernel::subkernel_finished(id, with_exception, exception_src).await;
|
||||||
match packet {
|
None
|
||||||
Packet::DmaPlaybackStatus {
|
}
|
||||||
id,
|
Packet::SubkernelMessage {
|
||||||
source,
|
id,
|
||||||
destination: 0,
|
source,
|
||||||
error,
|
destination: 0,
|
||||||
channel,
|
status,
|
||||||
timestamp,
|
length,
|
||||||
} => {
|
data,
|
||||||
remote_dma::playback_done(id, source, error, channel, timestamp).await;
|
} => {
|
||||||
}
|
subkernel::message_handle_incoming(id, status, length as usize, &data).await;
|
||||||
Packet::SubkernelFinished {
|
// acknowledge receiving part of the message
|
||||||
id,
|
drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: source })
|
||||||
destination: 0,
|
.await
|
||||||
with_exception,
|
.unwrap();
|
||||||
exception_src,
|
None
|
||||||
} => {
|
}
|
||||||
subkernel::subkernel_finished(id, with_exception, exception_src).await;
|
// routable packets
|
||||||
}
|
Packet::DmaAddTraceRequest { destination, .. }
|
||||||
Packet::SubkernelMessage {
|
| Packet::DmaAddTraceReply { destination, .. }
|
||||||
id,
|
| Packet::DmaRemoveTraceRequest { destination, .. }
|
||||||
source,
|
| Packet::DmaRemoveTraceReply { destination, .. }
|
||||||
destination: 0,
|
| Packet::DmaPlaybackRequest { destination, .. }
|
||||||
status,
|
| Packet::DmaPlaybackReply { destination, .. }
|
||||||
length,
|
| Packet::SubkernelLoadRunRequest { destination, .. }
|
||||||
data,
|
| Packet::SubkernelLoadRunReply { destination, .. }
|
||||||
} => {
|
| Packet::SubkernelMessage { destination, .. }
|
||||||
subkernel::message_handle_incoming(id, status, length as usize, &data).await;
|
| Packet::SubkernelMessageAck { destination, .. }
|
||||||
// acknowledge receiving part of the message
|
| Packet::DmaPlaybackStatus { destination, .. }
|
||||||
let _lock = aux_mutex.async_lock().await;
|
| Packet::SubkernelFinished { destination, .. } => {
|
||||||
drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: source })
|
if destination == 0 {
|
||||||
.await
|
Some(packet)
|
||||||
.unwrap();
|
|
||||||
let mut countdown = timer.countdown();
|
|
||||||
// give the satellites some time to process
|
|
||||||
delay(&mut countdown, Milliseconds(10)).await;
|
|
||||||
}
|
|
||||||
// routable packets
|
|
||||||
Packet::DmaAddTraceRequest { destination, .. }
|
|
||||||
| Packet::DmaAddTraceReply { destination, .. }
|
|
||||||
| Packet::DmaRemoveTraceRequest { destination, .. }
|
|
||||||
| Packet::DmaRemoveTraceReply { destination, .. }
|
|
||||||
| Packet::DmaPlaybackRequest { destination, .. }
|
|
||||||
| Packet::DmaPlaybackReply { destination, .. }
|
|
||||||
| Packet::SubkernelLoadRunRequest { destination, .. }
|
|
||||||
| Packet::SubkernelLoadRunReply { destination, .. }
|
|
||||||
| Packet::SubkernelMessage { destination, .. }
|
|
||||||
| Packet::SubkernelMessageAck { destination, .. }
|
|
||||||
| Packet::DmaPlaybackStatus { destination, .. }
|
|
||||||
| Packet::SubkernelFinished { destination, .. } => {
|
|
||||||
let dest_link = routing_table.0[destination as usize][0] - 1;
|
|
||||||
if dest_link == linkno {
|
|
||||||
warn!(
|
|
||||||
"[LINK#{}] Re-routed packet would return to the same link, dropping: {:?}",
|
|
||||||
linkno, packet
|
|
||||||
);
|
|
||||||
} else if destination == 0 {
|
|
||||||
warn!("[LINK#{}] Received invalid routable packet: {:?}", linkno, packet)
|
|
||||||
} else {
|
|
||||||
drtioaux_async::send(dest_link, &packet).await.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet::RoutingNoPackets => break,
|
|
||||||
|
|
||||||
other => warn!("[LINK#{}] Received an unroutable packet: {:?}", linkno, other),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
let dest_link = routing_table.0[destination as usize][0] - 1;
|
||||||
"[LINK#{}] Error handling async packets ({})",
|
if dest_link == linkno {
|
||||||
linkno,
|
warn!(
|
||||||
reply.unwrap_err()
|
"[LINK#{}] Re-routed packet would return to the same link, dropping: {:?}",
|
||||||
);
|
linkno, packet
|
||||||
return;
|
);
|
||||||
|
} else {
|
||||||
|
drtioaux_async::send(dest_link, &packet).await.unwrap();
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
other => Some(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn recv_aux_timeout(linkno: u8, timeout: u64, timer: GlobalTimer) -> Result<Packet, &'static str> {
|
async fn recv_aux_timeout(linkno: u8, timeout: u64, timer: GlobalTimer) -> Result<Packet, Error> {
|
||||||
if !link_rx_up(linkno).await {
|
if !link_rx_up(linkno).await {
|
||||||
return Err("link went down");
|
return Err(Error::LinkDown);
|
||||||
}
|
}
|
||||||
match drtioaux_async::recv_timeout(linkno, Some(timeout), timer).await {
|
match drtioaux_async::recv_timeout(linkno, Some(timeout), timer).await {
|
||||||
Ok(packet) => return Ok(packet),
|
Ok(packet) => return Ok(packet),
|
||||||
Err(Error::TimedOut) => return Err("timed out"),
|
Err(DrtioError::TimedOut) => return Err(Error::Timeout),
|
||||||
Err(_) => return Err("aux packet error"),
|
Err(_) => return Err(Error::AuxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn aux_transact(
|
pub async fn aux_transact(
|
||||||
aux_mutex: &Mutex<bool>,
|
aux_mutex: &Mutex<bool>,
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
|
routing_table: &RoutingTable,
|
||||||
request: &Packet,
|
request: &Packet,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) -> Result<Packet, &'static str> {
|
) -> Result<Packet, Error> {
|
||||||
if !link_rx_up(linkno).await {
|
if !link_rx_up(linkno).await {
|
||||||
return Err("link went down");
|
return Err(Error::LinkDown);
|
||||||
}
|
}
|
||||||
let _lock = aux_mutex.async_lock().await;
|
let _lock = aux_mutex.async_lock().await;
|
||||||
drtioaux_async::send(linkno, request).await.unwrap();
|
drtioaux_async::send(linkno, request).await.unwrap();
|
||||||
Ok(recv_aux_timeout(linkno, 200, timer).await?)
|
loop {
|
||||||
|
let packet = recv_aux_timeout(linkno, 200, timer).await?;
|
||||||
|
if let Some(packet) = process_async_packets(linkno, routing_table, packet).await {
|
||||||
|
return Ok(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn drain_buffer(linkno: u8, draining_time: Milliseconds, timer: GlobalTimer) {
|
async fn drain_buffer(linkno: u8, draining_time: Milliseconds, timer: GlobalTimer) {
|
||||||
|
@ -172,12 +184,17 @@ pub mod drtio {
|
||||||
loop {
|
loop {
|
||||||
if timer.get_time() > max_time {
|
if timer.get_time() > max_time {
|
||||||
return;
|
return;
|
||||||
} //could this be cut short?
|
}
|
||||||
let _ = drtioaux_async::recv(linkno).await;
|
let _ = drtioaux_async::recv(linkno).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ping_remote(aux_mutex: &Rc<Mutex<bool>>, linkno: u8, timer: GlobalTimer) -> u32 {
|
async fn ping_remote(
|
||||||
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
|
linkno: u8,
|
||||||
|
routing_table: &RoutingTable,
|
||||||
|
timer: GlobalTimer,
|
||||||
|
) -> u32 {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
loop {
|
loop {
|
||||||
if !link_rx_up(linkno).await {
|
if !link_rx_up(linkno).await {
|
||||||
|
@ -187,7 +204,7 @@ pub mod drtio {
|
||||||
if count > 100 {
|
if count > 100 {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
let reply = aux_transact(aux_mutex, linkno, &Packet::EchoRequest, timer).await;
|
let reply = aux_transact(aux_mutex, linkno, routing_table, &Packet::EchoRequest, timer).await;
|
||||||
match reply {
|
match reply {
|
||||||
Ok(Packet::EchoReply) => {
|
Ok(Packet::EchoReply) => {
|
||||||
// make sure receive buffer is drained
|
// make sure receive buffer is drained
|
||||||
|
@ -200,7 +217,7 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_tsc(aux_mutex: &Rc<Mutex<bool>>, linkno: u8, timer: GlobalTimer) -> Result<(), &'static str> {
|
async fn sync_tsc(aux_mutex: &Rc<Mutex<bool>>, linkno: u8, timer: GlobalTimer) -> Result<(), Error> {
|
||||||
let _lock = aux_mutex.async_lock().await;
|
let _lock = aux_mutex.async_lock().await;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -211,22 +228,23 @@ pub mod drtio {
|
||||||
// by the satellite, in response to a TSC set on the RT link.
|
// by the satellite, in response to a TSC set on the RT link.
|
||||||
let reply = recv_aux_timeout(linkno, 10000, timer).await?;
|
let reply = recv_aux_timeout(linkno, 10000, timer).await?;
|
||||||
if reply == Packet::TSCAck {
|
if reply == Packet::TSCAck {
|
||||||
return Ok(());
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
return Err("unexpected reply");
|
Err(Error::UnexpectedReply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn load_routing_table(
|
async fn load_routing_table(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
for i in 0..drtio_routing::DEST_COUNT {
|
for i in 0..drtio_routing::DEST_COUNT {
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::RoutingSetPath {
|
&Packet::RoutingSetPath {
|
||||||
destination: i as u8,
|
destination: i as u8,
|
||||||
hops: routing_table.0[i],
|
hops: routing_table.0[i],
|
||||||
|
@ -235,7 +253,7 @@ pub mod drtio {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if reply != Packet::RoutingAck {
|
if reply != Packet::RoutingAck {
|
||||||
return Err("unexpected reply");
|
return Err(Error::UnexpectedReply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -245,13 +263,21 @@ pub mod drtio {
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
rank: u8,
|
rank: u8,
|
||||||
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let reply = aux_transact(aux_mutex, linkno, &Packet::RoutingSetRank { rank: rank }, timer).await?;
|
let reply = aux_transact(
|
||||||
if reply != Packet::RoutingAck {
|
aux_mutex,
|
||||||
return Err("unexpected reply");
|
linkno,
|
||||||
|
routing_table,
|
||||||
|
&Packet::RoutingSetRank { rank: rank },
|
||||||
|
timer,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
match reply {
|
||||||
|
Packet::RoutingAck => Ok(()),
|
||||||
|
_ => Err(Error::UnexpectedReply),
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn init_buffer_space(destination: u8, linkno: u8) {
|
async fn init_buffer_space(destination: u8, linkno: u8) {
|
||||||
|
@ -270,10 +296,14 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_unsolicited_aux(aux_mutex: &Rc<Mutex<bool>>, linkno: u8) {
|
async fn process_unsolicited_aux(aux_mutex: &Mutex<bool>, linkno: u8, routing_table: &RoutingTable) {
|
||||||
let _lock = aux_mutex.async_lock().await;
|
let _lock = aux_mutex.async_lock().await;
|
||||||
match drtioaux_async::recv(linkno).await {
|
match drtioaux_async::recv(linkno).await {
|
||||||
Ok(Some(packet)) => warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet),
|
Ok(Some(packet)) => {
|
||||||
|
if let Some(packet) = process_async_packets(linkno, routing_table, packet).await {
|
||||||
|
warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(None) => (),
|
Ok(None) => (),
|
||||||
Err(_) => warn!("[LINK#{}] aux packet error", linkno),
|
Err(_) => warn!("[LINK#{}] aux packet error", linkno),
|
||||||
}
|
}
|
||||||
|
@ -301,7 +331,7 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn destination_set_up(
|
async fn destination_set_up(
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
up: bool,
|
up: bool,
|
||||||
|
@ -324,7 +354,7 @@ pub mod drtio {
|
||||||
|
|
||||||
async fn destination_survey(
|
async fn destination_survey(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
up_links: &[bool],
|
up_links: &[bool],
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
|
@ -345,6 +375,7 @@ pub mod drtio {
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::DestinationStatusRequest {
|
&Packet::DestinationStatusRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
},
|
},
|
||||||
|
@ -400,6 +431,7 @@ pub mod drtio {
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::DestinationStatusRequest {
|
&Packet::DestinationStatusRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
},
|
},
|
||||||
|
@ -427,7 +459,7 @@ pub mod drtio {
|
||||||
|
|
||||||
pub async fn link_task(
|
pub async fn link_task(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) {
|
) {
|
||||||
|
@ -438,8 +470,7 @@ pub mod drtio {
|
||||||
if up_links[linkno as usize] {
|
if up_links[linkno as usize] {
|
||||||
/* link was previously up */
|
/* link was previously up */
|
||||||
if link_rx_up(linkno).await {
|
if link_rx_up(linkno).await {
|
||||||
process_async_packets(aux_mutex, linkno, routing_table, timer).await;
|
process_unsolicited_aux(aux_mutex, linkno, routing_table).await;
|
||||||
process_unsolicited_aux(aux_mutex, linkno).await;
|
|
||||||
process_local_errors(linkno).await;
|
process_local_errors(linkno).await;
|
||||||
} else {
|
} else {
|
||||||
info!("[LINK#{}] link is down", linkno);
|
info!("[LINK#{}] link is down", linkno);
|
||||||
|
@ -449,7 +480,7 @@ pub mod drtio {
|
||||||
/* link was previously down */
|
/* link was previously down */
|
||||||
if link_rx_up(linkno).await {
|
if link_rx_up(linkno).await {
|
||||||
info!("[LINK#{}] link RX became up, pinging", linkno);
|
info!("[LINK#{}] link RX became up, pinging", linkno);
|
||||||
let ping_count = ping_remote(aux_mutex, linkno, timer).await;
|
let ping_count = ping_remote(aux_mutex, linkno, routing_table, timer).await;
|
||||||
if ping_count > 0 {
|
if ping_count > 0 {
|
||||||
info!("[LINK#{}] remote replied after {} packets", linkno, ping_count);
|
info!("[LINK#{}] remote replied after {} packets", linkno, ping_count);
|
||||||
up_links[linkno as usize] = true;
|
up_links[linkno as usize] = true;
|
||||||
|
@ -459,7 +490,7 @@ pub mod drtio {
|
||||||
if let Err(e) = load_routing_table(aux_mutex, linkno, routing_table, timer).await {
|
if let Err(e) = load_routing_table(aux_mutex, linkno, routing_table, timer).await {
|
||||||
error!("[LINK#{}] failed to load routing table ({})", linkno, e);
|
error!("[LINK#{}] failed to load routing table ({})", linkno, e);
|
||||||
}
|
}
|
||||||
if let Err(e) = set_rank(aux_mutex, linkno, 1 as u8, timer).await {
|
if let Err(e) = set_rank(aux_mutex, linkno, 1 as u8, routing_table, timer).await {
|
||||||
error!("[LINK#{}] failed to set rank ({})", linkno, e);
|
error!("[LINK#{}] failed to set rank ({})", linkno, e);
|
||||||
}
|
}
|
||||||
info!("[LINK#{}] link initialization completed", linkno);
|
info!("[LINK#{}] link initialization completed", linkno);
|
||||||
|
@ -476,7 +507,7 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn reset(aux_mutex: Rc<Mutex<bool>>, mut timer: GlobalTimer) {
|
pub fn reset(aux_mutex: Rc<Mutex<bool>>, routing_table: &RoutingTable, mut timer: GlobalTimer) {
|
||||||
for linkno in 0..csr::DRTIO.len() {
|
for linkno in 0..csr::DRTIO.len() {
|
||||||
unsafe {
|
unsafe {
|
||||||
(csr::DRTIO[linkno].reset_write)(1);
|
(csr::DRTIO[linkno].reset_write)(1);
|
||||||
|
@ -492,7 +523,13 @@ pub mod drtio {
|
||||||
for linkno in 0..csr::DRTIO.len() {
|
for linkno in 0..csr::DRTIO.len() {
|
||||||
let linkno = linkno as u8;
|
let linkno = linkno as u8;
|
||||||
if task::block_on(link_rx_up(linkno)) {
|
if task::block_on(link_rx_up(linkno)) {
|
||||||
let reply = task::block_on(aux_transact(&aux_mutex, linkno, &Packet::ResetRequest, timer));
|
let reply = task::block_on(aux_transact(
|
||||||
|
&aux_mutex,
|
||||||
|
linkno,
|
||||||
|
routing_table,
|
||||||
|
&Packet::ResetRequest,
|
||||||
|
timer,
|
||||||
|
));
|
||||||
match reply {
|
match reply {
|
||||||
Ok(Packet::ResetAck) => (),
|
Ok(Packet::ResetAck) => (),
|
||||||
Ok(_) => error!("[LINK#{}] reset failed, received unexpected aux packet", linkno),
|
Ok(_) => error!("[LINK#{}] reset failed, received unexpected aux packet", linkno),
|
||||||
|
@ -505,14 +542,15 @@ pub mod drtio {
|
||||||
async fn partition_data<PacketF, HandlerF>(
|
async fn partition_data<PacketF, HandlerF>(
|
||||||
linkno: u8,
|
linkno: u8,
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
packet_f: PacketF,
|
packet_f: PacketF,
|
||||||
reply_handler_f: HandlerF,
|
reply_handler_f: HandlerF,
|
||||||
) -> Result<(), &'static str>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
PacketF: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], PayloadStatus, usize) -> Packet,
|
PacketF: Fn(&[u8; MASTER_PAYLOAD_MAX_SIZE], PayloadStatus, usize) -> Packet,
|
||||||
HandlerF: Fn(&Packet) -> Result<(), &'static str>,
|
HandlerF: Fn(&Packet) -> Result<(), Error>,
|
||||||
{
|
{
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < data.len() {
|
while i < data.len() {
|
||||||
|
@ -528,7 +566,7 @@ pub mod drtio {
|
||||||
i += len;
|
i += len;
|
||||||
let status = PayloadStatus::from_status(first, last);
|
let status = PayloadStatus::from_status(first, last);
|
||||||
let packet = packet_f(&slice, status, len);
|
let packet = packet_f(&slice, status, len);
|
||||||
let reply = aux_transact(aux_mutex, linkno, &packet, timer).await?;
|
let reply = aux_transact(aux_mutex, linkno, routing_table, &packet, timer).await?;
|
||||||
reply_handler_f(&reply)?;
|
reply_handler_f(&reply)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -536,16 +574,17 @@ pub mod drtio {
|
||||||
|
|
||||||
pub async fn ddma_upload_trace(
|
pub async fn ddma_upload_trace(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
id: u32,
|
id: u32,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
trace: &Vec<u8>,
|
trace: &Vec<u8>,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
partition_data(
|
partition_data(
|
||||||
linkno,
|
linkno,
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
|
routing_table,
|
||||||
timer,
|
timer,
|
||||||
trace,
|
trace,
|
||||||
|slice, status, len| Packet::DmaAddTraceRequest {
|
|slice, status, len| Packet::DmaAddTraceRequest {
|
||||||
|
@ -566,8 +605,8 @@ pub mod drtio {
|
||||||
destination: 0,
|
destination: 0,
|
||||||
succeeded: false,
|
succeeded: false,
|
||||||
..
|
..
|
||||||
} => Err("error adding trace on satellite"),
|
} => Err(Error::DmaAddTraceFail(destination)),
|
||||||
_ => Err("adding DMA trace failed, unexpected aux packet"),
|
_ => Err(Error::UnexpectedReply),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -575,15 +614,16 @@ pub mod drtio {
|
||||||
|
|
||||||
pub async fn ddma_send_erase(
|
pub async fn ddma_send_erase(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
id: u32,
|
id: u32,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::DmaRemoveTraceRequest {
|
&Packet::DmaRemoveTraceRequest {
|
||||||
id: id,
|
id: id,
|
||||||
source: 0,
|
source: 0,
|
||||||
|
@ -591,33 +631,33 @@ pub mod drtio {
|
||||||
},
|
},
|
||||||
timer,
|
timer,
|
||||||
)
|
)
|
||||||
.await;
|
.await?;
|
||||||
match reply {
|
match reply {
|
||||||
Ok(Packet::DmaRemoveTraceReply {
|
Packet::DmaRemoveTraceReply {
|
||||||
destination: 0,
|
destination: 0,
|
||||||
succeeded: true,
|
succeeded: true,
|
||||||
}) => Ok(()),
|
} => Ok(()),
|
||||||
Ok(Packet::DmaRemoveTraceReply {
|
Packet::DmaRemoveTraceReply {
|
||||||
destination: 0,
|
destination: 0,
|
||||||
succeeded: false,
|
succeeded: false,
|
||||||
}) => Err("satellite DMA erase error"),
|
} => Err(Error::DmaEraseFail(destination)),
|
||||||
Ok(_) => Err("adding trace failed, unexpected aux packet"),
|
_ => Err(Error::UnexpectedReply),
|
||||||
Err(_) => Err("erasing trace failed, aux error"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn ddma_send_playback(
|
pub async fn ddma_send_playback(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
id: u32,
|
id: u32,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::DmaPlaybackRequest {
|
&Packet::DmaPlaybackRequest {
|
||||||
id: id,
|
id: id,
|
||||||
source: 0,
|
source: 0,
|
||||||
|
@ -626,45 +666,44 @@ pub mod drtio {
|
||||||
},
|
},
|
||||||
timer,
|
timer,
|
||||||
)
|
)
|
||||||
.await;
|
.await?;
|
||||||
match reply {
|
match reply {
|
||||||
Ok(Packet::DmaPlaybackReply {
|
Packet::DmaPlaybackReply {
|
||||||
destination: 0,
|
destination: 0,
|
||||||
succeeded: true,
|
succeeded: true,
|
||||||
}) => Ok(()),
|
} => Ok(()),
|
||||||
Ok(Packet::DmaPlaybackReply {
|
Packet::DmaPlaybackReply {
|
||||||
destination: 0,
|
destination: 0,
|
||||||
succeeded: false,
|
succeeded: false,
|
||||||
}) => Err("error on DMA playback request"),
|
} => Err(Error::DmaPlaybackFail(destination)),
|
||||||
Ok(_) => Err("received unexpected aux packet during DMA playback"),
|
_ => Err(Error::UnexpectedReply),
|
||||||
Err(_) => Err("aux error on DMA playback"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn analyzer_get_data(
|
async fn analyzer_get_data(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
) -> Result<RemoteBuffer, &'static str> {
|
) -> Result<RemoteBuffer, Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::AnalyzerHeaderRequest {
|
&Packet::AnalyzerHeaderRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
},
|
},
|
||||||
timer,
|
timer,
|
||||||
)
|
)
|
||||||
.await;
|
.await?;
|
||||||
let (sent, total, overflow) = match reply {
|
let (sent, total, overflow) = match reply {
|
||||||
Ok(Packet::AnalyzerHeader {
|
Packet::AnalyzerHeader {
|
||||||
sent_bytes,
|
sent_bytes,
|
||||||
total_byte_count,
|
total_byte_count,
|
||||||
overflow_occurred,
|
overflow_occurred,
|
||||||
}) => (sent_bytes, total_byte_count, overflow_occurred),
|
} => (sent_bytes, total_byte_count, overflow_occurred),
|
||||||
Ok(_) => return Err("received unexpected aux packet during remote analyzer header request"),
|
_ => return Err(Error::UnexpectedReply),
|
||||||
Err(e) => return Err(e),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut remote_data: Vec<u8> = Vec::new();
|
let mut remote_data: Vec<u8> = Vec::new();
|
||||||
|
@ -674,19 +713,19 @@ pub mod drtio {
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::AnalyzerDataRequest {
|
&Packet::AnalyzerDataRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
},
|
},
|
||||||
timer,
|
timer,
|
||||||
)
|
)
|
||||||
.await;
|
.await?;
|
||||||
match reply {
|
match reply {
|
||||||
Ok(Packet::AnalyzerData { last, length, data }) => {
|
Packet::AnalyzerData { last, length, data } => {
|
||||||
last_packet = last;
|
last_packet = last;
|
||||||
remote_data.extend(&data[0..length as usize]);
|
remote_data.extend(&data[0..length as usize]);
|
||||||
}
|
}
|
||||||
Ok(_) => return Err("received unexpected aux packet during remote analyzer data request"),
|
_ => return Err(Error::UnexpectedReply),
|
||||||
Err(e) => return Err(e),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,10 +740,10 @@ pub mod drtio {
|
||||||
|
|
||||||
pub async fn analyzer_query(
|
pub async fn analyzer_query(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) -> Result<Vec<RemoteBuffer>, &'static str> {
|
) -> Result<Vec<RemoteBuffer>, Error> {
|
||||||
let mut remote_buffers: Vec<RemoteBuffer> = Vec::new();
|
let mut remote_buffers: Vec<RemoteBuffer> = Vec::new();
|
||||||
for i in 1..drtio_routing::DEST_COUNT {
|
for i in 1..drtio_routing::DEST_COUNT {
|
||||||
if destination_up(up_destinations, i as u8).await {
|
if destination_up(up_destinations, i as u8).await {
|
||||||
|
@ -716,16 +755,17 @@ pub mod drtio {
|
||||||
|
|
||||||
pub async fn subkernel_upload(
|
pub async fn subkernel_upload(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
id: u32,
|
id: u32,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
data: &Vec<u8>,
|
data: &Vec<u8>,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
partition_data(
|
partition_data(
|
||||||
linkno,
|
linkno,
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
|
routing_table,
|
||||||
timer,
|
timer,
|
||||||
data,
|
data,
|
||||||
|slice, status, len| Packet::SubkernelAddDataRequest {
|
|slice, status, len| Packet::SubkernelAddDataRequest {
|
||||||
|
@ -737,8 +777,8 @@ pub mod drtio {
|
||||||
},
|
},
|
||||||
|reply| match reply {
|
|reply| match reply {
|
||||||
Packet::SubkernelAddDataReply { succeeded: true } => Ok(()),
|
Packet::SubkernelAddDataReply { succeeded: true } => Ok(()),
|
||||||
Packet::SubkernelAddDataReply { succeeded: false } => Err("error adding subkernel on satellite"),
|
Packet::SubkernelAddDataReply { succeeded: false } => Err(Error::SubkernelAddFail(destination)),
|
||||||
_ => Err("adding subkernel failed, unexpected aux packet"),
|
_ => Err(Error::UnexpectedReply),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -746,16 +786,17 @@ pub mod drtio {
|
||||||
|
|
||||||
pub async fn subkernel_load(
|
pub async fn subkernel_load(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
id: u32,
|
id: u32,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
run: bool,
|
run: bool,
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::SubkernelLoadRunRequest {
|
&Packet::SubkernelLoadRunRequest {
|
||||||
id: id,
|
id: id,
|
||||||
source: 0,
|
source: 0,
|
||||||
|
@ -773,23 +814,24 @@ pub mod drtio {
|
||||||
Packet::SubkernelLoadRunReply {
|
Packet::SubkernelLoadRunReply {
|
||||||
destination: 0,
|
destination: 0,
|
||||||
succeeded: false,
|
succeeded: false,
|
||||||
} => return Err("error on subkernel run request"),
|
} => return Err(Error::SubkernelRunFail(destination)),
|
||||||
_ => return Err("received unexpected aux packet during subkernel run"),
|
_ => Err(Error::UnexpectedReply),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn subkernel_retrieve_exception(
|
pub async fn subkernel_retrieve_exception(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
) -> Result<Vec<u8>, &'static str> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
let mut remote_data: Vec<u8> = Vec::new();
|
let mut remote_data: Vec<u8> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
let reply = aux_transact(
|
let reply = aux_transact(
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
linkno,
|
linkno,
|
||||||
|
routing_table,
|
||||||
&Packet::SubkernelExceptionRequest {
|
&Packet::SubkernelExceptionRequest {
|
||||||
destination: destination,
|
destination: destination,
|
||||||
},
|
},
|
||||||
|
@ -803,23 +845,24 @@ pub mod drtio {
|
||||||
return Ok(remote_data);
|
return Ok(remote_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err("received unexpected aux packet during subkernel exception request"),
|
_ => return Err(Error::UnexpectedReply),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn subkernel_send_message(
|
pub async fn subkernel_send_message(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &RoutingTable,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
id: u32,
|
id: u32,
|
||||||
destination: u8,
|
destination: u8,
|
||||||
message: &[u8],
|
message: &[u8],
|
||||||
) -> Result<(), &'static str> {
|
) -> Result<(), Error> {
|
||||||
let linkno = routing_table.0[destination as usize][0] - 1;
|
let linkno = routing_table.0[destination as usize][0] - 1;
|
||||||
partition_data(
|
partition_data(
|
||||||
linkno,
|
linkno,
|
||||||
aux_mutex,
|
aux_mutex,
|
||||||
|
routing_table,
|
||||||
timer,
|
timer,
|
||||||
message,
|
message,
|
||||||
|slice, status, len| Packet::SubkernelMessage {
|
|slice, status, len| Packet::SubkernelMessage {
|
||||||
|
@ -832,7 +875,7 @@ pub mod drtio {
|
||||||
},
|
},
|
||||||
|reply| match reply {
|
|reply| match reply {
|
||||||
Packet::SubkernelMessageAck { .. } => Ok(()),
|
Packet::SubkernelMessageAck { .. } => Ok(()),
|
||||||
_ => Err("sending message to subkernel failed, unexpected aux packet"),
|
_ => Err(Error::UnexpectedReply),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -845,19 +888,19 @@ pub mod drtio {
|
||||||
|
|
||||||
pub fn startup(
|
pub fn startup(
|
||||||
_aux_mutex: &Rc<Mutex<bool>>,
|
_aux_mutex: &Rc<Mutex<bool>>,
|
||||||
_routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
_routing_table: &Rc<RefCell<RoutingTable>>,
|
||||||
_up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
_up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
_timer: GlobalTimer,
|
_timer: GlobalTimer,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn reset(_aux_mutex: Rc<Mutex<bool>>, mut _timer: GlobalTimer) {}
|
pub fn reset(_aux_mutex: Rc<Mutex<bool>>, _routing_table: &RoutingTable, mut _timer: GlobalTimer) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn startup(
|
pub fn startup(
|
||||||
aux_mutex: &Rc<Mutex<bool>>,
|
aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
routing_table: &Rc<RefCell<RoutingTable>>,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer,
|
timer: GlobalTimer,
|
||||||
) {
|
) {
|
||||||
|
@ -868,9 +911,9 @@ pub fn startup(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn reset(aux_mutex: Rc<Mutex<bool>>, timer: GlobalTimer) {
|
pub fn reset(aux_mutex: Rc<Mutex<bool>>, routing_table: &RoutingTable, timer: GlobalTimer) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio_core::reset_write(1);
|
csr::rtio_core::reset_write(1);
|
||||||
}
|
}
|
||||||
drtio::reset(aux_mutex, timer)
|
drtio::reset(aux_mutex, routing_table, timer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
||||||
use libcortex_a9::mutex::Mutex;
|
use libcortex_a9::mutex::Mutex;
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
|
|
||||||
use crate::rtio_mgt::drtio;
|
use crate::rtio_mgt::{drtio, drtio::Error as DrtioError};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub enum FinishStatus {
|
pub enum FinishStatus {
|
||||||
|
@ -31,11 +31,11 @@ pub enum Error {
|
||||||
SubkernelNotFound,
|
SubkernelNotFound,
|
||||||
SubkernelException,
|
SubkernelException,
|
||||||
CommLost,
|
CommLost,
|
||||||
DrtioError(&'static str),
|
DrtioError(DrtioError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&'static str> for Error {
|
impl From<DrtioError> for Error {
|
||||||
fn from(value: &'static str) -> Error {
|
fn from(value: DrtioError) -> Error {
|
||||||
Error::DrtioError(value)
|
Error::DrtioError(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,12 +81,6 @@ fn drtiosat_tsc_loaded() -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drtiosat_async_ready() {
|
|
||||||
unsafe {
|
|
||||||
csr::drtiosat::async_messages_ready_write(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
macro_rules! forward {
|
macro_rules! forward {
|
||||||
($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr, $timer:expr) => {{
|
($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr, $timer:expr) => {{
|
||||||
|
@ -245,14 +239,6 @@ fn process_aux_packet(
|
||||||
#[cfg(not(has_drtio_routing))]
|
#[cfg(not(has_drtio_routing))]
|
||||||
drtioaux::Packet::RoutingSetRank { rank: _ } => drtioaux::send(0, &drtioaux::Packet::RoutingAck),
|
drtioaux::Packet::RoutingSetRank { rank: _ } => drtioaux::send(0, &drtioaux::Packet::RoutingAck),
|
||||||
|
|
||||||
drtioaux::Packet::RoutingRetrievePackets => {
|
|
||||||
let packet = router
|
|
||||||
.get_upstream_packet()
|
|
||||||
.or(Some(drtioaux::Packet::RoutingNoPackets))
|
|
||||||
.unwrap();
|
|
||||||
drtioaux::send(0, &packet)
|
|
||||||
}
|
|
||||||
|
|
||||||
drtioaux::Packet::MonitorRequest {
|
drtioaux::Packet::MonitorRequest {
|
||||||
destination: _destination,
|
destination: _destination,
|
||||||
channel,
|
channel,
|
||||||
|
@ -1067,8 +1053,8 @@ pub extern "C" fn main_core0() -> i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if router.any_upstream_waiting() {
|
if let Some(packet) = router.get_upstream_packet() {
|
||||||
drtiosat_async_ready();
|
drtioaux::send(0, &packet).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,16 +119,11 @@ impl Repeater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RepeaterState::Up => {
|
RepeaterState::Up => {
|
||||||
self.process_unsolicited_aux();
|
self.process_unsolicited_aux(routing_table, rank, destination, router);
|
||||||
if !rep_link_rx_up(self.repno) {
|
if !rep_link_rx_up(self.repno) {
|
||||||
info!("[REP#{}] link is down", self.repno);
|
info!("[REP#{}] link is down", self.repno);
|
||||||
self.state = RepeaterState::Down;
|
self.state = RepeaterState::Down;
|
||||||
}
|
}
|
||||||
if self.async_messages_ready() {
|
|
||||||
if let Err(e) = self.handle_async(routing_table, rank, destination, router, timer) {
|
|
||||||
warn!("[REP#{}] Error handling async messages ({:?})", self.repno, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
RepeaterState::Failed => {
|
RepeaterState::Failed => {
|
||||||
if !rep_link_rx_up(self.repno) {
|
if !rep_link_rx_up(self.repno) {
|
||||||
|
@ -139,9 +134,15 @@ impl Repeater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_unsolicited_aux(&self) {
|
fn process_unsolicited_aux(
|
||||||
|
&self,
|
||||||
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
|
rank: u8,
|
||||||
|
destination: u8,
|
||||||
|
router: &mut Router,
|
||||||
|
) {
|
||||||
match drtioaux::recv(self.auxno) {
|
match drtioaux::recv(self.auxno) {
|
||||||
Ok(Some(packet)) => warn!("[REP#{}] unsolicited aux packet: {:?}", self.repno, packet),
|
Ok(Some(packet)) => router.route(packet, routing_table, rank, destination),
|
||||||
Ok(None) => (),
|
Ok(None) => (),
|
||||||
Err(_) => warn!("[REP#{}] aux packet error", self.repno),
|
Err(_) => warn!("[REP#{}] aux packet error", self.repno),
|
||||||
}
|
}
|
||||||
|
@ -186,34 +187,6 @@ impl Repeater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn async_messages_ready(&self) -> bool {
|
|
||||||
let async_rdy;
|
|
||||||
unsafe {
|
|
||||||
async_rdy = (csr::DRTIOREP[self.repno as usize].async_messages_ready_read)();
|
|
||||||
(csr::DRTIOREP[self.repno as usize].async_messages_ready_write)(0);
|
|
||||||
}
|
|
||||||
async_rdy == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_async(
|
|
||||||
&self,
|
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
|
||||||
rank: u8,
|
|
||||||
self_destination: u8,
|
|
||||||
router: &mut Router,
|
|
||||||
timer: &mut GlobalTimer,
|
|
||||||
) -> Result<(), drtioaux::Error> {
|
|
||||||
loop {
|
|
||||||
drtioaux::send(self.auxno, &drtioaux::Packet::RoutingRetrievePackets).unwrap();
|
|
||||||
let reply = self.recv_aux_timeout(200, timer)?;
|
|
||||||
match reply {
|
|
||||||
drtioaux::Packet::RoutingNoPackets => break,
|
|
||||||
packet => router.route(packet, routing_table, rank, self_destination),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recv_aux_timeout(&self, timeout: u32, timer: &mut GlobalTimer) -> Result<drtioaux::Packet, drtioaux::Error> {
|
fn recv_aux_timeout(&self, timeout: u32, timer: &mut GlobalTimer) -> Result<drtioaux::Packet, drtioaux::Error> {
|
||||||
let max_time = timer.get_time() + Milliseconds(timeout.into());
|
let max_time = timer.get_time() + Milliseconds(timeout.into());
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -75,7 +75,6 @@ pub struct Router {
|
||||||
local_queue: VecDeque<drtioaux::Packet>,
|
local_queue: VecDeque<drtioaux::Packet>,
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
downstream_queue: VecDeque<(usize, drtioaux::Packet)>,
|
downstream_queue: VecDeque<(usize, drtioaux::Packet)>,
|
||||||
upstream_notified: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Router {
|
impl Router {
|
||||||
|
@ -85,7 +84,6 @@ impl Router {
|
||||||
local_queue: VecDeque::new(),
|
local_queue: VecDeque::new(),
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
downstream_queue: VecDeque::new(),
|
downstream_queue: VecDeque::new(),
|
||||||
upstream_notified: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,22 +159,8 @@ impl Router {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn any_upstream_waiting(&mut self) -> bool {
|
|
||||||
let empty = self.upstream_queue.is_empty();
|
|
||||||
if !empty && !self.upstream_notified {
|
|
||||||
self.upstream_notified = true; // so upstream will not get spammed with notifications
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_upstream_packet(&mut self) -> Option<drtioaux::Packet> {
|
pub fn get_upstream_packet(&mut self) -> Option<drtioaux::Packet> {
|
||||||
let packet = self.upstream_queue.pop_front();
|
self.upstream_queue.pop_front()
|
||||||
if packet.is_none() {
|
|
||||||
self.upstream_notified = false;
|
|
||||||
}
|
|
||||||
packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
|
|
Loading…
Reference in New Issue