BoardModulePkg: Add Ps2 Keyboard Library

Added a generic Ps2 keyboard library
that adds ps2 device path to ConIn and ConInDev
Uefi variables.

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Prince Agyeman <prince.agyeman@intel.com>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
Reviewed-by: Michael Kubacki <michael.a.kubacki@intel.com>
This commit is contained in:
Agyeman, Prince
2019-11-05 17:26:00 -08:00
committed by Michael Kubacki
parent eb4e08a20e
commit 0984a02a66
4 changed files with 306 additions and 0 deletions
@@ -88,3 +88,4 @@
BoardModulePkg/Library/BiosIdLib/PeiBiosIdLib.inf
BoardModulePkg/Library/PeiFirmwareBootMediaInfoLib/PeiFirmwareBootMediaInfoLib.inf
BoardModulePkg/Library/BdsPs2KbcLib/BdsPs2KbcLib.inf
@@ -0,0 +1,202 @@
/** @file
Main file for Ps2 keyboard controller library.
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BdsPs2KbcLib.h"
GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_KEYBOARD_DEVICE_PATH gKeyboardDevicePath = {
gPciRootBridge,
{
{
HARDWARE_DEVICE_PATH,
HW_PCI_DP,
{
(UINT8) (sizeof (PCI_DEVICE_PATH)),
(UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8)
}
},
0, // Function, patched in EnumPs2Keyboard
0 // Device, patched in EnumPs2Keyboard
},
{
{
ACPI_DEVICE_PATH,
ACPI_DP,
{
(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
}
},
EISA_PNP_ID(0x0303),
0
},
gEndEntire
};
/**
Check if PS2 keyboard is conntected, by sending ECHO command.
@retval TRUE if connected FALSE otherwise
**/
BOOLEAN
DetectPs2Keyboard (
VOID
)
{
UINT32 TimeOut;
UINT32 RegEmptied;
UINT8 Data;
UINT32 SumTimeOut;
BOOLEAN FoundPs2Kbc;
TimeOut = 0;
RegEmptied = 0;
FoundPs2Kbc = FALSE;
//
// Wait for input buffer empty
//
for (TimeOut = 0; TimeOut < PS2_KEYBOARD_TIMEOUT; TimeOut += 30) {
if ((IoRead8 (KEYBOARD_8042_STATUS_REGISTER) & 0x02) == 0) {
FoundPs2Kbc = TRUE;
break;
}
MicroSecondDelay (30);
}
if (FoundPs2Kbc == FALSE) {
return FALSE;
}
//
// Send echo command
//
IoWrite8 (KEYBOARD_8042_DATA_REGISTER, KBC_INPBUF_VIA60_KBECHO);
//
// Init variables
//
FoundPs2Kbc = FALSE;
TimeOut = 0;
SumTimeOut = 0;
Data = 0;
//
// Read from 8042 (multiple times if needed)
// until the expected value appears
// use SumTimeOut to control the iteration
//
while (1) {
//
// Perform a read
//
for (TimeOut = 0; TimeOut < PS2_KEYBOARD_TIMEOUT; TimeOut += 30) {
if (IoRead8 (KEYBOARD_8042_STATUS_REGISTER) & 0x01) {
Data = IoRead8 (KEYBOARD_8042_DATA_REGISTER);
break;
}
MicroSecondDelay (30);
}
SumTimeOut += TimeOut;
if (Data == KBC_INPBUF_VIA60_KBECHO) {
FoundPs2Kbc = TRUE;
break;
}
if (SumTimeOut >= PS2_KEYBOARD_WAITFORVALUE_TIMEOUT) {
break;
}
}
return FoundPs2Kbc;
}
/**
Check if PS2 keyboard is conntected. If the result of first time is
error, it will retry again.
@retval TRUE if connected FALSE otherwise
**/
BOOLEAN
IsPs2KeyboardConnected (
VOID
)
{
BOOLEAN Result;
Result = DetectPs2Keyboard ();
if (Result == FALSE) {
//
// If there is no ps2 keyboard detected for the 1st time, retry again.
//
Result = DetectPs2Keyboard ();
}
return Result;
}
/**
Updates the ConIn variable with Ps2 Keyboard device path,
if it doesn't already exists in ConIn and ConInDev
**/
VOID
AddPs2Keyboard (
VOID
)
{
SIO_PCI_ISA_BRIDGE_DEVICE_INFO *SioIsaInfo;
DEBUG ((DEBUG_INFO, "[AddPs2Keyboard]\n"));
SioIsaInfo = (SIO_PCI_ISA_BRIDGE_DEVICE_INFO*) FixedPcdGetPtr (PcdSuperIoPciIsaBridgeDevice);
//
// patch IsaBridge device and and function
//
gKeyboardDevicePath.IsaBridge.Device = SioIsaInfo->Device;
gKeyboardDevicePath.IsaBridge.Function = SioIsaInfo->Funtion;
//
// Append Ps2 Keyboard into "ConIn"
//
EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *) &gKeyboardDevicePath, NULL);
//
// Append Ps2 Keyboard into "ConInDev"
//
EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOCOL *) &gKeyboardDevicePath, NULL);
}
/**
Constructor for the Ps2 keyboard controller library.
@param ImageHandle the image handle of the process
@param SystemTable the EFI System Table pointer
@retval EFI_SUCCESS the shell command handlers were installed sucessfully
@retval EFI_UNSUPPORTED the shell level required was not found.
**/
EFI_STATUS
EFIAPI
BdsPs2KbcLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINT8 Ps2KbMsEnable;
Ps2KbMsEnable = PcdGet8 (PcdPs2KbMsEnable);
if (Ps2KbMsEnable == 0x1
&& IsPs2KeyboardConnected())
{
// add ps2 device path to ConIn and ConInDev
AddPs2Keyboard ();
}
return EFI_SUCCESS;
}
@@ -0,0 +1,65 @@
/** @file
Header file for the Ps2 keyboard controller library.
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _PS2_KBC_LIB_H
#define _PS2_KBC_LIB_H
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiBootManagerLib.h>
//
// Below is the platform console device path
//
typedef struct {
ACPI_HID_DEVICE_PATH PciRootBridge;
PCI_DEVICE_PATH IsaBridge;
ACPI_HID_DEVICE_PATH Keyboard;
EFI_DEVICE_PATH_PROTOCOL End;
} PLATFORM_KEYBOARD_DEVICE_PATH;
typedef struct {
UINT8 Segment;
UINT8 Bus;
UINT8 Device;
UINT8 Funtion;
} SIO_PCI_ISA_BRIDGE_DEVICE_INFO;
#define gPciRootBridge \
{ \
{ \
ACPI_DEVICE_PATH, \
ACPI_DP, \
{ \
(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
}, \
}, \
EISA_PNP_ID (0x0A03), \
0 \
}
#define gEndEntire \
{ \
END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
}
#define KBC_INPBUF_VIA60_KBECHO 0xEE
#define KEYBOARD_8042_DATA_REGISTER 0x60
#define KEYBOARD_8042_STATUS_REGISTER 0x64
#define PS2_KEYBOARD_TIMEOUT 65536 // 0.07s
#define PS2_KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s
#define PS2_KEYBOARD_KBEN 0xF4
#define PS2_KEYBOARD_CMDECHO_ACK 0xFA
#endif
@@ -0,0 +1,38 @@
## @file
# Component information file for Ps2 keyboard controller library
#
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = BdsPs2KbcLib
FILE_GUID = E94EA52E-E84C-42E7-B863-EA1327EFA265
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.2
LIBRARY_CLASS = NULL|UEFI_DRIVER
CONSTRUCTOR = BdsPs2KbcLibConstructor
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
BoardModulePkg/BoardModulePkg.dec
[Sources]
BdsPs2KbcLib.c
BdsPs2KbcLib.h
[LibraryClasses]
DevicePathLib
DebugLib
IoLib
UefiDriverEntryPoint
UefiBootManagerLib
UefiLib
TimerLib
[Pcd]
gBoardModulePkgTokenSpaceGuid.PcdPs2KbMsEnable
gBoardModulePkgTokenSpaceGuid.PcdSuperIoPciIsaBridgeDevice