From 3c033e6bdc6a5b863f04dbf8ead54314172bcbad Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 04:06:15 -0400 Subject: [PATCH 01/10] define isr0 via macro --- src/interrupts/src/lib.rs | 61 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index 1939363..69f3967 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -1,19 +1,19 @@ #![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; extern { - fn isr0(); fn isr1(); fn isr2(); fn isr3(); @@ -49,6 +49,59 @@ extern { fn isr33(); } +macro_rules! define_isr { + ($name:ident, $number:expr) => { + #[naked] + unsafe fn $name() { + asm!("pushq %rbp + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + pushq %rsi + pushq %rdi + pushq %rdx + pushq %rcx + pushq %rbx + pushq %rax + + movq %rsp, %rsi + pushq %rsi + movq 0, %rdi + pushq %rdi + + callq interrupt_handler + + addq 16, %rsp + + popq %rax + popq %rbx + popq %rcx + popq %rdx + popq %rdi + popq %rsi + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 + popq %rbp + + iretq" :::: "volatile"); + intrinsics::unreachable(); + } + } +} + +define_isr!(isr0, 0); + #[derive(Copy,Clone,Debug)] #[repr(packed,C)] struct IdtEntry { From 59e9cb491199bdb10de013ae24c16113cac0e356 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 04:11:07 -0400 Subject: [PATCH 02/10] define isr33 by macro --- src/interrupts/src/lib.rs | 88 +++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index 69f3967..4a60e29 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -14,6 +14,7 @@ use keyboard::Keyboard; use core::intrinsics; extern { + fn isr0(); fn isr1(); fn isr2(); fn isr3(); @@ -46,61 +47,60 @@ extern { fn isr30(); fn isr31(); fn isr32(); - fn isr33(); } macro_rules! define_isr { ($name:ident, $number:expr) => { #[naked] unsafe fn $name() { - asm!("pushq %rbp - pushq %r15 - pushq %r14 - pushq %r13 - pushq %r12 - pushq %r11 - pushq %r10 - pushq %r9 - pushq %r8 - pushq %rsi - pushq %rdi - pushq %rdx - pushq %rcx - pushq %rbx - pushq %rax - - movq %rsp, %rsi - pushq %rsi - movq 0, %rdi - pushq %rdi - - callq interrupt_handler - - addq 16, %rsp - - popq %rax - popq %rbx - popq %rcx - popq %rdx - popq %rdi - popq %rsi - popq %r8 - popq %r9 - popq %r10 - popq %r11 - popq %r12 - popq %r13 - popq %r14 - popq %r15 - popq %rbp - - iretq" :::: "volatile"); + 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 + movq rdi, 33 + push rdi + + call interrupt_handler + + add rsp, 16 + + 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" :::: "volatile", "intel"); intrinsics::unreachable(); } } } -define_isr!(isr0, 0); +define_isr!(isr33, 33); #[derive(Copy,Clone,Debug)] #[repr(packed,C)] From 300f032bcb7a54fd6d047303af4ca79f4e4987e5 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 04:20:41 -0400 Subject: [PATCH 03/10] define_isr now has a body --- src/interrupts/src/lib.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index 4a60e29..f308f3c 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -50,7 +50,12 @@ extern { } macro_rules! define_isr { - ($name:ident, $number:expr) => { + ($name:ident, $body:expr) => { + #[no_mangle] + pub extern "C" fn isr33handler(_interrupt_number: isize, _error_code: isize) { + $body + } + #[naked] unsafe fn $name() { asm!("push rbp @@ -74,7 +79,7 @@ macro_rules! define_isr { movq rdi, 33 push rdi - call interrupt_handler + call isr33handler add rsp, 16 @@ -100,7 +105,13 @@ macro_rules! define_isr { } } -define_isr!(isr33, 33); +define_isr!(isr33, { + let scancode = unsafe { inb(0x60) }; + Keyboard.handle_keys(scancode as usize); + + pic::eoi_for(33); + enable(); +}); #[derive(Copy,Clone,Debug)] #[repr(packed,C)] From 8b14419f52da712d00f2422848da45852903864c Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 04:23:04 -0400 Subject: [PATCH 04/10] remove vestigial keyboard handler code --- src/interrupts/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index f308f3c..e13f458 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -236,7 +236,6 @@ unsafe fn load_idt(ptr: &IdtPointer) { 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), } @@ -245,11 +244,6 @@ pub extern "C" fn interrupt_handler(interrupt_number: isize, error_code: isize) 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; From 1425eda3db07ae174436661e6bd8037744512c64 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 04:46:09 -0400 Subject: [PATCH 05/10] we don't need the number --- src/interrupts/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index e13f458..509d88d 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -52,7 +52,7 @@ extern { macro_rules! define_isr { ($name:ident, $body:expr) => { #[no_mangle] - pub extern "C" fn isr33handler(_interrupt_number: isize, _error_code: isize) { + pub extern "C" fn isr33handler(_error_code: isize) { $body } @@ -76,12 +76,10 @@ macro_rules! define_isr { mov rsi, rsp push rsi - movq rdi, 33 - push rdi call isr33handler - add rsp, 16 + add rsp, 8 pop rax pop rbx From c0e9baf9885020c9bde98d479bd9cb6ee488a5f3 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 04:48:27 -0400 Subject: [PATCH 06/10] clean some junk out of interrupt handler code --- src/src/asm/interrupt_handlers.asm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/src/asm/interrupt_handlers.asm b/src/src/asm/interrupt_handlers.asm index 03c4e01..50123a4 100644 --- a/src/src/asm/interrupt_handlers.asm +++ b/src/src/asm/interrupt_handlers.asm @@ -1,26 +1,23 @@ BITS 64 extern interrupt_handler; -extern gdt64.data; +section .text %assign i 0 -%rep 34 +%rep 33 global isr%+i %assign i i+1 %endrep -section .interrupt_handlers %assign i 0 -%rep 34 +%rep 33 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: From bf5db61d26ced41685f5d3fbd381427b4c338b25 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 07:26:41 -0400 Subject: [PATCH 07/10] Get rid of interrupt_handlers.asm This removes the trampoline from an assembly file and moves it into Rust. Fixes #33 ! --- src/Makefile | 6 +- src/interrupts/Cargo.lock | 210 ++++++++++++++++++ src/interrupts/src/lib.rs | 335 ++++++++++++++++++++--------- src/src/asm/interrupt_handlers.asm | 67 ------ 4 files changed, 447 insertions(+), 171 deletions(-) create mode 100644 src/interrupts/Cargo.lock delete mode 100644 src/src/asm/interrupt_handlers.asm 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 509d88d..498c913 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -13,51 +13,14 @@ extern crate pic; use keyboard::Keyboard; use core::intrinsics; -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(); -} - -macro_rules! define_isr { - ($name:ident, $body:expr) => { - #[no_mangle] - pub extern "C" fn isr33handler(_error_code: isize) { +macro_rules! make_idt_entry { + ($name:ident, $body:expr) => {{ + fn body() { $body } #[naked] - unsafe fn $name() { + unsafe extern fn $name() { asm!("push rbp push r15 push r14 @@ -77,7 +40,7 @@ macro_rules! define_isr { mov rsi, rsp push rsi - call isr33handler + call $0 add rsp, 8 @@ -97,19 +60,13 @@ macro_rules! define_isr { pop r15 pop rbp - iretq" :::: "volatile", "intel"); + iretq" :: "s"(body as fn()) :: "volatile", "intel"); intrinsics::unreachable(); } - } -} -define_isr!(isr33, { - let scancode = unsafe { inb(0x60) }; - Keyboard.handle_keys(scancode as usize); - - pic::eoi_for(33); - enable(); -}); + IdtEntry::new($name) + }} +} #[derive(Copy,Clone,Debug)] #[repr(packed,C)] @@ -123,6 +80,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 { @@ -147,18 +120,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; } } @@ -176,45 +139,219 @@ 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!(isr0, { + // do nothing for now + send_eoi_for(0); + enable(); + })); + + idt.set_isr(1, make_idt_entry!(isr1, { + // do nothing for now + send_eoi_for(1); + enable(); + })); + + idt.set_isr(2, make_idt_entry!(isr2, { + // do nothing for now + send_eoi_for(2); + enable(); + })); + + idt.set_isr(3, make_idt_entry!(isr3, { + // do nothing for now + send_eoi_for(3); + enable(); + })); + + idt.set_isr(4, make_idt_entry!(isr4, { + // do nothing for now + send_eoi_for(4); + enable(); + })); + + idt.set_isr(5, make_idt_entry!(isr5, { + // do nothing for now + send_eoi_for(5); + enable(); + })); + + idt.set_isr(6, make_idt_entry!(isr6, { + // do nothing for now + send_eoi_for(6); + enable(); + })); + + idt.set_isr(7, make_idt_entry!(isr7, { + // do nothing for now + send_eoi_for(7); + enable(); + })); + + idt.set_isr(8, make_idt_entry!(isr8, { + // do nothing for now + send_eoi_for(8); + enable(); + })); + + idt.set_isr(9, make_idt_entry!(isr9, { + // do nothing for now + send_eoi_for(9); + enable(); + })); + + idt.set_isr(10, make_idt_entry!(isr10, { + // do nothing for now + send_eoi_for(10); + enable(); + })); + + idt.set_isr(11, make_idt_entry!(isr11, { + // do nothing for now + send_eoi_for(11); + enable(); + })); + + idt.set_isr(12, make_idt_entry!(isr12, { + // do nothing for now + send_eoi_for(12); + enable(); + })); + + idt.set_isr(13, make_idt_entry!(isr13, { + // do nothing for now + send_eoi_for(13); + enable(); + })); + + idt.set_isr(14, make_idt_entry!(isr14, { + // do nothing for now + send_eoi_for(14); + enable(); + })); + + idt.set_isr(15, make_idt_entry!(isr15, { + // do nothing for now + send_eoi_for(15); + enable(); + })); + + idt.set_isr(16, make_idt_entry!(isr16, { + // do nothing for now + send_eoi_for(16); + enable(); + })); + + idt.set_isr(17, make_idt_entry!(isr17, { + // do nothing for now + send_eoi_for(17); + enable(); + })); + + idt.set_isr(18, make_idt_entry!(isr18, { + // do nothing for now + send_eoi_for(18); + enable(); + })); + + idt.set_isr(19, make_idt_entry!(isr19, { + // do nothing for now + send_eoi_for(19); + enable(); + })); + + idt.set_isr(20, make_idt_entry!(isr20, { + // do nothing for now + send_eoi_for(20); + enable(); + })); + + idt.set_isr(21, make_idt_entry!(isr21, { + // do nothing for now + send_eoi_for(21); + enable(); + })); + + idt.set_isr(22, make_idt_entry!(isr22, { + // do nothing for now + send_eoi_for(22); + enable(); + })); + + idt.set_isr(23, make_idt_entry!(isr23, { + // do nothing for now + send_eoi_for(23); + enable(); + })); + + idt.set_isr(24, make_idt_entry!(isr24, { + // do nothing for now + send_eoi_for(24); + enable(); + })); + + idt.set_isr(25, make_idt_entry!(isr25, { + // do nothing for now + send_eoi_for(25); + enable(); + })); + + idt.set_isr(26, make_idt_entry!(isr26, { + // do nothing for now + send_eoi_for(26); + enable(); + })); + + idt.set_isr(27, make_idt_entry!(isr27, { + // do nothing for now + send_eoi_for(27); + enable(); + })); + + idt.set_isr(28, make_idt_entry!(isr28, { + // do nothing for now + send_eoi_for(28); + enable(); + })); + + idt.set_isr(29, make_idt_entry!(isr29, { + // do nothing for now + send_eoi_for(29); + enable(); + })); + + idt.set_isr(30, make_idt_entry!(isr30, { + // do nothing for now + send_eoi_for(30); + enable(); + })); + + idt.set_isr(31, make_idt_entry!(isr31, { + // do nothing for now + send_eoi_for(31); + enable(); + })); + + 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); + + send_eoi_for(33); + enable(); + })); idt }; } - + +fn send_eoi_for(interrupt: isize) { + pic::eoi_for(interrupt); +} pub fn install() { IDT.install(); diff --git a/src/src/asm/interrupt_handlers.asm b/src/src/asm/interrupt_handlers.asm deleted file mode 100644 index 50123a4..0000000 --- a/src/src/asm/interrupt_handlers.asm +++ /dev/null @@ -1,67 +0,0 @@ -BITS 64 - -extern interrupt_handler; - -section .text - -%assign i 0 -%rep 33 -global isr%+i -%assign i i+1 -%endrep - -%assign i 0 -%rep 33 -isr%+i: - mov [number], byte i - jmp qword push_registers_and_call_handler -%assign i i+1 -%endrep - -; 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 From 8adbb8f5764ed732ca8aa26466d5c709dd8e43c7 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 07:29:59 -0400 Subject: [PATCH 08/10] Get rid of generic handler --- src/interrupts/src/lib.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index 498c913..bd2afc9 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -349,6 +349,8 @@ lazy_static! { }; } +/// This function is needed because the macros can't handle it, but can handle this. For some +/// reason. fn send_eoi_for(interrupt: isize) { pic::eoi_for(interrupt); } @@ -367,18 +369,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 - _ => panic!("interrupt {} with error code {:x}", interrupt_number, error_code), - } - - pic::eoi_for(interrupt_number); - - enable(); -} - #[inline] unsafe fn inb(port: u16) -> u8 { let ret : u8; From 6de1d266ae6f936efb6ca5686874d587a03dbf06 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 09:29:05 -0400 Subject: [PATCH 09/10] Improve ISR entry macro with unhandled entries Now, if you don't pass a body, we'll just assume it's not handled. Rock. --- src/interrupts/src/lib.rs | 232 +++++++------------------------------- 1 file changed, 40 insertions(+), 192 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index bd2afc9..031577f 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -14,6 +14,13 @@ use keyboard::Keyboard; 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 @@ -65,7 +72,7 @@ macro_rules! make_idt_entry { } IdtEntry::new($name) - }} + }}; } #[derive(Copy,Clone,Debug)] @@ -139,197 +146,38 @@ lazy_static! { }; 256] }; - idt.set_isr(0, make_idt_entry!(isr0, { - // do nothing for now - send_eoi_for(0); - enable(); - })); - - idt.set_isr(1, make_idt_entry!(isr1, { - // do nothing for now - send_eoi_for(1); - enable(); - })); - - idt.set_isr(2, make_idt_entry!(isr2, { - // do nothing for now - send_eoi_for(2); - enable(); - })); - - idt.set_isr(3, make_idt_entry!(isr3, { - // do nothing for now - send_eoi_for(3); - enable(); - })); - - idt.set_isr(4, make_idt_entry!(isr4, { - // do nothing for now - send_eoi_for(4); - enable(); - })); - - idt.set_isr(5, make_idt_entry!(isr5, { - // do nothing for now - send_eoi_for(5); - enable(); - })); - - idt.set_isr(6, make_idt_entry!(isr6, { - // do nothing for now - send_eoi_for(6); - enable(); - })); - - idt.set_isr(7, make_idt_entry!(isr7, { - // do nothing for now - send_eoi_for(7); - enable(); - })); - - idt.set_isr(8, make_idt_entry!(isr8, { - // do nothing for now - send_eoi_for(8); - enable(); - })); - - idt.set_isr(9, make_idt_entry!(isr9, { - // do nothing for now - send_eoi_for(9); - enable(); - })); - - idt.set_isr(10, make_idt_entry!(isr10, { - // do nothing for now - send_eoi_for(10); - enable(); - })); - - idt.set_isr(11, make_idt_entry!(isr11, { - // do nothing for now - send_eoi_for(11); - enable(); - })); - - idt.set_isr(12, make_idt_entry!(isr12, { - // do nothing for now - send_eoi_for(12); - enable(); - })); - - idt.set_isr(13, make_idt_entry!(isr13, { - // do nothing for now - send_eoi_for(13); - enable(); - })); - - idt.set_isr(14, make_idt_entry!(isr14, { - // do nothing for now - send_eoi_for(14); - enable(); - })); - - idt.set_isr(15, make_idt_entry!(isr15, { - // do nothing for now - send_eoi_for(15); - enable(); - })); - - idt.set_isr(16, make_idt_entry!(isr16, { - // do nothing for now - send_eoi_for(16); - enable(); - })); - - idt.set_isr(17, make_idt_entry!(isr17, { - // do nothing for now - send_eoi_for(17); - enable(); - })); - - idt.set_isr(18, make_idt_entry!(isr18, { - // do nothing for now - send_eoi_for(18); - enable(); - })); - - idt.set_isr(19, make_idt_entry!(isr19, { - // do nothing for now - send_eoi_for(19); - enable(); - })); - - idt.set_isr(20, make_idt_entry!(isr20, { - // do nothing for now - send_eoi_for(20); - enable(); - })); - - idt.set_isr(21, make_idt_entry!(isr21, { - // do nothing for now - send_eoi_for(21); - enable(); - })); - - idt.set_isr(22, make_idt_entry!(isr22, { - // do nothing for now - send_eoi_for(22); - enable(); - })); - - idt.set_isr(23, make_idt_entry!(isr23, { - // do nothing for now - send_eoi_for(23); - enable(); - })); - - idt.set_isr(24, make_idt_entry!(isr24, { - // do nothing for now - send_eoi_for(24); - enable(); - })); - - idt.set_isr(25, make_idt_entry!(isr25, { - // do nothing for now - send_eoi_for(25); - enable(); - })); - - idt.set_isr(26, make_idt_entry!(isr26, { - // do nothing for now - send_eoi_for(26); - enable(); - })); - - idt.set_isr(27, make_idt_entry!(isr27, { - // do nothing for now - send_eoi_for(27); - enable(); - })); - - idt.set_isr(28, make_idt_entry!(isr28, { - // do nothing for now - send_eoi_for(28); - enable(); - })); - - idt.set_isr(29, make_idt_entry!(isr29, { - // do nothing for now - send_eoi_for(29); - enable(); - })); - - idt.set_isr(30, make_idt_entry!(isr30, { - // do nothing for now - send_eoi_for(30); - enable(); - })); - - idt.set_isr(31, make_idt_entry!(isr31, { - // do nothing for now - send_eoi_for(31); - enable(); - })); + 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 From 1f417f5162291c2942c66702f42e7036bfdd9b7b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 13 Jun 2016 17:09:59 -0400 Subject: [PATCH 10/10] Remove unneeded function --- src/interrupts/src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/interrupts/src/lib.rs b/src/interrupts/src/lib.rs index 031577f..774ee43 100644 --- a/src/interrupts/src/lib.rs +++ b/src/interrupts/src/lib.rs @@ -189,7 +189,7 @@ lazy_static! { let scancode = unsafe { inb(0x60) }; Keyboard.handle_keys(scancode as usize); - send_eoi_for(33); + pic::eoi_for(33); enable(); })); @@ -197,12 +197,6 @@ lazy_static! { }; } -/// This function is needed because the macros can't handle it, but can handle this. For some -/// reason. -fn send_eoi_for(interrupt: isize) { - pic::eoi_for(interrupt); -} - pub fn install() { IDT.install(); }