2 ConsoleOut Routines that speak VGA.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "BiosKeyboard.h"
13 // EFI Driver Binding Protocol Instance
15 EFI_DRIVER_BINDING_PROTOCOL gBiosKeyboardDriverBinding
= {
16 BiosKeyboardDriverBindingSupported
,
17 BiosKeyboardDriverBindingStart
,
18 BiosKeyboardDriverBindingStop
,
28 @param Queue The queue to be enqueued.
29 @param KeyData The key data to be enqueued.
31 @retval EFI_NOT_READY The queue is full.
32 @retval EFI_SUCCESS Successfully enqueued the key data.
37 IN SIMPLE_QUEUE
*Queue
,
38 IN EFI_KEY_DATA
*KeyData
41 if ((Queue
->Rear
+ 1) % QUEUE_MAX_COUNT
== Queue
->Front
) {
45 CopyMem (&Queue
->Buffer
[Queue
->Rear
], KeyData
, sizeof (EFI_KEY_DATA
));
46 Queue
->Rear
= (Queue
->Rear
+ 1) % QUEUE_MAX_COUNT
;
55 @param Queue The queue to be dequeued.
56 @param KeyData The key data to be dequeued.
58 @retval EFI_NOT_READY The queue is empty.
59 @retval EFI_SUCCESS Successfully dequeued the key data.
64 IN SIMPLE_QUEUE
*Queue
,
65 IN EFI_KEY_DATA
*KeyData
68 if (Queue
->Front
== Queue
->Rear
) {
72 CopyMem (KeyData
, &Queue
->Buffer
[Queue
->Front
], sizeof (EFI_KEY_DATA
));
73 Queue
->Front
= (Queue
->Front
+ 1) % QUEUE_MAX_COUNT
;
80 Check whether the queue is empty.
82 @param Queue The queue to be checked.
84 @retval EFI_NOT_READY The queue is empty.
85 @retval EFI_SUCCESS The queue is not empty.
90 IN SIMPLE_QUEUE
*Queue
93 if (Queue
->Front
== Queue
->Rear
) {
101 // EFI Driver Binding Protocol Functions
105 Check whether the driver supports this device.
107 @param This The Udriver binding protocol.
108 @param Controller The controller handle to check.
109 @param RemainingDevicePath The remaining device path.
111 @retval EFI_SUCCESS The driver supports this controller.
112 @retval other This device isn't supported.
117 BiosKeyboardDriverBindingSupported (
118 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
119 IN EFI_HANDLE Controller
,
120 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
124 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
125 EFI_ISA_IO_PROTOCOL
*IsaIo
;
128 // See if the Legacy BIOS Protocol is available
130 Status
= gBS
->LocateProtocol (
131 &gEfiLegacyBiosProtocolGuid
,
133 (VOID
**) &LegacyBios
136 if (EFI_ERROR (Status
)) {
140 // Open the IO Abstraction(s) needed to perform the supported test
142 Status
= gBS
->OpenProtocol (
144 &gEfiIsaIoProtocolGuid
,
146 This
->DriverBindingHandle
,
148 EFI_OPEN_PROTOCOL_BY_DRIVER
151 if (EFI_ERROR (Status
)) {
155 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
157 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x303) || IsaIo
->ResourceList
->Device
.UID
!= 0) {
158 Status
= EFI_UNSUPPORTED
;
163 &gEfiIsaIoProtocolGuid
,
164 This
->DriverBindingHandle
,
172 Starts the device with this driver.
174 @param This The driver binding instance.
175 @param Controller Handle of device to bind driver to.
176 @param RemainingDevicePath Optional parameter use to pick a specific child
179 @retval EFI_SUCCESS The controller is controlled by the driver.
180 @retval Other This controller cannot be started.
185 BiosKeyboardDriverBindingStart (
186 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
187 IN EFI_HANDLE Controller
,
188 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
192 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
193 EFI_ISA_IO_PROTOCOL
*IsaIo
;
194 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
195 EFI_IA32_REGISTER_SET Regs
;
197 EFI_PS2_POLICY_PROTOCOL
*Ps2Policy
;
199 EFI_STATUS_CODE_VALUE StatusCode
;
201 BiosKeyboardPrivate
= NULL
;
206 // Get Ps2 policy to set. Will be use if present.
208 gBS
->LocateProtocol (
209 &gEfiPs2PolicyProtocolGuid
,
215 // See if the Legacy BIOS Protocol is available
217 Status
= gBS
->LocateProtocol (
218 &gEfiLegacyBiosProtocolGuid
,
220 (VOID
**) &LegacyBios
223 if (EFI_ERROR (Status
)) {
227 // Open the IO Abstraction(s) needed
229 Status
= gBS
->OpenProtocol (
231 &gEfiIsaIoProtocolGuid
,
233 This
->DriverBindingHandle
,
235 EFI_OPEN_PROTOCOL_BY_DRIVER
237 if (EFI_ERROR (Status
)) {
242 // Allocate the private device structure
244 BiosKeyboardPrivate
= (BIOS_KEYBOARD_DEV
*) AllocateZeroPool (sizeof (BIOS_KEYBOARD_DEV
));
245 if (NULL
== BiosKeyboardPrivate
) {
246 Status
= EFI_OUT_OF_RESOURCES
;
251 // Initialize the private device structure
253 BiosKeyboardPrivate
->Signature
= BIOS_KEYBOARD_DEV_SIGNATURE
;
254 BiosKeyboardPrivate
->Handle
= Controller
;
255 BiosKeyboardPrivate
->LegacyBios
= LegacyBios
;
256 BiosKeyboardPrivate
->IsaIo
= IsaIo
;
258 BiosKeyboardPrivate
->SimpleTextIn
.Reset
= BiosKeyboardReset
;
259 BiosKeyboardPrivate
->SimpleTextIn
.ReadKeyStroke
= BiosKeyboardReadKeyStroke
;
261 BiosKeyboardPrivate
->DataRegisterAddress
= KEYBOARD_8042_DATA_REGISTER
;
262 BiosKeyboardPrivate
->StatusRegisterAddress
= KEYBOARD_8042_STATUS_REGISTER
;
263 BiosKeyboardPrivate
->CommandRegisterAddress
= KEYBOARD_8042_COMMAND_REGISTER
;
264 BiosKeyboardPrivate
->ExtendedKeyboard
= TRUE
;
266 BiosKeyboardPrivate
->KeyState
.KeyShiftState
= 0;
267 BiosKeyboardPrivate
->KeyState
.KeyToggleState
= 0;
268 BiosKeyboardPrivate
->Queue
.Front
= 0;
269 BiosKeyboardPrivate
->Queue
.Rear
= 0;
270 BiosKeyboardPrivate
->QueueForNotify
.Front
= 0;
271 BiosKeyboardPrivate
->QueueForNotify
.Rear
= 0;
272 BiosKeyboardPrivate
->SimpleTextInputEx
.Reset
= BiosKeyboardResetEx
;
273 BiosKeyboardPrivate
->SimpleTextInputEx
.ReadKeyStrokeEx
= BiosKeyboardReadKeyStrokeEx
;
274 BiosKeyboardPrivate
->SimpleTextInputEx
.SetState
= BiosKeyboardSetState
;
275 BiosKeyboardPrivate
->SimpleTextInputEx
.RegisterKeyNotify
= BiosKeyboardRegisterKeyNotify
;
276 BiosKeyboardPrivate
->SimpleTextInputEx
.UnregisterKeyNotify
= BiosKeyboardUnregisterKeyNotify
;
277 InitializeListHead (&BiosKeyboardPrivate
->NotifyList
);
280 // Report that the keyboard is being enabled
284 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
288 // Setup the WaitForKey event
290 Status
= gBS
->CreateEvent (
293 BiosKeyboardWaitForKey
,
294 &(BiosKeyboardPrivate
->SimpleTextIn
),
295 &((BiosKeyboardPrivate
->SimpleTextIn
).WaitForKey
)
297 if (EFI_ERROR (Status
)) {
298 (BiosKeyboardPrivate
->SimpleTextIn
).WaitForKey
= NULL
;
301 Status
= gBS
->CreateEvent (
304 BiosKeyboardWaitForKeyEx
,
305 &(BiosKeyboardPrivate
->SimpleTextInputEx
),
306 &(BiosKeyboardPrivate
->SimpleTextInputEx
.WaitForKeyEx
)
308 if (EFI_ERROR (Status
)) {
309 BiosKeyboardPrivate
->SimpleTextInputEx
.WaitForKeyEx
= NULL
;
314 // Setup a periodic timer, used for reading keystrokes at a fixed interval
316 Status
= gBS
->CreateEvent (
317 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
319 BiosKeyboardTimerHandler
,
321 &BiosKeyboardPrivate
->TimerEvent
323 if (EFI_ERROR (Status
)) {
324 Status
= EFI_OUT_OF_RESOURCES
;
325 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
329 Status
= gBS
->SetTimer (
330 BiosKeyboardPrivate
->TimerEvent
,
332 KEYBOARD_TIMER_INTERVAL
334 if (EFI_ERROR (Status
)) {
335 Status
= EFI_OUT_OF_RESOURCES
;
336 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
340 Status
= gBS
->CreateEvent (
343 KeyNotifyProcessHandler
,
345 &BiosKeyboardPrivate
->KeyNotifyProcessEvent
347 if (EFI_ERROR (Status
)) {
348 Status
= EFI_OUT_OF_RESOURCES
;
349 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
354 // Report a Progress Code for an attempt to detect the precense of the keyboard device in the system
358 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
362 // Reset the keyboard device
364 Status
= BiosKeyboardPrivate
->SimpleTextInputEx
.Reset (
365 &BiosKeyboardPrivate
->SimpleTextInputEx
,
366 FeaturePcdGet (PcdPs2KbdExtendedVerification
)
368 if (EFI_ERROR (Status
)) {
369 DEBUG ((EFI_D_ERROR
, "[KBD]Reset Failed. Status - %r\n", Status
));
370 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_NOT_DETECTED
;
374 // Do platform specific policy like port swapping and keyboard light default
376 if (Ps2Policy
!= NULL
) {
378 Ps2Policy
->Ps2InitHardware (Controller
);
381 if ((Ps2Policy
->KeyboardLight
& EFI_KEYBOARD_CAPSLOCK
) == EFI_KEYBOARD_CAPSLOCK
) {
385 if ((Ps2Policy
->KeyboardLight
& EFI_KEYBOARD_NUMLOCK
) == EFI_KEYBOARD_NUMLOCK
) {
389 if ((Ps2Policy
->KeyboardLight
& EFI_KEYBOARD_SCROLLLOCK
) == EFI_KEYBOARD_SCROLLLOCK
) {
393 KeyboardWrite (BiosKeyboardPrivate
, 0xed);
394 KeyboardWaitForValue (BiosKeyboardPrivate
, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT
);
395 KeyboardWrite (BiosKeyboardPrivate
, Command
);
397 // Call Legacy BIOS Protocol to set whatever is necessary
399 LegacyBios
->UpdateKeyboardLedStatus (LegacyBios
, Command
);
405 CarryFlag
= BiosKeyboardPrivate
->LegacyBios
->Int86 (
406 BiosKeyboardPrivate
->LegacyBios
,
413 // Check bit 6 of Feature Byte 2.
414 // If it is set, then Int 16 Func 09 is supported
416 if (*(UINT8
*) (((UINTN
) Regs
.X
.ES
<< 4) + Regs
.X
.BX
+ 0x06) & 0x40) {
418 // Get Keyboard Functionality
421 CarryFlag
= BiosKeyboardPrivate
->LegacyBios
->Int86 (
422 BiosKeyboardPrivate
->LegacyBios
,
429 // Check bit 5 of AH.
430 // If it is set, then INT 16 Finc 10-12 are supported.
432 if ((Regs
.H
.AL
& 0x40) != 0) {
434 // Set the flag to use INT 16 Func 10-12
436 BiosKeyboardPrivate
->ExtendedKeyboard
= TRUE
;
441 DEBUG ((EFI_D_INFO
, "[KBD]Extended keystrokes supported by CSM16 - %02x\n", (UINTN
)BiosKeyboardPrivate
->ExtendedKeyboard
));
443 // Install protocol interfaces for the keyboard device.
445 Status
= gBS
->InstallMultipleProtocolInterfaces (
447 &gEfiSimpleTextInProtocolGuid
,
448 &BiosKeyboardPrivate
->SimpleTextIn
,
449 &gEfiSimpleTextInputExProtocolGuid
,
450 &BiosKeyboardPrivate
->SimpleTextInputEx
,
455 if (StatusCode
!= 0) {
457 // Report an Error Code for failing to start the keyboard device
460 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
465 if (EFI_ERROR (Status
)) {
467 if (BiosKeyboardPrivate
!= NULL
) {
468 if ((BiosKeyboardPrivate
->SimpleTextIn
).WaitForKey
!= NULL
) {
469 gBS
->CloseEvent ((BiosKeyboardPrivate
->SimpleTextIn
).WaitForKey
);
472 if ((BiosKeyboardPrivate
->SimpleTextInputEx
).WaitForKeyEx
!= NULL
) {
473 gBS
->CloseEvent ((BiosKeyboardPrivate
->SimpleTextInputEx
).WaitForKeyEx
);
476 if (BiosKeyboardPrivate
->KeyNotifyProcessEvent
!= NULL
) {
477 gBS
->CloseEvent (BiosKeyboardPrivate
->KeyNotifyProcessEvent
);
480 BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate
->NotifyList
);
482 if (BiosKeyboardPrivate
->TimerEvent
!= NULL
) {
483 gBS
->CloseEvent (BiosKeyboardPrivate
->TimerEvent
);
486 FreePool (BiosKeyboardPrivate
);
492 &gEfiIsaIoProtocolGuid
,
493 This
->DriverBindingHandle
,
503 Stop the device handled by this driver.
505 @param This The driver binding protocol.
506 @param Controller The controller to release.
507 @param NumberOfChildren The number of handles in ChildHandleBuffer.
508 @param ChildHandleBuffer The array of child handle.
510 @retval EFI_SUCCESS The device was stopped.
511 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
512 @retval Others Fail to uninstall protocols attached on the device.
517 BiosKeyboardDriverBindingStop (
518 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
519 IN EFI_HANDLE Controller
,
520 IN UINTN NumberOfChildren
,
521 IN EFI_HANDLE
*ChildHandleBuffer
525 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextIn
;
526 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
531 Status
= gBS
->OpenProtocol (
533 &gEfiSimpleTextInProtocolGuid
,
534 (VOID
**) &SimpleTextIn
,
535 This
->DriverBindingHandle
,
537 EFI_OPEN_PROTOCOL_GET_PROTOCOL
539 if (EFI_ERROR (Status
)) {
543 Status
= gBS
->OpenProtocol (
545 &gEfiSimpleTextInputExProtocolGuid
,
547 This
->DriverBindingHandle
,
549 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
551 if (EFI_ERROR (Status
)) {
555 BiosKeyboardPrivate
= BIOS_KEYBOARD_DEV_FROM_THIS (SimpleTextIn
);
557 Status
= gBS
->UninstallMultipleProtocolInterfaces (
559 &gEfiSimpleTextInProtocolGuid
,
560 &BiosKeyboardPrivate
->SimpleTextIn
,
561 &gEfiSimpleTextInputExProtocolGuid
,
562 &BiosKeyboardPrivate
->SimpleTextInputEx
,
565 if (EFI_ERROR (Status
)) {
569 // Release the IsaIo protocol on the controller handle
573 &gEfiIsaIoProtocolGuid
,
574 This
->DriverBindingHandle
,
579 // Free other resources
581 gBS
->CloseEvent ((BiosKeyboardPrivate
->SimpleTextIn
).WaitForKey
);
582 gBS
->CloseEvent (BiosKeyboardPrivate
->TimerEvent
);
583 gBS
->CloseEvent (BiosKeyboardPrivate
->SimpleTextInputEx
.WaitForKeyEx
);
584 gBS
->CloseEvent (BiosKeyboardPrivate
->KeyNotifyProcessEvent
);
585 BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate
->NotifyList
);
587 FreePool (BiosKeyboardPrivate
);
593 Read data byte from output buffer of Keyboard Controller without delay and waiting for buffer-empty state.
595 @param BiosKeyboardPrivate Keyboard instance pointer.
597 @return The data byte read from output buffer of Keyboard Controller from data port which often is port 60H.
601 KeyReadDataRegister (
602 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
608 // Use IsaIo protocol to perform IO operations
610 BiosKeyboardPrivate
->IsaIo
->Io
.Read (
611 BiosKeyboardPrivate
->IsaIo
,
613 BiosKeyboardPrivate
->DataRegisterAddress
,
622 Read status byte from status register of Keyboard Controller without delay and waiting for buffer-empty state.
624 @param BiosKeyboardPrivate Keyboard instance pointer.
626 @return The status byte read from status register of Keyboard Controller from command port which often is port 64H.
630 KeyReadStatusRegister (
631 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
637 // Use IsaIo protocol to perform IO operations
639 BiosKeyboardPrivate
->IsaIo
->Io
.Read (
640 BiosKeyboardPrivate
->IsaIo
,
642 BiosKeyboardPrivate
->StatusRegisterAddress
,
651 Write command byte to control register of Keyboard Controller without delay and waiting for buffer-empty state.
653 @param BiosKeyboardPrivate Keyboard instance pointer.
654 @param Data Data byte to write.
658 KeyWriteCommandRegister (
659 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
664 // Use IsaIo protocol to perform IO operations
666 BiosKeyboardPrivate
->IsaIo
->Io
.Write (
667 BiosKeyboardPrivate
->IsaIo
,
669 BiosKeyboardPrivate
->CommandRegisterAddress
,
676 Write data byte to input buffer or input/output ports of Keyboard Controller without delay and waiting for buffer-empty state.
678 @param BiosKeyboardPrivate Keyboard instance pointer.
679 @param Data Data byte to write.
683 KeyWriteDataRegister (
684 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
689 // Use IsaIo protocol to perform IO operations
691 BiosKeyboardPrivate
->IsaIo
->Io
.Write (
692 BiosKeyboardPrivate
->IsaIo
,
694 BiosKeyboardPrivate
->DataRegisterAddress
,
701 Read data byte from output buffer of Keyboard Controller with delay and waiting for buffer-empty state.
703 @param BiosKeyboardPrivate Keyboard instance pointer.
704 @param Data The pointer for data that being read out.
706 @retval EFI_SUCCESS The data byte read out successfully.
707 @retval EFI_TIMEOUT Timeout occurred during reading out data byte.
712 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
723 // wait till output buffer full then perform the read
725 for (TimeOut
= 0; TimeOut
< KEYBOARD_TIMEOUT
; TimeOut
+= 30) {
726 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & KBC_STSREG_VIA64_OUTB
) != 0) {
728 *Data
= KeyReadDataRegister (BiosKeyboardPrivate
);
735 if (RegFilled
== 0) {
743 Write data byte to input buffer or input/output ports of Keyboard Controller with delay and waiting for buffer-empty state.
745 @param BiosKeyboardPrivate Keyboard instance pointer.
746 @param Data Data byte to write.
748 @retval EFI_SUCCESS The data byte is written successfully.
749 @retval EFI_TIMEOUT Timeout occurred during writing.
754 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
765 // wait for input buffer empty
767 for (TimeOut
= 0; TimeOut
< KEYBOARD_TIMEOUT
; TimeOut
+= 30) {
768 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & KBC_STSREG_VIA64_INPB
) == 0) {
776 if (RegEmptied
== 0) {
782 KeyWriteDataRegister (BiosKeyboardPrivate
, Data
);
788 Write command byte to control register of Keyboard Controller with delay and waiting for buffer-empty state.
790 @param BiosKeyboardPrivate Keyboard instance pointer.
791 @param Data Command byte to write.
793 @retval EFI_SUCCESS The command byte is written successfully.
794 @retval EFI_TIMEOUT Timeout occurred during writing.
799 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
810 // Wait For Input Buffer Empty
812 for (TimeOut
= 0; TimeOut
< KEYBOARD_TIMEOUT
; TimeOut
+= 30) {
813 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & KBC_STSREG_VIA64_INPB
) == 0) {
821 if (RegEmptied
== 0) {
827 KeyWriteCommandRegister (BiosKeyboardPrivate
, Data
);
830 // Wait For Input Buffer Empty again
833 for (TimeOut
= 0; TimeOut
< KEYBOARD_TIMEOUT
; TimeOut
+= 30) {
834 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & KBC_STSREG_VIA64_INPB
) == 0) {
842 if (RegEmptied
== 0) {
850 Wait for a specific value to be presented in
851 Data register of Keyboard Controller by keyboard and then read it,
852 used in keyboard commands ack
854 @param BiosKeyboardPrivate Keyboard instance pointer.
855 @param Value The value to be waited for
856 @param WaitForValueTimeOut The limit of microseconds for timeout
858 @retval EFI_SUCCESS The command byte is written successfully.
859 @retval EFI_TIMEOUT Timeout occurred during writing.
863 KeyboardWaitForValue (
864 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
866 IN UINTN WaitForValueTimeOut
879 // Make sure the initial value of 'Data' is different from 'Value'
886 // Read from 8042 (multiple times if needed)
887 // until the expected value appears
888 // use SumTimeOut to control the iteration
894 for (TimeOut
= 0; TimeOut
< KEYBOARD_TIMEOUT
; TimeOut
+= 30) {
895 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & KBC_STSREG_VIA64_OUTB
) != 0) {
896 Data
= KeyReadDataRegister (BiosKeyboardPrivate
);
903 SumTimeOut
+= TimeOut
;
910 if (SumTimeOut
>= WaitForValueTimeOut
) {
926 Reads the next keystroke from the input device. The WaitForKey Event can
927 be used to test for existance of a keystroke via WaitForEvent () call.
929 @param BiosKeyboardPrivate Bioskeyboard driver private structure.
930 @param KeyData A pointer to a buffer that is filled in with the keystroke
931 state data for the key that was pressed.
933 @retval EFI_SUCCESS The keystroke information was returned.
934 @retval EFI_NOT_READY There was no keystroke data availiable.
935 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
937 @retval EFI_INVALID_PARAMETER KeyData is NULL.
941 KeyboardReadKeyStrokeWorker (
942 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
,
943 OUT EFI_KEY_DATA
*KeyData
948 if (KeyData
== NULL
) {
949 return EFI_INVALID_PARAMETER
;
953 // Use TimerEvent callback function to check whether there's any key pressed
957 // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
958 // Csm will be used to check whether there is a key pending, but the csm will disable all
959 // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
960 // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
961 // e.g. OS loader, other drivers which are driven by timer event will have a bad performance during this period,
962 // e.g. usb keyboard driver.
963 // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
964 // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
968 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
970 BiosKeyboardTimerHandler (NULL
, BiosKeyboardPrivate
);
972 // If there's no key, just return
974 Status
= CheckQueue (&BiosKeyboardPrivate
->Queue
);
975 if (EFI_ERROR (Status
)) {
976 ZeroMem (&KeyData
->Key
, sizeof (KeyData
->Key
));
977 CopyMem (&KeyData
->KeyState
, &BiosKeyboardPrivate
->KeyState
, sizeof (EFI_KEY_STATE
));
978 gBS
->RestoreTPL (OldTpl
);
979 return EFI_NOT_READY
;
982 Status
= Dequeue (&BiosKeyboardPrivate
->Queue
, KeyData
);
984 gBS
->RestoreTPL (OldTpl
);
990 // EFI Simple Text In Protocol Functions
993 Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
995 @param This Pointer of simple text Protocol.
996 @param ExtendedVerification Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
998 @retval EFI_SUCCESS The command byte is written successfully.
999 @retval EFI_DEVICE_ERROR Errors occurred during resetting keyboard.
1005 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
1006 IN BOOLEAN ExtendedVerification
1009 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
1013 BOOLEAN MouseEnable
;
1016 MouseEnable
= FALSE
;
1017 BiosKeyboardPrivate
= BIOS_KEYBOARD_DEV_FROM_THIS (This
);
1021 // Report reset progress code
1023 REPORT_STATUS_CODE (
1025 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_RESET
1029 // Report a Progress Code for clearing the keyboard buffer
1031 REPORT_STATUS_CODE (
1033 EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_CLEAR_BUFFER
1038 // Raise TPL to avoid mouse operation impact
1040 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1044 // Exhaust output buffer data
1047 Status
= BiosKeyboardReadKeyStroke (
1051 } while (!EFI_ERROR (Status
));
1054 // check for KBC itself firstly for setted-up already or not by reading SYSF (bit2) of status register via 64H
1055 // if not skip step 4&5 and jump to step 6 to selftest KBC and report this
1058 if (!PcdGetBool (PcdFastPS2Detection
)) {
1059 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & KBC_STSREG_VIA64_SYSF
) != 0) {
1062 // CheckMouseStatus to decide enable it later or not
1065 // Read the command byte of KBC
1067 Status
= KeyboardCommand (
1068 BiosKeyboardPrivate
,
1069 KBC_CMDREG_VIA64_CMDBYTE_R
1072 if (EFI_ERROR (Status
)) {
1073 Status
= EFI_DEVICE_ERROR
;
1077 Status
= KeyboardRead (
1078 BiosKeyboardPrivate
,
1082 if (EFI_ERROR (Status
)) {
1083 Status
= EFI_DEVICE_ERROR
;
1087 // Check mouse enabled or not before
1089 if ((CommandByte
& KB_CMMBYTE_DISABLE_AUX
) != 0) {
1090 MouseEnable
= FALSE
;
1096 // disable mouse (via KBC) and Keyborad device
1098 Status
= KeyboardCommand (
1099 BiosKeyboardPrivate
,
1100 KBC_CMDREG_VIA64_AUX_DISABLE
1103 if (EFI_ERROR (Status
)) {
1104 Status
= EFI_DEVICE_ERROR
;
1108 Status
= KeyboardCommand (
1109 BiosKeyboardPrivate
,
1110 KBC_CMDREG_VIA64_KB_DISABLE
1113 if (EFI_ERROR (Status
)) {
1114 Status
= EFI_DEVICE_ERROR
;
1123 // Report a Progress Code for performing a self test on the keyboard controller
1125 REPORT_STATUS_CODE (
1127 EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_SELF_TEST
1130 Status
= KeyboardCommand (
1131 BiosKeyboardPrivate
,
1132 KBC_CMDREG_VIA64_KBC_SLFTEST
1134 if (EFI_ERROR (Status
)) {
1135 Status
= EFI_DEVICE_ERROR
;
1139 Status
= KeyboardWaitForValue (
1140 BiosKeyboardPrivate
,
1141 KBC_CMDECHO_KBCSLFTEST_OK
,
1142 KEYBOARD_WAITFORVALUE_TIMEOUT
1144 if (EFI_ERROR (Status
)) {
1145 Status
= EFI_DEVICE_ERROR
;
1152 // Disable Mouse interface, enable Keyboard interface and declare selftest success
1154 // Mouse device will block keyboard interface before it be configured, so we should disable mouse first.
1156 Status
= KeyboardCommand (
1157 BiosKeyboardPrivate
,
1158 KBC_CMDREG_VIA64_CMDBYTE_W
1161 if (EFI_ERROR (Status
)) {
1162 Status
= EFI_DEVICE_ERROR
;
1167 // Write 8042 Command Byte, set System Flag
1168 // While at the same time:
1169 // 1. disable mouse interface,
1170 // 2. enable kbd interface,
1171 // 3. enable PC/XT kbd translation mode
1172 // 4. enable mouse and kbd interrupts
1174 //Command Byte bits:
1176 // 6: PC/XT translation mode
1177 // 5: Disable Auxiliary device interface
1178 // 4: Disable keyboard interface
1181 // 1: Enable Auxiliary device interrupt
1182 // 0: Enable Keyboard interrupt
1185 Status
= KeyboardWrite (
1186 BiosKeyboardPrivate
,
1187 (UINT8
) ((CommandByte
&
1188 (~KB_CMMBYTE_DISABLE_KB
)) |
1189 KB_CMMBYTE_KSCAN2UNI_COV
|
1190 KB_CMMBYTE_ENABLE_AUXINT
|
1191 KB_CMMBYTE_ENABLE_KBINT
|
1192 KB_CMMBYTE_SLFTEST_SUCC
|
1193 KB_CMMBYTE_DISABLE_AUX
)
1197 // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,
1198 // so we only do the real resetting for keyboard when user asks, and normally during booting an OS, it's skipped.
1199 // Call CheckKeyboardConnect() to check whether keyboard is connected, if it is not connected,
1200 // Real reset will not do.
1202 if (ExtendedVerification
&& CheckKeyboardConnect (BiosKeyboardPrivate
)) {
1205 // Send keyboard reset command then read ACK
1207 Status
= KeyboardWrite (
1208 BiosKeyboardPrivate
,
1209 KBC_INPBUF_VIA60_KBRESET
1212 if (EFI_ERROR (Status
)) {
1213 Status
= EFI_DEVICE_ERROR
;
1217 Status
= KeyboardWaitForValue (
1218 BiosKeyboardPrivate
,
1220 KEYBOARD_WAITFORVALUE_TIMEOUT
1223 if (EFI_ERROR (Status
)) {
1224 Status
= EFI_DEVICE_ERROR
;
1229 // Wait for keyboard return test OK.
1231 Status
= KeyboardWaitForValue (
1232 BiosKeyboardPrivate
,
1233 KBC_CMDECHO_BATTEST_OK
,
1234 KEYBOARD_WAITFORVALUE_TIMEOUT
1237 if (EFI_ERROR (Status
)) {
1238 Status
= EFI_DEVICE_ERROR
;
1243 // set keyboard scan code set = 02 (standard configuration)
1245 Status
= KeyboardWrite (
1246 BiosKeyboardPrivate
,
1247 KBC_INPBUF_VIA60_KBSCODE
1249 if (EFI_ERROR (Status
)) {
1250 Status
= EFI_DEVICE_ERROR
;
1254 Status
= KeyboardWaitForValue (
1255 BiosKeyboardPrivate
,
1257 KEYBOARD_WAITFORVALUE_TIMEOUT
1260 if (EFI_ERROR (Status
)) {
1261 Status
= EFI_DEVICE_ERROR
;
1265 Status
= KeyboardWrite (
1266 BiosKeyboardPrivate
,
1267 KBC_INPBUF_VIA60_SCODESET2
1269 if (EFI_ERROR (Status
)) {
1270 Status
= EFI_DEVICE_ERROR
;
1274 Status
= KeyboardWaitForValue (
1275 BiosKeyboardPrivate
,
1277 KEYBOARD_WAITFORVALUE_TIMEOUT
1280 if (EFI_ERROR (Status
)) {
1281 Status
= EFI_DEVICE_ERROR
;
1286 // enable keyboard itself (not via KBC) by writing CMD F4 via 60H
1288 Status
= KeyboardWrite (
1289 BiosKeyboardPrivate
,
1290 KBC_INPBUF_VIA60_KBEN
1292 if (EFI_ERROR (Status
)) {
1293 Status
= EFI_DEVICE_ERROR
;
1297 Status
= KeyboardWaitForValue (
1298 BiosKeyboardPrivate
,
1300 KEYBOARD_WAITFORVALUE_TIMEOUT
1303 if (EFI_ERROR (Status
)) {
1304 Status
= EFI_DEVICE_ERROR
;
1309 // Additional validation, do it as follow:
1310 // 1). check for status register of PARE && TIM via 64H
1311 // 2). perform KB checking by writing ABh via 64H
1313 if ((KeyReadStatusRegister (BiosKeyboardPrivate
) & (KBC_STSREG_VIA64_PARE
| KBC_STSREG_VIA64_TIM
)) != 0) {
1314 Status
= EFI_DEVICE_ERROR
;
1318 Status
= KeyboardCommand (
1319 BiosKeyboardPrivate
,
1320 KBC_CMDREG_VIA64_KB_CKECK
1322 if (EFI_ERROR (Status
)) {
1323 Status
= EFI_DEVICE_ERROR
;
1327 Status
= KeyboardWaitForValue (
1328 BiosKeyboardPrivate
,
1329 KBC_CMDECHO_KBCHECK_OK
,
1330 KEYBOARD_WAITFORVALUE_TIMEOUT
1333 if (EFI_ERROR (Status
)) {
1334 Status
= EFI_DEVICE_ERROR
;
1340 // Done for validating keyboard. Enable keyboard (via KBC)
1341 // and recover the command byte to proper value
1343 if (!PcdGetBool (PcdFastPS2Detection
)) {
1344 Status
= KeyboardCommand (
1345 BiosKeyboardPrivate
,
1346 KBC_CMDREG_VIA64_KB_ENABLE
1349 if (EFI_ERROR (Status
)) {
1350 Status
= EFI_DEVICE_ERROR
;
1357 // conditionally enable mouse (via KBC)
1360 Status
= KeyboardCommand (
1361 BiosKeyboardPrivate
,
1362 KBC_CMDREG_VIA64_AUX_ENABLE
1365 if (EFI_ERROR (Status
)) {
1366 Status
= EFI_DEVICE_ERROR
;
1374 // resume priority of task level
1376 gBS
->RestoreTPL (OldTpl
);
1383 Read out the scan code of the key that has just been stroked.
1385 @param This Pointer of simple text Protocol.
1386 @param Key Pointer for store the key that read out.
1388 @retval EFI_SUCCESS The key is read out successfully.
1389 @retval other The key reading failed.
1394 BiosKeyboardReadKeyStroke (
1395 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
1396 OUT EFI_INPUT_KEY
*Key
1399 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
1401 EFI_KEY_DATA KeyData
;
1403 BiosKeyboardPrivate
= BIOS_KEYBOARD_DEV_FROM_THIS (This
);
1405 Status
= KeyboardReadKeyStrokeWorker (BiosKeyboardPrivate
, &KeyData
);
1406 if (EFI_ERROR (Status
)) {
1411 // Convert the Ctrl+[a-z] to Ctrl+[1-26]
1413 if ((KeyData
.KeyState
.KeyShiftState
& (EFI_LEFT_CONTROL_PRESSED
| EFI_RIGHT_CONTROL_PRESSED
)) != 0) {
1414 if (KeyData
.Key
.UnicodeChar
>= L
'a' && KeyData
.Key
.UnicodeChar
<= L
'z') {
1415 KeyData
.Key
.UnicodeChar
= (CHAR16
) (KeyData
.Key
.UnicodeChar
- L
'a' + 1);
1416 } else if (KeyData
.Key
.UnicodeChar
>= L
'A' && KeyData
.Key
.UnicodeChar
<= L
'Z') {
1417 KeyData
.Key
.UnicodeChar
= (CHAR16
) (KeyData
.Key
.UnicodeChar
- L
'A' + 1);
1421 CopyMem (Key
, &KeyData
.Key
, sizeof (EFI_INPUT_KEY
));
1427 Waiting on the keyboard event, if there's any key pressed by the user, signal the event
1429 @param Event The event that be siganlled when any key has been stroked.
1430 @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
1435 BiosKeyboardWaitForKey (
1441 // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
1442 // Csm will be used to check whether there is a key pending, but the csm will disable all
1443 // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
1444 // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
1445 // e.g. UI setup or Shell, other drivers which are driven by timer event will have a bad performance during this period,
1446 // e.g. usb keyboard driver.
1447 // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
1448 // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
1452 // Use TimerEvent callback function to check whether there's any key pressed
1454 BiosKeyboardTimerHandler (NULL
, BIOS_KEYBOARD_DEV_FROM_THIS (Context
));
1456 if (!EFI_ERROR (BiosKeyboardCheckForKey (Context
))) {
1457 gBS
->SignalEvent (Event
);
1462 Check key buffer to get the key stroke status.
1464 @param This Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.
1466 @retval EFI_SUCCESS A key is being pressed now.
1467 @retval Other No key is now pressed.
1472 BiosKeyboardCheckForKey (
1473 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
1476 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
1478 BiosKeyboardPrivate
= BIOS_KEYBOARD_DEV_FROM_THIS (This
);
1480 return CheckQueue (&BiosKeyboardPrivate
->Queue
);
1483 // Private worker functions
1485 #define TABLE_END 0x0
1487 typedef struct _CONVERT_TABLE_ENTRY
{
1490 } CONVERT_TABLE_ENTRY
;
1492 CONVERT_TABLE_ENTRY mConvertTable
[] = {
1534 // Function Keys are only valid if KeyChar == 0x00
1535 // This function does not require KeyChar to be 0x00
1586 // Convert ALT + Fn keys
1635 Convert unicode combined with scan code of key to the counterpart of EFIScancode of it.
1637 @param KeyChar Unicode of key.
1638 @param ScanCode Scan code of key.
1640 @return The value of EFI Scancode for the key.
1641 @retval SCAN_NULL No corresponding value in the EFI convert table is found for the key.
1645 ConvertToEFIScanCode (
1653 if (KeyChar
== CHAR_ESC
) {
1654 EfiScanCode
= SCAN_ESC
;
1655 } else if (KeyChar
== 0x00 || KeyChar
== 0xe0) {
1657 // Movement & Function Keys
1659 for (Index
= 0; (Index
< sizeof (mConvertTable
) / sizeof (CONVERT_TABLE_ENTRY
)) && (mConvertTable
[Index
].ScanCode
!= TABLE_END
); Index
+= 1) {
1660 if (ScanCode
== mConvertTable
[Index
].ScanCode
) {
1661 return mConvertTable
[Index
].EfiScanCode
;
1665 // Reach Table end, return default value
1676 Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
1677 If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
1678 should not be in system.
1680 @param BiosKeyboardPrivate Keyboard Private Data Struture
1682 @retval TRUE Keyboard in System.
1683 @retval FALSE Keyboard not in System.
1687 CheckKeyboardConnect (
1688 IN BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
1693 Status
= EFI_SUCCESS
;
1695 // enable keyboard itself and wait for its ack
1696 // If can't receive ack, Keyboard should not be connected.
1698 if (!PcdGetBool (PcdFastPS2Detection
)) {
1699 Status
= KeyboardWrite (
1700 BiosKeyboardPrivate
,
1701 KBC_INPBUF_VIA60_KBEN
1703 if (EFI_ERROR (Status
)) {
1704 DEBUG ((EFI_D_ERROR
, "[KBD]CheckKeyboardConnect - Keyboard enable failed!\n"));
1705 REPORT_STATUS_CODE (
1706 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1707 EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
1712 Status
= KeyboardWaitForValue (
1713 BiosKeyboardPrivate
,
1715 KEYBOARD_WAITFORVALUE_TIMEOUT
1718 if (EFI_ERROR (Status
)) {
1719 DEBUG ((EFI_D_ERROR
, "[KBD]CheckKeyboardConnect - Timeout!\n"));
1720 REPORT_STATUS_CODE (
1721 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1722 EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
1733 Timer event handler: read a series of key stroke from 8042
1734 and put them into memory key buffer.
1735 It is registered as running under TPL_NOTIFY
1737 @param Event The timer event
1738 @param Context A BIOS_KEYBOARD_DEV pointer
1743 BiosKeyboardTimerHandler (
1749 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
1750 EFI_IA32_REGISTER_SET Regs
;
1751 UINT8 KbFlag1
; // 0040h:0017h - KEYBOARD - STATUS FLAGS 1
1752 UINT8 KbFlag2
; // 0040h:0018h - KEYBOARD - STATUS FLAGS 2
1753 EFI_KEY_DATA KeyData
;
1755 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
1757 BiosKeyboardPrivate
= Context
;
1760 // Enter critical section
1762 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1765 // if there is no key present, just return
1767 if (BiosKeyboardPrivate
->ExtendedKeyboard
) {
1773 BiosKeyboardPrivate
->LegacyBios
->Int86 (
1774 BiosKeyboardPrivate
->LegacyBios
,
1778 if (Regs
.X
.Flags
.ZF
!= 0) {
1779 gBS
->RestoreTPL (OldTpl
);
1786 if (BiosKeyboardPrivate
->ExtendedKeyboard
) {
1792 BiosKeyboardPrivate
->LegacyBios
->Int86 (
1793 BiosKeyboardPrivate
->LegacyBios
,
1798 KeyData
.Key
.ScanCode
= (UINT16
) Regs
.H
.AH
;
1799 KeyData
.Key
.UnicodeChar
= (UINT16
) Regs
.H
.AL
;
1802 "[KBD]INT16 returns EFI_INPUT_KEY.ScanCode - %x, EFI_INPUT_KEY.UnicodeChar - %x\n",
1803 KeyData
.Key
.ScanCode
,
1804 KeyData
.Key
.UnicodeChar
1807 KeyData
.KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1808 KeyData
.KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1810 // Leagcy Bios use Int 9 which is IRQ1 interrupt handler to get keystroke scancode to KB buffer in BDA (BIOS DATE AREA), then
1811 // Int 16 depend KB buffer and some key bits in BDA to translate the scancode to ASCII code, and return both the scancode and ASCII
1812 // code to Int 16 caller. This translation process works well if the Int 9 could response user input in time. But in Tiano enviorment, the Int 9
1813 // will be disabled after the thunk call finish, which means if user crazy input during int 9 being disabled, some keystrokes will be lost when
1814 // KB device own hardware buffer overflows. And if the lost keystroke code is CTRL or ALT or SHIFT release code, these function key flags bit
1815 // in BDA will not be updated. So the Int 16 will believe the CTRL or ALT or SHIFT is still pressed, and Int 16 will translate later scancode
1816 // to wrong ASCII code. We can increase the Thunk frequence to let Int 9 response in time, but this way will much hurt other drivers
1817 // performance, like USB.
1819 // 1. If CTRL or ALT release code is missed, all later input keys will be translated to wrong ASCII codes which the Tiano cannot support. In
1820 // this case, the KB input seems fail to work, and user input is blocked. To solve the problem, we can help to clear the CTRL or ALT flag in BDA
1821 // after every Int 16 finish. Thus persist to press CTRL or ALT has same effection as only press one time. It is Ok, since user not often use the
1824 // 2. If SHIFT release code is missed, all later lowercase input will become capital. This is ugly, but not block user input. If user press the lost
1825 // SHIFT again, the lowercase will come back to normal. Since user often use the SHIFT, it is not reasonable to help to clear the SHIFT flag in BDA,
1826 // which will let persist to press SHIFT has same effection as only press one time.
1828 //0040h:0017h - KEYBOARD - STATUS FLAGS 1
1830 // 6 Caps Lock active
1831 // 5 Num Lock active
1832 // 4 Scroll Lock active
1833 // 3 either Alt pressed
1834 // 2 either Ctrl pressed
1835 // 1 Left Shift pressed
1836 // 0 Right Shift pressed
1840 // Clear the CTRL and ALT BDA flag
1843 KbFlag1
= *((UINT8
*) (UINTN
) 0x417); // read the STATUS FLAGS 1
1844 KbFlag2
= *((UINT8
*) (UINTN
) 0x418); // read STATUS FLAGS 2
1849 if ((KbFlag1
& KB_CAPS_LOCK_BIT
) == KB_CAPS_LOCK_BIT
) {
1850 DEBUG ((EFI_D_INFO
, "[KBD]Caps Lock Key is pressed.\n"));
1852 if ((KbFlag1
& KB_NUM_LOCK_BIT
) == KB_NUM_LOCK_BIT
) {
1853 DEBUG ((EFI_D_INFO
, "[KBD]Num Lock Key is pressed.\n"));
1855 if ((KbFlag1
& KB_SCROLL_LOCK_BIT
) == KB_SCROLL_LOCK_BIT
) {
1856 DEBUG ((EFI_D_INFO
, "[KBD]Scroll Lock Key is pressed.\n"));
1858 if ((KbFlag1
& KB_ALT_PRESSED
) == KB_ALT_PRESSED
) {
1859 if ((KbFlag2
& KB_LEFT_ALT_PRESSED
) == KB_LEFT_ALT_PRESSED
) {
1860 DEBUG ((EFI_D_INFO
, "[KBD]Left Alt Key is pressed.\n"));
1862 DEBUG ((EFI_D_INFO
, "[KBD]Right Alt Key is pressed.\n"));
1865 if ((KbFlag1
& KB_CTRL_PRESSED
) == KB_CTRL_PRESSED
) {
1866 if ((KbFlag2
& KB_LEFT_CTRL_PRESSED
) == KB_LEFT_CTRL_PRESSED
) {
1867 DEBUG ((EFI_D_INFO
, "[KBD]Left Ctrl Key is pressed.\n"));
1869 DEBUG ((EFI_D_INFO
, "[KBD]Right Ctrl Key is pressed.\n"));
1872 if ((KbFlag1
& KB_LEFT_SHIFT_PRESSED
) == KB_LEFT_SHIFT_PRESSED
) {
1873 DEBUG ((EFI_D_INFO
, "[KBD]Left Shift Key is pressed.\n"));
1875 if ((KbFlag1
& KB_RIGHT_SHIFT_PRESSED
) == KB_RIGHT_SHIFT_PRESSED
) {
1876 DEBUG ((EFI_D_INFO
, "[KBD]Right Shift Key is pressed.\n"));
1882 // Record toggle state
1884 if ((KbFlag1
& KB_CAPS_LOCK_BIT
) == KB_CAPS_LOCK_BIT
) {
1885 KeyData
.KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1887 if ((KbFlag1
& KB_NUM_LOCK_BIT
) == KB_NUM_LOCK_BIT
) {
1888 KeyData
.KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1890 if ((KbFlag1
& KB_SCROLL_LOCK_BIT
) == KB_SCROLL_LOCK_BIT
) {
1891 KeyData
.KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1894 // Record shift state
1895 // BUGBUG: Need add Menu key and Left/Right Logo key state in the future
1897 if ((KbFlag1
& KB_ALT_PRESSED
) == KB_ALT_PRESSED
) {
1898 KeyData
.KeyState
.KeyShiftState
|= ((KbFlag2
& KB_LEFT_ALT_PRESSED
) == KB_LEFT_ALT_PRESSED
) ? EFI_LEFT_ALT_PRESSED
: EFI_RIGHT_ALT_PRESSED
;
1900 if ((KbFlag1
& KB_CTRL_PRESSED
) == KB_CTRL_PRESSED
) {
1901 KeyData
.KeyState
.KeyShiftState
|= ((KbFlag2
& KB_LEFT_CTRL_PRESSED
) == KB_LEFT_CTRL_PRESSED
) ? EFI_LEFT_CONTROL_PRESSED
: EFI_RIGHT_CONTROL_PRESSED
;
1903 if ((KbFlag1
& KB_LEFT_SHIFT_PRESSED
) == KB_LEFT_SHIFT_PRESSED
) {
1904 KeyData
.KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1906 if ((KbFlag1
& KB_RIGHT_SHIFT_PRESSED
) == KB_RIGHT_SHIFT_PRESSED
) {
1907 KeyData
.KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1911 // Clear left alt and left ctrl BDA flag
1914 KbFlag2
&= ~(KB_LEFT_ALT_PRESSED
| KB_LEFT_CTRL_PRESSED
);
1915 *((UINT8
*) (UINTN
) 0x418) = KbFlag2
;
1917 *((UINT8
*) (UINTN
) 0x417) = KbFlag1
;
1921 // Output EFI input key and shift/toggle state
1923 if (KeyData
.Key
.UnicodeChar
== CHAR_NULL
|| KeyData
.Key
.UnicodeChar
== CHAR_SCANCODE
|| KeyData
.Key
.UnicodeChar
== CHAR_ESC
) {
1924 KeyData
.Key
.ScanCode
= ConvertToEFIScanCode (KeyData
.Key
.UnicodeChar
, KeyData
.Key
.ScanCode
);
1925 KeyData
.Key
.UnicodeChar
= CHAR_NULL
;
1927 KeyData
.Key
.ScanCode
= SCAN_NULL
;
1931 // CSM16 has converted the Ctrl+[a-z] to [1-26], converted it back.
1933 if ((KeyData
.KeyState
.KeyShiftState
& (EFI_LEFT_CONTROL_PRESSED
| EFI_RIGHT_CONTROL_PRESSED
)) != 0) {
1934 if (KeyData
.Key
.UnicodeChar
>= 1 && KeyData
.Key
.UnicodeChar
<= 26) {
1935 if (((KeyData
.KeyState
.KeyShiftState
& (EFI_LEFT_SHIFT_PRESSED
| EFI_RIGHT_SHIFT_PRESSED
)) != 0) ==
1936 ((KeyData
.KeyState
.KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) != 0)
1938 KeyData
.Key
.UnicodeChar
= (UINT16
) (KeyData
.Key
.UnicodeChar
+ L
'a' - 1);
1940 KeyData
.Key
.UnicodeChar
= (UINT16
) (KeyData
.Key
.UnicodeChar
+ L
'A' - 1);
1947 "[KBD]Convert to EFI Scan Code, EFI_INPUT_KEY.ScanCode - %x, EFI_INPUT_KEY.UnicodeChar - %x\n",
1948 KeyData
.Key
.ScanCode
,
1949 KeyData
.Key
.UnicodeChar
1953 // Need not return associated shift state if a class of printable characters that
1954 // are normally adjusted by shift modifiers.
1955 // e.g. Shift Key + 'f' key = 'F'; Shift Key + 'F' key = 'f'.
1957 if ((KeyData
.Key
.UnicodeChar
>= L
'A' && KeyData
.Key
.UnicodeChar
<= L
'Z') ||
1958 (KeyData
.Key
.UnicodeChar
>= L
'a' && KeyData
.Key
.UnicodeChar
<= L
'z')
1960 DEBUG ((EFI_D_INFO
, "[KBD]Shift key with a~z are pressed, remove shift state in EFI_KEY_STATE.\n"));
1961 KeyData
.KeyState
.KeyShiftState
&= ~(EFI_LEFT_SHIFT_PRESSED
| EFI_RIGHT_SHIFT_PRESSED
);
1965 // Signal KeyNotify process event if this key pressed matches any key registered.
1967 for (Link
= BiosKeyboardPrivate
->NotifyList
.ForwardLink
; Link
!= &BiosKeyboardPrivate
->NotifyList
; Link
= Link
->ForwardLink
) {
1968 CurrentNotify
= CR (
1970 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
1972 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1974 if (IsKeyRegistered (&CurrentNotify
->KeyData
, &KeyData
)) {
1976 // The key notification function needs to run at TPL_CALLBACK
1977 // while current TPL is TPL_NOTIFY. It will be invoked in
1978 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1980 Enqueue (&BiosKeyboardPrivate
->QueueForNotify
, &KeyData
);
1981 gBS
->SignalEvent (BiosKeyboardPrivate
->KeyNotifyProcessEvent
);
1986 Enqueue (&BiosKeyboardPrivate
->Queue
, &KeyData
);
1989 // Save the current key state
1991 CopyMem (&BiosKeyboardPrivate
->KeyState
, &KeyData
.KeyState
, sizeof (EFI_KEY_STATE
));
1994 // Leave critical section and return
1996 gBS
->RestoreTPL (OldTpl
);
2004 @param Event Indicates the event that invoke this function.
2005 @param Context Indicates the calling context.
2009 KeyNotifyProcessHandler (
2015 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2016 EFI_KEY_DATA KeyData
;
2018 LIST_ENTRY
*NotifyList
;
2019 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
2022 BiosKeyboardPrivate
= (BIOS_KEYBOARD_DEV
*) Context
;
2025 // Invoke notification functions.
2027 NotifyList
= &BiosKeyboardPrivate
->NotifyList
;
2030 // Enter critical section
2032 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
2033 Status
= Dequeue (&BiosKeyboardPrivate
->QueueForNotify
, &KeyData
);
2035 // Leave critical section
2037 gBS
->RestoreTPL (OldTpl
);
2038 if (EFI_ERROR (Status
)) {
2041 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
, Link
); Link
= GetNextNode (NotifyList
, Link
)) {
2042 CurrentNotify
= CR (Link
, BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
, NotifyEntry
, BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
2043 if (IsKeyRegistered (&CurrentNotify
->KeyData
, &KeyData
)) {
2044 CurrentNotify
->KeyNotificationFn (&KeyData
);
2051 Free keyboard notify list.
2053 @param ListHead The list head
2055 @retval EFI_SUCCESS Free the notify list successfully
2056 @retval EFI_INVALID_PARAMETER ListHead is invalid.
2060 BiosKeyboardFreeNotifyList (
2061 IN OUT LIST_ENTRY
*ListHead
2064 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
2066 if (ListHead
== NULL
) {
2067 return EFI_INVALID_PARAMETER
;
2069 while (!IsListEmpty (ListHead
)) {
2071 ListHead
->ForwardLink
,
2072 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
2074 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
2076 RemoveEntryList (ListHead
->ForwardLink
);
2077 gBS
->FreePool (NotifyNode
);
2084 Check if key is registered.
2086 @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
2087 state data for the key that was registered.
2088 @param InputData A pointer to a buffer that is filled in with the keystroke
2089 state data for the key that was pressed.
2091 @retval TRUE Key be pressed matches a registered key.
2092 @retval FLASE Match failed.
2097 IN EFI_KEY_DATA
*RegsiteredData
,
2098 IN EFI_KEY_DATA
*InputData
2101 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
2103 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
2104 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
2109 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
2111 if (RegsiteredData
->KeyState
.KeyShiftState
!= 0 &&
2112 RegsiteredData
->KeyState
.KeyShiftState
!= InputData
->KeyState
.KeyShiftState
) {
2115 if (RegsiteredData
->KeyState
.KeyToggleState
!= 0 &&
2116 RegsiteredData
->KeyState
.KeyToggleState
!= InputData
->KeyState
.KeyToggleState
) {
2125 Waiting on the keyboard event, if there's any key pressed by the user, signal the event
2127 @param Event The event that be siganlled when any key has been stroked.
2128 @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
2133 BiosKeyboardWaitForKeyEx (
2138 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2140 BiosKeyboardPrivate
= TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (Context
);
2141 BiosKeyboardWaitForKey (Event
, &BiosKeyboardPrivate
->SimpleTextIn
);
2146 Reset the input device and optionaly run diagnostics
2148 @param This Protocol instance pointer.
2149 @param ExtendedVerification Driver may perform diagnostics on reset.
2151 @retval EFI_SUCCESS The device was reset.
2152 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
2158 BiosKeyboardResetEx (
2159 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
2160 IN BOOLEAN ExtendedVerification
2163 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2167 BiosKeyboardPrivate
= TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This
);
2169 Status
= BiosKeyboardPrivate
->SimpleTextIn
.Reset (
2170 &BiosKeyboardPrivate
->SimpleTextIn
,
2171 ExtendedVerification
2173 if (EFI_ERROR (Status
)) {
2174 return EFI_DEVICE_ERROR
;
2177 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
2179 gBS
->RestoreTPL (OldTpl
);
2186 Reads the next keystroke from the input device. The WaitForKey Event can
2187 be used to test for existance of a keystroke via WaitForEvent () call.
2189 @param This Protocol instance pointer.
2190 @param KeyData A pointer to a buffer that is filled in with the keystroke
2191 state data for the key that was pressed.
2193 @retval EFI_SUCCESS The keystroke information was returned.
2194 @retval EFI_NOT_READY There was no keystroke data availiable.
2195 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
2197 @retval EFI_INVALID_PARAMETER KeyData is NULL.
2202 BiosKeyboardReadKeyStrokeEx (
2203 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
2204 OUT EFI_KEY_DATA
*KeyData
2207 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2209 if (KeyData
== NULL
) {
2210 return EFI_INVALID_PARAMETER
;
2213 BiosKeyboardPrivate
= TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This
);
2215 return KeyboardReadKeyStrokeWorker (BiosKeyboardPrivate
, KeyData
);
2220 Set certain state for the input device.
2222 @param This Protocol instance pointer.
2223 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
2224 state for the input device.
2226 @retval EFI_SUCCESS The device state was set successfully.
2227 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
2228 not have the setting adjusted.
2229 @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
2230 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
2235 BiosKeyboardSetState (
2236 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
2237 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
2241 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2243 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
2246 if (KeyToggleState
== NULL
) {
2247 return EFI_INVALID_PARAMETER
;
2251 // Thunk keyboard driver doesn't support partial keystroke.
2253 if ((*KeyToggleState
& EFI_TOGGLE_STATE_VALID
) != EFI_TOGGLE_STATE_VALID
||
2254 (*KeyToggleState
& EFI_KEY_STATE_EXPOSED
) == EFI_KEY_STATE_EXPOSED
2256 return EFI_UNSUPPORTED
;
2259 BiosKeyboardPrivate
= TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This
);
2261 // See if the Legacy BIOS Protocol is available
2263 Status
= gBS
->LocateProtocol (
2264 &gEfiLegacyBiosProtocolGuid
,
2266 (VOID
**) &LegacyBios
2269 ASSERT_EFI_ERROR (Status
);
2271 // Enter critical section
2273 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
2276 if ((*KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) == EFI_CAPS_LOCK_ACTIVE
) {
2279 if ((*KeyToggleState
& EFI_NUM_LOCK_ACTIVE
) == EFI_NUM_LOCK_ACTIVE
) {
2282 if ((*KeyToggleState
& EFI_SCROLL_LOCK_ACTIVE
) == EFI_SCROLL_LOCK_ACTIVE
) {
2286 Status
= KeyboardWrite (BiosKeyboardPrivate
, 0xed);
2287 if (EFI_ERROR (Status
)) {
2288 Status
= EFI_DEVICE_ERROR
;
2291 Status
= KeyboardWaitForValue (BiosKeyboardPrivate
, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT
);
2292 if (EFI_ERROR (Status
)) {
2293 Status
= EFI_DEVICE_ERROR
;
2296 Status
= KeyboardWrite (BiosKeyboardPrivate
, Command
);
2297 if (EFI_ERROR (Status
)) {
2298 Status
= EFI_DEVICE_ERROR
;
2302 // Call Legacy BIOS Protocol to set whatever is necessary
2304 LegacyBios
->UpdateKeyboardLedStatus (LegacyBios
, Command
);
2306 Status
= EFI_SUCCESS
;
2310 // Leave critical section and return
2312 gBS
->RestoreTPL (OldTpl
);
2319 Register a notification function for a particular keystroke for the input device.
2321 @param This Protocol instance pointer.
2322 @param KeyData A pointer to a buffer that is filled in with the keystroke
2323 information data for the key that was pressed. If KeyData.Key,
2324 KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState
2325 are 0, then any incomplete keystroke will trigger a notification of
2326 the KeyNotificationFunction.
2327 @param KeyNotificationFunction Points to the function to be called when the key
2328 sequence is typed specified by KeyData. This notification function
2329 should be called at <=TPL_CALLBACK.
2330 @param NotifyHandle Points to the unique handle assigned to the registered notification.
2332 @retval EFI_SUCCESS The notification function was registered successfully.
2333 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
2334 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
2339 BiosKeyboardRegisterKeyNotify (
2340 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
2341 IN EFI_KEY_DATA
*KeyData
,
2342 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
2343 OUT VOID
**NotifyHandle
2347 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2349 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*NewNotify
;
2351 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
2353 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
2354 return EFI_INVALID_PARAMETER
;
2357 BiosKeyboardPrivate
= TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This
);
2360 // Enter critical section
2362 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
2365 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
2367 for (Link
= BiosKeyboardPrivate
->NotifyList
.ForwardLink
; Link
!= &BiosKeyboardPrivate
->NotifyList
; Link
= Link
->ForwardLink
) {
2368 CurrentNotify
= CR (
2370 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
2372 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
2374 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
2375 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
2376 *NotifyHandle
= CurrentNotify
;
2377 Status
= EFI_SUCCESS
;
2384 // Allocate resource to save the notification function
2387 NewNotify
= (BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*) AllocateZeroPool (sizeof (BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
));
2388 if (NewNotify
== NULL
) {
2389 Status
= EFI_OUT_OF_RESOURCES
;
2393 NewNotify
->Signature
= BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
;
2394 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
2395 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
2396 InsertTailList (&BiosKeyboardPrivate
->NotifyList
, &NewNotify
->NotifyEntry
);
2398 *NotifyHandle
= NewNotify
;
2399 Status
= EFI_SUCCESS
;
2403 // Leave critical section and return
2405 gBS
->RestoreTPL (OldTpl
);
2410 Remove a registered notification function from a particular keystroke.
2412 @param This Protocol instance pointer.
2413 @param NotificationHandle The handle of the notification function being unregistered.
2415 @retval EFI_SUCCESS The notification function was unregistered successfully.
2416 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
2421 BiosKeyboardUnregisterKeyNotify (
2422 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
2423 IN VOID
*NotificationHandle
2427 BIOS_KEYBOARD_DEV
*BiosKeyboardPrivate
;
2430 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
2433 // Check incoming notification handle
2435 if (NotificationHandle
== NULL
) {
2436 return EFI_INVALID_PARAMETER
;
2439 if (((BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
*) NotificationHandle
)->Signature
!= BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
) {
2440 return EFI_INVALID_PARAMETER
;
2443 BiosKeyboardPrivate
= TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This
);
2446 // Enter critical section
2448 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
2450 for (Link
= BiosKeyboardPrivate
->NotifyList
.ForwardLink
; Link
!= &BiosKeyboardPrivate
->NotifyList
; Link
= Link
->ForwardLink
) {
2451 CurrentNotify
= CR (
2453 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY
,
2455 BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
2457 if (CurrentNotify
== NotificationHandle
) {
2459 // Remove the notification function from NotifyList and free resources
2461 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
2463 Status
= EFI_SUCCESS
;
2469 // Can not find the specified Notification Handle
2471 Status
= EFI_INVALID_PARAMETER
;
2475 // Leave critical section and return
2477 gBS
->RestoreTPL (OldTpl
);
2482 The user Entry Point for module BiosKeyboard. The user code starts with this function.
2484 @param[in] ImageHandle The firmware allocated handle for the EFI image.
2485 @param[in] SystemTable A pointer to the EFI System Table.
2487 @retval EFI_SUCCESS The entry point is executed successfully.
2488 @retval other Some error occurs when executing this entry point.
2493 InitializeBiosKeyboard(
2494 IN EFI_HANDLE ImageHandle
,
2495 IN EFI_SYSTEM_TABLE
*SystemTable
2501 // Install driver model protocol(s).
2503 Status
= EfiLibInstallDriverBindingComponentName2 (
2506 &gBiosKeyboardDriverBinding
,
2508 &gBiosKeyboardComponentName
,
2509 &gBiosKeyboardComponentName2
2511 ASSERT_EFI_ERROR (Status
);