From aa6f248d039b8804f8fe2f59b2e73027a8914f89 Mon Sep 17 00:00:00 2001 From: Cautreoxit Date: Thu, 6 Nov 2025 20:54:17 +0800 Subject: [PATCH] Remove magic numbers in i8042 component --- .../keyboard/src/i8042_chip/controller.rs | 22 +++++++++---- .../comps/keyboard/src/i8042_chip/keyboard.rs | 32 ++++++++++++------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/kernel/comps/keyboard/src/i8042_chip/controller.rs b/kernel/comps/keyboard/src/i8042_chip/controller.rs index 9bd31ccc6..9d1c7f20c 100644 --- a/kernel/comps/keyboard/src/i8042_chip/controller.rs +++ b/kernel/comps/keyboard/src/i8042_chip/controller.rs @@ -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> = 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 { + 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) } diff --git a/kernel/comps/keyboard/src/i8042_chip/keyboard.rs b/kernel/comps/keyboard/src/i8042_chip/keyboard.rs index 49ebfe4aa..130b78144 100644 --- a/kernel/comps/keyboard/src/i8042_chip/keyboard.rs +++ b/kernel/comps/keyboard/src/i8042_chip/keyboard.rs @@ -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 = 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 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 { // Remove the release bit. - let code = self.scancode.0 & 0x7F; + let code = self.scancode.key(); // Handle extended keys. if self.extended {