rsp -> Context.

master
WangRunji 7 years ago
parent 37d2497de3
commit b715cecf8d

@ -63,7 +63,7 @@ impl TrapFrame {
#[derive(Debug, Default)]
#[repr(C)]
struct Context {
struct ContextData {
r15: usize,
r14: usize,
r13: usize,
@ -73,9 +73,9 @@ struct Context {
rip: usize,
}
impl Context {
impl ContextData {
fn new() -> Self {
let mut context = Context::default();
let mut context = ContextData::default();
context.rip = forkret as usize;
context
}
@ -85,7 +85,7 @@ impl Context {
#[derive(Debug)]
#[repr(C)]
pub struct InitStack {
context: Context,
context: ContextData,
trapret: usize,
tf: TrapFrame,
}
@ -93,21 +93,21 @@ pub struct InitStack {
impl InitStack {
pub fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, rsp: usize) -> Self {
InitStack {
context: Context::new(),
context: ContextData::new(),
trapret: trap_ret as usize,
tf: TrapFrame::new_kernel_thread(entry, arg, rsp),
}
}
pub fn new_user_thread(entry_addr: usize, rsp: usize, is32: bool) -> Self {
InitStack {
context: Context::new(),
context: ContextData::new(),
trapret: trap_ret as usize,
tf: TrapFrame::new_user_thread(entry_addr, rsp, is32),
}
}
pub fn new_fork(tf: &TrapFrame) -> Self {
InitStack {
context: Context::new(),
context: ContextData::new(),
trapret: trap_ret as usize,
tf: {
let mut tf = tf.clone();
@ -116,6 +116,11 @@ impl InitStack {
},
}
}
pub unsafe fn push_at(self, stack_top: usize) -> Context {
let ptr = (stack_top as *mut Self).offset(-1);
*ptr = self;
Context(ptr as usize)
}
}
extern {
@ -128,41 +133,50 @@ extern fn forkret() {
// Will return to `trapret`
}
/// Switch to another kernel thread.
///
/// Defined in `trap.asm`.
///
/// Push all callee-saved registers at the current kernel stack.
/// Store current rsp at `from_rsp`. Switch kernel stack to `to_rsp`.
/// Pop all callee-saved registers, then return to the target.
#[naked]
#[inline(never)]
pub unsafe extern fn switch(from_rsp: &mut usize, to_rsp: usize) {
asm!(
"
// push rip (by caller)
// Save old callee-save registers
push rbx
push rbp
push r12
push r13
push r14
push r15
// Switch stacks
mov [rdi], rsp // rdi = from_rsp
mov rsp, rsi // rsi = to_rsp
// Save old callee-save registers
pop r15
pop r14
pop r13
pop r12
pop rbp
pop rbx
// pop rip
ret"
: : : : "intel" "volatile" )
#[derive(Debug)]
pub struct Context(usize);
impl Context {
/// Switch to another kernel thread.
///
/// Defined in `trap.asm`.
///
/// Push all callee-saved registers at the current kernel stack.
/// Store current rsp, switch to target.
/// Pop all callee-saved registers, then return to the target.
#[naked]
#[inline(never)]
pub unsafe extern fn switch(&mut self, target: &mut Self) {
asm!(
"
// push rip (by caller)
// Save old callee-save registers
push rbx
push rbp
push r12
push r13
push r14
push r15
// Switch stacks
mov [rdi], rsp // rdi = from_rsp
mov rsp, [rsi] // rsi = to_rsp
// Save old callee-save registers
pop r15
pop r14
pop r13
pop r12
pop rbp
pop rbx
// pop rip
ret"
: : : : "intel" "volatile" )
}
pub unsafe fn null() -> Self {
Context(0)
}
}

@ -10,11 +10,11 @@ pub struct Process {
pub(in process) pid: Pid,
pub(in process) parent: Pid,
pub(in process) name: String,
kstack: Stack,
kstack: Stack,
pub(in process) memory_set: Option<MemorySet>,
pub(in process) page_table: Option<InactivePageTable>,
pub(in process) status: Status,
pub(in process) rsp: usize,
pub(in process) context: Context,
pub(in process) is_user: bool,
}
@ -35,7 +35,7 @@ impl Process {
pub fn new(name: &str, entry: extern fn(usize) -> !, arg: usize, mc: &mut MemoryController) -> Self {
let kstack = mc.alloc_stack(7).unwrap();
let data = InitStack::new_kernel_thread(entry, arg, kstack.top());
let rsp = kstack.push_at_top(data);
let context = unsafe { data.push_at(kstack.top()) };
Process {
pid: 0,
@ -45,7 +45,7 @@ impl Process {
memory_set: None,
page_table: None,
status: Status::Ready,
rsp,
context,
is_user: false,
}
}
@ -62,7 +62,7 @@ impl Process {
memory_set: None,
page_table: None,
status: Status::Running,
rsp: 0, // will be set at first schedule
context: unsafe { Context::null() }, // will be set at first schedule
is_user: false,
}
}
@ -120,9 +120,8 @@ impl Process {
// Allocate kernel stack and push trap frame
let kstack = mc.alloc_stack(7).unwrap();
let tf = InitStack::new_user_thread(entry_addr, user_stack_top - 8, is32);
let rsp = kstack.push_at_top(tf);
trace!("rsp = {:#x}", rsp);
let data = InitStack::new_user_thread(entry_addr, user_stack_top - 8, is32);
let context = unsafe { data.push_at(kstack.top()) };
Process {
pid: 0,
@ -132,7 +131,7 @@ impl Process {
memory_set: Some(memory_set),
page_table: Some(page_table),
status: Status::Ready,
rsp,
context,
is_user: true,
}
}
@ -161,7 +160,7 @@ impl Process {
// Allocate kernel stack and push trap frame
let kstack = mc.alloc_stack(7).unwrap();
let data = InitStack::new_fork(tf);
let rsp = kstack.push_at_top(data);
let context = unsafe { data.push_at(kstack.top()) };
Process {
pid: 0,
@ -171,7 +170,7 @@ impl Process {
memory_set: Some(memory_set),
page_table: Some(page_table),
status: Status::Ready,
rsp,
context,
is_user: true,
}
}

@ -153,12 +153,12 @@ impl Processor {
*from_pt = Some(old_table);
}
info!("switch from {} to {}\n rsp: ??? -> {:#x}", pid0, pid, to.rsp);
info!("switch from {} to {}\n rsp: ??? -> {:?}", pid0, pid, to.context);
unsafe {
// FIXME: safely pass MutexGuard
use core::mem::forget;
super::PROCESSOR.try().unwrap().force_unlock();
switch(&mut from.rsp, to.rsp);
from.context.switch(&mut to.context);
forget(super::PROCESSOR.try().unwrap().lock());
}
}

Loading…
Cancel
Save