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