25 PCI_CLASS_DISPLAY_VGA,
26 CIRRUS_LOGIC_VENDOR_ID,
27 CIRRUS_LOGIC_5430_DEVICE_ID,
28 QEMU_VIDEO_CIRRUS_5430,
31 PCI_CLASS_DISPLAY_VGA,
32 CIRRUS_LOGIC_VENDOR_ID,
33 CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,
34 QEMU_VIDEO_CIRRUS_5430,
37 PCI_CLASS_DISPLAY_VGA,
38 CIRRUS_LOGIC_VENDOR_ID,
39 CIRRUS_LOGIC_5446_DEVICE_ID,
40 QEMU_VIDEO_CIRRUS_5446,
43 PCI_CLASS_DISPLAY_VGA,
46 QEMU_VIDEO_BOCHS_MMIO,
49 PCI_CLASS_DISPLAY_OTHER,
52 QEMU_VIDEO_BOCHS_MMIO,
53 L
"QEMU Standard VGA (secondary)"
55 PCI_CLASS_DISPLAY_VGA,
61 PCI_CLASS_DISPLAY_VGA,
64 QEMU_VIDEO_BOCHS_MMIO,
67 PCI_CLASS_DISPLAY_VGA,
70 QEMU_VIDEO_VMWARE_SVGA,
86 while (gQemuVideoCardList[Index].VendorId != 0) {
87 if ((gQemuVideoCardList[Index].SubClass == SubClass) &&
88 (gQemuVideoCardList[Index].VendorId == VendorId) &&
89 (gQemuVideoCardList[Index].DeviceId == DeviceId))
91 return gQemuVideoCardList + Index;
127 Status =
gBS->OpenProtocol (
129 &gEfiPciIoProtocolGuid,
131 This->DriverBindingHandle,
133 EFI_OPEN_PROTOCOL_BY_DRIVER
135 if (EFI_ERROR (Status)) {
142 Status = PciIo->Pci.
Read (
146 sizeof (Pci) /
sizeof (UINT32),
149 if (EFI_ERROR (Status)) {
153 Status = EFI_UNSUPPORTED;
158 Card = QemuVideoDetect (Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
160 DEBUG ((DEBUG_INFO,
"QemuVideo: %s detected\n", Card->Name));
170 &gEfiPciIoProtocolGuid,
171 This->DriverBindingHandle,
208 UINT64 SupportedVgaIo;
210 OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
216 if (Private ==
NULL) {
217 Status = EFI_OUT_OF_RESOURCES;
224 Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;
229 Status =
gBS->OpenProtocol (
231 &gEfiPciIoProtocolGuid,
232 (VOID **)&Private->PciIo,
233 This->DriverBindingHandle,
235 EFI_OPEN_PROTOCOL_BY_DRIVER
237 if (EFI_ERROR (Status)) {
244 Status = Private->PciIo->Pci.
Read (
248 sizeof (Pci) /
sizeof (UINT32),
251 if (EFI_ERROR (Status)) {
258 Card = QemuVideoDetect (Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
260 Status = EFI_DEVICE_ERROR;
264 Private->Variant = Card->Variant;
270 IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);
275 Status = Private->PciIo->Attributes (
279 &Private->OriginalPciAttributes
282 if (EFI_ERROR (Status)) {
289 Status = Private->PciIo->Attributes (
295 if (EFI_ERROR (Status)) {
300 if ((SupportedVgaIo == 0) &&
IS_PCI_VGA (&Pci)) {
301 Status = EFI_UNSUPPORTED;
308 Status = Private->PciIo->Attributes (
314 if (EFI_ERROR (Status)) {
321 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
324 Status = Private->PciIo->GetBarAttributes (
330 if (EFI_ERROR (Status) ||
331 (MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM))
333 DEBUG ((DEBUG_INFO,
"QemuVideo: No mmio bar, fallback to port io\n"));
334 Private->Variant = QEMU_VIDEO_BOCHS;
338 "QemuVideo: Using mmio bar @ 0x%lx\n",
339 MmioDesc->AddrRangeMin
343 if (!EFI_ERROR (Status)) {
351 if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {
352 Private->Variant = QEMU_VIDEO_BOCHS;
353 Private->FrameBufferVramBarIndex = PCI_BAR_IDX1;
359 if ((Private->Variant == QEMU_VIDEO_BOCHS_MMIO) ||
360 (Private->Variant == QEMU_VIDEO_BOCHS))
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;
374 Status =
gBS->HandleProtocol (
376 &gEfiDevicePathProtocolGuid,
377 (VOID **)&ParentDevicePath
379 if (EFI_ERROR (Status)) {
380 goto RestoreAttributes;
389 AcpiDeviceNode.
ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
396 if (Private->GopDevicePath ==
NULL) {
397 Status = EFI_OUT_OF_RESOURCES;
398 goto RestoreAttributes;
404 Status =
gBS->InstallMultipleProtocolInterfaces (
406 &gEfiDevicePathProtocolGuid,
407 Private->GopDevicePath,
410 if (EFI_ERROR (Status)) {
411 goto FreeGopDevicePath;
417 switch (Private->Variant) {
418 case QEMU_VIDEO_CIRRUS_5430:
419 case QEMU_VIDEO_CIRRUS_5446:
422 case QEMU_VIDEO_BOCHS_MMIO:
423 case QEMU_VIDEO_BOCHS:
424 Status = QemuVideoBochsModeSetup (Private, IsQxl);
428 Status = EFI_DEVICE_ERROR;
432 if (EFI_ERROR (Status)) {
433 goto UninstallGopDevicePath;
439 Status = QemuVideoGraphicsOutputConstructor (Private);
440 if (EFI_ERROR (Status)) {
444 Status =
gBS->InstallMultipleProtocolInterfaces (
446 &gEfiGraphicsOutputProtocolGuid,
447 &Private->GraphicsOutput,
450 if (EFI_ERROR (Status)) {
451 goto DestructQemuVideoGraphics;
457 Status =
gBS->OpenProtocol (
459 &gEfiPciIoProtocolGuid,
460 (VOID **)&ChildPciIo,
461 This->DriverBindingHandle,
463 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
465 if (EFI_ERROR (Status)) {
469 gBS->RestoreTPL (OldTpl);
473 gBS->UninstallProtocolInterface (
475 &gEfiGraphicsOutputProtocolGuid,
476 &Private->GraphicsOutput
479DestructQemuVideoGraphics:
480 QemuVideoGraphicsOutputDestructor (Private);
485UninstallGopDevicePath:
486 gBS->UninstallProtocolInterface (
488 &gEfiDevicePathProtocolGuid,
489 Private->GopDevicePath
496 Private->PciIo->Attributes (
499 Private->OriginalPciAttributes,
506 &gEfiPciIoProtocolGuid,
507 This->DriverBindingHandle,
515 gBS->RestoreTPL (OldTpl);
547 if (NumberOfChildren == 0) {
553 &gEfiPciIoProtocolGuid,
554 This->DriverBindingHandle,
564 ASSERT (NumberOfChildren == 1);
565 Status =
gBS->OpenProtocol (
566 ChildHandleBuffer[0],
567 &gEfiGraphicsOutputProtocolGuid,
568 (VOID **)&GraphicsOutput,
569 This->DriverBindingHandle,
571 EFI_OPEN_PROTOCOL_GET_PROTOCOL
573 if (EFI_ERROR (Status)) {
580 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
581 ASSERT (Private->Handle == ChildHandleBuffer[0]);
583 QemuVideoGraphicsOutputDestructor (Private);
587 Status =
gBS->UninstallMultipleProtocolInterfaces (
589 &gEfiGraphicsOutputProtocolGuid,
590 &Private->GraphicsOutput,
594 if (EFI_ERROR (Status)) {
601 Private->PciIo->Attributes (
604 Private->OriginalPciAttributes,
610 &gEfiPciIoProtocolGuid,
611 This->DriverBindingHandle,
616 gBS->UninstallProtocolInterface (
618 &gEfiDevicePathProtocolGuid,
619 Private->GopDevicePath
626 gBS->FreePool (Private);
648 Private->PciIo->Io.
Write (
675 Private->PciIo->Io.
Write (
702 Private->PciIo->Io.
Read (
730 Private->PciIo->Io.
Read (
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));
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));
813 Private->PciIo->Mem.
Write (
815 EfiPciIoWidthFillUint32,
816 Private->FrameBufferVramBarIndex,
858 outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
859 outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
861 for (Index = 0; Index < 15; Index++) {
862 outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
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);
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);
876 for (Index = 0; Index < 28; Index++) {
877 outw (Private, CRTC_ADDRESS_REGISTER, (UINT16)((ModeData->CrtcSettings[Index] << 8) | Index));
880 for (Index = 0; Index < 9; Index++) {
884 inb (Private, INPUT_STATUS_1_REGISTER);
886 for (Index = 0; Index < 21; Index++) {
887 outb (Private, ATT_ADDRESS_REGISTER, (UINT8)Index);
891 outb (Private, ATT_ADDRESS_REGISTER, 0x20);
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);
911 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
912 Status = Private->PciIo->Mem.
Write (
922 outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
923 outw (Private, VBE_DISPI_IOPORT_DATA, Data);
936 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
937 Status = Private->PciIo->Mem.
Read (
947 outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
948 Data =
inw (Private, VBE_DISPI_IOPORT_DATA);
963 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
964 Status = Private->PciIo->Mem.
Write (
974 outb (Private, Reg, Data);
988 if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
990 Status = Private->PciIo->Mem.
Read (
1000 Data =
inb (Private, Reg);
1007InitializeBochsGraphicsMode (
1014 "InitializeBochsGraphicsMode: %dx%d @ %d\n",
1015 ModeData->HorizontalResolution,
1016 ModeData->VerticalResolution,
1017 ModeData->ColorDepth
1021 VgaOutb (Private, MISC_OUTPUT_REGISTER, 0x01);
1024 VgaInb (Private, INPUT_STATUS_1_REGISTER);
1025 VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20);
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);
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);
1040 VBE_DISPI_INDEX_ENABLE,
1041 VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED
1050InitializeQemuVideo (
1060 &gQemuVideoDriverBinding,
1062 &gQemuVideoComponentName,
1063 &gQemuVideoComponentName2
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
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 ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
MEM cycles 0xA0000-0xBFFFF (24 bit decode)
#define EFI_PCI_IO_PASS_THROUGH_BAR
Special BAR that passes a memory or I/O cycle through unchanged.
#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode)
@ EfiPciIoAttributeOperationGet
@ EfiPciIoAttributeOperationEnable
@ EfiPciIoAttributeOperationSet
@ EfiPciIoAttributeOperationSupported
#define EFI_PCI_IO_ATTRIBUTE_VGA_IO
I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode)
VOID SetDefaultPalette(QEMU_VIDEO_PRIVATE_DATA *Private)
VOID outb(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address, UINT8 Data)
UINT8 inb(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address)
EFI_STATUS EFIAPI QemuVideoControllerDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
VOID DrawLogo(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN ScreenWidth, UINTN ScreenHeight)
UINT16 inw(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address)
VOID InitializeCirrusGraphicsMode(QEMU_VIDEO_PRIVATE_DATA *Private, QEMU_VIDEO_CIRRUS_MODES *ModeData)
VOID outw(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Address, UINT16 Data)
EFI_STATUS EFIAPI QemuVideoControllerDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
VOID SetPaletteColor(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Index, UINT8 Red, UINT8 Green, UINT8 Blue)
EFI_STATUS EFIAPI QemuVideoControllerDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
VOID ClearScreen(QEMU_VIDEO_PRIVATE_DATA *Private)
UINT8 GraphicsController[9]
EFI_STATUS QemuVideoCirrusModeSetup(QEMU_VIDEO_PRIVATE_DATA *Private)
UINT8 AttributeController[21]
#define IS_PCI_DISPLAY(_p)
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
EFI_PCI_IO_PROTOCOL_IO_MEM Read
EFI_PCI_IO_PROTOCOL_CONFIG Read