forked from M-Labs/artiq-zynq
Compare commits
5 Commits
15f9d1a9e5
...
e0726755da
Author | SHA1 | Date |
---|---|---|
Simon Renblad | e0726755da | |
Simon Renblad | 6e6fbedba1 | |
Simon Renblad | 30eed621db | |
Simon Renblad | 2f27315d13 | |
Simon Renblad | 256b145b39 |
10
README.md
10
README.md
|
@ -59,16 +59,6 @@ Notes:
|
||||||
- Firmware type must be either ``runtime`` for DRTIO-less or DRTIO master variants, or ``satman`` for DRTIO satellite.
|
- Firmware type must be either ``runtime`` for DRTIO-less or DRTIO master variants, or ``satman`` for DRTIO satellite.
|
||||||
- If the board is connected to the local machine, use the ``local_run.sh`` script.
|
- If the board is connected to the local machine, use the ``local_run.sh`` script.
|
||||||
|
|
||||||
Pre-Commit Hooks
|
|
||||||
----------------
|
|
||||||
|
|
||||||
You are strongly recommended to use the provided pre-commit hooks to automatically reformat files and check for non-optimal Rust/C/C++ practices. Run `pre-commit install` to install the hook and `pre-commit` will automatically run `cargo fmt`, `cargo clippy`, and `clang-format` for you.
|
|
||||||
|
|
||||||
Several things to note:
|
|
||||||
|
|
||||||
- If `cargo fmt`, `cargo clippy`, or `clang-format` returns an error, the pre-commit hook will fail. You should fix all errors before trying to commit again.
|
|
||||||
- If `cargo fmt` or `clang-format` reformats some files, the pre-commit hook will also fail. You should review the changes and, if satisfied, try to commit again.
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -364,8 +364,7 @@
|
||||||
(board-package-set { target = "zc706"; variant = "acpki_nist_qc2_satellite_100mhz"; }) //
|
(board-package-set { target = "zc706"; variant = "acpki_nist_qc2_satellite_100mhz"; }) //
|
||||||
(board-package-set { target = "kasli_soc"; variant = "demo"; json = ./demo.json; }) //
|
(board-package-set { target = "kasli_soc"; variant = "demo"; json = ./demo.json; }) //
|
||||||
(board-package-set { target = "kasli_soc"; variant = "master"; json = ./kasli-soc-master.json; }) //
|
(board-package-set { target = "kasli_soc"; variant = "master"; json = ./kasli-soc-master.json; }) //
|
||||||
(board-package-set { target = "kasli_soc"; variant = "satellite"; json = ./kasli-soc-satellite.json; }) //
|
(board-package-set { target = "kasli_soc"; variant = "satellite"; json = ./kasli-soc-satellite.json; });
|
||||||
(board-package-set { target = "ebaz4205"; variant = "base"; });
|
|
||||||
|
|
||||||
hydraJobs = packages.x86_64-linux // { inherit zc706-hitl-tests; inherit gateware-sim; inherit fmt-check; };
|
hydraJobs = packages.x86_64-linux // { inherit zc706-hitl-tests; inherit gateware-sim; inherit fmt-check; };
|
||||||
|
|
||||||
|
@ -385,7 +384,6 @@
|
||||||
artiqpkgs.artiq
|
artiqpkgs.artiq
|
||||||
artiqpkgs.vivado
|
artiqpkgs.vivado
|
||||||
binutils-arm
|
binutils-arm
|
||||||
pre-commit
|
|
||||||
];
|
];
|
||||||
XARGO_RUST_SRC = "${rust}/lib/rustlib/src/rust/library";
|
XARGO_RUST_SRC = "${rust}/lib/rustlib/src/rust/library";
|
||||||
CLANG_EXTRA_INCLUDE_DIR = "${llvmPackages_11.clang-unwrapped.lib}/lib/clang/11.1.0/include";
|
CLANG_EXTRA_INCLUDE_DIR = "${llvmPackages_11.clang-unwrapped.lib}/lib/clang/11.1.0/include";
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
BasedOnStyle: LLVM
|
|
||||||
|
|
||||||
Language: Cpp
|
|
||||||
Standard: Cpp11
|
|
||||||
|
|
||||||
AccessModifierOffset: -1
|
|
||||||
AlignEscapedNewlines: Left
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: Inline
|
|
||||||
BinPackParameters: false
|
|
||||||
BreakBeforeBinaryOperators: NonAssignment
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializers: AfterColon
|
|
||||||
BreakInheritanceList: AfterColon
|
|
||||||
ColumnLimit: 120
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentPPDirectives: None
|
|
||||||
IndentWidth: 4
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
PointerAlignment: Left
|
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: false
|
|
||||||
SortUsingDeclarations: true
|
|
||||||
SpaceAfterTemplateKeyword: false
|
|
||||||
SpacesBeforeTrailingComments: 2
|
|
||||||
TabWidth: 4
|
|
||||||
UseTab: Never
|
|
|
@ -1 +0,0 @@
|
||||||
doc-valid-idents = ["CPython", "NumPy", ".."]
|
|
|
@ -1,32 +0,0 @@
|
||||||
# See https://pre-commit.com for more information
|
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
|
||||||
|
|
||||||
default_stages: [commit]
|
|
||||||
|
|
||||||
repos:
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- id: cargo-fmt
|
|
||||||
name: artiq-zynq cargo format
|
|
||||||
entry: nix
|
|
||||||
language: system
|
|
||||||
types: [file, rust]
|
|
||||||
pass_filenames: false
|
|
||||||
description: Runs cargo fmt on the codebase.
|
|
||||||
args: [develop, -c, cargo, fmt, --manifest-path, src/Cargo.toml, --all]
|
|
||||||
- id: cargo-clippy
|
|
||||||
name: artiq-zynq cargo clippy
|
|
||||||
entry: nix
|
|
||||||
language: system
|
|
||||||
types: [file, rust]
|
|
||||||
pass_filenames: false
|
|
||||||
description: Runs cargo clippy on the codebase.
|
|
||||||
args: [develop, -c, cargo, clippy, --manifest-path, src/Cargo.toml, --tests]
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
|
||||||
rev: v19.1.0
|
|
||||||
hooks:
|
|
||||||
- id: clang-format
|
|
||||||
name: artiq-zynq clang-format
|
|
||||||
description: Runs clang-format on the codebase.
|
|
||||||
files: \.(cpp|h|hpp|c)$
|
|
||||||
args: [-style=file, -fallback-style=none, -assume-filename=src/.clang-format]
|
|
|
@ -212,14 +212,6 @@ class EBAZ4205(SoCCore):
|
||||||
self.csr_devices.append("rtio_analyzer")
|
self.csr_devices.append("rtio_analyzer")
|
||||||
|
|
||||||
|
|
||||||
class BASE(EBAZ4205):
|
|
||||||
def __init__(self, rtio_clk, acpki):
|
|
||||||
EBAZ4205.__init__(self, rtio_clk, acpki)
|
|
||||||
|
|
||||||
|
|
||||||
VARIANTS = {cls.__name__.lower(): cls for cls in [BASE]}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="ARTIQ port to the EBAZ4205 control card of Ebit E9+ BTC miner"
|
description="ARTIQ port to the EBAZ4205 control card of Ebit E9+ BTC miner"
|
||||||
|
@ -240,25 +232,11 @@ def main():
|
||||||
)
|
)
|
||||||
parser.add_argument("--rtio-clk", default=125e6, help="RTIO Clock Frequency (Hz)")
|
parser.add_argument("--rtio-clk", default=125e6, help="RTIO Clock Frequency (Hz)")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-V",
|
"--acpki", default=False, action="store_true", help="enable ACPKI"
|
||||||
"--variant",
|
|
||||||
default="base",
|
|
||||||
help="variant: " "[acpki_]base" "(default: %(default)s)",
|
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
rtio_clk = int(args.rtio_clk)
|
soc = EBAZ4205(rtio_clk=int(args.rtio_clk), acpki=args.acpki)
|
||||||
variant = args.variant.lower()
|
|
||||||
acpki = variant.startswith("acpki_")
|
|
||||||
if acpki:
|
|
||||||
variant = variant[6:]
|
|
||||||
|
|
||||||
try:
|
|
||||||
cls = VARIANTS[variant]
|
|
||||||
except KeyError:
|
|
||||||
raise SystemExit("Invalid variant (-V/--variant)")
|
|
||||||
|
|
||||||
soc = cls(rtio_clk=rtio_clk, acpki=acpki)
|
|
||||||
soc.finalize()
|
soc.finalize()
|
||||||
|
|
||||||
if args.r is not None:
|
if args.r is not None:
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub use crate::drtioaux_proto::Packet;
|
||||||
use crate::{drtioaux_proto::Error as ProtocolError, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX};
|
use crate::{drtioaux_proto::Error as ProtocolError, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error<T> {
|
pub enum Error {
|
||||||
GatewareError,
|
GatewareError,
|
||||||
CorruptedPacket,
|
CorruptedPacket,
|
||||||
|
|
||||||
|
@ -19,17 +19,17 @@ pub enum Error<T> {
|
||||||
|
|
||||||
RoutingError,
|
RoutingError,
|
||||||
|
|
||||||
Protocol(ProtocolError<T>),
|
Protocol(ProtocolError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<ProtocolError<T>> for Error<T> {
|
impl From<ProtocolError> for Error {
|
||||||
fn from(value: ProtocolError<T>) -> Error<T> {
|
fn from(value: ProtocolError) -> Error {
|
||||||
Error::Protocol(value)
|
Error::Protocol(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<IoError<T>> for Error<T> {
|
impl From<IoError> for Error {
|
||||||
fn from(value: IoError<T>) -> Error<T> {
|
fn from(value: IoError) -> Error {
|
||||||
Error::Protocol(ProtocolError::Io(value))
|
Error::Protocol(ProtocolError::Io(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ pub fn has_rx_error(linkno: u8) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error<!>>
|
fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
|
||||||
where F: FnOnce(&[u8]) -> Result<T, Error<!>> {
|
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 {
|
||||||
|
@ -72,14 +72,14 @@ where F: FnOnce(&[u8]) -> Result<T, Error<!>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv(linkno: u8) -> Result<Option<Packet>, Error<!>> {
|
pub fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
||||||
if has_rx_error(linkno) {
|
if has_rx_error(linkno) {
|
||||||
return Err(Error::GatewareError);
|
return Err(Error::GatewareError);
|
||||||
}
|
}
|
||||||
|
|
||||||
receive(linkno, |buffer| {
|
receive(linkno, |buffer| {
|
||||||
if buffer.len() < 8 {
|
if buffer.len() < 8 {
|
||||||
return Err(IoError::UnexpectedEnd.into());
|
return Err(IoError::UnexpectedEnd).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = Cursor::new(buffer);
|
let mut reader = Cursor::new(buffer);
|
||||||
|
@ -96,7 +96,7 @@ pub fn recv(linkno: u8) -> Result<Option<Packet>, Error<!>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error<!>> {
|
pub fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error> {
|
||||||
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
||||||
let limit = timer.get_time() + timeout_ms;
|
let limit = timer.get_time() + timeout_ms;
|
||||||
while timer.get_time() < limit {
|
while timer.get_time() < limit {
|
||||||
|
@ -108,8 +108,8 @@ pub fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) ->
|
||||||
Err(Error::TimedOut)
|
Err(Error::TimedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transmit<F>(linkno: u8, f: F) -> Result<(), Error<!>>
|
fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
|
||||||
where F: FnOnce(&mut [u8]) -> Result<usize, Error<!>> {
|
where F: FnOnce(&mut [u8]) -> Result<usize, Error> {
|
||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
|
||||||
|
@ -121,7 +121,7 @@ where F: FnOnce(&mut [u8]) -> Result<usize, Error<!>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(linkno: u8, packet: &Packet) -> Result<(), Error<!>> {
|
pub fn send(linkno: u8, packet: &Packet) -> Result<(), Error> {
|
||||||
transmit(linkno, |buffer| {
|
transmit(linkno, |buffer| {
|
||||||
let mut writer = Cursor::new(buffer);
|
let mut writer = Cursor::new(buffer);
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ fn tx_ready(linkno: usize) -> nb::Result<(), Void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error<!>>
|
async fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
|
||||||
where F: FnOnce(&[u8]) -> Result<T, Error<!>> {
|
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 {
|
||||||
|
@ -50,14 +50,14 @@ where F: FnOnce(&[u8]) -> Result<T, Error<!>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error<!>> {
|
pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error> {
|
||||||
if has_rx_error(linkno) {
|
if has_rx_error(linkno) {
|
||||||
return Err(Error::GatewareError);
|
return Err(Error::GatewareError);
|
||||||
}
|
}
|
||||||
|
|
||||||
receive(linkno, |buffer| {
|
receive(linkno, |buffer| {
|
||||||
if buffer.len() < 8 {
|
if buffer.len() < 8 {
|
||||||
return Err(IoError::UnexpectedEnd.into());
|
return Err(IoError::UnexpectedEnd).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = Cursor::new(buffer);
|
let mut reader = Cursor::new(buffer);
|
||||||
|
@ -75,7 +75,7 @@ pub async fn recv(linkno: u8) -> Result<Option<Packet>, Error<!>> {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error<!>> {
|
pub async fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTimer) -> Result<Packet, Error> {
|
||||||
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10));
|
||||||
let limit = timer.get_time() + timeout_ms;
|
let limit = timer.get_time() + timeout_ms;
|
||||||
let mut would_block = false;
|
let mut would_block = false;
|
||||||
|
@ -95,8 +95,8 @@ pub async fn recv_timeout(linkno: u8, timeout_ms: Option<u64>, timer: GlobalTime
|
||||||
Err(Error::TimedOut)
|
Err(Error::TimedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn transmit<F>(linkno: u8, f: F) -> Result<(), Error<!>>
|
async fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
|
||||||
where F: FnOnce(&mut [u8]) -> Result<usize, Error<!>> {
|
where F: FnOnce(&mut [u8]) -> Result<usize, Error> {
|
||||||
let linkno = linkno as usize;
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = block_async!(tx_ready(linkno)).await;
|
let _ = block_async!(tx_ready(linkno)).await;
|
||||||
|
@ -108,7 +108,7 @@ where F: FnOnce(&mut [u8]) -> Result<usize, Error<!>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(linkno: u8, packet: &Packet) -> Result<(), Error<!>> {
|
pub async fn send(linkno: u8, packet: &Packet) -> Result<(), Error> {
|
||||||
transmit(linkno, |buffer| {
|
transmit(linkno, |buffer| {
|
||||||
let mut writer = Cursor::new(buffer);
|
let mut writer = Cursor::new(buffer);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![allow(unexpected_cfgs)]
|
#![feature(asm)]
|
||||||
|
|
||||||
extern crate crc;
|
extern crate crc;
|
||||||
extern crate embedded_hal;
|
extern crate embedded_hal;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![allow(unexpected_cfgs)]
|
|
||||||
|
|
||||||
use std::{env,
|
use std::{env,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{BufRead, BufReader, Write},
|
io::{BufRead, BufReader, Write},
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![allow(unexpected_cfgs)]
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
// By design, this personality function is only ever called in the search phase, although
|
// By design, this personality function is only ever called in the search phase, although
|
||||||
// to keep things simple and close to upstream, it is not modified
|
// to keep things simple and close to upstream, it is not modified
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::{c_int, uintptr_t};
|
||||||
|
|
||||||
use dwarf::eh::{EHAction, EHContext};
|
use dwarf::eh::{self, EHAction, EHContext};
|
||||||
|
|
||||||
// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
|
// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
|
||||||
// and TargetLowering::getExceptionSelectorRegister() for each architecture,
|
// and TargetLowering::getExceptionSelectorRegister() for each architecture,
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
#![feature(c_variadic)]
|
#![feature(c_variadic)]
|
||||||
#![feature(const_btree_len)]
|
#![feature(const_btree_len)]
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![allow(unexpected_cfgs)]
|
#![feature(asm)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
|
@ -44,7 +44,7 @@ unsafe fn recv_elements<F, R, E>(
|
||||||
alloc: &mut F,
|
alloc: &mut F,
|
||||||
) -> Result<(), E>
|
) -> Result<(), E>
|
||||||
where
|
where
|
||||||
F: FnMut(usize) -> Result<*mut (), E>,
|
F: FnMut(usize) -> *mut (),
|
||||||
R: Read + ?Sized,
|
R: Read + ?Sized,
|
||||||
E: From<Error<R::ReadError>>,
|
E: From<Error<R::ReadError>>,
|
||||||
{
|
{
|
||||||
|
@ -57,6 +57,7 @@ where
|
||||||
let ptr = storage as *mut u32;
|
let ptr = storage as *mut u32;
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
||||||
reader.read_exact(dest)?;
|
reader.read_exact(dest)?;
|
||||||
|
drop(dest);
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
||||||
NativeEndian::from_slice_u32(dest);
|
NativeEndian::from_slice_u32(dest);
|
||||||
}
|
}
|
||||||
|
@ -64,6 +65,7 @@ where
|
||||||
let ptr = storage as *mut u64;
|
let ptr = storage as *mut u64;
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
||||||
reader.read_exact(dest)?;
|
reader.read_exact(dest)?;
|
||||||
|
drop(dest);
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
||||||
NativeEndian::from_slice_u64(dest);
|
NativeEndian::from_slice_u64(dest);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +81,7 @@ where
|
||||||
|
|
||||||
unsafe fn recv_value<F, R, E>(reader: &mut R, tag: Tag, data: &mut *mut (), alloc: &mut F) -> Result<(), E>
|
unsafe fn recv_value<F, R, E>(reader: &mut R, tag: Tag, data: &mut *mut (), alloc: &mut F) -> Result<(), E>
|
||||||
where
|
where
|
||||||
F: FnMut(usize) -> Result<*mut (), E>,
|
F: FnMut(usize) -> *mut (),
|
||||||
R: Read + ?Sized,
|
R: Read + ?Sized,
|
||||||
E: From<Error<R::ReadError>>,
|
E: From<Error<R::ReadError>>,
|
||||||
{
|
{
|
||||||
|
@ -108,7 +110,7 @@ where
|
||||||
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
||||||
consume_value!(CMutSlice<u8>, |ptr| {
|
consume_value!(CMutSlice<u8>, |ptr| {
|
||||||
let length = reader.read_u32()? as usize;
|
let length = reader.read_u32()? as usize;
|
||||||
*ptr = CMutSlice::new(alloc(length)? as *mut u8, length);
|
*ptr = CMutSlice::new(alloc(length) as *mut u8, length);
|
||||||
reader.read_exact((*ptr).as_mut())?;
|
reader.read_exact((*ptr).as_mut())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -138,7 +140,7 @@ where
|
||||||
let storage_offset = round_up(list_size, tag.alignment());
|
let storage_offset = round_up(list_size, tag.alignment());
|
||||||
let storage_size = tag.size() * length;
|
let storage_size = tag.size() * length;
|
||||||
|
|
||||||
let allocation = alloc(storage_offset + storage_size)? as *mut u8;
|
let allocation = alloc(storage_offset + storage_size) as *mut u8;
|
||||||
*ptr_to_list = allocation as *mut List;
|
*ptr_to_list = allocation as *mut List;
|
||||||
let storage = allocation.offset(storage_offset as isize) as *mut ();
|
let storage = allocation.offset(storage_offset as isize) as *mut ();
|
||||||
|
|
||||||
|
@ -157,7 +159,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let elt_tag = it.clone().next().expect("truncated tag");
|
let elt_tag = it.clone().next().expect("truncated tag");
|
||||||
*buffer = alloc(elt_tag.size() * total_len)?;
|
*buffer = alloc(elt_tag.size() * total_len);
|
||||||
recv_elements(reader, elt_tag, total_len, *buffer, alloc)
|
recv_elements(reader, elt_tag, total_len, *buffer, alloc)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -181,7 +183,7 @@ pub fn recv_return<'a, F, R, E>(
|
||||||
alloc: &mut F,
|
alloc: &mut F,
|
||||||
) -> Result<&'a [u8], E>
|
) -> Result<&'a [u8], E>
|
||||||
where
|
where
|
||||||
F: FnMut(usize) -> Result<*mut (), E>,
|
F: FnMut(usize) -> *mut (),
|
||||||
R: Read + ?Sized,
|
R: Read + ?Sized,
|
||||||
E: From<Error<R::ReadError>>,
|
E: From<Error<R::ReadError>>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![allow(unexpected_cfgs)]
|
|
||||||
extern crate build_zynq;
|
extern crate build_zynq;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![recursion_limit = "1024"] // for futures_util::select!
|
#![recursion_limit = "1024"] // for futures_util::select!
|
||||||
#![allow(unexpected_cfgs)]
|
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(const_btree_len)]
|
#![feature(const_btree_new)]
|
||||||
|
#![feature(panic_info_message)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
|
@ -38,6 +38,7 @@ where
|
||||||
let ptr = storage as *mut u32;
|
let ptr = storage as *mut u32;
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
||||||
proto_async::read_chunk(stream, dest).await?;
|
proto_async::read_chunk(stream, dest).await?;
|
||||||
|
drop(dest);
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
||||||
NativeEndian::from_slice_u32(dest);
|
NativeEndian::from_slice_u32(dest);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +46,7 @@ where
|
||||||
let ptr = storage as *mut u64;
|
let ptr = storage as *mut u64;
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
||||||
proto_async::read_chunk(stream, dest).await?;
|
proto_async::read_chunk(stream, dest).await?;
|
||||||
|
drop(dest);
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
||||||
NativeEndian::from_slice_u64(dest);
|
NativeEndian::from_slice_u64(dest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(alloc_error_handler, never_type)]
|
#![feature(alloc_error_handler, try_trait, never_type, panic_info_message)]
|
||||||
#![allow(unexpected_cfgs)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
@ -150,7 +149,7 @@ fn process_aux_packet(
|
||||||
analyzer: &mut Analyzer,
|
analyzer: &mut Analyzer,
|
||||||
kernel_manager: &mut KernelManager,
|
kernel_manager: &mut KernelManager,
|
||||||
router: &mut Router,
|
router: &mut Router,
|
||||||
) -> Result<(), drtioaux::Error<!>> {
|
) -> Result<(), drtioaux::Error> {
|
||||||
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
||||||
// and u16 otherwise; hence the `as _` conversion.
|
// and u16 otherwise; hence the `as _` conversion.
|
||||||
match packet {
|
match packet {
|
||||||
|
@ -1458,7 +1457,7 @@ pub fn panic_fmt(info: &core::panic::PanicInfo) -> ! {
|
||||||
} else {
|
} else {
|
||||||
print!("unknown location");
|
print!("unknown location");
|
||||||
}
|
}
|
||||||
if let Some(message) = info.message().as_str() {
|
if let Some(message) = info.message() {
|
||||||
println!(": {}", message);
|
println!(": {}", message);
|
||||||
} else {
|
} else {
|
||||||
println!("");
|
println!("");
|
||||||
|
|
|
@ -191,7 +191,7 @@ impl Repeater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
if !rep_link_rx_up(self.repno) {
|
if !rep_link_rx_up(self.repno) {
|
||||||
|
@ -216,7 +216,7 @@ impl Repeater {
|
||||||
rank: u8,
|
rank: u8,
|
||||||
self_destination: u8,
|
self_destination: u8,
|
||||||
timer: &mut GlobalTimer,
|
timer: &mut GlobalTimer,
|
||||||
) -> Result<(), drtioaux::Error<!>> {
|
) -> Result<(), drtioaux::Error> {
|
||||||
self.aux_send(request)?;
|
self.aux_send(request)?;
|
||||||
loop {
|
loop {
|
||||||
let reply = self.recv_aux_timeout(200, timer)?;
|
let reply = self.recv_aux_timeout(200, timer)?;
|
||||||
|
@ -242,14 +242,14 @@ impl Repeater {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aux_send(&self, request: &drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
pub fn aux_send(&self, request: &drtioaux::Packet) -> Result<(), drtioaux::Error> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Err(drtioaux::Error::LinkDown);
|
return Err(drtioaux::Error::LinkDown);
|
||||||
}
|
}
|
||||||
drtioaux::send(self.auxno, request)
|
drtioaux::send(self.auxno, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_tsc(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
pub fn sync_tsc(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ impl Repeater {
|
||||||
destination: u8,
|
destination: u8,
|
||||||
hops: &[u8; drtio_routing::MAX_HOPS],
|
hops: &[u8; drtio_routing::MAX_HOPS],
|
||||||
timer: &mut GlobalTimer,
|
timer: &mut GlobalTimer,
|
||||||
) -> Result<(), drtioaux::Error<!>> {
|
) -> Result<(), drtioaux::Error> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -299,14 +299,14 @@ impl Repeater {
|
||||||
&self,
|
&self,
|
||||||
routing_table: &drtio_routing::RoutingTable,
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
timer: &mut GlobalTimer,
|
timer: &mut GlobalTimer,
|
||||||
) -> Result<(), drtioaux::Error<!>> {
|
) -> Result<(), drtioaux::Error> {
|
||||||
for i in 0..drtio_routing::DEST_COUNT {
|
for i in 0..drtio_routing::DEST_COUNT {
|
||||||
self.set_path(i as u8, &routing_table.0[i], timer)?;
|
self.set_path(i as u8, &routing_table.0[i], timer)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_rank(&self, rank: u8, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
pub fn set_rank(&self, rank: u8, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
||||||
if self.state != RepeaterState::Up {
|
if self.state != RepeaterState::Up {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ impl Repeater {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rtio_reset(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
pub fn rtio_reset(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
||||||
let repno = self.repno as usize;
|
let repno = self.repno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
(csr::DRTIOREP[repno].reset_write)(1);
|
(csr::DRTIOREP[repno].reset_write)(1);
|
||||||
|
@ -361,11 +361,11 @@ impl Repeater {
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_tsc(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
pub fn sync_tsc(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rtio_reset(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error<!>> {
|
pub fn rtio_reset(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl Router {
|
||||||
_routing_table: &drtio_routing::RoutingTable,
|
_routing_table: &drtio_routing::RoutingTable,
|
||||||
_rank: u8,
|
_rank: u8,
|
||||||
_destination: u8,
|
_destination: u8,
|
||||||
) -> Result<(), drtioaux::Error<!>> {
|
) -> Result<(), drtioaux::Error> {
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
{
|
{
|
||||||
let destination = packet.routable_destination();
|
let destination = packet.routable_destination();
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
use alloc::{
|
use alloc::{collections::BTreeMap,
|
||||||
collections::BTreeMap,
|
|
||||||
format,
|
format,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec};
|
||||||
};
|
use core::{option::NoneError, slice, str};
|
||||||
use core::{slice, str};
|
|
||||||
|
|
||||||
use cslice::AsCSlice;
|
use cslice::AsCSlice;
|
||||||
use dma::{Error as DmaError, Manager as DmaManager};
|
use dma::{Error as DmaError, Manager as DmaManager};
|
||||||
use io::{Cursor, Error as IoError, ProtoWrite, Write};
|
use io::{Cursor, Error as IoError, ProtoWrite, Write};
|
||||||
use ksupport::{eh_artiq, kernel, rpc};
|
use ksupport::{eh_artiq, kernel, rpc};
|
||||||
use libboard_artiq::{
|
use libboard_artiq::{drtio_routing::RoutingTable,
|
||||||
drtio_routing::RoutingTable,
|
|
||||||
drtioaux,
|
drtioaux,
|
||||||
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE},
|
drtioaux_proto::{PayloadStatus, MASTER_PAYLOAD_MAX_SIZE},
|
||||||
pl::csr,
|
pl::csr};
|
||||||
};
|
|
||||||
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
use libboard_zynq::{time::Milliseconds, timer::GlobalTimer};
|
||||||
use libcortex_a9::sync_channel::Receiver;
|
use libcortex_a9::sync_channel::Receiver;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
@ -55,7 +51,6 @@ enum KernelState {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Load(String),
|
Load(String),
|
||||||
|
@ -69,8 +64,14 @@ pub enum Error {
|
||||||
DmaError(DmaError),
|
DmaError(DmaError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<IoError<T>> for Error {
|
impl From<NoneError> for Error {
|
||||||
fn from(_value: IoError<T>) -> Error {
|
fn from(_: NoneError) -> Error {
|
||||||
|
Error::KernelNotFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IoError> for Error {
|
||||||
|
fn from(_value: IoError) -> Error {
|
||||||
Error::SubkernelIoError
|
Error::SubkernelIoError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,8 +88,8 @@ impl From<()> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<drtioaux::Error<T>> for Error {
|
impl From<drtioaux::Error> for Error {
|
||||||
fn from(_value: drtioaux::Error<T>) -> Error {
|
fn from(_value: drtioaux::Error) -> Error {
|
||||||
Error::DrtioError
|
Error::DrtioError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,10 +221,7 @@ impl MessageManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_outgoing_slice(
|
pub fn get_outgoing_slice(&mut self, data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> Option<SliceMeta> {
|
||||||
&mut self,
|
|
||||||
data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE],
|
|
||||||
) -> Option<SliceMeta> {
|
|
||||||
if self.out_state != OutMessageState::MessageBeingSent {
|
if self.out_state != OutMessageState::MessageBeingSent {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -304,13 +302,7 @@ impl<'a> Manager<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(
|
pub fn add(&mut self, id: u32, status: PayloadStatus, data: &[u8], data_len: usize) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
id: u32,
|
|
||||||
status: PayloadStatus,
|
|
||||||
data: &[u8],
|
|
||||||
data_len: usize,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let kernel = match self.kernels.get_mut(&id) {
|
let kernel = match self.kernels.get_mut(&id) {
|
||||||
Some(kernel) => {
|
Some(kernel) => {
|
||||||
if kernel.complete || status.is_first() {
|
if kernel.complete || status.is_first() {
|
||||||
|
@ -323,7 +315,7 @@ impl<'a> Manager<'_> {
|
||||||
complete: false,
|
complete: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.kernels.get_mut(&id).ok_or(Error::KernelNotFound)?
|
self.kernels.get_mut(&id)?
|
||||||
} else {
|
} else {
|
||||||
kernel
|
kernel
|
||||||
}
|
}
|
||||||
|
@ -336,7 +328,7 @@ impl<'a> Manager<'_> {
|
||||||
complete: false,
|
complete: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.kernels.get_mut(&id).ok_or(Error::KernelNotFound)?
|
self.kernels.get_mut(&id)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
kernel.library.extend(&data[0..data_len]);
|
kernel.library.extend(&data[0..data_len]);
|
||||||
|
@ -380,15 +372,10 @@ impl<'a> Manager<'_> {
|
||||||
if !self.running() {
|
if !self.running() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.session
|
self.session.messages.handle_incoming(status, id, length, slice);
|
||||||
.messages
|
|
||||||
.handle_incoming(status, id, length, slice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message_get_slice(
|
pub fn message_get_slice(&mut self, slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> Option<SliceMeta> {
|
||||||
&mut self,
|
|
||||||
slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE],
|
|
||||||
) -> Option<SliceMeta> {
|
|
||||||
if !self.running() {
|
if !self.running() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -407,19 +394,15 @@ impl<'a> Manager<'_> {
|
||||||
if self.session.id == id && self.session.kernel_state == KernelState::Loaded {
|
if self.session.id == id && self.session.kernel_state == KernelState::Loaded {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if !self.kernels.get(&id).ok_or(Error::KernelNotFound)?.complete {
|
if !self.kernels.get(&id)?.complete {
|
||||||
return Err(Error::KernelNotFound);
|
return Err(Error::KernelNotFound);
|
||||||
}
|
}
|
||||||
self.session = Session::new(id);
|
self.session = Session::new(id);
|
||||||
self.control.restart();
|
self.control.restart();
|
||||||
|
|
||||||
self.control.tx.send(kernel::Message::LoadRequest(
|
self.control
|
||||||
self.kernels
|
.tx
|
||||||
.get(&id)
|
.send(kernel::Message::LoadRequest(self.kernels.get(&id)?.library.clone()));
|
||||||
.ok_or(Error::KernelNotFound)?
|
|
||||||
.library
|
|
||||||
.clone(),
|
|
||||||
));
|
|
||||||
let reply = self.control.rx.recv();
|
let reply = self.control.rx.recv();
|
||||||
match reply {
|
match reply {
|
||||||
kernel::Message::LoadCompleted => Ok(()),
|
kernel::Message::LoadCompleted => Ok(()),
|
||||||
|
@ -431,10 +414,7 @@ impl<'a> Manager<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exception_get_slice(
|
pub fn exception_get_slice(&mut self, data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE]) -> SliceMeta {
|
||||||
&mut self,
|
|
||||||
data_slice: &mut [u8; MASTER_PAYLOAD_MAX_SIZE],
|
|
||||||
) -> SliceMeta {
|
|
||||||
match self.session.last_exception.as_mut() {
|
match self.session.last_exception.as_mut() {
|
||||||
Some(exception) => exception.get_slice_master(data_slice),
|
Some(exception) => exception.get_slice_master(data_slice),
|
||||||
None => SliceMeta {
|
None => SliceMeta {
|
||||||
|
@ -588,14 +568,7 @@ impl<'a> Manager<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.process_kern_message(
|
match self.process_kern_message(router, routing_table, rank, destination, dma_manager, timer) {
|
||||||
router,
|
|
||||||
routing_table,
|
|
||||||
rank,
|
|
||||||
destination,
|
|
||||||
dma_manager,
|
|
||||||
timer,
|
|
||||||
) {
|
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
self.last_finished = Some(SubkernelFinished {
|
self.last_finished = Some(SubkernelFinished {
|
||||||
id: self.session.id,
|
id: self.session.id,
|
||||||
|
@ -638,9 +611,7 @@ impl<'a> Manager<'_> {
|
||||||
for (i, (status, exception_source)) in self.session.subkernels_finished.iter().enumerate() {
|
for (i, (status, exception_source)) in self.session.subkernels_finished.iter().enumerate() {
|
||||||
if *status == id {
|
if *status == id {
|
||||||
if exception_source.is_none() {
|
if exception_source.is_none() {
|
||||||
self.control
|
self.control.tx.send(kernel::Message::SubkernelAwaitFinishReply);
|
||||||
.tx
|
|
||||||
.send(kernel::Message::SubkernelAwaitFinishReply);
|
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
self.session.subkernels_finished.swap_remove(i);
|
self.session.subkernels_finished.swap_remove(i);
|
||||||
} else {
|
} else {
|
||||||
|
@ -668,26 +639,15 @@ impl<'a> Manager<'_> {
|
||||||
if self.session.kernel_state == KernelState::SubkernelAwaitLoad {
|
if self.session.kernel_state == KernelState::SubkernelAwaitLoad {
|
||||||
self.control
|
self.control
|
||||||
.tx
|
.tx
|
||||||
.send(kernel::Message::SubkernelLoadRunReply {
|
.send(kernel::Message::SubkernelLoadRunReply { succeeded: succeeded });
|
||||||
succeeded: succeeded,
|
|
||||||
});
|
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
} else {
|
} else {
|
||||||
warn!("received unsolicited SubkernelLoadRunReply");
|
warn!("received unsolicited SubkernelLoadRunReply");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_subkernel_finished(
|
pub fn remote_subkernel_finished(&mut self, id: u32, with_exception: bool, exception_source: u8) {
|
||||||
&mut self,
|
let exception_src = if with_exception { Some(exception_source) } else { None };
|
||||||
id: u32,
|
|
||||||
with_exception: bool,
|
|
||||||
exception_source: u8,
|
|
||||||
) {
|
|
||||||
let exception_src = if with_exception {
|
|
||||||
Some(exception_source)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
self.session.subkernels_finished.push((id, exception_src));
|
self.session.subkernels_finished.push((id, exception_src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,19 +660,18 @@ impl<'a> Manager<'_> {
|
||||||
rank: u8,
|
rank: u8,
|
||||||
self_destination: u8,
|
self_destination: u8,
|
||||||
) {
|
) {
|
||||||
if let KernelState::SubkernelRetrievingException { destination } = self.session.kernel_state
|
if let KernelState::SubkernelRetrievingException { destination } = self.session.kernel_state {
|
||||||
{
|
|
||||||
self.session
|
self.session
|
||||||
.external_exception
|
.external_exception
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.extend_from_slice(exception_data);
|
.extend_from_slice(exception_data);
|
||||||
if last {
|
if last {
|
||||||
self.control.tx.send(kernel::Message::SubkernelError(
|
self.control
|
||||||
kernel::SubkernelStatus::Exception(
|
.tx
|
||||||
|
.send(kernel::Message::SubkernelError(kernel::SubkernelStatus::Exception(
|
||||||
self.session.external_exception.take().unwrap(),
|
self.session.external_exception.take().unwrap(),
|
||||||
),
|
)));
|
||||||
));
|
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
} else {
|
} else {
|
||||||
/* fetch another slice */
|
/* fetch another slice */
|
||||||
|
@ -747,12 +706,7 @@ impl<'a> Manager<'_> {
|
||||||
dma_manager.cleanup(router, rank, self_destination, routing_table);
|
dma_manager.cleanup(router, rank, self_destination, routing_table);
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
kernel::Message::KernelException(
|
kernel::Message::KernelException(exceptions, stack_pointers, backtrace, async_errors) => {
|
||||||
exceptions,
|
|
||||||
stack_pointers,
|
|
||||||
backtrace,
|
|
||||||
async_errors,
|
|
||||||
) => {
|
|
||||||
error!("exception in kernel");
|
error!("exception in kernel");
|
||||||
for exception in exceptions {
|
for exception in exceptions {
|
||||||
error!("{:?}", exception.unwrap());
|
error!("{:?}", exception.unwrap());
|
||||||
|
@ -761,21 +715,12 @@ impl<'a> Manager<'_> {
|
||||||
error!("backtrace: {:?}", backtrace);
|
error!("backtrace: {:?}", backtrace);
|
||||||
let buf: Vec<u8> = Vec::new();
|
let buf: Vec<u8> = Vec::new();
|
||||||
let mut writer = Cursor::new(buf);
|
let mut writer = Cursor::new(buf);
|
||||||
match write_exception(
|
match write_exception(&mut writer, exceptions, stack_pointers, backtrace, async_errors) {
|
||||||
&mut writer,
|
|
||||||
exceptions,
|
|
||||||
stack_pointers,
|
|
||||||
backtrace,
|
|
||||||
async_errors,
|
|
||||||
) {
|
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(_) => error!("Error writing exception data"),
|
Err(_) => error!("Error writing exception data"),
|
||||||
}
|
}
|
||||||
self.kernel_stop();
|
self.kernel_stop();
|
||||||
return Err(Error::KernelException(Sliceable::new(
|
return Err(Error::KernelException(Sliceable::new(0, writer.into_inner())));
|
||||||
0,
|
|
||||||
writer.into_inner(),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
kernel::Message::CachePutRequest(key, value) => {
|
kernel::Message::CachePutRequest(key, value) => {
|
||||||
self.cache.insert(key, value);
|
self.cache.insert(key, value);
|
||||||
|
@ -823,13 +768,11 @@ impl<'a> Manager<'_> {
|
||||||
let max_time = timer.get_time() + Milliseconds(10000);
|
let max_time = timer.get_time() + Milliseconds(10000);
|
||||||
self.session.kernel_state = match self.session.kernel_state {
|
self.session.kernel_state = match self.session.kernel_state {
|
||||||
// if we are still waiting for the traces to be uploaded, extend the state by timeout
|
// if we are still waiting for the traces to be uploaded, extend the state by timeout
|
||||||
KernelState::DmaPendingPlayback { id, timestamp } => {
|
KernelState::DmaPendingPlayback { id, timestamp } => KernelState::DmaPendingAwait {
|
||||||
KernelState::DmaPendingAwait {
|
|
||||||
id: id,
|
id: id,
|
||||||
timestamp: timestamp,
|
timestamp: timestamp,
|
||||||
max_time: max_time,
|
max_time: max_time,
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => KernelState::DmaAwait { max_time: max_time },
|
_ => KernelState::DmaAwait { max_time: max_time },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -900,10 +843,7 @@ impl<'a> Manager<'_> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unexpected!(
|
unexpected!("unexpected message from core1 while kernel was running: {:?}", reply);
|
||||||
"unexpected message from core1 while kernel was running: {:?}",
|
|
||||||
reply
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok(false)
|
||||||
|
@ -921,9 +861,9 @@ impl<'a> Manager<'_> {
|
||||||
KernelState::MsgAwait { max_time, id, tags } => {
|
KernelState::MsgAwait { max_time, id, tags } => {
|
||||||
if let Some(max_time) = *max_time {
|
if let Some(max_time) = *max_time {
|
||||||
if timer.get_time() > max_time {
|
if timer.get_time() > max_time {
|
||||||
self.control.tx.send(kernel::Message::SubkernelError(
|
self.control
|
||||||
kernel::SubkernelStatus::Timeout,
|
.tx
|
||||||
));
|
.send(kernel::Message::SubkernelError(kernel::SubkernelStatus::Timeout));
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -931,9 +871,7 @@ impl<'a> Manager<'_> {
|
||||||
if let Some(message) = self.session.messages.get_incoming(*id) {
|
if let Some(message) = self.session.messages.get_incoming(*id) {
|
||||||
self.control
|
self.control
|
||||||
.tx
|
.tx
|
||||||
.send(kernel::Message::SubkernelMsgRecvReply {
|
.send(kernel::Message::SubkernelMsgRecvReply { count: message.count });
|
||||||
count: message.count,
|
|
||||||
});
|
|
||||||
let tags = tags.clone();
|
let tags = tags.clone();
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
self.pass_message_to_kernel(&message, tags, timer)
|
self.pass_message_to_kernel(&message, tags, timer)
|
||||||
|
@ -955,9 +893,9 @@ impl<'a> Manager<'_> {
|
||||||
KernelState::SubkernelAwaitFinish { max_time, id } => {
|
KernelState::SubkernelAwaitFinish { max_time, id } => {
|
||||||
if let Some(max_time) = *max_time {
|
if let Some(max_time) = *max_time {
|
||||||
if timer.get_time() > max_time {
|
if timer.get_time() > max_time {
|
||||||
self.control.tx.send(kernel::Message::SubkernelError(
|
self.control
|
||||||
kernel::SubkernelStatus::Timeout,
|
.tx
|
||||||
));
|
.send(kernel::Message::SubkernelError(kernel::SubkernelStatus::Timeout));
|
||||||
self.session.kernel_state = KernelState::Running;
|
self.session.kernel_state = KernelState::Running;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -983,12 +921,7 @@ impl<'a> Manager<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pass_message_to_kernel(
|
fn pass_message_to_kernel(&mut self, message: &Message, tags: Vec<u8>, timer: &GlobalTimer) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
message: &Message,
|
|
||||||
tags: Vec<u8>,
|
|
||||||
timer: &GlobalTimer,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let mut reader = Cursor::new(&message.data);
|
let mut reader = Cursor::new(&message.data);
|
||||||
let mut current_tags: &[u8] = &tags;
|
let mut current_tags: &[u8] = &tags;
|
||||||
let mut i = message.count;
|
let mut i = message.count;
|
||||||
|
@ -999,50 +932,29 @@ impl<'a> Manager<'_> {
|
||||||
};
|
};
|
||||||
let mut exception: Option<Sliceable> = None;
|
let mut exception: Option<Sliceable> = None;
|
||||||
let mut unexpected: Option<String> = None;
|
let mut unexpected: Option<String> = None;
|
||||||
let remaining_tags =
|
let remaining_tags = rpc::recv_return(&mut reader, current_tags, slot, &mut |size| {
|
||||||
rpc::recv_return(&mut reader, current_tags, slot, &mut |size| -> Result<
|
|
||||||
_,
|
|
||||||
Error,
|
|
||||||
> {
|
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
Ok(0 as *mut ())
|
0 as *mut ()
|
||||||
} else {
|
} else {
|
||||||
self.control
|
self.control.tx.send(kernel::Message::RpcRecvReply(Ok(size)));
|
||||||
.tx
|
|
||||||
.send(kernel::Message::RpcRecvReply(Ok(size)));
|
|
||||||
match recv_w_timeout(&mut self.control.rx, timer, 100) {
|
match recv_w_timeout(&mut self.control.rx, timer, 100) {
|
||||||
Ok(kernel::Message::RpcRecvRequest(slot)) => Ok(slot),
|
Ok(kernel::Message::RpcRecvRequest(slot)) => slot,
|
||||||
Ok(kernel::Message::KernelException(
|
Ok(kernel::Message::KernelException(exceptions, stack_pointers, backtrace, async_errors)) => {
|
||||||
exceptions,
|
|
||||||
stack_pointers,
|
|
||||||
backtrace,
|
|
||||||
async_errors,
|
|
||||||
)) => {
|
|
||||||
let buf: Vec<u8> = Vec::new();
|
let buf: Vec<u8> = Vec::new();
|
||||||
let mut writer = Cursor::new(buf);
|
let mut writer = Cursor::new(buf);
|
||||||
match write_exception(
|
match write_exception(&mut writer, exceptions, stack_pointers, backtrace, async_errors) {
|
||||||
&mut writer,
|
|
||||||
exceptions,
|
|
||||||
stack_pointers,
|
|
||||||
backtrace,
|
|
||||||
async_errors,
|
|
||||||
) {
|
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
exception = Some(Sliceable::new(0, writer.into_inner()));
|
exception = Some(Sliceable::new(0, writer.into_inner()));
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
unexpected =
|
unexpected = Some("Error writing exception data".to_string());
|
||||||
Some("Error writing exception data".to_string());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(0 as *mut ())
|
0 as *mut ()
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
unexpected = Some(format!(
|
unexpected = Some(format!("expected nested value slot from kernel CPU, not {:?}", other));
|
||||||
"expected nested value slot from kernel CPU, not {:?}",
|
0 as *mut ()
|
||||||
other
|
|
||||||
));
|
|
||||||
Ok(0 as *mut ())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1088,9 +1000,8 @@ where
|
||||||
writer.write_u32(u32::MAX)?;
|
writer.write_u32(u32::MAX)?;
|
||||||
writer.write_u32(exception.message.as_ptr() as u32)?;
|
writer.write_u32(exception.message.as_ptr() as u32)?;
|
||||||
} else {
|
} else {
|
||||||
let msg = str::from_utf8(unsafe {
|
let msg =
|
||||||
slice::from_raw_parts(exception.message.as_ptr(), exception.message.len())
|
str::from_utf8(unsafe { slice::from_raw_parts(exception.message.as_ptr(), exception.message.len()) })
|
||||||
})
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.replace(
|
.replace(
|
||||||
"{rtio_channel_info:0}",
|
"{rtio_channel_info:0}",
|
||||||
|
|
Loading…
Reference in New Issue