mirror of https://github.com/vinc/moros.git
Add kernel::keyboard module
This commit is contained in:
parent
44c4cfdbd9
commit
e36bfbf3de
|
@ -1,8 +1,7 @@
|
|||
use crate::print;
|
||||
use crate::kernel::{gdt, clock, console};
|
||||
use crate::{print, kernel};
|
||||
use lazy_static::lazy_static;
|
||||
use pic8259_simple::ChainedPics;
|
||||
use spin;
|
||||
use spin::Mutex;
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
|
||||
pub const PIC_1_OFFSET: u8 = 32;
|
||||
|
@ -25,14 +24,14 @@ impl InterruptIndex {
|
|||
}
|
||||
}
|
||||
|
||||
pub static PICS: spin::Mutex<ChainedPics> = spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||
pub static PICS: Mutex<ChainedPics> = Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||
|
||||
lazy_static! {
|
||||
static ref IDT: InterruptDescriptorTable = {
|
||||
let mut idt = InterruptDescriptorTable::new();
|
||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
unsafe {
|
||||
idt.double_fault.set_handler_fn(double_fault_handler).set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
idt.double_fault.set_handler_fn(double_fault_handler).set_stack_index(kernel::gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
}
|
||||
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler);
|
||||
idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard_interrupt_handler);
|
||||
|
@ -53,7 +52,7 @@ extern "x86-interrupt" fn double_fault_handler(stack_frame: &mut InterruptStackF
|
|||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: &mut InterruptStackFrame) {
|
||||
clock::tick();
|
||||
kernel::clock::tick();
|
||||
|
||||
unsafe {
|
||||
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
|
@ -61,23 +60,11 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: &mut InterruptSt
|
|||
}
|
||||
|
||||
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: &mut InterruptStackFrame) {
|
||||
use pc_keyboard::{Keyboard, ScancodeSet1, HandleControl, layouts};
|
||||
use spin::Mutex;
|
||||
use x86_64::instructions::port::Port;
|
||||
|
||||
lazy_static! {
|
||||
static ref KEYBOARD: Mutex<Keyboard<layouts::Dvorak104Key, ScancodeSet1>> = Mutex::new(
|
||||
Keyboard::new(layouts::Dvorak104Key, ScancodeSet1, HandleControl::MapLettersToUnicode)
|
||||
);
|
||||
}
|
||||
|
||||
let mut keyboard = KEYBOARD.lock();
|
||||
let mut port = Port::new(0x60);
|
||||
|
||||
let scancode: u8 = unsafe { port.read() };
|
||||
let mut keyboard = kernel::keyboard::KEYBOARD.lock();
|
||||
let scancode = kernel::keyboard::read_scancode();
|
||||
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||
console::key_handle(key);
|
||||
kernel::console::key_handle(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
//use crate::{print, kernel};
|
||||
use lazy_static::lazy_static;
|
||||
use pc_keyboard::{Keyboard, ScancodeSet1, HandleControl, layouts};
|
||||
use spin::Mutex;
|
||||
use x86_64::instructions::port::Port;
|
||||
|
||||
lazy_static! {
|
||||
// NOTE: Replace `Dvorak104Key` with `Us104Key` for Qwerty keyboards
|
||||
// TODO: Support layout change from userspace
|
||||
pub static ref KEYBOARD: Mutex<Keyboard<layouts::Dvorak104Key, ScancodeSet1>> = Mutex::new(
|
||||
Keyboard::new(layouts::Dvorak104Key, ScancodeSet1, HandleControl::MapLettersToUnicode)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn init() {
|
||||
let mut port = Port::new(0x60);
|
||||
|
||||
// Identify
|
||||
let res = unsafe {
|
||||
port.write(0xF2 as u8); // Identify
|
||||
port.read()
|
||||
};
|
||||
if res != 0xFA { // 0xFA == ACK, 0xFE == Resend
|
||||
return init();
|
||||
}
|
||||
let res = unsafe {
|
||||
port.read()
|
||||
};
|
||||
print!("[{:.6}] keyboard: identify 0x{:X}\n", kernel::clock::clock_monotonic(), res);
|
||||
let res = unsafe {
|
||||
port.read()
|
||||
};
|
||||
print!("[{:.6}] keyboard: identify 0x{:X}\n", kernel::clock::clock_monotonic(), res);
|
||||
|
||||
// Self-test
|
||||
let res = unsafe {
|
||||
port.write(0xFF as u8); // Reset and self-test
|
||||
port.read()
|
||||
};
|
||||
if res != 0xFA { // 0xFA == ACK, 0xFE == Resend
|
||||
return init();
|
||||
}
|
||||
let res = unsafe {
|
||||
port.read()
|
||||
};
|
||||
if res == 0xAA { // 0xAA == Passed, 0xFC or 0xFD == Failed, 0xFE == Resend
|
||||
print!("[{:.6}] keyboard: self test passed\n", kernel::clock::clock_monotonic());
|
||||
} else {
|
||||
print!("[{:.6}] keyboard: self test failed (0x{:X})\n", kernel::clock::clock_monotonic(), res);
|
||||
}
|
||||
|
||||
// Switch to scancode set 2
|
||||
// TODO: Not working because PS/2 controller is configured to do the translation (0xAB, 0x41)
|
||||
let res = unsafe {
|
||||
port.write(0xF0 as u8); // Set current scancode set
|
||||
port.write(0x02 as u8); // to 2
|
||||
port.read()
|
||||
};
|
||||
if res != 0xFA { // 0xFA == ACK, 0xFE == Resend
|
||||
return init();
|
||||
}
|
||||
print!("[{:.6}] keyboard: switch to scancode set 2\n", kernel::clock::clock_monotonic());
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn read_scancode() -> u8 {
|
||||
let mut port = Port::new(0x60);
|
||||
unsafe {
|
||||
port.read()
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ pub mod console;
|
|||
pub mod fs;
|
||||
pub mod gdt;
|
||||
pub mod interrupts;
|
||||
pub mod keyboard;
|
||||
pub mod random;
|
||||
pub mod sleep;
|
||||
pub mod vga;
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod kernel;
|
|||
pub mod user;
|
||||
|
||||
pub fn init() {
|
||||
//kernel::keyboard::init();
|
||||
kernel::gdt::init();
|
||||
kernel::interrupts::init_idt();
|
||||
unsafe { kernel::interrupts::PICS.lock().initialize() };
|
||||
|
|
Loading…
Reference in New Issue