forked from M-Labs/artiq-zynq
libkernel -> ksupport
This commit is contained in:
parent
49205eea17
commit
623cc7b79e
|
@ -219,7 +219,7 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel"
|
name = "ksupport"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
|
@ -465,7 +465,7 @@ dependencies = [
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"futures",
|
"futures",
|
||||||
"io",
|
"io",
|
||||||
"kernel",
|
"ksupport",
|
||||||
"libasync",
|
"libasync",
|
||||||
"libboard_artiq",
|
"libboard_artiq",
|
||||||
"libboard_zynq",
|
"libboard_zynq",
|
||||||
|
@ -498,6 +498,7 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
|
"ksupport",
|
||||||
"libasync",
|
"libasync",
|
||||||
"libboard_artiq",
|
"libboard_artiq",
|
||||||
"libboard_zynq",
|
"libboard_zynq",
|
||||||
|
|
|
@ -5,6 +5,7 @@ members = [
|
||||||
"libdwarf",
|
"libdwarf",
|
||||||
"libio",
|
"libio",
|
||||||
"libunwind",
|
"libunwind",
|
||||||
|
"libksupport",
|
||||||
"runtime",
|
"runtime",
|
||||||
"satman"
|
"satman"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core_io::{Error as IoError, Read, Write};
|
use core_io::{Error as IoError, Read, Write};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -64,7 +66,7 @@ impl Write for Cursor<&mut [u8]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl Write for Cursor<::alloc::Vec<u8>> {
|
impl Write for Cursor<Vec<u8>> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
||||||
self.inner.extend_from_slice(buf);
|
self.inner.extend_from_slice(buf);
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate core_io;
|
extern crate core_io;
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
#[macro_use]
|
|
||||||
use alloc;
|
|
||||||
#[cfg(feature = "byteorder")]
|
#[cfg(feature = "byteorder")]
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
use core::ptr;
|
|
||||||
|
|
||||||
use libcortex_a9::{mutex::Mutex, semaphore::Semaphore, sync_channel};
|
|
||||||
|
|
||||||
use crate::Message;
|
|
||||||
|
|
||||||
mod control;
|
|
||||||
pub use control::Control;
|
|
||||||
mod api;
|
|
||||||
pub mod core1;
|
|
||||||
mod dma;
|
|
||||||
mod rpc;
|
|
||||||
pub use dma::DmaRecorder;
|
|
||||||
mod cache;
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
mod subkernel;
|
|
||||||
|
|
||||||
static CHANNEL_0TO1: Mutex<Option<sync_channel::Sender<'static, Message>>> = Mutex::new(None);
|
|
||||||
static CHANNEL_1TO0: Mutex<Option<sync_channel::Receiver<'static, Message>>> = Mutex::new(None);
|
|
||||||
static CHANNEL_SEM: Semaphore = Semaphore::new(0, 1);
|
|
||||||
|
|
||||||
static mut KERNEL_CHANNEL_0TO1: Option<sync_channel::Receiver<'static, Message>> = None;
|
|
||||||
static mut KERNEL_CHANNEL_1TO0: Option<sync_channel::Sender<'static, Message>> = None;
|
|
||||||
|
|
||||||
pub static mut KERNEL_IMAGE: *const core1::KernelImage = ptr::null();
|
|
||||||
|
|
||||||
static INIT_LOCK: Mutex<()> = Mutex::new(());
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "kernel"
|
name = "ksupport"
|
||||||
description = "Kernel support for Zynq-based platforms"
|
description = "Kernel support for Zynq-based platforms"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["M-Labs"]
|
authors = ["M-Labs"]
|
|
@ -11,8 +11,6 @@ use super::{cache,
|
||||||
core1::rtio_get_destination_status,
|
core1::rtio_get_destination_status,
|
||||||
dma,
|
dma,
|
||||||
rpc::{rpc_recv, rpc_send, rpc_send_async}};
|
rpc::{rpc_recv, rpc_send, rpc_send_async}};
|
||||||
#[cfg(has_drtio)]
|
|
||||||
use super::subkernel;
|
|
||||||
use crate::{eh_artiq, i2c, rtio};
|
use crate::{eh_artiq, i2c, rtio};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
|
@ -3,8 +3,8 @@ use core::mem::{forget, replace};
|
||||||
use libcortex_a9::sync_channel::{Receiver, Sender};
|
use libcortex_a9::sync_channel::{Receiver, Sender};
|
||||||
use libsupport_zynq::boot::Core1;
|
use libsupport_zynq::boot::Core1;
|
||||||
|
|
||||||
use super::{CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK};
|
use super::{Message, CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK};
|
||||||
use crate::{irq::restart_core1, Message};
|
use crate::{irq::restart_core1};
|
||||||
|
|
||||||
pub struct Control {
|
pub struct Control {
|
||||||
pub tx: Sender<'static, Message>,
|
pub tx: Sender<'static, Message>,
|
|
@ -0,0 +1,123 @@
|
||||||
|
use alloc::{string::String, vec::Vec};
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
|
use libcortex_a9::{mutex::Mutex, semaphore::Semaphore, sync_channel};
|
||||||
|
|
||||||
|
use crate::{eh_artiq, RPCException};
|
||||||
|
|
||||||
|
mod control;
|
||||||
|
pub use control::Control;
|
||||||
|
mod api;
|
||||||
|
pub mod core1;
|
||||||
|
mod dma;
|
||||||
|
mod rpc;
|
||||||
|
pub use dma::DmaRecorder;
|
||||||
|
mod cache;
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
mod subkernel;
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum SubkernelStatus {
|
||||||
|
NoError,
|
||||||
|
Timeout,
|
||||||
|
IncorrectState,
|
||||||
|
CommLost,
|
||||||
|
OtherError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Message {
|
||||||
|
LoadRequest(Vec<u8>),
|
||||||
|
LoadCompleted,
|
||||||
|
LoadFailed,
|
||||||
|
StartRequest,
|
||||||
|
KernelFinished(u8),
|
||||||
|
KernelException(
|
||||||
|
&'static [Option<eh_artiq::Exception<'static>>],
|
||||||
|
&'static [eh_artiq::StackPointerBacktrace],
|
||||||
|
&'static [(usize, usize)],
|
||||||
|
u8,
|
||||||
|
),
|
||||||
|
RpcSend {
|
||||||
|
is_async: bool,
|
||||||
|
data: Vec<u8>,
|
||||||
|
},
|
||||||
|
RpcRecvRequest(*mut ()),
|
||||||
|
RpcRecvReply(Result<usize, RPCException>),
|
||||||
|
|
||||||
|
CacheGetRequest(String),
|
||||||
|
CacheGetReply(Vec<i32>),
|
||||||
|
CachePutRequest(String, Vec<i32>),
|
||||||
|
|
||||||
|
DmaPutRequest(DmaRecorder),
|
||||||
|
DmaEraseRequest(String),
|
||||||
|
DmaGetRequest(String),
|
||||||
|
DmaGetReply(Option<(i32, i64, bool)>),
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
DmaStartRemoteRequest {
|
||||||
|
id: i32,
|
||||||
|
timestamp: i64,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
DmaAwaitRemoteRequest(i32),
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
DmaAwaitRemoteReply {
|
||||||
|
timeout: bool,
|
||||||
|
error: u8,
|
||||||
|
channel: u32,
|
||||||
|
timestamp: u64,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
UpDestinationsRequest(i32),
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
UpDestinationsReply(bool),
|
||||||
|
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelLoadRunRequest {
|
||||||
|
id: u32,
|
||||||
|
run: bool,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelLoadRunReply {
|
||||||
|
succeeded: bool,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelAwaitFinishRequest {
|
||||||
|
id: u32,
|
||||||
|
timeout: u64,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelAwaitFinishReply {
|
||||||
|
status: SubkernelStatus,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelMsgSend {
|
||||||
|
id: u32,
|
||||||
|
data: Vec<u8>,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelMsgSent,
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelMsgRecvRequest {
|
||||||
|
id: u32,
|
||||||
|
timeout: u64,
|
||||||
|
},
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
SubkernelMsgRecvReply {
|
||||||
|
status: SubkernelStatus,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
static CHANNEL_0TO1: Mutex<Option<sync_channel::Sender<'static, Message>>> = Mutex::new(None);
|
||||||
|
static CHANNEL_1TO0: Mutex<Option<sync_channel::Receiver<'static, Message>>> = Mutex::new(None);
|
||||||
|
static CHANNEL_SEM: Semaphore = Semaphore::new(0, 1);
|
||||||
|
|
||||||
|
static mut KERNEL_CHANNEL_0TO1: Option<sync_channel::Receiver<'static, Message>> = None;
|
||||||
|
static mut KERNEL_CHANNEL_1TO0: Option<sync_channel::Sender<'static, Message>> = None;
|
||||||
|
|
||||||
|
pub static mut KERNEL_IMAGE: *const core1::KernelImage = ptr::null();
|
||||||
|
|
||||||
|
static INIT_LOCK: Mutex<()> = Mutex::new(());
|
|
@ -2,8 +2,8 @@ use alloc::vec::Vec;
|
||||||
|
|
||||||
use cslice::CSlice;
|
use cslice::CSlice;
|
||||||
|
|
||||||
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0};
|
use super::{Message, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, SubkernelStatus};
|
||||||
use crate::{artiq_raise, rpc::send_args, Message, SubkernelStatus};
|
use crate::{artiq_raise, rpc::send_args};
|
||||||
|
|
||||||
pub extern "C" fn load_run(id: u32, run: bool) {
|
pub extern "C" fn load_run(id: u32, run: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -62,6 +62,10 @@ pub extern "C" fn send_message(id: u32, count: u8, tag: &CSlice<u8>, data: *cons
|
||||||
data: buffer[3..].to_vec(),
|
data: buffer[3..].to_vec(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
match unsafe { KERNEL_CHANNEL_0TO1.as_mut().unwrap() }.recv() {
|
||||||
|
Message::SubkernelMsgSent => (),
|
||||||
|
_ => panic!("expected SubkernelMsgSent after SubkernelMsgSend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn await_message(id: u32, timeout: u64, min: u8, max: u8) {
|
pub extern "C" fn await_message(id: u32, timeout: u64, min: u8, max: u8) {
|
|
@ -8,14 +8,14 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::{collections::BTreeMap, string::String, vec::Vec};
|
use alloc::{collections::BTreeMap, string::String};
|
||||||
|
|
||||||
use io::{Cursor, ProtoRead};
|
use io::{Cursor, ProtoRead};
|
||||||
pub use kernel::{Control, DmaRecorder};
|
|
||||||
use libasync::block_async;
|
use libasync::block_async;
|
||||||
use libconfig::Config;
|
use libconfig::Config;
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use void::Void;
|
use void::Void;
|
||||||
|
use rtio::rtio_core;
|
||||||
|
|
||||||
pub mod eh_artiq;
|
pub mod eh_artiq;
|
||||||
pub mod i2c;
|
pub mod i2c;
|
||||||
|
@ -151,7 +151,7 @@ pub unsafe fn get_async_errors() -> u8 {
|
||||||
|
|
||||||
fn wait_for_async_rtio_error() -> nb::Result<(), Void> {
|
fn wait_for_async_rtio_error() -> nb::Result<(), Void> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if pl::csr::rtio_core::async_error_read() != 0 {
|
if rtio_core::async_error_read() != 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(nb::Error::WouldBlock)
|
Err(nb::Error::WouldBlock)
|
||||||
|
@ -163,9 +163,9 @@ pub async fn report_async_rtio_errors() {
|
||||||
loop {
|
loop {
|
||||||
let _ = block_async!(wait_for_async_rtio_error()).await;
|
let _ = block_async!(wait_for_async_rtio_error()).await;
|
||||||
unsafe {
|
unsafe {
|
||||||
let errors = pl::csr::rtio_core::async_error_read();
|
let errors = rtio_core::async_error_read();
|
||||||
if errors & ASYNC_ERROR_COLLISION != 0 {
|
if errors & ASYNC_ERROR_COLLISION != 0 {
|
||||||
let channel = pl::csr::rtio_core::collision_channel_read();
|
let channel = rtio_core::collision_channel_read();
|
||||||
error!(
|
error!(
|
||||||
"RTIO collision involving channel 0x{:04x}:{}",
|
"RTIO collision involving channel 0x{:04x}:{}",
|
||||||
channel,
|
channel,
|
||||||
|
@ -173,7 +173,7 @@ pub async fn report_async_rtio_errors() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if errors & ASYNC_ERROR_BUSY != 0 {
|
if errors & ASYNC_ERROR_BUSY != 0 {
|
||||||
let channel = pl::csr::rtio_core::busy_channel_read();
|
let channel = rtio_core::busy_channel_read();
|
||||||
error!(
|
error!(
|
||||||
"RTIO busy error involving channel 0x{:04x}:{}",
|
"RTIO busy error involving channel 0x{:04x}:{}",
|
||||||
channel,
|
channel,
|
||||||
|
@ -181,7 +181,7 @@ pub async fn report_async_rtio_errors() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 {
|
if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 {
|
||||||
let channel = pl::csr::rtio_core::sequence_error_channel_read();
|
let channel = rtio_core::sequence_error_channel_read();
|
||||||
error!(
|
error!(
|
||||||
"RTIO sequence error involving channel 0x{:04x}:{}",
|
"RTIO sequence error involving channel 0x{:04x}:{}",
|
||||||
channel,
|
channel,
|
||||||
|
@ -189,7 +189,7 @@ pub async fn report_async_rtio_errors() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
SEEN_ASYNC_ERRORS = errors;
|
SEEN_ASYNC_ERRORS = errors;
|
||||||
pl::csr::rtio_core::async_error_write(errors);
|
rtio_core::async_error_write(errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -190,173 +190,6 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// versions for Cursor rather than TcpStream
|
|
||||||
// they will be made into sync for satellite subkernels later
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
#[async_recursion(?Send)]
|
|
||||||
async unsafe fn recv_elements_cursor<F>(
|
|
||||||
cursor: &mut Cursor<Vec<u8>>,
|
|
||||||
elt_tag: Tag<'async_recursion>,
|
|
||||||
length: usize,
|
|
||||||
storage: *mut (),
|
|
||||||
alloc: &(impl Fn(usize) -> F + 'async_recursion),
|
|
||||||
) -> Result<(), Error>
|
|
||||||
where
|
|
||||||
F: Future<Output = *mut ()>,
|
|
||||||
{
|
|
||||||
match elt_tag {
|
|
||||||
Tag::Bool => {
|
|
||||||
let dest = core::slice::from_raw_parts_mut(storage as *mut u8, length);
|
|
||||||
cursor.read_exact(dest)?;
|
|
||||||
}
|
|
||||||
Tag::Int32 => {
|
|
||||||
let ptr = storage as *mut u32;
|
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4);
|
|
||||||
cursor.read_exact(dest)?;
|
|
||||||
drop(dest);
|
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
|
||||||
NativeEndian::from_slice_u32(dest);
|
|
||||||
}
|
|
||||||
Tag::Int64 | Tag::Float64 => {
|
|
||||||
let ptr = storage as *mut u64;
|
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8);
|
|
||||||
cursor.read_exact(dest)?;
|
|
||||||
drop(dest);
|
|
||||||
let dest = core::slice::from_raw_parts_mut(ptr, length);
|
|
||||||
NativeEndian::from_slice_u64(dest);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let mut data = storage;
|
|
||||||
for _ in 0..length {
|
|
||||||
recv_value_cursor(cursor, elt_tag, &mut data, alloc).await?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
#[async_recursion(?Send)]
|
|
||||||
async unsafe fn recv_value_cursor<F>(
|
|
||||||
cursor: &mut Cursor<Vec<u8>>,
|
|
||||||
tag: Tag<'async_recursion>,
|
|
||||||
data: &mut *mut (),
|
|
||||||
alloc: &(impl Fn(usize) -> F + 'async_recursion),
|
|
||||||
) -> Result<(), Error>
|
|
||||||
where
|
|
||||||
F: Future<Output = *mut ()>,
|
|
||||||
{
|
|
||||||
macro_rules! consume_value {
|
|
||||||
($ty:ty, | $ptr:ident | $map:expr) => {{
|
|
||||||
let $ptr = align_ptr_mut::<$ty>(*data);
|
|
||||||
*data = $ptr.offset(1) as *mut ();
|
|
||||||
$map
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Tag::None => Ok(()),
|
|
||||||
Tag::Bool => consume_value!(i8, |ptr| {
|
|
||||||
*ptr = cursor.read_u8()? as i8;
|
|
||||||
Ok(())
|
|
||||||
}),
|
|
||||||
Tag::Int32 => consume_value!(i32, |ptr| {
|
|
||||||
*ptr = cursor.read_u32()? as i32;
|
|
||||||
Ok(())
|
|
||||||
}),
|
|
||||||
Tag::Int64 | Tag::Float64 => consume_value!(i64, |ptr| {
|
|
||||||
*ptr = cursor.read_u64()? as i64;
|
|
||||||
Ok(())
|
|
||||||
}),
|
|
||||||
Tag::String | Tag::Bytes | Tag::ByteArray => {
|
|
||||||
consume_value!(CMutSlice<u8>, |ptr| {
|
|
||||||
let length = cursor.read_u32()? as usize;
|
|
||||||
*ptr = CMutSlice::new(alloc(length).await as *mut u8, length);
|
|
||||||
cursor.read_exact((*ptr).as_mut())?;
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Tag::Tuple(it, arity) => {
|
|
||||||
let alignment = tag.alignment();
|
|
||||||
*data = round_up_mut(*data, alignment);
|
|
||||||
let mut it = it.clone();
|
|
||||||
for _ in 0..arity {
|
|
||||||
let tag = it.next().expect("truncated tag");
|
|
||||||
recv_value_cursor(cursor, tag, data, alloc).await?
|
|
||||||
}
|
|
||||||
*data = round_up_mut(*data, alignment);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Tag::List(it) => {
|
|
||||||
#[repr(C)]
|
|
||||||
struct List {
|
|
||||||
elements: *mut (),
|
|
||||||
length: usize,
|
|
||||||
}
|
|
||||||
consume_value!(*mut List, |ptr_to_list| {
|
|
||||||
let tag = it.clone().next().expect("truncated tag");
|
|
||||||
let length = cursor.read_u32()? as usize;
|
|
||||||
|
|
||||||
let list_size = 4 + 4;
|
|
||||||
let storage_offset = round_up(list_size, tag.alignment());
|
|
||||||
let storage_size = tag.size() * length;
|
|
||||||
|
|
||||||
let allocation = alloc(storage_offset + storage_size).await as *mut u8;
|
|
||||||
*ptr_to_list = allocation as *mut List;
|
|
||||||
let storage = allocation.offset(storage_offset as isize) as *mut ();
|
|
||||||
|
|
||||||
(**ptr_to_list).length = length;
|
|
||||||
(**ptr_to_list).elements = storage;
|
|
||||||
recv_elements_cursor(cursor, tag, length, storage, alloc).await
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Tag::Array(it, num_dims) => {
|
|
||||||
consume_value!(*mut (), |buffer| {
|
|
||||||
let mut total_len: usize = 1;
|
|
||||||
for _ in 0..num_dims {
|
|
||||||
let len = cursor.read_u32()? as usize;
|
|
||||||
total_len *= len;
|
|
||||||
consume_value!(usize, |ptr| *ptr = len)
|
|
||||||
}
|
|
||||||
|
|
||||||
let elt_tag = it.clone().next().expect("truncated tag");
|
|
||||||
*buffer = alloc(elt_tag.size() * total_len).await;
|
|
||||||
recv_elements_cursor(cursor, elt_tag, total_len, *buffer, alloc).await
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Tag::Range(it) => {
|
|
||||||
*data = round_up_mut(*data, tag.alignment());
|
|
||||||
let tag = it.clone().next().expect("truncated tag");
|
|
||||||
recv_value_cursor(cursor, tag, data, alloc).await?;
|
|
||||||
recv_value_cursor(cursor, tag, data, alloc).await?;
|
|
||||||
recv_value_cursor(cursor, tag, data, alloc).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Tag::Keyword(_) => unreachable!(),
|
|
||||||
Tag::Object => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
pub async fn recv_return_cursor<F>(
|
|
||||||
cursor: &mut Cursor<Vec<u8>>,
|
|
||||||
tag_bytes: &[u8],
|
|
||||||
data: *mut (),
|
|
||||||
alloc: &impl Fn(usize) -> F,
|
|
||||||
) -> Result<(), Error>
|
|
||||||
where
|
|
||||||
F: Future<Output = *mut ()>,
|
|
||||||
{
|
|
||||||
let mut it = TagIterator::new(tag_bytes);
|
|
||||||
trace!("recv ...->{}", it);
|
|
||||||
|
|
||||||
let tag = it.next().expect("truncated tag");
|
|
||||||
let mut data = data;
|
|
||||||
unsafe { recv_value_cursor(cursor, tag, &mut data, alloc).await? };
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn send_elements<W>(writer: &mut W, elt_tag: Tag, length: usize, data: *const ()) -> Result<(), Error>
|
unsafe fn send_elements<W>(writer: &mut W, elt_tag: Tag, length: usize, data: *const ()) -> Result<(), Error>
|
||||||
where W: Write + ?Sized {
|
where W: Write + ?Sized {
|
||||||
writer.write_u8(elt_tag.as_u8())?;
|
writer.write_u8(elt_tag.as_u8())?;
|
|
@ -5,6 +5,10 @@ use libcortex_a9::asm;
|
||||||
use vcell::VolatileCell;
|
use vcell::VolatileCell;
|
||||||
|
|
||||||
use crate::{artiq_raise, pl::csr, resolve_channel_name};
|
use crate::{artiq_raise, pl::csr, resolve_channel_name};
|
||||||
|
#[cfg(has_drtiosat)]
|
||||||
|
pub use crate::pl::csr::drtiosat as rtio_core;
|
||||||
|
#[cfg(has_rtio_core)]
|
||||||
|
pub use crate::pl::csr::rtio_core;
|
||||||
|
|
||||||
pub const RTIO_O_STATUS_WAIT: i32 = 1;
|
pub const RTIO_O_STATUS_WAIT: i32 = 1;
|
||||||
pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
|
pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
|
||||||
|
@ -52,7 +56,7 @@ static mut TRANSACTION_BUFFER: Transaction = Transaction {
|
||||||
|
|
||||||
pub extern "C" fn init() {
|
pub extern "C" fn init() {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio_core::reset_write(1);
|
rtio_core::reset_write(1);
|
||||||
csr::rtio::engine_addr_base_write(&TRANSACTION_BUFFER as *const Transaction as u32);
|
csr::rtio::engine_addr_base_write(&TRANSACTION_BUFFER as *const Transaction as u32);
|
||||||
csr::rtio::enable_write(1);
|
csr::rtio::enable_write(1);
|
||||||
}
|
}
|
|
@ -3,6 +3,10 @@ use core::ptr::{read_volatile, write_volatile};
|
||||||
use cslice::CSlice;
|
use cslice::CSlice;
|
||||||
|
|
||||||
use crate::{artiq_raise, pl::csr, resolve_channel_name};
|
use crate::{artiq_raise, pl::csr, resolve_channel_name};
|
||||||
|
#[cfg(has_drtiosat)]
|
||||||
|
pub use crate::pl::csr::drtiosat as rtio_core;
|
||||||
|
#[cfg(has_rtio_core)]
|
||||||
|
pub use crate::pl::csr::rtio_core;
|
||||||
|
|
||||||
pub const RTIO_O_STATUS_WAIT: u8 = 1;
|
pub const RTIO_O_STATUS_WAIT: u8 = 1;
|
||||||
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2;
|
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2;
|
||||||
|
@ -20,7 +24,7 @@ pub struct TimestampedData {
|
||||||
|
|
||||||
pub extern "C" fn init() {
|
pub extern "C" fn init() {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio_core::reset_write(1);
|
rtio_core::reset_write(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,5 +39,5 @@ dwarf = { path = "../libdwarf" }
|
||||||
unwind = { path = "../libunwind" }
|
unwind = { path = "../libunwind" }
|
||||||
libc = { path = "../libc" }
|
libc = { path = "../libc" }
|
||||||
io = { path = "../libio" }
|
io = { path = "../libio" }
|
||||||
kernel = { path = "../libkernel" }
|
ksupport = { path = "../libksupport" }
|
||||||
libboard_artiq = { path = "../libboard_artiq" }
|
libboard_artiq = { path = "../libboard_artiq" }
|
|
@ -6,9 +6,9 @@ use cslice::CSlice;
|
||||||
use futures::{future::FutureExt, select_biased};
|
use futures::{future::FutureExt, select_biased};
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use io::{Cursor, ProtoRead};
|
use io::{Cursor, ProtoRead};
|
||||||
use kernel::resolve_channel_name;
|
use ksupport::{kernel, resolve_channel_name};
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use kernel::rpc;
|
use ksupport::rpc;
|
||||||
use libasync::{smoltcp::{Sockets, TcpStream},
|
use libasync::{smoltcp::{Sockets, TcpStream},
|
||||||
task};
|
task};
|
||||||
use libboard_artiq::drtio_routing;
|
use libboard_artiq::drtio_routing;
|
||||||
|
@ -252,7 +252,7 @@ async fn handle_run_kernel(
|
||||||
let function = read_i32(stream).await? as u32;
|
let function = read_i32(stream).await? as u32;
|
||||||
control
|
control
|
||||||
.tx
|
.tx
|
||||||
.async_send(kernel::Message::RpcRecvReply(Err(kernel::RPCException {
|
.async_send(kernel::Message::RpcRecvReply(Err(ksupport::RPCException {
|
||||||
id,
|
id,
|
||||||
message,
|
message,
|
||||||
param,
|
param,
|
||||||
|
@ -444,6 +444,7 @@ async fn handle_run_kernel(
|
||||||
error!("error sending subkernel message: {:?}", e)
|
error!("error sending subkernel message: {:?}", e)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
control.borrow_mut().tx.async_send(kernel::Message::SubkernelMsgSent).await;
|
||||||
}
|
}
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
kernel::Message::SubkernelMsgRecvRequest { id, timeout } => {
|
kernel::Message::SubkernelMsgRecvRequest { id, timeout } => {
|
||||||
|
@ -685,7 +686,7 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
|
||||||
drtio_routing::interconnect_disable_all();
|
drtio_routing::interconnect_disable_all();
|
||||||
|
|
||||||
rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer);
|
rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer);
|
||||||
kernel::setup_device_map(&cfg);
|
ksupport::setup_device_map(&cfg);
|
||||||
|
|
||||||
analyzer::start(&aux_mutex, &drtio_routing_table, &up_destinations, timer);
|
analyzer::start(&aux_mutex, &drtio_routing_table, &up_destinations, timer);
|
||||||
moninj::start(timer, &aux_mutex, &drtio_routing_table);
|
moninj::start(timer, &aux_mutex, &drtio_routing_table);
|
||||||
|
|
|
@ -11,7 +11,7 @@ extern crate alloc;
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use kernel;
|
use ksupport;
|
||||||
use libasync::task;
|
use libasync::task;
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
use libboard_artiq::io_expander;
|
use libboard_artiq::io_expander;
|
||||||
|
@ -74,9 +74,9 @@ pub fn main_core0() {
|
||||||
|
|
||||||
info!("gateware ident: {}", identifier_read(&mut [0; 64]));
|
info!("gateware ident: {}", identifier_read(&mut [0; 64]));
|
||||||
|
|
||||||
kernel::i2c::init();
|
ksupport::i2c::init();
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
let i2c_bus = unsafe { (kernel::i2c::I2C_BUS).as_mut().unwrap() };
|
let i2c_bus = unsafe { (ksupport::i2c::I2C_BUS).as_mut().unwrap() };
|
||||||
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
let (mut io_expander0, mut io_expander1);
|
let (mut io_expander0, mut io_expander1);
|
||||||
|
@ -109,7 +109,7 @@ pub fn main_core0() {
|
||||||
|
|
||||||
rtio_clocking::init(&mut timer, &cfg);
|
rtio_clocking::init(&mut timer, &cfg);
|
||||||
|
|
||||||
task::spawn(kernel::report_async_rtio_errors());
|
task::spawn(ksupport::report_async_rtio_errors());
|
||||||
|
|
||||||
#[cfg(feature = "target_kasli_soc")]
|
#[cfg(feature = "target_kasli_soc")]
|
||||||
task::spawn(io_expanders_service(
|
task::spawn(io_expanders_service(
|
||||||
|
|
|
@ -4,7 +4,7 @@ use core::future::Future;
|
||||||
use async_recursion::async_recursion;
|
use async_recursion::async_recursion;
|
||||||
use byteorder::{ByteOrder, NativeEndian};
|
use byteorder::{ByteOrder, NativeEndian};
|
||||||
use cslice::CMutSlice;
|
use cslice::CMutSlice;
|
||||||
use kernel::rpc::{tag::{Tag, TagIterator},
|
use ksupport::rpc::{tag::{Tag, TagIterator},
|
||||||
*};
|
*};
|
||||||
use libasync::smoltcp::TcpStream;
|
use libasync::smoltcp::TcpStream;
|
||||||
use libboard_zynq::smoltcp;
|
use libboard_zynq::smoltcp;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use embedded_hal::blocking::delay::DelayMs;
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
use kernel::i2c;
|
use ksupport::i2c;
|
||||||
use libboard_artiq::pl;
|
use libboard_artiq::pl;
|
||||||
#[cfg(has_si5324)]
|
#[cfg(has_si5324)]
|
||||||
use libboard_artiq::si5324;
|
use libboard_artiq::si5324;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use alloc::{collections::BTreeMap, rc::Rc, string::String, vec::Vec};
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
use kernel::DmaRecorder;
|
use ksupport::kernel::DmaRecorder;
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use libasync::task;
|
use libasync::task;
|
||||||
use libboard_artiq::drtio_routing::RoutingTable;
|
use libboard_artiq::drtio_routing::RoutingTable;
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub mod drtio {
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use embedded_hal::blocking::delay::DelayMs;
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
use kernel::{ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR, SEEN_ASYNC_ERRORS};
|
use ksupport::{ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR, SEEN_ASYNC_ERRORS, resolve_channel_name};
|
||||||
use libasync::{delay, task};
|
use libasync::{delay, task};
|
||||||
use libboard_artiq::{drtioaux::Error, drtioaux_async, drtioaux_async::Packet,
|
use libboard_artiq::{drtioaux::Error, drtioaux_async, drtioaux_async::Packet,
|
||||||
drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE};
|
drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE};
|
||||||
|
|
Loading…
Reference in New Issue