diff --git a/kernel/src/arch/x86_64/driver/keyboard.rs b/kernel/src/arch/x86_64/driver/keyboard.rs index ad000fd..36ca5e1 100644 --- a/kernel/src/arch/x86_64/driver/keyboard.rs +++ b/kernel/src/arch/x86_64/driver/keyboard.rs @@ -4,9 +4,9 @@ use pc_keyboard::{Keyboard, ScancodeSet1, DecodedKey, layouts}; use lazy_static::lazy_static; pub fn init() { - use crate::arch::interrupt::consts::*; + use crate::arch::interrupt::consts; use crate::arch::interrupt::enable_irq; - enable_irq(IRQ_KBD); + enable_irq(consts::Keyboard); } /// Receive character from keyboard diff --git a/kernel/src/arch/x86_64/driver/serial.rs b/kernel/src/arch/x86_64/driver/serial.rs index 443a2a8..ce84af5 100644 --- a/kernel/src/arch/x86_64/driver/serial.rs +++ b/kernel/src/arch/x86_64/driver/serial.rs @@ -1,9 +1,11 @@ // Copy from Redox -use x86_64::instructions::port::Port; +use once::*; use spin::Mutex; use uart_16550::SerialPort; -use once::*; +use x86_64::instructions::port::Port; + +use crate::arch::interrupt::{consts, enable_irq}; pub static COM1: Mutex = Mutex::new(SerialPort::new(0x3F8)); pub static COM2: Mutex = Mutex::new(SerialPort::new(0x2F8)); @@ -13,9 +15,8 @@ pub fn init() { COM1.lock().init(); COM2.lock().init(); - use crate::arch::interrupt::{enable_irq, consts::{IRQ_COM1, IRQ_COM2}}; - enable_irq(IRQ_COM1); - enable_irq(IRQ_COM2); + enable_irq(consts::COM1); + enable_irq(consts::COM2); } pub trait SerialRead { diff --git a/kernel/src/arch/x86_64/idt.rs b/kernel/src/arch/x86_64/idt.rs index 0d6b94f..59ecf87 100644 --- a/kernel/src/arch/x86_64/idt.rs +++ b/kernel/src/arch/x86_64/idt.rs @@ -19,7 +19,7 @@ lazy_static! { // * 某些保留中断号不允许设置,会触发panic // 于是下面用了一些trick绕过了它们 - let ring3 = [T_SWITCH_TOK, T_SYSCALL, T_SYSCALL32]; + let ring3 = [SwitchToKernel, Syscall, Syscall32]; let mut idt = InterruptDescriptorTable::new(); let entries = unsafe{ &mut *(&mut idt as *mut _ as *mut [Entry; 256]) }; @@ -29,7 +29,7 @@ lazy_static! { opt.set_privilege_level(PrivilegeLevel::Ring3); opt.disable_interrupts(false); } - if i == T_DBLFLT as usize { + if i == DoubleFault as usize { unsafe{ opt.set_stack_index(DOUBLE_FAULT_IST_INDEX as u16); } } } diff --git a/kernel/src/arch/x86_64/interrupt/consts.rs b/kernel/src/arch/x86_64/interrupt/consts.rs index bb087a0..449c56f 100644 --- a/kernel/src/arch/x86_64/interrupt/consts.rs +++ b/kernel/src/arch/x86_64/interrupt/consts.rs @@ -1,34 +1,39 @@ -pub const T_DIVIDE : u8 = 0 ; // divide error -pub const T_DEBUG : u8 = 1 ; // debug exception -pub const T_NMI : u8 = 2 ; // non-maskable interrupt -pub const T_BRKPT : u8 = 3 ; // breakpoint -pub const T_OFLOW : u8 = 4 ; // overflow -pub const T_BOUND : u8 = 5 ; // bounds check -pub const T_ILLOP : u8 = 6 ; // illegal opcode -pub const T_DEVICE : u8 = 7 ; // device not available -pub const T_DBLFLT : u8 = 8 ; // double fault -pub const T_COPROC : u8 = 9 ; // reserved (not used since 486) -pub const T_TSS : u8 = 10; // invalid task switch segment -pub const T_SEGNP : u8 = 11; // segment not present -pub const T_STACK : u8 = 12; // stack exception -pub const T_GPFLT : u8 = 13; // general protection fault -pub const T_PGFLT : u8 = 14; // page fault -pub const T_RES : u8 = 15; // reserved -pub const T_FPERR : u8 = 16; // floating point error -pub const T_ALIGN : u8 = 17; // aligment check -pub const T_MCHK : u8 = 18; // machine check -pub const T_SIMDERR : u8 = 19; // SIMD floating point error -pub const T_IRQ0 : u8 = 32; // IRQ 0 corresponds to int T_IRQ -pub const IRQ_TIMER : u8 = 0; -pub const IRQ_KBD : u8 = 1; -pub const IRQ_COM2 : u8 = 3; -pub const IRQ_COM1 : u8 = 4; -pub const IRQ_IDE : u8 = 14; -pub const IRQ_ERROR : u8 = 19; -pub const IRQ_SPURIOUS : u8 = 31; -pub const T_SYSCALL: u8 = 0x40; -// xv6 x86_64 syscall -pub const T_SYSCALL32: u8 = 0x80; -// ucore syscall -pub const T_SWITCH_TOU : u8 = 120; // user/kernel switch -pub const T_SWITCH_TOK : u8 = 121; // user/kernel switch \ No newline at end of file +#![allow(non_upper_case_globals)] +// Reference: https://wiki.osdev.org/Exceptions + +pub const DivideError: u8 = 0; +pub const Debug: u8 = 1; +pub const NonMaskableInterrupt: u8 = 2; +pub const Breakpoint: u8 = 3; +pub const Overflow: u8 = 4; +pub const BoundRangeExceeded: u8 = 5; +pub const InvalidOpcode: u8 = 6; +pub const DeviceNotAvailable: u8 = 7; +pub const DoubleFault: u8 = 8; +pub const CoprocessorSegmentOverrun: u8 = 9; +pub const InvalidTSS: u8 = 10; +pub const SegmentNotPresent: u8 = 11; +pub const StackSegmentFault: u8 = 12; +pub const GeneralProtectionFault: u8 = 13; +pub const PageFault: u8 = 14; +pub const FloatingPointException: u8 = 16; +pub const AlignmentCheck: u8 = 17; +pub const MachineCheck: u8 = 18; +pub const SIMDFloatingPointException: u8 = 19; +pub const VirtualizationException: u8 = 20; +pub const SecurityException: u8 = 30; + +pub const IRQ0: u8 = 32; +pub const Syscall: u8 = 0x40; +pub const Syscall32: u8 = 0x80; +pub const SwitchToUser: u8 = 120; +pub const SwitchToKernel: u8 = 121; + +// IRQ +pub const Timer: u8 = 0; +pub const Keyboard: u8 = 1; +pub const COM2: u8 = 3; +pub const COM1: u8 = 4; +pub const IDE: u8 = 14; +pub const Error: u8 = 19; +pub const Spurious: u8 = 31; diff --git a/kernel/src/arch/x86_64/interrupt/handler.rs b/kernel/src/arch/x86_64/interrupt/handler.rs index 233a9ee..8be3700 100644 --- a/kernel/src/arch/x86_64/interrupt/handler.rs +++ b/kernel/src/arch/x86_64/interrupt/handler.rs @@ -71,31 +71,32 @@ use log::*; global_asm!(include_str!("trap.asm")); global_asm!(include_str!("vector.asm")); +#[allow(non_upper_case_globals)] #[no_mangle] pub extern fn rust_trap(tf: &mut TrapFrame) { trace!("Interrupt: {:#x} @ CPU{}", tf.trap_num, super::super::cpu::id()); // Dispatch match tf.trap_num as u8 { - T_BRKPT => breakpoint(), - T_DBLFLT => double_fault(tf), - T_PGFLT => page_fault(tf), - T_IRQ0...63 => { - let irq = tf.trap_num as u8 - T_IRQ0; + Breakpoint => breakpoint(), + DoubleFault => double_fault(tf), + PageFault => page_fault(tf), + IRQ0...63 => { + let irq = tf.trap_num as u8 - IRQ0; super::ack(irq); // must ack before switching match irq { - IRQ_TIMER => crate::trap::timer(), - IRQ_KBD => keyboard(), - IRQ_COM1 => com1(), - IRQ_COM2 => com2(), - IRQ_IDE => ide(), + Timer => crate::trap::timer(), + Keyboard => keyboard(), + COM1 => com1(), + COM2 => com2(), + IDE => ide(), _ => panic!("Invalid IRQ number: {}", irq), } } - T_SWITCH_TOK => to_kernel(tf), - T_SWITCH_TOU => to_user(tf), - T_SYSCALL => syscall(tf), - T_SYSCALL32 => syscall32(tf), - T_DIVIDE | T_GPFLT | T_ILLOP => error(tf), + SwitchToKernel => to_kernel(tf), + SwitchToUser => to_user(tf), + Syscall => syscall(tf), + Syscall32 => syscall32(tf), + DivideError | GeneralProtectionFault | InvalidOpcode => error(tf), _ => panic!("Unhandled interrupt {:x}", tf.trap_num), } }