TianoCore EDK2 master
Loading...
Searching...
No Matches
Ps2KbdCtrller.c
Go to the documentation of this file.
1
9#include "Ps2Keyboard.h"
10
11struct {
12 UINT8 ScanCode;
13 UINT16 EfiScanCode;
14 CHAR16 UnicodeChar;
15 CHAR16 ShiftUnicodeChar;
16} ConvertKeyboardScanCodeToEfiKey[] = {
17 {
18 0x01, // Escape
19 SCAN_ESC,
20 0x0000,
21 0x0000
22 },
23 {
24 0x02,
25 SCAN_NULL,
26 L'1',
27 L'!'
28 },
29 {
30 0x03,
31 SCAN_NULL,
32 L'2',
33 L'@'
34 },
35 {
36 0x04,
37 SCAN_NULL,
38 L'3',
39 L'#'
40 },
41 {
42 0x05,
43 SCAN_NULL,
44 L'4',
45 L'$'
46 },
47 {
48 0x06,
49 SCAN_NULL,
50 L'5',
51 L'%'
52 },
53 {
54 0x07,
55 SCAN_NULL,
56 L'6',
57 L'^'
58 },
59 {
60 0x08,
61 SCAN_NULL,
62 L'7',
63 L'&'
64 },
65 {
66 0x09,
67 SCAN_NULL,
68 L'8',
69 L'*'
70 },
71 {
72 0x0A,
73 SCAN_NULL,
74 L'9',
75 L'('
76 },
77 {
78 0x0B,
79 SCAN_NULL,
80 L'0',
81 L')'
82 },
83 {
84 0x0C,
85 SCAN_NULL,
86 L'-',
87 L'_'
88 },
89 {
90 0x0D,
91 SCAN_NULL,
92 L'=',
93 L'+'
94 },
95 {
96 0x0E, // BackSpace
97 SCAN_NULL,
98 0x0008,
99 0x0008
100 },
101 {
102 0x0F, // Tab
103 SCAN_NULL,
104 0x0009,
105 0x0009
106 },
107 {
108 0x10,
109 SCAN_NULL,
110 L'q',
111 L'Q'
112 },
113 {
114 0x11,
115 SCAN_NULL,
116 L'w',
117 L'W'
118 },
119 {
120 0x12,
121 SCAN_NULL,
122 L'e',
123 L'E'
124 },
125 {
126 0x13,
127 SCAN_NULL,
128 L'r',
129 L'R'
130 },
131 {
132 0x14,
133 SCAN_NULL,
134 L't',
135 L'T'
136 },
137 {
138 0x15,
139 SCAN_NULL,
140 L'y',
141 L'Y'
142 },
143 {
144 0x16,
145 SCAN_NULL,
146 L'u',
147 L'U'
148 },
149 {
150 0x17,
151 SCAN_NULL,
152 L'i',
153 L'I'
154 },
155 {
156 0x18,
157 SCAN_NULL,
158 L'o',
159 L'O'
160 },
161 {
162 0x19,
163 SCAN_NULL,
164 L'p',
165 L'P'
166 },
167 {
168 0x1a,
169 SCAN_NULL,
170 L'[',
171 L'{'
172 },
173 {
174 0x1b,
175 SCAN_NULL,
176 L']',
177 L'}'
178 },
179 {
180 0x1c, // Enter
181 SCAN_NULL,
182 0x000d,
183 0x000d
184 },
185 {
186 0x1d,
187 SCAN_NULL,
188 0x0000,
189 0x0000
190 },
191 {
192 0x1e,
193 SCAN_NULL,
194 L'a',
195 L'A'
196 },
197 {
198 0x1f,
199 SCAN_NULL,
200 L's',
201 L'S'
202 },
203 {
204 0x20,
205 SCAN_NULL,
206 L'd',
207 L'D'
208 },
209 {
210 0x21,
211 SCAN_NULL,
212 L'f',
213 L'F'
214 },
215 {
216 0x22,
217 SCAN_NULL,
218 L'g',
219 L'G'
220 },
221 {
222 0x23,
223 SCAN_NULL,
224 L'h',
225 L'H'
226 },
227 {
228 0x24,
229 SCAN_NULL,
230 L'j',
231 L'J'
232 },
233 {
234 0x25,
235 SCAN_NULL,
236 L'k',
237 L'K'
238 },
239 {
240 0x26,
241 SCAN_NULL,
242 L'l',
243 L'L'
244 },
245 {
246 0x27,
247 SCAN_NULL,
248 L';',
249 L':'
250 },
251 {
252 0x28,
253 SCAN_NULL,
254 L'\'',
255 L'"'
256 },
257 {
258 0x29,
259 SCAN_NULL,
260 L'`',
261 L'~'
262 },
263 {
264 0x2a, // Left Shift
265 SCAN_NULL,
266 0x0000,
267 0x0000
268 },
269 {
270 0x2b,
271 SCAN_NULL,
272 L'\\',
273 L'|'
274 },
275 {
276 0x2c,
277 SCAN_NULL,
278 L'z',
279 L'Z'
280 },
281 {
282 0x2d,
283 SCAN_NULL,
284 L'x',
285 L'X'
286 },
287 {
288 0x2e,
289 SCAN_NULL,
290 L'c',
291 L'C'
292 },
293 {
294 0x2f,
295 SCAN_NULL,
296 L'v',
297 L'V'
298 },
299 {
300 0x30,
301 SCAN_NULL,
302 L'b',
303 L'B'
304 },
305 {
306 0x31,
307 SCAN_NULL,
308 L'n',
309 L'N'
310 },
311 {
312 0x32,
313 SCAN_NULL,
314 L'm',
315 L'M'
316 },
317 {
318 0x33,
319 SCAN_NULL,
320 L',',
321 L'<'
322 },
323 {
324 0x34,
325 SCAN_NULL,
326 L'.',
327 L'>'
328 },
329 {
330 0x35,
331 SCAN_NULL,
332 L'/',
333 L'?'
334 },
335 {
336 0x36, // Right Shift
337 SCAN_NULL,
338 0x0000,
339 0x0000
340 },
341 {
342 0x37, // Numeric Keypad *
343 SCAN_NULL,
344 L'*',
345 L'*'
346 },
347 {
348 0x38, // Left Alt/Extended Right Alt
349 SCAN_NULL,
350 0x0000,
351 0x0000
352 },
353 {
354 0x39,
355 SCAN_NULL,
356 L' ',
357 L' '
358 },
359 {
360 0x3A, // CapsLock
361 SCAN_NULL,
362 0x0000,
363 0x0000
364 },
365 {
366 0x3B,
367 SCAN_F1,
368 0x0000,
369 0x0000
370 },
371 {
372 0x3C,
373 SCAN_F2,
374 0x0000,
375 0x0000
376 },
377 {
378 0x3D,
379 SCAN_F3,
380 0x0000,
381 0x0000
382 },
383 {
384 0x3E,
385 SCAN_F4,
386 0x0000,
387 0x0000
388 },
389 {
390 0x3F,
391 SCAN_F5,
392 0x0000,
393 0x0000
394 },
395 {
396 0x40,
397 SCAN_F6,
398 0x0000,
399 0x0000
400 },
401 {
402 0x41,
403 SCAN_F7,
404 0x0000,
405 0x0000
406 },
407 {
408 0x42,
409 SCAN_F8,
410 0x0000,
411 0x0000
412 },
413 {
414 0x43,
415 SCAN_F9,
416 0x0000,
417 0x0000
418 },
419 {
420 0x44,
421 SCAN_F10,
422 0x0000,
423 0x0000
424 },
425 {
426 0x45, // NumLock
427 SCAN_NULL,
428 0x0000,
429 0x0000
430 },
431 {
432 0x46, // ScrollLock
433 SCAN_NULL,
434 0x0000,
435 0x0000
436 },
437 {
438 0x47,
439 SCAN_HOME,
440 L'7',
441 L'7'
442 },
443 {
444 0x48,
445 SCAN_UP,
446 L'8',
447 L'8'
448 },
449 {
450 0x49,
451 SCAN_PAGE_UP,
452 L'9',
453 L'9'
454 },
455 {
456 0x4a,
457 SCAN_NULL,
458 L'-',
459 L'-'
460 },
461 {
462 0x4b,
463 SCAN_LEFT,
464 L'4',
465 L'4'
466 },
467 {
468 0x4c, // Numeric Keypad 5
469 SCAN_NULL,
470 L'5',
471 L'5'
472 },
473 {
474 0x4d,
475 SCAN_RIGHT,
476 L'6',
477 L'6'
478 },
479 {
480 0x4e,
481 SCAN_NULL,
482 L'+',
483 L'+'
484 },
485 {
486 0x4f,
487 SCAN_END,
488 L'1',
489 L'1'
490 },
491 {
492 0x50,
493 SCAN_DOWN,
494 L'2',
495 L'2'
496 },
497 {
498 0x51,
499 SCAN_PAGE_DOWN,
500 L'3',
501 L'3'
502 },
503 {
504 0x52,
505 SCAN_INSERT,
506 L'0',
507 L'0'
508 },
509 {
510 0x53,
511 SCAN_DELETE,
512 L'.',
513 L'.'
514 },
515 {
516 0x57,
517 SCAN_F11,
518 0x0000,
519 0x0000
520 },
521 {
522 0x58,
523 SCAN_F12,
524 0x0000,
525 0x0000
526 },
527 {
528 0x5B, // Left LOGO
529 SCAN_NULL,
530 0x0000,
531 0x0000
532 },
533 {
534 0x5C, // Right LOGO
535 SCAN_NULL,
536 0x0000,
537 0x0000
538 },
539 {
540 0x5D, // Menu key
541 SCAN_NULL,
542 0x0000,
543 0x0000
544 },
545 {
546 TABLE_END,
547 TABLE_END,
548 SCAN_NULL,
549 SCAN_NULL
550 },
551};
552
553//
554// The WaitForValue time out
555//
556UINTN mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
557
558BOOLEAN mEnableMouseInterface;
559
567UINTN
569 IN SCAN_CODE_QUEUE *Queue
570 )
571{
572 if (Queue->Head <= Queue->Tail) {
573 return Queue->Tail - Queue->Head;
574 } else {
575 return Queue->Tail + KEYBOARD_SCAN_CODE_MAX_COUNT - Queue->Head;
576 }
577}
578
593 IN SCAN_CODE_QUEUE *Queue,
594 IN UINTN Count,
595 OUT UINT8 *Buf
596 )
597{
598 UINTN Index;
599 UINTN Pos;
600
601 //
602 // check the valid range of parameter 'Count'
603 //
604 if (GetScancodeBufCount (Queue) < Count) {
605 return EFI_NOT_READY;
606 }
607
608 //
609 // retrieve the values
610 //
611 for (Index = 0, Pos = Queue->Head; Index < Count; Index++, Pos = (Pos + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
612 Buf[Index] = Queue->Buffer[Pos];
613 }
614
615 return EFI_SUCCESS;
616}
617
632 IN SCAN_CODE_QUEUE *Queue,
633 IN UINTN Count,
634 OUT UINT8 *Buf OPTIONAL
635 )
636{
637 UINTN Index;
638
639 //
640 // Check the valid range of parameter 'Count'
641 //
642 if (GetScancodeBufCount (Queue) < Count) {
643 return EFI_NOT_READY;
644 }
645
646 //
647 // Retrieve and remove the values
648 //
649 for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
650 if (Buf != NULL) {
651 Buf[Index] = Queue->Buffer[Queue->Head];
652 }
653 }
654
655 return EFI_SUCCESS;
656}
657
664VOID
666 IN SCAN_CODE_QUEUE *Queue,
667 IN UINT8 Scancode
668 )
669{
670 if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {
671 PopScancodeBufHead (Queue, 1, NULL);
672 }
673
674 Queue->Buffer[Queue->Tail] = Scancode;
675 Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;
676}
677
686UINT8
688 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
689 )
690
691{
692 return IoRead8 (ConsoleIn->DataRegisterAddress);
693}
694
702VOID
704 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
705 IN UINT8 Data
706 )
707{
708 IoWrite8 (ConsoleIn->DataRegisterAddress, Data);
709}
710
719UINT8
721 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
722 )
723{
724 return IoRead8 (ConsoleIn->StatusRegisterAddress);
725}
726
734VOID
736 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
737 IN UINT8 Data
738 )
739{
740 IoWrite8 (ConsoleIn->CommandRegisterAddress, Data);
741}
742
750VOID
752 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
753 IN CHAR16 *ErrMsg
754 )
755{
756 ConsoleIn->KeyboardErr = TRUE;
757}
758
770VOID
771EFIAPI
773 IN EFI_EVENT Event,
774 IN VOID *Context
775 )
776
777{
778 UINT8 Data;
779 EFI_TPL OldTpl;
780 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
781
782 ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
783
784 //
785 // Enter critical section
786 //
787 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
788
789 if (((KEYBOARD_CONSOLE_IN_DEV *)Context)->KeyboardErr) {
790 //
791 // Leave critical section and return
792 //
793 gBS->RestoreTPL (OldTpl);
794 return;
795 }
796
797 //
798 // To let KB driver support Hot plug, here should skip the 'resend' command for the case that
799 // KB is not connected to system. If KB is not connected to system, driver will find there's something
800 // error in the following code and wait for the input buffer empty, this waiting time should be short enough since
801 // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.
802 // Just skip the 'resend' process simply.
803 //
804
807 )
808 {
809 //
810 // Read one byte of the scan code and store it into the memory buffer
811 //
812 Data = KeyReadDataRegister (ConsoleIn);
813 PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);
814 }
815
816 KeyGetchar (ConsoleIn);
817
818 //
819 // Leave critical section and return
820 //
821 gBS->RestoreTPL (OldTpl);
822}
823
836 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
837 OUT UINT8 *Data
838 )
839
840{
841 UINT32 TimeOut;
842 UINT32 RegFilled;
843
844 TimeOut = 0;
845 RegFilled = 0;
846
847 //
848 // wait till output buffer full then perform the read
849 //
850 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
852 RegFilled = 1;
853 *Data = KeyReadDataRegister (ConsoleIn);
854 break;
855 }
856
857 MicroSecondDelay (30);
858 }
859
860 if (RegFilled == 0) {
861 return EFI_TIMEOUT;
862 }
863
864 return EFI_SUCCESS;
865}
866
879 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
880 IN UINT8 Data
881 )
882{
883 UINT32 TimeOut;
884 UINT32 RegEmptied;
885
886 TimeOut = 0;
887 RegEmptied = 0;
888
889 //
890 // wait for input buffer empty
891 //
892 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
893 if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
894 RegEmptied = 1;
895 break;
896 }
897
898 MicroSecondDelay (30);
899 }
900
901 if (RegEmptied == 0) {
902 return EFI_TIMEOUT;
903 }
904
905 //
906 // Write it
907 //
908 KeyWriteDataRegister (ConsoleIn, Data);
909
910 return EFI_SUCCESS;
911}
912
925 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
926 IN UINT8 Data
927 )
928{
929 UINT32 TimeOut;
930 UINT32 RegEmptied;
931
932 TimeOut = 0;
933 RegEmptied = 0;
934
935 //
936 // Wait For Input Buffer Empty
937 //
938 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
939 if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
940 RegEmptied = 1;
941 break;
942 }
943
944 MicroSecondDelay (30);
945 }
946
947 if (RegEmptied == 0) {
948 return EFI_TIMEOUT;
949 }
950
951 //
952 // issue the command
953 //
954 KeyWriteCommandRegister (ConsoleIn, Data);
955
956 //
957 // Wait For Input Buffer Empty again
958 //
959 RegEmptied = 0;
960 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
961 if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
962 RegEmptied = 1;
963 break;
964 }
965
966 MicroSecondDelay (30);
967 }
968
969 if (RegEmptied == 0) {
970 return EFI_TIMEOUT;
971 }
972
973 return EFI_SUCCESS;
974}
975
990 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
991 IN UINT8 Value
992 )
993{
994 UINT8 Data;
995 UINT32 TimeOut;
996 UINT32 SumTimeOut;
997 UINT32 GotIt;
998
999 GotIt = 0;
1000 TimeOut = 0;
1001 SumTimeOut = 0;
1002
1003 //
1004 // Make sure the initial value of 'Data' is different from 'Value'
1005 //
1006 Data = 0;
1007 if (Data == Value) {
1008 Data = 1;
1009 }
1010
1011 //
1012 // Read from 8042 (multiple times if needed)
1013 // until the expected value appears
1014 // use SumTimeOut to control the iteration
1015 //
1016 while (1) {
1017 //
1018 // Perform a read
1019 //
1020 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
1021 if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
1022 Data = KeyReadDataRegister (ConsoleIn);
1023 break;
1024 }
1025
1026 MicroSecondDelay (30);
1027 }
1028
1029 SumTimeOut += TimeOut;
1030
1031 if (Data == Value) {
1032 GotIt = 1;
1033 break;
1034 }
1035
1036 if (SumTimeOut >= mWaitForValueTimeOut) {
1037 break;
1038 }
1039 }
1040
1041 //
1042 // Check results
1043 //
1044 if (GotIt == 1) {
1045 return EFI_SUCCESS;
1046 } else {
1047 return EFI_TIMEOUT;
1048 }
1049}
1050
1062 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
1063 )
1064{
1065 EFI_STATUS Status;
1066 UINT8 Command;
1067
1068 //
1069 // Send keyboard command
1070 //
1071 Status = KeyboardWrite (ConsoleIn, 0xed);
1072 if (EFI_ERROR (Status)) {
1073 return Status;
1074 }
1075
1076 KeyboardWaitForValue (ConsoleIn, 0xfa);
1077
1078 //
1079 // Light configuration
1080 //
1081 Command = 0;
1082 if (ConsoleIn->CapsLock) {
1083 Command |= 4;
1084 }
1085
1086 if (ConsoleIn->NumLock) {
1087 Command |= 2;
1088 }
1089
1090 if (ConsoleIn->ScrollLock) {
1091 Command |= 1;
1092 }
1093
1094 Status = KeyboardWrite (ConsoleIn, Command);
1095
1096 if (EFI_ERROR (Status)) {
1097 return Status;
1098 }
1099
1100 KeyboardWaitForValue (ConsoleIn, 0xfa);
1101 return Status;
1102}
1103
1110VOID
1112 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
1113 OUT EFI_KEY_STATE *KeyState
1114 )
1115{
1116 KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID
1117 | (ConsoleIn->LeftCtrl ? EFI_LEFT_CONTROL_PRESSED : 0)
1118 | (ConsoleIn->RightCtrl ? EFI_RIGHT_CONTROL_PRESSED : 0)
1119 | (ConsoleIn->LeftAlt ? EFI_LEFT_ALT_PRESSED : 0)
1120 | (ConsoleIn->RightAlt ? EFI_RIGHT_ALT_PRESSED : 0)
1121 | (ConsoleIn->LeftShift ? EFI_LEFT_SHIFT_PRESSED : 0)
1122 | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED : 0)
1123 | (ConsoleIn->LeftLogo ? EFI_LEFT_LOGO_PRESSED : 0)
1124 | (ConsoleIn->RightLogo ? EFI_RIGHT_LOGO_PRESSED : 0)
1125 | (ConsoleIn->Menu ? EFI_MENU_KEY_PRESSED : 0)
1126 | (ConsoleIn->SysReq ? EFI_SYS_REQ_PRESSED : 0)
1127 ;
1128 KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID
1129 | (ConsoleIn->CapsLock ? EFI_CAPS_LOCK_ACTIVE : 0)
1130 | (ConsoleIn->NumLock ? EFI_NUM_LOCK_ACTIVE : 0)
1131 | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
1132 | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
1133 ;
1134}
1135
1144VOID
1146 IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
1147 )
1148{
1149 EFI_STATUS Status;
1150 UINT16 ScanCode;
1151 BOOLEAN Extend0;
1152 BOOLEAN Extend1;
1153 UINTN Index;
1154 EFI_KEY_DATA KeyData;
1155 LIST_ENTRY *Link;
1156 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
1157 //
1158 // 3 bytes most
1159 //
1160 UINT8 ScancodeArr[3];
1161 UINT32 ScancodeArrPos;
1162
1163 //
1164 // Check if there are enough bytes of scancode representing a single key
1165 // available in the buffer
1166 //
1167 while (TRUE) {
1168 Extend0 = FALSE;
1169 Extend1 = FALSE;
1170 ScancodeArrPos = 0;
1171 Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
1172 if (EFI_ERROR (Status)) {
1173 return;
1174 }
1175
1176 if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED0) {
1177 //
1178 // E0 to look ahead 2 bytes
1179 //
1180 Extend0 = TRUE;
1181 ScancodeArrPos = 1;
1182 Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
1183 if (EFI_ERROR (Status)) {
1184 return;
1185 }
1186 } else if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {
1187 //
1188 // E1 to look ahead 3 bytes
1189 //
1190 Extend1 = TRUE;
1191 ScancodeArrPos = 2;
1192 Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
1193 if (EFI_ERROR (Status)) {
1194 return;
1195 }
1196 }
1197
1198 //
1199 // if we reach this position, scancodes for a key is in buffer now,pop them
1200 //
1201 Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
1202 ASSERT_EFI_ERROR (Status);
1203
1204 //
1205 // store the last available byte, this byte of scancode will be checked
1206 //
1207 ScanCode = ScancodeArr[ScancodeArrPos];
1208
1209 if (!Extend1) {
1210 //
1211 // Check for special keys and update the driver state.
1212 //
1213 switch (ScanCode) {
1214 case SCANCODE_CTRL_MAKE:
1215 if (Extend0) {
1216 ConsoleIn->RightCtrl = TRUE;
1217 } else {
1218 ConsoleIn->LeftCtrl = TRUE;
1219 }
1220
1221 break;
1222 case SCANCODE_CTRL_BREAK:
1223 if (Extend0) {
1224 ConsoleIn->RightCtrl = FALSE;
1225 } else {
1226 ConsoleIn->LeftCtrl = FALSE;
1227 }
1228
1229 break;
1230
1231 case SCANCODE_ALT_MAKE:
1232 if (Extend0) {
1233 ConsoleIn->RightAlt = TRUE;
1234 } else {
1235 ConsoleIn->LeftAlt = TRUE;
1236 }
1237
1238 break;
1239 case SCANCODE_ALT_BREAK:
1240 if (Extend0) {
1241 ConsoleIn->RightAlt = FALSE;
1242 } else {
1243 ConsoleIn->LeftAlt = FALSE;
1244 }
1245
1246 break;
1247
1248 case SCANCODE_LEFT_SHIFT_MAKE:
1249 //
1250 // To avoid recognize PRNT_SCRN key as a L_SHIFT key
1251 // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code.
1252 // If it the second byte of the PRNT_ScRN skip it.
1253 //
1254 if (!Extend0) {
1255 ConsoleIn->LeftShift = TRUE;
1256 break;
1257 }
1258
1259 continue;
1260
1261 case SCANCODE_LEFT_SHIFT_BREAK:
1262 if (!Extend0) {
1263 ConsoleIn->LeftShift = FALSE;
1264 }
1265
1266 break;
1267
1268 case SCANCODE_RIGHT_SHIFT_MAKE:
1269 ConsoleIn->RightShift = TRUE;
1270 break;
1271 case SCANCODE_RIGHT_SHIFT_BREAK:
1272 ConsoleIn->RightShift = FALSE;
1273 break;
1274
1275 case SCANCODE_LEFT_LOGO_MAKE:
1276 ConsoleIn->LeftLogo = TRUE;
1277 break;
1278 case SCANCODE_LEFT_LOGO_BREAK:
1279 ConsoleIn->LeftLogo = FALSE;
1280 break;
1281
1282 case SCANCODE_RIGHT_LOGO_MAKE:
1283 ConsoleIn->RightLogo = TRUE;
1284 break;
1285 case SCANCODE_RIGHT_LOGO_BREAK:
1286 ConsoleIn->RightLogo = FALSE;
1287 break;
1288
1289 case SCANCODE_MENU_MAKE:
1290 ConsoleIn->Menu = TRUE;
1291 break;
1292 case SCANCODE_MENU_BREAK:
1293 ConsoleIn->Menu = FALSE;
1294 break;
1295
1296 case SCANCODE_SYS_REQ_MAKE:
1297 if (Extend0) {
1298 ConsoleIn->SysReq = TRUE;
1299 }
1300
1301 break;
1302 case SCANCODE_SYS_REQ_BREAK:
1303 if (Extend0) {
1304 ConsoleIn->SysReq = FALSE;
1305 }
1306
1307 break;
1308
1309 case SCANCODE_SYS_REQ_MAKE_WITH_ALT:
1310 ConsoleIn->SysReq = TRUE;
1311 break;
1312 case SCANCODE_SYS_REQ_BREAK_WITH_ALT:
1313 ConsoleIn->SysReq = FALSE;
1314 break;
1315
1316 case SCANCODE_CAPS_LOCK_MAKE:
1317 ConsoleIn->CapsLock = (BOOLEAN) !ConsoleIn->CapsLock;
1318 UpdateStatusLights (ConsoleIn);
1319 break;
1320 case SCANCODE_NUM_LOCK_MAKE:
1321 ConsoleIn->NumLock = (BOOLEAN) !ConsoleIn->NumLock;
1322 UpdateStatusLights (ConsoleIn);
1323 break;
1324 case SCANCODE_SCROLL_LOCK_MAKE:
1325 if (!Extend0) {
1326 ConsoleIn->ScrollLock = (BOOLEAN) !ConsoleIn->ScrollLock;
1327 UpdateStatusLights (ConsoleIn);
1328 }
1329
1330 break;
1331 }
1332 }
1333
1334 //
1335 // If this is above the valid range, ignore it
1336 //
1337 if (ScanCode >= SCANCODE_MAX_MAKE) {
1338 continue;
1339 } else {
1340 break;
1341 }
1342 }
1343
1344 //
1345 // Handle Ctrl+Alt+Del hotkey
1346 //
1347 if ((ConsoleIn->LeftCtrl || ConsoleIn->RightCtrl) &&
1348 (ConsoleIn->LeftAlt || ConsoleIn->RightAlt) &&
1349 (ScanCode == SCANCODE_DELETE_MAKE)
1350 )
1351 {
1352 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1353 }
1354
1355 //
1356 // Save the Shift/Toggle state
1357 //
1358 InitializeKeyState (ConsoleIn, &KeyData.KeyState);
1359 KeyData.Key.ScanCode = SCAN_NULL;
1360 KeyData.Key.UnicodeChar = CHAR_NULL;
1361
1362 //
1363 // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix
1364 //
1365 if (Extend0 && (ScanCode == 0x35)) {
1366 KeyData.Key.UnicodeChar = L'/';
1367 KeyData.Key.ScanCode = SCAN_NULL;
1368
1369 //
1370 // PAUSE shares the same scancode as that of NUM except PAUSE has E1 prefix
1371 //
1372 } else if (Extend1 && (ScanCode == SCANCODE_NUM_LOCK_MAKE)) {
1373 KeyData.Key.UnicodeChar = CHAR_NULL;
1374 KeyData.Key.ScanCode = SCAN_PAUSE;
1375
1376 //
1377 // PAUSE shares the same scancode as that of SCROLL except PAUSE (CTRL pressed) has E0 prefix
1378 //
1379 } else if (Extend0 && (ScanCode == SCANCODE_SCROLL_LOCK_MAKE)) {
1380 KeyData.Key.UnicodeChar = CHAR_NULL;
1381 KeyData.Key.ScanCode = SCAN_PAUSE;
1382
1383 //
1384 // PRNT_SCRN shares the same scancode as that of Key Pad "*" except PRNT_SCRN has E0 prefix
1385 //
1386 } else if (Extend0 && (ScanCode == SCANCODE_SYS_REQ_MAKE)) {
1387 KeyData.Key.UnicodeChar = CHAR_NULL;
1388 KeyData.Key.ScanCode = SCAN_NULL;
1389
1390 //
1391 // Except the above special case, all others can be handled by convert table
1392 //
1393 } else {
1394 for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index++) {
1395 if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {
1396 KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;
1397 KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
1398
1399 if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) &&
1400 (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar))
1401 {
1402 KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
1403 //
1404 // Need not return associated shift state if a class of printable characters that
1405 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
1406 //
1407 KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
1408 }
1409
1410 //
1411 // alphabetic key is affected by CapsLock State
1412 //
1413 if (ConsoleIn->CapsLock) {
1414 if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {
1415 KeyData.Key.UnicodeChar = (UINT16)(KeyData.Key.UnicodeChar - L'a' + L'A');
1416 } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {
1417 KeyData.Key.UnicodeChar = (UINT16)(KeyData.Key.UnicodeChar - L'A' + L'a');
1418 }
1419 }
1420
1421 break;
1422 }
1423 }
1424 }
1425
1426 //
1427 // distinguish numeric key pad keys' 'up symbol' and 'down symbol'
1428 //
1429 if ((ScanCode >= 0x47) && (ScanCode <= 0x53)) {
1430 if (ConsoleIn->NumLock && !(ConsoleIn->LeftShift || ConsoleIn->RightShift) && !Extend0) {
1431 KeyData.Key.ScanCode = SCAN_NULL;
1432 } else if ((ScanCode != 0x4a) && (ScanCode != 0x4e)) {
1433 KeyData.Key.UnicodeChar = CHAR_NULL;
1434 }
1435 }
1436
1437 //
1438 // If the key can not be converted then just return.
1439 //
1440 if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
1441 if (!ConsoleIn->IsSupportPartialKey) {
1442 return;
1443 }
1444 }
1445
1446 //
1447 // Signal KeyNotify process event if this key pressed matches any key registered.
1448 //
1449 for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {
1450 CurrentNotify = CR (
1451 Link,
1453 NotifyEntry,
1454 KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
1455 );
1456 if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
1457 //
1458 // The key notification function needs to run at TPL_CALLBACK
1459 // while current TPL is TPL_NOTIFY. It will be invoked in
1460 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
1461 //
1462 PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
1463 gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent);
1464 break;
1465 }
1466 }
1467
1468 PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, &KeyData);
1469}
1470
1484 IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
1485 IN BOOLEAN ExtendedVerification
1486 )
1487{
1488 EFI_STATUS Status;
1489 EFI_STATUS Status1;
1490 UINT8 CommandByte;
1491 EFI_PS2_POLICY_PROTOCOL *Ps2Policy;
1492 UINT32 TryTime;
1493
1494 Status = EFI_SUCCESS;
1495 mEnableMouseInterface = TRUE;
1496 TryTime = 0;
1497
1498 //
1499 // Get Ps2 policy to set this
1500 //
1501 gBS->LocateProtocol (
1502 &gEfiPs2PolicyProtocolGuid,
1503 NULL,
1504 (VOID **)&Ps2Policy
1505 );
1506
1509 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER,
1510 ConsoleIn->DevicePath
1511 );
1512
1513 //
1514 // Perform a read to cleanup the Status Register's
1515 // output buffer full bits within MAX TRY times
1516 //
1518 while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) {
1519 Status = KeyboardRead (ConsoleIn, &CommandByte);
1520 TryTime++;
1521 }
1522
1523 //
1524 // Exceed the max try times. The device may be error.
1525 //
1526 if (TryTime == KEYBOARD_MAX_TRY) {
1527 Status = EFI_DEVICE_ERROR;
1528 goto Done;
1529 }
1530 }
1531
1532 //
1533 // We should disable mouse interface during the initialization process
1534 // since mouse device output could block keyboard device output in the
1535 // 60H port of 8042 controller.
1536 //
1537 // So if we are not initializing 8042 controller for the
1538 // first time, we have to remember the previous mouse interface
1539 // enabling state
1540 //
1541 // Test the system flag in to determine whether this is the first
1542 // time initialization
1543 //
1545 if (!PcdGetBool (PcdFastPS2Detection)) {
1546 //
1547 // 8042 controller is already setup (by myself or by mouse driver):
1548 // See whether mouse interface is already enabled
1549 // which determines whether we should enable it later
1550 //
1551 //
1552 // Read the command byte of 8042 controller
1553 //
1554 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ);
1555 if (EFI_ERROR (Status)) {
1556 KeyboardError (ConsoleIn, L"\n\r");
1557 goto Done;
1558 }
1559
1560 Status = KeyboardRead (ConsoleIn, &CommandByte);
1561 if (EFI_ERROR (Status)) {
1562 KeyboardError (ConsoleIn, L"\n\r");
1563 goto Done;
1564 }
1565
1566 //
1567 // Test the mouse enabling bit
1568 //
1569 if ((CommandByte & 0x20) != 0) {
1570 mEnableMouseInterface = FALSE;
1571 } else {
1572 mEnableMouseInterface = TRUE;
1573 }
1574 } else {
1575 mEnableMouseInterface = FALSE;
1576 }
1577 } else {
1578 //
1579 // 8042 controller is not setup yet:
1580 // 8042 controller selftest;
1581 // Don't enable mouse interface later.
1582 //
1583 //
1584 // Disable keyboard and mouse interfaces
1585 //
1586 if (!PcdGetBool (PcdFastPS2Detection)) {
1587 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);
1588 if (EFI_ERROR (Status)) {
1589 KeyboardError (ConsoleIn, L"\n\r");
1590 goto Done;
1591 }
1592
1593 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE);
1594 if (EFI_ERROR (Status)) {
1595 KeyboardError (ConsoleIn, L"\n\r");
1596 goto Done;
1597 }
1598
1601 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,
1602 ConsoleIn->DevicePath
1603 );
1604 //
1605 // 8042 Controller Self Test
1606 //
1607 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST);
1608 if (EFI_ERROR (Status)) {
1609 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
1610 goto Done;
1611 }
1612
1613 Status = KeyboardWaitForValue (ConsoleIn, 0x55);
1614 if (EFI_ERROR (Status)) {
1615 KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r");
1616 goto Done;
1617 }
1618 }
1619
1620 //
1621 // Don't enable mouse interface later
1622 //
1623 mEnableMouseInterface = FALSE;
1624 }
1625
1626 if (Ps2Policy != NULL) {
1627 Ps2Policy->Ps2InitHardware (ConsoleIn->Handle);
1628 }
1629
1630 //
1631 // Write 8042 Command Byte, set System Flag
1632 // While at the same time:
1633 // 1. disable mouse interface,
1634 // 2. enable kbd interface,
1635 // 3. enable PC/XT kbd translation mode
1636 // 4. enable mouse and kbd interrupts
1637 //
1638 // ( Command Byte bits:
1639 // 7: Reserved
1640 // 6: PC/XT translation mode
1641 // 5: Disable Auxiliary device interface
1642 // 4: Disable keyboard interface
1643 // 3: Reserved
1644 // 2: System Flag
1645 // 1: Enable Auxiliary device interrupt
1646 // 0: Enable Keyboard interrupt )
1647 //
1648 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_WRITE);
1649 if (EFI_ERROR (Status)) {
1650 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
1651 goto Done;
1652 }
1653
1654 Status = KeyboardWrite (ConsoleIn, 0x67);
1655 if (EFI_ERROR (Status)) {
1656 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
1657 goto Done;
1658 }
1659
1660 //
1661 // Clear Memory Scancode Buffer
1662 //
1663 ConsoleIn->ScancodeQueue.Head = 0;
1664 ConsoleIn->ScancodeQueue.Tail = 0;
1665 ConsoleIn->EfiKeyQueue.Head = 0;
1666 ConsoleIn->EfiKeyQueue.Tail = 0;
1667 ConsoleIn->EfiKeyQueueForNotify.Head = 0;
1668 ConsoleIn->EfiKeyQueueForNotify.Tail = 0;
1669
1670 //
1671 // Reset the status indicators
1672 //
1673 ConsoleIn->CapsLock = FALSE;
1674 ConsoleIn->NumLock = FALSE;
1675 ConsoleIn->ScrollLock = FALSE;
1676 ConsoleIn->LeftCtrl = FALSE;
1677 ConsoleIn->RightCtrl = FALSE;
1678 ConsoleIn->LeftAlt = FALSE;
1679 ConsoleIn->RightAlt = FALSE;
1680 ConsoleIn->LeftShift = FALSE;
1681 ConsoleIn->RightShift = FALSE;
1682 ConsoleIn->LeftLogo = FALSE;
1683 ConsoleIn->RightLogo = FALSE;
1684 ConsoleIn->Menu = FALSE;
1685 ConsoleIn->SysReq = FALSE;
1686
1687 ConsoleIn->IsSupportPartialKey = FALSE;
1688 //
1689 // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,
1690 // and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected
1691 // to system. So we only do the real resetting for keyboard when user asks and there is a real KB connected t system,
1692 // and normally during booting an OS, it's skipped.
1693 //
1694 if (ExtendedVerification && CheckKeyboardConnect (ConsoleIn)) {
1695 //
1696 // Additional verifications for keyboard interface
1697 //
1698 //
1699 // Keyboard Interface Test
1700 //
1701 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST);
1702 if (EFI_ERROR (Status)) {
1703 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
1704 goto Done;
1705 }
1706
1707 Status = KeyboardWaitForValue (ConsoleIn, 0x00);
1708 if (EFI_ERROR (Status)) {
1710 ConsoleIn,
1711 L"Some specific value not acquired from 8042 controller!\n\r"
1712 );
1713 goto Done;
1714 }
1715
1716 //
1717 // Keyboard reset with a BAT(Basic Assurance Test)
1718 //
1719 Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_RESET);
1720 if (EFI_ERROR (Status)) {
1721 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
1722 goto Done;
1723 }
1724
1725 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
1726 if (EFI_ERROR (Status)) {
1727 KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
1728 goto Done;
1729 }
1730
1731 //
1732 // wait for BAT completion code
1733 //
1734 KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);
1735
1736 mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
1737
1738 //
1739 // Set Keyboard to use Scan Code Set 2
1740 //
1741 Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET);
1742 if (EFI_ERROR (Status)) {
1743 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
1744 goto Done;
1745 }
1746
1747 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
1748 if (EFI_ERROR (Status)) {
1749 KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
1750 goto Done;
1751 }
1752
1753 Status = KeyboardWrite (ConsoleIn, 0x02);
1754 if (EFI_ERROR (Status)) {
1755 KeyboardError (ConsoleIn, L"8042 controller data write error!!\n\r");
1756 goto Done;
1757 }
1758
1759 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
1760 if (EFI_ERROR (Status)) {
1761 KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
1762 goto Done;
1763 }
1764
1765 //
1766 // Clear Keyboard Scancode Buffer
1767 //
1768 Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA);
1769 if (EFI_ERROR (Status)) {
1770 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
1771 goto Done;
1772 }
1773
1774 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
1775 if (EFI_ERROR (Status)) {
1776 KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
1777 goto Done;
1778 }
1779
1780 //
1781 if (Ps2Policy != NULL) {
1782 if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_CAPSLOCK) == EFI_KEYBOARD_CAPSLOCK) {
1783 ConsoleIn->CapsLock = TRUE;
1784 }
1785
1786 if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_NUMLOCK) == EFI_KEYBOARD_NUMLOCK) {
1787 ConsoleIn->NumLock = TRUE;
1788 }
1789
1790 if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_SCROLLLOCK) == EFI_KEYBOARD_SCROLLLOCK) {
1791 ConsoleIn->ScrollLock = TRUE;
1792 }
1793 }
1794
1795 //
1796 // Update Keyboard Lights
1797 //
1798 Status = UpdateStatusLights (ConsoleIn);
1799 if (EFI_ERROR (Status)) {
1800 KeyboardError (ConsoleIn, L"Update keyboard status lights error!\n\r");
1801 goto Done;
1802 }
1803 }
1804
1805 //
1806 // At last, we can now enable the mouse interface if appropriate
1807 //
1808Done:
1809
1810 if (mEnableMouseInterface) {
1811 //
1812 // Enable mouse interface
1813 //
1814 Status1 = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE);
1815 if (EFI_ERROR (Status1)) {
1816 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
1817 return EFI_DEVICE_ERROR;
1818 }
1819 }
1820
1821 if (!EFI_ERROR (Status)) {
1822 return EFI_SUCCESS;
1823 } else {
1824 return EFI_DEVICE_ERROR;
1825 }
1826}
1827
1838BOOLEAN
1839EFIAPI
1841 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
1842 )
1843{
1844 EFI_STATUS Status;
1845 UINTN WaitForValueTimeOutBcakup;
1846
1847 //
1848 // enable keyboard itself and wait for its ack
1849 // If can't receive ack, Keyboard should not be connected.
1850 //
1851 if (!PcdGetBool (PcdFastPS2Detection)) {
1852 Status = KeyboardWrite (
1853 ConsoleIn,
1854 KEYBOARD_KBEN
1855 );
1856
1857 if (EFI_ERROR (Status)) {
1858 return FALSE;
1859 }
1860
1861 //
1862 // wait for 1s
1863 //
1864 WaitForValueTimeOutBcakup = mWaitForValueTimeOut;
1865 mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
1866 Status = KeyboardWaitForValue (
1867 ConsoleIn,
1868 KEYBOARD_CMDECHO_ACK
1869 );
1870 mWaitForValueTimeOut = WaitForValueTimeOutBcakup;
1871
1872 if (EFI_ERROR (Status)) {
1873 return FALSE;
1874 }
1875
1876 return TRUE;
1877 } else {
1878 return TRUE;
1879 }
1880}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
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
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
Definition: IoLibArmVirt.c:200
UINT8 EFIAPI IoRead8(IN UINTN Port)
Definition: IoLibArmVirt.c:175
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 ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
#define EFI_P_KEYBOARD_PC_CLEAR_BUFFER
Definition: PiStatusCode.h:392
BOOLEAN EFIAPI CheckKeyboardConnect(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn)
VOID InitializeKeyState(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, OUT EFI_KEY_STATE *KeyState)
UINT8 KeyReadStatusRegister(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn)
EFI_STATUS KeyboardCommand(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN UINT8 Data)
VOID EFIAPI KeyboardTimerHandler(IN EFI_EVENT Event, IN VOID *Context)
VOID KeyboardError(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN CHAR16 *ErrMsg)
EFI_STATUS KeyboardWaitForValue(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN UINT8 Value)
UINT8 ScanCode
follows value defined in Scan Code Set1
Definition: Ps2KbdCtrller.c:12
EFI_STATUS KeyboardRead(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, OUT UINT8 *Data)
VOID PushScancodeBufTail(IN SCAN_CODE_QUEUE *Queue, IN UINT8 Scancode)
UINT8 KeyReadDataRegister(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn)
EFI_STATUS KeyboardWrite(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN UINT8 Data)
EFI_STATUS UpdateStatusLights(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn)
UINTN GetScancodeBufCount(IN SCAN_CODE_QUEUE *Queue)
EFI_STATUS PopScancodeBufHead(IN SCAN_CODE_QUEUE *Queue, IN UINTN Count, OUT UINT8 *Buf OPTIONAL)
EFI_STATUS GetScancodeBufHead(IN SCAN_CODE_QUEUE *Queue, IN UINTN Count, OUT UINT8 *Buf)
VOID KeyWriteDataRegister(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN UINT8 Data)
EFI_STATUS InitKeyboard(IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN BOOLEAN ExtendedVerification)
VOID KeyWriteCommandRegister(IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN UINT8 Data)
VOID KeyGetchar(IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn)
VOID PushEfikeyBufTail(IN EFI_KEY_QUEUE *Queue, IN EFI_KEY_DATA *KeyData)
Definition: Ps2KbdTextIn.c:65
#define KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT
0 - Transmit is complete without timeout; 1 - Transmit is timeout without complete
Definition: Ps2Keyboard.h:194
#define KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA
0 - Output register has no data; 1 - Output register has data
Definition: Ps2Keyboard.h:189
#define KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG
Set to 0 after power on reset.
Definition: Ps2Keyboard.h:191
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiResetWarm
BOOLEAN IsKeyRegistered(IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData)
UINT32 KeyShiftState
EFI_INPUT_KEY Key
EFI_KEY_STATE KeyState