Arch context in kernel context

This commit is contained in:
Jeremy Soller 2016-08-24 10:35:42 -06:00
parent f6e57ff5d1
commit 2be7ccaec2
3 changed files with 60 additions and 16 deletions

View file

@ -1,26 +1,36 @@
#[derive(Debug)]
pub struct Context { pub struct Context {
flags: usize, /// RFLAGS register
bx: usize, rflags: usize,
/// RBX register
rbx: usize,
/// R12 register
r12: usize, r12: usize,
/// R13 register
r13: usize, r13: usize,
/// R14 register
r14: usize, r14: usize,
/// R15 register
r15: usize, r15: usize,
bp: usize, /// Base pointer
sp: usize, rbp: usize,
/// Stack pointer
rsp: usize,
/// Page table pointer
cr3: usize cr3: usize
} }
impl Context { impl Context {
pub fn new() -> Context { pub fn new() -> Context {
Context { Context {
flags: 0, rflags: 0,
bx: 0, rbx: 0,
r12: 0, r12: 0,
r13: 0, r13: 0,
r14: 0, r14: 0,
r15: 0, r15: 0,
bp: 0, rbp: 0,
sp: 0, rsp: 0,
cr3: 0 cr3: 0
} }
} }
@ -40,11 +50,11 @@ impl Context {
} }
*/ */
asm!("pushfq ; pop $0" : "=r"(self.flags) : : "memory" : "intel", "volatile"); asm!("pushfq ; pop $0" : "=r"(self.rflags) : : "memory" : "intel", "volatile");
asm!("push $0 ; popfq" : : "r"(next.flags) : "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 $0, rbx" : "=r"(self.rbx) : : "memory" : "intel", "volatile");
asm!("mov rbx, $0" : : "r"(next.bx) : "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 $0, r12" : "=r"(self.r12) : : "memory" : "intel", "volatile");
asm!("mov r12, $0" : : "r"(next.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 $0, r15" : "=r"(self.r15) : : "memory" : "intel", "volatile");
asm!("mov r15, $0" : : "r"(next.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 $0, rbp" : "=r"(self.rbp) : : "memory" : "intel", "volatile");
asm!("mov rbp, $0" : : "r"(next.bp) : "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 $0, rsp" : "=r"(self.rsp) : : "memory" : "intel", "volatile");
asm!("mov rsp, $0" : : "r"(next.sp) : "memory" : "intel", "volatile"); asm!("mov rsp, $0" : : "r"(next.rsp) : "memory" : "intel", "volatile");
/* TODO /* TODO
asm!("mov $0, cr3" : "=r"(self.cr3) : : "memory" : "intel", "volatile"); asm!("mov $0, cr3" : "=r"(self.cr3) : : "memory" : "intel", "volatile");

View file

@ -4,6 +4,7 @@ use collections::{BTreeMap, Vec};
use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use arch::context::Context as ArchContext;
use syscall::{Error, Result}; use syscall::{Error, Result};
/// File operations /// File operations
@ -55,6 +56,15 @@ impl ContextList {
assert!(self.map.insert(id, RwLock::new(Context::new(id))).is_none()); assert!(self.map.insert(id, RwLock::new(Context::new(id))).is_none());
Ok(self.map.get(&id).expect("failed to insert new context")) Ok(self.map.get(&id).expect("failed to insert new context"))
} }
pub fn spawn(&mut self, func: extern fn()) -> Result<&RwLock<Context>> {
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 /// Contexts list
@ -85,19 +95,31 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> {
CONTEXTS.call_once(init_contexts).write() 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 /// A context, which identifies either a process or a thread
#[derive(Debug)] #[derive(Debug)]
pub struct Context { pub struct Context {
/// The ID of this context /// The ID of this context
pub id: usize, pub id: usize,
/// The architecture specific context
pub arch: ArchContext,
/// The open files in the scheme /// The open files in the scheme
pub files: Vec<Option<file::File>> pub files: Vec<Option<file::File>>
} }
impl Context { impl Context {
/// Create a new context
pub fn new(id: usize) -> Context { pub fn new(id: usize) -> Context {
Context { Context {
id: id, id: id,
arch: ArchContext::new(),
files: Vec::new() files: Vec::new()
} }
} }

View file

@ -110,12 +110,24 @@ pub mod syscall;
#[cfg(test)] #[cfg(test)]
pub mod tests; pub mod tests;
pub extern fn context_test() {
print!("TEST\n");
loop {
unsafe { interrupt::enable_and_halt(); }
}
}
#[no_mangle] #[no_mangle]
pub extern fn kmain() { pub extern fn kmain() {
context::init(); context::init();
print!("{}", format!("BSP: {:?}\n", syscall::getpid())); print!("{}", format!("BSP: {:?}\n", syscall::getpid()));
if let Ok(context) = context::contexts_mut().spawn(context_test) {
}
loop { loop {
unsafe { interrupt::enable_and_halt(); } unsafe { interrupt::enable_and_halt(); }
} }