1 /*
2 * Copyright (c) 2015, Pluribus Networks, Inc.
3 *
4 * This program and the accompanying materials are licensed and made
5 * available under the terms and conditions of the BSD License which
6 * accompanies this distribution. The full text of the license may be
7 * found at http://opensource.org/licenses/bsd-license.php
8 *
9 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
10 * BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
11 * EXPRESS OR IMPLIED.
12 */
13
14 #include <Uefi.h>
15
16 #include "BhyveCsm16.h"
17
18 #include "Debug.h"
19 #include "Printf.h"
20
21 #define KEYBOARD_MAX_TRY 256
22
23 #define KEYBOARD_8042_DATA_REGISTER 0x60
24 #define KEYBOARD_8042_STATUS_REGISTER 0x64
25 #define KEYBOARD_8042_COMMAND_REGISTER 0x64
26
27 #define KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA 0x1
28 #define KEYBOARD_STATUS_REGISTER_HAS_INPUT_DATA 0x2
29
30 #define KEYBOARD_8042_COMMAND_WRITE 0x60
31 #define KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE 0xA7
32 #define KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST 0xAA
33 #define KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE 0xAD
34 #define KEYBOARD_8042_COMMAND_ENABLE_KEYBOARD_INTERFACE 0xAE
35
36 #define KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET 0xF0
37 #define KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA 0xF4
38 #define KEYBOARD_8048_RETURN_8042_ACK 0xFA
39
40 // KEYBOARD COMMAND BYTE
41 // 7: Reserved
42 // 6: PC/XT translation mode convert
43 // 5: Disable Auxiliary device interface
44 // 4: Disable keyboard interface
45 // 3: Reserved
46 // 2: System Flag: selftest successful
47 // 1: Enable Auxiliary device interrupt
48 // 0: Enable Keyboard interrupt
49 #define KEYBOARD_CMMBYTE_TRANSLATE (0x1 << 6)
50 #define KEYBOARD_CMMBYTE_DISABLE_AUX (0x1 << 5)
51 #define KEYBOARD_CMMBYTE_DISABLE_KB (0x1 << 4)
52 #define KEYBOARD_CMMBYTE_SELFTEST_OK (0x1 << 2)
53 #define KEYBOARD_CMMBYTE_ENABLE_AUXINT (0x1 << 1)
54 #define KEYBOARD_CMMBYTE_ENABLE_KBINT (0x1 << 0)
55
56 STATIC UINT8
KeyReadStatusRegister(VOID)57 KeyReadStatusRegister(VOID)
58 {
59 return (IoRead8(KEYBOARD_8042_STATUS_REGISTER));
60 }
61
62 STATIC UINT8
KeyReadDataRegister(VOID)63 KeyReadDataRegister(VOID)
64 {
65 return (IoRead8(KEYBOARD_8042_DATA_REGISTER));
66 }
67
68 STATIC VOID
KeyWriteDataRegister(UINT8 Data)69 KeyWriteDataRegister(UINT8 Data)
70 {
71 IoWrite8(KEYBOARD_8042_DATA_REGISTER, Data);
72 }
73
74 STATIC VOID
KeyWriteCommandRegister(UINT8 Data)75 KeyWriteCommandRegister(UINT8 Data)
76 {
77 IoWrite8(KEYBOARD_8042_COMMAND_REGISTER, Data);
78 }
79
80 EFI_STATUS
KeyboardWaitForValue(UINT8 Value)81 KeyboardWaitForValue(UINT8 Value)
82 {
83 UINTN TryTime;
84 UINT8 Data;
85
86 DEBUG (("XXX KeyboardWaitForValue() Value=0x%x\n", Value));
87 for (TryTime = 0; TryTime < KEYBOARD_MAX_TRY; TryTime++) {
88 if ((KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) != 0) {
89 Data = KeyReadDataRegister();
90 DEBUG (("XXX KeyboardWaitForValue() Data=0%x\n", Data));
91 if (Data == Value)
92 return EFI_SUCCESS;
93 }
94 }
95
96 return EFI_TIMEOUT;
97 }
98
99 STATIC EFI_STATUS
KeyboardRead(UINT8 * Data)100 KeyboardRead(UINT8 *Data)
101 {
102 if (KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {
103 *Data = KeyReadDataRegister();
104 return EFI_SUCCESS;
105 }
106
107 return EFI_TIMEOUT;
108 }
109
110 STATIC EFI_STATUS
KeyboardWrite(IN UINT8 Data)111 KeyboardWrite (
112 IN UINT8 Data
113 )
114 {
115 UINTN TryTime;
116
117 //
118 // Wait For Input Buffer Empty
119 //
120 for (TryTime = 0; TryTime < KEYBOARD_MAX_TRY; TryTime++) {
121 if ((KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_INPUT_DATA) == 0)
122 break;
123 }
124
125 if (TryTime == KEYBOARD_MAX_TRY) {
126 return (EFI_DEVICE_ERROR);
127 }
128
129 KeyWriteDataRegister(Data);
130
131 return EFI_SUCCESS;
132 }
133
134 STATIC EFI_STATUS
KeyboardCommand(IN UINT8 Data)135 KeyboardCommand (
136 IN UINT8 Data
137 )
138 {
139 UINTN TryTime;
140
141 //
142 // Wait For Input Buffer Empty
143 //
144 for (TryTime = 0; TryTime < KEYBOARD_MAX_TRY; TryTime++) {
145 if ((KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_INPUT_DATA) == 0)
146 break;
147 }
148
149 if (TryTime == KEYBOARD_MAX_TRY) {
150 return (EFI_DEVICE_ERROR);
151 }
152
153 KeyWriteCommandRegister(Data);
154
155 //
156 // Wait For Input Buffer Empty again
157 //
158 for (TryTime = 0; TryTime < KEYBOARD_MAX_TRY; TryTime++) {
159 if ((KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_INPUT_DATA) == 0)
160 break;
161 }
162
163 if (TryTime == KEYBOARD_MAX_TRY) {
164 return (EFI_DEVICE_ERROR);
165 }
166
167 return EFI_SUCCESS;
168 }
169
170 #define SCANCODE_CONTROL 0x1d
171 #define SCANCODE_L_SHIFT 0x2a
172 #define SCANCODE_R_SHIFT 0x36
173 #define SCANCODE_ALT 0x38
174 #define SCANCODE_CAPS_LOCK 0x3a
175 #define SCANCODE_NUM_LOCK 0x45
176 #define SCANCODE_SCROLL_LOCK 0x46
177 #define SCANCODE_INSERT 0x52
178
179 struct KeyEntry {
180 UINT16 Normal;
181 UINT16 Shift;
182 UINT16 Control;
183 UINT16 Alt;
184 };
185
186 struct KeyEntry KeyOneByteEntries[] = {
187 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 0 */
188 { 0x011b, 0x011b, 0x011b, 0xffff }, /* key 1 - Escape key */
189 { 0x0231, 0x0221, 0xffff, 0x7800 }, /* key 2 - '1' */
190 { 0x0332, 0x0340, 0x0300, 0x7900 }, /* key 3 - '2' */
191 { 0x0433, 0x0423, 0xffff, 0x7a00 }, /* key 4 - '3' */
192 { 0x0534, 0x0524, 0xffff, 0x7b00 }, /* key 5 - '4' */
193 { 0x0635, 0x0625, 0xffff, 0x7c00 }, /* key 6 - '5' */
194 { 0x0736, 0x075e, 0x071e, 0x7d00 }, /* key 7 - '6' */
195 { 0x0837, 0x0826, 0xffff, 0x7e00 }, /* key 8 - '7' */
196 { 0x0938, 0x092a, 0xffff, 0x7f00 }, /* key 9 - '8' */
197 { 0x0a39, 0x0a28, 0xffff, 0x8000 }, /* key 10 - '9' */
198 { 0x0b30, 0x0b29, 0xffff, 0x8100 }, /* key 11 - '0' */
199 { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200 }, /* key 12 - '-' */
200 { 0x0d3d, 0x0d2b, 0xffff, 0x8300 }, /* key 13 - '=' */
201 { 0x0e08, 0x0e08, 0x0e7f, 0xffff }, /* key 14 - backspace */
202 { 0x0f09, 0x0f00, 0xffff, 0xffff }, /* key 15 - tab */
203 { 0x1071, 0x1051, 0x1011, 0x1000 }, /* key 16 - 'Q' */
204 { 0x1177, 0x1157, 0x1117, 0x1100 }, /* key 17 - 'W' */
205 { 0x1265, 0x1245, 0x1205, 0x1200 }, /* key 18 - 'E' */
206 { 0x1372, 0x1352, 0x1312, 0x1300 }, /* key 19 - 'R' */
207 { 0x1474, 0x1454, 0x1414, 0x1400 }, /* key 20 - 'T' */
208 { 0x1579, 0x1559, 0x1519, 0x1500 }, /* key 21 - 'Y' */
209 { 0x1675, 0x1655, 0x1615, 0x1600 }, /* key 22 - 'U' */
210 { 0x1769, 0x1749, 0x1709, 0x1700 }, /* key 23 - 'I' */
211 { 0x186f, 0x184f, 0x180f, 0x1800 }, /* key 24 - 'O' */
212 { 0x1970, 0x1950, 0x1910, 0x1900 }, /* key 25 - 'P' */
213 { 0x1a5b, 0x1a7b, 0x1a1b, 0xffff }, /* key 26 - '[' */
214 { 0x1b5d, 0x1b7d, 0x1b1d, 0xffff }, /* key 27 - ']' */
215 { 0x1c0d, 0x1c0d, 0x1c0a, 0xffff }, /* key 28 - CR */
216 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 29 - left control */
217 { 0x1e61, 0x1e41, 0x1e01, 0x1e00 }, /* key 30 - 'A' */
218 { 0x1f73, 0x1f53, 0x1f13, 0x1f00 }, /* key 31 - 'S' */
219 { 0x2064, 0x2044, 0x2004, 0x2000 }, /* key 32 - 'D' */
220 { 0x2166, 0x2146, 0x2106, 0x2100 }, /* key 33 - 'F' */
221 { 0x2267, 0x2247, 0x2207, 0x2200 }, /* key 34 - 'G' */
222 { 0x2368, 0x2348, 0x2308, 0x2300 }, /* key 35 - 'H' */
223 { 0x246a, 0x244a, 0x240a, 0x2400 }, /* key 36 - 'J' */
224 { 0x256b, 0x254b, 0x250b, 0x2500 }, /* key 37 - 'K' */
225 { 0x266c, 0x264c, 0x260c, 0x2600 }, /* key 38 - 'L' */
226 { 0x273b, 0x273a, 0xffff, 0xffff }, /* key 39 - ';' */
227 { 0x2827, 0x2822, 0xffff, 0xffff }, /* key 40 - ''' */
228 { 0x2960, 0x297e, 0xffff, 0xffff }, /* key 41 - '`' */
229 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 42 - left shift */
230 { 0x2b5c, 0x2b7c, 0x2b1c, 0xffff }, /* key 43 - '' */
231 { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00 }, /* key 44 - 'Z' */
232 { 0x2d78, 0x2d58, 0x2d18, 0x2d00 }, /* key 45 - 'X' */
233 { 0x2e63, 0x2e43, 0x2e03, 0x2e00 }, /* key 46 - 'C' */
234 { 0x2f76, 0x2f56, 0x2f16, 0x2f00 }, /* key 47 - 'V' */
235 { 0x3062, 0x3042, 0x3002, 0x3000 }, /* key 48 - 'B' */
236 { 0x316e, 0x314e, 0x310e, 0x3100 }, /* key 49 - 'N' */
237 { 0x326d, 0x324d, 0x320d, 0x3200 }, /* key 50 - 'M' */
238 { 0x332c, 0x333c, 0xffff, 0xffff }, /* key 51 - ',' */
239 { 0x342e, 0x343e, 0xffff, 0xffff }, /* key 52 - '.' */
240 { 0x352f, 0x353f, 0xffff, 0xffff }, /* key 53 - '/' */
241 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 54 - right shift - */
242 { 0x372a, 0xffff, 0x3772, 0xffff }, /* key 55 - prt-scr - */
243 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 56 - left alt - */
244 { 0x3920, 0x3920, 0x3920, 0x3920 }, /* key 57 - space bar */
245 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 58 - caps-lock - */
246 { 0x3b00, 0x5400, 0x5e00, 0x6800 }, /* key 59 - F1 */
247 { 0x3c00, 0x5500, 0x5f00, 0x6900 }, /* key 60 - F2 */
248 { 0x3d00, 0x5600, 0x6000, 0x6a00 }, /* key 61 - F3 */
249 { 0x3e00, 0x5700, 0x6100, 0x6b00 }, /* key 62 - F4 */
250 { 0x3f00, 0x5800, 0x6200, 0x6c00 }, /* key 63 - F5 */
251 { 0x4000, 0x5900, 0x6300, 0x6d00 }, /* key 64 - F6 */
252 { 0x4100, 0x5a00, 0x6400, 0x6e00 }, /* key 65 - F7 */
253 { 0x4200, 0x5b00, 0x6500, 0x6f00 }, /* key 66 - F8 */
254 { 0x4300, 0x5c00, 0x6600, 0x7000 }, /* key 67 - F9 */
255 { 0x4400, 0x5d00, 0x6700, 0x7100 }, /* key 68 - F10 */
256 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 69 - num-lock - */
257 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 70 - scroll-lock - */
258 { 0x4700, 0x4737, 0x7700, 0xffff }, /* key 71 - home */
259 { 0x4800, 0x4838, 0xffff, 0xffff }, /* key 72 - cursor up */
260 { 0x4900, 0x4939, 0x8400, 0xffff }, /* key 73 - page up */
261 { 0x4a2d, 0x4a2d, 0xffff, 0xffff }, /* key 74 - minus sign */
262 { 0x4b00, 0x4b34, 0x7300, 0xffff }, /* key 75 - cursor left */
263 { 0xffff, 0x4c35, 0xffff, 0xffff }, /* key 76 - center key */
264 { 0x4d00, 0x4d36, 0x7400, 0xffff }, /* key 77 - cursor right */
265 { 0x4e2b, 0x4e2b, 0xffff, 0xffff }, /* key 78 - plus sign */
266 { 0x4f00, 0x4f31, 0x7500, 0xffff }, /* key 79 - end */
267 { 0x5000, 0x5032, 0xffff, 0xffff }, /* key 80 - cursor down */
268 { 0x5100, 0x5133, 0x7600, 0xffff }, /* key 81 - page down */
269 { 0x5200, 0x5230, 0xffff, 0xffff }, /* key 82 - insert */
270 { 0x5300, 0x532e, 0xffff, 0xffff }, /* key 83 - delete */
271 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 84 - sys key */
272 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 85 */
273 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 86 */
274 { 0x8500, 0x5787, 0x8900, 0x8b00 }, /* key 87 - F11 */
275 { 0x8600, 0x5888, 0x8a00, 0x8c00 }, /* key 88 - F12 */
276 };
277
278 struct KeyEntry KeyTwoByteEntries[] = {
279 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 0 */
280 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 1 */
281 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 2 */
282 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3 */
283 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 4 */
284 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 5 */
285 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 6 */
286 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 7 */
287 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 8 */
288 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 9 */
289 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 a */
290 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 b */
291 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 c */
292 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 d */
293 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 e */
294 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 f */
295 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 10 */
296 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 11 */
297 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 12 */
298 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 13 */
299 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 14 */
300 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 15 */
301 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 16 */
302 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 17 */
303 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 18 */
304 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 19 */
305 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 1a */
306 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 1b */
307 { 0x1c0d, 0x1c0d, 0x1c0a, 0xffff }, /* key e0 1c - numeric keypad enter */
308 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 1d - right control */
309 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 1e */
310 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 1f */
311 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 20 */
312 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 21 */
313 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 22 */
314 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 23 */
315 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 24 */
316 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 25 */
317 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 26 */
318 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 27 */
319 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 28 */
320 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 29 */
321 { 0xffff, 0xffff, 0x7200, 0xffff }, /* key e0 2a - numlock */
322 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 2b */
323 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 2c */
324 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 2d */
325 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 2e */
326 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 2f */
327 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 30 */
328 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 31 */
329 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 32 */
330 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 33 */
331 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 34 */
332 { 0x352f, 0x352f, 0xffff, 0xffff }, /* key e0 35 - '/' */
333 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 36 */
334 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 37 */
335 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 38 - right alt */
336 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 39 */
337 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3a */
338 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3b */
339 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3c */
340 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3d */
341 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3e */
342 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 3f */
343 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 40 */
344 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 41 */
345 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 42 */
346 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 43 */
347 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 44 */
348 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 45 */
349 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 46 */
350 { 0x4700, 0x4700, 0x7700, 0xffff }, /* key e0 47 - home */
351 { 0x4800, 0x4800, 0xffff, 0xffff }, /* key e0 48 - cursor up */
352 { 0x4900, 0x4900, 0x8400, 0xffff }, /* key e0 49 - page up */
353 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 4a */
354 { 0x4b00, 0x4b00, 0x7300, 0xffff }, /* key e0 4b - cursor left */
355 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 4c */
356 { 0x4d00, 0x4d00, 0x7400, 0xffff }, /* key e0 4d - cursor right */
357 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key e0 4e */
358 { 0x4f00, 0x4f00, 0x7500, 0xffff }, /* key e0 4f - end */
359 { 0x5000, 0x5000, 0xffff, 0xffff }, /* key e0 50 - cursor down */
360 { 0x5100, 0x5100, 0x7600, 0xffff }, /* key e0 51 - page down */
361 { 0x5200, 0x5200, 0xffff, 0xffff }, /* key e0 52 - insert */
362 { 0x5300, 0x5300, 0xffff, 0xffff }, /* key e0 53 - delete */
363 };
364
365 static VOID
ProcessReleasedScancode(UINT8 Scancode)366 ProcessReleasedScancode(UINT8 Scancode)
367 {
368 switch (Scancode) {
369 case SCANCODE_INSERT:
370 mBdaPtr->KeyboardStatus1 &= ~KBSF1_INSERT_BIT;
371 break;
372 case SCANCODE_CAPS_LOCK:
373 mBdaPtr->KeyboardStatus1 &= ~KBSF1_CAPS_LOCK_BIT;
374 break;
375 case SCANCODE_NUM_LOCK:
376 mBdaPtr->KeyboardStatus1 &= ~KBSF1_NUM_LOCK_BIT;
377 break;
378 case SCANCODE_SCROLL_LOCK:
379 mBdaPtr->KeyboardStatus1 &= ~KBSF1_SCROLL_LOCK_BIT;
380 break;
381 case SCANCODE_ALT:
382 mBdaPtr->KeyboardStatus1 &= ~KBSF1_ALT_PRESSED;
383 break;
384 case SCANCODE_CONTROL:
385 mBdaPtr->KeyboardStatus1 &= ~KBSF1_CTRL_PRESSED;
386 break;
387 case SCANCODE_L_SHIFT:
388 mBdaPtr->KeyboardStatus1 &= ~KBSF1_LEFT_SHIFT_PRESSED;
389 break;
390 case SCANCODE_R_SHIFT:
391 mBdaPtr->KeyboardStatus1 &= ~KBSF1_RIGHT_SHIFT_PRESSED;
392 break;
393 }
394 }
395
396 static VOID
ProcessPressedScancode(UINT8 Scancode)397 ProcessPressedScancode(UINT8 Scancode)
398 {
399 struct KeyEntry *KeyEntries;
400 UINT16 Key;
401 UINT16 Newtail;
402
403 DEBUG (("XXX ProcessPressedScancode()\n"));
404 switch (Scancode) {
405 case SCANCODE_INSERT:
406 mBdaPtr->KeyboardStatus1 |= KBSF1_INSERT_BIT;
407 break;
408 case SCANCODE_CAPS_LOCK:
409 mBdaPtr->KeyboardStatus1 |= KBSF1_CAPS_LOCK_BIT;
410 break;
411 case SCANCODE_NUM_LOCK:
412 mBdaPtr->KeyboardStatus1 |= KBSF1_NUM_LOCK_BIT;
413 break;
414 case SCANCODE_SCROLL_LOCK:
415 mBdaPtr->KeyboardStatus1 |= KBSF1_SCROLL_LOCK_BIT;
416 break;
417 case SCANCODE_ALT:
418 mBdaPtr->KeyboardStatus1 |= KBSF1_ALT_PRESSED;
419 break;
420 case SCANCODE_CONTROL:
421 mBdaPtr->KeyboardStatus1 |= KBSF1_CTRL_PRESSED;
422 break;
423 case SCANCODE_L_SHIFT:
424 mBdaPtr->KeyboardStatus1 |= KBSF1_LEFT_SHIFT_PRESSED;
425 break;
426 case SCANCODE_R_SHIFT:
427 mBdaPtr->KeyboardStatus1 |= KBSF1_RIGHT_SHIFT_PRESSED;
428 break;
429 }
430
431 if ((mBdaPtr->KeyboardStatus3 & KBSF3_LAST_CODE_WAS_E0) != 0) {
432 DEBUG(("XXX E0 Scancode = 0x%x\n", Scancode));
433 KeyEntries = KeyTwoByteEntries;
434 DEBUG(("XXX KeyEntries = 0x%p\n", KeyEntries));
435 DEBUG(("XXX KeyEntries[0].Normal = 0x%x\n", KeyEntries[0].Normal));
436 DEBUG(("XXX KeyEntries[0x10].Normal = 0x%x\n", KeyEntries[0x10].Normal));
437 DEBUG(("XXX KeyEntries[0x1c].Normal = 0x%x\n", KeyEntries[0x1c].Normal));
438 DEBUG(("XXX KeyEntries[0x35].Normal = 0x%x\n", KeyEntries[0x35].Normal));
439 DEBUG(("XXX KeyEntries[0x50].Normal = 0x%x\n", KeyEntries[0x50].Normal));
440 } else {
441 KeyEntries = KeyOneByteEntries;
442 }
443
444 if ((mBdaPtr->KeyboardStatus1 & KBSF1_ALT_PRESSED) != 0) {
445 Key = KeyEntries[Scancode].Alt;
446 } else if ((mBdaPtr->KeyboardStatus1 & KBSF1_CTRL_PRESSED) != 0) {
447 Key = KeyEntries[Scancode].Control;
448 } else if ((mBdaPtr->KeyboardStatus1 & KBSF1_LEFT_SHIFT_PRESSED) != 0 ||
449 (mBdaPtr->KeyboardStatus1 & KBSF1_RIGHT_SHIFT_PRESSED) != 0) {
450 Key = KeyEntries[Scancode].Shift;
451 } else {
452 Key = KeyEntries[Scancode].Normal;
453 }
454
455 DEBUG(("XXX Key = 0x%x\n", Key));
456 if (Key == 0xffff)
457 return;
458
459 Newtail = mBdaPtr->KeyBufferTail + 2;
460 if (Newtail == mBdaPtr->KeyBufferEnd)
461 Newtail = mBdaPtr->KeyBufferStart;
462
463 if (Newtail == mBdaPtr->KeyBufferHead)
464 return;
465
466 *(UINT16 *)((UINT8 *)(UINTN)0x400 + mBdaPtr->KeyBufferTail) = Key;
467 mBdaPtr->KeyBufferTail = Newtail;
468 }
469
470 static VOID
ProcessScancode(UINT8 Scancode)471 ProcessScancode(UINT8 Scancode)
472 {
473 DEBUG(("XXX ProcessScancode() 0x%x\n", Scancode));
474 if (Scancode == 0xe0) {
475 mBdaPtr->KeyboardStatus3 |= KBSF3_LAST_CODE_WAS_E0;
476 return;
477 }
478 if (Scancode == 0xe1) {
479 mBdaPtr->KeyboardStatus3 |= KBSF3_LAST_CODE_WAS_E1;
480 return;
481 }
482
483 if ((Scancode & 0x80) != 0) {
484 ProcessReleasedScancode(Scancode & 0x7F);
485 } else {
486 ProcessPressedScancode(Scancode);
487 }
488
489 if (Scancode != 0xe0) {
490 mBdaPtr->KeyboardStatus3 &= ~KBSF3_LAST_CODE_WAS_E0;
491 }
492 if (Scancode != 0xe1) {
493 mBdaPtr->KeyboardStatus3 &= ~KBSF3_LAST_CODE_WAS_E1;
494 }
495 }
496
497 STATIC VOID
InterruptVector0x16ReadScancode(EFI_IA32_REGISTER_SET * Regs)498 InterruptVector0x16ReadScancode(EFI_IA32_REGISTER_SET *Regs)
499 {
500 UINT16 Key;
501
502 DEBUG (("XXX InterruptVector0x16ReadScancode()\n"));
503 DEBUG (("XXX KeyBufferHead = 0x%x KeyBufferTail = 0x%x\n", mBdaPtr->KeyBufferHead, mBdaPtr->KeyBufferTail));
504
505 do {
506 EnableInterrupts();
507 DisableInterrupts();
508 } while (mBdaPtr->KeyBufferHead == mBdaPtr->KeyBufferTail);
509
510 Key = *(UINT16 *)((UINT8 *)(UINTN)0x400 + mBdaPtr->KeyBufferHead);
511 Regs->X.AX = Key;
512 Regs->E.EFlags.ZF = 0;
513 switch (Regs->H.AL) {
514 case '\n':
515 DEBUG (("XXX InterruptVector0x16ReadScancode() Regs->H.AL=0%x '\\n'\n", Regs->H.AL));
516 break;
517 case '\r':
518 DEBUG (("XXX InterruptVector0x16ReadScancode() Regs->H.AL=0%x '\\r'\n", Regs->H.AL));
519 break;
520 default:
521 DEBUG (("XXX InterruptVector0x16ReadScancode() Regs->H.AL=0%x ('%c')\n", Regs->H.AL, Regs->H.AL));
522 break;
523 }
524 DEBUG (("XXX InterruptVector0x16ReadScancode() Regs->H.AH=0%x\n", Regs->H.AH));
525 DEBUG (("XXX InterruptVector0x16ReadScancode() Regs->X.AX=0%x\n", Regs->X.AX));
526
527 mBdaPtr->KeyBufferHead += 2;
528 if (mBdaPtr->KeyBufferHead == mBdaPtr->KeyBufferEnd)
529 mBdaPtr->KeyBufferHead = mBdaPtr->KeyBufferStart;
530
531 DEBUG (("XXX InterruptVector0x16ReadScancode() KeyBufferHead = 0x%x KeyBufferTail = 0x%x\n", mBdaPtr->KeyBufferHead, mBdaPtr->KeyBufferTail));
532 }
533
534 STATIC VOID
InterruptVector0x16PreviewScancode(EFI_IA32_REGISTER_SET * Regs)535 InterruptVector0x16PreviewScancode(EFI_IA32_REGISTER_SET *Regs)
536 {
537 UINT16 Key;
538
539 //DEBUG (("XXX InterruptVector0x16PreviewScancode()\n"));
540 //DEBUG (("XXX InterruptVector0x16PreviewScancode() KeyBufferHead = 0x%x KeyBufferTail = 0x%x\n", mBdaPtr->KeyBufferHead, mBdaPtr->KeyBufferTail));
541 if (mBdaPtr->KeyBufferHead == mBdaPtr->KeyBufferTail) {
542 Regs->E.EFlags.ZF = 1;
543 } else {
544 Regs->E.EFlags.ZF = 0;
545 Key = *(UINT16 *)((UINT8 *)(UINTN)0x400 + mBdaPtr->KeyBufferHead);
546 Regs->X.AX = Key;
547 switch (Regs->H.AL) {
548 case '\n':
549 // DEBUG (("XXX InterruptVector0x16PreviewScancode() Regs->H.AL=0%x '\\n'\n", Regs->H.AL));
550 break;
551 case '\r':
552 // DEBUG (("XXX InterruptVector0x16PreviewScancode() Regs->H.AL=0%x '\\r'\n", Regs->H.AL));
553 break;
554 default:
555 // DEBUG (("XXX InterruptVector0x16PreviewScancode() Regs->H.AL=0%x ('%c')\n", Regs->H.AL, Regs->H.AL));
556 break;
557 }
558 // DEBUG (("XXX InterruptVector0x16PreviewScancode() Regs->H.AH=0%x\n", Regs->H.AH));
559 // DEBUG (("XXX InterruptVector0x16PreviewScancode() Regs->X.AX=0%x\n", Regs->X.AX));
560 }
561 }
562
563 /*
564 * Keyboard I/O
565 */
566 VOID
InterruptVector0x16(EFI_IA32_REGISTER_SET * Regs)567 InterruptVector0x16(EFI_IA32_REGISTER_SET *Regs)
568 {
569 // DEBUG (("XXX InterruptVector0x16() Regs->H.AL=0%x\n", Regs->H.AL));
570 // DEBUG (("XXX InterruptVector0x16() Regs->H.AH=0%x\n", Regs->H.AH));
571 // DEBUG (("XXX InterruptVector0x16() Regs->X.AX=0%x\n", Regs->X.AX));
572
573 EnableInterrupts();
574 DisableInterrupts();
575
576 switch (Regs->H.AH) {
577 case 0x0: /* Read Keyboard Input */
578 // DEBUG (("XXX InterruptVector0x16() Read Keyboard Input\n"));
579 InterruptVector0x16ReadScancode(Regs);
580 break;
581 case 0x1: /* Query Keyboard Status / Preview Key */
582 // DEBUG (("XXX InterruptVector0x16() Query Keyboard Status / Preview Key\n"));
583 InterruptVector0x16PreviewScancode(Regs);
584 break;
585 case 0x2: /* Read Keyboard Shift Status */
586 // DEBUG (("XXX InterruptVector0x16() Read Keyboard Shift Status\n"));
587 Regs->H.AL = mBdaPtr->KeyboardStatus1;
588 DEBUG (("XXX Regs->H.AL = 0x%x\n", Regs->H.AL));
589 break;
590 case 0x3: /* Set Keyboard Typematic Rate */
591 break;
592 case 0x5: /* Store keycode */
593 Regs->H.AL = 1;
594 break;
595 case 0x10:
596 // DEBUG (("XXX InterruptVector0x16() Read Extended Keyboard Input\n"));
597 InterruptVector0x16ReadScancode(Regs);
598 break;
599 case 0x11: /* Query Extended Keyboard Status / Preview Key */
600 // DEBUG (("XXX InterruptVector0x16() Query Extended Keyboard Status / Preview Key\n"));
601 InterruptVector0x16PreviewScancode(Regs);
602 break;
603 case 0x12: /* Read Extended Keyboard Shift Status */
604 // DEBUG (("XXX InterruptVector0x16() Read Extended Keyboard Shift Status\n"));
605 Regs->H.AL = mBdaPtr->KeyboardStatus1;
606 Regs->H.AH = mBdaPtr->KeyboardStatus2;
607 break;
608 default:
609 DEBUG (("XXX InterruptVector0x16() Regs->H.AL=0%x\n", Regs->H.AL));
610 DEBUG (("XXX InterruptVector0x16() Regs->H.AH=0%x\n", Regs->H.AH));
611 DEBUG (("XXX InterruptVector0x16() Regs->X.AX=0%x\n", Regs->X.AX));
612 DEBUG (("XXX keyboard unhandled\n"));
613 // for (;;) ;
614 break;
615 }
616 }
617
618 VOID
KeyboardInitialize(VOID)619 KeyboardInitialize(VOID)
620 {
621 EFI_STATUS Status;
622 UINT8 CommandByte;
623 UINTN TryTime;
624
625 mBdaPtr->KeyBufferStart = 0x1E;
626 mBdaPtr->KeyBufferEnd = 0x3E;
627 mBdaPtr->KeyBufferHead = mBdaPtr->KeyBufferTail = mBdaPtr->KeyBufferStart;
628
629 mBdaPtr->KeyboardStatus3 = KBSF3_ENHANCED_KBD;
630
631 if ((KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) != 0) {
632 while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) {
633 Status = KeyboardRead(&CommandByte);
634 TryTime ++;
635 }
636
637 if (TryTime == KEYBOARD_MAX_TRY) {
638 return;
639 }
640 }
641
642 Status = KeyboardCommand(KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);
643 if (EFI_ERROR (Status)) {
644 return;
645 }
646
647 Status = KeyboardCommand(KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE);
648 if (EFI_ERROR (Status)) {
649 return;
650 }
651
652 Status = KeyboardCommand(KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST);
653 if (EFI_ERROR (Status)) {
654 return;
655 }
656
657 Status = KeyboardWaitForValue(0x55);
658 if (EFI_ERROR (Status)) {
659 return;
660 }
661
662 Status = KeyboardWrite(KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET);
663 if (EFI_ERROR (Status)) {
664 return;
665 }
666
667 Status = KeyboardWaitForValue(KEYBOARD_8048_RETURN_8042_ACK);
668 if (EFI_ERROR (Status)) {
669 return;
670 }
671
672 Status = KeyboardWrite(0x02); // scan code set 2
673 if (EFI_ERROR (Status)) {
674 return;
675 }
676
677 Status = KeyboardWaitForValue(KEYBOARD_8048_RETURN_8042_ACK);
678 if (EFI_ERROR (Status)) {
679 return;
680 }
681
682 Status = KeyboardWrite(KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA);
683 if (EFI_ERROR (Status)) {
684 return;
685 }
686
687 Status = KeyboardWaitForValue(KEYBOARD_8048_RETURN_8042_ACK);
688 if (EFI_ERROR (Status)) {
689 return;
690 }
691
692 Status = KeyboardCommand(KEYBOARD_8042_COMMAND_WRITE);
693 if (EFI_ERROR (Status)) {
694 return;
695 }
696
697 Status = KeyboardWrite(KEYBOARD_CMMBYTE_TRANSLATE |
698 KEYBOARD_CMMBYTE_DISABLE_AUX |
699 KEYBOARD_CMMBYTE_SELFTEST_OK |
700 KEYBOARD_CMMBYTE_ENABLE_KBINT);
701 if (EFI_ERROR (Status)) {
702 return;
703 }
704
705 DEBUG (("XXX KeyboardInitialize() done (0x%lx)\n", ReadTsc()));
706 }
707
708 VOID
InterruptVector0x09(EFI_IA32_REGISTER_SET * Regs)709 InterruptVector0x09(EFI_IA32_REGISTER_SET *Regs)
710 {
711 UINT8 Data;
712
713 DEBUG (("XXX InterruptVector0x09() (0x%lx)\n", ReadTsc()));
714
715 KeyboardCommand(KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);
716
717 if ((KeyReadStatusRegister() & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) != 0) {
718 Data = KeyReadDataRegister();
719 ProcessScancode(Data);
720 }
721
722 KeyboardCommand(KEYBOARD_8042_COMMAND_ENABLE_KEYBOARD_INTERFACE);
723
724 mLegacy8259->EndOfInterrupt(mLegacy8259, Efi8259Irq1);
725
726 DEBUG (("XXX InterruptVector0x09() done\n"));
727 }
728
729