Add IRQ handler for ToUser, ToKernel, GPF, Syscall.

Now trigger ToUser interrupt will cause GPF.
master
WangRunji 7 years ago
parent cb19bc5464
commit 69f6f4070e

@ -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

@ -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);

@ -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");
}

@ -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
}

@ -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!();

Loading…
Cancel
Save