From 77833d0b649f5daa5a03cb8ddea3c2048031b583 Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Fri, 17 Jul 2015 17:40:15 +0800 Subject: [PATCH] MdeModulePkg: Add Ps2MouseDxe driver Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Reviewed-by: Feng Tian --- MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c | 858 ++++++++++++++++++ MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.h | 395 ++++++++ .../Bus/Isa/Ps2MouseDxe/ComponentName.c | 223 +++++ MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c | 805 ++++++++++++++++ MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.h | 399 ++++++++ .../Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf | 76 ++ .../Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.uni | 22 + .../Bus/Isa/Ps2MouseDxe/Ps2MouseDxeExtra.uni | 20 + MdeModulePkg/MdeModulePkg.dec | 7 + MdeModulePkg/MdeModulePkg.dsc | 1 + 10 files changed, 2806 insertions(+) create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.h create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/ComponentName.c create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.h create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.uni create mode 100644 MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxeExtra.uni diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c new file mode 100644 index 0000000000..7539c3217a --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c @@ -0,0 +1,858 @@ +/** @file + PS2 Mouse Communication Interface. + +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Ps2Mouse.h" +#include "CommPs2.h" + +UINT8 SampleRateTbl[MaxSampleRate] = { 0xa, 0x14, 0x28, 0x3c, 0x50, 0x64, 0xc8 }; + +UINT8 ResolutionTbl[MaxResolution] = { 0, 1, 2, 3 }; + +/** + Issue self test command via IsaIo interface. + + @return EFI_SUCCESS Success to do keyboard self testing. + @return others Fail to do keyboard self testing. +**/ +EFI_STATUS +KbcSelfTest ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 Data; + + // + // Keyboard controller self test + // + Status = Out8042Command (SELF_TEST); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Read return code + // + Status = In8042Data (&Data); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Data != 0x55) { + return EFI_DEVICE_ERROR; + } + // + // Set system flag + // + Status = Out8042Command (READ_CMD_BYTE); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = In8042Data (&Data); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = Out8042Command (WRITE_CMD_BYTE); + if (EFI_ERROR (Status)) { + return Status; + } + + Data |= CMD_SYS_FLAG; + Status = Out8042Data (Data); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + Issue command to enable keyboard AUX functionality. + + @return Status of command issuing. +**/ +EFI_STATUS +KbcEnableAux ( + VOID + ) +{ + // + // Send 8042 enable mouse command + // + return Out8042Command (ENABLE_AUX); +} + +/** + Issue command to disable keyboard AUX functionality. + + @param IsaIo Pointer to instance of EFI_ISA_IO_PROTOCOL + + @return Status of command issuing. +**/ +EFI_STATUS +KbcDisableAux ( + VOID + ) +{ + // + // Send 8042 disable mouse command + // + return Out8042Command (DISABLE_AUX); +} + +/** + Issue command to enable keyboard. + + @param IsaIo Pointer to instance of EFI_ISA_IO_PROTOCOL + + @return Status of command issuing. +**/ +EFI_STATUS +KbcEnableKb ( + VOID + ) +{ + // + // Send 8042 enable keyboard command + // + return Out8042Command (ENABLE_KB); +} + +/** + Issue command to disable keyboard. + + @return Status of command issuing. +**/ +EFI_STATUS +KbcDisableKb ( + VOID + ) +{ + // + // Send 8042 disable keyboard command + // + return Out8042Command (DISABLE_KB); +} + +/** + Issue command to check keyboard status. + + @param KeyboardEnable return whether keyboard is enable. + + @return Status of command issuing. +**/ +EFI_STATUS +CheckKbStatus ( + OUT BOOLEAN *KeyboardEnable + ) +{ + EFI_STATUS Status; + UINT8 Data; + + // + // Send command to read KBC command byte + // + Status = Out8042Command (READ_CMD_BYTE); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = In8042Data (&Data); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Check keyboard enable or not + // + if ((Data & CMD_KB_STS) == CMD_KB_DIS) { + *KeyboardEnable = FALSE; + } else { + *KeyboardEnable = TRUE; + } + + return EFI_SUCCESS; +} + +/** + Issue command to reset keyboard. + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseReset ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 Data; + + Status = Out8042AuxCommand (RESET_CMD, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = In8042AuxData (&Data); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Check BAT Complete Code + // + if (Data != PS2MOUSE_BAT1) { + return EFI_DEVICE_ERROR; + } + + Status = In8042AuxData (&Data); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Check BAT Complete Code + // + if (Data != PS2MOUSE_BAT2) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Issue command to set mouse's sample rate + + @param SampleRate value of sample rate + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseSetSampleRate ( + IN MOUSE_SR SampleRate + ) +{ + EFI_STATUS Status; + + // + // Send auxiliary command to set mouse sample rate + // + Status = Out8042AuxCommand (SETSR_CMD, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = Out8042AuxData (SampleRateTbl[SampleRate]); + + return Status; +} + +/** + Issue command to set mouse's resolution. + + @param Resolution value of resolution + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseSetResolution ( + IN MOUSE_RE Resolution + ) +{ + EFI_STATUS Status; + + // + // Send auxiliary command to set mouse resolution + // + Status = Out8042AuxCommand (SETRE_CMD, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = Out8042AuxData (ResolutionTbl[Resolution]); + + return Status; +} + +/** + Issue command to set mouse's scaling. + + @param Scaling value of scaling + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseSetScaling ( + IN MOUSE_SF Scaling + ) +{ + // + // Send auxiliary command to set mouse scaling data + // + return Out8042AuxCommand (Scaling == Scaling1 ? SETSF1_CMD : SETSF2_CMD, FALSE); +} + +/** + Issue command to enable Ps2 mouse. + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseEnable ( + VOID + ) +{ + // + // Send auxiliary command to enable mouse + // + return Out8042AuxCommand (ENABLE_CMD, FALSE); +} + +/** + Get mouse packet . Only care first 3 bytes + + @param MouseDev Pointer of PS2 Mouse Private Data Structure + + @retval EFI_NOT_READY Mouse Device not ready to input data packet, or some error happened during getting the packet + @retval EFI_SUCCESS The data packet is gotten successfully. + +**/ +EFI_STATUS +PS2MouseGetPacket ( + PS2_MOUSE_DEV *MouseDev + ) + +{ + EFI_STATUS Status; + BOOLEAN KeyboardEnable; + UINT8 Packet[PS2_PACKET_LENGTH]; + UINT8 Data; + UINTN Count; + UINTN State; + INT16 RelativeMovementX; + INT16 RelativeMovementY; + BOOLEAN LButton; + BOOLEAN RButton; + + KeyboardEnable = FALSE; + Count = 1; + State = PS2_READ_BYTE_ONE; + + // + // State machine to get mouse packet + // + while (1) { + + switch (State) { + case PS2_READ_BYTE_ONE: + // + // Read mouse first byte data, if failed, immediately return + // + KbcDisableAux (); + Status = PS2MouseRead (&Data, &Count, State); + if (EFI_ERROR (Status)) { + KbcEnableAux (); + return EFI_NOT_READY; + } + + if (Count != 1) { + KbcEnableAux (); + return EFI_NOT_READY; + } + + if (IS_PS2_SYNC_BYTE (Data)) { + Packet[0] = Data; + State = PS2_READ_DATA_BYTE; + + CheckKbStatus (&KeyboardEnable); + KbcDisableKb (); + KbcEnableAux (); + } + break; + + case PS2_READ_DATA_BYTE: + Count = 2; + Status = PS2MouseRead ((Packet + 1), &Count, State); + if (EFI_ERROR (Status)) { + if (KeyboardEnable) { + KbcEnableKb (); + } + + return EFI_NOT_READY; + } + + if (Count != 2) { + if (KeyboardEnable) { + KbcEnableKb (); + } + + return EFI_NOT_READY; + } + + State = PS2_PROCESS_PACKET; + break; + + case PS2_PROCESS_PACKET: + if (KeyboardEnable) { + KbcEnableKb (); + } + // + // Decode the packet + // + RelativeMovementX = Packet[1]; + RelativeMovementY = Packet[2]; + // + // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 + // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn + // Byte 1 | 8 bit X Movement + // Byte 2 | 8 bit Y Movement + // + // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission. + // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement. + // + // + // First, Clear X and Y high 8 bits + // + RelativeMovementX = (INT16) (RelativeMovementX & 0xFF); + RelativeMovementY = (INT16) (RelativeMovementY & 0xFF); + // + // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff + // + if ((Packet[0] & 0x10) != 0) { + RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00); + } + if ((Packet[0] & 0x20) != 0) { + RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00); + } + + + RButton = (UINT8) (Packet[0] & 0x2); + LButton = (UINT8) (Packet[0] & 0x1); + + // + // Update mouse state + // + MouseDev->State.RelativeMovementX += RelativeMovementX; + MouseDev->State.RelativeMovementY -= RelativeMovementY; + MouseDev->State.RightButton = (UINT8) (RButton ? TRUE : FALSE); + MouseDev->State.LeftButton = (UINT8) (LButton ? TRUE : FALSE); + MouseDev->StateChanged = TRUE; + + return EFI_SUCCESS; + } + } +} + +/** + Read data via IsaIo protocol with given number. + + @param Buffer Buffer receive data of mouse + @param BufSize The size of buffer + @param State Check input or read data + + @return status of reading mouse data. +**/ +EFI_STATUS +PS2MouseRead ( + OUT UINT8 *Buffer, + IN OUT UINTN *BufSize, + IN UINTN State + ) +{ + EFI_STATUS Status; + UINTN BytesRead; + + Status = EFI_SUCCESS; + + if (State == PS2_READ_BYTE_ONE) { + // + // Check input for mouse + // + Status = CheckForInput (); + + if (EFI_ERROR (Status)) { + return Status; + } + } + + for (BytesRead = 0; BytesRead < *BufSize; BytesRead++) { + + Status = WaitOutputFull (TIMEOUT); + if (EFI_ERROR (Status)) { + break; + } + Buffer[BytesRead] = IoRead8 (KBC_DATA_PORT); + } + // + // Verify the correct number of bytes read + // + if (BytesRead == 0 || BytesRead != *BufSize) { + Status = EFI_NOT_FOUND; + } + + *BufSize = BytesRead; + return Status; +} + +// +// 8042 I/O function +// +/** + I/O work flow of outing 8042 command. + + @param Command I/O command. + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042Command ( + IN UINT8 Command + ) +{ + EFI_STATUS Status; + + // + // Wait keyboard controller input buffer empty + // + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Send command + // + IoWrite8 (KBC_CMD_STS_PORT, Command); + + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + I/O work flow of outing 8042 data. + + @param Data Data value + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042Data ( + IN UINT8 Data + ) +{ + EFI_STATUS Status; + // + // Wait keyboard controller input buffer empty + // + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + IoWrite8 (KBC_DATA_PORT, Data); + return WaitInputEmpty (TIMEOUT); +} + +/** + I/O work flow of in 8042 data. + + @param Data Data value + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +In8042Data ( + IN OUT UINT8 *Data + ) +{ + UINTN Delay; + + Delay = TIMEOUT / 50; + + do { + // + // Check keyboard controller status bit 0(output buffer status) + // + if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) { + break; + } + + gBS->Stall (50); + Delay--; + } while (Delay != 0); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + *Data = IoRead8 (KBC_DATA_PORT); + + return EFI_SUCCESS; +} + +/** + I/O work flow of outing 8042 Aux command. + + @param Command Aux I/O command + @param Resend Whether need resend the Aux command. + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042AuxCommand ( + IN UINT8 Command, + IN BOOLEAN Resend + ) +{ + EFI_STATUS Status; + UINT8 Data; + + // + // Wait keyboard controller input buffer empty + // + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Send write to auxiliary device command + // + IoWrite8 (KBC_CMD_STS_PORT, WRITE_AUX_DEV); + + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Send auxiliary device command + // + IoWrite8 (KBC_DATA_PORT, Command); + + // + // Read return code + // + Status = In8042AuxData (&Data); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Data == PS2_ACK) { + // + // Receive mouse acknowledge, command send success + // + return EFI_SUCCESS; + + } else if (Resend) { + // + // Resend fail + // + return EFI_DEVICE_ERROR; + + } else if (Data == PS2_RESEND) { + // + // Resend command + // + Status = Out8042AuxCommand (Command, TRUE); + if (EFI_ERROR (Status)) { + return Status; + } + + } else { + // + // Invalid return code + // + return EFI_DEVICE_ERROR; + + } + + return EFI_SUCCESS; +} + +/** + I/O work flow of outing 8042 Aux data. + + @param Data Buffer holding return value + + @retval EFI_SUCCESS Success to excute I/O work flow. + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042AuxData ( + IN UINT8 Data + ) +{ + EFI_STATUS Status; + // + // Wait keyboard controller input buffer empty + // + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Send write to auxiliary device command + // + IoWrite8 (KBC_CMD_STS_PORT, WRITE_AUX_DEV); + + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + IoWrite8 (KBC_DATA_PORT, Data); + + Status = WaitInputEmpty (TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + I/O work flow of in 8042 Aux data. + + @param Data Buffer holding return value. + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +In8042AuxData ( + IN OUT UINT8 *Data + ) +{ + EFI_STATUS Status; + + // + // wait for output data + // + Status = WaitOutputFull (BAT_TIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } + + *Data = IoRead8 (KBC_DATA_PORT); + + return EFI_SUCCESS; +} + + +/** + Check keyboard controller status, if it is output buffer full and for auxiliary device. + + @retval EFI_SUCCESS Keyboard controller is ready + @retval EFI_NOT_READY Keyboard controller is not ready +**/ +EFI_STATUS +CheckForInput ( + VOID + ) +{ + UINT8 Data; + + Data = IoRead8 (KBC_CMD_STS_PORT); + + // + // Check keyboard controller status, if it is output buffer full and for auxiliary device + // + if ((Data & (KBC_OUTB | KBC_AUXB)) != (KBC_OUTB | KBC_AUXB)) { + return EFI_NOT_READY; + } + + return EFI_SUCCESS; +} + +/** + I/O work flow to wait input buffer empty in given time. + + @param Timeout Wating time. + + @retval EFI_TIMEOUT if input is still not empty in given time. + @retval EFI_SUCCESS input is empty. +**/ +EFI_STATUS +WaitInputEmpty ( + IN UINTN Timeout + ) +{ + UINTN Delay; + UINT8 Data; + + Delay = Timeout / 50; + + do { + Data = IoRead8 (KBC_CMD_STS_PORT); + + // + // Check keyboard controller status bit 1(input buffer status) + // + if ((Data & KBC_INPB) == 0) { + break; + } + + gBS->Stall (50); + Delay--; + } while (Delay != 0); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/** + I/O work flow to wait output buffer full in given time. + + @param Timeout given time + + @retval EFI_TIMEOUT output is not full in given time + @retval EFI_SUCCESS output is full in given time. +**/ +EFI_STATUS +WaitOutputFull ( + IN UINTN Timeout + ) +{ + UINTN Delay; + UINT8 Data; + + Delay = Timeout / 50; + + do { + Data = IoRead8 (KBC_CMD_STS_PORT); + + // + // Check keyboard controller status bit 0(output buffer status) + // & bit5(output buffer for auxiliary device) + // + if ((Data & (KBC_OUTB | KBC_AUXB)) == (KBC_OUTB | KBC_AUXB)) { + break; + } + + gBS->Stall (50); + Delay--; + } while (Delay != 0); + + if (Delay == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.h b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.h new file mode 100644 index 0000000000..6cf814e8f0 --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.h @@ -0,0 +1,395 @@ +/** @file + PS2 Mouse Communication Interface + +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _COMMPS2_H_ +#define _COMMPS2_H_ + +#include "Ps2Mouse.h" + +#define PS2_PACKET_LENGTH 3 +#define PS2_SYNC_MASK 0xc +#define PS2_SYNC_BYTE 0x8 + +#define IS_PS2_SYNC_BYTE(byte) ((byte & PS2_SYNC_MASK) == PS2_SYNC_BYTE) + +#define PS2_READ_BYTE_ONE 0 +#define PS2_READ_DATA_BYTE 1 +#define PS2_PROCESS_PACKET 2 + +#define TIMEOUT 50000 +#define BAT_TIMEOUT 500000 + +// +// 8042 I/O Port +// +#define KBC_DATA_PORT 0x60 +#define KBC_CMD_STS_PORT 0x64 + +// +// 8042 Command +// +#define READ_CMD_BYTE 0x20 +#define WRITE_CMD_BYTE 0x60 +#define DISABLE_AUX 0xa7 +#define ENABLE_AUX 0xa8 +#define SELF_TEST 0xaa +#define DISABLE_KB 0xad +#define ENABLE_KB 0xae +#define WRITE_AUX_DEV 0xd4 + +#define CMD_SYS_FLAG 0x04 +#define CMD_KB_STS 0x10 +#define CMD_KB_DIS 0x10 +#define CMD_KB_EN 0x0 + +// +// 8042 Auxiliary Device Command +// +#define SETSF1_CMD 0xe6 +#define SETSF2_CMD 0xe7 +#define SETRE_CMD 0xe8 +#define READ_CMD 0xeb +#define SETRM_CMD 0xf0 +#define SETSR_CMD 0xf3 +#define ENABLE_CMD 0xf4 +#define DISABLE_CMD 0xf5 +#define RESET_CMD 0xff + +// +// return code +// +#define PS2_ACK 0xfa +#define PS2_RESEND 0xfe +#define PS2MOUSE_BAT1 0xaa +#define PS2MOUSE_BAT2 0x0 + +// +// Keyboard Controller Status +// +/// +/// Parity Error +/// +#define KBC_PARE 0x80 +/// +/// General Time Out +/// +#define KBC_TIM 0x40 +/// +/// Output buffer for auxiliary device (PS/2): +/// 0 - Holds keyboard data +/// 1 - Holds data for auxiliary device +/// +#define KBC_AUXB 0x20 +/// +/// Keyboard lock status: +/// 0 - keyboard locked +/// 1 - keyboard free +/// +#define KBC_KEYL 0x10 +/// +/// Command/Data: +/// 0 - data byte written via port 60h +/// 1 - command byte written via port 64h +/// +#define KBC_CD 0x08 +/// +/// System Flag: +/// 0 - power-on reset +/// 1 - self-test successful +/// +#define KBC_SYSF 0x04 +/// +/// Input Buffer Status : +/// 0 - input buffer empty +/// 1 - CPU data in input buffer +/// +#define KBC_INPB 0x02 +/// +/// Output Buffer Status : +/// 0 - output buffer empty +/// 1 - keyboard controller data in output buffer +/// +#define KBC_OUTB 0x01 + +/** + Issue self test command via IsaIo interface. + + @return EFI_SUCCESS Success to do keyboard self testing. + @return others Fail to do keyboard self testing. +**/ +EFI_STATUS +KbcSelfTest ( + VOID + ); + +/** + Issue command to enable keyboard AUX functionality. + + @return Status of command issuing. +**/ +EFI_STATUS +KbcEnableAux ( + VOID + ); + +/** + Issue command to disable keyboard AUX functionality. + + @return Status of command issuing. +**/ +EFI_STATUS +KbcDisableAux ( + VOID + ); + +/** + Issue command to enable keyboard. + + @return Status of command issuing. +**/ +EFI_STATUS +KbcEnableKb ( + VOID + ); + +/** + Issue command to disable keyboard. + + @return Status of command issuing. +**/ +EFI_STATUS +KbcDisableKb ( + VOID + ); + +/** + Issue command to check keyboard status. + + @param KeyboardEnable return whether keyboard is enable. + + @return Status of command issuing. +**/ +EFI_STATUS +CheckKbStatus ( + OUT BOOLEAN *KeyboardEnable + ); + +/** + Issue command to reset keyboard. + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseReset ( + VOID + ); + +/** + Issue command to set mouse's sample rate + + @param SampleRate value of sample rate + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseSetSampleRate ( + IN MOUSE_SR SampleRate + ); + +/** + Issue command to set mouse's resolution. + + @param Resolution value of resolution + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseSetResolution ( + IN MOUSE_RE Resolution + ); + +/** + Issue command to set mouse's scaling. + + @param Scaling value of scaling + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseSetScaling ( + IN MOUSE_SF Scaling + ); + +/** + Issue command to enable Ps2 mouse. + + @return Status of command issuing. +**/ +EFI_STATUS +PS2MouseEnable ( + VOID + ); + +/** + Get mouse packet . Only care first 3 bytes + + @param MouseDev Pointer of PS2 Mouse Private Data Structure + + @retval EFI_NOT_READY Mouse Device not ready to input data packet, or some error happened during getting the packet + @retval EFI_SUCCESS The data packet is gotten successfully. + +**/ +EFI_STATUS +PS2MouseGetPacket ( + PS2_MOUSE_DEV *MouseDev + ); + +/** + Read data via IsaIo protocol with given number. + + @param Buffer Buffer receive data of mouse + @param BufSize The size of buffer + @param State Check input or read data + + @return status of reading mouse data. +**/ +EFI_STATUS +PS2MouseRead ( + OUT VOID *Buffer, + IN OUT UINTN *BufSize, + IN UINTN State + ); + +// +// 8042 I/O function +// +/** + I/O work flow of outing 8042 command. + + @param Command I/O command. + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042Command ( + IN UINT8 Command + ); + +/** + I/O work flow of in 8042 data. + + @param Data Data value + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +In8042Data ( + IN OUT UINT8 *Data + ); + +/** + I/O work flow of outing 8042 data. + + @param Data Data value + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042Data ( + IN UINT8 Data + ); + +/** + I/O work flow of outing 8042 Aux command. + + @param Command Aux I/O command + @param Resend Whether need resend the Aux command. + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042AuxCommand ( + IN UINT8 Command, + IN BOOLEAN Resend + ); + +/** + I/O work flow of in 8042 Aux data. + + @param Data Buffer holding return value. + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +In8042AuxData ( + IN OUT UINT8 *Data + ); + +/** + I/O work flow of outing 8042 Aux data. + + @param Data Buffer holding return value + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +Out8042AuxData ( + IN UINT8 Data + ); + +/** + Check keyboard controller status, if it is output buffer full and for auxiliary device. + + @retval EFI_SUCCESS Keyboard controller is ready + @retval EFI_NOT_READY Keyboard controller is not ready +**/ +EFI_STATUS +CheckForInput ( + VOID + ); + +/** + I/O work flow to wait input buffer empty in given time. + + @param Timeout Wating time. + + @retval EFI_TIMEOUT if input is still not empty in given time. + @retval EFI_SUCCESS input is empty. +**/ +EFI_STATUS +WaitInputEmpty ( + IN UINTN Timeout + ); + +/** + I/O work flow to wait output buffer full in given time. + + @param Timeout given time + + @retval EFI_TIMEOUT output is not full in given time + @retval EFI_SUCCESS output is full in given time. +**/ +EFI_STATUS +WaitOutputFull ( + IN UINTN Timeout + ); + +#endif + diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/ComponentName.c b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/ComponentName.c new file mode 100644 index 0000000000..962480265b --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/ComponentName.c @@ -0,0 +1,223 @@ +/** @file + UEFI Component Name(2) protocol implementation for Ps2MouseDxe driver. + +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Ps2Mouse.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPs2MouseComponentName = { + Ps2MouseComponentNameGetDriverName, + Ps2MouseComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPs2MouseComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) Ps2MouseComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) Ps2MouseComponentNameGetControllerName, + "en" +}; + + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPs2MouseDriverNameTable[] = { + { + "eng;en", + L"PS/2 Mouse Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ps2MouseComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mPs2MouseDriverNameTable, + DriverName, + (BOOLEAN)(This == &gPs2MouseComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ps2MouseComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol; + PS2_MOUSE_DEV *MouseDev; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + // + // Check Controller's handle + // + Status = EfiTestManagedDevice (ControllerHandle, gPS2MouseDriver.DriverBindingHandle, &gEfiSioProtocolGuid); + + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get the device context + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimplePointerProtocolGuid, + (VOID **) &SimplePointerProtocol, + gPS2MouseDriver.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol); + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + MouseDev->ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gPs2MouseComponentName) + ); +} diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c new file mode 100644 index 0000000000..91fac556cf --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c @@ -0,0 +1,805 @@ +/** @file + PS/2 Mouse driver. Routines that interacts with callers, + conforming to EFI driver model. + +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Ps2Mouse.h" +#include "CommPs2.h" + +/// +/// DriverBinding Protocol Instance +/// +EFI_DRIVER_BINDING_PROTOCOL gPS2MouseDriver = { + PS2MouseDriverSupported, + PS2MouseDriverStart, + PS2MouseDriverStop, + 0xa, + NULL, + NULL +}; + +/** + Test to see if this driver supports ControllerHandle. Any ControllerHandle + than contains a IsaIo protocol can be supported. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to test + @param RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver supports this device + @retval EFI_ALREADY_STARTED This driver is already running on this device + @retval other This driver does not support this device + +**/ +EFI_STATUS +EFIAPI +PS2MouseDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_SIO_PROTOCOL *Sio; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + ACPI_HID_DEVICE_PATH *Acpi; + + // + // Check whether the controller is keyboard. + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + do { + Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; + DevicePath = NextDevicePathNode (DevicePath); + } while (!IsDevicePathEnd (DevicePath)); + + if (DevicePathType (Acpi) != ACPI_DEVICE_PATH || + (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) { + return EFI_UNSUPPORTED; + } + + switch (Acpi->HID) { + case EISA_PNP_ID (0xF03): + // + // Microsoft PS/2 style mouse + // + case EISA_PNP_ID (0xF13): + // + // PS/2 Port for PS/2-style Mice + // + break; + + case EISA_PNP_ID (0x303): + // + // IBM Enhanced (101/102-key, PS/2 mouse support) + // + if (Acpi->UID == 1) { + break; + } + + default: + return EFI_UNSUPPORTED; + break; + } + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiSioProtocolGuid, + (VOID **) &Sio, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Close the I/O Abstraction(s) used to perform the supported test + // + gBS->CloseProtocol ( + Controller, + &gEfiSioProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return Status; +} + +/** + Start this driver on ControllerHandle by opening a Sio protocol, creating + PS2_MOUSE_DEV device and install gEfiSimplePointerProtocolGuid finally. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to bind driver to + @param RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle + @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle + @retval other This driver does not support this device + +**/ +EFI_STATUS +EFIAPI +PS2MouseDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_STATUS EmptyStatus; + EFI_SIO_PROTOCOL *Sio; + PS2_MOUSE_DEV *MouseDev; + UINT8 Data; + EFI_TPL OldTpl; + EFI_STATUS_CODE_VALUE StatusCode; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + StatusCode = 0; + + // + // Open the device path protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Report that the keyboard is being enabled + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE, + DevicePath + ); + + // + // Get the ISA I/O Protocol on Controller's handle + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiSioProtocolGuid, + (VOID **) &Sio, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Raise TPL to avoid keyboard operation impact + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + // + // Allocate private data + // + MouseDev = AllocateZeroPool (sizeof (PS2_MOUSE_DEV)); + if (MouseDev == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + // + // Setup the device instance + // + MouseDev->Signature = PS2_MOUSE_DEV_SIGNATURE; + MouseDev->Handle = Controller; + MouseDev->SampleRate = SampleRate20; + MouseDev->Resolution = MouseResolution4; + MouseDev->Scaling = Scaling1; + MouseDev->DataPackageSize = 3; + MouseDev->DevicePath = DevicePath; + + // + // Resolution = 4 counts/mm + // + MouseDev->Mode.ResolutionX = 4; + MouseDev->Mode.ResolutionY = 4; + MouseDev->Mode.LeftButton = TRUE; + MouseDev->Mode.RightButton = TRUE; + + MouseDev->SimplePointerProtocol.Reset = MouseReset; + MouseDev->SimplePointerProtocol.GetState = MouseGetState; + MouseDev->SimplePointerProtocol.Mode = &(MouseDev->Mode); + + // + // Initialize keyboard controller if necessary + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST, + DevicePath + ); + + Data = IoRead8 (KBC_CMD_STS_PORT); + // + // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS. + // + if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { + // + // If nobody decodes KBC I/O port, it will read back as 0xFF. + // Check the Time-Out and Parity bit to see if it has an active KBC in system + // + Status = EFI_DEVICE_ERROR; + StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED; + goto ErrorExit; + } + + if ((Data & KBC_SYSF) != KBC_SYSF) { + Status = KbcSelfTest (); + if (EFI_ERROR (Status)) { + StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR; + goto ErrorExit; + } + } + + KbcEnableAux (); + + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT, + DevicePath + ); + + // + // Reset the mouse + // + Status = MouseDev->SimplePointerProtocol.Reset ( + &MouseDev->SimplePointerProtocol, + FeaturePcdGet (PcdPs2MouseExtendedVerification) + ); + if (EFI_ERROR (Status)) { + // + // mouse not connected + // + Status = EFI_SUCCESS; + StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED; + goto ErrorExit; + } + + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED, + DevicePath + ); + + // + // Setup the WaitForKey event + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + MouseWaitForInput, + MouseDev, + &((MouseDev->SimplePointerProtocol).WaitForInput) + ); + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + // + // Setup a periodic timer, used to poll mouse state + // + Status = gBS->CreateEvent ( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + PollMouse, + MouseDev, + &MouseDev->TimerEvent + ); + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + // + // Start timer to poll mouse (100 samples per second) + // + Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000); + if (EFI_ERROR (Status)) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + MouseDev->ControllerNameTable = NULL; + AddUnicodeString2 ( + "eng", + gPs2MouseComponentName.SupportedLanguages, + &MouseDev->ControllerNameTable, + L"PS/2 Mouse Device", + TRUE + ); + AddUnicodeString2 ( + "en", + gPs2MouseComponentName2.SupportedLanguages, + &MouseDev->ControllerNameTable, + L"PS/2 Mouse Device", + FALSE + ); + + + // + // Install protocol interfaces for the mouse device. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Controller, + &gEfiSimplePointerProtocolGuid, + &MouseDev->SimplePointerProtocol, + NULL + ); + if (EFI_ERROR (Status)) { + goto ErrorExit; + } + + gBS->RestoreTPL (OldTpl); + + return Status; + +ErrorExit: + + if (Status != EFI_DEVICE_ERROR) { + KbcDisableAux (); + } + + if (StatusCode != 0) { + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + StatusCode, + DevicePath + ); + } + + if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) { + gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput); + } + + if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) { + gBS->CloseEvent (MouseDev->TimerEvent); + } + + if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) { + FreeUnicodeStringTable (MouseDev->ControllerNameTable); + } + + if (Status != EFI_DEVICE_ERROR) { + // + // Since there will be no timer handler for mouse input any more, + // exhaust input data just in case there is still mouse data left + // + EmptyStatus = EFI_SUCCESS; + while (!EFI_ERROR (EmptyStatus)) { + EmptyStatus = In8042Data (&Data); + } + } + + if (MouseDev != NULL) { + FreePool (MouseDev); + } + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->CloseProtocol ( + Controller, + &gEfiSioProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->RestoreTPL (OldTpl); + + return Status; +} + +/** + Stop this driver on ControllerHandle. Support stoping any child handles + created by this driver. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to stop driver on + @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of + children is zero stop the entire bus driver. + @param ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle + @retval other This driver was not removed from this device + +**/ +EFI_STATUS +EFIAPI +PS2MouseDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol; + PS2_MOUSE_DEV *MouseDev; + UINT8 Data; + + Status = gBS->OpenProtocol ( + Controller, + &gEfiSimplePointerProtocolGuid, + (VOID **) &SimplePointerProtocol, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol); + + // + // Report that the keyboard is being disabled + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE, + MouseDev->DevicePath + ); + + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEfiSimplePointerProtocolGuid, + &MouseDev->SimplePointerProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Cancel mouse data polling timer, close timer event + // + gBS->SetTimer (MouseDev->TimerEvent, TimerCancel, 0); + gBS->CloseEvent (MouseDev->TimerEvent); + + // + // Since there will be no timer handler for mouse input any more, + // exhaust input data just in case there is still mouse data left + // + Status = EFI_SUCCESS; + while (!EFI_ERROR (Status)) { + Status = In8042Data (&Data); + } + + gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput); + FreeUnicodeStringTable (MouseDev->ControllerNameTable); + FreePool (MouseDev); + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + gBS->CloseProtocol ( + Controller, + &gEfiSioProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return EFI_SUCCESS; +} + +/** + Reset the Mouse and do BAT test for it, if ExtendedVerification is TRUE and + there is a mouse device connectted to system. + + @param This - Pointer of simple pointer Protocol. + @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip. + + + @retval EFI_SUCCESS - The command byte is written successfully. + @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard. + +**/ +EFI_STATUS +EFIAPI +MouseReset ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EFI_STATUS Status; + PS2_MOUSE_DEV *MouseDev; + EFI_TPL OldTpl; + BOOLEAN KeyboardEnable; + UINT8 Data; + + MouseDev = PS2_MOUSE_DEV_FROM_THIS (This); + + // + // Report reset progress code + // + REPORT_STATUS_CODE_WITH_DEVICE_PATH ( + EFI_PROGRESS_CODE, + EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET, + MouseDev->DevicePath + ); + + KeyboardEnable = FALSE; + + // + // Raise TPL to avoid keyboard operation impact + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + ZeroMem (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE)); + MouseDev->StateChanged = FALSE; + + // + // Exhaust input data + // + Status = EFI_SUCCESS; + while (!EFI_ERROR (Status)) { + Status = In8042Data (&Data); + } + + CheckKbStatus (&KeyboardEnable); + + KbcDisableKb (); + + // + // if there's data block on KBC data port, read it out + // + if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) { + IoRead8 (KBC_DATA_PORT); + } + + Status = EFI_SUCCESS; + // + // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system. + // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is + // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling + // + if (ExtendedVerification && CheckMouseConnect (MouseDev)) { + // + // Send mouse reset command and set mouse default configure + // + Status = PS2MouseReset (); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = PS2MouseSetSampleRate (MouseDev->SampleRate); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = PS2MouseSetResolution (MouseDev->Resolution); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = PS2MouseSetScaling (MouseDev->Scaling); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + + Status = PS2MouseEnable (); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } + } +Exit: + gBS->RestoreTPL (OldTpl); + + if (KeyboardEnable) { + KbcEnableKb (); + } + + return Status; +} + +/** + Check whether there is Ps/2 mouse device in system + + @param MouseDev - Mouse Private Data Structure + + @retval TRUE - Keyboard in System. + @retval FALSE - Keyboard not in System. + +**/ +BOOLEAN +CheckMouseConnect ( + IN PS2_MOUSE_DEV *MouseDev + ) + +{ + EFI_STATUS Status; + + Status = PS2MouseEnable (); + if (!EFI_ERROR (Status)) { + return TRUE; + } + + return FALSE; +} + +/** + Get and Clear mouse status. + + @param This - Pointer of simple pointer Protocol. + @param State - Output buffer holding status. + + @retval EFI_INVALID_PARAMETER Output buffer is invalid. + @retval EFI_NOT_READY Mouse is not changed status yet. + @retval EFI_SUCCESS Mouse status is changed and get successful. +**/ +EFI_STATUS +EFIAPI +MouseGetState ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN OUT EFI_SIMPLE_POINTER_STATE *State + ) +{ + PS2_MOUSE_DEV *MouseDev; + EFI_TPL OldTpl; + + MouseDev = PS2_MOUSE_DEV_FROM_THIS (This); + + if (State == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (!MouseDev->StateChanged) { + return EFI_NOT_READY; + } + + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + CopyMem (State, &(MouseDev->State), sizeof (EFI_SIMPLE_POINTER_STATE)); + + // + // clear mouse state + // + MouseDev->State.RelativeMovementX = 0; + MouseDev->State.RelativeMovementY = 0; + MouseDev->State.RelativeMovementZ = 0; + MouseDev->StateChanged = FALSE; + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; +} + +/** + + Event notification function for SIMPLE_POINTER.WaitForInput event. + Signal the event if there is input from mouse. + + @param Event event object + @param Context event context + +**/ +VOID +EFIAPI +MouseWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + PS2_MOUSE_DEV *MouseDev; + + MouseDev = (PS2_MOUSE_DEV *) Context; + + // + // Someone is waiting on the mouse event, if there's + // input from mouse, signal the event + // + if (MouseDev->StateChanged) { + gBS->SignalEvent (Event); + } + +} + +/** + Event notification function for TimerEvent event. + If mouse device is connected to system, try to get the mouse packet data. + + @param Event - TimerEvent in PS2_MOUSE_DEV + @param Context - Pointer to PS2_MOUSE_DEV structure + +**/ +VOID +EFIAPI +PollMouse ( + IN EFI_EVENT Event, + IN VOID *Context + ) + +{ + PS2_MOUSE_DEV *MouseDev; + + MouseDev = (PS2_MOUSE_DEV *) Context; + + // + // Polling mouse packet data + // + PS2MouseGetPacket (MouseDev); +} + +/** + The user Entry Point for module Ps2Mouse. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializePs2Mouse( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Install driver model protocol(s). + // + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gPS2MouseDriver, + ImageHandle, + &gPs2MouseComponentName, + &gPs2MouseComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + + return Status; +} + diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.h b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.h new file mode 100644 index 0000000000..6419b89a70 --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.h @@ -0,0 +1,399 @@ +/** @file + PS/2 Mouse driver header file. + +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PS2MOUSE_H_ +#define _PS2MOUSE_H_ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gPS2MouseDriver; +extern EFI_COMPONENT_NAME_PROTOCOL gPs2MouseComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gPs2MouseComponentName2; + +// +// PS/2 mouse sample rate +// +typedef enum { + SampleRate10, + SampleRate20, + SampleRate40, + SampleRate60, + SampleRate80, + SampleRate100, + SampleRate200, + MaxSampleRate +} MOUSE_SR; + +// +// PS/2 mouse resolution +// +typedef enum { + MouseResolution1, + MouseResolution2, + MouseResolution4, + MouseResolution8, + MaxResolution +} MOUSE_RE; + +// +// PS/2 mouse scaling +// +typedef enum { + Scaling1, + Scaling2 +} MOUSE_SF; + +// +// Driver Private Data +// +#define PS2_MOUSE_DEV_SIGNATURE SIGNATURE_32 ('p', 's', '2', 'm') + +typedef struct { + UINTN Signature; + + EFI_HANDLE Handle; + EFI_SIMPLE_POINTER_PROTOCOL SimplePointerProtocol; + EFI_SIMPLE_POINTER_STATE State; + EFI_SIMPLE_POINTER_MODE Mode; + BOOLEAN StateChanged; + + // + // PS2 Mouse device specific information + // + MOUSE_SR SampleRate; + MOUSE_RE Resolution; + MOUSE_SF Scaling; + UINT8 DataPackageSize; + + EFI_EVENT TimerEvent; + + EFI_UNICODE_STRING_TABLE *ControllerNameTable; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; +} PS2_MOUSE_DEV; + +#define PS2_MOUSE_DEV_FROM_THIS(a) CR (a, PS2_MOUSE_DEV, SimplePointerProtocol, PS2_MOUSE_DEV_SIGNATURE) + +// +// Function prototypes +// +/** + Test to see if this driver supports ControllerHandle. Any ControllerHandle + than contains a IsaIo protocol can be supported. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to test + @param RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver supports this device + @retval EFI_ALREADY_STARTED This driver is already running on this device + @retval other This driver does not support this device + +**/ +EFI_STATUS +EFIAPI +PS2MouseDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + Start this driver on ControllerHandle by opening a IsaIo + protocol, creating PS2_MOUSE_ABSOLUTE_POINTER_DEV device and install gEfiAbsolutePointerProtocolGuid + finnally. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to bind driver to + @param RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver is added to ControllerHandle + @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle + @retval other This driver does not support this device + +**/ +EFI_STATUS +EFIAPI +PS2MouseDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + Stop this driver on ControllerHandle. Support stoping any child handles + created by this driver. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to stop driver on + @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of + children is zero stop the entire bus driver. + @param ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed ControllerHandle + @retval other This driver was not removed from this device + +**/ +EFI_STATUS +EFIAPI +PS2MouseDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ps2MouseComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ps2MouseComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +/** + Reset the Mouse and do BAT test for it, if ExtendedVerification is TRUE and + there is a mouse device connectted to system. + + @param This - Pointer of simple pointer Protocol. + @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip. + + + @retval EFI_SUCCESS - The command byte is written successfully. + @retval EFI_DEVICE_ERROR - Errors occurred during reseting keyboard. + +**/ +EFI_STATUS +EFIAPI +MouseReset ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Get and Clear mouse status. + + @param This - Pointer of simple pointer Protocol. + @param State - Output buffer holding status. + + @retval EFI_INVALID_PARAMETER Output buffer is invalid. + @retval EFI_NOT_READY Mouse is not changed status yet. + @retval EFI_SUCCESS Mouse status is changed and get successful. +**/ +EFI_STATUS +EFIAPI +MouseGetState ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN OUT EFI_SIMPLE_POINTER_STATE *State + ); + +/** + + Event notification function for SIMPLE_POINTER.WaitForInput event. + Signal the event if there is input from mouse. + + @param Event event object + @param Context event context + +**/ +VOID +EFIAPI +MouseWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Event notification function for TimerEvent event. + If mouse device is connected to system, try to get the mouse packet data. + + @param Event - TimerEvent in PS2_MOUSE_DEV + @param Context - Pointer to PS2_MOUSE_DEV structure + +**/ +VOID +EFIAPI +PollMouse ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + I/O work flow of in 8042 data. + + @param Data Data value + + @retval EFI_SUCCESS Success to excute I/O work flow + @retval EFI_TIMEOUT Keyboard controller time out. +**/ +EFI_STATUS +In8042Data ( + IN OUT UINT8 *Data + ); + +/** + Check whether there is Ps/2 mouse device in system + + @param MouseDev - Mouse Private Data Structure + + @retval TRUE - Keyboard in System. + @retval FALSE - Keyboard not in System. + +**/ +BOOLEAN +CheckMouseConnect ( + IN PS2_MOUSE_DEV *MouseDev + ); + +#endif diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf new file mode 100644 index 0000000000..1d257f5dfa --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf @@ -0,0 +1,76 @@ +## @file +# PS2 Mouse Driver. +# +# This dirver provides support for PS2 based mice. +# +# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Ps2MouseDxe + MODULE_UNI_FILE = Ps2MouseDxe.uni + FILE_GUID = 202A2B0E-9A31-4812-B291-8747DF152439 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitializePs2Mouse + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# DRIVER_BINDING = gPS2MouseDriver; +# COMPONENT_NAME = gPs2MouseComponentName; +# COMPONENT_NAME2 = gPs2MouseComponentName2; +# + +[Sources] + ComponentName.c + CommPs2.h + CommPs2.c + Ps2Mouse.h + Ps2Mouse.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + ReportStatusCodeLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + UefiLib + UefiDriverEntryPoint + DebugLib + PcdLib + IoLib + DevicePathLib + +[Protocols] + gEfiSioProtocolGuid ## TO_START + gEfiSimplePointerProtocolGuid ## BY_START + gEfiDevicePathProtocolGuid ## TO_START + +[FeaturePcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification ## CONSUMES + +# +# [Event] +# +# ## +# # Timer event used to check the mouse state at a regular interval. +# # +# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES +# + +[UserExtensions.TianoCore."ExtraFiles"] + Ps2MouseDxeExtra.uni diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.uni b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.uni new file mode 100644 index 0000000000..417474411d --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.uni @@ -0,0 +1,22 @@ +// /** @file +// PS2 Mouse Driver. +// +// This dirver provides support for PS2 based mice. +// +// Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "PS2 Mouse Driver" + +#string STR_MODULE_DESCRIPTION #language en-US "This driver provides support for PS2-based mice." + diff --git a/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxeExtra.uni b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxeExtra.uni new file mode 100644 index 0000000000..fee64d8d18 --- /dev/null +++ b/MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxeExtra.uni @@ -0,0 +1,20 @@ +// /** @file +// Ps2MouseDxe Localized Strings and Content +// +// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"PS2 Mouse DXE Driver" + + diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index e74b0d92ac..49bd105db7 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -731,6 +731,13 @@ # @Prompt Enable export HII data and configuration to be used in OS runtime. gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|TRUE|BOOLEAN|0x00010074 + ## Indicates if PS2 mouse does a extended verification during start. + # Extended verification will take some performance. It can be set to FALSE for boot performance.

+ # TRUE - Turn on PS2 mouse extended verification.
+ # FALSE - Turn off PS2 mouse extended verification.
+ # @Prompt Turn on PS2 Mouse Extended Verification + gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|TRUE|BOOLEAN|0x00010075 + [PcdsFeatureFlag.IA32, PcdsFeatureFlag.X64] ## Indicates if DxeIpl should switch to long mode to enter DXE phase. # It is assumed that 64-bit DxeCore is built in firmware if it is true; otherwise 32-bit DxeCore diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index f1d7a1470a..c2f5171451 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -248,6 +248,7 @@ MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf MdeModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf + MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf MdeModulePkg/Core/Dxe/DxeMain.inf { -- 2.39.2