libkernel -> ksupport

pull/267/head
mwojcik 2023-09-05 16:21:39 +08:00
parent 49205eea17
commit 623cc7b79e
29 changed files with 172 additions and 231 deletions

5
src/Cargo.lock generated
View File

@ -219,7 +219,7 @@ dependencies = [
]
[[package]]
name = "kernel"
name = "ksupport"
version = "0.1.0"
dependencies = [
"build_zynq",
@ -465,7 +465,7 @@ dependencies = [
"embedded-hal",
"futures",
"io",
"kernel",
"ksupport",
"libasync",
"libboard_artiq",
"libboard_zynq",
@ -498,6 +498,7 @@ version = "0.0.0"
dependencies = [
"build_zynq",
"embedded-hal",
"ksupport",
"libasync",
"libboard_artiq",
"libboard_zynq",

View File

@ -5,6 +5,7 @@ members = [
"libdwarf",
"libio",
"libunwind",
"libksupport",
"runtime",
"satman"
]

View File

@ -1,3 +1,5 @@
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core_io::{Error as IoError, Read, Write};
#[derive(Debug, Clone)]
@ -64,7 +66,7 @@ impl Write for Cursor<&mut [u8]> {
}
#[cfg(feature = "alloc")]
impl Write for Cursor<::alloc::Vec<u8>> {
impl Write for Cursor<Vec<u8>> {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
self.inner.extend_from_slice(buf);

View File

@ -1,13 +1,10 @@
#![no_std]
#![feature(never_type)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#[cfg(feature = "alloc")]
extern crate alloc;
extern crate core_io;
#[cfg(feature = "alloc")]
#[macro_use]
use alloc;
#[cfg(feature = "byteorder")]
extern crate byteorder;

View File

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

View File

@ -1,5 +1,5 @@
[package]
name = "kernel"
name = "ksupport"
description = "Kernel support for Zynq-based platforms"
version = "0.1.0"
authors = ["M-Labs"]

View File

@ -11,8 +11,6 @@ use super::{cache,
core1::rtio_get_destination_status,
dma,
rpc::{rpc_recv, rpc_send, rpc_send_async}};
#[cfg(has_drtio)]
use super::subkernel;
use crate::{eh_artiq, i2c, rtio};
extern "C" {

View File

@ -3,8 +3,8 @@ use core::mem::{forget, replace};
use libcortex_a9::sync_channel::{Receiver, Sender};
use libsupport_zynq::boot::Core1;
use super::{CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK};
use crate::{irq::restart_core1, Message};
use super::{Message, CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK};
use crate::{irq::restart_core1};
pub struct Control {
pub tx: Sender<'static, Message>,

View File

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

View File

@ -2,8 +2,8 @@ use alloc::vec::Vec;
use cslice::CSlice;
use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0};
use crate::{artiq_raise, rpc::send_args, Message, SubkernelStatus};
use super::{Message, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, SubkernelStatus};
use crate::{artiq_raise, rpc::send_args};
pub extern "C" fn load_run(id: u32, run: bool) {
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(),
});
}
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) {

View File

@ -8,14 +8,14 @@
#[macro_use]
extern crate alloc;
use alloc::{collections::BTreeMap, string::String, vec::Vec};
use alloc::{collections::BTreeMap, string::String};
use io::{Cursor, ProtoRead};
pub use kernel::{Control, DmaRecorder};
use libasync::block_async;
use libconfig::Config;
use log::{error, warn};
use void::Void;
use rtio::rtio_core;
pub mod eh_artiq;
pub mod i2c;
@ -151,7 +151,7 @@ pub unsafe fn get_async_errors() -> u8 {
fn wait_for_async_rtio_error() -> nb::Result<(), Void> {
unsafe {
if pl::csr::rtio_core::async_error_read() != 0 {
if rtio_core::async_error_read() != 0 {
Ok(())
} else {
Err(nb::Error::WouldBlock)
@ -163,9 +163,9 @@ pub async fn report_async_rtio_errors() {
loop {
let _ = block_async!(wait_for_async_rtio_error()).await;
unsafe {
let errors = pl::csr::rtio_core::async_error_read();
let errors = rtio_core::async_error_read();
if errors & ASYNC_ERROR_COLLISION != 0 {
let channel = pl::csr::rtio_core::collision_channel_read();
let channel = rtio_core::collision_channel_read();
error!(
"RTIO collision involving channel 0x{:04x}:{}",
channel,
@ -173,7 +173,7 @@ pub async fn report_async_rtio_errors() {
);
}
if errors & ASYNC_ERROR_BUSY != 0 {
let channel = pl::csr::rtio_core::busy_channel_read();
let channel = rtio_core::busy_channel_read();
error!(
"RTIO busy error involving channel 0x{:04x}:{}",
channel,
@ -181,7 +181,7 @@ pub async fn report_async_rtio_errors() {
);
}
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!(
"RTIO sequence error involving channel 0x{:04x}:{}",
channel,
@ -189,7 +189,7 @@ pub async fn report_async_rtio_errors() {
);
}
SEEN_ASYNC_ERRORS = errors;
pl::csr::rtio_core::async_error_write(errors);
rtio_core::async_error_write(errors);
}
}
}

View File

@ -190,173 +190,6 @@ where
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>
where W: Write + ?Sized {
writer.write_u8(elt_tag.as_u8())?;

View File

@ -5,6 +5,10 @@ use libcortex_a9::asm;
use vcell::VolatileCell;
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_UNDERFLOW: i32 = 2;
@ -52,7 +56,7 @@ static mut TRANSACTION_BUFFER: Transaction = Transaction {
pub extern "C" fn init() {
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::enable_write(1);
}

View File

@ -3,6 +3,10 @@ use core::ptr::{read_volatile, write_volatile};
use cslice::CSlice;
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_UNDERFLOW: u8 = 2;
@ -20,7 +24,7 @@ pub struct TimestampedData {
pub extern "C" fn init() {
unsafe {
csr::rtio_core::reset_write(1);
rtio_core::reset_write(1);
}
}

View File

@ -39,5 +39,5 @@ dwarf = { path = "../libdwarf" }
unwind = { path = "../libunwind" }
libc = { path = "../libc" }
io = { path = "../libio" }
kernel = { path = "../libkernel" }
ksupport = { path = "../libksupport" }
libboard_artiq = { path = "../libboard_artiq" }

View File

@ -6,9 +6,9 @@ use cslice::CSlice;
use futures::{future::FutureExt, select_biased};
#[cfg(has_drtio)]
use io::{Cursor, ProtoRead};
use kernel::resolve_channel_name;
use ksupport::{kernel, resolve_channel_name};
#[cfg(has_drtio)]
use kernel::rpc;
use ksupport::rpc;
use libasync::{smoltcp::{Sockets, TcpStream},
task};
use libboard_artiq::drtio_routing;
@ -252,7 +252,7 @@ async fn handle_run_kernel(
let function = read_i32(stream).await? as u32;
control
.tx
.async_send(kernel::Message::RpcRecvReply(Err(kernel::RPCException {
.async_send(kernel::Message::RpcRecvReply(Err(ksupport::RPCException {
id,
message,
param,
@ -444,6 +444,7 @@ async fn handle_run_kernel(
error!("error sending subkernel message: {:?}", e)
}
};
control.borrow_mut().tx.async_send(kernel::Message::SubkernelMsgSent).await;
}
#[cfg(has_drtio)]
kernel::Message::SubkernelMsgRecvRequest { id, timeout } => {
@ -685,7 +686,7 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
drtio_routing::interconnect_disable_all();
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);
moninj::start(timer, &aux_mutex, &drtio_routing_table);

View File

@ -11,7 +11,7 @@ extern crate alloc;
#[cfg(feature = "target_kasli_soc")]
use core::cell::RefCell;
use kernel;
use ksupport;
use libasync::task;
#[cfg(feature = "target_kasli_soc")]
use libboard_artiq::io_expander;
@ -74,9 +74,9 @@ pub fn main_core0() {
info!("gateware ident: {}", identifier_read(&mut [0; 64]));
kernel::i2c::init();
ksupport::i2c::init();
#[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")]
let (mut io_expander0, mut io_expander1);
@ -109,7 +109,7 @@ pub fn main_core0() {
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")]
task::spawn(io_expanders_service(

View File

@ -4,7 +4,7 @@ use core::future::Future;
use async_recursion::async_recursion;
use byteorder::{ByteOrder, NativeEndian};
use cslice::CMutSlice;
use kernel::rpc::{tag::{Tag, TagIterator},
use ksupport::rpc::{tag::{Tag, TagIterator},
*};
use libasync::smoltcp::TcpStream;
use libboard_zynq::smoltcp;

View File

@ -1,6 +1,6 @@
use embedded_hal::blocking::delay::DelayMs;
#[cfg(has_si5324)]
use kernel::i2c;
use ksupport::i2c;
use libboard_artiq::pl;
#[cfg(has_si5324)]
use libboard_artiq::si5324;

View File

@ -2,7 +2,7 @@ use alloc::{collections::BTreeMap, rc::Rc, string::String, vec::Vec};
#[cfg(has_drtio)]
use core::mem;
use kernel::DmaRecorder;
use ksupport::kernel::DmaRecorder;
#[cfg(has_drtio)]
use libasync::task;
use libboard_artiq::drtio_routing::RoutingTable;

View File

@ -10,7 +10,7 @@ pub mod drtio {
use alloc::vec::Vec;
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 libboard_artiq::{drtioaux::Error, drtioaux_async, drtioaux_async::Packet,
drtioaux_proto::MASTER_PAYLOAD_MAX_SIZE};