From a9e28e9ce9607ebd1953898dda370c22d4f1425d Mon Sep 17 00:00:00 2001 From: LoGin Date: Sat, 26 Oct 2024 12:55:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=B4=E6=97=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=94=AE=E7=9B=98=E9=A9=B1=E5=8A=A8=E4=B8=8E=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E5=86=B2=E7=AA=81=E5=AF=BC=E8=87=B4=E9=94=AE?= =?UTF-8?q?=E7=9B=98=E6=97=A0=E5=93=8D=E5=BA=94=20(#1014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 暂时通过条件编译的方式解决. 目前认为是鼠标驱动问题,没有正确判断是不是自己的数据... 但是因为我们场景下,鼠标驱动几乎用不到,因此先条件编译屏蔽. Signed-off-by: longjin --- kernel/Cargo.toml | 1 + kernel/src/arch/x86_64/asm/entry.S | 1 - kernel/src/driver/input/mod.rs | 2 +- kernel/src/driver/input/serio/i8042/mod.rs | 2 +- kernel/src/driver/keyboard/ps2_keyboard.rs | 59 +++++++++++++++------- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index ebe69b99..d18d22f0 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -23,6 +23,7 @@ kvm = [] fatfs = [] fatfs-secure = ["fatfs"] +driver_ps2_mouse = [] # kprobe kprobe_test = [] diff --git a/kernel/src/arch/x86_64/asm/entry.S b/kernel/src/arch/x86_64/asm/entry.S index f61d7472..355d9938 100644 --- a/kernel/src/arch/x86_64/asm/entry.S +++ b/kernel/src/arch/x86_64/asm/entry.S @@ -54,7 +54,6 @@ Restore_all: popq %rax addq $0x10, %rsp // 弹出变量FUNC和errcode - sti iretq ret_from_exception: diff --git a/kernel/src/driver/input/mod.rs b/kernel/src/driver/input/mod.rs index 3bd4c7ee..1067a1e8 100644 --- a/kernel/src/driver/input/mod.rs +++ b/kernel/src/driver/input/mod.rs @@ -1,4 +1,4 @@ pub mod ps2_dev; -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", feature = "driver_ps2_mouse"))] pub mod ps2_mouse; pub mod serio; diff --git a/kernel/src/driver/input/serio/i8042/mod.rs b/kernel/src/driver/input/serio/i8042/mod.rs index b70873ae..a54d4281 100644 --- a/kernel/src/driver/input/serio/i8042/mod.rs +++ b/kernel/src/driver/input/serio/i8042/mod.rs @@ -69,7 +69,7 @@ pub fn i8042_setup_aux() -> Result<(), SystemError> { ))); serio_device_manager().register_port(aux_port.clone() as Arc)?; - #[cfg(target_arch = "x86_64")] + #[cfg(all(target_arch = "x86_64", feature = "driver_ps2_mouse"))] crate::driver::input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init( aux_port.clone() as Arc )?; diff --git a/kernel/src/driver/keyboard/ps2_keyboard.rs b/kernel/src/driver/keyboard/ps2_keyboard.rs index 4133be0b..94564e9f 100644 --- a/kernel/src/driver/keyboard/ps2_keyboard.rs +++ b/kernel/src/driver/keyboard/ps2_keyboard.rs @@ -8,7 +8,7 @@ use alloc::{ use unified_init::macros::unified_init; use crate::{ - arch::{io::PortIOArch, CurrentPortIOArch}, + arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch}, driver::{ base::device::device_number::{DeviceNumber, Major}, input::ps2_dev::Ps2StatusRegister, @@ -17,7 +17,7 @@ use crate::{ irqdata::IrqHandlerData, irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn}, manage::irq_manager, - IrqNumber, + InterruptArch, IrqNumber, }, filesystem::{ devfs::{devfs_register, DevFS, DeviceINode}, @@ -186,17 +186,24 @@ impl IrqHandler for Ps2KeyboardIrqHandler { _dev_id: Option>, ) -> Result { // 先检查状态寄存器,看看是否有数据 - let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; - let status = Ps2StatusRegister::from(status); - if !status.outbuf_full() { - return Ok(IrqReturn::Handled); + let mut fsm = PS2_KEYBOARD_FSM.lock(); + let mut handled = false; + loop { + let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; + let status = Ps2StatusRegister::from(status); + if status.outbuf_full() { + let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; + fsm.parse(input); + handled = true; + } else { + break; + } + } + if handled { + Ok(IrqReturn::Handled) + } else { + Ok(IrqReturn::NotHandled) } - - let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; - // wait_ps2_keyboard_read(); - PS2_KEYBOARD_FSM.lock().parse(input); - - return Ok(IrqReturn::Handled); } } @@ -219,8 +226,27 @@ fn wait_ps2_keyboard_write() { spin_loop(); } } + +fn force_clear_input_buffer() { + loop { + let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; + let status = Ps2StatusRegister::from(status); + if status.outbuf_full() { + unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; + } else { + break; + } + } +} + #[unified_init(INITCALL_DEVICE)] fn ps2_keyboard_init() -> Result<(), SystemError> { + let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; + + // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。 + // 清空键盘缓冲区 + force_clear_input_buffer(); + // ======== 初始化键盘控制器,写入配置值 ========= wait_ps2_keyboard_write(); unsafe { @@ -245,12 +271,9 @@ fn ps2_keyboard_init() -> Result<(), SystemError> { ) .expect("Failed to request irq for ps2 keyboard"); - // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。 - let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) }; - let status = Ps2StatusRegister::from(status); - if status.outbuf_full() { - unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) }; - } + // 清空键盘缓冲区 + force_clear_input_buffer(); + drop(irq_guard); // 将设备挂载到devfs ps2_keyboard_register();