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