From 75753e9e36e45210d88a4cceeb568212f5a71ab6 Mon Sep 17 00:00:00 2001 From: Knarkzel Date: Sat, 27 Jan 2024 21:26:22 +0100 Subject: [PATCH] Keyboard --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/interrupts.rs | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 378fa15..d8dfbcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,7 @@ version = "0.1.0" dependencies = [ "bootloader", "lazy_static", + "pc-keyboard", "pic8259", "spin 0.9.8", "uart_16550", @@ -64,6 +65,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "pc-keyboard" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed089a1fbffe3337a1a345501c981f1eb1e47e69de5a40e852433e12953c3174" + [[package]] name = "pic8259" version = "0.10.4" diff --git a/Cargo.toml b/Cargo.toml index ff6d385..764831a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ uart_16550 = "0.2.0" bootloader = "0.9.23" lazy_static = { version = "1.0", features = ["spin_no_std"] } pic8259 = "0.10.4" +pc-keyboard = "0.7.0" [package.metadata.bootimage] test-success-exit-code = 33 diff --git a/src/interrupts.rs b/src/interrupts.rs index 9a28067..f93aefc 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -13,6 +13,7 @@ pub static PICS: spin::Mutex = #[repr(u8)] pub enum InterruptIndex { Timer = PIC_1_OFFSET, + Keyboard, } impl InterruptIndex { @@ -30,10 +31,12 @@ lazy_static! { let mut idt = InterruptDescriptorTable::new(); idt.breakpoint.set_handler_fn(breakpoint_handler); idt[InterruptIndex::Timer.as_usize()] - .set_handler_fn(timer_interrupt_handler); // new + .set_handler_fn(timer_interrupt_handler); + idt[InterruptIndex::Keyboard.as_usize()] + .set_handler_fn(keyboard_interrupt_handler); unsafe { idt.double_fault.set_handler_fn(double_fault_handler) - .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); // new + .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); } idt }; @@ -60,7 +63,6 @@ extern "x86-interrupt" fn double_fault_handler( panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); } - extern "x86-interrupt" fn timer_interrupt_handler( _stack_frame: InterruptStackFrame) { @@ -69,3 +71,36 @@ extern "x86-interrupt" fn timer_interrupt_handler( PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8()); } } + +extern "x86-interrupt" fn keyboard_interrupt_handler( + _stack_frame: InterruptStackFrame) +{ + use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1}; + use spin::Mutex; + use x86_64::instructions::port::Port; + + lazy_static! { + static ref KEYBOARD: Mutex> = + Mutex::new(Keyboard::new(ScancodeSet1::new(), layouts::Us104Key, + HandleControl::Ignore) + ); + } + + let mut keyboard = KEYBOARD.lock(); + let mut port = Port::new(0x60); + + let scancode: u8 = unsafe { port.read() }; + if let Ok(Some(key_event)) = keyboard.add_byte(scancode) { + if let Some(key) = keyboard.process_keyevent(key_event) { + match key { + DecodedKey::Unicode(character) => print!("{}", character), + DecodedKey::RawKey(key) => print!("{:?}", key), + } + } + } + + unsafe { + PICS.lock() + .notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8()); + } +}