diff --git a/src/arch/x86_64/gdt.rs b/src/arch/x86_64/gdt.rs index a4cee8f..2db9cca 100644 --- a/src/arch/x86_64/gdt.rs +++ b/src/arch/x86_64/gdt.rs @@ -32,8 +32,7 @@ pub fn init() { let mut tss_selector = SegmentSelector(0); let gdt = Box::new({ let mut gdt = Gdt::new(); - gdt.add_entry(GNULL); - code_selector = + code_selector = gdt.add_entry(KCODE); gdt.add_entry(UCODE); gdt.add_entry(KDATA); @@ -55,7 +54,6 @@ pub fn init() { pub const DOUBLE_FAULT_IST_INDEX: usize = 0; // Copied from xv6 x86_64 -const GNULL: Descriptor = Descriptor::UserSegment(0); const KCODE: Descriptor = Descriptor::UserSegment(0x0020980000000000); // EXECUTABLE | USER_SEGMENT | PRESENT | LONG_MODE const UCODE: Descriptor = Descriptor::UserSegment(0x0020F80000000000); // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT | LONG_MODE const KDATA: Descriptor = Descriptor::UserSegment(0x0000920000000000); // DATA_WRITABLE | USER_SEGMENT | PRESENT diff --git a/src/arch/x86_64/idt.rs b/src/arch/x86_64/idt.rs index e2d412b..f08428a 100644 --- a/src/arch/x86_64/idt.rs +++ b/src/arch/x86_64/idt.rs @@ -12,10 +12,14 @@ pub fn init() { let mut idt = Idt::new(); idt.breakpoint.set_handler_fn(breakpoint_handler); idt.double_fault.set_handler_fn(double_fault_handler); + idt.general_protection_fault.set_handler_fn(general_protection_fault_handler); idt[(T_IRQ0 + IRQ_COM1) as usize].set_handler_fn(com1_handler); idt[(T_IRQ0 + IRQ_COM2) as usize].set_handler_fn(com2_handler); idt[(T_IRQ0 + IRQ_KBD) as usize].set_handler_fn(keyboard_handler); idt[(T_IRQ0 + IRQ_TIMER) as usize].set_handler_fn(timer_handler); + idt[T_SWITCH_TOU as usize].set_handler_fn(to_user_handler); + idt[T_SWITCH_TOK as usize].set_handler_fn(to_kernel_handler); + idt[T_SYSCALL as usize].set_handler_fn(syscall_handler); unsafe { idt.page_fault.set_handler_fn(page_fault_handler) .set_stack_index(DOUBLE_FAULT_IST_INDEX as u16); diff --git a/src/arch/x86_64/interrupt/irq.rs b/src/arch/x86_64/interrupt/irq.rs index 1b5523b..b875805 100644 --- a/src/arch/x86_64/interrupt/irq.rs +++ b/src/arch/x86_64/interrupt/irq.rs @@ -22,6 +22,12 @@ pub extern "x86-interrupt" fn page_fault_handler( loop {} } +pub extern "x86-interrupt" fn general_protection_fault_handler( + stack_frame: &mut ExceptionStackFrame, error_code: u64) +{ + println!("\nEXCEPTION: General Protection Fault\n{:#?}\nErrorCode: {:#x}", stack_frame, error_code); +} + #[cfg(feature = "use_apic")] use arch::driver::apic::ack; #[cfg(not(feature = "use_apic"))] @@ -70,4 +76,26 @@ pub extern "x86-interrupt" fn timer_handler( println!("\nInterupt: Timer\ntick = {}", tick); } ack(IRQ_TIMER); +} + +pub extern "x86-interrupt" fn to_user_handler( + stack_frame: &mut ExceptionStackFrame) +{ + println!("\nInterupt: To User"); + stack_frame.code_segment = 16; + stack_frame.stack_segment = 32; +} + +pub extern "x86-interrupt" fn to_kernel_handler( + stack_frame: &mut ExceptionStackFrame) +{ + println!("\nInterupt: To Kernel"); + stack_frame.code_segment = 8; + stack_frame.stack_segment = 24; +} + +pub extern "x86-interrupt" fn syscall_handler( + stack_frame: &mut ExceptionStackFrame) +{ + println!("\nInterupt: Syscall"); } \ No newline at end of file diff --git a/src/consts.rs b/src/consts.rs index 67ab9b6..19f5cb3 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -104,4 +104,7 @@ pub mod irq { pub const IRQ_IDE : u8 = 14; pub const IRQ_ERROR : u8 = 19; pub const IRQ_SPURIOUS : u8 = 31; + pub const T_SYSCALL : u8 = 0x80; // SYSCALL, ONLY FOR THIS PROJ + pub const T_SWITCH_TOU : u8 = 120; // user/kernel switch + pub const T_SWITCH_TOK : u8 = 121; // user/kernel switch } diff --git a/src/lib.rs b/src/lib.rs index 3affcd9..fc4f920 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ #![feature(abi_x86_interrupt)] #![feature(iterator_step_by)] #![feature(unboxed_closures)] +#![feature(asm)] #![no_std] @@ -21,6 +22,7 @@ extern crate spin; extern crate multiboot2; #[macro_use] extern crate bitflags; +#[macro_use] extern crate x86_64; #[macro_use] extern crate once; @@ -74,6 +76,9 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) -> ! { arch::smp::start_other_cores(&acpi, &mut memory_controller); unsafe{ arch::interrupt::enable(); } + + unsafe{ int!(120); } // to user + loop{} test_end!();