3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Helper functions for USB Keyboard Driver
26 #include <Library/UsbLib.h>
29 // Static English keyboard layout
30 // Format:<efi key>, <unicode without shift>, <unicode with shift>, <Modifier>, <AffectedAttribute>
33 UINT8 KeyboardLayoutTable
[USB_KEYCODE_MAX_MAKE
+ 8][5] = {
34 {EfiKeyC1
, 'a', 'A', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x04
35 {EfiKeyB5
, 'b', 'B', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x05
36 {EfiKeyB3
, 'c', 'C', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x06
37 {EfiKeyC3
, 'd', 'D', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x07
38 {EfiKeyD3
, 'e', 'E', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x08
39 {EfiKeyC4
, 'f', 'F', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x09
40 {EfiKeyC5
, 'g', 'G', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0A
41 {EfiKeyC6
, 'h', 'H', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0B
42 {EfiKeyD8
, 'i', 'I', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0C
43 {EfiKeyC7
, 'j', 'J', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0D
44 {EfiKeyC8
, 'k', 'K', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0E
45 {EfiKeyC9
, 'l', 'L', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x0F
46 {EfiKeyB7
, 'm', 'M', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x10
47 {EfiKeyB6
, 'n', 'N', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x11
48 {EfiKeyD9
, 'o', 'O', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x12
49 {EfiKeyD10
, 'p', 'P', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x13
50 {EfiKeyD1
, 'q', 'Q', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x14
51 {EfiKeyD4
, 'r', 'R', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x15
52 {EfiKeyC2
, 's', 'S', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x16
53 {EfiKeyD5
, 't', 'T', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x17
54 {EfiKeyD7
, 'u', 'U', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x18
55 {EfiKeyB4
, 'v', 'V', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x19
56 {EfiKeyD2
, 'w', 'W', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1A
57 {EfiKeyB2
, 'x', 'X', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1B
58 {EfiKeyD6
, 'y', 'Y', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1C
59 {EfiKeyB1
, 'z', 'Z', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_CAPS_LOCK
}, // 0x1D
60 {EfiKeyE1
, '1', '!', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x1E
61 {EfiKeyE2
, '2', '@', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x1F
62 {EfiKeyE3
, '3', '#', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x20
63 {EfiKeyE4
, '4', '$', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x21
64 {EfiKeyE5
, '5', '%', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x22
65 {EfiKeyE6
, '6', '^', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x23
66 {EfiKeyE7
, '7', '&', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x24
67 {EfiKeyE8
, '8', '*', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x25
68 {EfiKeyE9
, '9', '(', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x26
69 {EfiKeyE10
, '0', ')', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x27
70 {EfiKeyEnter
, 0x0d, 0x0d, EFI_NULL_MODIFIER
, 0}, // 0x28 Enter
71 {EfiKeyEsc
, 0x1b, 0x1b, EFI_NULL_MODIFIER
, 0}, // 0x29 Esc
72 {EfiKeyBackSpace
, 0x08, 0x08, EFI_NULL_MODIFIER
, 0}, // 0x2A Backspace
73 {EfiKeyTab
, 0x09, 0x09, EFI_NULL_MODIFIER
, 0}, // 0x2B Tab
74 {EfiKeySpaceBar
, ' ', ' ', EFI_NULL_MODIFIER
, 0}, // 0x2C Spacebar
75 {EfiKeyE11
, '-', '_', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x2D
76 {EfiKeyE12
, '=', '+', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x2E
77 {EfiKeyD11
, '[', '{', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x2F
78 {EfiKeyD12
, ']', '}', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x30
79 {EfiKeyD13
, '\\', '|', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x31
80 {EfiKeyC12
, '\\', '|', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x32 Keyboard Non-US # and ~
81 {EfiKeyC10
, ';', ':', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x33
82 {EfiKeyC11
, '\'', '"', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x34
83 {EfiKeyE0
, '`', '~', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x35 Keyboard Grave Accent and Tlide
84 {EfiKeyB8
, ',', '<', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x36
85 {EfiKeyB9
, '.', '>', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x37
86 {EfiKeyB10
, '/', '?', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x38
87 {EfiKeyCapsLock
, 0x00, 0x00, EFI_CAPS_LOCK_MODIFIER
, 0}, // 0x39 CapsLock
88 {EfiKeyF1
, 0x00, 0x00, EFI_FUNCTION_KEY_ONE_MODIFIER
, 0}, // 0x3A
89 {EfiKeyF2
, 0x00, 0x00, EFI_FUNCTION_KEY_TWO_MODIFIER
, 0}, // 0x3B
90 {EfiKeyF3
, 0x00, 0x00, EFI_FUNCTION_KEY_THREE_MODIFIER
, 0}, // 0x3C
91 {EfiKeyF4
, 0x00, 0x00, EFI_FUNCTION_KEY_FOUR_MODIFIER
, 0}, // 0x3D
92 {EfiKeyF5
, 0x00, 0x00, EFI_FUNCTION_KEY_FIVE_MODIFIER
, 0}, // 0x3E
93 {EfiKeyF6
, 0x00, 0x00, EFI_FUNCTION_KEY_SIX_MODIFIER
, 0}, // 0x3F
94 {EfiKeyF7
, 0x00, 0x00, EFI_FUNCTION_KEY_SEVEN_MODIFIER
, 0}, // 0x40
95 {EfiKeyF8
, 0x00, 0x00, EFI_FUNCTION_KEY_EIGHT_MODIFIER
, 0}, // 0x41
96 {EfiKeyF9
, 0x00, 0x00, EFI_FUNCTION_KEY_NINE_MODIFIER
, 0}, // 0x42
97 {EfiKeyF10
, 0x00, 0x00, EFI_FUNCTION_KEY_TEN_MODIFIER
, 0}, // 0x43
98 {EfiKeyF11
, 0x00, 0x00, EFI_FUNCTION_KEY_ELEVEN_MODIFIER
, 0}, // 0x44 F11
99 {EfiKeyF12
, 0x00, 0x00, EFI_FUNCTION_KEY_TWELVE_MODIFIER
, 0}, // 0x45 F12
100 {EfiKeyPrint
, 0x00, 0x00, EFI_PRINT_MODIFIER
, 0}, // 0x46 PrintScreen
101 {EfiKeySLck
, 0x00, 0x00, EFI_SCROLL_LOCK_MODIFIER
, 0}, // 0x47 Scroll Lock
102 {EfiKeyPause
, 0x00, 0x00, EFI_PAUSE_MODIFIER
, 0}, // 0x48 Pause
103 {EfiKeyIns
, 0x00, 0x00, EFI_INSERT_MODIFIER
, 0}, // 0x49
104 {EfiKeyHome
, 0x00, 0x00, EFI_HOME_MODIFIER
, 0}, // 0x4A
105 {EfiKeyPgUp
, 0x00, 0x00, EFI_PAGE_UP_MODIFIER
, 0}, // 0x4B
106 {EfiKeyDel
, 0x00, 0x00, EFI_DELETE_MODIFIER
, 0}, // 0x4C
107 {EfiKeyEnd
, 0x00, 0x00, EFI_END_MODIFIER
, 0}, // 0x4D
108 {EfiKeyPgDn
, 0x00, 0x00, EFI_PAGE_DOWN_MODIFIER
, 0}, // 0x4E
109 {EfiKeyRightArrow
, 0x00, 0x00, EFI_RIGHT_ARROW_MODIFIER
, 0}, // 0x4F
110 {EfiKeyLeftArrow
, 0x00, 0x00, EFI_LEFT_ARROW_MODIFIER
, 0}, // 0x50
111 {EfiKeyDownArrow
, 0x00, 0x00, EFI_DOWN_ARROW_MODIFIER
, 0}, // 0x51
112 {EfiKeyUpArrow
, 0x00, 0x00, EFI_UP_ARROW_MODIFIER
, 0}, // 0x52
113 {EfiKeyNLck
, 0x00, 0x00, EFI_NUM_LOCK_MODIFIER
, 0}, // 0x53 NumLock
114 {EfiKeySlash
, '/', '/', EFI_NULL_MODIFIER
, 0}, // 0x54
115 {EfiKeyAsterisk
, '*', '*', EFI_NULL_MODIFIER
, 0}, // 0x55
116 {EfiKeyMinus
, '-', '-', EFI_NULL_MODIFIER
, 0}, // 0x56
117 {EfiKeyPlus
, '+', '+', EFI_NULL_MODIFIER
, 0}, // 0x57
118 {EfiKeyEnter
, 0x0d, 0x0d, EFI_NULL_MODIFIER
, 0}, // 0x58
119 {EfiKeyOne
, '1', '1', EFI_END_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x59
120 {EfiKeyTwo
, '2', '2', EFI_DOWN_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5A
121 {EfiKeyThree
, '3', '3', EFI_PAGE_DOWN_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5B
122 {EfiKeyFour
, '4', '4', EFI_LEFT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5C
123 {EfiKeyFive
, '5', '5', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5D
124 {EfiKeySix
, '6', '6', EFI_RIGHT_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5E
125 {EfiKeySeven
, '7', '7', EFI_HOME_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x5F
126 {EfiKeyEight
, '8', '8', EFI_UP_ARROW_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x60
127 {EfiKeyNine
, '9', '9', EFI_PAGE_UP_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x61
128 {EfiKeyZero
, '0', '0', EFI_INSERT_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x62
129 {EfiKeyPeriod
, '.', '.', EFI_DELETE_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
| EFI_AFFECTED_BY_NUM_LOCK
}, // 0x63
130 {EfiKeyB0
, '\\', '|', EFI_NULL_MODIFIER
, EFI_AFFECTED_BY_STANDARD_SHIFT
}, // 0x64 Keyboard Non-US \ and |
131 {EfiKeyA4
, 0x00, 0x00, EFI_NULL_MODIFIER
, 0}, // 0x65 Keyboard Application
133 {EfiKeyLCtrl
, 0, 0, EFI_LEFT_CONTROL_MODIFIER
, 0}, // 0xe0
134 {EfiKeyLShift
, 0, 0, EFI_LEFT_SHIFT_MODIFIER
, 0}, // 0xe1
135 {EfiKeyLAlt
, 0, 0, EFI_LEFT_ALT_MODIFIER
, 0}, // 0xe2
136 {EfiKeyA0
, 0, 0, EFI_NULL_MODIFIER
, 0}, // 0xe3
137 {EfiKeyRCtrl
, 0, 0, EFI_RIGHT_CONTROL_MODIFIER
, 0}, // 0xe4
138 {EfiKeyRShift
, 0, 0, EFI_RIGHT_SHIFT_MODIFIER
, 0}, // 0xe5
139 {EfiKeyA2
, 0, 0, EFI_RIGHT_ALT_MODIFIER
, 0}, // 0xe6
140 {EfiKeyA3
, 0, 0, EFI_NULL_MODIFIER
, 0}, // 0xe7
144 LoadDefaultKeyboardLayout (
145 IN USB_KB_DEV
*UsbKeyboardDevice
150 Initialize KeyConvertionTable by using default keyboard layout.
153 UsbKeyboardDevice The USB_KB_DEV instance.
161 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
164 // Construct KeyConvertionTable by default keyboard layout
166 KeyDescriptor
= &UsbKeyboardDevice
->KeyConvertionTable
[0];
168 for (Index
= 0; Index
< (USB_KEYCODE_MAX_MAKE
+ 8); Index
++) {
169 KeyDescriptor
->Key
= (EFI_KEY
) KeyboardLayoutTable
[Index
][0];
170 KeyDescriptor
->Unicode
= KeyboardLayoutTable
[Index
][1];
171 KeyDescriptor
->ShiftedUnicode
= KeyboardLayoutTable
[Index
][2];
172 KeyDescriptor
->AltGrUnicode
= 0;
173 KeyDescriptor
->ShiftedAltGrUnicode
= 0;
174 KeyDescriptor
->Modifier
= KeyboardLayoutTable
[Index
][3];
175 KeyDescriptor
->AffectedAttribute
= KeyboardLayoutTable
[Index
][4];
182 // EFI_KEY to USB Scan Code convertion table
185 UINT8 UsbScanCodeConvertionTable
[] = {
189 0x2c, // EfiKeySpaceBar
194 0x50, // EfiKeyLeftArrow
195 0x51, // EfiKeyDownArrow
196 0x4F, // EfiKeyRightArrow
198 0x63, // EfiKeyPeriod
200 0xe1, // EfiKeyLShift
212 0xe5, // EfiKeyRShift
213 0x52, // EfiKeyUpArrow
217 0x39, // EfiKeyCapsLock
267 0x2A, // EfiKeyBackSpace
273 0x55, // EfiKeyAsterisk
294 // Keyboard Layout Modifier to EFI Scan Code convertion table
297 UINT8 EfiScanCodeConvertionTable
[] = {
298 SCAN_NULL
, // EFI_NULL_MODIFIER
299 SCAN_NULL
, // EFI_LEFT_CONTROL_MODIFIER
300 SCAN_NULL
, // EFI_RIGHT_CONTROL_MODIFIER
301 SCAN_NULL
, // EFI_LEFT_ALT_MODIFIER
302 SCAN_NULL
, // EFI_RIGHT_ALT_MODIFIER
303 SCAN_NULL
, // EFI_ALT_GR_MODIFIER
304 SCAN_INSERT
, // EFI_INSERT_MODIFIER
305 SCAN_DELETE
, // EFI_DELETE_MODIFIER
306 SCAN_PAGE_DOWN
, // EFI_PAGE_DOWN_MODIFIER
307 SCAN_PAGE_UP
, // EFI_PAGE_UP_MODIFIER
308 SCAN_HOME
, // EFI_HOME_MODIFIER
309 SCAN_END
, // EFI_END_MODIFIER
310 SCAN_NULL
, // EFI_LEFT_SHIFT_MODIFIER
311 SCAN_NULL
, // EFI_RIGHT_SHIFT_MODIFIER
312 SCAN_NULL
, // EFI_CAPS_LOCK_MODIFIER
313 SCAN_NULL
, // EFI_NUM_LOCK_MODIFIER
314 SCAN_LEFT
, // EFI_LEFT_ARROW_MODIFIER
315 SCAN_RIGHT
, // EFI_RIGHT_ARROW_MODIFIER
316 SCAN_DOWN
, // EFI_DOWN_ARROW_MODIFIER
317 SCAN_UP
, // EFI_UP_ARROW_MODIFIER
318 SCAN_NULL
, // EFI_NS_KEY_MODIFIER
319 SCAN_NULL
, // EFI_NS_KEY_DEPENDENCY_MODIFIER
320 SCAN_F1
, // EFI_FUNCTION_KEY_ONE_MODIFIER
321 SCAN_F2
, // EFI_FUNCTION_KEY_TWO_MODIFIER
322 SCAN_F3
, // EFI_FUNCTION_KEY_THREE_MODIFIER
323 SCAN_F4
, // EFI_FUNCTION_KEY_FOUR_MODIFIER
324 SCAN_F5
, // EFI_FUNCTION_KEY_FIVE_MODIFIER
325 SCAN_F6
, // EFI_FUNCTION_KEY_SIX_MODIFIER
326 SCAN_F7
, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
327 SCAN_F8
, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
328 SCAN_F9
, // EFI_FUNCTION_KEY_NINE_MODIFIER
329 SCAN_F10
, // EFI_FUNCTION_KEY_TEN_MODIFIER
330 SCAN_F11
, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
331 SCAN_F12
, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
334 EFI_GUID mKeyboardLayoutEventGuid
= EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
;
337 STATIC KB_MODIFIER KB_Mod
[8] = {
338 { MOD_CONTROL_L
, 0xe0 }, // 11100000
339 { MOD_CONTROL_R
, 0xe4 }, // 11100100
340 { MOD_SHIFT_L
, 0xe1 }, // 11100001
341 { MOD_SHIFT_R
, 0xe5 }, // 11100101
342 { MOD_ALT_L
, 0xe2 }, // 11100010
343 { MOD_ALT_R
, 0xe6 }, // 11100110
344 { MOD_WIN_L
, 0xe3 }, // 11100011
345 { MOD_WIN_R
, 0xe7 }, // 11100111
351 Uses USB I/O to check whether the device is a USB Keyboard device.
353 UsbIo: Points to a USB I/O protocol instance.
359 IN EFI_USB_IO_PROTOCOL
*UsbIo
363 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
366 // Get the Default interface descriptor, currently we
367 // assume it is interface 1
369 Status
= UsbIo
->UsbGetInterfaceDescriptor (
374 if (EFI_ERROR (Status
)) {
378 if (InterfaceDescriptor
.InterfaceClass
== CLASS_HID
&&
379 InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
&&
380 InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_KEYBOARD
390 EFI_HII_KEYBOARD_LAYOUT
*
391 GetCurrentKeyboardLayout (
397 Get current keyboard layout from HII database.
403 Pointer to EFI_HII_KEYBOARD_LAYOUT.
408 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
409 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
413 // Locate Hii database protocol
415 Status
= gBS
->LocateProtocol (
416 &gEfiHiiDatabaseProtocolGuid
,
418 (VOID
**) &HiiDatabase
420 if (EFI_ERROR (Status
)) {
425 // Get current keyboard layout from HII database
428 KeyboardLayout
= NULL
;
429 Status
= HiiDatabase
->GetKeyboardLayout (
435 if (Status
== EFI_BUFFER_TOO_SMALL
) {
436 KeyboardLayout
= AllocatePool (Length
);
437 ASSERT (KeyboardLayout
!= NULL
);
439 Status
= HiiDatabase
->GetKeyboardLayout (
445 if (EFI_ERROR (Status
)) {
446 gBS
->FreePool (KeyboardLayout
);
447 KeyboardLayout
= NULL
;
451 return KeyboardLayout
;
456 IN USB_KB_DEV
*UsbKeyboardDevice
,
462 Find Key Descriptor in KeyConvertionTable given its scan code.
465 UsbKeyboardDevice - The USB_KB_DEV instance.
466 ScanCode - USB scan code.
469 The Key descriptor in KeyConvertionTable.
475 if (((ScanCode
> 0x65) && (ScanCode
< 0xe0)) || (ScanCode
> 0xe7)) {
479 if (ScanCode
<= 0x65) {
480 Index
= (UINT8
) (ScanCode
- 4);
482 Index
= (UINT8
) (ScanCode
- 0xe0 + USB_KEYCODE_MAX_MAKE
);
485 return &UsbKeyboardDevice
->KeyConvertionTable
[Index
];
490 IN USB_KB_DEV
*UsbKeyboardDevice
,
491 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
496 Find Non-Spacing key for given KeyDescriptor.
499 UsbKeyboardDevice - The USB_KB_DEV instance.
500 KeyDescriptor - Key descriptor.
508 USB_NS_KEY
*UsbNsKey
;
510 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
511 while (!IsNull (&UsbKeyboardDevice
->NsKeyList
, Link
)) {
512 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
514 if (UsbNsKey
->NsKey
[0].Key
== KeyDescriptor
->Key
) {
518 Link
= GetNextNode (&UsbKeyboardDevice
->NsKeyList
, Link
);
526 IN USB_NS_KEY
*UsbNsKey
,
527 IN EFI_KEY_DESCRIPTOR
*KeyDescriptor
532 Find physical key definition for a given Key stroke.
535 UsbNsKey - The Non-Spacing key information.
536 KeyDescriptor - The key stroke.
539 The physical key definition.
544 EFI_KEY_DESCRIPTOR
*PhysicalKey
;
546 PhysicalKey
= &UsbNsKey
->NsKey
[1];
547 for (Index
= 0; Index
< UsbNsKey
->KeyCount
; Index
++) {
548 if (KeyDescriptor
->Key
== PhysicalKey
->Key
) {
556 // No children definition matched, return original key
558 return KeyDescriptor
;
563 SetKeyboardLayoutEvent (
570 The notification function for SET_KEYBOARD_LAYOUT_EVENT.
578 USB_KB_DEV
*UsbKeyboardDevice
;
579 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
580 EFI_KEY_DESCRIPTOR TempKey
;
581 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
582 EFI_KEY_DESCRIPTOR
*TableEntry
;
583 EFI_KEY_DESCRIPTOR
*NsKey
;
584 USB_NS_KEY
*UsbNsKey
;
590 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
593 // Try to get current Keyboard Layout from HII database
595 KeyboardLayout
= GetCurrentKeyboardLayout ();
596 if (KeyboardLayout
== NULL
) {
601 // Allocate resource for KeyConvertionTable
603 ReleaseKeyboardLayoutResources (UsbKeyboardDevice
);
604 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((USB_KEYCODE_MAX_MAKE
+ 8) * sizeof (EFI_KEY_DESCRIPTOR
));
605 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
607 KeyDescriptor
= (EFI_KEY_DESCRIPTOR
*) (((UINT8
*) KeyboardLayout
) + sizeof (EFI_HII_KEYBOARD_LAYOUT
));
608 for (Index
= 0; Index
< KeyboardLayout
->DescriptorCount
; Index
++) {
610 // Copy from HII keyboard layout package binary for alignment
612 CopyMem (&TempKey
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
615 // Fill the key into KeyConvertionTable (which use USB Scan Code as index)
617 ScanCode
= UsbScanCodeConvertionTable
[(UINT8
) (TempKey
.Key
)];
618 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, ScanCode
);
619 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
621 if (TempKey
.Modifier
== EFI_NS_KEY_MODIFIER
) {
625 UsbNsKey
= AllocatePool (sizeof (USB_NS_KEY
));
626 ASSERT (UsbNsKey
!= NULL
);
629 // Search for sequential children physical key definitions
632 NsKey
= KeyDescriptor
+ 1;
633 for (Index2
= Index
+ 1; Index2
< KeyboardLayout
->DescriptorCount
; Index2
++) {
634 CopyMem (&TempKey
, NsKey
, sizeof (EFI_KEY_DESCRIPTOR
));
635 if (TempKey
.Modifier
& EFI_NS_KEY_DEPENDENCY_MODIFIER
) {
643 UsbNsKey
->Signature
= USB_NS_KEY_SIGNATURE
;
644 UsbNsKey
->KeyCount
= KeyCount
;
645 UsbNsKey
->NsKey
= AllocateCopyPool (
646 (KeyCount
+ 1) * sizeof (EFI_KEY_DESCRIPTOR
),
649 InsertTailList (&UsbKeyboardDevice
->NsKeyList
, &UsbNsKey
->Link
);
652 // Skip over the child physical keys
655 KeyDescriptor
+= KeyCount
;
662 // There are two EfiKeyEnter, duplicate its Key Descriptor
664 TableEntry
= GetKeyDescriptor (UsbKeyboardDevice
, 0x58);
665 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, 0x28);
666 CopyMem (TableEntry
, KeyDescriptor
, sizeof (EFI_KEY_DESCRIPTOR
));
668 gBS
->FreePool (KeyboardLayout
);
672 ReleaseKeyboardLayoutResources (
673 IN USB_KB_DEV
*UsbKeyboardDevice
678 Destroy resources for Keyboard layout.
681 UsbKeyboardDevice - The USB_KB_DEV instance.
688 USB_NS_KEY
*UsbNsKey
;
691 SafeFreePool (UsbKeyboardDevice
->KeyConvertionTable
);
692 UsbKeyboardDevice
->KeyConvertionTable
= NULL
;
694 while (!IsListEmpty (&UsbKeyboardDevice
->NsKeyList
)) {
695 Link
= GetFirstNode (&UsbKeyboardDevice
->NsKeyList
);
696 UsbNsKey
= USB_NS_KEY_FORM_FROM_LINK (Link
);
697 RemoveEntryList (&UsbNsKey
->Link
);
699 gBS
->FreePool (UsbNsKey
->NsKey
);
700 gBS
->FreePool (UsbNsKey
);
706 IN USB_KB_DEV
*UsbKeyboardDevice
711 Initialize USB Keyboard layout.
714 UsbKeyboardDevice The USB_KB_DEV instance.
717 EFI_SUCCESS - Success
718 Other - Keyboard layout initial failed.
721 EFI_HII_KEYBOARD_LAYOUT
*KeyboardLayout
;
724 UsbKeyboardDevice
->KeyConvertionTable
= AllocateZeroPool ((USB_KEYCODE_MAX_MAKE
+ 8) * sizeof (EFI_KEY_DESCRIPTOR
));
725 ASSERT (UsbKeyboardDevice
->KeyConvertionTable
!= NULL
);
727 InitializeListHead (&UsbKeyboardDevice
->NsKeyList
);
728 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
729 UsbKeyboardDevice
->KeyboardLayoutEvent
= NULL
;
732 // Register SET_KEYBOARD_LAYOUT_EVENT notification
734 Status
= gBS
->CreateEventEx (
735 EFI_EVENT_NOTIFY_SIGNAL
,
737 SetKeyboardLayoutEvent
,
739 &mKeyboardLayoutEventGuid
,
740 &UsbKeyboardDevice
->KeyboardLayoutEvent
742 if (EFI_ERROR (Status
)) {
747 // Try to get current keyboard layout from HII database
749 KeyboardLayout
= GetCurrentKeyboardLayout ();
750 if (KeyboardLayout
!= NULL
) {
752 // Force to initialize the keyboard layout
754 gBS
->SignalEvent (UsbKeyboardDevice
->KeyboardLayoutEvent
);
756 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver
)) {
757 return EFI_NOT_READY
;
761 // Fail to get keyboard layout from HII database,
762 // use default keyboard layout
764 LoadDefaultKeyboardLayout (UsbKeyboardDevice
);
773 Initialize USB Keyboard device and all private data structures.
775 UsbKeyboardDevice The USB_KB_DEV instance.
777 @retval EFI_SUCCESS Success
778 @retval EFI_DEVICE_ERROR Hardware Error
783 IN USB_KB_DEV
*UsbKeyboardDevice
791 UINT32 TransferResult
;
793 KbdReportStatusCode (
794 UsbKeyboardDevice
->DevicePath
,
796 PcdGet32 (PcdStatusCodeValueKeyboardSelfTest
)
799 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
802 // default configurations
807 // Uses default configuration to configure the USB Keyboard device.
809 Status
= UsbSetConfiguration (
810 UsbKeyboardDevice
->UsbIo
,
811 (UINT16
) ConfigValue
,
814 if (EFI_ERROR (Status
)) {
816 // If configuration could not be set here, it means
817 // the keyboard interface has some errors and could
818 // not be initialized
820 KbdReportStatusCode (
821 UsbKeyboardDevice
->DevicePath
,
822 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
823 PcdGet32 (PcdStatusCodeValueKeyboardInterfaceError
)
826 return EFI_DEVICE_ERROR
;
829 UsbGetProtocolRequest (
830 UsbKeyboardDevice
->UsbIo
,
831 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
835 // Sets boot protocol for the USB Keyboard.
836 // This driver only supports boot protocol.
837 // !!BugBug: How about the device that does not support boot protocol?
839 if (Protocol
!= BOOT_PROTOCOL
) {
840 UsbSetProtocolRequest (
841 UsbKeyboardDevice
->UsbIo
,
842 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
847 // the duration is indefinite, so the endpoint will inhibit reporting forever,
848 // and only reporting when a change is detected in the report data.
852 // idle value for all report ID
856 // idle forever until there is a key pressed and released.
860 UsbKeyboardDevice
->UsbIo
,
861 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
866 UsbKeyboardDevice
->CtrlOn
= 0;
867 UsbKeyboardDevice
->AltOn
= 0;
868 UsbKeyboardDevice
->ShiftOn
= 0;
869 UsbKeyboardDevice
->NumLockOn
= 0;
870 UsbKeyboardDevice
->CapsOn
= 0;
871 UsbKeyboardDevice
->ScrollOn
= 0;
873 UsbKeyboardDevice
->LeftCtrlOn
= 0;
874 UsbKeyboardDevice
->LeftAltOn
= 0;
875 UsbKeyboardDevice
->LeftShiftOn
= 0;
876 UsbKeyboardDevice
->LeftLogoOn
= 0;
877 UsbKeyboardDevice
->RightCtrlOn
= 0;
878 UsbKeyboardDevice
->RightAltOn
= 0;
879 UsbKeyboardDevice
->RightShiftOn
= 0;
880 UsbKeyboardDevice
->RightLogoOn
= 0;
881 UsbKeyboardDevice
->MenuKeyOn
= 0;
882 UsbKeyboardDevice
->SysReqOn
= 0;
884 UsbKeyboardDevice
->AltGrOn
= 0;
886 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
889 // Sync the initial state of lights
891 SetKeyLED (UsbKeyboardDevice
);
893 ZeroMem (UsbKeyboardDevice
->LastKeyCodeArray
, sizeof (UINT8
) * 8);
896 // Set a timer for repeat keys' generation.
898 if (UsbKeyboardDevice
->RepeatTimer
) {
899 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
900 UsbKeyboardDevice
->RepeatTimer
= 0;
903 Status
= gBS
->CreateEvent (
904 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
906 USBKeyboardRepeatHandler
,
908 &UsbKeyboardDevice
->RepeatTimer
911 if (UsbKeyboardDevice
->DelayedRecoveryEvent
) {
912 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
913 UsbKeyboardDevice
->DelayedRecoveryEvent
= 0;
916 Status
= gBS
->CreateEvent (
917 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
919 USBKeyboardRecoveryHandler
,
921 &UsbKeyboardDevice
->DelayedRecoveryEvent
929 Handler function for USB Keyboard's asynchronous interrupt transfer.
931 Data A pointer to a buffer that is filled with key data which is
932 retrieved via asynchronous interrupt transfer.
933 DataLength Indicates the size of the data buffer.
934 Context Pointing to USB_KB_DEV instance.
935 Result Indicates the result of the asynchronous interrupt transfer.
937 @retval EFI_SUCCESS Success
938 @retval EFI_DEVICE_ERROR Hardware Error
950 USB_KB_DEV
*UsbKeyboardDevice
;
951 EFI_USB_IO_PROTOCOL
*UsbIo
;
952 UINT8
*CurKeyCodeBuffer
;
953 UINT8
*OldKeyCodeBuffer
;
954 UINT8 CurModifierMap
;
955 UINT8 OldModifierMap
;
965 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
970 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
971 UsbIo
= UsbKeyboardDevice
->UsbIo
;
974 // Analyzes the Result and performs corresponding action.
976 if (Result
!= EFI_USB_NOERROR
) {
978 // Some errors happen during the process
980 KbdReportStatusCode (
981 UsbKeyboardDevice
->DevicePath
,
982 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
983 PcdGet32 (PcdStatusCodeValueKeyboardInputError
)
987 // stop the repeat key generation if any
989 UsbKeyboardDevice
->RepeatKey
= 0;
992 UsbKeyboardDevice
->RepeatTimer
,
997 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
998 UsbClearEndpointHalt (
1000 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1006 // Delete & Submit this interrupt again
1009 UsbIo
->UsbAsyncInterruptTransfer (
1011 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1020 UsbKeyboardDevice
->DelayedRecoveryEvent
,
1022 EFI_USB_INTERRUPT_DELAY
1025 return EFI_DEVICE_ERROR
;
1028 if (DataLength
== 0 || Data
== NULL
) {
1032 CurKeyCodeBuffer
= (UINT8
*) Data
;
1033 OldKeyCodeBuffer
= UsbKeyboardDevice
->LastKeyCodeArray
;
1036 // checks for new key stroke.
1037 // if no new key got, return immediately.
1039 for (Index
= 0; Index
< 8; Index
++) {
1040 if (OldKeyCodeBuffer
[Index
] != CurKeyCodeBuffer
[Index
]) {
1050 // Parse the modifier key
1052 CurModifierMap
= CurKeyCodeBuffer
[0];
1053 OldModifierMap
= OldKeyCodeBuffer
[0];
1056 // handle modifier key's pressing or releasing situation.
1058 for (Index
= 0; Index
< 8; Index
++) {
1060 if ((CurModifierMap
& KB_Mod
[Index
].Mask
) != (OldModifierMap
& KB_Mod
[Index
].Mask
)) {
1062 // if current modifier key is up, then
1063 // CurModifierMap & KB_Mod[Index].Mask = 0;
1064 // otherwize it is a non-zero value.
1065 // Inserts the pressed modifier key into key buffer.
1067 Down
= (UINT8
) (CurModifierMap
& KB_Mod
[Index
].Mask
);
1068 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), KB_Mod
[Index
].Key
, Down
);
1073 // handle normal key's releasing situation
1076 for (Index
= 2; Index
< 8; Index
++) {
1078 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index
])) {
1083 for (Index2
= 2; Index2
< 8; Index2
++) {
1085 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index2
])) {
1089 if (OldKeyCodeBuffer
[Index
] == CurKeyCodeBuffer
[Index2
]) {
1097 &(UsbKeyboardDevice
->KeyboardBuffer
),
1098 OldKeyCodeBuffer
[Index
],
1102 // the original reapeat key is released.
1104 if (OldKeyCodeBuffer
[Index
] == UsbKeyboardDevice
->RepeatKey
) {
1105 UsbKeyboardDevice
->RepeatKey
= 0;
1111 // original repeat key is released, cancel the repeat timer
1113 if (UsbKeyboardDevice
->RepeatKey
== 0) {
1115 UsbKeyboardDevice
->RepeatTimer
,
1122 // handle normal key's pressing situation
1125 for (Index
= 2; Index
< 8; Index
++) {
1127 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer
[Index
])) {
1132 for (Index2
= 2; Index2
< 8; Index2
++) {
1134 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer
[Index2
])) {
1138 if (CurKeyCodeBuffer
[Index
] == OldKeyCodeBuffer
[Index2
]) {
1145 InsertKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), CurKeyCodeBuffer
[Index
], 1);
1147 // NumLock pressed or CapsLock pressed
1149 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, CurKeyCodeBuffer
[Index
]);
1150 if (KeyDescriptor
->Modifier
== EFI_NUM_LOCK_MODIFIER
|| KeyDescriptor
->Modifier
== EFI_CAPS_LOCK_MODIFIER
) {
1151 UsbKeyboardDevice
->RepeatKey
= 0;
1153 NewRepeatKey
= CurKeyCodeBuffer
[Index
];
1155 // do not repeat the original repeated key
1157 UsbKeyboardDevice
->RepeatKey
= 0;
1163 // Update LastKeycodeArray[] buffer in the
1164 // Usb Keyboard Device data structure.
1166 for (Index
= 0; Index
< 8; Index
++) {
1167 UsbKeyboardDevice
->LastKeyCodeArray
[Index
] = CurKeyCodeBuffer
[Index
];
1171 // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
1172 // and judge whether it will invoke reset event.
1174 SavedTail
= UsbKeyboardDevice
->KeyboardBuffer
.bTail
;
1175 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
1176 while (Index
!= SavedTail
) {
1177 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
1179 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1181 switch (KeyDescriptor
->Modifier
) {
1183 case EFI_LEFT_CONTROL_MODIFIER
:
1184 case EFI_RIGHT_CONTROL_MODIFIER
:
1186 UsbKeyboardDevice
->CtrlOn
= 1;
1188 UsbKeyboardDevice
->CtrlOn
= 0;
1192 case EFI_LEFT_ALT_MODIFIER
:
1193 case EFI_RIGHT_ALT_MODIFIER
:
1195 UsbKeyboardDevice
->AltOn
= 1;
1197 UsbKeyboardDevice
->AltOn
= 0;
1201 case EFI_ALT_GR_MODIFIER
:
1203 UsbKeyboardDevice
->AltGrOn
= 1;
1205 UsbKeyboardDevice
->AltGrOn
= 0;
1212 case EFI_DELETE_MODIFIER
:
1214 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
1215 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1225 // insert the key back to the buffer.
1226 // so the key sequence will not be destroyed.
1229 &(UsbKeyboardDevice
->KeyboardBuffer
),
1233 Index
= UsbKeyboardDevice
->KeyboardBuffer
.bHead
;
1237 // If have new key pressed, update the RepeatKey value, and set the
1238 // timer to repeate delay timer
1240 if (NewRepeatKey
!= 0) {
1242 // sets trigger time to "Repeat Delay Time",
1243 // to trigger the repeat timer when the key is hold long
1247 UsbKeyboardDevice
->RepeatTimer
,
1251 UsbKeyboardDevice
->RepeatKey
= NewRepeatKey
;
1259 Retrieves a key character after parsing the raw data in keyboard buffer.
1261 UsbKeyboardDevice The USB_KB_DEV instance.
1262 KeyChar Points to the Key character after key parsing.
1264 @retval EFI_SUCCESS Success
1265 @retval EFI_NOT_READY Device is not ready
1270 IN OUT USB_KB_DEV
*UsbKeyboardDevice
,
1275 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1279 while (!IsUSBKeyboardBufferEmpty (&UsbKeyboardDevice
->KeyboardBuffer
)) {
1281 // pops one raw data off.
1283 RemoveKeyCode (&(UsbKeyboardDevice
->KeyboardBuffer
), &UsbKey
);
1285 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, UsbKey
.KeyCode
);
1287 switch (KeyDescriptor
->Modifier
) {
1292 case EFI_LEFT_CONTROL_MODIFIER
:
1293 UsbKeyboardDevice
->LeftCtrlOn
= 0;
1294 UsbKeyboardDevice
->CtrlOn
= 0;
1296 case EFI_RIGHT_CONTROL_MODIFIER
:
1297 UsbKeyboardDevice
->RightCtrlOn
= 0;
1298 UsbKeyboardDevice
->CtrlOn
= 0;
1304 case EFI_LEFT_SHIFT_MODIFIER
:
1305 UsbKeyboardDevice
->LeftShiftOn
= 0;
1306 UsbKeyboardDevice
->ShiftOn
= 0;
1308 case EFI_RIGHT_SHIFT_MODIFIER
:
1309 UsbKeyboardDevice
->RightShiftOn
= 0;
1310 UsbKeyboardDevice
->ShiftOn
= 0;
1316 case EFI_LEFT_ALT_MODIFIER
:
1317 UsbKeyboardDevice
->LeftAltOn
= 0;
1318 UsbKeyboardDevice
->AltOn
= 0;
1320 case EFI_RIGHT_ALT_MODIFIER
:
1321 UsbKeyboardDevice
->RightAltOn
= 0;
1322 UsbKeyboardDevice
->AltOn
= 0;
1326 // Left Logo release
1328 case EFI_LEFT_LOGO_MODIFIER
:
1329 UsbKeyboardDevice
->LeftLogoOn
= 0;
1333 // Right Logo release
1335 case EFI_RIGHT_LOGO_MODIFIER
:
1336 UsbKeyboardDevice
->RightLogoOn
= 0;
1342 case EFI_MENU_MODIFIER
:
1343 UsbKeyboardDevice
->MenuKeyOn
= 0;
1349 case EFI_SYS_REQUEST_MODIFIER
:
1350 UsbKeyboardDevice
->SysReqOn
= 0;
1356 case EFI_ALT_GR_MODIFIER
:
1357 UsbKeyboardDevice
->AltGrOn
= 0;
1368 // Analyzes key pressing situation
1370 switch (KeyDescriptor
->Modifier
) {
1375 case EFI_LEFT_CONTROL_MODIFIER
:
1376 UsbKeyboardDevice
->LeftCtrlOn
= 1;
1377 UsbKeyboardDevice
->CtrlOn
= 1;
1380 case EFI_RIGHT_CONTROL_MODIFIER
:
1381 UsbKeyboardDevice
->RightCtrlOn
= 1;
1382 UsbKeyboardDevice
->CtrlOn
= 1;
1389 case EFI_LEFT_SHIFT_MODIFIER
:
1390 UsbKeyboardDevice
->LeftShiftOn
= 1;
1391 UsbKeyboardDevice
->ShiftOn
= 1;
1394 case EFI_RIGHT_SHIFT_MODIFIER
:
1395 UsbKeyboardDevice
->RightShiftOn
= 1;
1396 UsbKeyboardDevice
->ShiftOn
= 1;
1403 case EFI_LEFT_ALT_MODIFIER
:
1404 UsbKeyboardDevice
->LeftAltOn
= 1;
1405 UsbKeyboardDevice
->AltOn
= 1;
1408 case EFI_RIGHT_ALT_MODIFIER
:
1409 UsbKeyboardDevice
->RightAltOn
= 1;
1410 UsbKeyboardDevice
->AltOn
= 1;
1417 case EFI_LEFT_LOGO_MODIFIER
:
1418 UsbKeyboardDevice
->LeftLogoOn
= 1;
1424 case EFI_RIGHT_LOGO_MODIFIER
:
1425 UsbKeyboardDevice
->RightLogoOn
= 1;
1431 case EFI_MENU_MODIFIER
:
1432 UsbKeyboardDevice
->MenuKeyOn
= 1;
1438 case EFI_SYS_REQUEST_MODIFIER
:
1439 UsbKeyboardDevice
->SysReqOn
= 1;
1446 case EFI_ALT_GR_MODIFIER
:
1447 UsbKeyboardDevice
->AltGrOn
= 1;
1450 case EFI_NUM_LOCK_MODIFIER
:
1451 UsbKeyboardDevice
->NumLockOn
^= 1;
1453 // Turn on the NumLock light on KB
1455 SetKeyLED (UsbKeyboardDevice
);
1459 case EFI_CAPS_LOCK_MODIFIER
:
1460 UsbKeyboardDevice
->CapsOn
^= 1;
1462 // Turn on the CapsLock light on KB
1464 SetKeyLED (UsbKeyboardDevice
);
1468 case EFI_SCROLL_LOCK_MODIFIER
:
1469 UsbKeyboardDevice
->ScrollOn
^= 1;
1471 // Turn on the ScrollLock light on KB
1473 SetKeyLED (UsbKeyboardDevice
);
1478 // F11,F12,PrintScreen,Pause/Break
1479 // could not be retrieved via SimpleTxtInEx protocol
1481 case EFI_FUNCTION_KEY_ELEVEN_MODIFIER
:
1482 case EFI_FUNCTION_KEY_TWELVE_MODIFIER
:
1483 case EFI_PRINT_MODIFIER
:
1484 case EFI_PAUSE_MODIFIER
:
1485 case EFI_BREAK_MODIFIER
:
1497 // When encountered Del Key...
1499 if (KeyDescriptor
->Modifier
== EFI_DELETE_MODIFIER
) {
1500 if (UsbKeyboardDevice
->CtrlOn
&& UsbKeyboardDevice
->AltOn
) {
1501 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1505 *KeyChar
= UsbKey
.KeyCode
;
1509 return EFI_NOT_READY
;
1515 Converts USB Keyboard code to EFI Scan Code.
1517 UsbKeyboardDevice The USB_KB_DEV instance.
1518 KeyChar Indicates the key code that will be interpreted.
1519 Key A pointer to a buffer that is filled in with
1520 the keystroke information for the key that
1523 @retval EFI_NOT_READY Device is not ready
1524 @retval EFI_SUCCESS Success
1528 USBKeyCodeToEFIScanCode (
1529 IN USB_KB_DEV
*UsbKeyboardDevice
,
1531 OUT EFI_INPUT_KEY
*Key
1535 EFI_KEY_DESCRIPTOR
*KeyDescriptor
;
1537 if (!USBKBD_VALID_KEYCODE (KeyChar
)) {
1538 return EFI_NOT_READY
;
1542 // valid USB Key Code starts from 4
1544 Index
= (UINT8
) (KeyChar
- 4);
1546 if (Index
>= USB_KEYCODE_MAX_MAKE
) {
1547 return EFI_NOT_READY
;
1550 KeyDescriptor
= GetKeyDescriptor (UsbKeyboardDevice
, KeyChar
);
1553 // Check for Non-spacing key
1555 if (KeyDescriptor
->Modifier
== EFI_NS_KEY_MODIFIER
) {
1556 UsbKeyboardDevice
->CurrentNsKey
= FindUsbNsKey (UsbKeyboardDevice
, KeyDescriptor
);
1557 return EFI_NOT_READY
;
1561 // Check whether this keystroke follows a Non-spacing key
1563 if (UsbKeyboardDevice
->CurrentNsKey
!= NULL
) {
1564 KeyDescriptor
= FindPhysicalKey (UsbKeyboardDevice
->CurrentNsKey
, KeyDescriptor
);
1565 UsbKeyboardDevice
->CurrentNsKey
= NULL
;
1568 Key
->ScanCode
= EfiScanCodeConvertionTable
[KeyDescriptor
->Modifier
];
1569 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1571 if (KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_STANDARD_SHIFT
) {
1572 if (UsbKeyboardDevice
->ShiftOn
) {
1573 Key
->UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1576 // Need not return associated shift state if a class of printable characters that
1577 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1579 if (KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) {
1580 UsbKeyboardDevice
->LeftShiftOn
= 0;
1581 UsbKeyboardDevice
->RightShiftOn
= 0;
1584 if (UsbKeyboardDevice
->AltGrOn
) {
1585 Key
->UnicodeChar
= KeyDescriptor
->ShiftedAltGrUnicode
;
1591 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1593 if (UsbKeyboardDevice
->AltGrOn
) {
1594 Key
->UnicodeChar
= KeyDescriptor
->AltGrUnicode
;
1599 if (KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_CAPS_LOCK
) {
1600 if (UsbKeyboardDevice
->CapsOn
) {
1602 if (Key
->UnicodeChar
== KeyDescriptor
->Unicode
) {
1604 Key
->UnicodeChar
= KeyDescriptor
->ShiftedUnicode
;
1606 } else if (Key
->UnicodeChar
== KeyDescriptor
->ShiftedUnicode
) {
1608 Key
->UnicodeChar
= KeyDescriptor
->Unicode
;
1615 // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
1617 if (UsbKeyboardDevice
->CtrlOn
) {
1618 if (Key
->UnicodeChar
>= 'a' && Key
->UnicodeChar
<= 'z') {
1619 Key
->UnicodeChar
= (UINT8
) (Key
->UnicodeChar
- 'a' + 1);
1620 } else if (Key
->UnicodeChar
>= 'A' && Key
->UnicodeChar
<= 'Z') {
1621 Key
->UnicodeChar
= (UINT8
) (Key
->UnicodeChar
- 'A' + 1);
1625 if (KeyDescriptor
->AffectedAttribute
& EFI_AFFECTED_BY_NUM_LOCK
) {
1627 if (UsbKeyboardDevice
->NumLockOn
&& !UsbKeyboardDevice
->ShiftOn
) {
1629 Key
->ScanCode
= SCAN_NULL
;
1632 Key
->UnicodeChar
= 0x00;
1637 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1639 if (Key
->UnicodeChar
== 0x1B && Key
->ScanCode
== SCAN_NULL
) {
1640 Key
->ScanCode
= SCAN_ESC
;
1641 Key
->UnicodeChar
= 0x00;
1644 if (Key
->UnicodeChar
== 0 && Key
->ScanCode
== SCAN_NULL
) {
1645 return EFI_NOT_READY
;
1650 // Save Shift/Toggle state
1652 if (UsbKeyboardDevice
->LeftCtrlOn
== 1) {
1653 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
1655 if (UsbKeyboardDevice
->RightCtrlOn
== 1) {
1656 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
1658 if (UsbKeyboardDevice
->LeftAltOn
== 1) {
1659 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
1661 if (UsbKeyboardDevice
->RightAltOn
== 1) {
1662 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_ALT_PRESSED
;
1664 if (UsbKeyboardDevice
->LeftShiftOn
== 1) {
1665 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
1667 if (UsbKeyboardDevice
->RightShiftOn
== 1) {
1668 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
1670 if (UsbKeyboardDevice
->LeftLogoOn
== 1) {
1671 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
1673 if (UsbKeyboardDevice
->RightLogoOn
== 1) {
1674 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
1676 if (UsbKeyboardDevice
->MenuKeyOn
== 1) {
1677 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_MENU_KEY_PRESSED
;
1679 if (UsbKeyboardDevice
->SysReqOn
== 1) {
1680 UsbKeyboardDevice
->KeyState
.KeyShiftState
|= EFI_SYS_REQ_PRESSED
;
1683 if (UsbKeyboardDevice
->ScrollOn
== 1) {
1684 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_SCROLL_LOCK_ACTIVE
;
1686 if (UsbKeyboardDevice
->NumLockOn
== 1) {
1687 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_NUM_LOCK_ACTIVE
;
1689 if (UsbKeyboardDevice
->CapsOn
== 1) {
1690 UsbKeyboardDevice
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
1700 Resets USB Keyboard Buffer.
1702 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1704 @retval EFI_SUCCESS Success
1709 IN OUT USB_KB_BUFFER
*KeyboardBuffer
1712 ZeroMem (KeyboardBuffer
, sizeof (USB_KB_BUFFER
));
1714 KeyboardBuffer
->bHead
= KeyboardBuffer
->bTail
;
1721 Check whether USB Keyboard buffer is empty.
1723 @param KeyboardBuffer USB Keyboard Buffer.
1728 IsUSBKeyboardBufferEmpty (
1729 IN USB_KB_BUFFER
*KeyboardBuffer
1733 // meet FIFO empty condition
1735 return (BOOLEAN
) (KeyboardBuffer
->bHead
== KeyboardBuffer
->bTail
);
1741 Check whether USB Keyboard buffer is full.
1743 @param KeyboardBuffer USB Keyboard Buffer.
1748 IsUSBKeyboardBufferFull (
1749 IN USB_KB_BUFFER
*KeyboardBuffer
1752 return (BOOLEAN
)(((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1)) ==
1753 KeyboardBuffer
->bHead
);
1759 Inserts a key code into keyboard buffer.
1761 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1763 @param Down Special key
1765 @retval EFI_SUCCESS Success
1770 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1778 // if keyboard buffer is full, throw the
1779 // first key out of the keyboard buffer.
1781 if (IsUSBKeyboardBufferFull (KeyboardBuffer
)) {
1782 RemoveKeyCode (KeyboardBuffer
, &UsbKey
);
1785 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].KeyCode
= Key
;
1786 KeyboardBuffer
->buffer
[KeyboardBuffer
->bTail
].Down
= Down
;
1789 // adjust the tail pointer of the FIFO keyboard buffer.
1791 KeyboardBuffer
->bTail
= (UINT8
) ((KeyboardBuffer
->bTail
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1798 Pops a key code off from keyboard buffer.
1800 @param KeyboardBuffer Points to the USB Keyboard Buffer.
1801 @param UsbKey Points to the buffer that contains a usb key code.
1803 @retval EFI_SUCCESS Success
1804 @retval EFI_DEVICE_ERROR Hardware Error
1809 IN OUT USB_KB_BUFFER
*KeyboardBuffer
,
1813 if (IsUSBKeyboardBufferEmpty (KeyboardBuffer
)) {
1814 return EFI_DEVICE_ERROR
;
1817 UsbKey
->KeyCode
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].KeyCode
;
1818 UsbKey
->Down
= KeyboardBuffer
->buffer
[KeyboardBuffer
->bHead
].Down
;
1821 // adjust the head pointer of the FIFO keyboard buffer.
1823 KeyboardBuffer
->bHead
= (UINT8
) ((KeyboardBuffer
->bHead
+ 1) % (MAX_KEY_ALLOWED
+ 1));
1830 Sets USB Keyboard LED state.
1832 @param UsbKeyboardDevice The USB_KB_DEV instance.
1834 @retval EFI_SUCCESS Success
1839 IN USB_KB_DEV
*UsbKeyboardDevice
1846 // Set each field in Led map.
1848 Led
.NumLock
= (UINT8
) UsbKeyboardDevice
->NumLockOn
;
1849 Led
.CapsLock
= (UINT8
) UsbKeyboardDevice
->CapsOn
;
1850 Led
.ScrollLock
= (UINT8
) UsbKeyboardDevice
->ScrollOn
;
1855 // call Set Report Request to lighten the LED.
1857 UsbSetReportRequest (
1858 UsbKeyboardDevice
->UsbIo
,
1859 UsbKeyboardDevice
->InterfaceDescriptor
.InterfaceNumber
,
1871 Timer handler for Repeat Key timer.
1873 @param Event The Repeat Key event.
1874 @param Context Points to the USB_KB_DEV instance.
1880 USBKeyboardRepeatHandler (
1885 USB_KB_DEV
*UsbKeyboardDevice
;
1887 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1890 // Do nothing when there is no repeat key.
1892 if (UsbKeyboardDevice
->RepeatKey
!= 0) {
1894 // Inserts one Repeat key into keyboard buffer,
1897 &(UsbKeyboardDevice
->KeyboardBuffer
),
1898 UsbKeyboardDevice
->RepeatKey
,
1903 // set repeate rate for repeat key generation.
1906 UsbKeyboardDevice
->RepeatTimer
,
1916 Timer handler for Delayed Recovery timer.
1918 @param Event The Delayed Recovery event.
1919 @param Context Points to the USB_KB_DEV instance.
1925 USBKeyboardRecoveryHandler (
1931 USB_KB_DEV
*UsbKeyboardDevice
;
1932 EFI_USB_IO_PROTOCOL
*UsbIo
;
1935 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
1937 UsbIo
= UsbKeyboardDevice
->UsbIo
;
1939 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
1941 UsbIo
->UsbAsyncInterruptTransfer (
1943 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
1945 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,