]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClass.c
Add in VgaClassDxe
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / Console / VgaClassDxe / VgaClass.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation. All rights reserved. <BR>
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
10 Intel Corporation.
11
12
13 Module Name:
14
15 VgaClass.c
16
17 Abstract:
18 This driver produces a VGA console.
19
20 --*/
21
22 #include "VgaClass.h"
23
24 //
25 // EFI Driver Binding Protocol for the VGA Class Driver
26 //
27 EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding = {
28 VgaClassDriverBindingSupported,
29 VgaClassDriverBindingStart,
30 VgaClassDriverBindingStop,
31 0xa,
32 NULL,
33 NULL
34 };
35
36 /**
37 The user Entry Point for module VgaClass. The user code starts with this function.
38
39 @param[in] ImageHandle The firmware allocated handle for the EFI image.
40 @param[in] SystemTable A pointer to the EFI System Table.
41
42 @retval EFI_SUCCESS The entry point is executed successfully.
43 @retval other Some error occurs when executing this entry point.
44
45 **/
46 EFI_STATUS
47 EFIAPI
48 InitializeVgaClass(
49 IN EFI_HANDLE ImageHandle,
50 IN EFI_SYSTEM_TABLE *SystemTable
51 )
52 {
53 EFI_STATUS Status;
54
55 //
56 // Install driver model protocol(s).
57 //
58 Status = EfiLibInstallAllDriverProtocols (
59 ImageHandle,
60 SystemTable,
61 &gVgaClassDriverBinding,
62 ImageHandle,
63 &gVgaClassComponentName,
64 NULL,
65 NULL
66 );
67 ASSERT_EFI_ERROR (Status);
68
69
70 return Status;
71 }
72
73 //
74 // Local variables
75 //
76 static CHAR16 CrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
77
78 typedef struct {
79 CHAR16 Unicode;
80 CHAR8 PcAnsi;
81 CHAR8 Ascii;
82 } UNICODE_TO_CHAR;
83
84 //
85 // This list is used to define the valid extend chars.
86 // It also provides a mapping from Unicode to PCANSI or
87 // ASCII. The ASCII mapping we just made up.
88 //
89 //
90 STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {
91 {
92 BOXDRAW_HORIZONTAL,
93 0xc4,
94 L'-'
95 },
96 {
97 BOXDRAW_VERTICAL,
98 0xb3,
99 L'|'
100 },
101 {
102 BOXDRAW_DOWN_RIGHT,
103 0xda,
104 L'/'
105 },
106 {
107 BOXDRAW_DOWN_LEFT,
108 0xbf,
109 L'\\'
110 },
111 {
112 BOXDRAW_UP_RIGHT,
113 0xc0,
114 L'\\'
115 },
116 {
117 BOXDRAW_UP_LEFT,
118 0xd9,
119 L'/'
120 },
121 {
122 BOXDRAW_VERTICAL_RIGHT,
123 0xc3,
124 L'|'
125 },
126 {
127 BOXDRAW_VERTICAL_LEFT,
128 0xb4,
129 L'|'
130 },
131 {
132 BOXDRAW_DOWN_HORIZONTAL,
133 0xc2,
134 L'+'
135 },
136 {
137 BOXDRAW_UP_HORIZONTAL,
138 0xc1,
139 L'+'
140 },
141 {
142 BOXDRAW_VERTICAL_HORIZONTAL,
143 0xc5,
144 L'+'
145 },
146 {
147 BOXDRAW_DOUBLE_HORIZONTAL,
148 0xcd,
149 L'-'
150 },
151 {
152 BOXDRAW_DOUBLE_VERTICAL,
153 0xba,
154 L'|'
155 },
156 {
157 BOXDRAW_DOWN_RIGHT_DOUBLE,
158 0xd5,
159 L'/'
160 },
161 {
162 BOXDRAW_DOWN_DOUBLE_RIGHT,
163 0xd6,
164 L'/'
165 },
166 {
167 BOXDRAW_DOUBLE_DOWN_RIGHT,
168 0xc9,
169 L'/'
170 },
171 {
172 BOXDRAW_DOWN_LEFT_DOUBLE,
173 0xb8,
174 L'\\'
175 },
176 {
177 BOXDRAW_DOWN_DOUBLE_LEFT,
178 0xb7,
179 L'\\'
180 },
181 {
182 BOXDRAW_DOUBLE_DOWN_LEFT,
183 0xbb,
184 L'\\'
185 },
186 {
187 BOXDRAW_UP_RIGHT_DOUBLE,
188 0xd4,
189 L'\\'
190 },
191 {
192 BOXDRAW_UP_DOUBLE_RIGHT,
193 0xd3,
194 L'\\'
195 },
196 {
197 BOXDRAW_DOUBLE_UP_RIGHT,
198 0xc8,
199 L'\\'
200 },
201 {
202 BOXDRAW_UP_LEFT_DOUBLE,
203 0xbe,
204 L'/'
205 },
206 {
207 BOXDRAW_UP_DOUBLE_LEFT,
208 0xbd,
209 L'/'
210 },
211 {
212 BOXDRAW_DOUBLE_UP_LEFT,
213 0xbc,
214 L'/'
215 },
216 {
217 BOXDRAW_VERTICAL_RIGHT_DOUBLE,
218 0xc6,
219 L'|'
220 },
221 {
222 BOXDRAW_VERTICAL_DOUBLE_RIGHT,
223 0xc7,
224 L'|'
225 },
226 {
227 BOXDRAW_DOUBLE_VERTICAL_RIGHT,
228 0xcc,
229 L'|'
230 },
231 {
232 BOXDRAW_VERTICAL_LEFT_DOUBLE,
233 0xb5,
234 L'|'
235 },
236 {
237 BOXDRAW_VERTICAL_DOUBLE_LEFT,
238 0xb6,
239 L'|'
240 },
241 {
242 BOXDRAW_DOUBLE_VERTICAL_LEFT,
243 0xb9,
244 L'|'
245 },
246 {
247 BOXDRAW_DOWN_HORIZONTAL_DOUBLE,
248 0xd1,
249 L'+'
250 },
251 {
252 BOXDRAW_DOWN_DOUBLE_HORIZONTAL,
253 0xd2,
254 L'+'
255 },
256 {
257 BOXDRAW_DOUBLE_DOWN_HORIZONTAL,
258 0xcb,
259 L'+'
260 },
261 {
262 BOXDRAW_UP_HORIZONTAL_DOUBLE,
263 0xcf,
264 L'+'
265 },
266 {
267 BOXDRAW_UP_DOUBLE_HORIZONTAL,
268 0xd0,
269 L'+'
270 },
271 {
272 BOXDRAW_DOUBLE_UP_HORIZONTAL,
273 0xca,
274 L'+'
275 },
276 {
277 BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE,
278 0xd8,
279 L'+'
280 },
281 {
282 BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL,
283 0xd7,
284 L'+'
285 },
286 {
287 BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL,
288 0xce,
289 L'+'
290 },
291
292 {
293 BLOCKELEMENT_FULL_BLOCK,
294 0xdb,
295 L'*'
296 },
297 {
298 BLOCKELEMENT_LIGHT_SHADE,
299 0xb0,
300 L'+'
301 },
302
303 {
304 GEOMETRICSHAPE_UP_TRIANGLE,
305 0x1e,
306 L'^'
307 },
308 {
309 GEOMETRICSHAPE_RIGHT_TRIANGLE,
310 0x10,
311 L'>'
312 },
313 {
314 GEOMETRICSHAPE_DOWN_TRIANGLE,
315 0x1f,
316 L'v'
317 },
318 {
319 GEOMETRICSHAPE_LEFT_TRIANGLE,
320 0x11,
321 L'<'
322 },
323
324 {
325 ARROW_LEFT,
326 0x3c,
327 L'<'
328 },
329
330 {
331 ARROW_UP,
332 0x18,
333 L'^'
334 },
335
336 {
337 ARROW_RIGHT,
338 0x3e,
339 L'>'
340 },
341
342 {
343 ARROW_DOWN,
344 0x19,
345 L'v'
346 },
347
348 {
349 0x0000,
350 0x00,
351 0x00
352 }
353 };
354
355 //
356 // Private worker functions
357 //
358 STATIC
359 VOID
360 SetVideoCursorPosition (
361 IN VGA_CLASS_DEV *VgaClassDev,
362 IN UINTN Column,
363 IN UINTN Row,
364 IN UINTN MaxColumn
365 );
366
367 STATIC
368 VOID
369 WriteCrtc (
370 IN VGA_CLASS_DEV *VgaClassDev,
371 IN UINT16 Address,
372 IN UINT8 Data
373 );
374
375 STATIC
376 BOOLEAN
377 LibIsValidTextGraphics (
378 IN CHAR16 Graphic,
379 OUT CHAR8 *PcAnsi, OPTIONAL
380 OUT CHAR8 *Ascii OPTIONAL
381 );
382
383 STATIC
384 BOOLEAN
385 IsValidAscii (
386 IN CHAR16 Ascii
387 );
388
389 STATIC
390 BOOLEAN
391 IsValidEfiCntlChar (
392 IN CHAR16 c
393 );
394
395 EFI_STATUS
396 EFIAPI
397 VgaClassDriverBindingSupported (
398 IN EFI_DRIVER_BINDING_PROTOCOL *This,
399 IN EFI_HANDLE Controller,
400 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
401 )
402 /*++
403
404 Routine Description:
405
406 Supported.
407
408 Arguments:
409
410 (Standard DriverBinding Protocol Supported() function)
411
412 Returns:
413
414 EFI_STATUS
415
416 --*/
417 // GC_TODO: This - add argument and description to function comment
418 // GC_TODO: Controller - add argument and description to function comment
419 // GC_TODO: RemainingDevicePath - add argument and description to function comment
420 {
421 EFI_STATUS Status;
422 EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
423
424 //
425 // Open the IO Abstraction(s) needed to perform the supported test
426 //
427 Status = gBS->OpenProtocol (
428 Controller,
429 &gEfiVgaMiniPortProtocolGuid,
430 (VOID **) &VgaMiniPort,
431 This->DriverBindingHandle,
432 Controller,
433 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
434 );
435 if (EFI_ERROR (Status)) {
436 return Status;
437 }
438 //
439 // Open the IO Abstraction(s) needed to perform the supported test
440 //
441 Status = gBS->OpenProtocol (
442 Controller,
443 &gEfiPciIoProtocolGuid,
444 NULL,
445 This->DriverBindingHandle,
446 Controller,
447 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
448 );
449 if (EFI_ERROR (Status)) {
450 return Status;
451 }
452
453 return Status;
454 }
455
456 EFI_STATUS
457 EFIAPI
458 VgaClassDriverBindingStart (
459 IN EFI_DRIVER_BINDING_PROTOCOL *This,
460 IN EFI_HANDLE Controller,
461 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
462 )
463 /*++
464
465 Routine Description:
466
467 Layers the Simple Text Output Protocol on top of the
468 VGA Mini Port Protocol
469
470 Arguments:
471
472 (Standard DriverBinding Protocol Start() function)
473
474 Returns:
475
476 EFI_STATUS
477
478 --*/
479 // GC_TODO: This - add argument and description to function comment
480 // GC_TODO: Controller - add argument and description to function comment
481 // GC_TODO: RemainingDevicePath - add argument and description to function comment
482 // GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
483 {
484 EFI_STATUS Status;
485 EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
486 EFI_PCI_IO_PROTOCOL *PciIo;
487 VGA_CLASS_DEV *VgaClassPrivate;
488 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
489
490 Status = gBS->HandleProtocol (
491 Controller,
492 &gEfiDevicePathProtocolGuid,
493 (VOID **) &DevicePath
494 );
495 if (EFI_ERROR (Status)) {
496 return Status;
497 }
498 //
499 // Report that VGA Class driver is being enabled
500 //
501 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
502 EFI_PROGRESS_CODE,
503 EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE,
504 DevicePath
505 );
506
507 //
508 // Open the IO Abstraction(s) needed
509 //
510 Status = gBS->OpenProtocol (
511 Controller,
512 &gEfiPciIoProtocolGuid,
513 (VOID **) &PciIo,
514 This->DriverBindingHandle,
515 Controller,
516 EFI_OPEN_PROTOCOL_GET_PROTOCOL
517 );
518 if (EFI_ERROR (Status)) {
519 return Status;
520 }
521
522 Status = gBS->OpenProtocol (
523 Controller,
524 &gEfiVgaMiniPortProtocolGuid,
525 (VOID **) &VgaMiniPort,
526 This->DriverBindingHandle,
527 Controller,
528 EFI_OPEN_PROTOCOL_BY_DRIVER
529 );
530 if (EFI_ERROR (Status)) {
531 return Status;
532 }
533 //
534 // Allocate the private device structure
535 //
536 Status = gBS->AllocatePool (
537 EfiBootServicesData,
538 sizeof (VGA_CLASS_DEV),
539 (VOID **) &VgaClassPrivate
540 );
541 if (EFI_ERROR (Status)) {
542 gBS->CloseProtocol (
543 Controller,
544 &gEfiVgaMiniPortProtocolGuid,
545 This->DriverBindingHandle,
546 Controller
547 );
548 return EFI_OUT_OF_RESOURCES;
549 }
550
551 ZeroMem (VgaClassPrivate, sizeof (VGA_CLASS_DEV));
552
553 //
554 // Initialize the private device structure
555 //
556 VgaClassPrivate->Signature = VGA_CLASS_DEV_SIGNATURE;
557 VgaClassPrivate->Handle = Controller;
558 VgaClassPrivate->VgaMiniPort = VgaMiniPort;
559 VgaClassPrivate->PciIo = PciIo;
560
561 VgaClassPrivate->SimpleTextOut.Reset = VgaClassReset;
562 VgaClassPrivate->SimpleTextOut.OutputString = VgaClassOutputString;
563 VgaClassPrivate->SimpleTextOut.TestString = VgaClassTestString;
564 VgaClassPrivate->SimpleTextOut.ClearScreen = VgaClassClearScreen;
565 VgaClassPrivate->SimpleTextOut.SetAttribute = VgaClassSetAttribute;
566 VgaClassPrivate->SimpleTextOut.SetCursorPosition = VgaClassSetCursorPosition;
567 VgaClassPrivate->SimpleTextOut.EnableCursor = VgaClassEnableCursor;
568 VgaClassPrivate->SimpleTextOut.QueryMode = VgaClassQueryMode;
569 VgaClassPrivate->SimpleTextOut.SetMode = VgaClassSetMode;
570
571 VgaClassPrivate->SimpleTextOut.Mode = &VgaClassPrivate->SimpleTextOutputMode;
572 VgaClassPrivate->SimpleTextOutputMode.MaxMode = VgaMiniPort->MaxMode;
573 VgaClassPrivate->DevicePath = DevicePath;
574
575 Status = VgaClassPrivate->SimpleTextOut.SetAttribute (
576 &VgaClassPrivate->SimpleTextOut,
577 EFI_TEXT_ATTR (EFI_WHITE,
578 EFI_BLACK)
579 );
580 if (EFI_ERROR (Status)) {
581 goto ErrorExit;
582 }
583
584 Status = VgaClassPrivate->SimpleTextOut.Reset (
585 &VgaClassPrivate->SimpleTextOut,
586 FALSE
587 );
588 if (EFI_ERROR (Status)) {
589 goto ErrorExit;
590 }
591
592 Status = VgaClassPrivate->SimpleTextOut.EnableCursor (
593 &VgaClassPrivate->SimpleTextOut,
594 TRUE
595 );
596 if (EFI_ERROR (Status)) {
597 goto ErrorExit;
598 }
599
600 Status = gBS->InstallMultipleProtocolInterfaces (
601 &Controller,
602 &gEfiSimpleTextOutProtocolGuid,
603 &VgaClassPrivate->SimpleTextOut,
604 NULL
605 );
606
607 return Status;
608
609 ErrorExit:
610 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
611 EFI_ERROR_CODE | EFI_ERROR_MINOR,
612 EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
613 DevicePath
614 );
615
616 return Status;
617
618 }
619
620 EFI_STATUS
621 EFIAPI
622 VgaClassDriverBindingStop (
623 IN EFI_DRIVER_BINDING_PROTOCOL *This,
624 IN EFI_HANDLE Controller,
625 IN UINTN NumberOfChildren,
626 IN EFI_HANDLE *ChildHandleBuffer
627 )
628 /*++
629
630 Routine Description:
631
632 Stop.
633
634 Arguments:
635
636 (Standard DriverBinding Protocol Stop() function)
637
638 Returns:
639
640 EFI_STATUS
641
642 --*/
643 // GC_TODO: This - add argument and description to function comment
644 // GC_TODO: Controller - add argument and description to function comment
645 // GC_TODO: NumberOfChildren - add argument and description to function comment
646 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
647 // GC_TODO: EFI_SUCCESS - add return value to function comment
648 {
649 EFI_STATUS Status;
650 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
651 VGA_CLASS_DEV *VgaClassPrivate;
652
653 Status = gBS->OpenProtocol (
654 Controller,
655 &gEfiSimpleTextOutProtocolGuid,
656 (VOID **) &SimpleTextOut,
657 This->DriverBindingHandle,
658 Controller,
659 EFI_OPEN_PROTOCOL_GET_PROTOCOL
660 );
661 if (EFI_ERROR (Status)) {
662 return Status;
663 }
664
665 VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (SimpleTextOut);
666
667 //
668 // Report that VGA Class driver is being disabled
669 //
670 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
671 EFI_PROGRESS_CODE,
672 EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE,
673 VgaClassPrivate->DevicePath
674 );
675
676 Status = gBS->UninstallProtocolInterface (
677 Controller,
678 &gEfiSimpleTextOutProtocolGuid,
679 &VgaClassPrivate->SimpleTextOut
680 );
681 if (EFI_ERROR (Status)) {
682 return Status;
683 }
684 //
685 // Release PCI I/O and VGA Mini Port Protocols on the controller handle.
686 //
687 gBS->CloseProtocol (
688 Controller,
689 &gEfiPciIoProtocolGuid,
690 This->DriverBindingHandle,
691 Controller
692 );
693
694 gBS->CloseProtocol (
695 Controller,
696 &gEfiVgaMiniPortProtocolGuid,
697 This->DriverBindingHandle,
698 Controller
699 );
700
701 gBS->FreePool (VgaClassPrivate);
702
703 return EFI_SUCCESS;
704 }
705 //
706 // Simple Text Output Protocol Functions
707 //
708 EFI_STATUS
709 EFIAPI
710 VgaClassReset (
711 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
712 IN BOOLEAN ExtendedVerification
713 )
714 /*++
715
716 Routine Description:
717
718 GC_TODO: Add function description
719
720 Arguments:
721
722 This - GC_TODO: add argument description
723 ExtendedVerification - GC_TODO: add argument description
724
725 Returns:
726
727 GC_TODO: add return values
728
729 --*/
730 {
731 EFI_STATUS Status;
732 VGA_CLASS_DEV *VgaClassPrivate;
733
734 VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (This);
735
736 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
737 EFI_PROGRESS_CODE,
738 EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_RESET,
739 VgaClassPrivate->DevicePath
740 );
741
742 This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
743
744 Status = This->SetMode (This, 0);
745 if (EFI_ERROR (Status)) {
746 return Status;
747 }
748
749 return This->ClearScreen (This);
750 }
751
752 EFI_STATUS
753 EFIAPI
754 VgaClassOutputString (
755 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
756 IN CHAR16 *WString
757 )
758 /*++
759
760 Routine Description:
761
762 GC_TODO: Add function description
763
764 Arguments:
765
766 This - GC_TODO: add argument description
767 WString - GC_TODO: add argument description
768
769 Returns:
770
771 EFI_SUCCESS - GC_TODO: Add description for return value
772
773 --*/
774 {
775 EFI_STATUS Status;
776 VGA_CLASS_DEV *VgaClassDev;
777 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
778 UINTN MaxColumn;
779 UINTN MaxRow;
780 UINT32 VideoChar;
781 CHAR8 GraphicChar;
782
783 VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
784
785 Mode = This->Mode;
786
787 Status = This->QueryMode (
788 This,
789 Mode->Mode,
790 &MaxColumn,
791 &MaxRow
792 );
793 if (EFI_ERROR (Status)) {
794 return Status;
795 }
796
797 for (; *WString != CHAR_NULL; WString++) {
798
799 switch (*WString) {
800 case CHAR_BACKSPACE:
801 if (Mode->CursorColumn > 0) {
802 Mode->CursorColumn--;
803 }
804 break;
805
806 case CHAR_LINEFEED:
807 if (Mode->CursorRow == (INT32) (MaxRow - 1)) {
808 //
809 // Scroll the screen by copying the contents
810 // of the VGA display up one line
811 //
812 VgaClassDev->PciIo->CopyMem (
813 VgaClassDev->PciIo,
814 EfiPciIoWidthUint32,
815 VgaClassDev->VgaMiniPort->VgaMemoryBar,
816 VgaClassDev->VgaMiniPort->VgaMemoryOffset,
817 VgaClassDev->VgaMiniPort->VgaMemoryBar,
818 VgaClassDev->VgaMiniPort->VgaMemoryOffset + MaxColumn * 2,
819 ((MaxRow - 1) * MaxColumn) >> 1
820 );
821
822 //
823 // Print Blank Line of spaces with the current color attributes
824 //
825 VideoChar = (Mode->Attribute << 8) | ' ';
826 VideoChar = (VideoChar << 16) | VideoChar;
827 VgaClassDev->PciIo->Mem.Write (
828 VgaClassDev->PciIo,
829 EfiPciIoWidthFillUint32,
830 VgaClassDev->VgaMiniPort->VgaMemoryBar,
831 VgaClassDev->VgaMiniPort->VgaMemoryOffset + (MaxRow - 1) * MaxColumn * 2,
832 MaxColumn >> 1,
833 &VideoChar
834 );
835 }
836
837 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
838 Mode->CursorRow++;
839 }
840 break;
841
842 case CHAR_CARRIAGE_RETURN:
843 Mode->CursorColumn = 0;
844 break;
845
846 default:
847 if (!LibIsValidTextGraphics (*WString, &GraphicChar, NULL)) {
848 //
849 // Just convert to ASCII
850 //
851 GraphicChar = (CHAR8) *WString;
852 if (!IsValidAscii (GraphicChar)) {
853 //
854 // Keep the API from supporting PCANSI Graphics chars
855 //
856 GraphicChar = '?';
857 }
858 }
859
860 VideoChar = (Mode->Attribute << 8) | GraphicChar;
861 VgaClassDev->PciIo->Mem.Write (
862 VgaClassDev->PciIo,
863 EfiPciIoWidthUint16,
864 VgaClassDev->VgaMiniPort->VgaMemoryBar,
865 VgaClassDev->VgaMiniPort->VgaMemoryOffset + ((Mode->CursorRow * MaxColumn + Mode->CursorColumn) * 2),
866 1,
867 &VideoChar
868 );
869
870 if (Mode->CursorColumn >= (INT32) (MaxColumn - 1)) {
871 This->OutputString (This, CrLfString);
872 } else {
873 Mode->CursorColumn++;
874 }
875 break;
876 }
877 }
878
879 SetVideoCursorPosition (
880 VgaClassDev,
881 (UINTN) Mode->CursorColumn,
882 (UINTN) Mode->CursorRow,
883 MaxColumn
884 );
885
886 return EFI_SUCCESS;
887 }
888
889 EFI_STATUS
890 EFIAPI
891 VgaClassTestString (
892 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
893 IN CHAR16 *WString
894 )
895 /*++
896
897 Routine Description:
898
899 GC_TODO: Add function description
900
901 Arguments:
902
903 This - GC_TODO: add argument description
904 WString - GC_TODO: add argument description
905
906 Returns:
907
908 EFI_UNSUPPORTED - GC_TODO: Add description for return value
909 EFI_SUCCESS - GC_TODO: Add description for return value
910
911 --*/
912 {
913 while (*WString != 0x0000) {
914 if (!(IsValidAscii (*WString) || IsValidEfiCntlChar (*WString) || LibIsValidTextGraphics (*WString, NULL, NULL))) {
915 return EFI_UNSUPPORTED;
916 }
917
918 WString++;
919 }
920
921 return EFI_SUCCESS;
922 }
923
924 EFI_STATUS
925 EFIAPI
926 VgaClassClearScreen (
927 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
928 )
929 /*++
930
931 Routine Description:
932
933 GC_TODO: Add function description
934
935 Arguments:
936
937 This - GC_TODO: add argument description
938
939 Returns:
940
941 EFI_SUCCESS - GC_TODO: Add description for return value
942
943 --*/
944 {
945 EFI_STATUS Status;
946 VGA_CLASS_DEV *VgaClassDev;
947 UINTN MaxRow;
948 UINTN MaxColumn;
949 UINT32 VideoChar;
950
951 VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
952
953 Status = This->QueryMode (
954 This,
955 This->Mode->Mode,
956 &MaxColumn,
957 &MaxRow
958 );
959 if (EFI_ERROR (Status)) {
960 return Status;
961 }
962
963 VideoChar = (This->Mode->Attribute << 8) | ' ';
964 VideoChar = (VideoChar << 16) | VideoChar;
965 VgaClassDev->PciIo->Mem.Write (
966 VgaClassDev->PciIo,
967 EfiPciIoWidthFillUint32,
968 VgaClassDev->VgaMiniPort->VgaMemoryBar,
969 VgaClassDev->VgaMiniPort->VgaMemoryOffset,
970 (MaxRow * MaxColumn) >> 1,
971 &VideoChar
972 );
973
974 This->SetCursorPosition (This, 0, 0);
975
976 return EFI_SUCCESS;
977 }
978
979 EFI_STATUS
980 EFIAPI
981 VgaClassSetAttribute (
982 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
983 IN UINTN Attribute
984 )
985 /*++
986
987 Routine Description:
988
989 GC_TODO: Add function description
990
991 Arguments:
992
993 This - GC_TODO: add argument description
994 Attribute - GC_TODO: add argument description
995
996 Returns:
997
998 EFI_SUCCESS - GC_TODO: Add description for return value
999 EFI_UNSUPPORTED - GC_TODO: Add description for return value
1000
1001 --*/
1002 {
1003 if (Attribute <= EFI_MAX_ATTRIBUTE) {
1004 This->Mode->Attribute = (INT32) Attribute;
1005 return EFI_SUCCESS;
1006 }
1007
1008 return EFI_UNSUPPORTED;
1009 }
1010
1011 EFI_STATUS
1012 EFIAPI
1013 VgaClassSetCursorPosition (
1014 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1015 IN UINTN Column,
1016 IN UINTN Row
1017 )
1018 /*++
1019
1020 Routine Description:
1021
1022 GC_TODO: Add function description
1023
1024 Arguments:
1025
1026 This - GC_TODO: add argument description
1027 Column - GC_TODO: add argument description
1028 Row - GC_TODO: add argument description
1029
1030 Returns:
1031
1032 EFI_UNSUPPORTED - GC_TODO: Add description for return value
1033 EFI_SUCCESS - GC_TODO: Add description for return value
1034
1035 --*/
1036 {
1037 EFI_STATUS Status;
1038 VGA_CLASS_DEV *VgaClassDev;
1039 UINTN MaxColumn;
1040 UINTN MaxRow;
1041
1042 VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
1043
1044 Status = This->QueryMode (
1045 This,
1046 This->Mode->Mode,
1047 &MaxColumn,
1048 &MaxRow
1049 );
1050 if (EFI_ERROR (Status)) {
1051 return Status;
1052 }
1053
1054 if (Column >= MaxColumn || Row >= MaxRow) {
1055 return EFI_UNSUPPORTED;
1056 }
1057
1058 SetVideoCursorPosition (VgaClassDev, Column, Row, MaxColumn);
1059
1060 This->Mode->CursorColumn = (INT32) Column;
1061 This->Mode->CursorRow = (INT32) Row;
1062
1063 return EFI_SUCCESS;
1064 }
1065
1066 EFI_STATUS
1067 EFIAPI
1068 VgaClassEnableCursor (
1069 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1070 IN BOOLEAN Visible
1071 )
1072 /*++
1073
1074 Routine Description:
1075
1076 GC_TODO: Add function description
1077
1078 Arguments:
1079
1080 This - GC_TODO: add argument description
1081 Visible - GC_TODO: add argument description
1082
1083 Returns:
1084
1085 EFI_SUCCESS - GC_TODO: Add description for return value
1086
1087 --*/
1088 {
1089 VGA_CLASS_DEV *VgaClassDev;
1090
1091 VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
1092 if (Visible) {
1093 switch (This->Mode->Mode) {
1094 case 1:
1095 WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x06);
1096 WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x07);
1097 break;
1098
1099 default:
1100 WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x0e);
1101 WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x0f);
1102 break;
1103 }
1104 } else {
1105 WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x20);
1106 }
1107
1108 This->Mode->CursorVisible = Visible;
1109 return EFI_SUCCESS;
1110 }
1111
1112 EFI_STATUS
1113 EFIAPI
1114 VgaClassQueryMode (
1115 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1116 IN UINTN ModeNumber,
1117 OUT UINTN *Columns,
1118 OUT UINTN *Rows
1119 )
1120 /*++
1121
1122 Routine Description:
1123
1124 GC_TODO: Add function description
1125
1126 Arguments:
1127
1128 This - GC_TODO: add argument description
1129 ModeNumber - GC_TODO: add argument description
1130 Columns - GC_TODO: add argument description
1131 Rows - GC_TODO: add argument description
1132
1133 Returns:
1134
1135 EFI_UNSUPPORTED - GC_TODO: Add description for return value
1136 EFI_UNSUPPORTED - GC_TODO: Add description for return value
1137 EFI_SUCCESS - GC_TODO: Add description for return value
1138
1139 --*/
1140 {
1141 if ((INT32) ModeNumber >= This->Mode->MaxMode) {
1142 *Columns = 0;
1143 *Rows = 0;
1144 return EFI_UNSUPPORTED;
1145 }
1146
1147 switch (ModeNumber) {
1148 case 0:
1149 *Columns = 80;
1150 *Rows = 25;
1151 break;
1152
1153 case 1:
1154 *Columns = 80;
1155 *Rows = 50;
1156 break;
1157
1158 default:
1159 *Columns = 0;
1160 *Rows = 0;
1161 return EFI_UNSUPPORTED;
1162 }
1163
1164 return EFI_SUCCESS;
1165 }
1166
1167 EFI_STATUS
1168 EFIAPI
1169 VgaClassSetMode (
1170 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
1171 IN UINTN ModeNumber
1172 )
1173 /*++
1174
1175 Routine Description:
1176
1177 GC_TODO: Add function description
1178
1179 Arguments:
1180
1181 This - GC_TODO: add argument description
1182 ModeNumber - GC_TODO: add argument description
1183
1184 Returns:
1185
1186 EFI_UNSUPPORTED - GC_TODO: Add description for return value
1187
1188 --*/
1189 {
1190 EFI_STATUS Status;
1191 VGA_CLASS_DEV *VgaClassDev;
1192
1193 VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
1194
1195 if ((INT32) ModeNumber >= This->Mode->MaxMode) {
1196 return EFI_UNSUPPORTED;
1197 }
1198
1199 This->ClearScreen (This);
1200
1201 This->Mode->Mode = (INT32) ModeNumber;
1202
1203 Status = VgaClassDev->VgaMiniPort->SetMode (VgaClassDev->VgaMiniPort, ModeNumber);
1204
1205 return Status;
1206 }
1207 //
1208 // Private Worker Functions
1209 //
1210 STATIC
1211 VOID
1212 SetVideoCursorPosition (
1213 IN VGA_CLASS_DEV *VgaClassDev,
1214 IN UINTN Column,
1215 IN UINTN Row,
1216 IN UINTN MaxColumn
1217 )
1218 /*++
1219
1220 Routine Description:
1221
1222 GC_TODO: Add function description
1223
1224 Arguments:
1225
1226 VgaClassDev - GC_TODO: add argument description
1227 Column - GC_TODO: add argument description
1228 Row - GC_TODO: add argument description
1229 MaxColumn - GC_TODO: add argument description
1230
1231 Returns:
1232
1233 GC_TODO: add return values
1234
1235 --*/
1236 {
1237 Column = Column & 0xff;
1238 Row = Row & 0xff;
1239 MaxColumn = MaxColumn & 0xff;
1240 WriteCrtc (
1241 VgaClassDev,
1242 CRTC_CURSOR_LOCATION_HIGH,
1243 (UINT8) ((Row * MaxColumn + Column) >> 8)
1244 );
1245 WriteCrtc (
1246 VgaClassDev,
1247 CRTC_CURSOR_LOCATION_LOW,
1248 (UINT8) ((Row * MaxColumn + Column) & 0xff)
1249 );
1250 }
1251
1252 STATIC
1253 VOID
1254 WriteCrtc (
1255 IN VGA_CLASS_DEV *VgaClassDev,
1256 IN UINT16 Address,
1257 IN UINT8 Data
1258 )
1259 /*++
1260
1261 Routine Description:
1262
1263 GC_TODO: Add function description
1264
1265 Arguments:
1266
1267 VgaClassDev - GC_TODO: add argument description
1268 Address - GC_TODO: add argument description
1269 Data - GC_TODO: add argument description
1270
1271 Returns:
1272
1273 GC_TODO: add return values
1274
1275 --*/
1276 {
1277 VgaClassDev->PciIo->Io.Write (
1278 VgaClassDev->PciIo,
1279 EfiPciIoWidthUint8,
1280 VgaClassDev->VgaMiniPort->CrtcAddressRegisterBar,
1281 VgaClassDev->VgaMiniPort->CrtcAddressRegisterOffset,
1282 1,
1283 &Address
1284 );
1285
1286 VgaClassDev->PciIo->Io.Write (
1287 VgaClassDev->PciIo,
1288 EfiPciIoWidthUint8,
1289 VgaClassDev->VgaMiniPort->CrtcDataRegisterBar,
1290 VgaClassDev->VgaMiniPort->CrtcDataRegisterOffset,
1291 1,
1292 &Data
1293 );
1294 }
1295
1296 STATIC
1297 BOOLEAN
1298 LibIsValidTextGraphics (
1299 IN CHAR16 Graphic,
1300 OUT CHAR8 *PcAnsi, OPTIONAL
1301 OUT CHAR8 *Ascii OPTIONAL
1302 )
1303 /*++
1304
1305 Routine Description:
1306
1307 Detects if a Unicode char is for Box Drawing text graphics.
1308
1309 Arguments:
1310
1311 Grphic - Unicode char to test.
1312
1313 PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.
1314
1315 Asci - Optional pointer to return Ascii equivalent of Graphic.
1316
1317 Returns:
1318
1319 TRUE if Gpaphic is a supported Unicode Box Drawing character.
1320
1321 --*/
1322 // GC_TODO: Graphic - add argument and description to function comment
1323 {
1324 UNICODE_TO_CHAR *Table;
1325
1326 if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
1327 //
1328 // Unicode drawing code charts are all in the 0x25xx range,
1329 // arrows are 0x21xx
1330 //
1331 return FALSE;
1332 }
1333
1334 for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
1335 if (Graphic == Table->Unicode) {
1336 if (PcAnsi) {
1337 *PcAnsi = Table->PcAnsi;
1338 }
1339
1340 if (Ascii) {
1341 *Ascii = Table->Ascii;
1342 }
1343
1344 return TRUE;
1345 }
1346 }
1347
1348 return FALSE;
1349 }
1350
1351 STATIC
1352 BOOLEAN
1353 IsValidAscii (
1354 IN CHAR16 Ascii
1355 )
1356 /*++
1357
1358 Routine Description:
1359
1360 GC_TODO: Add function description
1361
1362 Arguments:
1363
1364 Ascii - GC_TODO: add argument description
1365
1366 Returns:
1367
1368 GC_TODO: add return values
1369
1370 --*/
1371 {
1372 if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
1373 return TRUE;
1374 }
1375
1376 return FALSE;
1377 }
1378
1379 STATIC
1380 BOOLEAN
1381 IsValidEfiCntlChar (
1382 IN CHAR16 c
1383 )
1384 /*++
1385
1386 Routine Description:
1387
1388 GC_TODO: Add function description
1389
1390 Arguments:
1391
1392 c - GC_TODO: add argument description
1393
1394 Returns:
1395
1396 GC_TODO: add return values
1397
1398 --*/
1399 {
1400 if (c == CHAR_NULL || c == CHAR_BACKSPACE || c == CHAR_LINEFEED || c == CHAR_CARRIAGE_RETURN) {
1401 return TRUE;
1402 }
1403
1404 return FALSE;
1405 }