mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-07-15 15:01:45 +00:00
Unify DTCM and mem sections.
Move getting the return code and fault registers into Rust and out from the C driver. This means extending the DTCM to cover memory previously covered by `mem`. Change-Id: I9d1ad8e9823445ad7dd476ef05f128a29567999b GitOrigin-RevId: 21bc1ee544d39d6b4a2ff963aaae7c145fdd7fa9
This commit is contained in:
parent
3185f9f503
commit
39f9eac9c3
@ -8,7 +8,7 @@ component MlCoordinator {
|
|||||||
|
|
||||||
dataport Buf(0x300000) elf_file;
|
dataport Buf(0x300000) elf_file;
|
||||||
dataport Buf(0x40000) itcm;
|
dataport Buf(0x40000) itcm;
|
||||||
dataport Buf(0xfff000) dtcm;
|
dataport Buf(0x1000000) dtcm;
|
||||||
|
|
||||||
uses LoggerInterface logger;
|
uses LoggerInterface logger;
|
||||||
uses SecurityCoordinatorInterface security;
|
uses SecurityCoordinatorInterface security;
|
||||||
|
@ -11,19 +11,19 @@ const DTCM_SIZE: usize = 0x1000000;
|
|||||||
const DTCM_PADDR: usize = 0x34000000;
|
const DTCM_PADDR: usize = 0x34000000;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static elf_file: *const u8;
|
static elf_file: *const u32;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static itcm: *mut u8;
|
static itcm: *mut u32;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static dtcm: *mut u8;
|
static dtcm: *mut u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn loadelf() -> Result<(), &'static str> {
|
pub fn loadelf() -> Result<(), &'static str> {
|
||||||
let elf_slice = unsafe { slice::from_raw_parts(elf_file, ELF_SIZE) };
|
let elf_slice = unsafe { slice::from_raw_parts(elf_file as *const u8, ELF_SIZE) };
|
||||||
let itcm_slice = unsafe { slice::from_raw_parts_mut(itcm, ITCM_SIZE) };
|
let itcm_slice = unsafe { slice::from_raw_parts_mut(itcm as *mut u8, ITCM_SIZE) };
|
||||||
let dtcm_slice = unsafe { slice::from_raw_parts_mut(dtcm, DTCM_SIZE) };
|
let dtcm_slice = unsafe { slice::from_raw_parts_mut(dtcm as *mut u8, DTCM_SIZE) };
|
||||||
|
|
||||||
let elf = ElfFile::new(&elf_slice)?;
|
let elf = ElfFile::new(&elf_slice)?;
|
||||||
|
|
||||||
@ -47,10 +47,8 @@ pub fn loadelf() -> Result<(), &'static str> {
|
|||||||
itcm_slice[..fsize].copy_from_slice(&bytes);
|
itcm_slice[..fsize].copy_from_slice(&bytes);
|
||||||
}
|
}
|
||||||
} else if seg.virtual_addr() as usize == DTCM_PADDR {
|
} else if seg.virtual_addr() as usize == DTCM_PADDR {
|
||||||
// TODO(jesionowski): Change to msize. Will currently fail as a portion
|
|
||||||
// of the memory is mapped to the vctop driver for getting return information.
|
|
||||||
assert!(
|
assert!(
|
||||||
fsize <= DTCM_SIZE,
|
msize <= DTCM_SIZE,
|
||||||
"Elf's DTCM section is larger than than DTCM_SIZE"
|
"Elf's DTCM section is larger than than DTCM_SIZE"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -67,3 +65,18 @@ pub fn loadelf() -> Result<(), &'static str> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_dtcm_slice() -> &'static mut [u32] {
|
||||||
|
unsafe { slice::from_raw_parts_mut(dtcm, DTCM_SIZE / 4) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(jesionowski): Read these from CSRs when available.
|
||||||
|
pub fn get_return_code() -> u32 {
|
||||||
|
const RC_OFFSET: usize = 0x3FFFEE;
|
||||||
|
get_dtcm_slice()[RC_OFFSET]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_fault_register() -> u32 {
|
||||||
|
const FAULT_OFFSET: usize = 0x3FFFEF;
|
||||||
|
get_dtcm_slice()[FAULT_OFFSET]
|
||||||
|
}
|
||||||
|
@ -16,6 +16,22 @@ pub struct MLCoordinator {
|
|||||||
|
|
||||||
pub static mut ML_COORD: MLCoordinator = MLCoordinator { is_loaded: false };
|
pub static mut ML_COORD: MLCoordinator = MLCoordinator { is_loaded: false };
|
||||||
|
|
||||||
|
impl MLCoordinator {
|
||||||
|
fn handle_return_interrupt(&self) {
|
||||||
|
// TODO(hcindyl): check the return code and fault registers, move the result
|
||||||
|
// from TCM to SRAM, update the input/model, and call mlcoord_execute again.
|
||||||
|
let return_code = mlcore::get_return_code();
|
||||||
|
let fault = mlcore::get_fault_register();
|
||||||
|
|
||||||
|
if return_code != 0 {
|
||||||
|
error!(
|
||||||
|
"vctop execution failed with code {}, fault pc: {:#010X}",
|
||||||
|
return_code, fault
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MlCoordinatorInterface for MLCoordinator {
|
impl MlCoordinatorInterface for MLCoordinator {
|
||||||
fn execute(&mut self) {
|
fn execute(&mut self) {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -63,16 +79,14 @@ fn vctop_ctrl(freeze: u32, vc_reset: u32, pc_start: u32) -> u32 {
|
|||||||
// TODO: Once multiple model support is in start by name.
|
// TODO: Once multiple model support is in start by name.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn mlcoord_execute() {
|
pub extern "C" fn mlcoord_execute() {
|
||||||
unsafe { ML_COORD.execute() };
|
unsafe {
|
||||||
|
ML_COORD.execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn vctop_return_update_result(return_code: u32, fault: u32) {
|
pub extern "C" fn vctop_return_update_result() {
|
||||||
// TODO(hcindyl): check the return code and fault registers, move the result
|
unsafe {
|
||||||
// from TCM to SRAM, update the input/model, and call mlcoord_execute again.
|
ML_COORD.handle_return_interrupt();
|
||||||
trace!(
|
}
|
||||||
"vctop execution done with code {}, fault pc: {:#010X}",
|
|
||||||
return_code,
|
|
||||||
fault
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
component VectorCoreDriver {
|
component VectorCoreDriver {
|
||||||
dataport Buf csr;
|
dataport Buf csr;
|
||||||
dataport Buf mem;
|
|
||||||
consumes Interrupt host_req;
|
consumes Interrupt host_req;
|
||||||
consumes Interrupt finish;
|
consumes Interrupt finish;
|
||||||
consumes Interrupt instruction_fault;
|
consumes Interrupt instruction_fault;
|
||||||
|
@ -8,16 +8,6 @@
|
|||||||
#define VCTOP_REG(name) \
|
#define VCTOP_REG(name) \
|
||||||
*((volatile uint32_t *)(CSR_OFFSET + VC_TOP_##name##_REG_OFFSET))
|
*((volatile uint32_t *)(CSR_OFFSET + VC_TOP_##name##_REG_OFFSET))
|
||||||
|
|
||||||
static inline uint32_t get_return_code() {
|
|
||||||
const uint32_t kReturnCodeOffset = 0xfb8;
|
|
||||||
return *((volatile uint32_t *)((void *)mem + kReturnCodeOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_fault_register() {
|
|
||||||
const uint32_t kFaultRegOffset = 0xfbc;
|
|
||||||
return *((volatile uint32_t *)((void *)mem + kFaultRegOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
// CAmkES initialization hook.
|
// CAmkES initialization hook.
|
||||||
//
|
//
|
||||||
// Enables Interrupts.
|
// Enables Interrupts.
|
||||||
@ -42,7 +32,7 @@ void host_req_handle(void) {
|
|||||||
|
|
||||||
void finish_handle(void) {
|
void finish_handle(void) {
|
||||||
// Read main() return code and machine exception PC.
|
// Read main() return code and machine exception PC.
|
||||||
vctop_return_update_result(get_return_code(), get_fault_register());
|
vctop_return_update_result();
|
||||||
// Also need to clear the INTR_STATE (write-1-to-clear).
|
// Also need to clear the INTR_STATE (write-1-to-clear).
|
||||||
VCTOP_REG(INTR_STATE) = BIT(VC_TOP_INTR_STATE_FINISH_BIT);
|
VCTOP_REG(INTR_STATE) = BIT(VC_TOP_INTR_STATE_FINISH_BIT);
|
||||||
seL4_Assert(finish_acknowledge() == 0);
|
seL4_Assert(finish_acknowledge() == 0);
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
procedure VectorCoreReturnInterface {
|
procedure VectorCoreReturnInterface {
|
||||||
void update_result(in uint32_t return_code, in uint32_t fault);
|
void update_result();
|
||||||
};
|
};
|
||||||
|
@ -35,9 +35,8 @@ component OpenTitanUART {
|
|||||||
component VectorCoreHw {
|
component VectorCoreHw {
|
||||||
hardware;
|
hardware;
|
||||||
dataport Buf csr;
|
dataport Buf csr;
|
||||||
dataport Buf mem;
|
|
||||||
dataport Buf(0x40000) itcm;
|
dataport Buf(0x40000) itcm;
|
||||||
dataport Buf(0xfff000) dtcm;
|
dataport Buf(0x1000000) dtcm;
|
||||||
|
|
||||||
emits Interrupt host_req;
|
emits Interrupt host_req;
|
||||||
emits Interrupt finish;
|
emits Interrupt finish;
|
||||||
@ -77,7 +76,6 @@ assembly {
|
|||||||
|
|
||||||
// VectorCoreDriver
|
// VectorCoreDriver
|
||||||
connection seL4HardwareMMIO vc_csr(from vc_drv.csr, to vctop.csr);
|
connection seL4HardwareMMIO vc_csr(from vc_drv.csr, to vctop.csr);
|
||||||
connection seL4HardwareMMIO vc_mem(from vc_drv.mem, to vctop.mem);
|
|
||||||
connection seL4RPCCall ml_coord_to_driver(from ml_coordinator.vctop,
|
connection seL4RPCCall ml_coord_to_driver(from ml_coordinator.vctop,
|
||||||
to vc_drv.vctop);
|
to vc_drv.vctop);
|
||||||
connection seL4RPCCall vc_driver_to_ml_coord(from vc_drv.vctop_return,
|
connection seL4RPCCall vc_driver_to_ml_coord(from vc_drv.vctop_return,
|
||||||
@ -148,13 +146,10 @@ assembly {
|
|||||||
|
|
||||||
vctop.csr_paddr = 0x48000000;
|
vctop.csr_paddr = 0x48000000;
|
||||||
vctop.csr_size = 0x1000;
|
vctop.csr_size = 0x1000;
|
||||||
// TODO(jesionowski): Merge mem and dtcm
|
|
||||||
vctop.mem_paddr = 0x34fff000;
|
|
||||||
vctop.mem_size = 0x1000;
|
|
||||||
vctop.itcm_paddr = 0x30000000;
|
vctop.itcm_paddr = 0x30000000;
|
||||||
vctop.itcm_size = 0x40000;
|
vctop.itcm_size = 0x40000;
|
||||||
vctop.dtcm_paddr = 0x34000000;
|
vctop.dtcm_paddr = 0x34000000;
|
||||||
vctop.dtcm_size = 0xfff000;
|
vctop.dtcm_size = 0x1000000;
|
||||||
vctop.host_req_irq_number = 179;
|
vctop.host_req_irq_number = 179;
|
||||||
vctop.finish_irq_number = 180;
|
vctop.finish_irq_number = 180;
|
||||||
vctop.instruction_fault_irq_number = 181;
|
vctop.instruction_fault_irq_number = 181;
|
||||||
|
Loading…
Reference in New Issue
Block a user