Remove magic numbers in i8042 component

This commit is contained in:
Cautreoxit 2025-11-06 20:54:17 +08:00 committed by Tate, Hongliang Tian
parent f15106aed8
commit aa6f248d03
2 changed files with 37 additions and 17 deletions

View File

@ -13,10 +13,17 @@ use ostd::{
};
use spin::Once;
pub(super) const PS2_CMD_RESET: u8 = 0xFF;
pub(super) const PS2_ACK: u8 = 0xFA;
pub(super) const PS2_BAT_OK: u8 = 0xAA;
/// The `I8042Controller` singleton.
pub(super) static I8042_CONTROLLER: Once<SpinLock<I8042Controller, LocalIrqDisabled>> = Once::new();
pub(super) fn init() -> Result<(), I8042ControllerError> {
const SELF_TEST_OK: u8 = 0x55;
const PORT_TEST_OK: u8 = 0x00;
let mut controller = I8042Controller::new()?;
// The steps to initialize the i8042 controller are from:
@ -41,8 +48,8 @@ pub(super) fn init() -> Result<(), I8042ControllerError> {
// Perform controller self-test.
controller.wait_and_send_command(Command::TestController)?;
let result = controller.wait_and_recv_data()?;
if result != 0x55 {
// Any value other than 0x55 indicates a self-test fail.
if result != SELF_TEST_OK {
// Any value other than `SELF_TEST_OK` indicates a self-test fail.
return Err(I8042ControllerError::ControllerTestFailed);
}
// The self-test may reset the controller. Restore the original configuration.
@ -63,7 +70,7 @@ pub(super) fn init() -> Result<(), I8042ControllerError> {
// Perform interface tests to the first PS/2 port.
controller.wait_and_send_command(Command::TestFirstPort)?;
let result = controller.wait_and_recv_data()?;
if result != 0x00 {
if result != PORT_TEST_OK {
return Err(I8042ControllerError::FirstPortTestFailed);
}
@ -71,7 +78,7 @@ pub(super) fn init() -> Result<(), I8042ControllerError> {
if has_second_port {
controller.wait_and_send_command(Command::TestSecondPort)?;
let result = controller.wait_and_recv_data()?;
if result != 0x00 {
if result != PORT_TEST_OK {
return Err(I8042ControllerError::SecondPortTestFailed);
}
}
@ -112,6 +119,9 @@ const MAX_WAITING_COUNT: usize = 64;
impl I8042Controller {
fn new() -> Result<Self, I8042ControllerError> {
const DATA_PORT_ADDR: u16 = 0x60;
const STATUS_OR_COMMAND_PORT_ADDR: u16 = 0x64;
if ACPI_INFO
.get()
.unwrap()
@ -124,8 +134,8 @@ impl I8042Controller {
}
let controller = Self {
data_port: IoPort::acquire(0x60).unwrap(),
status_or_command_port: IoPort::acquire(0x64).unwrap(),
data_port: IoPort::acquire(DATA_PORT_ADDR).unwrap(),
status_or_command_port: IoPort::acquire(STATUS_OR_COMMAND_PORT_ADDR).unwrap(),
};
Ok(controller)
}

View File

@ -18,7 +18,9 @@ use ostd::{
};
use spin::Once;
use super::controller::{I8042Controller, I8042ControllerError, I8042_CONTROLLER};
use super::controller::{
I8042Controller, I8042ControllerError, I8042_CONTROLLER, PS2_ACK, PS2_BAT_OK, PS2_CMD_RESET,
};
use crate::alloc::string::ToString;
/// IRQ line for i8042 keyboard.
@ -31,16 +33,16 @@ static REGISTERED_DEVICE: Once<RegisteredInputDevice> = Once::new();
const ISA_INTR_NUM: u8 = 1;
pub(super) fn init(controller: &mut I8042Controller) -> Result<(), I8042ControllerError> {
// Reset keyboard device by sending 0xFF (reset command, supported by all PS/2 devices) to port 1
// Reset keyboard device by sending `PS2_CMD_RESET` (reset command, supported by all PS/2 devices) to port 1
// and waiting for a response.
controller.wait_and_send_data(0xFF)?;
controller.wait_and_send_data(PS2_CMD_RESET)?;
// The response should be 0xFA (ACK) and 0xAA (BAT successful), followed by the device PS/2 ID.
if controller.wait_and_recv_data()? != 0xFA {
// The response should be `PS2_ACK` and `PS2_BAT_OK`, followed by the device PS/2 ID.
if controller.wait_and_recv_data()? != PS2_ACK {
return Err(I8042ControllerError::DeviceResetFailed);
}
// The reset command may take some time to finish. Try again a few times.
if (0..5).find_map(|_| controller.wait_and_recv_data().ok()) != Some(0xAA) {
if (0..5).find_map(|_| controller.wait_and_recv_data().ok()) != Some(PS2_BAT_OK) {
return Err(I8042ControllerError::DeviceResetFailed);
}
// See <https://wiki.osdev.org/I8042_PS/2_Controller#Detecting_PS/2_Device_Types> for a list of IDs.
@ -87,7 +89,7 @@ impl I8042Keyboard {
capability.set_supported_event_type(aster_input::event_type_codes::EventTypes::KEY);
capability.set_supported_event_type(aster_input::event_type_codes::EventTypes::SYN);
// Adds all standard keyboard keys.
// Add all standard keyboard keys.
capability.add_standard_keyboard_keys();
Self {
@ -171,13 +173,17 @@ fn handle_keyboard_input(_trap_frame: &TrapFrame) {
struct ScanCode(u8);
impl ScanCode {
const CODE_ERROR: u8 = 0xFF;
const CODE_EXT_PREFIX: u8 = 0xE0;
const RELEASE_MASK: u8 = 0x80;
fn has_error(&self) -> bool {
// Key detection error or internal buffer overrun.
self.0 == 0xFF
self.0 == Self::CODE_ERROR
}
fn key_status(&self) -> KeyStatus {
if self.0 & 0x80 == 0 {
if self.0 & Self::RELEASE_MASK == 0 {
KeyStatus::Pressed
} else {
KeyStatus::Released
@ -185,7 +191,11 @@ impl ScanCode {
}
fn is_extension(&self) -> bool {
self.0 == 0xE0
self.0 == Self::CODE_EXT_PREFIX
}
fn key(&self) -> u8 {
self.0 & !Self::RELEASE_MASK
}
}
@ -237,7 +247,7 @@ impl ScancodeInfo {
/// Maps the keyboard [`ScanCode`] to a [`KeyCode`] in the input subsystem.
fn to_key_code(&self) -> Option<KeyCode> {
// Remove the release bit.
let code = self.scancode.0 & 0x7F;
let code = self.scancode.key();
// Handle extended keys.
if self.extended {