forked from M-Labs/artiq
ksupport: support subkernels
This commit is contained in:
parent
76f1318bc0
commit
b42816582e
@ -71,7 +71,6 @@ def build_artiq_soc(soc, argdict):
|
||||
if not soc.config["DRTIO_ROLE"] == "satellite":
|
||||
builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime"))
|
||||
else:
|
||||
# Assume DRTIO satellite.
|
||||
builder.add_software_package("satman", os.path.join(firmware_dir, "satman"))
|
||||
try:
|
||||
builder.build()
|
||||
|
@ -157,6 +157,11 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
||||
api!(dma_retrieve = ::dma_retrieve),
|
||||
api!(dma_playback = ::dma_playback),
|
||||
|
||||
api!(subkernel_load_run = ::subkernel_load_run),
|
||||
api!(subkernel_send_message = ::subkernel_send_message),
|
||||
api!(subkernel_await_message = ::subkernel_await_message),
|
||||
api!(subkernel_await_finish = ::subkernel_await_finish),
|
||||
|
||||
api!(i2c_start = ::nrt_bus::i2c::start),
|
||||
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
||||
api!(i2c_stop = ::nrt_bus::i2c::stop),
|
||||
|
@ -333,7 +333,7 @@ extern fn stop_fn(_version: c_int,
|
||||
}
|
||||
}
|
||||
|
||||
static EXCEPTION_ID_LOOKUP: [(&str, u32); 11] = [
|
||||
static EXCEPTION_ID_LOOKUP: [(&str, u32); 12] = [
|
||||
("RuntimeError", 0),
|
||||
("RTIOUnderflow", 1),
|
||||
("RTIOOverflow", 2),
|
||||
@ -345,6 +345,7 @@ static EXCEPTION_ID_LOOKUP: [(&str, u32); 11] = [
|
||||
("ZeroDivisionError", 8),
|
||||
("IndexError", 9),
|
||||
("UnwrapNoneError", 10),
|
||||
("SubkernelError", 11)
|
||||
];
|
||||
|
||||
pub fn get_exception_id(name: &str) -> u32 {
|
||||
|
@ -21,7 +21,6 @@ use dyld::Library;
|
||||
use board_artiq::{mailbox, rpc_queue};
|
||||
use proto_artiq::{kernel_proto, rpc_proto};
|
||||
use kernel_proto::*;
|
||||
#[cfg(has_rtio_dma)]
|
||||
use board_misoc::csr;
|
||||
use riscv::register::{mcause, mepc, mtval};
|
||||
|
||||
@ -396,7 +395,7 @@ extern fn dma_retrieve(name: &CSlice<u8>) -> DmaTrace {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(has_rtio_dma)]
|
||||
#[cfg(kernel_has_rtio_dma)]
|
||||
#[unwind(allowed)]
|
||||
extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) {
|
||||
assert!(ptr % 64 == 0);
|
||||
@ -454,10 +453,74 @@ extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(has_rtio_dma))]
|
||||
#[cfg(not(kernel_has_rtio_dma))]
|
||||
#[unwind(allowed)]
|
||||
extern fn dma_playback(_timestamp: i64, _ptr: i32, _uses_ddma: bool) {
|
||||
unimplemented!("not(has_rtio_dma)")
|
||||
unimplemented!("not(kernel_has_rtio_dma)")
|
||||
}
|
||||
|
||||
#[unwind(allowed)]
|
||||
extern fn subkernel_load_run(id: u32, run: bool) {
|
||||
send(&SubkernelLoadRunRequest { id: id, run: run });
|
||||
recv!(&SubkernelLoadRunReply { succeeded } => {
|
||||
if !succeeded {
|
||||
raise!("SubkernelError",
|
||||
"Error loading or running the subkernel");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[unwind(allowed)]
|
||||
extern fn subkernel_await_finish(id: u32, timeout: u64) {
|
||||
send(&SubkernelAwaitFinishRequest { id: id, timeout: timeout });
|
||||
recv!(SubkernelAwaitFinishReply { status } => {
|
||||
match status {
|
||||
SubkernelStatus::NoError => (),
|
||||
SubkernelStatus::IncorrectState => raise!("SubkernelError",
|
||||
"Subkernel not running"),
|
||||
SubkernelStatus::Timeout => raise!("SubkernelError",
|
||||
"Subkernel timed out"),
|
||||
SubkernelStatus::CommLost => raise!("SubkernelError",
|
||||
"Lost communication with satellite"),
|
||||
SubkernelStatus::OtherError => raise!("SubkernelError",
|
||||
"An error occurred during subkernel operation")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[unwind(aborts)]
|
||||
extern fn subkernel_send_message(id: u32, count: u8, tag: &CSlice<u8>, data: *const *const ()) {
|
||||
send(&SubkernelMsgSend {
|
||||
id: id,
|
||||
count: count,
|
||||
tag: tag.as_ref(),
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
#[unwind(allowed)]
|
||||
extern fn subkernel_await_message(id: u32, timeout: u64, min: u8, max: u8) -> u8 {
|
||||
send(&SubkernelMsgRecvRequest { id: id, timeout: timeout });
|
||||
recv!(SubkernelMsgRecvReply { status, count } => {
|
||||
match status {
|
||||
SubkernelStatus::NoError => {
|
||||
if count < &min || count > &max {
|
||||
raise!("SubkernelError",
|
||||
"Received less or more arguments than expected");
|
||||
}
|
||||
*count
|
||||
}
|
||||
SubkernelStatus::IncorrectState => raise!("SubkernelError",
|
||||
"Subkernel not running"),
|
||||
SubkernelStatus::Timeout => raise!("SubkernelError",
|
||||
"Subkernel timed out"),
|
||||
SubkernelStatus::CommLost => raise!("SubkernelError",
|
||||
"Lost communication with satellite"),
|
||||
SubkernelStatus::OtherError => raise!("SubkernelError",
|
||||
"An error occurred during subkernel operation")
|
||||
}
|
||||
})
|
||||
// RpcRecvRequest should be called `count` times after this to receive message data
|
||||
}
|
||||
|
||||
unsafe fn attribute_writeback(typeinfo: *const ()) {
|
||||
|
@ -10,6 +10,15 @@ pub const KERNELCPU_LAST_ADDRESS: usize = 0x4fffffff;
|
||||
// section in ksupport.elf.
|
||||
pub const KSUPPORT_HEADER_SIZE: usize = 0x74;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SubkernelStatus {
|
||||
NoError,
|
||||
Timeout,
|
||||
IncorrectState,
|
||||
CommLost,
|
||||
OtherError
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Message<'a> {
|
||||
LoadRequest(&'a [u8]),
|
||||
@ -94,6 +103,14 @@ pub enum Message<'a> {
|
||||
SpiReadReply { succeeded: bool, data: u32 },
|
||||
SpiBasicReply { succeeded: bool },
|
||||
|
||||
SubkernelLoadRunRequest { id: u32, run: bool },
|
||||
SubkernelLoadRunReply { succeeded: bool },
|
||||
SubkernelAwaitFinishRequest { id: u32, timeout: u64 },
|
||||
SubkernelAwaitFinishReply { status: SubkernelStatus },
|
||||
SubkernelMsgSend { id: u32, count: u8, tag: &'a [u8], data: *const *const () },
|
||||
SubkernelMsgRecvRequest { id: u32, timeout: u64 },
|
||||
SubkernelMsgRecvReply { status: SubkernelStatus, count: u8 },
|
||||
|
||||
Log(fmt::Arguments<'a>),
|
||||
LogSlice(&'a str)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user