Move TaskContext into TCB instead of kstack.

This commit is contained in:
Yifan Wu 2021-07-10 12:35:17 +08:00
parent f1aabb5e0e
commit 92b949a01f
6 changed files with 49 additions and 46 deletions

View file

@ -28,14 +28,10 @@ impl KernelStack {
fn get_sp(&self) -> usize { fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + KERNEL_STACK_SIZE self.data.as_ptr() as usize + KERNEL_STACK_SIZE
} }
pub fn push_context(&self, trap_cx: TrapContext, task_cx: TaskContext) -> &'static mut TaskContext { pub fn push_context(&self, trap_cx: TrapContext) -> usize {
unsafe { let trap_cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
let trap_cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext; unsafe { *trap_cx_ptr = trap_cx; }
*trap_cx_ptr = trap_cx; trap_cx_ptr as usize
let task_cx_ptr = (trap_cx_ptr as usize - core::mem::size_of::<TaskContext>()) as *mut TaskContext;
*task_cx_ptr = task_cx;
task_cx_ptr.as_mut().unwrap()
}
} }
} }
@ -81,9 +77,8 @@ pub fn load_apps() {
} }
} }
pub fn init_app_cx(app_id: usize) -> &'static TaskContext { pub fn init_app_cx(app_id: usize) -> usize {
KERNEL_STACK[app_id].push_context( KERNEL_STACK[app_id].push_context(
TrapContext::app_init_context(get_base_i(app_id), USER_STACK[app_id].get_sp()), TrapContext::app_init_context(get_base_i(app_id), USER_STACK[app_id].get_sp()),
TaskContext::goto_restore(),
) )
} }

View file

@ -1,14 +1,24 @@
#[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct TaskContext { pub struct TaskContext {
ra: usize, ra: usize,
sp: usize,
s: [usize; 12], s: [usize; 12],
} }
impl TaskContext { impl TaskContext {
pub fn goto_restore() -> Self { pub fn zero_init() -> Self {
Self {
ra: 0,
sp: 0,
s: [0; 12],
}
}
pub fn goto_restore(kstack_ptr: usize) -> Self {
extern "C" { fn __restore(); } extern "C" { fn __restore(); }
Self { Self {
ra: __restore as usize, ra: __restore as usize,
sp: kstack_ptr,
s: [0; 12], s: [0; 12],
} }
} }

View file

@ -25,11 +25,14 @@ lazy_static! {
pub static ref TASK_MANAGER: TaskManager = { pub static ref TASK_MANAGER: TaskManager = {
let num_app = get_num_app(); let num_app = get_num_app();
let mut tasks = [ let mut tasks = [
TaskControlBlock { task_cx_ptr: 0, task_status: TaskStatus::UnInit }; TaskControlBlock {
task_cx: TaskContext::zero_init(),
task_status: TaskStatus::UnInit
};
MAX_APP_NUM MAX_APP_NUM
]; ];
for i in 0..num_app { for i in 0..num_app {
tasks[i].task_cx_ptr = init_app_cx(i) as * const _ as usize; tasks[i].task_cx = TaskContext::goto_restore(init_app_cx(i));
tasks[i].task_status = TaskStatus::Ready; tasks[i].task_status = TaskStatus::Ready;
} }
TaskManager { TaskManager {
@ -46,12 +49,12 @@ impl TaskManager {
fn run_first_task(&self) { fn run_first_task(&self) {
let task0 = &mut self.inner.upsafe_access().tasks[0]; let task0 = &mut self.inner.upsafe_access().tasks[0];
task0.task_status = TaskStatus::Running; task0.task_status = TaskStatus::Running;
let next_task_cx_ptr2 = task0.get_task_cx_ptr2(); let next_task_cx_ptr = &task0.task_cx as *const TaskContext;
let _unused: usize = 0; let mut _unused = TaskContext::zero_init();
unsafe { unsafe {
__switch( __switch(
&_unused as *const _, &mut _unused as *mut TaskContext,
next_task_cx_ptr2, next_task_cx_ptr,
); );
} }
} }
@ -84,13 +87,13 @@ impl TaskManager {
let current = inner.current_task; let current = inner.current_task;
inner.tasks[next].task_status = TaskStatus::Running; inner.tasks[next].task_status = TaskStatus::Running;
inner.current_task = next; inner.current_task = next;
let current_task_cx_ptr2 = inner.tasks[current].get_task_cx_ptr2(); let current_task_cx_ptr = &mut inner.tasks[current].task_cx as *mut TaskContext;
let next_task_cx_ptr2 = inner.tasks[next].get_task_cx_ptr2(); let next_task_cx_ptr = &inner.tasks[next].task_cx as *const TaskContext;
core::mem::drop(inner); drop(inner);
unsafe { unsafe {
__switch( __switch(
current_task_cx_ptr2, current_task_cx_ptr,
next_task_cx_ptr2, next_task_cx_ptr,
); );
} }
} else { } else {

View file

@ -1,37 +1,34 @@
.altmacro .altmacro
.macro SAVE_SN n .macro SAVE_SN n
sd s\n, (\n+1)*8(sp) sd s\n, (\n+2)*8(a0)
.endm .endm
.macro LOAD_SN n .macro LOAD_SN n
ld s\n, (\n+1)*8(sp) ld s\n, (\n+2)*8(a1)
.endm .endm
.section .text .section .text
.globl __switch .globl __switch
__switch: __switch:
# __switch( # __switch(
# current_task_cx_ptr2: &*const TaskContext, # current_task_cx_ptr: *mut TaskContext,
# next_task_cx_ptr2: &*const TaskContext # next_task_cx_ptr: *const TaskContext
# ) # )
# push TaskContext to current sp and save its address to where a0 points to # save kernel stack of current task
addi sp, sp, -13*8 sd sp, 8(a0)
sd sp, 0(a0) # save ra & s0~s11 of current execution
# fill TaskContext with ra & s0-s11 sd ra, 0(a0)
sd ra, 0(sp)
.set n, 0 .set n, 0
.rept 12 .rept 12
SAVE_SN %n SAVE_SN %n
.set n, n + 1 .set n, n + 1
.endr .endr
# ready for loading TaskContext a1 points to # restore ra & s0~s11 of next execution
ld sp, 0(a1) ld ra, 0(a1)
# load registers in the TaskContext
ld ra, 0(sp)
.set n, 0 .set n, 0
.rept 12 .rept 12
LOAD_SN %n LOAD_SN %n
.set n, n + 1 .set n, n + 1
.endr .endr
# pop TaskContext # restore kernel stack of next task
addi sp, sp, 13*8 ld sp, 8(a1)
ret ret

View file

@ -1,8 +1,10 @@
global_asm!(include_str!("switch.S")); global_asm!(include_str!("switch.S"));
use super::TaskContext;
extern "C" { extern "C" {
pub fn __switch( pub fn __switch(
current_task_cx_ptr2: *const usize, current_task_cx_ptr: *mut TaskContext,
next_task_cx_ptr2: *const usize next_task_cx_ptr: *const TaskContext
); );
} }

View file

@ -1,13 +1,9 @@
use super::TaskContext;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct TaskControlBlock { pub struct TaskControlBlock {
pub task_cx_ptr: usize,
pub task_status: TaskStatus, pub task_status: TaskStatus,
} pub task_cx: TaskContext,
impl TaskControlBlock {
pub fn get_task_cx_ptr2(&self) -> *const usize {
&self.task_cx_ptr as *const usize
}
} }
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]