|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
use lazy_static::*;
|
|
|
|
|
use crate::trap::TrapContext;
|
|
|
|
|
use crate::sync::UPSafeCell;
|
|
|
|
|
use crate::trap::TrapContext;
|
|
|
|
|
use core::arch::asm;
|
|
|
|
|
use lazy_static::*;
|
|
|
|
|
|
|
|
|
|
const USER_STACK_SIZE: usize = 4096 * 2;
|
|
|
|
|
const KERNEL_STACK_SIZE: usize = 4096 * 2;
|
|
|
|
@ -19,8 +19,12 @@ struct UserStack {
|
|
|
|
|
data: [u8; USER_STACK_SIZE],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static KERNEL_STACK: KernelStack = KernelStack { data: [0; KERNEL_STACK_SIZE] };
|
|
|
|
|
static USER_STACK: UserStack = UserStack { data: [0; USER_STACK_SIZE] };
|
|
|
|
|
static KERNEL_STACK: KernelStack = KernelStack {
|
|
|
|
|
data: [0; KERNEL_STACK_SIZE],
|
|
|
|
|
};
|
|
|
|
|
static USER_STACK: UserStack = UserStack {
|
|
|
|
|
data: [0; USER_STACK_SIZE],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
impl KernelStack {
|
|
|
|
|
fn get_sp(&self) -> usize {
|
|
|
|
@ -28,7 +32,9 @@ impl KernelStack {
|
|
|
|
|
}
|
|
|
|
|
pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
|
|
|
|
|
let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
|
|
|
|
|
unsafe { *cx_ptr = cx; }
|
|
|
|
|
unsafe {
|
|
|
|
|
*cx_ptr = cx;
|
|
|
|
|
}
|
|
|
|
|
unsafe { cx_ptr.as_mut().unwrap() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -49,7 +55,12 @@ impl AppManager {
|
|
|
|
|
pub fn print_app_info(&self) {
|
|
|
|
|
println!("[kernel] num_app = {}", self.num_app);
|
|
|
|
|
for i in 0..self.num_app {
|
|
|
|
|
println!("[kernel] app_{} [{:#x}, {:#x})", i, self.app_start[i], self.app_start[i + 1]);
|
|
|
|
|
println!(
|
|
|
|
|
"[kernel] app_{} [{:#x}, {:#x})",
|
|
|
|
|
i,
|
|
|
|
|
self.app_start[i],
|
|
|
|
|
self.app_start[i + 1]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -61,22 +72,18 @@ impl AppManager {
|
|
|
|
|
// clear icache
|
|
|
|
|
asm!("fence.i");
|
|
|
|
|
// clear app area
|
|
|
|
|
core::slice::from_raw_parts_mut(
|
|
|
|
|
APP_BASE_ADDRESS as *mut u8,
|
|
|
|
|
APP_SIZE_LIMIT
|
|
|
|
|
).fill(0);
|
|
|
|
|
core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, APP_SIZE_LIMIT).fill(0);
|
|
|
|
|
let app_src = core::slice::from_raw_parts(
|
|
|
|
|
self.app_start[app_id] as *const u8,
|
|
|
|
|
self.app_start[app_id + 1] - self.app_start[app_id]
|
|
|
|
|
);
|
|
|
|
|
let app_dst = core::slice::from_raw_parts_mut(
|
|
|
|
|
APP_BASE_ADDRESS as *mut u8,
|
|
|
|
|
app_src.len()
|
|
|
|
|
self.app_start[app_id + 1] - self.app_start[app_id],
|
|
|
|
|
);
|
|
|
|
|
let app_dst = core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, app_src.len());
|
|
|
|
|
app_dst.copy_from_slice(app_src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_current_app(&self) -> usize { self.current_app }
|
|
|
|
|
pub fn get_current_app(&self) -> usize {
|
|
|
|
|
self.current_app
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn move_to_next_app(&mut self) {
|
|
|
|
|
self.current_app += 1;
|
|
|
|
@ -84,21 +91,24 @@ impl AppManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
|
static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe { UPSafeCell::new({
|
|
|
|
|
extern "C" { fn _num_app(); }
|
|
|
|
|
let num_app_ptr = _num_app as usize as *const usize;
|
|
|
|
|
let num_app = num_app_ptr.read_volatile();
|
|
|
|
|
let mut app_start: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1];
|
|
|
|
|
let app_start_raw: &[usize] = core::slice::from_raw_parts(
|
|
|
|
|
num_app_ptr.add(1), num_app + 1
|
|
|
|
|
);
|
|
|
|
|
app_start[..=num_app].copy_from_slice(app_start_raw);
|
|
|
|
|
AppManager {
|
|
|
|
|
num_app,
|
|
|
|
|
current_app: 0,
|
|
|
|
|
app_start,
|
|
|
|
|
}
|
|
|
|
|
})};
|
|
|
|
|
static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe {
|
|
|
|
|
UPSafeCell::new({
|
|
|
|
|
extern "C" {
|
|
|
|
|
fn _num_app();
|
|
|
|
|
}
|
|
|
|
|
let num_app_ptr = _num_app as usize as *const usize;
|
|
|
|
|
let num_app = num_app_ptr.read_volatile();
|
|
|
|
|
let mut app_start: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1];
|
|
|
|
|
let app_start_raw: &[usize] =
|
|
|
|
|
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1);
|
|
|
|
|
app_start[..=num_app].copy_from_slice(app_start_raw);
|
|
|
|
|
AppManager {
|
|
|
|
|
num_app,
|
|
|
|
|
current_app: 0,
|
|
|
|
|
app_start,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn init() {
|
|
|
|
@ -119,11 +129,14 @@ pub fn run_next_app() -> ! {
|
|
|
|
|
drop(app_manager);
|
|
|
|
|
// before this we have to drop local variables related to resources manually
|
|
|
|
|
// and release the resources
|
|
|
|
|
extern "C" { fn __restore(cx_addr: usize); }
|
|
|
|
|
extern "C" {
|
|
|
|
|
fn __restore(cx_addr: usize);
|
|
|
|
|
}
|
|
|
|
|
unsafe {
|
|
|
|
|
__restore(KERNEL_STACK.push_context(
|
|
|
|
|
TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp())
|
|
|
|
|
) as *const _ as usize);
|
|
|
|
|
__restore(KERNEL_STACK.push_context(TrapContext::app_init_context(
|
|
|
|
|
APP_BASE_ADDRESS,
|
|
|
|
|
USER_STACK.get_sp(),
|
|
|
|
|
)) as *const _ as usize);
|
|
|
|
|
}
|
|
|
|
|
panic!("Unreachable in batch::run_current_app!");
|
|
|
|
|
}
|
|
|
|
|