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