diff --git a/arch/x86_64/src/context.rs b/arch/x86_64/src/context.rs index 8818118..cbfde75 100644 --- a/arch/x86_64/src/context.rs +++ b/arch/x86_64/src/context.rs @@ -1,26 +1,36 @@ +#[derive(Debug)] pub struct Context { - flags: usize, - bx: usize, + /// RFLAGS register + rflags: usize, + /// RBX register + rbx: usize, + /// R12 register r12: usize, + /// R13 register r13: usize, + /// R14 register r14: usize, + /// R15 register r15: usize, - bp: usize, - sp: usize, + /// Base pointer + rbp: usize, + /// Stack pointer + rsp: usize, + /// Page table pointer cr3: usize } impl Context { pub fn new() -> Context { Context { - flags: 0, - bx: 0, + rflags: 0, + rbx: 0, r12: 0, r13: 0, r14: 0, r15: 0, - bp: 0, - sp: 0, + rbp: 0, + rsp: 0, cr3: 0 } } @@ -40,11 +50,11 @@ impl Context { } */ - asm!("pushfq ; pop $0" : "=r"(self.flags) : : "memory" : "intel", "volatile"); - asm!("push $0 ; popfq" : : "r"(next.flags) : "memory" : "intel", "volatile"); + asm!("pushfq ; pop $0" : "=r"(self.rflags) : : "memory" : "intel", "volatile"); + asm!("push $0 ; popfq" : : "r"(next.rflags) : "memory" : "intel", "volatile"); - asm!("mov $0, rbx" : "=r"(self.bx) : : "memory" : "intel", "volatile"); - asm!("mov rbx, $0" : : "r"(next.bx) : "memory" : "intel", "volatile"); + asm!("mov $0, rbx" : "=r"(self.rbx) : : "memory" : "intel", "volatile"); + asm!("mov rbx, $0" : : "r"(next.rbx) : "memory" : "intel", "volatile"); asm!("mov $0, r12" : "=r"(self.r12) : : "memory" : "intel", "volatile"); asm!("mov r12, $0" : : "r"(next.r12) : "memory" : "intel", "volatile"); @@ -58,11 +68,11 @@ impl Context { asm!("mov $0, r15" : "=r"(self.r15) : : "memory" : "intel", "volatile"); asm!("mov r15, $0" : : "r"(next.r15) : "memory" : "intel", "volatile"); - asm!("mov $0, rbp" : "=r"(self.bp) : : "memory" : "intel", "volatile"); - asm!("mov rbp, $0" : : "r"(next.bp) : "memory" : "intel", "volatile"); + asm!("mov $0, rbp" : "=r"(self.rbp) : : "memory" : "intel", "volatile"); + asm!("mov rbp, $0" : : "r"(next.rbp) : "memory" : "intel", "volatile"); - asm!("mov $0, rsp" : "=r"(self.sp) : : "memory" : "intel", "volatile"); - asm!("mov rsp, $0" : : "r"(next.sp) : "memory" : "intel", "volatile"); + asm!("mov $0, rsp" : "=r"(self.rsp) : : "memory" : "intel", "volatile"); + asm!("mov rsp, $0" : : "r"(next.rsp) : "memory" : "intel", "volatile"); /* TODO asm!("mov $0, cr3" : "=r"(self.cr3) : : "memory" : "intel", "volatile"); diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index 30feb93..42ff8ba 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -4,6 +4,7 @@ use collections::{BTreeMap, Vec}; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; +use arch::context::Context as ArchContext; use syscall::{Error, Result}; /// File operations @@ -55,6 +56,15 @@ impl ContextList { assert!(self.map.insert(id, RwLock::new(Context::new(id))).is_none()); Ok(self.map.get(&id).expect("failed to insert new context")) } + + pub fn spawn(&mut self, func: extern fn()) -> Result<&RwLock> { + let context_lock = self.new_context()?; + { + let mut context = context_lock.write(); + print!("{}", format!("{}: {:X}\n", context.id, func as usize)); + } + Ok(context_lock) + } } /// Contexts list @@ -85,19 +95,31 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> { CONTEXTS.call_once(init_contexts).write() } +/// Switch to the next context +/// Do not call this while holding locks! +pub unsafe fn context_switch() { + + + current.arch.switch_to(&mut next.arch); +} + /// A context, which identifies either a process or a thread #[derive(Debug)] pub struct Context { /// The ID of this context pub id: usize, + /// The architecture specific context + pub arch: ArchContext, /// The open files in the scheme pub files: Vec> } impl Context { + /// Create a new context pub fn new(id: usize) -> Context { Context { id: id, + arch: ArchContext::new(), files: Vec::new() } } diff --git a/kernel/lib.rs b/kernel/lib.rs index a5aa1fe..f4c85f0 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -110,12 +110,24 @@ pub mod syscall; #[cfg(test)] pub mod tests; +pub extern fn context_test() { + print!("TEST\n"); + + loop { + unsafe { interrupt::enable_and_halt(); } + } +} + #[no_mangle] pub extern fn kmain() { context::init(); print!("{}", format!("BSP: {:?}\n", syscall::getpid())); + if let Ok(context) = context::contexts_mut().spawn(context_test) { + + } + loop { unsafe { interrupt::enable_and_halt(); } }