]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
Refine the comments.
[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
df0dcb5e 4Copyright (c) 2006 - 2007, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
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
67319626 18 UINT8 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
f3d1e940 552 }, \r
05fbd06d 553 {\r
554 TABLE_END,\r
555 TABLE_END,\r
556 SCAN_NULL,\r
557 SCAN_NULL\r
558 },\r
559};\r
560\r
561\r
562//\r
563// The WaitForValue time out\r
564//\r
819d1488 565UINTN mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
05fbd06d 566\r
4fd730b3 567BOOLEAN mEnableMouseInterface;\r
568\r
bcd70414 569/**\r
f713c4fe 570 Read data register .\r
bcd70414 571\r
572 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
573\r
574 @return return the value \r
575\r
576**/\r
05fbd06d 577UINT8\r
578KeyReadDataRegister (\r
579 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
580 )\r
05fbd06d 581\r
05fbd06d 582{\r
583 EFI_ISA_IO_PROTOCOL *IsaIo;\r
584 UINT8 Data;\r
585\r
586 //\r
587 // Use IsaIo protocol to perform IO operations\r
588 //\r
589 IsaIo = ConsoleIn->IsaIo;\r
590\r
591 IsaIo->Io.Read (\r
592 IsaIo,\r
593 EfiIsaIoWidthUint8,\r
594 ConsoleIn->DataRegisterAddress,\r
595 1,\r
596 &Data\r
597 );\r
598\r
599 return Data;\r
600}\r
601\r
bcd70414 602/**\r
f713c4fe 603 Write data register.\r
bcd70414 604\r
605 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
606 @param Data value wanted to be written\r
607\r
608**/\r
05fbd06d 609VOID\r
610KeyWriteDataRegister (\r
611 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
612 IN UINT8 Data\r
613 )\r
05fbd06d 614\r
05fbd06d 615{\r
616 EFI_ISA_IO_PROTOCOL *IsaIo;\r
617\r
618 //\r
619 // Use IsaIo protocol to perform IO operations\r
620 //\r
621 IsaIo = ConsoleIn->IsaIo;\r
622\r
623 IsaIo->Io.Write (\r
624 IsaIo,\r
625 EfiIsaIoWidthUint8,\r
626 ConsoleIn->DataRegisterAddress,\r
627 1,\r
628 &Data\r
629 );\r
630\r
05fbd06d 631}\r
632\r
bcd70414 633/**\r
f713c4fe 634 Read status register.\r
bcd70414 635\r
636 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
637\r
638 @return value in status register\r
639\r
640**/\r
05fbd06d 641UINT8\r
642KeyReadStatusRegister (\r
643 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
644 )\r
05fbd06d 645{\r
646 EFI_ISA_IO_PROTOCOL *IsaIo;\r
647 UINT8 Data;\r
648\r
649 //\r
650 // Use IsaIo protocol to perform IO operations\r
651 //\r
652 IsaIo = ConsoleIn->IsaIo;\r
653\r
654 IsaIo->Io.Read (\r
655 IsaIo,\r
656 EfiIsaIoWidthUint8,\r
657 ConsoleIn->StatusRegisterAddress,\r
658 1,\r
659 &Data\r
660 );\r
661\r
662 return Data;\r
663\r
664}\r
665\r
bcd70414 666/**\r
f713c4fe 667 Write command register .\r
bcd70414 668\r
669 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
670 @param Data The value wanted to be written\r
671\r
672**/\r
05fbd06d 673VOID\r
674KeyWriteCommandRegister (\r
675 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
676 IN UINT8 Data\r
677 )\r
05fbd06d 678{\r
679 EFI_ISA_IO_PROTOCOL *IsaIo;\r
680\r
681 //\r
682 // Use IsaIo protocol to perform IO operations\r
683 //\r
684 IsaIo = ConsoleIn->IsaIo;\r
685\r
686 IsaIo->Io.Write (\r
687 IsaIo,\r
688 EfiIsaIoWidthUint8,\r
689 ConsoleIn->CommandRegisterAddress,\r
690 1,\r
691 &Data\r
692 );\r
693\r
694}\r
695\r
bcd70414 696/**\r
f713c4fe 697 Display error message.\r
bcd70414 698\r
699 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
700 @param ErrMsg Unicode string of error message\r
701 \r
702**/\r
05fbd06d 703VOID\r
704KeyboardError (\r
705 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
706 IN CHAR16 *ErrMsg\r
707 )\r
05fbd06d 708{\r
709 ConsoleIn->KeyboardErr = TRUE;\r
05fbd06d 710}\r
711\r
bcd70414 712/**\r
05fbd06d 713 Timer event handler: read a series of scancodes from 8042\r
714 and put them into memory scancode buffer.\r
715 it read as much scancodes to either fill\r
716 the memory buffer or empty the keyboard buffer.\r
717 It is registered as running under TPL_NOTIFY\r
718\r
b6763e03 719 @param Event The timer event\r
720 @param Context A KEYBOARD_CONSOLE_IN_DEV pointer\r
05fbd06d 721\r
bcd70414 722**/\r
723VOID\r
724EFIAPI\r
725KeyboardTimerHandler (\r
726 IN EFI_EVENT Event,\r
727 IN VOID *Context\r
728 )\r
05fbd06d 729\r
05fbd06d 730{\r
731 UINT8 Data;\r
732 EFI_TPL OldTpl;\r
733 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
734\r
735 ConsoleIn = Context;\r
736\r
737 //\r
738 // Enter critical section\r
739 //\r
740 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
741\r
742 if (((KEYBOARD_CONSOLE_IN_DEV *) Context)->KeyboardErr) {\r
743 //\r
744 // Leave critical section and return\r
745 //\r
746 gBS->RestoreTPL (OldTpl);\r
747 return ;\r
748 }\r
b6763e03 749\r
05fbd06d 750 //\r
751 // To let KB driver support Hot plug, here should skip the 'resend' command for the case that\r
752 // KB is not connected to system. If KB is not connected to system, driver will find there's something\r
753 // error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since\r
754 // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
755 // Just skip the 'resend' process simply.\r
756 //\r
757\r
758 Data = 0;\r
759\r
760 //\r
761 // if there is no key present, just return\r
762 //\r
b6763e03 763 if ((KeyReadStatusRegister (Context) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) != KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {\r
05fbd06d 764 //\r
765 // Leave critical section and return\r
766 //\r
767 gBS->RestoreTPL (OldTpl);\r
768\r
769 return ;\r
770 }\r
771 //\r
772 // Read one byte of the scan code and store it into the memory buffer\r
773 //\r
774 if (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT) {\r
775\r
776 Data = KeyReadDataRegister (Context);\r
777 //\r
778 // put the scancode into the memory scancode buffer\r
779 //\r
780 ConsoleIn->ScancodeBufCount++;\r
781 ConsoleIn->ScancodeBufEndPos++;\r
782 if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
783 ConsoleIn->ScancodeBufEndPos = 0;\r
784 }\r
785\r
786 ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Data;\r
787\r
788 //\r
789 // Handle Alt+Ctrl+Del Key combination\r
790 //\r
791 switch (Data) {\r
792 case SCANCODE_CTRL_MAKE:\r
793 ConsoleIn->Ctrled = TRUE;\r
794 break;\r
795\r
796 case SCANCODE_CTRL_BREAK:\r
797 ConsoleIn->Ctrled = FALSE;\r
798 break;\r
799\r
800 case SCANCODE_ALT_MAKE:\r
801 ConsoleIn->Alted = TRUE;\r
802 break;\r
803\r
804 case SCANCODE_ALT_BREAK:\r
805 ConsoleIn->Alted = FALSE;\r
806 break;\r
807 }\r
808 //\r
809 // if Alt+Ctrl+Del, Reboot the System\r
810 //\r
811 if (ConsoleIn->Ctrled && ConsoleIn->Alted && Data == 0x53) {\r
812 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
813 }\r
814 }\r
815 //\r
816 // Leave critical section and return\r
817 //\r
818 gBS->RestoreTPL (OldTpl);\r
819\r
820 return ;\r
821}\r
822\r
bcd70414 823/**\r
824 Read several bytes from the scancode buffer without removing them.\r
825 This function is called to see if there are enough bytes of scancode\r
826 representing a single key.\r
827\r
f713c4fe 828 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
829 @param Count Number of bytes to be read\r
830 @param Buf Store the results\r
bcd70414 831\r
832 @retval EFI_SUCCESS success to scan the keyboard code\r
833 @retval EFI_NOT_READY invalid parameter\r
834**/\r
05fbd06d 835EFI_STATUS\r
836GetScancodeBufHead (\r
837 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
838 IN UINT32 Count,\r
839 OUT UINT8 *Buf\r
840 )\r
05fbd06d 841{\r
842 UINT32 Index;\r
843 UINT32 Pos;\r
844\r
845 Index = 0;\r
846 Pos = 0;\r
847\r
848 //\r
849 // check the valid range of parameter 'Count'\r
850 //\r
851 if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {\r
852 return EFI_NOT_READY;\r
853 }\r
854 //\r
855 // retrieve the values\r
856 //\r
857 for (Index = 0; Index < Count; Index++) {\r
858\r
859 if (Index == 0) {\r
860\r
861 Pos = ConsoleIn->ScancodeBufStartPos;\r
862 } else {\r
863\r
864 Pos = Pos + 1;\r
865 if (Pos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
866 Pos = 0;\r
867 }\r
868 }\r
869\r
870 Buf[Index] = ConsoleIn->ScancodeBuf[Pos];\r
871 }\r
872\r
873 return EFI_SUCCESS;\r
874}\r
875\r
bcd70414 876/**\r
877\r
878 Read & remove several bytes from the scancode buffer.\r
879 This function is usually called after GetScancodeBufHead()\r
880\r
f713c4fe 881 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
882 @param Count Number of bytes to be read\r
883 @param Buf Store the results\r
bcd70414 884\r
885 @retval EFI_SUCCESS success to scan the keyboard code\r
886 @retval EFI_NOT_READY invalid parameter\r
887**/\r
05fbd06d 888EFI_STATUS\r
889PopScancodeBufHead (\r
890 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
891 IN UINT32 Count,\r
892 OUT UINT8 *Buf\r
893 )\r
05fbd06d 894{\r
895 UINT32 Index;\r
896\r
897 Index = 0;\r
898\r
899 //\r
900 // Check the valid range of parameter 'Count'\r
901 //\r
902 if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {\r
903 return EFI_NOT_READY;\r
904 }\r
905 //\r
906 // Retrieve and remove the values\r
907 //\r
908 for (Index = 0; Index < Count; Index++) {\r
909\r
910 if (Index != 0) {\r
911\r
912 ConsoleIn->ScancodeBufStartPos++;\r
913 if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
914 ConsoleIn->ScancodeBufStartPos = 0;\r
915 }\r
916 }\r
917\r
918 Buf[Index] = ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufStartPos];\r
919 ConsoleIn->ScancodeBufCount--;\r
920 }\r
921\r
922 ConsoleIn->ScancodeBufStartPos++;\r
923 if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
924 ConsoleIn->ScancodeBufStartPos = 0;\r
925 }\r
926\r
927 return EFI_SUCCESS;\r
928}\r
929\r
bcd70414 930/**\r
f713c4fe 931 Read key value .\r
bcd70414 932\r
933 @param ConsoleIn - Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
934 @param Data - Pointer to outof buffer for keeping key value\r
935\r
936 @retval EFI_TIMEOUT Status resigter time out\r
937 @retval EFI_SUCCESS Success to read keyboard\r
938\r
939**/\r
05fbd06d 940EFI_STATUS\r
941KeyboardRead (\r
942 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
943 OUT UINT8 *Data\r
944 )\r
05fbd06d 945\r
05fbd06d 946{\r
947 UINT32 TimeOut;\r
948 UINT32 RegFilled;\r
949\r
950 TimeOut = 0;\r
951 RegFilled = 0;\r
952\r
953 //\r
954 // wait till output buffer full then perform the read\r
955 //\r
956 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
b6763e03 957 if (KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {\r
05fbd06d 958 RegFilled = 1;\r
959 *Data = KeyReadDataRegister (ConsoleIn);\r
960 break;\r
961 }\r
962\r
b6763e03 963 MicroSecondDelay (30);\r
05fbd06d 964 }\r
965\r
f713c4fe 966 if (RegFilled == 0) {\r
05fbd06d 967 return EFI_TIMEOUT;\r
968 }\r
969\r
970 return EFI_SUCCESS;\r
971}\r
972\r
bcd70414 973/**\r
974 write key to keyboard\r
975\r
976 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
977 @param Data value wanted to be written\r
978\r
b6763e03 979 @retval EFI_TIMEOUT The input buffer register is full for putting new value util timeout\r
980 @retval EFI_SUCCESS The new value is sucess put into input buffer register.\r
bcd70414 981\r
982**/\r
05fbd06d 983EFI_STATUS\r
984KeyboardWrite (\r
985 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
986 IN UINT8 Data\r
987 )\r
05fbd06d 988{\r
989 UINT32 TimeOut;\r
990 UINT32 RegEmptied;\r
991\r
992 TimeOut = 0;\r
993 RegEmptied = 0;\r
994\r
995 //\r
996 // wait for input buffer empty\r
997 //\r
998 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
f713c4fe 999 if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {\r
05fbd06d 1000 RegEmptied = 1;\r
1001 break;\r
1002 }\r
1003\r
b6763e03 1004 MicroSecondDelay (30);\r
05fbd06d 1005 }\r
1006\r
f713c4fe 1007 if (RegEmptied == 0) {\r
05fbd06d 1008 return EFI_TIMEOUT;\r
1009 }\r
1010 //\r
1011 // Write it\r
1012 //\r
1013 KeyWriteDataRegister (ConsoleIn, Data);\r
1014\r
1015 return EFI_SUCCESS;\r
1016}\r
1017\r
bcd70414 1018/**\r
f713c4fe 1019 Issue keyboard command.\r
bcd70414 1020\r
1021 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
1022 @param Data The buff holding the command \r
1023\r
1024 @retval EFI_TIMEOUT Keyboard is not ready to issuing \r
1025 @retval EFI_SUCCESS Success to issue keyboard command\r
1026\r
1027**/\r
05fbd06d 1028EFI_STATUS\r
1029KeyboardCommand (\r
1030 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
1031 IN UINT8 Data\r
1032 )\r
05fbd06d 1033{\r
1034 UINT32 TimeOut;\r
1035 UINT32 RegEmptied;\r
1036\r
1037 TimeOut = 0;\r
1038 RegEmptied = 0;\r
1039\r
1040 //\r
1041 // Wait For Input Buffer Empty\r
1042 //\r
1043 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
f713c4fe 1044 if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {\r
05fbd06d 1045 RegEmptied = 1;\r
1046 break;\r
1047 }\r
1048\r
b6763e03 1049 MicroSecondDelay (30);\r
05fbd06d 1050 }\r
1051\r
f713c4fe 1052 if (RegEmptied == 0) {\r
05fbd06d 1053 return EFI_TIMEOUT;\r
1054 }\r
1055 //\r
1056 // issue the command\r
1057 //\r
1058 KeyWriteCommandRegister (ConsoleIn, Data);\r
1059\r
1060 //\r
1061 // Wait For Input Buffer Empty again\r
1062 //\r
1063 RegEmptied = 0;\r
1064 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
f713c4fe 1065 if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {\r
05fbd06d 1066 RegEmptied = 1;\r
1067 break;\r
1068 }\r
1069\r
b6763e03 1070 MicroSecondDelay (30);\r
05fbd06d 1071 }\r
1072\r
f713c4fe 1073 if (RegEmptied == 0) {\r
05fbd06d 1074 return EFI_TIMEOUT;\r
1075 }\r
1076\r
1077 return EFI_SUCCESS;\r
1078}\r
1079\r
bcd70414 1080/**\r
1081 wait for a specific value to be presented on\r
1082 8042 Data register by keyboard and then read it,\r
1083 used in keyboard commands ack\r
1084\r
1085 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
1086 @param Value the value wanted to be waited.\r
1087\r
1088 @retval EFI_TIMEOUT Fail to get specific value in given time\r
1089 @retval EFI_SUCCESS Success to get specific value in given time.\r
1090 \r
1091**/\r
05fbd06d 1092EFI_STATUS\r
1093KeyboardWaitForValue (\r
1094 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
1095 IN UINT8 Value\r
1096 )\r
05fbd06d 1097{\r
1098 UINT8 Data;\r
1099 UINT32 TimeOut;\r
1100 UINT32 SumTimeOut;\r
1101 UINT32 GotIt;\r
1102\r
1103 GotIt = 0;\r
1104 TimeOut = 0;\r
1105 SumTimeOut = 0;\r
1106\r
1107 //\r
1108 // Make sure the initial value of 'Data' is different from 'Value'\r
1109 //\r
1110 Data = 0;\r
1111 if (Data == Value) {\r
1112 Data = 1;\r
1113 }\r
1114 //\r
1115 // Read from 8042 (multiple times if needed)\r
1116 // until the expected value appears\r
1117 // use SumTimeOut to control the iteration\r
1118 //\r
1119 while (1) {\r
1120 //\r
1121 // Perform a read\r
1122 //\r
1123 for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
1124 if (KeyReadStatusRegister (ConsoleIn) & 0x01) {\r
1125 Data = KeyReadDataRegister (ConsoleIn);\r
1126 break;\r
1127 }\r
1128\r
b6763e03 1129 MicroSecondDelay (30);\r
05fbd06d 1130 }\r
1131\r
1132 SumTimeOut += TimeOut;\r
1133\r
1134 if (Data == Value) {\r
1135 GotIt = 1;\r
1136 break;\r
1137 }\r
1138\r
1139 if (SumTimeOut >= mWaitForValueTimeOut) {\r
1140 break;\r
1141 }\r
1142 }\r
1143 //\r
1144 // Check results\r
1145 //\r
b6763e03 1146 if (GotIt == 1) {\r
05fbd06d 1147 return EFI_SUCCESS;\r
1148 } else {\r
1149 return EFI_TIMEOUT;\r
1150 }\r
1151\r
1152}\r
1153\r
bcd70414 1154/**\r
05fbd06d 1155 Show keyboard status lights according to\r
1156 indicators in ConsoleIn.\r
1157\r
bcd70414 1158 @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV\r
1159 \r
b6763e03 1160 @return status of updating keyboard register\r
05fbd06d 1161\r
bcd70414 1162**/\r
1163EFI_STATUS\r
1164UpdateStatusLights (\r
1165 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
1166 )\r
05fbd06d 1167{\r
1168 EFI_STATUS Status;\r
1169 UINT8 Command;\r
1170\r
1171 //\r
1172 // Send keyboard command\r
1173 //\r
1174 Status = KeyboardWrite (ConsoleIn, 0xed);\r
1175 if (EFI_ERROR (Status)) {\r
1176 return Status;\r
1177 }\r
1178\r
1179 KeyboardWaitForValue (ConsoleIn, 0xfa);\r
1180\r
1181 //\r
1182 // Light configuration\r
1183 //\r
1184 Command = 0;\r
1185 if (ConsoleIn->CapsLock) {\r
1186 Command |= 4;\r
1187 }\r
1188\r
1189 if (ConsoleIn->NumLock) {\r
1190 Command |= 2;\r
1191 }\r
1192\r
1193 if (ConsoleIn->ScrollLock) {\r
1194 Command |= 1;\r
1195 }\r
1196\r
1197 Status = KeyboardWrite (ConsoleIn, Command);\r
1198\r
1199 if (EFI_ERROR (Status)) {\r
1200 return Status;\r
1201 }\r
1202\r
1203 KeyboardWaitForValue (ConsoleIn, 0xfa);\r
1204 return Status;\r
1205}\r
1206\r
bcd70414 1207/**\r
05fbd06d 1208 Get scancode from scancode buffer\r
1209 and translate into EFI-scancode and unicode defined by EFI spec\r
1210 The function is always called in TPL_NOTIFY\r
1211\r
bcd70414 1212 @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer\r
05fbd06d 1213\r
b6763e03 1214 @retval EFI_NOT_READY Input from console not ready yet.\r
1215 @retval EFI_SUCCESS Function executed successfully.\r
05fbd06d 1216\r
bcd70414 1217**/\r
1218EFI_STATUS\r
1219KeyGetchar (\r
1220 IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
1221 )\r
05fbd06d 1222{\r
1223 EFI_STATUS Status;\r
1224 UINT8 ScanCode;\r
1225 UINT8 Readed;\r
1226 BOOLEAN Extended;\r
1227 UINT8 ScancodeArr[4];\r
1228 UINTN Index;\r
1229 //\r
1230 // 4 bytes most\r
1231 //\r
1232 UINT32 ScancodeArrPos;\r
1233 //\r
1234 // point to the current position in ScancodeArr\r
1235 //\r
1236\r
1237 Readed = 0;\r
1238 Extended = FALSE;\r
1239 ScancodeArrPos = 0;\r
1240\r
1241 //\r
1242 // Read one byte of the scan code and store it into the memory buffer\r
1243 // This block of code is added to insert an action that is equivalent to\r
1244 // the timer event handling function, so as to increase the frequency of\r
1245 // detecting the availability of keys. Timer event has a max frequency of\r
1246 // 18Hz which is insufficient\r
1247 //\r
1248 //\r
1249 // To let KB driver support Hot plug, here should skip the 'resend' command for the case that\r
1250 // KB is not connected to system. If KB is not connected to system, driver will find there's something\r
1251 // error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since\r
1252 // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.\r
1253 // Just skip the 'resend' process simply.\r
1254 //\r
1255\r
1256\r
1257 if (((KeyReadStatusRegister (ConsoleIn) & 0x21) == 0x1) && (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT)) {\r
1258\r
1259 Readed = KeyReadDataRegister (ConsoleIn);\r
1260 //\r
1261 // put the scancode into the memory scancode buffer\r
1262 //\r
1263 ConsoleIn->ScancodeBufCount++;\r
1264 ConsoleIn->ScancodeBufEndPos++;\r
1265 if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {\r
1266 ConsoleIn->ScancodeBufEndPos = 0;\r
1267 }\r
1268\r
1269 ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Readed;\r
1270\r
1271 //\r
1272 // Handle Alt+Ctrl+Del Key combination\r
1273 //\r
1274 switch (Readed) {\r
1275\r
1276 case SCANCODE_CTRL_MAKE:\r
1277 ConsoleIn->Ctrled = TRUE;\r
1278 break;\r
1279\r
1280 case SCANCODE_CTRL_BREAK:\r
1281 ConsoleIn->Ctrled = FALSE;\r
1282 break;\r
1283\r
1284 case SCANCODE_ALT_MAKE:\r
1285 ConsoleIn->Alted = TRUE;\r
1286 break;\r
1287\r
1288 case SCANCODE_ALT_BREAK:\r
1289 ConsoleIn->Alted = FALSE;\r
1290 break;\r
1291 }\r
1292 //\r
1293 // if Alt+Ctrl+Del, Reboot the System\r
1294 //\r
1295 if (ConsoleIn->Ctrled && ConsoleIn->Alted && Readed == 0x53) {\r
1296 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
1297 }\r
1298 }\r
1299 //\r
1300 // Check if there are enough bytes of scancode representing a single key\r
1301 // available in the buffer\r
1302 //\r
b6763e03 1303 while (TRUE) {\r
05fbd06d 1304\r
1305 Status = GetScancodeBufHead (ConsoleIn, 1, ScancodeArr);\r
1306 ScancodeArrPos = 0;\r
1307 if (EFI_ERROR (Status)) {\r
1308 return EFI_NOT_READY;\r
1309 }\r
1310\r
1311 if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {\r
1312 Extended = TRUE;\r
1313 Status = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);\r
1314 ScancodeArrPos = 1;\r
1315 if (EFI_ERROR (Status)) {\r
1316 return EFI_NOT_READY;\r
1317 }\r
1318 }\r
1319 //\r
1320 // Checks for key scancode for PAUSE:E1-1D/45-E1/9D-C5\r
1321 // if present, ignore them\r
1322 //\r
1323 if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {\r
1324\r
1325 Status = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);\r
1326 ScancodeArrPos = 1;\r
1327\r
1328 if (EFI_ERROR (Status)) {\r
1329 return EFI_NOT_READY;\r
1330 }\r
1331\r
1332 Status = GetScancodeBufHead (ConsoleIn, 3, ScancodeArr);\r
1333 ScancodeArrPos = 2;\r
1334\r
1335 if (EFI_ERROR (Status)) {\r
1336 return EFI_NOT_READY;\r
1337 }\r
1338\r
1339 PopScancodeBufHead (ConsoleIn, 3, ScancodeArr);\r
1340 return EFI_NOT_READY;\r
1341 }\r
1342 //\r
1343 // if we reach this position, scancodes for a key is in buffer now,pop them\r
1344 //\r
1345 Status = PopScancodeBufHead (ConsoleIn, ScancodeArrPos + 1, ScancodeArr);\r
1346 if (EFI_ERROR (Status)) {\r
1347 return EFI_NOT_READY;\r
1348 }\r
1349 //\r
1350 // store the last available byte, this byte of scancode will be checked\r
1351 //\r
1352 ScanCode = ScancodeArr[ScancodeArrPos];\r
1353\r
1354 //\r
1355 // Check for special keys and update the driver state.\r
1356 //\r
1357 switch (ScanCode) {\r
1358\r
1359 case SCANCODE_CTRL_MAKE:\r
1360 ConsoleIn->Ctrl = TRUE;\r
1361 break;\r
1362\r
1363 case SCANCODE_CTRL_BREAK:\r
1364 ConsoleIn->Ctrl = FALSE;\r
1365 break;\r
1366\r
1367 case SCANCODE_ALT_MAKE:\r
1368 ConsoleIn->Alt = TRUE;\r
1369 break;\r
1370\r
1371 case SCANCODE_ALT_BREAK:\r
1372 ConsoleIn->Alt = FALSE;\r
1373 break;\r
1374\r
1375 case SCANCODE_LEFT_SHIFT_MAKE:\r
f3d1e940 1376 if (!Extended) {\r
1377 ConsoleIn->Shift = TRUE;\r
1378 ConsoleIn->LeftShift = TRUE;\r
1379 } \r
1380 break;\r
05fbd06d 1381 case SCANCODE_RIGHT_SHIFT_MAKE:\r
1382 if (!Extended) {\r
1383 ConsoleIn->Shift = TRUE;\r
f3d1e940 1384 ConsoleIn->RightShift = TRUE;\r
05fbd06d 1385 }\r
1386 break;\r
1387\r
1388 case SCANCODE_LEFT_SHIFT_BREAK:\r
f3d1e940 1389 if (!Extended) {\r
1390 ConsoleIn->Shift = FALSE;\r
1391 ConsoleIn->LeftShift = FALSE;\r
1392 } else {\r
1393 ConsoleIn->SysReq = FALSE;\r
1394 } \r
1395 break;\r
05fbd06d 1396 case SCANCODE_RIGHT_SHIFT_BREAK:\r
1397 if (!Extended) {\r
1398 ConsoleIn->Shift = FALSE;\r
f3d1e940 1399 ConsoleIn->RightShift = FALSE;\r
05fbd06d 1400 }\r
1401 break;\r
1402\r
f3d1e940 1403 case SCANCODE_LEFT_LOGO_MAKE:\r
1404 ConsoleIn->LeftLogo = TRUE;\r
1405 break; \r
1406 case SCANCODE_LEFT_LOGO_BREAK:\r
1407 ConsoleIn->LeftLogo = FALSE;\r
1408 break; \r
1409 case SCANCODE_RIGHT_LOGO_MAKE:\r
1410 ConsoleIn->RightLogo = TRUE;\r
1411 break;\r
1412 case SCANCODE_RIGHT_LOGO_BREAK:\r
1413 ConsoleIn->RightLogo = FALSE;\r
1414 break; \r
1415 case SCANCODE_MENU_MAKE:\r
1416 ConsoleIn->Menu = TRUE;\r
1417 break;\r
1418 case SCANCODE_MENU_BREAK:\r
1419 ConsoleIn->Menu = FALSE;\r
1420 break; \r
1421 case SCANCODE_SYS_REQ_MAKE:\r
1422 if (Extended) {\r
1423 ConsoleIn->SysReq = TRUE;\r
1424 }\r
05fbd06d 1425 case SCANCODE_CAPS_LOCK_MAKE:\r
1426 ConsoleIn->CapsLock = (BOOLEAN)!ConsoleIn->CapsLock;\r
1427 UpdateStatusLights (ConsoleIn);\r
1428 break;\r
1429\r
1430 case SCANCODE_NUM_LOCK_MAKE:\r
1431 ConsoleIn->NumLock = (BOOLEAN)!ConsoleIn->NumLock;\r
1432 UpdateStatusLights (ConsoleIn);\r
1433 break;\r
1434\r
1435 case SCANCODE_SCROLL_LOCK_MAKE:\r
1436 ConsoleIn->ScrollLock = (BOOLEAN)!ConsoleIn->ScrollLock;\r
1437 UpdateStatusLights (ConsoleIn);\r
1438 break;\r
1439 }\r
1440 //\r
1441 // If this is a BREAK Key or above the valid range, ignore it\r
1442 //\r
1443 if (ScanCode >= SCANCODE_MAX_MAKE) {\r
1444 continue;\r
1445 } else {\r
1446 break;\r
1447 }\r
1448 }\r
1449 //\r
05fbd06d 1450 // Treat Numeric Key Pad "/" specially\r
1451 //\r
1452 if (Extended && ScanCode == 0x35) {\r
1453 ConsoleIn->Key.ScanCode = SCAN_NULL;\r
b6763e03 1454 ConsoleIn->Key.UnicodeChar = L'/';\r
05fbd06d 1455 return EFI_SUCCESS;\r
1456 }\r
1457 //\r
1458 // Convert Keyboard ScanCode into an EFI Key\r
1459 //\r
1460 for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {\r
1461 if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {\r
1462 ConsoleIn->Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;\r
1463 if (ConsoleIn->Shift) {\r
1464 ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
f3d1e940 1465 //\r
1466 // Need not return associated shift state if a class of printable characters that\r
1467 // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'\r
1468 //\r
b6763e03 1469 if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {\r
f3d1e940 1470 ConsoleIn->LeftShift = FALSE;\r
1471 ConsoleIn->RightShift = FALSE;\r
1472 }\r
05fbd06d 1473 } else {\r
1474 ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
1475 }\r
1476 //\r
1477 // alphabetic key is affected by CapsLock State\r
1478 //\r
1479 if (ConsoleIn->CapsLock) {\r
b6763e03 1480 if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') {\r
05fbd06d 1481 ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;\r
b6763e03 1482 } else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {\r
05fbd06d 1483 ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;\r
1484 }\r
1485 }\r
1f771698 1486 //\r
1487 // Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
1488 //\r
1489 if (ConsoleIn->Ctrled) {\r
b6763e03 1490 if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') {\r
1491 ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - L'a' + 1);\r
1492 } else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {\r
1493 ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - L'A' + 1);\r
1f771698 1494 }\r
1495 }\r
05fbd06d 1496\r
1497 break;\r
1498 }\r
1499 }\r
1500\r
1501 //\r
1502 // distinguish numeric key pad keys' 'up symbol' and 'down symbol'\r
1503 //\r
1504 if (ScanCode >= 0x47 && ScanCode <= 0x53) {\r
1505\r
1506 if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {\r
1507 ConsoleIn->Key.ScanCode = SCAN_NULL;\r
1508 } else if (ScanCode != 0x4a && ScanCode != 0x4e) {\r
b6763e03 1509 ConsoleIn->Key.UnicodeChar = 0x0000;\r
05fbd06d 1510 }\r
1511 }\r
1512 //\r
1513 // If the key can not be converted then just return.\r
1514 //\r
b6763e03 1515 if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x0000) {\r
05fbd06d 1516 return EFI_NOT_READY;\r
1517 }\r
1518\r
f3d1e940 1519 //\r
1520 // Save the Shift/Toggle state\r
1521 //\r
1522 if (ConsoleIn->Ctrl) {\r
f713c4fe 1523 ConsoleIn->KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_CONTROL_PRESSED : EFI_LEFT_CONTROL_PRESSED;\r
f3d1e940 1524 } \r
1525 if (ConsoleIn->Alt) { \r
f713c4fe 1526 ConsoleIn->KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_ALT_PRESSED : EFI_LEFT_ALT_PRESSED;\r
f3d1e940 1527 } \r
1528 if (ConsoleIn->LeftShift) { \r
1529 ConsoleIn->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
1530 } \r
1531 if (ConsoleIn->RightShift) { \r
1532 ConsoleIn->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
1533 } \r
1534 if (ConsoleIn->LeftLogo) { \r
1535 ConsoleIn->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;\r
1536 } \r
1537 if (ConsoleIn->RightLogo) { \r
1538 ConsoleIn->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;\r
1539 } \r
1540 if (ConsoleIn->Menu) { \r
1541 ConsoleIn->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;\r
1542 } \r
1543 if (ConsoleIn->SysReq) { \r
1544 ConsoleIn->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
1545 } \r
1546 if (ConsoleIn->CapsLock) {\r
1547 ConsoleIn->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
1548 }\r
1549 if (ConsoleIn->NumLock) {\r
1550 ConsoleIn->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
1551 }\r
1552 if (ConsoleIn->ScrollLock) {\r
1553 ConsoleIn->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
1554 }\r
1555\r
05fbd06d 1556 return EFI_SUCCESS;\r
1557}\r
1558\r
bcd70414 1559/**\r
f713c4fe 1560 Perform 8042 controller and keyboard Initialization. \r
05fbd06d 1561 If ExtendedVerification is TRUE, do additional test for\r
1562 the keyboard interface\r
1563\r
bcd70414 1564 @param ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer\r
1565 @param ExtendedVerification - indicates a thorough initialization\r
05fbd06d 1566\r
bcd70414 1567 @retval EFI_DEVICE_ERROR Fail to init keyboard\r
1568 @retval EFI_SUCCESS Success to init keyboard\r
1569**/\r
1570EFI_STATUS\r
1571InitKeyboard (\r
1572 IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,\r
1573 IN BOOLEAN ExtendedVerification\r
1574 )\r
05fbd06d 1575{\r
1576 EFI_STATUS Status;\r
1577 EFI_STATUS Status1;\r
1578 UINT8 CommandByte;\r
05fbd06d 1579 EFI_PS2_POLICY_PROTOCOL *Ps2Policy;\r
05f89b17 1580 UINT32 TryTime;\r
05fbd06d 1581\r
05f89b17 1582 Status = EFI_SUCCESS;\r
4fd730b3 1583 mEnableMouseInterface = TRUE;\r
05f89b17 1584 TryTime = 0;\r
05fbd06d 1585\r
1586 //\r
1587 // Get Ps2 policy to set this\r
1588 //\r
05f89b17
LG
1589 gBS->LocateProtocol (\r
1590 &gEfiPs2PolicyProtocolGuid,\r
1591 NULL,\r
1592 (VOID **) &Ps2Policy\r
1593 );\r
05fbd06d 1594\r
1595 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1596 EFI_PROGRESS_CODE,\r
1597 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER,\r
1598 ConsoleIn->DevicePath\r
1599 );\r
1600\r
1601 //\r
1602 // Perform a read to cleanup the Status Register's\r
05f89b17 1603 // output buffer full bits within MAX TRY times\r
05fbd06d 1604 //\r
05f89b17 1605 while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) {\r
05fbd06d 1606 Status = KeyboardRead (ConsoleIn, &CommandByte);\r
05f89b17
LG
1607 TryTime ++;\r
1608 }\r
1609 //\r
1610 // Exceed the max try times. The device may be error.\r
1611 //\r
1612 if (TryTime == KEYBOARD_MAX_TRY) {\r
1613 Status = EFI_DEVICE_ERROR;\r
1614 goto Done;\r
05fbd06d 1615 }\r
1616 //\r
1617 // We should disable mouse interface during the initialization process\r
1618 // since mouse device output could block keyboard device output in the\r
1619 // 60H port of 8042 controller.\r
1620 //\r
1621 // So if we are not initializing 8042 controller for the\r
1622 // first time, we have to remember the previous mouse interface\r
1623 // enabling state\r
1624 //\r
1625 // Test the system flag in to determine whether this is the first\r
1626 // time initialization\r
1627 //\r
f713c4fe 1628 if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG) != 0) {\r
05fbd06d 1629 //\r
1630 // 8042 controller is already setup (by myself or by mouse driver):\r
1631 // See whether mouse interface is already enabled\r
1632 // which determines whether we should enable it later\r
1633 //\r
1634 //\r
1635 // Read the command byte of 8042 controller\r
1636 //\r
b6763e03 1637 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ);\r
05fbd06d 1638 if (EFI_ERROR (Status)) {\r
1639 KeyboardError (ConsoleIn, L"\n\r");\r
1640 goto Done;\r
1641 }\r
1642\r
1643 Status = KeyboardRead (ConsoleIn, &CommandByte);\r
1644 if (EFI_ERROR (Status)) {\r
1645 KeyboardError (ConsoleIn, L"\n\r");\r
1646 goto Done;\r
1647 }\r
1648 //\r
1649 // Test the mouse enabling bit\r
1650 //\r
f713c4fe 1651 if ((CommandByte & 0x20) != 0) {\r
4fd730b3 1652 mEnableMouseInterface = FALSE;\r
05fbd06d 1653 } else {\r
4fd730b3 1654 mEnableMouseInterface = TRUE;\r
05fbd06d 1655 }\r
1656\r
1657 } else {\r
1658 //\r
1659 // 8042 controller is not setup yet:\r
1660 // 8042 controller selftest;\r
1661 // Don't enable mouse interface later.\r
1662 //\r
1663 //\r
1664 // Disable keyboard and mouse interfaces\r
1665 //\r
b6763e03 1666 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);\r
05fbd06d 1667 if (EFI_ERROR (Status)) {\r
1668 KeyboardError (ConsoleIn, L"\n\r");\r
1669 goto Done;\r
1670 }\r
1671\r
b6763e03 1672 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE);\r
05fbd06d 1673 if (EFI_ERROR (Status)) {\r
1674 KeyboardError (ConsoleIn, L"\n\r");\r
1675 goto Done;\r
1676 }\r
1677\r
1678 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1679 EFI_PROGRESS_CODE,\r
1680 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,\r
1681 ConsoleIn->DevicePath\r
1682 );\r
1683 //\r
1684 // 8042 Controller Self Test\r
1685 //\r
b6763e03 1686 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_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, 0x55);\r
1693 if (EFI_ERROR (Status)) {\r
1694 KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r");\r
1695 goto Done;\r
1696 }\r
1697 //\r
1698 // Don't enable mouse interface later\r
1699 //\r
4fd730b3 1700 mEnableMouseInterface = FALSE;\r
05fbd06d 1701\r
1702 }\r
1703\r
1704 if (Ps2Policy != NULL) {\r
1705 Ps2Policy->Ps2InitHardware (ConsoleIn->Handle);\r
1706 }\r
1707 //\r
1708 // Write 8042 Command Byte, set System Flag\r
1709 // While at the same time:\r
1710 // 1. disable mouse interface,\r
1711 // 2. enable kbd interface,\r
1712 // 3. enable PC/XT kbd translation mode\r
1713 // 4. enable mouse and kbd interrupts\r
1714 //\r
1715 // ( Command Byte bits:\r
1716 // 7: Reserved\r
1717 // 6: PC/XT translation mode\r
1718 // 5: Disable Auxiliary device interface\r
1719 // 4: Disable keyboard interface\r
1720 // 3: Reserved\r
1721 // 2: System Flag\r
1722 // 1: Enable Auxiliary device interrupt\r
1723 // 0: Enable Keyboard interrupt )\r
1724 //\r
b6763e03 1725 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_WRITE);\r
05fbd06d 1726 if (EFI_ERROR (Status)) {\r
1727 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
1728 goto Done;\r
1729 }\r
1730\r
1731 Status = KeyboardWrite (ConsoleIn, 0x67);\r
1732 if (EFI_ERROR (Status)) {\r
1733 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
1734 goto Done;\r
1735 }\r
1736\r
1737 //\r
1738 // Clear Memory Scancode Buffer\r
1739 //\r
1740 ConsoleIn->ScancodeBufStartPos = 0;\r
1741 ConsoleIn->ScancodeBufEndPos = KEYBOARD_BUFFER_MAX_COUNT - 1;\r
1742 ConsoleIn->ScancodeBufCount = 0;\r
1743 ConsoleIn->Ctrled = FALSE;\r
1744 ConsoleIn->Alted = FALSE;\r
1745\r
1746 //\r
1747 // Reset the status indicators\r
1748 //\r
1749 ConsoleIn->Ctrl = FALSE;\r
1750 ConsoleIn->Alt = FALSE;\r
1751 ConsoleIn->Shift = FALSE;\r
1752 ConsoleIn->CapsLock = FALSE;\r
1753 ConsoleIn->NumLock = FALSE;\r
1754 ConsoleIn->ScrollLock = FALSE;\r
f3d1e940 1755 ConsoleIn->LeftShift = FALSE;\r
1756 ConsoleIn->RightShift = FALSE;\r
1757 ConsoleIn->LeftLogo = FALSE;\r
1758 ConsoleIn->RightLogo = FALSE;\r
1759 ConsoleIn->Menu = FALSE;\r
1760 ConsoleIn->SysReq = FALSE; \r
05fbd06d 1761\r
1762 //\r
1763 // For reseting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,\r
1764 // and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected\r
1765 // to system. So we only do the real reseting for keyboard when user asks and there is a real KB connected t system,\r
1766 // and normally during booting an OS, it's skipped.\r
1767 //\r
1768 if (ExtendedVerification && CheckKeyboardConnect (ConsoleIn)) {\r
1769 //\r
1770 // Additional verifications for keyboard interface\r
1771 //\r
1772 //\r
1773 // Keyboard Interface Test\r
1774 //\r
b6763e03 1775 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST);\r
05fbd06d 1776 if (EFI_ERROR (Status)) {\r
1777 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
1778 goto Done;\r
1779 }\r
1780\r
1781 Status = KeyboardWaitForValue (ConsoleIn, 0x00);\r
1782 if (EFI_ERROR (Status)) {\r
1783 KeyboardError (\r
1784 ConsoleIn,\r
1785 L"Some specific value not aquired from 8042 controller!\n\r"\r
1786 );\r
1787 goto Done;\r
1788 }\r
1789 //\r
1790 // Keyboard reset with a BAT(Basic Assurance Test)\r
1791 //\r
b6763e03 1792 Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_RESET);\r
05fbd06d 1793 if (EFI_ERROR (Status)) {\r
1794 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
1795 goto Done;\r
1796 }\r
1797\r
b6763e03 1798 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
05fbd06d 1799 if (EFI_ERROR (Status)) {\r
1800 KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
1801 goto Done;\r
1802 }\r
1803 //\r
1804 // wait for BAT completion code\r
1805 //\r
1806 mWaitForValueTimeOut = KEYBOARD_BAT_TIMEOUT;\r
1807\r
b6763e03 1808 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);\r
05fbd06d 1809 if (EFI_ERROR (Status)) {\r
1810 KeyboardError (ConsoleIn, L"Keyboard self test failed!\n\r");\r
1811 goto Done;\r
1812 }\r
1813\r
1814 mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
1815\r
1816 //\r
1817 // Set Keyboard to use Scan Code Set 2\r
1818 //\r
b6763e03 1819 Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET);\r
05fbd06d 1820 if (EFI_ERROR (Status)) {\r
1821 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
1822 goto Done;\r
1823 }\r
1824\r
b6763e03 1825 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
05fbd06d 1826 if (EFI_ERROR (Status)) {\r
1827 KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
1828 goto Done;\r
1829 }\r
1830\r
1831 Status = KeyboardWrite (ConsoleIn, 0x02);\r
1832 if (EFI_ERROR (Status)) {\r
1833 KeyboardError (ConsoleIn, L"8042 controller data write error!!\n\r");\r
1834 goto Done;\r
1835 }\r
1836\r
b6763e03 1837 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
05fbd06d 1838 if (EFI_ERROR (Status)) {\r
1839 KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
1840 goto Done;\r
1841 }\r
1842\r
1843 //\r
1844 // Clear Keyboard Scancode Buffer\r
1845 //\r
b6763e03 1846 Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA);\r
05fbd06d 1847 if (EFI_ERROR (Status)) {\r
1848 KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");\r
1849 goto Done;\r
1850 }\r
1851\r
b6763e03 1852 Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);\r
05fbd06d 1853 if (EFI_ERROR (Status)) {\r
1854 KeyboardError (ConsoleIn, L"Some specific value not aquired from 8042 controller!\n\r");\r
1855 goto Done;\r
1856 }\r
1857 //\r
1858 if (Ps2Policy != NULL) {\r
1859 if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_CAPSLOCK) == EFI_KEYBOARD_CAPSLOCK) {\r
1860 ConsoleIn->CapsLock = TRUE;\r
1861 }\r
1862\r
1863 if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_NUMLOCK) == EFI_KEYBOARD_NUMLOCK) {\r
1864 ConsoleIn->NumLock = TRUE;\r
1865 }\r
1866\r
1867 if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_SCROLLLOCK) == EFI_KEYBOARD_SCROLLLOCK) {\r
1868 ConsoleIn->ScrollLock = TRUE;\r
1869 }\r
1870 }\r
1871 //\r
1872 // Update Keyboard Lights\r
1873 //\r
1874 Status = UpdateStatusLights (ConsoleIn);\r
1875 if (EFI_ERROR (Status)) {\r
1876 KeyboardError (ConsoleIn, L"Update keyboard status lights error!\n\r");\r
1877 goto Done;\r
1878 }\r
1879 }\r
1880 //\r
1881 // At last, we can now enable the mouse interface if appropriate\r
1882 //\r
1883Done:\r
1884\r
4fd730b3 1885 if (mEnableMouseInterface) {\r
05fbd06d 1886 //\r
1887 // Enable mouse interface\r
1888 //\r
b6763e03 1889 Status1 = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE);\r
05fbd06d 1890 if (EFI_ERROR (Status1)) {\r
1891 KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");\r
1892 return EFI_DEVICE_ERROR;\r
1893 }\r
1894 }\r
1895\r
1896 if (!EFI_ERROR (Status)) {\r
1897 return EFI_SUCCESS;\r
1898 } else {\r
1899 return EFI_DEVICE_ERROR;\r
1900 }\r
1901\r
1902}\r
1903\r
bcd70414 1904/**\r
f713c4fe 1905 Disable the keyboard interface of the 8042 controller.\r
05fbd06d 1906\r
f713c4fe 1907 @param ConsoleIn The device instance\r
05fbd06d 1908\r
bcd70414 1909 @return status of issuing disable command\r
05fbd06d 1910\r
bcd70414 1911**/\r
1912EFI_STATUS\r
1913DisableKeyboard (\r
1914 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
1915 )\r
05fbd06d 1916{\r
1917 EFI_STATUS Status;\r
1918\r
1919 //\r
1920 // Disable keyboard interface\r
1921 //\r
b6763e03 1922 Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);\r
05fbd06d 1923 if (EFI_ERROR (Status)) {\r
1924 KeyboardError (ConsoleIn, L"\n\r");\r
1925 return EFI_DEVICE_ERROR;\r
1926 }\r
1927\r
1928 return Status;\r
1929}\r
1930\r
1931/**\r
1932 Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command\r
1933 If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device\r
1934 should not be in system.\r
1935\r
fdb05fa3 1936 @param[in] ConsoleIn Keyboard Private Data Structure\r
05fbd06d 1937\r
f3d1e940 1938 @retval TRUE Keyboard in System.\r
1939 @retval FALSE Keyboard not in System.\r
05fbd06d 1940**/\r
1941BOOLEAN\r
1942EFIAPI\r
1943CheckKeyboardConnect (\r
1944 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn\r
1945 )\r
1946{\r
1947 EFI_STATUS Status;\r
1948 UINTN WaitForValueTimeOutBcakup;\r
1949\r
1950 Status = EFI_SUCCESS;\r
1951 //\r
1952 // enable keyboard itself and wait for its ack\r
1953 // If can't receive ack, Keyboard should not be connected.\r
1954 //\r
1955 Status = KeyboardWrite (\r
1956 ConsoleIn,\r
1957 KEYBOARD_KBEN\r
1958 );\r
1959\r
1960 if (EFI_ERROR (Status)) {\r
1961 return FALSE;\r
1962 }\r
1963 //\r
1964 // wait for 1s\r
1965 //\r
1966 WaitForValueTimeOutBcakup = mWaitForValueTimeOut;\r
1967 mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;\r
1968 Status = KeyboardWaitForValue (\r
1969 ConsoleIn,\r
1970 KEYBOARD_CMDECHO_ACK\r
1971 );\r
1972 mWaitForValueTimeOut = WaitForValueTimeOutBcakup;\r
1973\r
1974 if (EFI_ERROR (Status)) {\r
1975 return FALSE;\r
1976 }\r
1977\r
1978 return TRUE;\r
1979}\r
bcd70414 1980\r