From 0b03c18b0636d5678e218334de9840744ff28fda Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 28 Dec 2016 16:21:33 +0100 Subject: [PATCH] Rewrite interrupts::init using a lazy_static IDT again --- src/interrupts/mod.rs | 72 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/src/interrupts/mod.rs b/src/interrupts/mod.rs index 5719411d..15dde3ed 100644 --- a/src/interrupts/mod.rs +++ b/src/interrupts/mod.rs @@ -91,52 +91,54 @@ macro_rules! handler_with_error_code { }} } -static IDT: Once = Once::new(); -static TSS: Once = Once::new(); -static GDT: Once = Once::new(); - -pub fn init(memory_controller: &mut MemoryController) { - let double_fault_stack = memory_controller.alloc_stack(1) - .expect("could not allocate double fault stack"); - - const DOUBLE_FAULT_IST_INDEX: u8 = 0; - - let tss = TSS.call_once(|| { - let mut tss = TaskStateSegment::new(); - tss.ist[DOUBLE_FAULT_IST_INDEX as usize] = double_fault_stack.top() as u64; - tss - }); - - let mut code_selector = gdt::Selector::new(); - let mut data_selector = gdt::Selector::new(); - let mut tss_selector = gdt::Selector::new(); - let gdt = GDT.call_once(|| { - let mut gdt = gdt::Gdt::new(); - - code_selector = gdt.add_entry(gdt::Entry::code_segment()); - data_selector = gdt.add_entry(gdt::Entry::data_segment()); - tss_selector = gdt.add_entry(gdt::Entry::tss_segment(tss)); - - gdt - }); - gdt.load(); - gdt::reload_segment_registers(code_selector, data_selector); - unsafe { gdt::load_ltr(tss_selector) }; - - let idt = IDT.call_once(|| { +lazy_static! { + static ref IDT: idt::Idt = { let mut idt = idt::Idt::new(); idt.set_handler(0, handler!(divide_by_zero_handler)); idt.set_handler(3, handler!(breakpoint_handler)); idt.set_handler(6, handler!(invalid_opcode_handler)); idt.set_handler(8, handler_with_error_code!(double_fault_handler)) - .set_stack_index(DOUBLE_FAULT_IST_INDEX); + .set_stack_index(DOUBLE_FAULT_IST_INDEX as u8); idt.set_handler(14, handler_with_error_code!(page_fault_handler)); idt + }; +} + +static TSS: Once = Once::new(); +static GDT: Once = Once::new(); +const DOUBLE_FAULT_IST_INDEX: usize = 0; + +pub fn init(memory_controller: &mut MemoryController) { + use x86::shared::segmentation::{SegmentSelector, set_cs}; + use x86::shared::task::load_tr; + + let double_fault_stack = memory_controller.alloc_stack(1) + .expect("could not allocate double fault stack"); + + let tss = TSS.call_once(|| { + let mut tss = TaskStateSegment::new(); + tss.ist[DOUBLE_FAULT_IST_INDEX] = double_fault_stack.top() as u64; + tss }); - idt.load(); + let mut code_selector = SegmentSelector::empty(); + let mut tss_selector = SegmentSelector::empty(); + let gdt = GDT.call_once(|| { + let mut gdt = gdt::Gdt::new(); + tss_selector = gdt.add_entry(gdt::Descriptor::tss_segment(&tss)); + code_selector = gdt.add_entry(gdt::Descriptor::kernel_code_segment()); + gdt + }); + gdt.load(); + + unsafe { + set_cs(code_selector); + load_tr(tss_selector); + } + + IDT.load(); } #[derive(Debug)]