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