forked from M-Labs/artiq-zynq
kernel: refactor main_core1 into KernelImage
This commit is contained in:
parent
b3d4590eec
commit
2c1773b91b
@ -1,11 +1,12 @@
|
|||||||
//! Kernel prologue/epilogue that runs on the 2nd CPU core
|
//! Kernel prologue/epilogue that runs on the 2nd CPU core
|
||||||
|
|
||||||
use core::{ptr, mem};
|
use core::{mem, ptr};
|
||||||
|
use alloc::borrow::ToOwned;
|
||||||
use log::{debug, info, error};
|
use log::{debug, info, error};
|
||||||
use cslice::CSlice;
|
use cslice::CSlice;
|
||||||
|
|
||||||
use libcortex_a9::{enable_fpu, cache::dcci_slice, sync_channel};
|
use libcortex_a9::{enable_fpu, cache::dcci_slice, sync_channel};
|
||||||
use dyld;
|
use dyld::{self, Library};
|
||||||
use crate::eh_artiq;
|
use crate::eh_artiq;
|
||||||
use super::{
|
use super::{
|
||||||
api::resolve,
|
api::resolve,
|
||||||
@ -56,7 +57,50 @@ unsafe fn attribute_writeback(typeinfo: *const ()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct KernelImage {
|
||||||
|
library: Library,
|
||||||
|
__modinit__: u32,
|
||||||
|
typeinfo: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KernelImage {
|
||||||
|
pub fn new(library: Library) -> Result<Self, dyld::Error> {
|
||||||
|
let __modinit__ = library.lookup(b"__modinit__")
|
||||||
|
.ok_or(dyld::Error::Lookup("__modinit__".to_owned()))?;
|
||||||
|
let typeinfo = library.lookup(b"typeinfo");
|
||||||
|
|
||||||
|
// clear .bss
|
||||||
|
let bss_start = library.lookup(b"__bss_start");
|
||||||
|
let end = library.lookup(b"_end");
|
||||||
|
if let Some(bss_start) = bss_start {
|
||||||
|
let end = end
|
||||||
|
.ok_or(dyld::Error::Lookup("_end".to_owned()))?;
|
||||||
|
unsafe {
|
||||||
|
ptr::write_bytes(bss_start as *mut u8, 0, (end - bss_start) as usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(KernelImage {
|
||||||
|
library,
|
||||||
|
__modinit__,
|
||||||
|
typeinfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn exec(&mut self) {
|
||||||
|
// Flush data cache entries for the image in DDR, including
|
||||||
|
// Memory/Instruction Symchronization Barriers
|
||||||
|
dcci_slice(self.library.image.data);
|
||||||
|
|
||||||
|
(mem::transmute::<u32, fn()>(self.__modinit__))();
|
||||||
|
|
||||||
|
if let Some(typeinfo) = self.typeinfo {
|
||||||
|
attribute_writeback(typeinfo as *const ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn main_core1() {
|
pub fn main_core1() {
|
||||||
debug!("Core1 started");
|
debug!("Core1 started");
|
||||||
@ -76,36 +120,22 @@ pub fn main_core1() {
|
|||||||
}
|
}
|
||||||
let mut core1_rx = core1_rx.unwrap();
|
let mut core1_rx = core1_rx.unwrap();
|
||||||
|
|
||||||
let mut current_modinit: Option<u32> = None;
|
// set on load, cleared on start
|
||||||
let mut current_typeinfo: Option<u32> = None;
|
let mut loaded_kernel = None;
|
||||||
let mut library_handle: Option<dyld::Library> = None;
|
|
||||||
loop {
|
loop {
|
||||||
let message = core1_rx.recv();
|
let message = core1_rx.recv();
|
||||||
match *message {
|
match *message {
|
||||||
Message::LoadRequest(data) => {
|
Message::LoadRequest(data) => {
|
||||||
match dyld::load(&data, &resolve) {
|
let result = dyld::load(&data, &resolve)
|
||||||
Ok(library) => {
|
.and_then(KernelImage::new);
|
||||||
|
match result {
|
||||||
|
Ok(kernel) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
KERNEL_LOAD_ADDR = library.image.as_ptr() as usize;
|
KERNEL_LOAD_ADDR = kernel.library.image.as_ptr() as usize;
|
||||||
}
|
}
|
||||||
let bss_start = library.lookup(b"__bss_start");
|
loaded_kernel = Some(kernel);
|
||||||
let end = library.lookup(b"_end");
|
|
||||||
if let Some(bss_start) = bss_start {
|
|
||||||
let end = end.unwrap();
|
|
||||||
unsafe {
|
|
||||||
ptr::write_bytes(bss_start as *mut u8, 0, (end - bss_start) as usize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let __modinit__ = library.lookup(b"__modinit__").unwrap();
|
|
||||||
current_modinit = Some(__modinit__);
|
|
||||||
current_typeinfo = library.lookup(b"typeinfo");
|
|
||||||
debug!("kernel loaded");
|
debug!("kernel loaded");
|
||||||
// Flush data cache entries for the image in DDR, including
|
|
||||||
// Memory/Instruction Symchronization Barriers
|
|
||||||
dcci_slice(library.image.data);
|
|
||||||
|
|
||||||
core1_tx.send(Message::LoadCompleted);
|
core1_tx.send(Message::LoadCompleted);
|
||||||
library_handle = Some(library);
|
|
||||||
},
|
},
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
error!("failed to load shared library: {}", error);
|
error!("failed to load shared library: {}", error);
|
||||||
@ -115,19 +145,15 @@ pub fn main_core1() {
|
|||||||
},
|
},
|
||||||
Message::StartRequest => {
|
Message::StartRequest => {
|
||||||
info!("kernel starting");
|
info!("kernel starting");
|
||||||
if let Some(__modinit__) = current_modinit {
|
if let Some(mut kernel) = loaded_kernel.take() {
|
||||||
unsafe {
|
unsafe {
|
||||||
KERNEL_CHANNEL_0TO1 = mem::transmute(&mut core1_rx);
|
KERNEL_CHANNEL_0TO1 = mem::transmute(&mut core1_rx);
|
||||||
KERNEL_CHANNEL_1TO0 = mem::transmute(&mut core1_tx);
|
KERNEL_CHANNEL_1TO0 = mem::transmute(&mut core1_tx);
|
||||||
(mem::transmute::<u32, fn()>(__modinit__))();
|
kernel.exec();
|
||||||
if let Some(typeinfo) = current_typeinfo {
|
|
||||||
attribute_writeback(typeinfo as *const ());
|
|
||||||
}
|
|
||||||
KERNEL_CHANNEL_0TO1 = ptr::null_mut();
|
KERNEL_CHANNEL_0TO1 = ptr::null_mut();
|
||||||
KERNEL_CHANNEL_1TO0 = ptr::null_mut();
|
KERNEL_CHANNEL_1TO0 = ptr::null_mut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
library_handle = None;
|
|
||||||
info!("kernel finished");
|
info!("kernel finished");
|
||||||
core1_tx.send(Message::KernelFinished);
|
core1_tx.send(Message::KernelFinished);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user