1
0
mirror of https://github.com/rcore-os/rCore.git synced 2025-01-19 01:07:05 +04:00

Move keyboard to drivers

This commit is contained in:
Jiajie Chen 2020-06-20 16:13:08 +08:00
parent 9732f2148d
commit 88544bdd3c
8 changed files with 102 additions and 86 deletions

View File

@ -1,34 +0,0 @@
use crate::sync::SpinLock as Mutex;
use lazy_static::lazy_static;
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
use x86_64::instructions::port::Port;
pub fn init() {
use crate::arch::interrupt::consts;
use crate::arch::interrupt::enable_irq;
enable_irq(consts::Keyboard);
info!("keyboard: init end");
}
/// Receive character from keyboard
/// Should be called on every interrupt
pub fn receive() -> Option<DecodedKey> {
lazy_static! {
static ref KEYBOARD: Mutex<Keyboard<layouts::Us104Key, ScancodeSet1>> = Mutex::new(
Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore)
);
}
let mut keyboard = KEYBOARD.lock();
let mut data_port = Port::<u8>::new(0x60);
let mut status_port = Port::<u8>::new(0x64);
// Output buffer status = 1
if unsafe { status_port.read() } & (1 << 0) != 0 {
let scancode = unsafe { data_port.read() };
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
return keyboard.process_keyevent(key_event);
}
}
None
}

View File

@ -1,12 +0,0 @@
pub mod keyboard;
use super::BootInfo;
pub fn init(_boot_info: &BootInfo) {
keyboard::init();
}
pub fn init_graphic(boot_info: &BootInfo) {
super::board::init_driver(boot_info);
crate::drivers::console::init();
}

View File

@ -28,9 +28,6 @@ pub const Syscall32: usize = 0x80;
// IRQ
pub const Timer: usize = 0;
pub const Keyboard: usize = 1;
pub const COM2: usize = 3;
pub const COM1: usize = 4;
pub const Error: usize = 19;
pub const Spurious: usize = 31;

View File

@ -97,10 +97,9 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
}
*/
}
Keyboard => keyboard(),
_ => {
if IRQ_MANAGER.read().try_handle_interrupt(Some(irq)) {
debug!("driver processed interrupt");
trace!("driver processed interrupt");
return;
}
warn!("unhandled external IRQ number: {}", irq);
@ -152,33 +151,3 @@ fn page_fault(tf: &mut TrapFrame) {
error!("\nEXCEPTION: Page Fault @ {:#x}, code: {:?}", addr, code);
loop {}
}
fn keyboard() {
use crate::arch::driver::keyboard;
use pc_keyboard::{DecodedKey, KeyCode};
trace!("\nInterupt: Keyboard");
if let Some(key) = keyboard::receive() {
match key {
DecodedKey::Unicode(c) => {
// at most 4 is needed
let mut buffer = [0u8; 4];
let res = c.encode_utf8(&mut buffer);
for c in res.bytes() {
crate::trap::serial(c)
}
}
DecodedKey::RawKey(code) => {
let s = match code {
KeyCode::ArrowUp => "\u{1b}[A",
KeyCode::ArrowDown => "\u{1b}[B",
KeyCode::ArrowRight => "\u{1b}[C",
KeyCode::ArrowLeft => "\u{1b}[D",
_ => "",
};
for c in s.bytes() {
crate::trap::serial(c);
}
}
}
}
}

View File

@ -6,7 +6,6 @@ pub mod acpi;
pub mod board;
pub mod consts;
pub mod cpu;
pub mod driver;
pub mod gdt;
pub mod interrupt;
pub mod io;
@ -38,8 +37,6 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! {
// serial
crate::drivers::early_init();
// init graphic output
driver::init_graphic(boot_info);
println!("Hello world! from CPU {}!", cpu_id);
@ -64,8 +61,8 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! {
cpu::init();
// now we can start LKM.
crate::lkm::manager::ModuleManager::init();
// use IOAPIC instead of PIC, use APIC Timer instead of PIT, init serial&keyboard in x86_64
driver::init(boot_info);
// init board
board::init_driver(boot_info);
// init pci/bus-based devices ,e.g. Intel 10Gb NIC, ...
crate::drivers::init();
// init cpu scheduler and process manager, and add user shell app in process manager

View File

@ -119,6 +119,8 @@ pub fn init(dtb: usize) {
pub fn init() {
bus::pci::init();
rtc::rtc_cmos::init();
serial::keyboard::init();
console::init();
}
#[cfg(target_arch = "x86_64")]

View File

@ -0,0 +1,95 @@
//! Keyboard in x86
use super::super::DRIVERS;
use super::super::IRQ_MANAGER;
use super::{super::SERIAL_DRIVERS, SerialDriver};
use crate::{
drivers::{DeviceType, Driver},
sync::SpinNoIrqLock as Mutex,
};
use alloc::string::String;
use alloc::sync::Arc;
use pc_keyboard::{layouts, DecodedKey, HandleControl, KeyCode, ScancodeSet1};
use uart_16550::SerialPort;
use x86_64::instructions::port::Port;
pub const Keyboard: usize = 1;
struct Keyboard {
keyboard: Mutex<pc_keyboard::Keyboard<layouts::Us104Key, ScancodeSet1>>,
}
impl Keyboard {
fn new() -> Keyboard {
Keyboard {
keyboard: Mutex::new(pc_keyboard::Keyboard::new(
layouts::Us104Key,
ScancodeSet1,
HandleControl::Ignore,
)),
}
}
}
impl Driver for Keyboard {
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
let mut keyboard = self.keyboard.lock();
let mut data_port = Port::<u8>::new(0x60);
let mut status_port = Port::<u8>::new(0x64);
// Output buffer status = 1
if unsafe { status_port.read() } & (1 << 0) != 0 {
let scancode = unsafe { data_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(c) => {
// at most 4 is needed
let mut buffer = [0u8; 4];
let res = c.encode_utf8(&mut buffer);
for c in res.bytes() {
crate::trap::serial(c)
}
}
DecodedKey::RawKey(code) => {
let s = match code {
KeyCode::ArrowUp => "\u{1b}[A",
KeyCode::ArrowDown => "\u{1b}[B",
KeyCode::ArrowRight => "\u{1b}[C",
KeyCode::ArrowLeft => "\u{1b}[D",
_ => "",
};
for c in s.bytes() {
crate::trap::serial(c);
}
}
}
}
}
}
true
}
fn device_type(&self) -> DeviceType {
DeviceType::Serial
}
fn get_id(&self) -> String {
format!("keyboard")
}
}
impl SerialDriver for Keyboard {
fn read(&self) -> u8 {
unimplemented!()
}
fn write(&self, data: &[u8]) {
unimplemented!()
}
}
pub fn init() {
let keyboard = Arc::new(Keyboard::new());
DRIVERS.write().push(keyboard.clone());
SERIAL_DRIVERS.write().push(keyboard.clone());
IRQ_MANAGER.write().register_irq(Keyboard, keyboard);
}

View File

@ -5,6 +5,8 @@ use core::fmt::{Result, Write};
#[cfg(target_arch = "x86_64")]
pub mod com;
#[cfg(target_arch = "x86_64")]
pub mod keyboard;
pub trait SerialDriver: Driver {
// read one byte from tty