Add arch context, WIP switching
This commit is contained in:
parent
4ced24e8d1
commit
f6e57ff5d1
72
arch/x86_64/src/context.rs
Normal file
72
arch/x86_64/src/context.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
pub struct Context {
|
||||||
|
flags: usize,
|
||||||
|
bx: usize,
|
||||||
|
r12: usize,
|
||||||
|
r13: usize,
|
||||||
|
r14: usize,
|
||||||
|
r15: usize,
|
||||||
|
bp: usize,
|
||||||
|
sp: usize,
|
||||||
|
cr3: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
pub fn new() -> Context {
|
||||||
|
Context {
|
||||||
|
flags: 0,
|
||||||
|
bx: 0,
|
||||||
|
r12: 0,
|
||||||
|
r13: 0,
|
||||||
|
r14: 0,
|
||||||
|
r15: 0,
|
||||||
|
bp: 0,
|
||||||
|
sp: 0,
|
||||||
|
cr3: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
#[naked]
|
||||||
|
pub unsafe fn switch_to(&mut self, next: &mut Context) {
|
||||||
|
asm!("xchg bx, bx" : : : "memory" : "intel", "volatile");
|
||||||
|
|
||||||
|
/*
|
||||||
|
asm!("fxsave [$0]" : : "r"(self.fx) : "memory" : "intel", "volatile");
|
||||||
|
self.loadable = true;
|
||||||
|
if next.loadable {
|
||||||
|
asm!("fxrstor [$0]" : : "r"(next.fx) : "memory" : "intel", "volatile");
|
||||||
|
}else{
|
||||||
|
asm!("fninit" : : : "memory" : "intel", "volatile");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
asm!("pushfq ; pop $0" : "=r"(self.flags) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("push $0 ; popfq" : : "r"(next.flags) : "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, r12" : "=r"(self.r12) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("mov r12, $0" : : "r"(next.r12) : "memory" : "intel", "volatile");
|
||||||
|
|
||||||
|
asm!("mov $0, r13" : "=r"(self.r13) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("mov r13, $0" : : "r"(next.r13) : "memory" : "intel", "volatile");
|
||||||
|
|
||||||
|
asm!("mov $0, r14" : "=r"(self.r14) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("mov r14, $0" : : "r"(next.r14) : "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 $0, rbp" : "=r"(self.bp) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("mov rbp, $0" : : "r"(next.bp) : "memory" : "intel", "volatile");
|
||||||
|
|
||||||
|
asm!("mov $0, rsp" : "=r"(self.sp) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("mov rsp, $0" : : "r"(next.sp) : "memory" : "intel", "volatile");
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
asm!("mov $0, cr3" : "=r"(self.cr3) : : "memory" : "intel", "volatile");
|
||||||
|
asm!("mov cr3, $0" : : "r"(self.cr3) : "memory" : "intel", "volatile");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
|
@ -107,6 +107,7 @@ pub unsafe fn init_ap(tcb_offset: usize, stack_offset: usize) {
|
||||||
// Load the initial GDT, before we have access to thread locals
|
// Load the initial GDT, before we have access to thread locals
|
||||||
dtables::lgdt(&INIT_GDTR);
|
dtables::lgdt(&INIT_GDTR);
|
||||||
|
|
||||||
|
// Load the segment descriptors
|
||||||
segmentation::load_cs(SegmentSelector::new(GDT_KERNEL_CODE as u16));
|
segmentation::load_cs(SegmentSelector::new(GDT_KERNEL_CODE as u16));
|
||||||
segmentation::load_ds(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
segmentation::load_ds(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
||||||
segmentation::load_es(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
segmentation::load_es(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
||||||
|
@ -131,6 +132,14 @@ pub unsafe fn init_ap(tcb_offset: usize, stack_offset: usize) {
|
||||||
// Load the new GDT, which is correctly located in thread local storage
|
// Load the new GDT, which is correctly located in thread local storage
|
||||||
dtables::lgdt(&GDTR);
|
dtables::lgdt(&GDTR);
|
||||||
|
|
||||||
|
// Reload the segment descriptors
|
||||||
|
segmentation::load_cs(SegmentSelector::new(GDT_KERNEL_CODE as u16));
|
||||||
|
segmentation::load_ds(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
||||||
|
segmentation::load_es(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
||||||
|
segmentation::load_fs(SegmentSelector::new(GDT_KERNEL_TLS as u16));
|
||||||
|
segmentation::load_gs(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
||||||
|
segmentation::load_ss(SegmentSelector::new(GDT_KERNEL_DATA as u16));
|
||||||
|
|
||||||
// Load the task register
|
// Load the task register
|
||||||
task::load_ltr(SegmentSelector::new(GDT_TSS as u16));
|
task::load_ltr(SegmentSelector::new(GDT_TSS as u16));
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,9 @@ macro_rules! interrupt_error {
|
||||||
/// ACPI table parsing
|
/// ACPI table parsing
|
||||||
pub mod acpi;
|
pub mod acpi;
|
||||||
|
|
||||||
|
/// Context switching
|
||||||
|
pub mod context;
|
||||||
|
|
||||||
/// Memcpy, memmove, etc.
|
/// Memcpy, memmove, etc.
|
||||||
pub mod externs;
|
pub mod externs;
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ pub unsafe extern fn kstart() -> ! {
|
||||||
|
|
||||||
{
|
{
|
||||||
let index = heap_start_page.p4_index();
|
let index = heap_start_page.p4_index();
|
||||||
println!("HEAP: {} {} {} {}", index, heap_start_page.p3_index(), heap_start_page.p2_index(), heap_start_page.p1_index());
|
|
||||||
assert_eq!(index, heap_end_page.p4_index());
|
assert_eq!(index, heap_end_page.p4_index());
|
||||||
|
|
||||||
let frame = memory::allocate_frame().expect("no frames available");
|
let frame = memory::allocate_frame().expect("no frames available");
|
||||||
|
|
|
@ -103,8 +103,6 @@ startup_arch:
|
||||||
or ebx, 1 << 31 | 1 << 16 | 1 ;Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
|
or ebx, 1 << 31 | 1 << 16 | 1 ;Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
|
||||||
mov cr0, ebx
|
mov cr0, ebx
|
||||||
|
|
||||||
xchg bx, bx
|
|
||||||
|
|
||||||
; far jump to enable Long Mode and load CS with 64 bit segment
|
; far jump to enable Long Mode and load CS with 64 bit segment
|
||||||
jmp gdt.kernel_code:long_mode
|
jmp gdt.kernel_code:long_mode
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue