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