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