TianoCore EDK2 master
Loading...
Searching...
No Matches
Driver.c
Go to the documentation of this file.
1
11#include "Qemu.h"
13
14EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {
18 0x10,
19 NULL,
20 NULL
21};
22
23QEMU_VIDEO_CARD gQemuVideoCardList[] = {
24 {
25 PCI_CLASS_DISPLAY_VGA,
26 CIRRUS_LOGIC_VENDOR_ID,
27 CIRRUS_LOGIC_5430_DEVICE_ID,
28 QEMU_VIDEO_CIRRUS_5430,
29 L"Cirrus 5430"
30 },{
31 PCI_CLASS_DISPLAY_VGA,
32 CIRRUS_LOGIC_VENDOR_ID,
33 CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,
34 QEMU_VIDEO_CIRRUS_5430,
35 L"Cirrus 5430"
36 },{
37 PCI_CLASS_DISPLAY_VGA,
38 CIRRUS_LOGIC_VENDOR_ID,
39 CIRRUS_LOGIC_5446_DEVICE_ID,
40 QEMU_VIDEO_CIRRUS_5446,
41 L"Cirrus 5446"
42 },{
43 PCI_CLASS_DISPLAY_VGA,
44 0x1234,
45 0x1111,
46 QEMU_VIDEO_BOCHS_MMIO,
47 L"QEMU Standard VGA"
48 },{
49 PCI_CLASS_DISPLAY_OTHER,
50 0x1234,
51 0x1111,
52 QEMU_VIDEO_BOCHS_MMIO,
53 L"QEMU Standard VGA (secondary)"
54 },{
55 PCI_CLASS_DISPLAY_VGA,
56 0x1b36,
57 0x0100,
58 QEMU_VIDEO_BOCHS,
59 L"QEMU QXL VGA"
60 },{
61 PCI_CLASS_DISPLAY_VGA,
62 0x1af4,
63 0x1050,
64 QEMU_VIDEO_BOCHS_MMIO,
65 L"QEMU VirtIO VGA"
66 },{
67 PCI_CLASS_DISPLAY_VGA,
68 0x15ad,
69 0x0405,
70 QEMU_VIDEO_VMWARE_SVGA,
71 L"QEMU VMWare SVGA"
72 },{
73 0 /* end of list */
74 }
75};
76
77static QEMU_VIDEO_CARD *
78QemuVideoDetect (
79 IN UINT8 SubClass,
80 IN UINT16 VendorId,
81 IN UINT16 DeviceId
82 )
83{
84 UINTN Index = 0;
85
86 while (gQemuVideoCardList[Index].VendorId != 0) {
87 if ((gQemuVideoCardList[Index].SubClass == SubClass) &&
88 (gQemuVideoCardList[Index].VendorId == VendorId) &&
89 (gQemuVideoCardList[Index].DeviceId == DeviceId))
90 {
91 return gQemuVideoCardList + Index;
92 }
93
94 Index++;
95 }
96
97 return NULL;
98}
99
112EFIAPI
115 IN EFI_HANDLE Controller,
116 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
117 )
118{
119 EFI_STATUS Status;
120 EFI_PCI_IO_PROTOCOL *PciIo;
121 PCI_TYPE00 Pci;
122 QEMU_VIDEO_CARD *Card;
123
124 //
125 // Open the PCI I/O Protocol
126 //
127 Status = gBS->OpenProtocol (
128 Controller,
129 &gEfiPciIoProtocolGuid,
130 (VOID **)&PciIo,
131 This->DriverBindingHandle,
132 Controller,
133 EFI_OPEN_PROTOCOL_BY_DRIVER
134 );
135 if (EFI_ERROR (Status)) {
136 return Status;
137 }
138
139 //
140 // Read the PCI Configuration Header from the PCI Device
141 //
142 Status = PciIo->Pci.Read (
143 PciIo,
144 EfiPciIoWidthUint32,
145 0,
146 sizeof (Pci) / sizeof (UINT32),
147 &Pci
148 );
149 if (EFI_ERROR (Status)) {
150 goto Done;
151 }
152
153 Status = EFI_UNSUPPORTED;
154 if (!IS_PCI_DISPLAY (&Pci)) {
155 goto Done;
156 }
157
158 Card = QemuVideoDetect (Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
159 if (Card != NULL) {
160 DEBUG ((DEBUG_INFO, "QemuVideo: %s detected\n", Card->Name));
161 Status = EFI_SUCCESS;
162 }
163
164Done:
165 //
166 // Close the PCI I/O Protocol
167 //
168 gBS->CloseProtocol (
169 Controller,
170 &gEfiPciIoProtocolGuid,
171 This->DriverBindingHandle,
172 Controller
173 );
174
175 return Status;
176}
177
192EFIAPI
195 IN EFI_HANDLE Controller,
196 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
197 )
198{
199 EFI_TPL OldTpl;
200 EFI_STATUS Status;
202 BOOLEAN IsQxl;
203 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
204 ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
205 PCI_TYPE00 Pci;
206 QEMU_VIDEO_CARD *Card;
207 EFI_PCI_IO_PROTOCOL *ChildPciIo;
208 UINT64 SupportedVgaIo;
209
210 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
211
212 //
213 // Allocate Private context data for GOP interface.
214 //
215 Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));
216 if (Private == NULL) {
217 Status = EFI_OUT_OF_RESOURCES;
218 goto RestoreTpl;
219 }
220
221 //
222 // Set up context record
223 //
224 Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;
225
226 //
227 // Open PCI I/O Protocol
228 //
229 Status = gBS->OpenProtocol (
230 Controller,
231 &gEfiPciIoProtocolGuid,
232 (VOID **)&Private->PciIo,
233 This->DriverBindingHandle,
234 Controller,
235 EFI_OPEN_PROTOCOL_BY_DRIVER
236 );
237 if (EFI_ERROR (Status)) {
238 goto FreePrivate;
239 }
240
241 //
242 // Read the PCI Configuration Header from the PCI Device
243 //
244 Status = Private->PciIo->Pci.Read (
245 Private->PciIo,
246 EfiPciIoWidthUint32,
247 0,
248 sizeof (Pci) / sizeof (UINT32),
249 &Pci
250 );
251 if (EFI_ERROR (Status)) {
252 goto ClosePciIo;
253 }
254
255 //
256 // Determine card variant.
257 //
258 Card = QemuVideoDetect (Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
259 if (Card == NULL) {
260 Status = EFI_DEVICE_ERROR;
261 goto ClosePciIo;
262 }
263
264 Private->Variant = Card->Variant;
265
266 //
267 // IsQxl is based on the detected Card->Variant, which at a later point might
268 // not match Private->Variant.
269 //
270 IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);
271
272 //
273 // Save original PCI attributes
274 //
275 Status = Private->PciIo->Attributes (
276 Private->PciIo,
278 0,
279 &Private->OriginalPciAttributes
280 );
281
282 if (EFI_ERROR (Status)) {
283 goto ClosePciIo;
284 }
285
286 //
287 // Get supported PCI attributes
288 //
289 Status = Private->PciIo->Attributes (
290 Private->PciIo,
292 0,
293 &SupportedVgaIo
294 );
295 if (EFI_ERROR (Status)) {
296 goto ClosePciIo;
297 }
298
300 if ((SupportedVgaIo == 0) && IS_PCI_VGA (&Pci)) {
301 Status = EFI_UNSUPPORTED;
302 goto ClosePciIo;
303 }
304
305 //
306 // Set new PCI attributes
307 //
308 Status = Private->PciIo->Attributes (
309 Private->PciIo,
311 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | SupportedVgaIo,
312 NULL
313 );
314 if (EFI_ERROR (Status)) {
315 goto ClosePciIo;
316 }
317
318 //
319 // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+).
320 //
321 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
323
324 Status = Private->PciIo->GetBarAttributes (
325 Private->PciIo,
326 PCI_BAR_IDX2,
327 NULL,
328 (VOID **)&MmioDesc
329 );
330 if (EFI_ERROR (Status) ||
331 (MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM))
332 {
333 DEBUG ((DEBUG_INFO, "QemuVideo: No mmio bar, fallback to port io\n"));
334 Private->Variant = QEMU_VIDEO_BOCHS;
335 } else {
336 DEBUG ((
337 DEBUG_INFO,
338 "QemuVideo: Using mmio bar @ 0x%lx\n",
339 MmioDesc->AddrRangeMin
340 ));
341 }
342
343 if (!EFI_ERROR (Status)) {
344 FreePool (MmioDesc);
345 }
346 }
347
348 //
349 // VMWare SVGA is handled like Bochs (with port IO only).
350 //
351 if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {
352 Private->Variant = QEMU_VIDEO_BOCHS;
353 Private->FrameBufferVramBarIndex = PCI_BAR_IDX1;
354 }
355
356 //
357 // Check if accessing the bochs interface works.
358 //
359 if ((Private->Variant == QEMU_VIDEO_BOCHS_MMIO) ||
360 (Private->Variant == QEMU_VIDEO_BOCHS))
361 {
362 UINT16 BochsId;
363 BochsId = BochsRead (Private, VBE_DISPI_INDEX_ID);
364 if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {
365 DEBUG ((DEBUG_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId));
366 Status = EFI_DEVICE_ERROR;
367 goto RestoreAttributes;
368 }
369 }
370
371 //
372 // Get ParentDevicePath
373 //
374 Status = gBS->HandleProtocol (
375 Controller,
376 &gEfiDevicePathProtocolGuid,
377 (VOID **)&ParentDevicePath
378 );
379 if (EFI_ERROR (Status)) {
380 goto RestoreAttributes;
381 }
382
383 //
384 // Set Gop Device Path
385 //
386 ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
387 AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
388 AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
389 AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
390 SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
391
392 Private->GopDevicePath = AppendDevicePathNode (
393 ParentDevicePath,
394 (EFI_DEVICE_PATH_PROTOCOL *)&AcpiDeviceNode
395 );
396 if (Private->GopDevicePath == NULL) {
397 Status = EFI_OUT_OF_RESOURCES;
398 goto RestoreAttributes;
399 }
400
401 //
402 // Create new child handle and install the device path protocol on it.
403 //
404 Status = gBS->InstallMultipleProtocolInterfaces (
405 &Private->Handle,
406 &gEfiDevicePathProtocolGuid,
407 Private->GopDevicePath,
408 NULL
409 );
410 if (EFI_ERROR (Status)) {
411 goto FreeGopDevicePath;
412 }
413
414 //
415 // Construct video mode buffer
416 //
417 switch (Private->Variant) {
418 case QEMU_VIDEO_CIRRUS_5430:
419 case QEMU_VIDEO_CIRRUS_5446:
420 Status = QemuVideoCirrusModeSetup (Private);
421 break;
422 case QEMU_VIDEO_BOCHS_MMIO:
423 case QEMU_VIDEO_BOCHS:
424 Status = QemuVideoBochsModeSetup (Private, IsQxl);
425 break;
426 default:
427 ASSERT (FALSE);
428 Status = EFI_DEVICE_ERROR;
429 break;
430 }
431
432 if (EFI_ERROR (Status)) {
433 goto UninstallGopDevicePath;
434 }
435
436 //
437 // Start the GOP software stack.
438 //
439 Status = QemuVideoGraphicsOutputConstructor (Private);
440 if (EFI_ERROR (Status)) {
441 goto FreeModeData;
442 }
443
444 Status = gBS->InstallMultipleProtocolInterfaces (
445 &Private->Handle,
446 &gEfiGraphicsOutputProtocolGuid,
447 &Private->GraphicsOutput,
448 NULL
449 );
450 if (EFI_ERROR (Status)) {
451 goto DestructQemuVideoGraphics;
452 }
453
454 //
455 // Reference parent handle from child handle.
456 //
457 Status = gBS->OpenProtocol (
458 Controller,
459 &gEfiPciIoProtocolGuid,
460 (VOID **)&ChildPciIo,
461 This->DriverBindingHandle,
462 Private->Handle,
463 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
464 );
465 if (EFI_ERROR (Status)) {
466 goto UninstallGop;
467 }
468
469 gBS->RestoreTPL (OldTpl);
470 return EFI_SUCCESS;
471
472UninstallGop:
473 gBS->UninstallProtocolInterface (
474 Private->Handle,
475 &gEfiGraphicsOutputProtocolGuid,
476 &Private->GraphicsOutput
477 );
478
479DestructQemuVideoGraphics:
480 QemuVideoGraphicsOutputDestructor (Private);
481
482FreeModeData:
483 FreePool (Private->ModeData);
484
485UninstallGopDevicePath:
486 gBS->UninstallProtocolInterface (
487 Private->Handle,
488 &gEfiDevicePathProtocolGuid,
489 Private->GopDevicePath
490 );
491
492FreeGopDevicePath:
493 FreePool (Private->GopDevicePath);
494
495RestoreAttributes:
496 Private->PciIo->Attributes (
497 Private->PciIo,
499 Private->OriginalPciAttributes,
500 NULL
501 );
502
503ClosePciIo:
504 gBS->CloseProtocol (
505 Controller,
506 &gEfiPciIoProtocolGuid,
507 This->DriverBindingHandle,
508 Controller
509 );
510
511FreePrivate:
512 FreePool (Private);
513
514RestoreTpl:
515 gBS->RestoreTPL (OldTpl);
516
517 return Status;
518}
519
534EFIAPI
537 IN EFI_HANDLE Controller,
538 IN UINTN NumberOfChildren,
539 IN EFI_HANDLE *ChildHandleBuffer
540 )
541{
542 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
543
544 EFI_STATUS Status;
546
547 if (NumberOfChildren == 0) {
548 //
549 // Close the PCI I/O Protocol
550 //
551 gBS->CloseProtocol (
552 Controller,
553 &gEfiPciIoProtocolGuid,
554 This->DriverBindingHandle,
555 Controller
556 );
557 return EFI_SUCCESS;
558 }
559
560 //
561 // free all resources for whose access we need the child handle, because the
562 // child handle is going away
563 //
564 ASSERT (NumberOfChildren == 1);
565 Status = gBS->OpenProtocol (
566 ChildHandleBuffer[0],
567 &gEfiGraphicsOutputProtocolGuid,
568 (VOID **)&GraphicsOutput,
569 This->DriverBindingHandle,
570 Controller,
571 EFI_OPEN_PROTOCOL_GET_PROTOCOL
572 );
573 if (EFI_ERROR (Status)) {
574 return Status;
575 }
576
577 //
578 // Get our private context information
579 //
580 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
581 ASSERT (Private->Handle == ChildHandleBuffer[0]);
582
583 QemuVideoGraphicsOutputDestructor (Private);
584 //
585 // Remove the GOP protocol interface from the system
586 //
587 Status = gBS->UninstallMultipleProtocolInterfaces (
588 Private->Handle,
589 &gEfiGraphicsOutputProtocolGuid,
590 &Private->GraphicsOutput,
591 NULL
592 );
593
594 if (EFI_ERROR (Status)) {
595 return Status;
596 }
597
598 //
599 // Restore original PCI attributes
600 //
601 Private->PciIo->Attributes (
602 Private->PciIo,
604 Private->OriginalPciAttributes,
605 NULL
606 );
607
608 gBS->CloseProtocol (
609 Controller,
610 &gEfiPciIoProtocolGuid,
611 This->DriverBindingHandle,
612 Private->Handle
613 );
614
615 FreePool (Private->ModeData);
616 gBS->UninstallProtocolInterface (
617 Private->Handle,
618 &gEfiDevicePathProtocolGuid,
619 Private->GopDevicePath
620 );
621 FreePool (Private->GopDevicePath);
622
623 //
624 // Free our instance data
625 //
626 gBS->FreePool (Private);
627
628 return EFI_SUCCESS;
629}
630
641VOID
644 UINTN Address,
645 UINT8 Data
646 )
647{
648 Private->PciIo->Io.Write (
649 Private->PciIo,
650 EfiPciIoWidthUint8,
652 Address,
653 1,
654 &Data
655 );
656}
657
668VOID
671 UINTN Address,
672 UINT16 Data
673 )
674{
675 Private->PciIo->Io.Write (
676 Private->PciIo,
677 EfiPciIoWidthUint16,
679 Address,
680 1,
681 &Data
682 );
683}
684
694UINT8
697 UINTN Address
698 )
699{
700 UINT8 Data;
701
702 Private->PciIo->Io.Read (
703 Private->PciIo,
704 EfiPciIoWidthUint8,
706 Address,
707 1,
708 &Data
709 );
710 return Data;
711}
712
722UINT16
725 UINTN Address
726 )
727{
728 UINT16 Data;
729
730 Private->PciIo->Io.Read (
731 Private->PciIo,
732 EfiPciIoWidthUint16,
734 Address,
735 1,
736 &Data
737 );
738 return Data;
739}
740
753VOID
756 UINTN Index,
757 UINT8 Red,
758 UINT8 Green,
759 UINT8 Blue
760 )
761{
762 VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8)Index);
763 VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8)(Red >> 2));
764 VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8)(Green >> 2));
765 VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8)(Blue >> 2));
766}
767
776VOID
779 )
780{
781 UINTN Index;
782 UINTN RedIndex;
783 UINTN GreenIndex;
784 UINTN BlueIndex;
785
786 Index = 0;
787 for (RedIndex = 0; RedIndex < 8; RedIndex++) {
788 for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
789 for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
790 SetPaletteColor (Private, Index, (UINT8)(RedIndex << 5), (UINT8)(GreenIndex << 5), (UINT8)(BlueIndex << 6));
791 Index++;
792 }
793 }
794 }
795}
796
805VOID
808 )
809{
810 UINT32 Color;
811
812 Color = 0;
813 Private->PciIo->Mem.Write (
814 Private->PciIo,
815 EfiPciIoWidthFillUint32,
816 Private->FrameBufferVramBarIndex,
817 0,
818 0x400000 >> 2,
819 &Color
820 );
821}
822
831VOID
834 UINTN ScreenWidth,
835 UINTN ScreenHeight
836 )
837{
838}
839
849VOID
853 )
854{
855 UINT8 Byte;
856 UINTN Index;
857
858 outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
859 outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
860
861 for (Index = 0; Index < 15; Index++) {
862 outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
863 }
864
865 if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {
866 outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
867 Byte = (UINT8)((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
868 outb (Private, SEQ_DATA_REGISTER, Byte);
869 }
870
871 outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
872 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
873 outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
874 outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
875
876 for (Index = 0; Index < 28; Index++) {
877 outw (Private, CRTC_ADDRESS_REGISTER, (UINT16)((ModeData->CrtcSettings[Index] << 8) | Index));
878 }
879
880 for (Index = 0; Index < 9; Index++) {
881 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16)((GraphicsController[Index] << 8) | Index));
882 }
883
884 inb (Private, INPUT_STATUS_1_REGISTER);
885
886 for (Index = 0; Index < 21; Index++) {
887 outb (Private, ATT_ADDRESS_REGISTER, (UINT8)Index);
888 outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
889 }
890
891 outb (Private, ATT_ADDRESS_REGISTER, 0x20);
892
893 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
894 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
895 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
896 outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
897
898 SetDefaultPalette (Private);
899 ClearScreen (Private);
900}
901
902VOID
903BochsWrite (
905 UINT16 Reg,
906 UINT16 Data
907 )
908{
909 EFI_STATUS Status;
910
911 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
912 Status = Private->PciIo->Mem.Write (
913 Private->PciIo,
914 EfiPciIoWidthUint16,
915 PCI_BAR_IDX2,
916 0x500 + (Reg << 1),
917 1,
918 &Data
919 );
920 ASSERT_EFI_ERROR (Status);
921 } else {
922 outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
923 outw (Private, VBE_DISPI_IOPORT_DATA, Data);
924 }
925}
926
927UINT16
928BochsRead (
930 UINT16 Reg
931 )
932{
933 EFI_STATUS Status;
934 UINT16 Data;
935
936 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
937 Status = Private->PciIo->Mem.Read (
938 Private->PciIo,
939 EfiPciIoWidthUint16,
940 PCI_BAR_IDX2,
941 0x500 + (Reg << 1),
942 1,
943 &Data
944 );
945 ASSERT_EFI_ERROR (Status);
946 } else {
947 outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
948 Data = inw (Private, VBE_DISPI_IOPORT_DATA);
949 }
950
951 return Data;
952}
953
954VOID
955VgaOutb (
957 UINTN Reg,
958 UINT8 Data
959 )
960{
961 EFI_STATUS Status;
962
963 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
964 Status = Private->PciIo->Mem.Write (
965 Private->PciIo,
966 EfiPciIoWidthUint8,
967 PCI_BAR_IDX2,
968 0x400 - 0x3c0 + Reg,
969 1,
970 &Data
971 );
972 ASSERT_EFI_ERROR (Status);
973 } else {
974 outb (Private, Reg, Data);
975 }
976}
977
978STATIC
979UINT8
980VgaInb (
982 UINTN Reg
983 )
984{
985 EFI_STATUS Status;
986 UINT8 Data;
987
988 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
989 Data = 0;
990 Status = Private->PciIo->Mem.Read (
991 Private->PciIo,
992 EfiPciIoWidthUint8,
993 PCI_BAR_IDX2,
994 0x400 - 0x3c0 + Reg,
995 1,
996 &Data
997 );
998 ASSERT_EFI_ERROR (Status);
999 } else {
1000 Data = inb (Private, Reg);
1001 }
1002
1003 return Data;
1004}
1005
1006VOID
1007InitializeBochsGraphicsMode (
1008 QEMU_VIDEO_PRIVATE_DATA *Private,
1009 QEMU_VIDEO_MODE_DATA *ModeData
1010 )
1011{
1012 DEBUG ((
1013 DEBUG_INFO,
1014 "InitializeBochsGraphicsMode: %dx%d @ %d\n",
1015 ModeData->HorizontalResolution,
1016 ModeData->VerticalResolution,
1017 ModeData->ColorDepth
1018 ));
1019
1020 /* set color mode */
1021 VgaOutb (Private, MISC_OUTPUT_REGISTER, 0x01);
1022
1023 /* reset flip flop + unblank */
1024 VgaInb (Private, INPUT_STATUS_1_REGISTER);
1025 VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20);
1026
1027 BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0);
1028 BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0);
1029 BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0);
1030 BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0);
1031
1032 BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16)ModeData->ColorDepth);
1033 BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16)ModeData->HorizontalResolution);
1034 BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16)ModeData->HorizontalResolution);
1035 BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16)ModeData->VerticalResolution);
1036 BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16)ModeData->VerticalResolution);
1037
1038 BochsWrite (
1039 Private,
1040 VBE_DISPI_INDEX_ENABLE,
1041 VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED
1042 );
1043
1044 SetDefaultPalette (Private);
1045 ClearScreen (Private);
1046}
1047
1049EFIAPI
1050InitializeQemuVideo (
1051 IN EFI_HANDLE ImageHandle,
1052 IN EFI_SYSTEM_TABLE *SystemTable
1053 )
1054{
1055 EFI_STATUS Status;
1056
1058 ImageHandle,
1059 SystemTable,
1060 &gQemuVideoDriverBinding,
1061 ImageHandle,
1062 &gQemuVideoComponentName,
1063 &gQemuVideoComponentName2
1064 );
1065 ASSERT_EFI_ERROR (Status);
1066
1067 return Status;
1068}
UINT64 UINTN
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ACPI_DEVICE_PATH
Definition: DevicePath.h:190
#define ACPI_ADR_DP
Definition: DevicePath.h:264
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
MEM cycles 0xA0000-0xBFFFF (24 bit decode)
Definition: PciIo.h:52
#define EFI_PCI_IO_PASS_THROUGH_BAR
Special BAR that passes a memory or I/O cycle through unchanged.
Definition: PciIo.h:47
#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode)
Definition: PciIo.h:67
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoAttributeOperationSet
Definition: PciIo.h:107
@ EfiPciIoAttributeOperationSupported
Definition: PciIo.h:119
#define EFI_PCI_IO_ATTRIBUTE_VGA_IO
I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode)
Definition: PciIo.h:53
VOID SetDefaultPalette(QEMU_VIDEO_PRIVATE_DATA *Private)
Definition: Driver.c:777
VOID outb(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address, UINT8 Data)
Definition: Driver.c:642
UINT8 inb(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address)
Definition: Driver.c:695
EFI_STATUS EFIAPI QemuVideoControllerDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: Driver.c:193
VOID DrawLogo(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN ScreenWidth, UINTN ScreenHeight)
Definition: Driver.c:832
UINT16 inw(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address)
Definition: Driver.c:723
VOID InitializeCirrusGraphicsMode(QEMU_VIDEO_PRIVATE_DATA *Private, QEMU_VIDEO_CIRRUS_MODES *ModeData)
Definition: Driver.c:850
VOID outw(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address, UINT16 Data)
Definition: Driver.c:669
EFI_STATUS EFIAPI QemuVideoControllerDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: Driver.c:535
VOID SetPaletteColor(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Index, UINT8 Red, UINT8 Green, UINT8 Blue)
Definition: Driver.c:754
EFI_STATUS EFIAPI QemuVideoControllerDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: Driver.c:113
VOID ClearScreen(QEMU_VIDEO_PRIVATE_DATA *Private)
Definition: Driver.c:806
UINT8 GraphicsController[9]
Definition: Initialize.c:24
EFI_STATUS QemuVideoCirrusModeSetup(QEMU_VIDEO_PRIVATE_DATA *Private)
Definition: Initialize.c:158
UINT8 AttributeController[21]
Definition: Initialize.c:15
#define IS_PCI_DISPLAY(_p)
Definition: Pci22.h:349
#define IS_PCI_VGA(_p)
Definition: Pci22.h:360
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_PCI_IO_PROTOCOL_IO_MEM Write
Definition: PciIo.h:197
EFI_PCI_IO_PROTOCOL_IO_MEM Read
Definition: PciIo.h:193
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232