mirror of https://github.com/m-labs/artiq.git
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":
|
if not soc.config["DRTIO_ROLE"] == "satellite":
|
||||||
builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime"))
|
builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime"))
|
||||||
else:
|
else:
|
||||||
# Assume DRTIO satellite.
|
|
||||||
builder.add_software_package("satman", os.path.join(firmware_dir, "satman"))
|
builder.add_software_package("satman", os.path.join(firmware_dir, "satman"))
|
||||||
try:
|
try:
|
||||||
builder.build()
|
builder.build()
|
||||||
|
|
|
@ -157,6 +157,11 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
||||||
api!(dma_retrieve = ::dma_retrieve),
|
api!(dma_retrieve = ::dma_retrieve),
|
||||||
api!(dma_playback = ::dma_playback),
|
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_start = ::nrt_bus::i2c::start),
|
||||||
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
||||||
api!(i2c_stop = ::nrt_bus::i2c::stop),
|
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),
|
("RuntimeError", 0),
|
||||||
("RTIOUnderflow", 1),
|
("RTIOUnderflow", 1),
|
||||||
("RTIOOverflow", 2),
|
("RTIOOverflow", 2),
|
||||||
|
@ -345,6 +345,7 @@ static EXCEPTION_ID_LOOKUP: [(&str, u32); 11] = [
|
||||||
("ZeroDivisionError", 8),
|
("ZeroDivisionError", 8),
|
||||||
("IndexError", 9),
|
("IndexError", 9),
|
||||||
("UnwrapNoneError", 10),
|
("UnwrapNoneError", 10),
|
||||||
|
("SubkernelError", 11)
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn get_exception_id(name: &str) -> u32 {
|
pub fn get_exception_id(name: &str) -> u32 {
|
||||||
|
|
|
@ -21,7 +21,6 @@ use dyld::Library;
|
||||||
use board_artiq::{mailbox, rpc_queue};
|
use board_artiq::{mailbox, rpc_queue};
|
||||||
use proto_artiq::{kernel_proto, rpc_proto};
|
use proto_artiq::{kernel_proto, rpc_proto};
|
||||||
use kernel_proto::*;
|
use kernel_proto::*;
|
||||||
#[cfg(has_rtio_dma)]
|
|
||||||
use board_misoc::csr;
|
use board_misoc::csr;
|
||||||
use riscv::register::{mcause, mepc, mtval};
|
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)]
|
#[unwind(allowed)]
|
||||||
extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) {
|
extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) {
|
||||||
assert!(ptr % 64 == 0);
|
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)]
|
#[unwind(allowed)]
|
||||||
extern fn dma_playback(_timestamp: i64, _ptr: i32, _uses_ddma: bool) {
|
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 ()) {
|
unsafe fn attribute_writeback(typeinfo: *const ()) {
|
||||||
|
|
|
@ -10,6 +10,15 @@ pub const KERNELCPU_LAST_ADDRESS: usize = 0x4fffffff;
|
||||||
// section in ksupport.elf.
|
// section in ksupport.elf.
|
||||||
pub const KSUPPORT_HEADER_SIZE: usize = 0x74;
|
pub const KSUPPORT_HEADER_SIZE: usize = 0x74;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum SubkernelStatus {
|
||||||
|
NoError,
|
||||||
|
Timeout,
|
||||||
|
IncorrectState,
|
||||||
|
CommLost,
|
||||||
|
OtherError
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Message<'a> {
|
pub enum Message<'a> {
|
||||||
LoadRequest(&'a [u8]),
|
LoadRequest(&'a [u8]),
|
||||||
|
@ -94,6 +103,14 @@ pub enum Message<'a> {
|
||||||
SpiReadReply { succeeded: bool, data: u32 },
|
SpiReadReply { succeeded: bool, data: u32 },
|
||||||
SpiBasicReply { succeeded: bool },
|
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>),
|
Log(fmt::Arguments<'a>),
|
||||||
LogSlice(&'a str)
|
LogSlice(&'a str)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue