diff --git a/src/Makefile b/src/Makefile index 7f52356..f10bdec 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ libcore_rlib_path = target/libcore/target/x86_64-unknown-intermezzos-gnu/release libcore_rlib = $(libcore_rlib_path)/libcore.rlib libcore_sha = 02e41cd5b925a1c878961042ecfb00470c68296b libintermezzos_a = target/x86_64-unknown-intermezzos-gnu/release/libintermezzos.a -o_files = target/multiboot_header.o target/boot.o target/interrupt_handlers.o +o_files = target/multiboot_header.o target/boot.o build: target/kernel.bin @@ -22,10 +22,6 @@ $(libcore_rlib): target/libcore cargo: $(libcore_rlib) RUSTFLAGS="-L $(libcore_rlib_path)" cargo build --release --target $(target).json -target/interrupt_handlers.o: src/asm/interrupt_handlers.asm - mkdir -p target - nasm -f elf64 src/asm/interrupt_handlers.asm -o target/interrupt_handlers.o - target/multiboot_header.o: src/asm/multiboot_header.asm mkdir -p target nasm -f elf64 src/asm/multiboot_header.asm -o target/multiboot_header.o diff --git a/src/interrupts/Cargo.lock b/src/interrupts/Cargo.lock new file mode 100644 index 0000000..3921b2a --- /dev/null +++ b/src/interrupts/Cargo.lock @@ -0,0 +1,210 @@ +[root] +name = "interrupts" +version = "0.1.0" +dependencies = [ + "keyboard 0.1.0", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pic 0.1.0", + "vga 0.1.0", +] + +[[package]] +name = "byteorder" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "csv" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "keyboard" +version = "0.1.0" +dependencies = [ + "vga 0.1.0", +] + +[[package]] +name = "lazy_static" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "spin 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-complex" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "phf" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "phf_codegen" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf_generator 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "phf_generator" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf_shared 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "phf_shared" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pic" +version = "0.1.0" + +[[package]] +name = "rand" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "raw-cpuid" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "spin" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "spin" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vga" +version = "0.1.0" +dependencies = [ + "spin 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "x86 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "csv 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "phf 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index 1939363..774ee43 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -1,52 +1,78 @@ #![feature(asm)] +#![feature(naked_functions)] +#![feature(core_intrinsics)] #![no_std] #[macro_use] extern crate vga; - #[macro_use] extern crate lazy_static; - extern crate keyboard; +extern crate pic; use keyboard::Keyboard; -extern crate pic; +use core::intrinsics; + +macro_rules! make_idt_entry { + ($number:expr) => {{ + unsafe extern fn handler() { + kprintln!("unhandled interrupt #{}", $number); + } + + IdtEntry::new(handler) + }}; + ($name:ident, $body:expr) => {{ + fn body() { + $body + } + + #[naked] + unsafe extern fn $name() { + asm!("push rbp + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rsi + push rdi + push rdx + push rcx + push rbx + push rax + + mov rsi, rsp + push rsi + + call $0 + + add rsp, 8 + + pop rax + pop rbx + pop rcx + pop rdx + pop rdi + pop rsi + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + pop rbp + + iretq" :: "s"(body as fn()) :: "volatile", "intel"); + intrinsics::unreachable(); + } -extern { - fn isr0(); - fn isr1(); - fn isr2(); - fn isr3(); - fn isr4(); - fn isr5(); - fn isr6(); - fn isr7(); - fn isr8(); - fn isr9(); - fn isr10(); - fn isr11(); - fn isr12(); - fn isr13(); - fn isr14(); - fn isr15(); - fn isr16(); - fn isr17(); - fn isr18(); - fn isr19(); - fn isr20(); - fn isr21(); - fn isr22(); - fn isr23(); - fn isr24(); - fn isr25(); - fn isr26(); - fn isr27(); - fn isr28(); - fn isr29(); - fn isr30(); - fn isr31(); - fn isr32(); - fn isr33(); + IdtEntry::new($name) + }}; } #[derive(Copy,Clone,Debug)] @@ -61,6 +87,22 @@ struct IdtEntry { reserved: u32, } +impl IdtEntry { + fn new(f: unsafe extern fn()) -> IdtEntry { + let base = f as u64; + + IdtEntry { + base_low: base as u16, + selector: 0x8, + zero: 0, + flags: 0x8e, + base_mid: (base >> 16) as u16, + base_high: (base >> 32) as u32, + reserved: 0, + } + } +} + #[derive(Debug)] #[repr(packed,C)] pub struct IdtPointer { @@ -85,18 +127,8 @@ impl Idt { } } - fn set_isr(&mut self, num: u8, base: u64) { - let new_isr = IdtEntry { - base_low: base as u16, - selector: 0x8, - zero: 0, - flags: 0x8e, - base_mid: (base >> 16) as u16, - base_high: (base >> 32) as u32, - reserved: 0, - }; - - self.entries[num as usize] = new_isr; + fn set_isr(&mut self, num: u8, entry: IdtEntry) { + self.entries[num as usize] = entry; } } @@ -114,45 +146,56 @@ lazy_static! { }; 256] }; - idt.set_isr(0, isr0 as u64); - idt.set_isr(1, isr1 as u64); - idt.set_isr(2, isr2 as u64); - idt.set_isr(3, isr3 as u64); - idt.set_isr(4, isr4 as u64); - idt.set_isr(5, isr5 as u64); - idt.set_isr(6, isr6 as u64); - idt.set_isr(7, isr7 as u64); - idt.set_isr(8, isr8 as u64); - idt.set_isr(9, isr9 as u64); - idt.set_isr(10, isr10 as u64); - idt.set_isr(11, isr11 as u64); - idt.set_isr(12, isr12 as u64); - idt.set_isr(13, isr13 as u64); - idt.set_isr(14, isr14 as u64); - idt.set_isr(15, isr15 as u64); - idt.set_isr(16, isr16 as u64); - idt.set_isr(17, isr17 as u64); - idt.set_isr(18, isr18 as u64); - idt.set_isr(19, isr19 as u64); - idt.set_isr(20, isr20 as u64); - idt.set_isr(21, isr21 as u64); - idt.set_isr(22, isr22 as u64); - idt.set_isr(23, isr23 as u64); - idt.set_isr(24, isr24 as u64); - idt.set_isr(25, isr25 as u64); - idt.set_isr(26, isr26 as u64); - idt.set_isr(27, isr27 as u64); - idt.set_isr(28, isr28 as u64); - idt.set_isr(29, isr29 as u64); - idt.set_isr(30, isr30 as u64); - idt.set_isr(31, isr31 as u64); - idt.set_isr(32, isr32 as u64); - idt.set_isr(33, isr33 as u64); + idt.set_isr(0, make_idt_entry!(0)); + idt.set_isr(1, make_idt_entry!(1)); + idt.set_isr(2, make_idt_entry!(2)); + idt.set_isr(3, make_idt_entry!(3)); + idt.set_isr(4, make_idt_entry!(4)); + idt.set_isr(5, make_idt_entry!(5)); + idt.set_isr(6, make_idt_entry!(6)); + idt.set_isr(7, make_idt_entry!(7)); + idt.set_isr(8, make_idt_entry!(8)); + idt.set_isr(9, make_idt_entry!(9)); + idt.set_isr(10, make_idt_entry!(10)); + idt.set_isr(11, make_idt_entry!(11)); + idt.set_isr(12, make_idt_entry!(12)); + idt.set_isr(13, make_idt_entry!(13)); + idt.set_isr(14, make_idt_entry!(14)); + idt.set_isr(15, make_idt_entry!(15)); + idt.set_isr(16, make_idt_entry!(16)); + idt.set_isr(17, make_idt_entry!(17)); + idt.set_isr(18, make_idt_entry!(18)); + idt.set_isr(19, make_idt_entry!(19)); + idt.set_isr(20, make_idt_entry!(20)); + idt.set_isr(21, make_idt_entry!(21)); + idt.set_isr(22, make_idt_entry!(22)); + idt.set_isr(23, make_idt_entry!(23)); + idt.set_isr(24, make_idt_entry!(24)); + idt.set_isr(25, make_idt_entry!(25)); + idt.set_isr(26, make_idt_entry!(26)); + idt.set_isr(27, make_idt_entry!(27)); + idt.set_isr(28, make_idt_entry!(28)); + idt.set_isr(29, make_idt_entry!(29)); + idt.set_isr(30, make_idt_entry!(30)); + idt.set_isr(31, make_idt_entry!(31)); + + idt.set_isr(32, make_idt_entry!(isr32, { + // timer, do nothing for now + pic::eoi_for(32); + enable(); + })); + + idt.set_isr(33, make_idt_entry!(isr33, { + let scancode = unsafe { inb(0x60) }; + Keyboard.handle_keys(scancode as usize); + + pic::eoi_for(33); + enable(); + })); idt }; } - pub fn install() { IDT.install(); @@ -168,24 +211,6 @@ unsafe fn load_idt(ptr: &IdtPointer) { asm!("lidt $0"::"*m"(ptr)::"volatile"); } -#[no_mangle] -pub extern "C" fn interrupt_handler(interrupt_number: isize, error_code: isize) { - match interrupt_number { - 32 => {}, // timer - 33 => keyboard_handler(), - _ => panic!("interrupt {} with error code {:x}", interrupt_number, error_code), - } - - pic::eoi_for(interrupt_number); - - enable(); -} - -fn keyboard_handler() { - let scancode = unsafe { inb(0x60) }; - Keyboard.handle_keys(scancode as usize); -} - #[inline] unsafe fn inb(port: u16) -> u8 { let ret : u8; diff --git a/src/src/asm/interrupt_handlers.asm b/src/src/asm/interrupt_handlers.asm deleted file mode 100644 index 03c4e01..0000000 --- a/src/src/asm/interrupt_handlers.asm +++ /dev/null @@ -1,70 +0,0 @@ -BITS 64 - -extern interrupt_handler; -extern gdt64.data; - - -%assign i 0 -%rep 34 -global isr%+i -%assign i i+1 -%endrep - -section .interrupt_handlers -%assign i 0 -%rep 34 -isr%+i: - mov [number], byte i - jmp qword push_registers_and_call_handler -%assign i i+1 -%endrep - -section .text - -; Stack must contain rax on top the interrupt frame below. The interrupt -; handler address must then be passed in rax. -push_registers_and_call_handler: - push rbp - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rsi - push rdi - push rdx - push rcx - push rbx - push rax - - mov rsi, rsp - push rsi - mov rdi, qword [number] - push rdi - - call qword interrupt_handler - - add rsp, 16 ; Skip interrupt code and reg pointer - - pop rax - pop rbx - pop rcx - pop rdx - pop rdi - pop rsi - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - pop rbp - - iretq - -number: dq 0