forked from M-Labs/artiq
support .tar flashed idle/startup kernels
This commit is contained in:
parent
875666f3ec
commit
de10e584f6
|
@ -13,6 +13,12 @@ dependencies = [
|
||||||
name = "alloc_list"
|
name = "alloc_list"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bare-metal"
|
name = "bare-metal"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
@ -332,6 +338,7 @@ dependencies = [
|
||||||
"proto_artiq",
|
"proto_artiq",
|
||||||
"riscv",
|
"riscv",
|
||||||
"smoltcp",
|
"smoltcp",
|
||||||
|
"tar-no-std",
|
||||||
"unwind_backtrace",
|
"unwind_backtrace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -416,6 +423,16 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tar-no-std"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "git+https://git.m-labs.hk/M-Labs/tar-no-std?rev=2ab6dc5#2ab6dc58e5249c59c4eb03eaf3a119bcdd678d32"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.0.4"
|
version = "0.0.4"
|
||||||
|
|
|
@ -40,3 +40,7 @@ git = "https://git.m-labs.hk/M-Labs/libfringe.git"
|
||||||
rev = "3ecbe5"
|
rev = "3ecbe5"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["alloc"]
|
features = ["alloc"]
|
||||||
|
|
||||||
|
[dependencies.tar-no-std]
|
||||||
|
git = "https://git.m-labs.hk/M-Labs/tar-no-std"
|
||||||
|
rev = "2ab6dc5"
|
||||||
|
|
|
@ -25,6 +25,8 @@ extern crate board_artiq;
|
||||||
extern crate logger_artiq;
|
extern crate logger_artiq;
|
||||||
extern crate proto_artiq;
|
extern crate proto_artiq;
|
||||||
extern crate riscv;
|
extern crate riscv;
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
extern crate tar_no_std;
|
||||||
|
|
||||||
use alloc::collections::BTreeMap;
|
use alloc::collections::BTreeMap;
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
|
@ -2,7 +2,10 @@ use core::{mem, str, cell::{Cell, RefCell}, fmt::Write as FmtWrite};
|
||||||
use alloc::{vec::Vec, string::{String, ToString}};
|
use alloc::{vec::Vec, string::{String, ToString}};
|
||||||
use byteorder::{ByteOrder, NativeEndian};
|
use byteorder::{ByteOrder, NativeEndian};
|
||||||
use cslice::CSlice;
|
use cslice::CSlice;
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
use tar_no_std::TarArchiveRef;
|
||||||
|
|
||||||
|
use dyld::elf;
|
||||||
use io::{Read, Write, Error as IoError};
|
use io::{Read, Write, Error as IoError};
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use io::Cursor;
|
use io::Cursor;
|
||||||
|
@ -45,6 +48,9 @@ pub enum Error<T> {
|
||||||
#[fail(display = "DDMA error: {}", _0)]
|
#[fail(display = "DDMA error: {}", _0)]
|
||||||
Ddma(#[cause] remote_dma::Error),
|
Ddma(#[cause] remote_dma::Error),
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
#[fail(display = "subkernel destination is down")]
|
||||||
|
DestinationDown,
|
||||||
|
#[cfg(has_drtio)]
|
||||||
#[fail(display = "subkernel error: {}", _0)]
|
#[fail(display = "subkernel error: {}", _0)]
|
||||||
Subkernel(#[cause] SubkernelError),
|
Subkernel(#[cause] SubkernelError),
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
@ -309,6 +315,63 @@ fn kern_run(session: &mut Session) -> Result<(), Error<SchedError>> {
|
||||||
kern_acknowledge()
|
kern_acknowledge()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn process_flash_kernel(io: &Io, _aux_mutex: &Mutex, _subkernel_mutex: &Mutex,
|
||||||
|
_routing_table: &drtio_routing::RoutingTable,
|
||||||
|
_up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
|
session: &mut Session, kernel: &[u8]
|
||||||
|
) -> Result<(), Error<SchedError>> {
|
||||||
|
// handle ELF and TAR files
|
||||||
|
if kernel[0] == elf::ELFMAG0 && kernel[1] == elf::ELFMAG1 &&
|
||||||
|
kernel[2] == elf::ELFMAG2 && kernel[3] == elf::ELFMAG3 {
|
||||||
|
// assume ELF file, proceed as before
|
||||||
|
unsafe {
|
||||||
|
// make a copy as kernel CPU cannot read SPI directly
|
||||||
|
kern_load(io, session, Vec::from(kernel).as_ref())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
{
|
||||||
|
let archive = TarArchiveRef::new(kernel);
|
||||||
|
let entries = archive.entries();
|
||||||
|
let mut main_lib: Option<&[u8]> = None;
|
||||||
|
for entry in entries {
|
||||||
|
if entry.filename().as_str() == "main.elf" {
|
||||||
|
main_lib = Some(entry.data());
|
||||||
|
} else {
|
||||||
|
// subkernel filename must be in format:
|
||||||
|
// "<subkernel id> <destination>.elf"
|
||||||
|
let filename = entry.filename();
|
||||||
|
let mut iter = filename.as_str().split_whitespace();
|
||||||
|
let sid: u32 = iter.next().unwrap()
|
||||||
|
.parse().unwrap();
|
||||||
|
let dest: u8 = iter.next().unwrap()
|
||||||
|
.strip_suffix(".elf").unwrap()
|
||||||
|
.parse().unwrap();
|
||||||
|
let up = {
|
||||||
|
let up_destinations = _up_destinations.borrow();
|
||||||
|
up_destinations[dest as usize]
|
||||||
|
};
|
||||||
|
if up {
|
||||||
|
let subkernel_lib = entry.data().to_vec();
|
||||||
|
subkernel::add_subkernel(io, _subkernel_mutex, sid, dest, subkernel_lib)?;
|
||||||
|
subkernel::upload(io, _aux_mutex, _subkernel_mutex, _routing_table, sid)?;
|
||||||
|
} else {
|
||||||
|
return Err(Error::DestinationDown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
kern_load(io, session, Vec::from(main_lib.unwrap()).as_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(has_drtio))]
|
||||||
|
{
|
||||||
|
unexpected!("multi-kernel libraries are not supported in standalone systems")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn process_host_message(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _subkernel_mutex: &Mutex,
|
fn process_host_message(io: &Io, _aux_mutex: &Mutex, _ddma_mutex: &Mutex, _subkernel_mutex: &Mutex,
|
||||||
_routing_table: &drtio_routing::RoutingTable, stream: &mut TcpStream,
|
_routing_table: &drtio_routing::RoutingTable, stream: &mut TcpStream,
|
||||||
session: &mut Session) -> Result<(), Error<SchedError>> {
|
session: &mut Session) -> Result<(), Error<SchedError>> {
|
||||||
|
@ -777,11 +840,17 @@ fn flash_kernel_worker(io: &Io, aux_mutex: &Mutex,
|
||||||
|
|
||||||
config::read(config_key, |result| {
|
config::read(config_key, |result| {
|
||||||
match result {
|
match result {
|
||||||
Ok(kernel) => unsafe {
|
Ok(kernel) => {
|
||||||
// kernel CPU cannot access the SPI flash address space directly,
|
// process .ELF or .TAR kernels
|
||||||
// so make a copy.
|
let res = process_flash_kernel(io, aux_mutex, subkernel_mutex, routing_table, up_destinations, &mut session, kernel);
|
||||||
kern_load(io, &mut session, Vec::from(kernel).as_ref())
|
#[cfg(has_drtio)]
|
||||||
},
|
match res {
|
||||||
|
// wait to establish the DRTIO connection
|
||||||
|
Err(Error::DestinationDown) => io.sleep(500)?,
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
_ => Err(Error::KernelNotFound)
|
_ => Err(Error::KernelNotFound)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -249,6 +249,7 @@
|
||||||
lockFile = ./artiq/firmware/Cargo.lock;
|
lockFile = ./artiq/firmware/Cargo.lock;
|
||||||
outputHashes = {
|
outputHashes = {
|
||||||
"fringe-1.2.1" = "sha256-m4rzttWXRlwx53LWYpaKuU5AZe4GSkbjHS6oINt5d3Y=";
|
"fringe-1.2.1" = "sha256-m4rzttWXRlwx53LWYpaKuU5AZe4GSkbjHS6oINt5d3Y=";
|
||||||
|
"tar-no-std-0.1.8" = "sha256-xm17108v4smXOqxdLvHl9CxTCJslmeogjm4Y87IXFuM=";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
Loading…
Reference in New Issue