From cdf09f9869428ee81dd0db7b1bdc0995ffba5234 Mon Sep 17 00:00:00 2001 From: wescande Date: Thu, 12 Apr 2018 19:37:43 +0200 Subject: [PATCH] keyboard use Pio --- kernel-rs/src/console.rs | 14 ++++------ kernel-rs/src/cpuio.rs | 7 ++++- kernel-rs/src/keyboard.rs | 59 ++++++++++++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/kernel-rs/src/console.rs b/kernel-rs/src/console.rs index 7b24dc20..3d5ca557 100644 --- a/kernel-rs/src/console.rs +++ b/kernel-rs/src/console.rs @@ -2,6 +2,7 @@ extern crate core; // extern crate multiboot2; use acpi; +use keyboard::PS2; use cpuio; use core::char; use vga::*; @@ -59,15 +60,10 @@ fn help() -> Result<(), &'static str> { /// If reboot failed, will loop on a halt cmd /// fn reboot() -> ! { - unsafe { asm!("cli") }; //TODO volatile ????? - // I will now clear the keyboard buffer - let mut buffer: u8 = 0x02; - while buffer & 0x02 != 0 { - cpuio::inb(0x60); - buffer = cpuio::inb(0x64); - } - cpuio::outb(0x64, 0xFE); //Send reset value to CPU //TODO doesn't work in QEMU ==> it seems that qemu cannot reboot - println!("Unable to perform reboot. Kernel will be halted"); + // acpi::reboot()?; + // println!("Unable to perform ACPI reboot."); + unsafe {PS2.ps2_8042_reset()};// TODO unsafe + println!("Unable to perform 8042 reboot. Kernel will be halted"); cpuio::halt(); } diff --git a/kernel-rs/src/cpuio.rs b/kernel-rs/src/cpuio.rs index 1343789d..50793228 100644 --- a/kernel-rs/src/cpuio.rs +++ b/kernel-rs/src/cpuio.rs @@ -38,9 +38,14 @@ pub fn outl(port: u16, value: u32) { unsafe { asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile") }; } +/// Disable interruption +pub fn cli() { + unsafe { asm!("cli" : : : : "volatile") }; +} + /// Halt system pub fn halt() -> ! { - unsafe { asm!("cli" : : : : "volatile") }; + cli(); loop { unsafe { asm!("hlt" : : : : "volatile") }; } diff --git a/kernel-rs/src/keyboard.rs b/kernel-rs/src/keyboard.rs index fddb2992..64daa163 100644 --- a/kernel-rs/src/keyboard.rs +++ b/kernel-rs/src/keyboard.rs @@ -2,6 +2,8 @@ extern crate core; use cpuio; use vga; +use io::Pio; +use io::Io; const MAX_KEYS: usize = 59; const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [ @@ -66,6 +68,49 @@ const KEYMAP_US: [[u8; 2]; MAX_KEYS] = [ *b"\0\0",//capslock ]; + +pub static mut PS2: Ps2 = Ps2::new(); + +pub struct Ps2 { + status: Pio, + data: Pio, +} + +impl Ps2 { + pub const fn new() -> Ps2 { + Ps2 { + status: Pio::new(0x64), + data: Pio::new(0x60), + } + } + + pub fn clear_buffer(&self) { + let mut buffer: u8 = 0x02; + while buffer & 0x02 != 0 { + self.data.read(); + buffer = self.status.read(); + } + } + + pub fn ps2_8042_reset(&mut self) { + cpuio::cli(); + self.clear_buffer(); + self.status.write(0xFE); + } + + pub fn get_scancode(&self) -> u8 { + let mut scancode = 0; + loop { + if self.data.read() != scancode { + scancode = self.data.read(); + if scancode > 0 { + return scancode; + } + } + } + } +} + const TOUCH_RELEASE: u8 = 1 << 7; fn check_key_state(key: u8) -> (bool, usize) { @@ -76,23 +121,11 @@ fn check_key_state(key: u8) -> (bool, usize) { } } -fn get_scancode() -> u8 { - let mut scancode = 0; - loop { - if cpuio::inb(0x60) != scancode { - scancode = cpuio::inb(0x60); - if scancode > 0 { - return scancode; - } - } - } -} - pub fn kbd_callback() { static mut SHIFT: bool = false; static mut CTRL: bool = false; static mut ALT: bool = false; - let scancode = get_scancode(); + let scancode = unsafe { PS2.get_scancode() }; let (is_release, scancode) = check_key_state(scancode); unsafe { //TODO remove unsafe