]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c
Add in Ps2keyboard.inf and Ps2Mouse.inf to IntelFrameworkModuelPkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2MouseDxe / CommPs2.c
CommitLineData
05fbd06d 1/*++\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR> \r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
12\r
13Module Name:\r
14\r
15 CommPs2.c\r
16 \r
17Abstract: \r
18\r
19 PS2 Mouse Communication Interface \r
20\r
21\r
22Revision History\r
23\r
24--*/\r
25\r
26//\r
27// Include common header file for this module.\r
28//\r
29#include "CommonHeader.h"\r
30\r
31#include "Ps2Mouse.h"\r
32#include "CommPs2.h"\r
33\r
34UINT8 SampleRateTbl[MAX_SR] = { 0xa, 0x14, 0x28, 0x3c, 0x50, 0x64, 0xc8 };\r
35\r
36UINT8 ResolutionTbl[MAX_CMR] = { 0, 1, 2, 3 };\r
37\r
38EFI_STATUS\r
39KbcSelfTest (\r
40 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
41 )\r
42/*++\r
43\r
44Routine Description:\r
45\r
46 GC_TODO: Add function description\r
47\r
48Arguments:\r
49\r
50 IsaIo - GC_TODO: add argument description\r
51\r
52Returns:\r
53\r
54 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
55 EFI_SUCCESS - GC_TODO: Add description for return value\r
56\r
57--*/\r
58{\r
59 EFI_STATUS Status;\r
60 UINT8 Data;\r
61\r
62 //\r
63 // Keyboard controller self test\r
64 //\r
65 Status = Out8042Command (IsaIo, SELF_TEST);\r
66 if (EFI_ERROR (Status)) {\r
67 return Status;\r
68 }\r
69 //\r
70 // Read return code\r
71 //\r
72 Status = In8042Data (IsaIo, &Data);\r
73 if (EFI_ERROR (Status)) {\r
74 return Status;\r
75 }\r
76\r
77 if (Data != 0x55) {\r
78 return EFI_DEVICE_ERROR;\r
79 }\r
80 //\r
81 // Set system flag\r
82 //\r
83 Status = Out8042Command (IsaIo, READ_CMD_BYTE);\r
84 if (EFI_ERROR (Status)) {\r
85 return Status;\r
86 }\r
87\r
88 Status = In8042Data (IsaIo, &Data);\r
89 if (EFI_ERROR (Status)) {\r
90 return Status;\r
91 }\r
92\r
93 Status = Out8042Command (IsaIo, WRITE_CMD_BYTE);\r
94 if (EFI_ERROR (Status)) {\r
95 return Status;\r
96 }\r
97\r
98 Data |= CMD_SYS_FLAG;\r
99 Status = Out8042Data (IsaIo, Data);\r
100 if (EFI_ERROR (Status)) {\r
101 return Status;\r
102 }\r
103\r
104 return EFI_SUCCESS;\r
105}\r
106\r
107EFI_STATUS\r
108KbcEnableAux (\r
109 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
110 )\r
111/*++\r
112\r
113Routine Description:\r
114\r
115 GC_TODO: Add function description\r
116\r
117Arguments:\r
118\r
119 IsaIo - GC_TODO: add argument description\r
120\r
121Returns:\r
122\r
123 GC_TODO: add return values\r
124\r
125--*/\r
126{\r
127 //\r
128 // Send 8042 enable mouse command\r
129 //\r
130 return Out8042Command (IsaIo, ENABLE_AUX);\r
131}\r
132\r
133EFI_STATUS\r
134KbcDisableAux (\r
135 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
136 )\r
137/*++\r
138\r
139Routine Description:\r
140\r
141 GC_TODO: Add function description\r
142\r
143Arguments:\r
144\r
145 IsaIo - GC_TODO: add argument description\r
146\r
147Returns:\r
148\r
149 GC_TODO: add return values\r
150\r
151--*/\r
152{\r
153 //\r
154 // Send 8042 disable mouse command\r
155 //\r
156 return Out8042Command (IsaIo, DISABLE_AUX);\r
157}\r
158\r
159EFI_STATUS\r
160KbcEnableKb (\r
161 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
162 )\r
163/*++\r
164\r
165Routine Description:\r
166\r
167 GC_TODO: Add function description\r
168\r
169Arguments:\r
170\r
171 IsaIo - GC_TODO: add argument description\r
172\r
173Returns:\r
174\r
175 GC_TODO: add return values\r
176\r
177--*/\r
178{\r
179 //\r
180 // Send 8042 enable keyboard command\r
181 //\r
182 return Out8042Command (IsaIo, ENABLE_KB);\r
183}\r
184\r
185EFI_STATUS\r
186KbcDisableKb (\r
187 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
188 )\r
189/*++\r
190\r
191Routine Description:\r
192\r
193 GC_TODO: Add function description\r
194\r
195Arguments:\r
196\r
197 IsaIo - GC_TODO: add argument description\r
198\r
199Returns:\r
200\r
201 GC_TODO: add return values\r
202\r
203--*/\r
204{\r
205 //\r
206 // Send 8042 disable keyboard command\r
207 //\r
208 return Out8042Command (IsaIo, DISABLE_KB);\r
209}\r
210\r
211EFI_STATUS\r
212CheckKbStatus (\r
213 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
214 OUT BOOLEAN *KeyboardEnable\r
215 )\r
216/*++\r
217\r
218Routine Description:\r
219\r
220 GC_TODO: Add function description\r
221\r
222Arguments:\r
223\r
224 IsaIo - GC_TODO: add argument description\r
225 KeyboardEnable - GC_TODO: add argument description\r
226\r
227Returns:\r
228\r
229 EFI_SUCCESS - GC_TODO: Add description for return value\r
230\r
231--*/\r
232{\r
233 EFI_STATUS Status;\r
234 UINT8 Data;\r
235\r
236 //\r
237 // Send command to read KBC command byte\r
238 //\r
239 Status = Out8042Command (IsaIo, READ_CMD_BYTE);\r
240 if (EFI_ERROR (Status)) {\r
241 return Status;\r
242 }\r
243\r
244 Status = In8042Data (IsaIo, &Data);\r
245 if (EFI_ERROR (Status)) {\r
246 return Status;\r
247 }\r
248 //\r
249 // Check keyboard enable or not\r
250 //\r
251 if ((Data & CMD_KB_STS) == CMD_KB_DIS) {\r
252 *KeyboardEnable = FALSE;\r
253 } else {\r
254 *KeyboardEnable = TRUE;\r
255 }\r
256\r
257 return EFI_SUCCESS;\r
258}\r
259\r
260EFI_STATUS\r
261PS2MouseReset (\r
262 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
263 )\r
264/*++\r
265\r
266Routine Description:\r
267\r
268 GC_TODO: Add function description\r
269\r
270Arguments:\r
271\r
272 IsaIo - GC_TODO: add argument description\r
273\r
274Returns:\r
275\r
276 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
277 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
278 EFI_SUCCESS - GC_TODO: Add description for return value\r
279\r
280--*/\r
281{\r
282 EFI_STATUS Status;\r
283 UINT8 Data;\r
284\r
285 Status = Out8042AuxCommand (IsaIo, RESET_CMD, FALSE);\r
286 if (EFI_ERROR (Status)) {\r
287 return Status;\r
288 }\r
289\r
290 Status = In8042AuxData (IsaIo, &Data);\r
291 if (EFI_ERROR (Status)) {\r
292 return Status;\r
293 }\r
294 //\r
295 // Check BAT Complete Code\r
296 //\r
297 if (Data != PS2MOUSE_BAT1) {\r
298 return EFI_DEVICE_ERROR;\r
299 }\r
300\r
301 Status = In8042AuxData (IsaIo, &Data);\r
302 if (EFI_ERROR (Status)) {\r
303 return Status;\r
304 }\r
305 //\r
306 // Check BAT Complete Code\r
307 //\r
308 if (Data != PS2MOUSE_BAT2) {\r
309 return EFI_DEVICE_ERROR;\r
310 }\r
311\r
312 return EFI_SUCCESS;\r
313}\r
314\r
315EFI_STATUS\r
316PS2MouseSetSampleRate (\r
317 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
318 IN MOUSE_SR SampleRate\r
319 )\r
320/*++\r
321\r
322Routine Description:\r
323\r
324 GC_TODO: Add function description\r
325\r
326Arguments:\r
327\r
328 IsaIo - GC_TODO: add argument description\r
329 SampleRate - GC_TODO: add argument description\r
330\r
331Returns:\r
332\r
333 GC_TODO: add return values\r
334\r
335--*/\r
336{\r
337 EFI_STATUS Status;\r
338\r
339 //\r
340 // Send auxiliary command to set mouse sample rate\r
341 //\r
342 Status = Out8042AuxCommand (IsaIo, SETSR_CMD, FALSE);\r
343 if (EFI_ERROR (Status)) {\r
344 return Status;\r
345 }\r
346\r
347 Status = Out8042AuxData (IsaIo, SampleRateTbl[SampleRate]);\r
348\r
349 return Status;\r
350}\r
351\r
352EFI_STATUS\r
353PS2MouseSetResolution (\r
354 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
355 IN MOUSE_RE Resolution\r
356 )\r
357/*++\r
358\r
359Routine Description:\r
360\r
361 GC_TODO: Add function description\r
362\r
363Arguments:\r
364\r
365 IsaIo - GC_TODO: add argument description\r
366 Resolution - GC_TODO: add argument description\r
367\r
368Returns:\r
369\r
370 GC_TODO: add return values\r
371\r
372--*/\r
373{\r
374 EFI_STATUS Status;\r
375\r
376 //\r
377 // Send auxiliary command to set mouse resolution\r
378 //\r
379 Status = Out8042AuxCommand (IsaIo, SETRE_CMD, FALSE);\r
380 if (EFI_ERROR (Status)) {\r
381 return Status;\r
382 }\r
383\r
384 Status = Out8042AuxData (IsaIo, ResolutionTbl[Resolution]);\r
385\r
386 return Status;\r
387}\r
388\r
389EFI_STATUS\r
390PS2MouseSetScaling (\r
391 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
392 IN MOUSE_SF Scaling\r
393 )\r
394/*++\r
395\r
396Routine Description:\r
397\r
398 GC_TODO: Add function description\r
399\r
400Arguments:\r
401\r
402 IsaIo - GC_TODO: add argument description\r
403 Scaling - GC_TODO: add argument description\r
404\r
405Returns:\r
406\r
407 GC_TODO: add return values\r
408\r
409--*/\r
410{\r
411 UINT8 Command;\r
412\r
413 Command = (UINT8) (Scaling == SF1 ? SETSF1_CMD : SETSF2_CMD);\r
414\r
415 //\r
416 // Send auxiliary command to set mouse scaling data\r
417 //\r
418 return Out8042AuxCommand (IsaIo, Command, FALSE);\r
419}\r
420\r
421EFI_STATUS\r
422PS2MouseEnable (\r
423 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
424 )\r
425/*++\r
426\r
427Routine Description:\r
428\r
429 GC_TODO: Add function description\r
430\r
431Arguments:\r
432\r
433 IsaIo - GC_TODO: add argument description\r
434\r
435Returns:\r
436\r
437 GC_TODO: add return values\r
438\r
439--*/\r
440{\r
441 //\r
442 // Send auxiliary command to enable mouse\r
443 //\r
444 return Out8042AuxCommand (IsaIo, ENABLE_CMD, FALSE);\r
445}\r
446\r
447EFI_STATUS\r
448PS2MouseGetPacket (\r
449 PS2_MOUSE_DEV *MouseDev\r
450 )\r
451/*++\r
452\r
453Routine Description:\r
454\r
455 Get mouse packet . Only care first 3 bytes\r
456\r
457Arguments:\r
458\r
459 MouseDev - Pointer of PS2 Mouse Private Data Structure \r
460\r
461Returns:\r
462\r
463 EFI_NOT_READY - Mouse Device not ready to input data packet, or some error happened during getting the packet\r
464 EFI_SUCCESS - The data packet is gotten successfully.\r
465\r
466--*/\r
467{\r
468 EFI_STATUS Status;\r
469 BOOLEAN KeyboardEnable;\r
470 UINT8 Packet[PS2_PACKET_LENGTH];\r
471 UINT8 Data;\r
472 UINTN Count;\r
473 UINTN State;\r
474 INT16 RelativeMovementX;\r
475 INT16 RelativeMovementY;\r
476 BOOLEAN LButton;\r
477 BOOLEAN RButton;\r
478\r
479 KeyboardEnable = FALSE;\r
480 Count = 1;\r
481 State = PS2_READ_BYTE_ONE;\r
482\r
483 //\r
484 // State machine to get mouse packet\r
485 //\r
486 while (1) {\r
487\r
488 switch (State) {\r
489 case PS2_READ_BYTE_ONE:\r
490 //\r
491 // Read mouse first byte data, if failed, immediately return\r
492 //\r
493 KbcDisableAux (MouseDev->IsaIo);\r
494 Status = PS2MouseRead (MouseDev->IsaIo, &Data, &Count, State);\r
495 if (EFI_ERROR (Status)) {\r
496 KbcEnableAux (MouseDev->IsaIo);\r
497 return EFI_NOT_READY;\r
498 }\r
499\r
500 if (Count != 1) {\r
501 KbcEnableAux (MouseDev->IsaIo);\r
502 return EFI_NOT_READY;\r
503 }\r
504\r
505 if (IS_PS2_SYNC_BYTE (Data)) {\r
506 Packet[0] = Data;\r
507 State = PS2_READ_DATA_BYTE;\r
508\r
509 CheckKbStatus (MouseDev->IsaIo, &KeyboardEnable);\r
510 KbcDisableKb (MouseDev->IsaIo);\r
511 KbcEnableAux (MouseDev->IsaIo);\r
512 }\r
513 break;\r
514\r
515 case PS2_READ_DATA_BYTE:\r
516 Count = 2;\r
517 Status = PS2MouseRead (MouseDev->IsaIo, (Packet + 1), &Count, State);\r
518 if (EFI_ERROR (Status)) {\r
519 if (KeyboardEnable) {\r
520 KbcEnableKb (MouseDev->IsaIo);\r
521 }\r
522\r
523 return EFI_NOT_READY;\r
524 }\r
525\r
526 if (Count != 2) {\r
527 if (KeyboardEnable) {\r
528 KbcEnableKb (MouseDev->IsaIo);\r
529 }\r
530\r
531 return EFI_NOT_READY;\r
532 }\r
533\r
534 State = PS2_PROCESS_PACKET;\r
535 break;\r
536\r
537 case PS2_PROCESS_PACKET:\r
538 if (KeyboardEnable) {\r
539 KbcEnableKb (MouseDev->IsaIo);\r
540 }\r
541 //\r
542 // Decode the packet\r
543 //\r
544 RelativeMovementX = Packet[1];\r
545 RelativeMovementY = Packet[2];\r
546 //\r
547 // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 \r
548 // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn \r
549 // Byte 1 | 8 bit X Movement \r
550 // Byte 2 | 8 bit Y Movement \r
551 // \r
552 // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission.\r
553 // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.\r
554 //\r
555 //\r
556 // First, Clear X and Y high 8 bits\r
557 //\r
558 RelativeMovementX = (INT16) (RelativeMovementX & 0xFF); \r
559 RelativeMovementY = (INT16) (RelativeMovementY & 0xFF); \r
560 //\r
561 // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff\r
562 //\r
563 if ((Packet[0] & 0x10) != 0) {\r
564 RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00);\r
565 }\r
566 if ((Packet[0] & 0x20) != 0) {\r
567 RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00);\r
568 }\r
569\r
570 \r
571 RButton = (UINT8) (Packet[0] & 0x2);\r
572 LButton = (UINT8) (Packet[0] & 0x1);\r
573\r
574 //\r
575 // Update mouse state\r
576 //\r
577 MouseDev->State.RelativeMovementX += RelativeMovementX;\r
578 MouseDev->State.RelativeMovementY -= RelativeMovementY;\r
579 MouseDev->State.RightButton = (UINT8) (RButton ? TRUE : FALSE);\r
580 MouseDev->State.LeftButton = (UINT8) (LButton ? TRUE : FALSE);\r
581 MouseDev->StateChanged = TRUE;\r
582\r
583 return EFI_SUCCESS;\r
584 }\r
585 }\r
586}\r
587\r
588EFI_STATUS\r
589PS2MouseRead (\r
590 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
591 OUT VOID *Buffer,\r
592 IN OUT UINTN *BufSize,\r
593 IN UINTN State\r
594 )\r
595/*++\r
596\r
597Routine Description:\r
598\r
599 GC_TODO: Add function description\r
600\r
601Arguments:\r
602\r
603 IsaIo - GC_TODO: add argument description\r
604 Buffer - GC_TODO: add argument description\r
605 BufSize - GC_TODO: add argument description\r
606 State - GC_TODO: add argument description\r
607\r
608Returns:\r
609\r
610 GC_TODO: add return values\r
611\r
612--*/\r
613{\r
614 EFI_STATUS Status;\r
615 UINTN BytesRead;\r
616\r
617 Status = EFI_SUCCESS;\r
618 BytesRead = 0;\r
619\r
620 if (State == PS2_READ_BYTE_ONE) {\r
621 //\r
622 // Check input for mouse\r
623 //\r
624 Status = CheckForInput (IsaIo);\r
625\r
626 if (EFI_ERROR (Status)) {\r
627 return Status;\r
628 }\r
629 }\r
630\r
631 while (BytesRead < *BufSize) {\r
632\r
633 Status = WaitOutputFull (IsaIo, TIMEOUT);\r
634 if (EFI_ERROR (Status)) {\r
635 break;\r
636 }\r
637\r
638 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Buffer);\r
639\r
640 BytesRead++;\r
641 Buffer = (UINT8 *) Buffer + 1;\r
642 }\r
643 //\r
644 // Verify the correct number of bytes read\r
645 //\r
646 if (BytesRead == 0 || BytesRead != *BufSize) {\r
647 Status = EFI_NOT_FOUND;\r
648 }\r
649\r
650 *BufSize = BytesRead;\r
651 return Status;\r
652}\r
653//\r
654// 8042 I/O function\r
655//\r
656EFI_STATUS\r
657Out8042Command (\r
658 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
659 IN UINT8 Command\r
660 )\r
661/*++\r
662\r
663Routine Description:\r
664\r
665 GC_TODO: Add function description\r
666\r
667Arguments:\r
668\r
669 IsaIo - GC_TODO: add argument description\r
670 Command - GC_TODO: add argument description\r
671\r
672Returns:\r
673\r
674 EFI_SUCCESS - GC_TODO: Add description for return value\r
675\r
676--*/\r
677{\r
678 EFI_STATUS Status;\r
679 UINT8 Data;\r
680\r
681 //\r
682 // Wait keyboard controller input buffer empty\r
683 //\r
684 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
685 if (EFI_ERROR (Status)) {\r
686 return Status;\r
687 }\r
688 //\r
689 // Send command\r
690 //\r
691 Data = Command;\r
692 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
693\r
694 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
695 if (EFI_ERROR (Status)) {\r
696 return Status;\r
697 }\r
698\r
699 return EFI_SUCCESS;\r
700}\r
701\r
702EFI_STATUS\r
703Out8042Data (\r
704 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
705 IN UINT8 Data\r
706 )\r
707/*++\r
708\r
709Routine Description:\r
710\r
711 GC_TODO: Add function description\r
712\r
713Arguments:\r
714\r
715 IsaIo - GC_TODO: add argument description\r
716 Data - GC_TODO: add argument description\r
717\r
718Returns:\r
719\r
720 EFI_SUCCESS - GC_TODO: Add description for return value\r
721\r
722--*/\r
723{\r
724 EFI_STATUS Status;\r
725 UINT8 temp;\r
726 //\r
727 // Wait keyboard controller input buffer empty\r
728 //\r
729 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
730 if (EFI_ERROR (Status)) {\r
731 return Status;\r
732 }\r
733\r
734 temp = Data;\r
735 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &temp);\r
736\r
737 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
738 if (EFI_ERROR (Status)) {\r
739 return Status;\r
740 }\r
741\r
742 return EFI_SUCCESS;\r
743}\r
744\r
745EFI_STATUS\r
746In8042Data (\r
747 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
748 IN OUT UINT8 *Data\r
749 )\r
750/*++\r
751\r
752Routine Description:\r
753\r
754 GC_TODO: Add function description\r
755\r
756Arguments:\r
757\r
758 IsaIo - GC_TODO: add argument description\r
759 Data - GC_TODO: add argument description\r
760\r
761Returns:\r
762\r
763 EFI_TIMEOUT - GC_TODO: Add description for return value\r
764 EFI_SUCCESS - GC_TODO: Add description for return value\r
765\r
766--*/\r
767{\r
768 UINTN Delay;\r
769 UINT8 temp;\r
770\r
771 Delay = TIMEOUT / 50;\r
772\r
773 do {\r
774 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &temp);\r
775\r
776 //\r
777 // Check keyboard controller status bit 0(output buffer status)\r
778 //\r
779 if ((temp & KBC_OUTB) == KBC_OUTB) {\r
780 break;\r
781 }\r
782\r
783 gBS->Stall (50);\r
784 Delay--;\r
785 } while (Delay);\r
786\r
787 if (Delay == 0) {\r
788 return EFI_TIMEOUT;\r
789 }\r
790\r
791 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);\r
792\r
793 return EFI_SUCCESS;\r
794}\r
795\r
796EFI_STATUS\r
797Out8042AuxCommand (\r
798 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
799 IN UINT8 Command,\r
800 IN BOOLEAN Resend\r
801 )\r
802/*++\r
803\r
804Routine Description:\r
805\r
806 GC_TODO: Add function description\r
807\r
808Arguments:\r
809\r
810 IsaIo - GC_TODO: add argument description\r
811 Command - GC_TODO: add argument description\r
812 Resend - GC_TODO: add argument description\r
813\r
814Returns:\r
815\r
816 EFI_SUCCESS - GC_TODO: Add description for return value\r
817 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
818 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
819 EFI_SUCCESS - GC_TODO: Add description for return value\r
820\r
821--*/\r
822{\r
823 EFI_STATUS Status;\r
824 UINT8 Data;\r
825\r
826 //\r
827 // Wait keyboard controller input buffer empty\r
828 //\r
829 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
830 if (EFI_ERROR (Status)) {\r
831 return Status;\r
832 }\r
833 //\r
834 // Send write to auxiliary device command\r
835 //\r
836 Data = WRITE_AUX_DEV;\r
837 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
838\r
839 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
840 if (EFI_ERROR (Status)) {\r
841 return Status;\r
842 }\r
843 //\r
844 // Send auxiliary device command\r
845 //\r
846 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Command);\r
847\r
848 //\r
849 // Read return code\r
850 //\r
851 Status = In8042AuxData (IsaIo, &Data);\r
852 if (EFI_ERROR (Status)) {\r
853 return Status;\r
854 }\r
855\r
856 if (Data == PS2_ACK) {\r
857 //\r
858 // Receive mouse acknowledge, command send success\r
859 //\r
860 return EFI_SUCCESS;\r
861\r
862 } else if (Resend) {\r
863 //\r
864 // Resend fail\r
865 //\r
866 return EFI_DEVICE_ERROR;\r
867\r
868 } else if (Data == PS2_RESEND) {\r
869 //\r
870 // Resend command\r
871 //\r
872 Status = Out8042AuxCommand (IsaIo, Command, TRUE);\r
873 if (EFI_ERROR (Status)) {\r
874 return Status;\r
875 }\r
876\r
877 } else {\r
878 //\r
879 // Invalid return code\r
880 //\r
881 return EFI_DEVICE_ERROR;\r
882\r
883 }\r
884\r
885 return EFI_SUCCESS;\r
886}\r
887\r
888EFI_STATUS\r
889Out8042AuxData (\r
890 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
891 IN UINT8 Data\r
892 )\r
893/*++\r
894\r
895Routine Description:\r
896\r
897 GC_TODO: Add function description\r
898\r
899Arguments:\r
900\r
901 IsaIo - GC_TODO: add argument description\r
902 Data - GC_TODO: add argument description\r
903\r
904Returns:\r
905\r
906 EFI_SUCCESS - GC_TODO: Add description for return value\r
907\r
908--*/\r
909{\r
910 EFI_STATUS Status;\r
911 UINT8 Temp;\r
912 //\r
913 // Wait keyboard controller input buffer empty\r
914 //\r
915 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
916 if (EFI_ERROR (Status)) {\r
917 return Status;\r
918 }\r
919 //\r
920 // Send write to auxiliary device command\r
921 //\r
922 Temp = WRITE_AUX_DEV;\r
923 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Temp);\r
924\r
925 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
926 if (EFI_ERROR (Status)) {\r
927 return Status;\r
928 }\r
929\r
930 Temp = Data;\r
931 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Temp);\r
932\r
933 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
934 if (EFI_ERROR (Status)) {\r
935 return Status;\r
936 }\r
937\r
938 return EFI_SUCCESS;\r
939}\r
940\r
941EFI_STATUS\r
942In8042AuxData (\r
943 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
944 IN OUT UINT8 *Data\r
945 )\r
946/*++\r
947\r
948Routine Description:\r
949\r
950 GC_TODO: Add function description\r
951\r
952Arguments:\r
953\r
954 IsaIo - GC_TODO: add argument description\r
955 Data - GC_TODO: add argument description\r
956\r
957Returns:\r
958\r
959 EFI_SUCCESS - GC_TODO: Add description for return value\r
960\r
961--*/\r
962{\r
963 EFI_STATUS Status;\r
964\r
965 //\r
966 // wait for output data\r
967 //\r
968 Status = WaitOutputFull (IsaIo, BAT_TIMEOUT);\r
969 if (EFI_ERROR (Status)) {\r
970 return Status;\r
971 }\r
972\r
973 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);\r
974\r
975 return EFI_SUCCESS;\r
976}\r
977\r
978EFI_STATUS\r
979CheckForInput (\r
980 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
981 )\r
982/*++\r
983\r
984Routine Description:\r
985\r
986 GC_TODO: Add function description\r
987\r
988Arguments:\r
989\r
990 IsaIo - GC_TODO: add argument description\r
991\r
992Returns:\r
993\r
994 EFI_NOT_READY - GC_TODO: Add description for return value\r
995 EFI_SUCCESS - GC_TODO: Add description for return value\r
996\r
997--*/\r
998{\r
999 UINT8 Data;\r
1000\r
1001 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
1002\r
1003 //\r
1004 // Check keyboard controller status, if it is output buffer full and for auxiliary device\r
1005 //\r
1006 if ((Data & (KBC_OUTB | KBC_AUXB)) != (KBC_OUTB | KBC_AUXB)) {\r
1007 return EFI_NOT_READY;\r
1008 }\r
1009\r
1010 return EFI_SUCCESS;\r
1011}\r
1012\r
1013EFI_STATUS\r
1014WaitInputEmpty (\r
1015 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
1016 IN UINTN Timeout\r
1017 )\r
1018/*++\r
1019\r
1020Routine Description:\r
1021\r
1022 GC_TODO: Add function description\r
1023\r
1024Arguments:\r
1025\r
1026 IsaIo - GC_TODO: add argument description\r
1027 Timeout - GC_TODO: add argument description\r
1028\r
1029Returns:\r
1030\r
1031 EFI_TIMEOUT - GC_TODO: Add description for return value\r
1032 EFI_SUCCESS - GC_TODO: Add description for return value\r
1033\r
1034--*/\r
1035{\r
1036 UINTN Delay;\r
1037 UINT8 Data;\r
1038\r
1039 Delay = Timeout / 50;\r
1040\r
1041 do {\r
1042 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
1043\r
1044 //\r
1045 // Check keyboard controller status bit 1(input buffer status)\r
1046 //\r
1047 if ((Data & KBC_INPB) == 0) {\r
1048 break;\r
1049 }\r
1050\r
1051 gBS->Stall (50);\r
1052 Delay--;\r
1053 } while (Delay);\r
1054\r
1055 if (Delay == 0) {\r
1056 return EFI_TIMEOUT;\r
1057 }\r
1058\r
1059 return EFI_SUCCESS;\r
1060}\r
1061\r
1062EFI_STATUS\r
1063WaitOutputFull (\r
1064 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
1065 IN UINTN Timeout\r
1066 )\r
1067/*++\r
1068\r
1069Routine Description:\r
1070\r
1071 GC_TODO: Add function description\r
1072\r
1073Arguments:\r
1074\r
1075 IsaIo - GC_TODO: add argument description\r
1076 Timeout - GC_TODO: add argument description\r
1077\r
1078Returns:\r
1079\r
1080 EFI_TIMEOUT - GC_TODO: Add description for return value\r
1081 EFI_SUCCESS - GC_TODO: Add description for return value\r
1082\r
1083--*/\r
1084{\r
1085 UINTN Delay;\r
1086 UINT8 Data;\r
1087\r
1088 Delay = Timeout / 50;\r
1089\r
1090 do {\r
1091 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
1092\r
1093 //\r
1094 // Check keyboard controller status bit 0(output buffer status)\r
1095 // & bit5(output buffer for auxiliary device)\r
1096 //\r
1097 if ((Data & (KBC_OUTB | KBC_AUXB)) == (KBC_OUTB | KBC_AUXB)) {\r
1098 break;\r
1099 }\r
1100\r
1101 gBS->Stall (50);\r
1102 Delay--;\r
1103 } while (Delay);\r
1104\r
1105 if (Delay == 0) {\r
1106 return EFI_TIMEOUT;\r
1107 }\r
1108\r
1109 return EFI_SUCCESS;\r
1110}\r