]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
MdeModulePkg/UsbKb: ReadKeyStrokeEx always return key state
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbKbDxe / KeyBoard.c
1 /** @file
2 Helper functions for USB Keyboard Driver.
3
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "KeyBoard.h"
16
17 USB_KEYBOARD_LAYOUT_PACK_BIN mUsbKeyboardLayoutBin = {
18 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN), // Binary size
19
20 //
21 // EFI_HII_PACKAGE_HEADER
22 //
23 {
24 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32),
25 EFI_HII_PACKAGE_KEYBOARD_LAYOUT
26 },
27 1, // LayoutCount
28 sizeof (USB_KEYBOARD_LAYOUT_PACK_BIN) - sizeof (UINT32) - sizeof (EFI_HII_PACKAGE_HEADER) - sizeof (UINT16), // LayoutLength
29 USB_KEYBOARD_LAYOUT_KEY_GUID, // KeyGuid
30 sizeof (UINT16) + sizeof (EFI_GUID) + sizeof (UINT32) + sizeof (UINT8) + (USB_KEYBOARD_KEY_COUNT * sizeof (EFI_KEY_DESCRIPTOR)), // LayoutDescriptorStringOffset
31 USB_KEYBOARD_KEY_COUNT, // DescriptorCount
32 {
33 //
34 // EFI_KEY_DESCRIPTOR (total number is USB_KEYBOARD_KEY_COUNT)
35 //
36 {EfiKeyC1, 'a', 'A', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
37 {EfiKeyB5, 'b', 'B', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
38 {EfiKeyB3, 'c', 'C', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
39 {EfiKeyC3, 'd', 'D', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
40 {EfiKeyD3, 'e', 'E', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
41 {EfiKeyC4, 'f', 'F', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
42 {EfiKeyC5, 'g', 'G', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
43 {EfiKeyC6, 'h', 'H', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
44 {EfiKeyD8, 'i', 'I', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
45 {EfiKeyC7, 'j', 'J', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
46 {EfiKeyC8, 'k', 'K', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
47 {EfiKeyC9, 'l', 'L', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
48 {EfiKeyB7, 'm', 'M', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
49 {EfiKeyB6, 'n', 'N', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
50 {EfiKeyD9, 'o', 'O', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
51 {EfiKeyD10, 'p', 'P', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
52 {EfiKeyD1, 'q', 'Q', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
53 {EfiKeyD4, 'r', 'R', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
54 {EfiKeyC2, 's', 'S', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
55 {EfiKeyD5, 't', 'T', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
56 {EfiKeyD7, 'u', 'U', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
57 {EfiKeyB4, 'v', 'V', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
58 {EfiKeyD2, 'w', 'W', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
59 {EfiKeyB2, 'x', 'X', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
60 {EfiKeyD6, 'y', 'Y', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
61 {EfiKeyB1, 'z', 'Z', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_CAPS_LOCK},
62 {EfiKeyE1, '1', '!', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
63 {EfiKeyE2, '2', '@', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
64 {EfiKeyE3, '3', '#', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
65 {EfiKeyE4, '4', '$', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
66 {EfiKeyE5, '5', '%', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
67 {EfiKeyE6, '6', '^', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
68 {EfiKeyE7, '7', '&', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
69 {EfiKeyE8, '8', '*', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
70 {EfiKeyE9, '9', '(', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
71 {EfiKeyE10, '0', ')', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
72 {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0},
73 {EfiKeyEsc, 0x1b, 0x1b, 0, 0, EFI_NULL_MODIFIER, 0},
74 {EfiKeyBackSpace, 0x08, 0x08, 0, 0, EFI_NULL_MODIFIER, 0},
75 {EfiKeyTab, 0x09, 0x09, 0, 0, EFI_NULL_MODIFIER, 0},
76 {EfiKeySpaceBar, ' ', ' ', 0, 0, EFI_NULL_MODIFIER, 0},
77 {EfiKeyE11, '-', '_', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
78 {EfiKeyE12, '=', '+', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
79 {EfiKeyD11, '[', '{', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
80 {EfiKeyD12, ']', '}', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
81 {EfiKeyD13, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
82 {EfiKeyC12, '\\', '|', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
83 {EfiKeyC10, ';', ':', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
84 {EfiKeyC11, '\'', '"', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
85 {EfiKeyE0, '`', '~', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
86 {EfiKeyB8, ',', '<', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
87 {EfiKeyB9, '.', '>', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
88 {EfiKeyB10, '/', '?', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT},
89 {EfiKeyCapsLock, 0x00, 0x00, 0, 0, EFI_CAPS_LOCK_MODIFIER, 0},
90 {EfiKeyF1, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ONE_MODIFIER, 0},
91 {EfiKeyF2, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWO_MODIFIER, 0},
92 {EfiKeyF3, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_THREE_MODIFIER, 0},
93 {EfiKeyF4, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FOUR_MODIFIER, 0},
94 {EfiKeyF5, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_FIVE_MODIFIER, 0},
95 {EfiKeyF6, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SIX_MODIFIER, 0},
96 {EfiKeyF7, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_SEVEN_MODIFIER, 0},
97 {EfiKeyF8, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_EIGHT_MODIFIER, 0},
98 {EfiKeyF9, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_NINE_MODIFIER, 0},
99 {EfiKeyF10, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TEN_MODIFIER, 0},
100 {EfiKeyF11, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_ELEVEN_MODIFIER, 0},
101 {EfiKeyF12, 0x00, 0x00, 0, 0, EFI_FUNCTION_KEY_TWELVE_MODIFIER, 0},
102 {EfiKeyPrint, 0x00, 0x00, 0, 0, EFI_PRINT_MODIFIER, 0},
103 {EfiKeySLck, 0x00, 0x00, 0, 0, EFI_SCROLL_LOCK_MODIFIER, 0},
104 {EfiKeyPause, 0x00, 0x00, 0, 0, EFI_PAUSE_MODIFIER, 0},
105 {EfiKeyIns, 0x00, 0x00, 0, 0, EFI_INSERT_MODIFIER, 0},
106 {EfiKeyHome, 0x00, 0x00, 0, 0, EFI_HOME_MODIFIER, 0},
107 {EfiKeyPgUp, 0x00, 0x00, 0, 0, EFI_PAGE_UP_MODIFIER, 0},
108 {EfiKeyDel, 0x00, 0x00, 0, 0, EFI_DELETE_MODIFIER, 0},
109 {EfiKeyEnd, 0x00, 0x00, 0, 0, EFI_END_MODIFIER, 0},
110 {EfiKeyPgDn, 0x00, 0x00, 0, 0, EFI_PAGE_DOWN_MODIFIER, 0},
111 {EfiKeyRightArrow, 0x00, 0x00, 0, 0, EFI_RIGHT_ARROW_MODIFIER, 0},
112 {EfiKeyLeftArrow, 0x00, 0x00, 0, 0, EFI_LEFT_ARROW_MODIFIER, 0},
113 {EfiKeyDownArrow, 0x00, 0x00, 0, 0, EFI_DOWN_ARROW_MODIFIER, 0},
114 {EfiKeyUpArrow, 0x00, 0x00, 0, 0, EFI_UP_ARROW_MODIFIER, 0},
115 {EfiKeyNLck, 0x00, 0x00, 0, 0, EFI_NUM_LOCK_MODIFIER, 0},
116 {EfiKeySlash, '/', '/', 0, 0, EFI_NULL_MODIFIER, 0},
117 {EfiKeyAsterisk, '*', '*', 0, 0, EFI_NULL_MODIFIER, 0},
118 {EfiKeyMinus, '-', '-', 0, 0, EFI_NULL_MODIFIER, 0},
119 {EfiKeyPlus, '+', '+', 0, 0, EFI_NULL_MODIFIER, 0},
120 {EfiKeyEnter, 0x0d, 0x0d, 0, 0, EFI_NULL_MODIFIER, 0},
121 {EfiKeyOne, '1', '1', 0, 0, EFI_END_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
122 {EfiKeyTwo, '2', '2', 0, 0, EFI_DOWN_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
123 {EfiKeyThree, '3', '3', 0, 0, EFI_PAGE_DOWN_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
124 {EfiKeyFour, '4', '4', 0, 0, EFI_LEFT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
125 {EfiKeyFive, '5', '5', 0, 0, EFI_NULL_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
126 {EfiKeySix, '6', '6', 0, 0, EFI_RIGHT_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
127 {EfiKeySeven, '7', '7', 0, 0, EFI_HOME_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
128 {EfiKeyEight, '8', '8', 0, 0, EFI_UP_ARROW_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
129 {EfiKeyNine, '9', '9', 0, 0, EFI_PAGE_UP_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
130 {EfiKeyZero, '0', '0', 0, 0, EFI_INSERT_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
131 {EfiKeyPeriod, '.', '.', 0, 0, EFI_DELETE_MODIFIER, EFI_AFFECTED_BY_STANDARD_SHIFT | EFI_AFFECTED_BY_NUM_LOCK},
132 {EfiKeyA4, 0x00, 0x00, 0, 0, EFI_MENU_MODIFIER, 0},
133 {EfiKeyLCtrl, 0, 0, 0, 0, EFI_LEFT_CONTROL_MODIFIER, 0},
134 {EfiKeyLShift, 0, 0, 0, 0, EFI_LEFT_SHIFT_MODIFIER, 0},
135 {EfiKeyLAlt, 0, 0, 0, 0, EFI_LEFT_ALT_MODIFIER, 0},
136 {EfiKeyA0, 0, 0, 0, 0, EFI_LEFT_LOGO_MODIFIER, 0},
137 {EfiKeyRCtrl, 0, 0, 0, 0, EFI_RIGHT_CONTROL_MODIFIER, 0},
138 {EfiKeyRShift, 0, 0, 0, 0, EFI_RIGHT_SHIFT_MODIFIER, 0},
139 {EfiKeyA2, 0, 0, 0, 0, EFI_RIGHT_ALT_MODIFIER, 0},
140 {EfiKeyA3, 0, 0, 0, 0, EFI_RIGHT_LOGO_MODIFIER, 0},
141 },
142 1, // DescriptionCount
143 {'e', 'n', '-', 'U', 'S'}, // RFC4646 language code
144 ' ', // Space
145 {'E', 'n', 'g', 'l', 'i', 's', 'h', ' ', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd', '\0'}, // DescriptionString[]
146 };
147
148 //
149 // EFI_KEY to USB Keycode conversion table
150 // EFI_KEY is defined in UEFI spec.
151 // USB Keycode is defined in USB HID Firmware spec.
152 //
153 UINT8 EfiKeyToUsbKeyCodeConvertionTable[] = {
154 0xe0, // EfiKeyLCtrl
155 0xe3, // EfiKeyA0
156 0xe2, // EfiKeyLAlt
157 0x2c, // EfiKeySpaceBar
158 0xe6, // EfiKeyA2
159 0xe7, // EfiKeyA3
160 0x65, // EfiKeyA4
161 0xe4, // EfiKeyRCtrl
162 0x50, // EfiKeyLeftArrow
163 0x51, // EfiKeyDownArrow
164 0x4F, // EfiKeyRightArrow
165 0x62, // EfiKeyZero
166 0x63, // EfiKeyPeriod
167 0x28, // EfiKeyEnter
168 0xe1, // EfiKeyLShift
169 0x64, // EfiKeyB0
170 0x1D, // EfiKeyB1
171 0x1B, // EfiKeyB2
172 0x06, // EfiKeyB3
173 0x19, // EfiKeyB4
174 0x05, // EfiKeyB5
175 0x11, // EfiKeyB6
176 0x10, // EfiKeyB7
177 0x36, // EfiKeyB8
178 0x37, // EfiKeyB9
179 0x38, // EfiKeyB10
180 0xe5, // EfiKeyRShift
181 0x52, // EfiKeyUpArrow
182 0x59, // EfiKeyOne
183 0x5A, // EfiKeyTwo
184 0x5B, // EfiKeyThree
185 0x39, // EfiKeyCapsLock
186 0x04, // EfiKeyC1
187 0x16, // EfiKeyC2
188 0x07, // EfiKeyC3
189 0x09, // EfiKeyC4
190 0x0A, // EfiKeyC5
191 0x0B, // EfiKeyC6
192 0x0D, // EfiKeyC7
193 0x0E, // EfiKeyC8
194 0x0F, // EfiKeyC9
195 0x33, // EfiKeyC10
196 0x34, // EfiKeyC11
197 0x32, // EfiKeyC12
198 0x5C, // EfiKeyFour
199 0x5D, // EfiKeyFive
200 0x5E, // EfiKeySix
201 0x57, // EfiKeyPlus
202 0x2B, // EfiKeyTab
203 0x14, // EfiKeyD1
204 0x1A, // EfiKeyD2
205 0x08, // EfiKeyD3
206 0x15, // EfiKeyD4
207 0x17, // EfiKeyD5
208 0x1C, // EfiKeyD6
209 0x18, // EfiKeyD7
210 0x0C, // EfiKeyD8
211 0x12, // EfiKeyD9
212 0x13, // EfiKeyD10
213 0x2F, // EfiKeyD11
214 0x30, // EfiKeyD12
215 0x31, // EfiKeyD13
216 0x4C, // EfiKeyDel
217 0x4D, // EfiKeyEnd
218 0x4E, // EfiKeyPgDn
219 0x5F, // EfiKeySeven
220 0x60, // EfiKeyEight
221 0x61, // EfiKeyNine
222 0x35, // EfiKeyE0
223 0x1E, // EfiKeyE1
224 0x1F, // EfiKeyE2
225 0x20, // EfiKeyE3
226 0x21, // EfiKeyE4
227 0x22, // EfiKeyE5
228 0x23, // EfiKeyE6
229 0x24, // EfiKeyE7
230 0x25, // EfiKeyE8
231 0x26, // EfiKeyE9
232 0x27, // EfiKeyE10
233 0x2D, // EfiKeyE11
234 0x2E, // EfiKeyE12
235 0x2A, // EfiKeyBackSpace
236 0x49, // EfiKeyIns
237 0x4A, // EfiKeyHome
238 0x4B, // EfiKeyPgUp
239 0x53, // EfiKeyNLck
240 0x54, // EfiKeySlash
241 0x55, // EfiKeyAsterisk
242 0x56, // EfiKeyMinus
243 0x29, // EfiKeyEsc
244 0x3A, // EfiKeyF1
245 0x3B, // EfiKeyF2
246 0x3C, // EfiKeyF3
247 0x3D, // EfiKeyF4
248 0x3E, // EfiKeyF5
249 0x3F, // EfiKeyF6
250 0x40, // EfiKeyF7
251 0x41, // EfiKeyF8
252 0x42, // EfiKeyF9
253 0x43, // EfiKeyF10
254 0x44, // EfiKeyF11
255 0x45, // EfiKeyF12
256 0x46, // EfiKeyPrint
257 0x47, // EfiKeySLck
258 0x48 // EfiKeyPause
259 };
260
261 //
262 // Keyboard modifier value to EFI Scan Code convertion table
263 // EFI Scan Code and the modifier values are defined in UEFI spec.
264 //
265 UINT8 ModifierValueToEfiScanCodeConvertionTable[] = {
266 SCAN_NULL, // EFI_NULL_MODIFIER
267 SCAN_NULL, // EFI_LEFT_CONTROL_MODIFIER
268 SCAN_NULL, // EFI_RIGHT_CONTROL_MODIFIER
269 SCAN_NULL, // EFI_LEFT_ALT_MODIFIER
270 SCAN_NULL, // EFI_RIGHT_ALT_MODIFIER
271 SCAN_NULL, // EFI_ALT_GR_MODIFIER
272 SCAN_INSERT, // EFI_INSERT_MODIFIER
273 SCAN_DELETE, // EFI_DELETE_MODIFIER
274 SCAN_PAGE_DOWN, // EFI_PAGE_DOWN_MODIFIER
275 SCAN_PAGE_UP, // EFI_PAGE_UP_MODIFIER
276 SCAN_HOME, // EFI_HOME_MODIFIER
277 SCAN_END, // EFI_END_MODIFIER
278 SCAN_NULL, // EFI_LEFT_SHIFT_MODIFIER
279 SCAN_NULL, // EFI_RIGHT_SHIFT_MODIFIER
280 SCAN_NULL, // EFI_CAPS_LOCK_MODIFIER
281 SCAN_NULL, // EFI_NUM_LOCK_MODIFIER
282 SCAN_LEFT, // EFI_LEFT_ARROW_MODIFIER
283 SCAN_RIGHT, // EFI_RIGHT_ARROW_MODIFIER
284 SCAN_DOWN, // EFI_DOWN_ARROW_MODIFIER
285 SCAN_UP, // EFI_UP_ARROW_MODIFIER
286 SCAN_NULL, // EFI_NS_KEY_MODIFIER
287 SCAN_NULL, // EFI_NS_KEY_DEPENDENCY_MODIFIER
288 SCAN_F1, // EFI_FUNCTION_KEY_ONE_MODIFIER
289 SCAN_F2, // EFI_FUNCTION_KEY_TWO_MODIFIER
290 SCAN_F3, // EFI_FUNCTION_KEY_THREE_MODIFIER
291 SCAN_F4, // EFI_FUNCTION_KEY_FOUR_MODIFIER
292 SCAN_F5, // EFI_FUNCTION_KEY_FIVE_MODIFIER
293 SCAN_F6, // EFI_FUNCTION_KEY_SIX_MODIFIER
294 SCAN_F7, // EFI_FUNCTION_KEY_SEVEN_MODIFIER
295 SCAN_F8, // EFI_FUNCTION_KEY_EIGHT_MODIFIER
296 SCAN_F9, // EFI_FUNCTION_KEY_NINE_MODIFIER
297 SCAN_F10, // EFI_FUNCTION_KEY_TEN_MODIFIER
298 SCAN_F11, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER
299 SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER
300 //
301 // For Partial Keystroke support
302 //
303 SCAN_NULL, // EFI_PRINT_MODIFIER
304 SCAN_NULL, // EFI_SYS_REQUEST_MODIFIER
305 SCAN_NULL, // EFI_SCROLL_LOCK_MODIFIER
306 SCAN_PAUSE, // EFI_PAUSE_MODIFIER
307 SCAN_NULL, // EFI_BREAK_MODIFIER
308 SCAN_NULL, // EFI_LEFT_LOGO_MODIFIER
309 SCAN_NULL, // EFI_RIGHT_LOGO_MODIFER
310 SCAN_NULL, // EFI_MENU_MODIFER
311 };
312
313 /**
314 Initialize Key Convention Table by using default keyboard layout.
315
316 @param UsbKeyboardDevice The USB_KB_DEV instance.
317
318 @retval EFI_SUCCESS The default keyboard layout was installed successfully
319 @retval Others Failure to install default keyboard layout.
320 **/
321 EFI_STATUS
322 InstallDefaultKeyboardLayout (
323 IN OUT USB_KB_DEV *UsbKeyboardDevice
324 )
325 {
326 EFI_STATUS Status;
327 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
328 EFI_HII_HANDLE HiiHandle;
329
330 //
331 // Locate Hii database protocol
332 //
333 Status = gBS->LocateProtocol (
334 &gEfiHiiDatabaseProtocolGuid,
335 NULL,
336 (VOID **) &HiiDatabase
337 );
338 if (EFI_ERROR (Status)) {
339 return Status;
340 }
341
342 //
343 // Install Keyboard Layout package to HII database
344 //
345 HiiHandle = HiiAddPackages (
346 &gUsbKeyboardLayoutPackageGuid,
347 UsbKeyboardDevice->ControllerHandle,
348 &mUsbKeyboardLayoutBin,
349 NULL
350 );
351 if (HiiHandle == NULL) {
352 return EFI_OUT_OF_RESOURCES;
353 }
354
355 //
356 // Set current keyboard layout
357 //
358 Status = HiiDatabase->SetKeyboardLayout (HiiDatabase, &gUsbKeyboardLayoutKeyGuid);
359
360 return Status;
361 }
362
363
364 /**
365 Uses USB I/O to check whether the device is a USB keyboard device.
366
367 @param UsbIo Pointer to a USB I/O protocol instance.
368
369 @retval TRUE Device is a USB keyboard device.
370 @retval FALSE Device is a not USB keyboard device.
371
372 **/
373 BOOLEAN
374 IsUSBKeyboard (
375 IN EFI_USB_IO_PROTOCOL *UsbIo
376 )
377 {
378 EFI_STATUS Status;
379 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
380
381 //
382 // Get the default interface descriptor
383 //
384 Status = UsbIo->UsbGetInterfaceDescriptor (
385 UsbIo,
386 &InterfaceDescriptor
387 );
388
389 if (EFI_ERROR (Status)) {
390 return FALSE;
391 }
392
393 if (InterfaceDescriptor.InterfaceClass == CLASS_HID &&
394 InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT &&
395 InterfaceDescriptor.InterfaceProtocol == PROTOCOL_KEYBOARD
396 ) {
397 return TRUE;
398 }
399
400 return FALSE;
401 }
402
403 /**
404 Get current keyboard layout from HII database.
405
406 @return Pointer to HII Keyboard Layout.
407 NULL means failure occurred while trying to get keyboard layout.
408
409 **/
410 EFI_HII_KEYBOARD_LAYOUT *
411 GetCurrentKeyboardLayout (
412 VOID
413 )
414 {
415 EFI_STATUS Status;
416 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
417 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
418 UINT16 Length;
419
420 //
421 // Locate HII Database Protocol
422 //
423 Status = gBS->LocateProtocol (
424 &gEfiHiiDatabaseProtocolGuid,
425 NULL,
426 (VOID **) &HiiDatabase
427 );
428 if (EFI_ERROR (Status)) {
429 return NULL;
430 }
431
432 //
433 // Get current keyboard layout from HII database
434 //
435 Length = 0;
436 KeyboardLayout = NULL;
437 Status = HiiDatabase->GetKeyboardLayout (
438 HiiDatabase,
439 NULL,
440 &Length,
441 KeyboardLayout
442 );
443 if (Status == EFI_BUFFER_TOO_SMALL) {
444 KeyboardLayout = AllocatePool (Length);
445 ASSERT (KeyboardLayout != NULL);
446
447 Status = HiiDatabase->GetKeyboardLayout (
448 HiiDatabase,
449 NULL,
450 &Length,
451 KeyboardLayout
452 );
453 if (EFI_ERROR (Status)) {
454 FreePool (KeyboardLayout);
455 KeyboardLayout = NULL;
456 }
457 }
458
459 return KeyboardLayout;
460 }
461
462 /**
463 Find Key Descriptor in Key Convertion Table given its USB keycode.
464
465 @param UsbKeyboardDevice The USB_KB_DEV instance.
466 @param KeyCode USB Keycode.
467
468 @return The Key Descriptor in Key Convertion Table.
469 NULL means not found.
470
471 **/
472 EFI_KEY_DESCRIPTOR *
473 GetKeyDescriptor (
474 IN USB_KB_DEV *UsbKeyboardDevice,
475 IN UINT8 KeyCode
476 )
477 {
478 UINT8 Index;
479
480 //
481 // Make sure KeyCode is in the range of [0x4, 0x65] or [0xe0, 0xe7]
482 //
483 if ((!USBKBD_VALID_KEYCODE (KeyCode)) || ((KeyCode > 0x65) && (KeyCode < 0xe0)) || (KeyCode > 0xe7)) {
484 return NULL;
485 }
486
487 //
488 // Calculate the index of Key Descriptor in Key Convertion Table
489 //
490 if (KeyCode <= 0x65) {
491 Index = (UINT8) (KeyCode - 4);
492 } else {
493 Index = (UINT8) (KeyCode - 0xe0 + NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE);
494 }
495
496 return &UsbKeyboardDevice->KeyConvertionTable[Index];
497 }
498
499 /**
500 Find Non-Spacing key for given Key descriptor.
501
502 @param UsbKeyboardDevice The USB_KB_DEV instance.
503 @param KeyDescriptor Key descriptor.
504
505 @return The Non-Spacing key corresponding to KeyDescriptor
506 NULL means not found.
507
508 **/
509 USB_NS_KEY *
510 FindUsbNsKey (
511 IN USB_KB_DEV *UsbKeyboardDevice,
512 IN EFI_KEY_DESCRIPTOR *KeyDescriptor
513 )
514 {
515 LIST_ENTRY *Link;
516 LIST_ENTRY *NsKeyList;
517 USB_NS_KEY *UsbNsKey;
518
519 NsKeyList = &UsbKeyboardDevice->NsKeyList;
520 Link = GetFirstNode (NsKeyList);
521 while (!IsNull (NsKeyList, Link)) {
522 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);
523
524 if (UsbNsKey->NsKey[0].Key == KeyDescriptor->Key) {
525 return UsbNsKey;
526 }
527
528 Link = GetNextNode (NsKeyList, Link);
529 }
530
531 return NULL;
532 }
533
534 /**
535 Find physical key definition for a given key descriptor.
536
537 For a specified non-spacing key, there are a list of physical
538 keys following it. This function traverses the list of
539 physical keys and tries to find the physical key matching
540 the KeyDescriptor.
541
542 @param UsbNsKey The non-spacing key information.
543 @param KeyDescriptor The key descriptor.
544
545 @return The physical key definition.
546 If no physical key is found, parameter KeyDescriptor is returned.
547
548 **/
549 EFI_KEY_DESCRIPTOR *
550 FindPhysicalKey (
551 IN USB_NS_KEY *UsbNsKey,
552 IN EFI_KEY_DESCRIPTOR *KeyDescriptor
553 )
554 {
555 UINTN Index;
556 EFI_KEY_DESCRIPTOR *PhysicalKey;
557
558 PhysicalKey = &UsbNsKey->NsKey[1];
559 for (Index = 0; Index < UsbNsKey->KeyCount; Index++) {
560 if (KeyDescriptor->Key == PhysicalKey->Key) {
561 return PhysicalKey;
562 }
563
564 PhysicalKey++;
565 }
566
567 //
568 // No children definition matched, return original key
569 //
570 return KeyDescriptor;
571 }
572
573 /**
574 The notification function for EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID.
575
576 This function is registered to event of EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
577 group type, which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
578 It tries to get curent keyboard layout from HII database.
579
580 @param Event Event being signaled.
581 @param Context Points to USB_KB_DEV instance.
582
583 **/
584 VOID
585 EFIAPI
586 SetKeyboardLayoutEvent (
587 IN EFI_EVENT Event,
588 IN VOID *Context
589 )
590 {
591 USB_KB_DEV *UsbKeyboardDevice;
592 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
593 EFI_KEY_DESCRIPTOR TempKey;
594 EFI_KEY_DESCRIPTOR *KeyDescriptor;
595 EFI_KEY_DESCRIPTOR *TableEntry;
596 EFI_KEY_DESCRIPTOR *NsKey;
597 USB_NS_KEY *UsbNsKey;
598 UINTN Index;
599 UINTN Index2;
600 UINTN KeyCount;
601 UINT8 KeyCode;
602
603 UsbKeyboardDevice = (USB_KB_DEV *) Context;
604 if (UsbKeyboardDevice->Signature != USB_KB_DEV_SIGNATURE) {
605 return;
606 }
607
608 //
609 // Try to get current keyboard layout from HII database
610 //
611 KeyboardLayout = GetCurrentKeyboardLayout ();
612 if (KeyboardLayout == NULL) {
613 return;
614 }
615
616 //
617 // Re-allocate resource for KeyConvertionTable
618 //
619 ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
620 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));
621 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
622
623 //
624 // Traverse the list of key descriptors following the header of EFI_HII_KEYBOARD_LAYOUT
625 //
626 KeyDescriptor = (EFI_KEY_DESCRIPTOR *) (((UINT8 *) KeyboardLayout) + sizeof (EFI_HII_KEYBOARD_LAYOUT));
627 for (Index = 0; Index < KeyboardLayout->DescriptorCount; Index++) {
628 //
629 // Copy from HII keyboard layout package binary for alignment
630 //
631 CopyMem (&TempKey, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
632
633 //
634 // Fill the key into KeyConvertionTable, whose index is calculated from USB keycode.
635 //
636 KeyCode = EfiKeyToUsbKeyCodeConvertionTable [(UINT8) (TempKey.Key)];
637 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);
638 if (TableEntry == NULL) {
639 ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
640 FreePool (KeyboardLayout);
641 return;
642 }
643 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
644
645 //
646 // For non-spacing key, create the list with a non-spacing key followed by physical keys.
647 //
648 if (TempKey.Modifier == EFI_NS_KEY_MODIFIER) {
649 UsbNsKey = AllocateZeroPool (sizeof (USB_NS_KEY));
650 ASSERT (UsbNsKey != NULL);
651
652 //
653 // Search for sequential children physical key definitions
654 //
655 KeyCount = 0;
656 NsKey = KeyDescriptor + 1;
657 for (Index2 = (UINT8) Index + 1; Index2 < KeyboardLayout->DescriptorCount; Index2++) {
658 CopyMem (&TempKey, NsKey, sizeof (EFI_KEY_DESCRIPTOR));
659 if (TempKey.Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER) {
660 KeyCount++;
661 } else {
662 break;
663 }
664 NsKey++;
665 }
666
667 UsbNsKey->Signature = USB_NS_KEY_SIGNATURE;
668 UsbNsKey->KeyCount = KeyCount;
669 UsbNsKey->NsKey = AllocateCopyPool (
670 (KeyCount + 1) * sizeof (EFI_KEY_DESCRIPTOR),
671 KeyDescriptor
672 );
673 InsertTailList (&UsbKeyboardDevice->NsKeyList, &UsbNsKey->Link);
674
675 //
676 // Skip over the child physical keys
677 //
678 Index += KeyCount;
679 KeyDescriptor += KeyCount;
680 }
681
682 KeyDescriptor++;
683 }
684
685 //
686 // There are two EfiKeyEnter, duplicate its key descriptor
687 //
688 TableEntry = GetKeyDescriptor (UsbKeyboardDevice, 0x58);
689 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, 0x28);
690 CopyMem (TableEntry, KeyDescriptor, sizeof (EFI_KEY_DESCRIPTOR));
691
692 FreePool (KeyboardLayout);
693 }
694
695 /**
696 Destroy resources for keyboard layout.
697
698 @param UsbKeyboardDevice The USB_KB_DEV instance.
699
700 **/
701 VOID
702 ReleaseKeyboardLayoutResources (
703 IN OUT USB_KB_DEV *UsbKeyboardDevice
704 )
705 {
706 USB_NS_KEY *UsbNsKey;
707 LIST_ENTRY *Link;
708
709 if (UsbKeyboardDevice->KeyConvertionTable != NULL) {
710 FreePool (UsbKeyboardDevice->KeyConvertionTable);
711 }
712 UsbKeyboardDevice->KeyConvertionTable = NULL;
713
714 while (!IsListEmpty (&UsbKeyboardDevice->NsKeyList)) {
715 Link = GetFirstNode (&UsbKeyboardDevice->NsKeyList);
716 UsbNsKey = USB_NS_KEY_FORM_FROM_LINK (Link);
717 RemoveEntryList (&UsbNsKey->Link);
718
719 FreePool (UsbNsKey->NsKey);
720 FreePool (UsbNsKey);
721 }
722 }
723
724 /**
725 Initialize USB keyboard layout.
726
727 This function initializes Key Convertion Table for the USB keyboard device.
728 It first tries to retrieve layout from HII database. If failed and default
729 layout is enabled, then it just uses the default layout.
730
731 @param UsbKeyboardDevice The USB_KB_DEV instance.
732
733 @retval EFI_SUCCESS Initialization succeeded.
734 @retval EFI_NOT_READY Keyboard layout cannot be retrieve from HII
735 database, and default layout is disabled.
736 @retval Other Fail to register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group.
737
738 **/
739 EFI_STATUS
740 InitKeyboardLayout (
741 OUT USB_KB_DEV *UsbKeyboardDevice
742 )
743 {
744 EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout;
745 EFI_STATUS Status;
746
747 UsbKeyboardDevice->KeyConvertionTable = AllocateZeroPool ((NUMBER_OF_VALID_USB_KEYCODE) * sizeof (EFI_KEY_DESCRIPTOR));
748 ASSERT (UsbKeyboardDevice->KeyConvertionTable != NULL);
749
750 InitializeListHead (&UsbKeyboardDevice->NsKeyList);
751 UsbKeyboardDevice->CurrentNsKey = NULL;
752 UsbKeyboardDevice->KeyboardLayoutEvent = NULL;
753
754 //
755 // Register event to EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group,
756 // which will be triggered by EFI_HII_DATABASE_PROTOCOL.SetKeyboardLayout().
757 //
758 Status = gBS->CreateEventEx (
759 EVT_NOTIFY_SIGNAL,
760 TPL_NOTIFY,
761 SetKeyboardLayoutEvent,
762 UsbKeyboardDevice,
763 &gEfiHiiKeyBoardLayoutGuid,
764 &UsbKeyboardDevice->KeyboardLayoutEvent
765 );
766 if (EFI_ERROR (Status)) {
767 return Status;
768 }
769
770 KeyboardLayout = GetCurrentKeyboardLayout ();
771 if (KeyboardLayout != NULL) {
772 //
773 // If current keyboard layout is successfully retrieved from HII database,
774 // force to initialize the keyboard layout.
775 //
776 gBS->SignalEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
777 } else {
778 if (FeaturePcdGet (PcdDisableDefaultKeyboardLayoutInUsbKbDriver)) {
779 //
780 // If no keyboard layout can be retrieved from HII database, and default layout
781 // is disabled, then return EFI_NOT_READY.
782 //
783 return EFI_NOT_READY;
784 }
785 //
786 // If no keyboard layout can be retrieved from HII database, and default layout
787 // is enabled, then load the default keyboard layout.
788 //
789 InstallDefaultKeyboardLayout (UsbKeyboardDevice);
790 }
791
792 return EFI_SUCCESS;
793 }
794
795
796 /**
797 Initialize USB keyboard device and all private data structures.
798
799 @param UsbKeyboardDevice The USB_KB_DEV instance.
800
801 @retval EFI_SUCCESS Initialization is successful.
802 @retval EFI_DEVICE_ERROR Keyboard initialization failed.
803
804 **/
805 EFI_STATUS
806 InitUSBKeyboard (
807 IN OUT USB_KB_DEV *UsbKeyboardDevice
808 )
809 {
810 UINT16 ConfigValue;
811 UINT8 Protocol;
812 EFI_STATUS Status;
813 UINT32 TransferResult;
814
815 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
816 EFI_PROGRESS_CODE,
817 (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST),
818 UsbKeyboardDevice->DevicePath
819 );
820
821 InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));
822 InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));
823 InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA));
824
825 //
826 // Use the config out of the descriptor
827 // Assumed the first config is the correct one and this is not always the case
828 //
829 Status = UsbGetConfiguration (
830 UsbKeyboardDevice->UsbIo,
831 &ConfigValue,
832 &TransferResult
833 );
834 if (EFI_ERROR (Status)) {
835 ConfigValue = 0x01;
836 //
837 // Uses default configuration to configure the USB Keyboard device.
838 //
839 Status = UsbSetConfiguration (
840 UsbKeyboardDevice->UsbIo,
841 ConfigValue,
842 &TransferResult
843 );
844 if (EFI_ERROR (Status)) {
845 //
846 // If configuration could not be set here, it means
847 // the keyboard interface has some errors and could
848 // not be initialized
849 //
850 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
851 EFI_ERROR_CODE | EFI_ERROR_MINOR,
852 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INTERFACE_ERROR),
853 UsbKeyboardDevice->DevicePath
854 );
855
856 return EFI_DEVICE_ERROR;
857 }
858 }
859
860 UsbGetProtocolRequest (
861 UsbKeyboardDevice->UsbIo,
862 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
863 &Protocol
864 );
865 //
866 // Set boot protocol for the USB Keyboard.
867 // This driver only supports boot protocol.
868 //
869 if (Protocol != BOOT_PROTOCOL) {
870 UsbSetProtocolRequest (
871 UsbKeyboardDevice->UsbIo,
872 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
873 BOOT_PROTOCOL
874 );
875 }
876
877 UsbKeyboardDevice->CtrlOn = FALSE;
878 UsbKeyboardDevice->AltOn = FALSE;
879 UsbKeyboardDevice->ShiftOn = FALSE;
880 UsbKeyboardDevice->NumLockOn = FALSE;
881 UsbKeyboardDevice->CapsOn = FALSE;
882 UsbKeyboardDevice->ScrollOn = FALSE;
883
884 UsbKeyboardDevice->LeftCtrlOn = FALSE;
885 UsbKeyboardDevice->LeftAltOn = FALSE;
886 UsbKeyboardDevice->LeftShiftOn = FALSE;
887 UsbKeyboardDevice->LeftLogoOn = FALSE;
888 UsbKeyboardDevice->RightCtrlOn = FALSE;
889 UsbKeyboardDevice->RightAltOn = FALSE;
890 UsbKeyboardDevice->RightShiftOn = FALSE;
891 UsbKeyboardDevice->RightLogoOn = FALSE;
892 UsbKeyboardDevice->MenuKeyOn = FALSE;
893 UsbKeyboardDevice->SysReqOn = FALSE;
894
895 UsbKeyboardDevice->AltGrOn = FALSE;
896
897 UsbKeyboardDevice->CurrentNsKey = NULL;
898
899 //
900 // Sync the initial state of lights on keyboard.
901 //
902 SetKeyLED (UsbKeyboardDevice);
903
904 ZeroMem (UsbKeyboardDevice->LastKeyCodeArray, sizeof (UINT8) * 8);
905
906 //
907 // Create event for repeat keys' generation.
908 //
909 if (UsbKeyboardDevice->RepeatTimer != NULL) {
910 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
911 UsbKeyboardDevice->RepeatTimer = NULL;
912 }
913
914 gBS->CreateEvent (
915 EVT_TIMER | EVT_NOTIFY_SIGNAL,
916 TPL_CALLBACK,
917 USBKeyboardRepeatHandler,
918 UsbKeyboardDevice,
919 &UsbKeyboardDevice->RepeatTimer
920 );
921
922 //
923 // Create event for delayed recovery, which deals with device error.
924 //
925 if (UsbKeyboardDevice->DelayedRecoveryEvent != NULL) {
926 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
927 UsbKeyboardDevice->DelayedRecoveryEvent = NULL;
928 }
929
930 gBS->CreateEvent (
931 EVT_TIMER | EVT_NOTIFY_SIGNAL,
932 TPL_NOTIFY,
933 USBKeyboardRecoveryHandler,
934 UsbKeyboardDevice,
935 &UsbKeyboardDevice->DelayedRecoveryEvent
936 );
937
938 return EFI_SUCCESS;
939 }
940
941
942 /**
943 Handler function for USB keyboard's asynchronous interrupt transfer.
944
945 This function is the handler function for USB keyboard's asynchronous interrupt transfer
946 to manage the keyboard. It parses the USB keyboard input report, and inserts data to
947 keyboard buffer according to state of modifer keys and normal keys. Timer for repeat key
948 is also set accordingly.
949
950 @param Data A pointer to a buffer that is filled with key data which is
951 retrieved via asynchronous interrupt transfer.
952 @param DataLength Indicates the size of the data buffer.
953 @param Context Pointing to USB_KB_DEV instance.
954 @param Result Indicates the result of the asynchronous interrupt transfer.
955
956 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
957 @retval EFI_DEVICE_ERROR Hardware error occurs.
958
959 **/
960 EFI_STATUS
961 EFIAPI
962 KeyboardHandler (
963 IN VOID *Data,
964 IN UINTN DataLength,
965 IN VOID *Context,
966 IN UINT32 Result
967 )
968 {
969 USB_KB_DEV *UsbKeyboardDevice;
970 EFI_USB_IO_PROTOCOL *UsbIo;
971 UINT8 *CurKeyCodeBuffer;
972 UINT8 *OldKeyCodeBuffer;
973 UINT8 CurModifierMap;
974 UINT8 OldModifierMap;
975 UINT8 Mask;
976 UINTN Index;
977 UINT8 Index2;
978 BOOLEAN KeyRelease;
979 BOOLEAN KeyPress;
980 USB_KEY UsbKey;
981 UINT8 NewRepeatKey;
982 UINT32 UsbStatus;
983 EFI_KEY_DESCRIPTOR *KeyDescriptor;
984
985 ASSERT (Context != NULL);
986
987 NewRepeatKey = 0;
988 UsbKeyboardDevice = (USB_KB_DEV *) Context;
989 UsbIo = UsbKeyboardDevice->UsbIo;
990
991 //
992 // Analyzes Result and performs corresponding action.
993 //
994 if (Result != EFI_USB_NOERROR) {
995 //
996 // Some errors happen during the process
997 //
998 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
999 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1000 (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_INPUT_ERROR),
1001 UsbKeyboardDevice->DevicePath
1002 );
1003
1004 //
1005 // Stop the repeat key generation if any
1006 //
1007 UsbKeyboardDevice->RepeatKey = 0;
1008
1009 gBS->SetTimer (
1010 UsbKeyboardDevice->RepeatTimer,
1011 TimerCancel,
1012 USBKBD_REPEAT_RATE
1013 );
1014
1015 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
1016 UsbClearEndpointHalt (
1017 UsbIo,
1018 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1019 &UsbStatus
1020 );
1021 }
1022
1023 //
1024 // Delete & Submit this interrupt again
1025 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
1026 //
1027 UsbIo->UsbAsyncInterruptTransfer (
1028 UsbIo,
1029 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1030 FALSE,
1031 0,
1032 0,
1033 NULL,
1034 NULL
1035 );
1036 //
1037 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
1038 //
1039 gBS->SetTimer (
1040 UsbKeyboardDevice->DelayedRecoveryEvent,
1041 TimerRelative,
1042 EFI_USB_INTERRUPT_DELAY
1043 );
1044
1045 return EFI_DEVICE_ERROR;
1046 }
1047
1048 //
1049 // If no error and no data, just return EFI_SUCCESS.
1050 //
1051 if (DataLength == 0 || Data == NULL) {
1052 return EFI_SUCCESS;
1053 }
1054
1055 //
1056 // Following code checks current keyboard input report against old key code buffer.
1057 // According to USB HID Firmware Specification, the report consists of 8 bytes.
1058 // Byte 0 is map of Modifier keys.
1059 // Byte 1 is reserved.
1060 // Bytes 2 to 7 are keycodes.
1061 //
1062 CurKeyCodeBuffer = (UINT8 *) Data;
1063 OldKeyCodeBuffer = UsbKeyboardDevice->LastKeyCodeArray;
1064
1065 //
1066 // Checks for new key stroke.
1067 //
1068 for (Index = 0; Index < 8; Index++) {
1069 if (OldKeyCodeBuffer[Index] != CurKeyCodeBuffer[Index]) {
1070 break;
1071 }
1072 }
1073
1074 //
1075 // If no new key, return EFI_SUCCESS immediately.
1076 //
1077 if (Index == 8) {
1078 return EFI_SUCCESS;
1079 }
1080
1081 //
1082 // Parse the modifier key, which is the first byte of keyboard input report.
1083 //
1084 CurModifierMap = CurKeyCodeBuffer[0];
1085 OldModifierMap = OldKeyCodeBuffer[0];
1086
1087 //
1088 // Handle modifier key's pressing or releasing situation.
1089 // According to USB HID Firmware spec, Byte 0 uses folloing map of Modifier keys:
1090 // Bit0: Left Control, Keycode: 0xe0
1091 // Bit1: Left Shift, Keycode: 0xe1
1092 // Bit2: Left Alt, Keycode: 0xe2
1093 // Bit3: Left GUI, Keycode: 0xe3
1094 // Bit4: Right Control, Keycode: 0xe4
1095 // Bit5: Right Shift, Keycode: 0xe5
1096 // Bit6: Right Alt, Keycode: 0xe6
1097 // Bit7: Right GUI, Keycode: 0xe7
1098 //
1099 for (Index = 0; Index < 8; Index++) {
1100 Mask = (UINT8) (1 << Index);
1101 if ((CurModifierMap & Mask) != (OldModifierMap & Mask)) {
1102 //
1103 // If current modifier key is up, then CurModifierMap & Mask = 0;
1104 // otherwise it is a non-zero value.
1105 // Insert the changed modifier key into key buffer.
1106 //
1107 UsbKey.KeyCode = (UINT8) (0xe0 + Index);
1108 UsbKey.Down = (BOOLEAN) ((CurModifierMap & Mask) != 0);
1109 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1110 }
1111 }
1112
1113 //
1114 // Handle normal key's releasing situation
1115 // Bytes 2 to 7 are for normal keycodes
1116 //
1117 KeyRelease = FALSE;
1118 for (Index = 2; Index < 8; Index++) {
1119
1120 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index])) {
1121 continue;
1122 }
1123 //
1124 // For any key in old keycode buffer, if it is not in current keycode buffer,
1125 // then it is released. Otherwise, it is not released.
1126 //
1127 KeyRelease = TRUE;
1128 for (Index2 = 2; Index2 < 8; Index2++) {
1129
1130 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index2])) {
1131 continue;
1132 }
1133
1134 if (OldKeyCodeBuffer[Index] == CurKeyCodeBuffer[Index2]) {
1135 KeyRelease = FALSE;
1136 break;
1137 }
1138 }
1139
1140 if (KeyRelease) {
1141 UsbKey.KeyCode = OldKeyCodeBuffer[Index];
1142 UsbKey.Down = FALSE;
1143 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1144 //
1145 // The original repeat key is released.
1146 //
1147 if (OldKeyCodeBuffer[Index] == UsbKeyboardDevice->RepeatKey) {
1148 UsbKeyboardDevice->RepeatKey = 0;
1149 }
1150 }
1151 }
1152
1153 //
1154 // If original repeat key is released, cancel the repeat timer
1155 //
1156 if (UsbKeyboardDevice->RepeatKey == 0) {
1157 gBS->SetTimer (
1158 UsbKeyboardDevice->RepeatTimer,
1159 TimerCancel,
1160 USBKBD_REPEAT_RATE
1161 );
1162 }
1163
1164 //
1165 // Handle normal key's pressing situation
1166 //
1167 KeyPress = FALSE;
1168 for (Index = 2; Index < 8; Index++) {
1169
1170 if (!USBKBD_VALID_KEYCODE (CurKeyCodeBuffer[Index])) {
1171 continue;
1172 }
1173 //
1174 // For any key in current keycode buffer, if it is not in old keycode buffer,
1175 // then it is pressed. Otherwise, it is not pressed.
1176 //
1177 KeyPress = TRUE;
1178 for (Index2 = 2; Index2 < 8; Index2++) {
1179
1180 if (!USBKBD_VALID_KEYCODE (OldKeyCodeBuffer[Index2])) {
1181 continue;
1182 }
1183
1184 if (CurKeyCodeBuffer[Index] == OldKeyCodeBuffer[Index2]) {
1185 KeyPress = FALSE;
1186 break;
1187 }
1188 }
1189
1190 if (KeyPress) {
1191 UsbKey.KeyCode = CurKeyCodeBuffer[Index];
1192 UsbKey.Down = TRUE;
1193 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1194
1195 //
1196 // Handle repeat key
1197 //
1198 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, CurKeyCodeBuffer[Index]);
1199 if (KeyDescriptor == NULL) {
1200 continue;
1201 }
1202
1203 if (KeyDescriptor->Modifier == EFI_NUM_LOCK_MODIFIER || KeyDescriptor->Modifier == EFI_CAPS_LOCK_MODIFIER) {
1204 //
1205 // For NumLock or CapsLock pressed, there is no need to handle repeat key for them.
1206 //
1207 UsbKeyboardDevice->RepeatKey = 0;
1208 } else {
1209 //
1210 // Prepare new repeat key, and clear the original one.
1211 //
1212 NewRepeatKey = CurKeyCodeBuffer[Index];
1213 UsbKeyboardDevice->RepeatKey = 0;
1214 }
1215 }
1216 }
1217
1218 //
1219 // Update LastKeycodeArray buffer in the UsbKeyboardDevice data structure.
1220 //
1221 for (Index = 0; Index < 8; Index++) {
1222 UsbKeyboardDevice->LastKeyCodeArray[Index] = CurKeyCodeBuffer[Index];
1223 }
1224
1225 //
1226 // If there is new key pressed, update the RepeatKey value, and set the
1227 // timer to repeate delay timer
1228 //
1229 if (NewRepeatKey != 0) {
1230 //
1231 // Sets trigger time to "Repeat Delay Time",
1232 // to trigger the repeat timer when the key is hold long
1233 // enough time.
1234 //
1235 gBS->SetTimer (
1236 UsbKeyboardDevice->RepeatTimer,
1237 TimerRelative,
1238 USBKBD_REPEAT_DELAY
1239 );
1240 UsbKeyboardDevice->RepeatKey = NewRepeatKey;
1241 }
1242
1243 return EFI_SUCCESS;
1244 }
1245
1246
1247 /**
1248 Retrieves a USB keycode after parsing the raw data in keyboard buffer.
1249
1250 This function parses keyboard buffer. It updates state of modifier key for
1251 USB_KB_DEV instancem, and returns keycode for output.
1252
1253 @param UsbKeyboardDevice The USB_KB_DEV instance.
1254 @param KeyCode Pointer to the USB keycode for output.
1255
1256 @retval EFI_SUCCESS Keycode successfully parsed.
1257 @retval EFI_NOT_READY Keyboard buffer is not ready for a valid keycode
1258
1259 **/
1260 EFI_STATUS
1261 USBParseKey (
1262 IN OUT USB_KB_DEV *UsbKeyboardDevice,
1263 OUT UINT8 *KeyCode
1264 )
1265 {
1266 USB_KEY UsbKey;
1267 EFI_KEY_DESCRIPTOR *KeyDescriptor;
1268
1269 *KeyCode = 0;
1270
1271 while (!IsQueueEmpty (&UsbKeyboardDevice->UsbKeyQueue)) {
1272 //
1273 // Pops one raw data off.
1274 //
1275 Dequeue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1276
1277 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, UsbKey.KeyCode);
1278 if (KeyDescriptor == NULL) {
1279 continue;
1280 }
1281 if (!UsbKey.Down) {
1282 //
1283 // Key is released.
1284 //
1285 switch (KeyDescriptor->Modifier) {
1286
1287 //
1288 // Ctrl release
1289 //
1290 case EFI_LEFT_CONTROL_MODIFIER:
1291 UsbKeyboardDevice->LeftCtrlOn = FALSE;
1292 UsbKeyboardDevice->CtrlOn = FALSE;
1293 break;
1294 case EFI_RIGHT_CONTROL_MODIFIER:
1295 UsbKeyboardDevice->RightCtrlOn = FALSE;
1296 UsbKeyboardDevice->CtrlOn = FALSE;
1297 break;
1298
1299 //
1300 // Shift release
1301 //
1302 case EFI_LEFT_SHIFT_MODIFIER:
1303 UsbKeyboardDevice->LeftShiftOn = FALSE;
1304 UsbKeyboardDevice->ShiftOn = FALSE;
1305 break;
1306 case EFI_RIGHT_SHIFT_MODIFIER:
1307 UsbKeyboardDevice->RightShiftOn = FALSE;
1308 UsbKeyboardDevice->ShiftOn = FALSE;
1309 break;
1310
1311 //
1312 // Alt release
1313 //
1314 case EFI_LEFT_ALT_MODIFIER:
1315 UsbKeyboardDevice->LeftAltOn = FALSE;
1316 UsbKeyboardDevice->AltOn = FALSE;
1317 break;
1318 case EFI_RIGHT_ALT_MODIFIER:
1319 UsbKeyboardDevice->RightAltOn = FALSE;
1320 UsbKeyboardDevice->AltOn = FALSE;
1321 break;
1322
1323 //
1324 // Left Logo release
1325 //
1326 case EFI_LEFT_LOGO_MODIFIER:
1327 UsbKeyboardDevice->LeftLogoOn = FALSE;
1328 break;
1329
1330 //
1331 // Right Logo release
1332 //
1333 case EFI_RIGHT_LOGO_MODIFIER:
1334 UsbKeyboardDevice->RightLogoOn = FALSE;
1335 break;
1336
1337 //
1338 // Menu key release
1339 //
1340 case EFI_MENU_MODIFIER:
1341 UsbKeyboardDevice->MenuKeyOn = FALSE;
1342 break;
1343
1344 //
1345 // SysReq release
1346 //
1347 case EFI_PRINT_MODIFIER:
1348 case EFI_SYS_REQUEST_MODIFIER:
1349 UsbKeyboardDevice->SysReqOn = FALSE;
1350 break;
1351
1352 //
1353 // AltGr release
1354 //
1355 case EFI_ALT_GR_MODIFIER:
1356 UsbKeyboardDevice->AltGrOn = FALSE;
1357 break;
1358
1359 default:
1360 break;
1361 }
1362
1363 continue;
1364 }
1365
1366 //
1367 // Analyzes key pressing situation
1368 //
1369 switch (KeyDescriptor->Modifier) {
1370
1371 //
1372 // Ctrl press
1373 //
1374 case EFI_LEFT_CONTROL_MODIFIER:
1375 UsbKeyboardDevice->LeftCtrlOn = TRUE;
1376 UsbKeyboardDevice->CtrlOn = TRUE;
1377 break;
1378 case EFI_RIGHT_CONTROL_MODIFIER:
1379 UsbKeyboardDevice->RightCtrlOn = TRUE;
1380 UsbKeyboardDevice->CtrlOn = TRUE;
1381 break;
1382
1383 //
1384 // Shift press
1385 //
1386 case EFI_LEFT_SHIFT_MODIFIER:
1387 UsbKeyboardDevice->LeftShiftOn = TRUE;
1388 UsbKeyboardDevice->ShiftOn = TRUE;
1389 break;
1390 case EFI_RIGHT_SHIFT_MODIFIER:
1391 UsbKeyboardDevice->RightShiftOn = TRUE;
1392 UsbKeyboardDevice->ShiftOn = TRUE;
1393 break;
1394
1395 //
1396 // Alt press
1397 //
1398 case EFI_LEFT_ALT_MODIFIER:
1399 UsbKeyboardDevice->LeftAltOn = TRUE;
1400 UsbKeyboardDevice->AltOn = TRUE;
1401 break;
1402 case EFI_RIGHT_ALT_MODIFIER:
1403 UsbKeyboardDevice->RightAltOn = TRUE;
1404 UsbKeyboardDevice->AltOn = TRUE;
1405 break;
1406
1407 //
1408 // Left Logo press
1409 //
1410 case EFI_LEFT_LOGO_MODIFIER:
1411 UsbKeyboardDevice->LeftLogoOn = TRUE;
1412 break;
1413
1414 //
1415 // Right Logo press
1416 //
1417 case EFI_RIGHT_LOGO_MODIFIER:
1418 UsbKeyboardDevice->RightLogoOn = TRUE;
1419 break;
1420
1421 //
1422 // Menu key press
1423 //
1424 case EFI_MENU_MODIFIER:
1425 UsbKeyboardDevice->MenuKeyOn = TRUE;
1426 break;
1427
1428 //
1429 // SysReq press
1430 //
1431 case EFI_PRINT_MODIFIER:
1432 case EFI_SYS_REQUEST_MODIFIER:
1433 UsbKeyboardDevice->SysReqOn = TRUE;
1434 break;
1435
1436 //
1437 // AltGr press
1438 //
1439 case EFI_ALT_GR_MODIFIER:
1440 UsbKeyboardDevice->AltGrOn = TRUE;
1441 break;
1442
1443 case EFI_NUM_LOCK_MODIFIER:
1444 //
1445 // Toggle NumLock
1446 //
1447 UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn));
1448 SetKeyLED (UsbKeyboardDevice);
1449 break;
1450
1451 case EFI_CAPS_LOCK_MODIFIER:
1452 //
1453 // Toggle CapsLock
1454 //
1455 UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn));
1456 SetKeyLED (UsbKeyboardDevice);
1457 break;
1458
1459 case EFI_SCROLL_LOCK_MODIFIER:
1460 //
1461 // Toggle ScrollLock
1462 //
1463 UsbKeyboardDevice->ScrollOn = (BOOLEAN) (!(UsbKeyboardDevice->ScrollOn));
1464 SetKeyLED (UsbKeyboardDevice);
1465 break;
1466
1467 default:
1468 break;
1469 }
1470
1471 //
1472 // When encountering Ctrl + Alt + Del, then warm reset.
1473 //
1474 if (KeyDescriptor->Modifier == EFI_DELETE_MODIFIER) {
1475 if ((UsbKeyboardDevice->CtrlOn) && (UsbKeyboardDevice->AltOn)) {
1476 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1477 }
1478 }
1479
1480 *KeyCode = UsbKey.KeyCode;
1481 return EFI_SUCCESS;
1482 }
1483
1484 return EFI_NOT_READY;
1485 }
1486
1487 /**
1488 Initialize the key state.
1489
1490 @param UsbKeyboardDevice The USB_KB_DEV instance.
1491 @param KeyState A pointer to receive the key state information.
1492 **/
1493 VOID
1494 InitializeKeyState (
1495 IN USB_KB_DEV *UsbKeyboardDevice,
1496 OUT EFI_KEY_STATE *KeyState
1497 )
1498 {
1499 KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID;
1500 KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;
1501
1502 if (UsbKeyboardDevice->LeftCtrlOn) {
1503 KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
1504 }
1505 if (UsbKeyboardDevice->RightCtrlOn) {
1506 KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
1507 }
1508 if (UsbKeyboardDevice->LeftAltOn) {
1509 KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;
1510 }
1511 if (UsbKeyboardDevice->RightAltOn) {
1512 KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
1513 }
1514 if (UsbKeyboardDevice->LeftShiftOn) {
1515 KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
1516 }
1517 if (UsbKeyboardDevice->RightShiftOn) {
1518 KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
1519 }
1520 if (UsbKeyboardDevice->LeftLogoOn) {
1521 KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
1522 }
1523 if (UsbKeyboardDevice->RightLogoOn) {
1524 KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
1525 }
1526 if (UsbKeyboardDevice->MenuKeyOn) {
1527 KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;
1528 }
1529 if (UsbKeyboardDevice->SysReqOn) {
1530 KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;
1531 }
1532
1533 if (UsbKeyboardDevice->ScrollOn) {
1534 KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
1535 }
1536 if (UsbKeyboardDevice->NumLockOn) {
1537 KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
1538 }
1539 if (UsbKeyboardDevice->CapsOn) {
1540 KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
1541 }
1542 if (UsbKeyboardDevice->IsSupportPartialKey) {
1543 KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;
1544 }
1545 }
1546
1547 /**
1548 Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
1549
1550 @param UsbKeyboardDevice The USB_KB_DEV instance.
1551 @param KeyCode Indicates the key code that will be interpreted.
1552 @param KeyData A pointer to a buffer that is filled in with
1553 the keystroke information for the key that
1554 was pressed.
1555
1556 @retval EFI_SUCCESS Success.
1557 @retval EFI_INVALID_PARAMETER KeyCode is not in the range of 0x4 to 0x65.
1558 @retval EFI_INVALID_PARAMETER Translated EFI_INPUT_KEY has zero for both ScanCode and UnicodeChar.
1559 @retval EFI_NOT_READY KeyCode represents a dead key with EFI_NS_KEY_MODIFIER
1560 @retval EFI_DEVICE_ERROR Keyboard layout is invalid.
1561
1562 **/
1563 EFI_STATUS
1564 UsbKeyCodeToEfiInputKey (
1565 IN USB_KB_DEV *UsbKeyboardDevice,
1566 IN UINT8 KeyCode,
1567 OUT EFI_KEY_DATA *KeyData
1568 )
1569 {
1570 EFI_KEY_DESCRIPTOR *KeyDescriptor;
1571 LIST_ENTRY *Link;
1572 LIST_ENTRY *NotifyList;
1573 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
1574
1575 //
1576 // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].
1577 //
1578 KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);
1579 if (KeyDescriptor == NULL) {
1580 return EFI_DEVICE_ERROR;
1581 }
1582
1583 if (KeyDescriptor->Modifier == EFI_NS_KEY_MODIFIER) {
1584 //
1585 // If this is a dead key with EFI_NS_KEY_MODIFIER, then record it and return.
1586 //
1587 UsbKeyboardDevice->CurrentNsKey = FindUsbNsKey (UsbKeyboardDevice, KeyDescriptor);
1588 return EFI_NOT_READY;
1589 }
1590
1591 if (UsbKeyboardDevice->CurrentNsKey != NULL) {
1592 //
1593 // If this keystroke follows a non-spacing key, then find the descriptor for corresponding
1594 // physical key.
1595 //
1596 KeyDescriptor = FindPhysicalKey (UsbKeyboardDevice->CurrentNsKey, KeyDescriptor);
1597 UsbKeyboardDevice->CurrentNsKey = NULL;
1598 }
1599
1600 //
1601 // Make sure modifier of Key Descriptor is in the valid range according to UEFI spec.
1602 //
1603 if (KeyDescriptor->Modifier >= (sizeof (ModifierValueToEfiScanCodeConvertionTable) / sizeof (UINT8))) {
1604 return EFI_DEVICE_ERROR;
1605 }
1606
1607 KeyData->Key.ScanCode = ModifierValueToEfiScanCodeConvertionTable[KeyDescriptor->Modifier];
1608 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
1609
1610 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_STANDARD_SHIFT)!= 0) {
1611 if (UsbKeyboardDevice->ShiftOn) {
1612 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;
1613
1614 //
1615 // Need not return associated shift state if a class of printable characters that
1616 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1617 //
1618 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
1619 UsbKeyboardDevice->LeftShiftOn = FALSE;
1620 UsbKeyboardDevice->RightShiftOn = FALSE;
1621 }
1622
1623 if (UsbKeyboardDevice->AltGrOn) {
1624 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedAltGrUnicode;
1625 }
1626 } else {
1627 //
1628 // Shift off
1629 //
1630 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
1631
1632 if (UsbKeyboardDevice->AltGrOn) {
1633 KeyData->Key.UnicodeChar = KeyDescriptor->AltGrUnicode;
1634 }
1635 }
1636 }
1637
1638 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_CAPS_LOCK) != 0) {
1639 if (UsbKeyboardDevice->CapsOn) {
1640 if (KeyData->Key.UnicodeChar == KeyDescriptor->Unicode) {
1641 KeyData->Key.UnicodeChar = KeyDescriptor->ShiftedUnicode;
1642 } else if (KeyData->Key.UnicodeChar == KeyDescriptor->ShiftedUnicode) {
1643 KeyData->Key.UnicodeChar = KeyDescriptor->Unicode;
1644 }
1645 }
1646 }
1647
1648 if ((KeyDescriptor->AffectedAttribute & EFI_AFFECTED_BY_NUM_LOCK) != 0) {
1649 //
1650 // For key affected by NumLock, if NumLock is on and Shift is not pressed, then it means
1651 // normal key, instead of original control key. So the ScanCode should be cleaned.
1652 // Otherwise, it means control key, so preserve the EFI Scan Code and clear the unicode keycode.
1653 //
1654 if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) {
1655 KeyData->Key.ScanCode = SCAN_NULL;
1656 } else {
1657 KeyData->Key.UnicodeChar = CHAR_NULL;
1658 }
1659 }
1660
1661 //
1662 // Translate Unicode 0x1B (ESC) to EFI Scan Code
1663 //
1664 if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) {
1665 KeyData->Key.ScanCode = SCAN_ESC;
1666 KeyData->Key.UnicodeChar = CHAR_NULL;
1667 }
1668
1669 //
1670 // Not valid for key without both unicode key code and EFI Scan Code.
1671 //
1672 if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) {
1673 if (!UsbKeyboardDevice->IsSupportPartialKey) {
1674 return EFI_NOT_READY;
1675 }
1676 }
1677
1678 //
1679 // Save Shift/Toggle state
1680 //
1681 InitializeKeyState (UsbKeyboardDevice, &KeyData->KeyState);
1682
1683 //
1684 // Signal KeyNotify process event if this key pressed matches any key registered.
1685 //
1686 NotifyList = &UsbKeyboardDevice->NotifyList;
1687 for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
1688 CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
1689 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
1690 //
1691 // The key notification function needs to run at TPL_CALLBACK
1692 // while current TPL is TPL_NOTIFY. It will be invoked in
1693 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1694 //
1695 Enqueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, KeyData, sizeof (*KeyData));
1696 gBS->SignalEvent (UsbKeyboardDevice->KeyNotifyProcessEvent);
1697 }
1698 }
1699
1700 return EFI_SUCCESS;
1701 }
1702
1703 /**
1704 Create the queue.
1705
1706 @param Queue Points to the queue.
1707 @param ItemSize Size of the single item.
1708
1709 **/
1710 VOID
1711 InitQueue (
1712 IN OUT USB_SIMPLE_QUEUE *Queue,
1713 IN UINTN ItemSize
1714 )
1715 {
1716 UINTN Index;
1717
1718 Queue->ItemSize = ItemSize;
1719 Queue->Head = 0;
1720 Queue->Tail = 0;
1721
1722 if (Queue->Buffer[0] != NULL) {
1723 FreePool (Queue->Buffer[0]);
1724 }
1725
1726 Queue->Buffer[0] = AllocatePool (sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]) * ItemSize);
1727 ASSERT (Queue->Buffer[0] != NULL);
1728
1729 for (Index = 1; Index < sizeof (Queue->Buffer) / sizeof (Queue->Buffer[0]); Index++) {
1730 Queue->Buffer[Index] = ((UINT8 *) Queue->Buffer[Index - 1]) + ItemSize;
1731 }
1732 }
1733
1734 /**
1735 Destroy the queue
1736
1737 @param Queue Points to the queue.
1738 **/
1739 VOID
1740 DestroyQueue (
1741 IN OUT USB_SIMPLE_QUEUE *Queue
1742 )
1743 {
1744 FreePool (Queue->Buffer[0]);
1745 }
1746
1747
1748 /**
1749 Check whether the queue is empty.
1750
1751 @param Queue Points to the queue.
1752
1753 @retval TRUE Queue is empty.
1754 @retval FALSE Queue is not empty.
1755
1756 **/
1757 BOOLEAN
1758 IsQueueEmpty (
1759 IN USB_SIMPLE_QUEUE *Queue
1760 )
1761 {
1762 //
1763 // Meet FIFO empty condition
1764 //
1765 return (BOOLEAN) (Queue->Head == Queue->Tail);
1766 }
1767
1768
1769 /**
1770 Check whether the queue is full.
1771
1772 @param Queue Points to the queue.
1773
1774 @retval TRUE Queue is full.
1775 @retval FALSE Queue is not full.
1776
1777 **/
1778 BOOLEAN
1779 IsQueueFull (
1780 IN USB_SIMPLE_QUEUE *Queue
1781 )
1782 {
1783 return (BOOLEAN) (((Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1)) == Queue->Head);
1784 }
1785
1786
1787 /**
1788 Enqueue the item to the queue.
1789
1790 @param Queue Points to the queue.
1791 @param Item Points to the item to be enqueued.
1792 @param ItemSize Size of the item.
1793 **/
1794 VOID
1795 Enqueue (
1796 IN OUT USB_SIMPLE_QUEUE *Queue,
1797 IN VOID *Item,
1798 IN UINTN ItemSize
1799 )
1800 {
1801 ASSERT (ItemSize == Queue->ItemSize);
1802 //
1803 // If keyboard buffer is full, throw the
1804 // first key out of the keyboard buffer.
1805 //
1806 if (IsQueueFull (Queue)) {
1807 Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);
1808 }
1809
1810 CopyMem (Queue->Buffer[Queue->Tail], Item, ItemSize);
1811
1812 //
1813 // Adjust the tail pointer of the FIFO keyboard buffer.
1814 //
1815 Queue->Tail = (Queue->Tail + 1) % (MAX_KEY_ALLOWED + 1);
1816 }
1817
1818
1819 /**
1820 Dequeue a item from the queue.
1821
1822 @param Queue Points to the queue.
1823 @param Item Receives the item.
1824 @param ItemSize Size of the item.
1825
1826 @retval EFI_SUCCESS Item was successfully dequeued.
1827 @retval EFI_DEVICE_ERROR The queue is empty.
1828
1829 **/
1830 EFI_STATUS
1831 Dequeue (
1832 IN OUT USB_SIMPLE_QUEUE *Queue,
1833 OUT VOID *Item,
1834 IN UINTN ItemSize
1835 )
1836 {
1837 ASSERT (Queue->ItemSize == ItemSize);
1838
1839 if (IsQueueEmpty (Queue)) {
1840 return EFI_DEVICE_ERROR;
1841 }
1842
1843 CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize);
1844
1845 //
1846 // Adjust the head pointer of the FIFO keyboard buffer.
1847 //
1848 Queue->Head = (Queue->Head + 1) % (MAX_KEY_ALLOWED + 1);
1849
1850 return EFI_SUCCESS;
1851 }
1852
1853
1854 /**
1855 Sets USB keyboard LED state.
1856
1857 @param UsbKeyboardDevice The USB_KB_DEV instance.
1858
1859 **/
1860 VOID
1861 SetKeyLED (
1862 IN USB_KB_DEV *UsbKeyboardDevice
1863 )
1864 {
1865 LED_MAP Led;
1866 UINT8 ReportId;
1867
1868 //
1869 // Set each field in Led map.
1870 //
1871 Led.NumLock = (UINT8) ((UsbKeyboardDevice->NumLockOn) ? 1 : 0);
1872 Led.CapsLock = (UINT8) ((UsbKeyboardDevice->CapsOn) ? 1 : 0);
1873 Led.ScrollLock = (UINT8) ((UsbKeyboardDevice->ScrollOn) ? 1 : 0);
1874 Led.Resrvd = 0;
1875
1876 ReportId = 0;
1877 //
1878 // Call Set_Report Request to lighten the LED.
1879 //
1880 UsbSetReportRequest (
1881 UsbKeyboardDevice->UsbIo,
1882 UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
1883 ReportId,
1884 HID_OUTPUT_REPORT,
1885 1,
1886 (UINT8 *) &Led
1887 );
1888 }
1889
1890
1891 /**
1892 Handler for Repeat Key event.
1893
1894 This function is the handler for Repeat Key event triggered
1895 by timer.
1896 After a repeatable key is pressed, the event would be triggered
1897 with interval of USBKBD_REPEAT_DELAY. Once the event is triggered,
1898 following trigger will come with interval of USBKBD_REPEAT_RATE.
1899
1900 @param Event The Repeat Key event.
1901 @param Context Points to the USB_KB_DEV instance.
1902
1903 **/
1904 VOID
1905 EFIAPI
1906 USBKeyboardRepeatHandler (
1907 IN EFI_EVENT Event,
1908 IN VOID *Context
1909 )
1910 {
1911 USB_KB_DEV *UsbKeyboardDevice;
1912 USB_KEY UsbKey;
1913
1914 UsbKeyboardDevice = (USB_KB_DEV *) Context;
1915
1916 //
1917 // Do nothing when there is no repeat key.
1918 //
1919 if (UsbKeyboardDevice->RepeatKey != 0) {
1920 //
1921 // Inserts the repeat key into keyboard buffer,
1922 //
1923 UsbKey.KeyCode = UsbKeyboardDevice->RepeatKey;
1924 UsbKey.Down = TRUE;
1925 Enqueue (&UsbKeyboardDevice->UsbKeyQueue, &UsbKey, sizeof (UsbKey));
1926
1927 //
1928 // Set repeat rate for next repeat key generation.
1929 //
1930 gBS->SetTimer (
1931 UsbKeyboardDevice->RepeatTimer,
1932 TimerRelative,
1933 USBKBD_REPEAT_RATE
1934 );
1935 }
1936 }
1937
1938
1939 /**
1940 Handler for Delayed Recovery event.
1941
1942 This function is the handler for Delayed Recovery event triggered
1943 by timer.
1944 After a device error occurs, the event would be triggered
1945 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
1946 is defined in USB standard for error handling.
1947
1948 @param Event The Delayed Recovery event.
1949 @param Context Points to the USB_KB_DEV instance.
1950
1951 **/
1952 VOID
1953 EFIAPI
1954 USBKeyboardRecoveryHandler (
1955 IN EFI_EVENT Event,
1956 IN VOID *Context
1957 )
1958 {
1959
1960 USB_KB_DEV *UsbKeyboardDevice;
1961 EFI_USB_IO_PROTOCOL *UsbIo;
1962 UINT8 PacketSize;
1963
1964 UsbKeyboardDevice = (USB_KB_DEV *) Context;
1965
1966 UsbIo = UsbKeyboardDevice->UsbIo;
1967
1968 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
1969
1970 //
1971 // Re-submit Asynchronous Interrupt Transfer for recovery.
1972 //
1973 UsbIo->UsbAsyncInterruptTransfer (
1974 UsbIo,
1975 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
1976 TRUE,
1977 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
1978 PacketSize,
1979 KeyboardHandler,
1980 UsbKeyboardDevice
1981 );
1982 }