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