X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FQemuVideoDxe%2FDriver.c;h=b91909a14e590b262d520e4383b02820109313a9;hb=HEAD;hp=2194cbef44a47b517112c81692bdb1352bdecf60;hpb=90803342b1b6060f1ddbb1aaea54fdf86a7ff9ad;p=mirror_edk2.git diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c index 2194cbef44..c28171d137 100644 --- a/OvmfPkg/QemuVideoDxe/Driver.c +++ b/OvmfPkg/QemuVideoDxe/Driver.c @@ -2,22 +2,16 @@ This driver is a sample implementation of the Graphics Output Protocol for the QEMU (Cirrus Logic 5446) video controller. - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "Qemu.h" #include -EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = { +EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = { QemuVideoControllerDriverSupported, QemuVideoControllerDriverStart, QemuVideoControllerDriverStop, @@ -26,52 +20,80 @@ EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = { NULL }; -QEMU_VIDEO_CARD gQemuVideoCardList[] = { - { - CIRRUS_LOGIC_VENDOR_ID, - CIRRUS_LOGIC_5430_DEVICE_ID, - QEMU_VIDEO_CIRRUS_5430, - L"Cirrus 5430" - },{ - CIRRUS_LOGIC_VENDOR_ID, - CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID, - QEMU_VIDEO_CIRRUS_5430, - L"Cirrus 5430" - },{ - CIRRUS_LOGIC_VENDOR_ID, - CIRRUS_LOGIC_5446_DEVICE_ID, - QEMU_VIDEO_CIRRUS_5446, - L"Cirrus 5446" - },{ - 0x1234, - 0x1111, - QEMU_VIDEO_BOCHS_MMIO, - L"QEMU Standard VGA" - },{ - 0x1b36, - 0x0100, - QEMU_VIDEO_BOCHS, - L"QEMU QXL VGA" - },{ - 0 /* end of list */ - } +QEMU_VIDEO_CARD gQemuVideoCardList[] = { + { + PCI_CLASS_DISPLAY_VGA, + CIRRUS_LOGIC_VENDOR_ID, + CIRRUS_LOGIC_5430_DEVICE_ID, + QEMU_VIDEO_CIRRUS_5430, + L"Cirrus 5430" + },{ + PCI_CLASS_DISPLAY_VGA, + CIRRUS_LOGIC_VENDOR_ID, + CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID, + QEMU_VIDEO_CIRRUS_5430, + L"Cirrus 5430" + },{ + PCI_CLASS_DISPLAY_VGA, + CIRRUS_LOGIC_VENDOR_ID, + CIRRUS_LOGIC_5446_DEVICE_ID, + QEMU_VIDEO_CIRRUS_5446, + L"Cirrus 5446" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x1234, + 0x1111, + QEMU_VIDEO_BOCHS_MMIO, + L"QEMU Standard VGA" + },{ + PCI_CLASS_DISPLAY_OTHER, + 0x1234, + 0x1111, + QEMU_VIDEO_BOCHS_MMIO, + L"QEMU Standard VGA (secondary)" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x1b36, + 0x0100, + QEMU_VIDEO_BOCHS, + L"QEMU QXL VGA" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x1af4, + 0x1050, + QEMU_VIDEO_BOCHS_MMIO, + L"QEMU VirtIO VGA" + },{ + PCI_CLASS_DISPLAY_VGA, + 0x15ad, + 0x0405, + QEMU_VIDEO_VMWARE_SVGA, + L"QEMU VMWare SVGA" + },{ + 0 /* end of list */ + } }; -static QEMU_VIDEO_CARD* -QemuVideoDetect( - IN UINT16 VendorId, - IN UINT16 DeviceId +static QEMU_VIDEO_CARD * +QemuVideoDetect ( + IN UINT8 SubClass, + IN UINT16 VendorId, + IN UINT16 DeviceId ) { - UINTN Index = 0; + UINTN Index = 0; while (gQemuVideoCardList[Index].VendorId != 0) { - if (gQemuVideoCardList[Index].VendorId == VendorId && - gQemuVideoCardList[Index].DeviceId == DeviceId) { + if ((gQemuVideoCardList[Index].SubClass == SubClass) && + (gQemuVideoCardList[Index].VendorId == VendorId) && + (gQemuVideoCardList[Index].DeviceId == DeviceId)) + { return gQemuVideoCardList + Index; } + Index++; } + return NULL; } @@ -89,15 +111,15 @@ QemuVideoDetect( EFI_STATUS EFIAPI QemuVideoControllerDriverSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 Pci; - QEMU_VIDEO_CARD *Card; + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + QEMU_VIDEO_CARD *Card; // // Open the PCI I/O Protocol @@ -105,7 +127,7 @@ QemuVideoControllerDriverSupported ( Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, + (VOID **)&PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER @@ -129,9 +151,13 @@ QemuVideoControllerDriverSupported ( } Status = EFI_UNSUPPORTED; - Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId); + if (!IS_PCI_DISPLAY (&Pci)) { + goto Done; + } + + Card = QemuVideoDetect (Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId); if (Card != NULL) { - DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name)); + DEBUG ((DEBUG_INFO, "QemuVideo: %s detected\n", Card->Name)); Status = EFI_SUCCESS; } @@ -140,11 +166,11 @@ Done: // Close the PCI I/O Protocol // gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); return Status; } @@ -165,24 +191,26 @@ Done: EFI_STATUS EFIAPI QemuVideoControllerDriverStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { - EFI_TPL OldTpl; - EFI_STATUS Status; - QEMU_VIDEO_PRIVATE_DATA *Private; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - ACPI_ADR_DEVICE_PATH AcpiDeviceNode; - PCI_TYPE00 Pci; - QEMU_VIDEO_CARD *Card; - EFI_PCI_IO_PROTOCOL *ChildPciIo; + EFI_TPL OldTpl; + EFI_STATUS Status; + QEMU_VIDEO_PRIVATE_DATA *Private; + BOOLEAN IsQxl; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + ACPI_ADR_DEVICE_PATH AcpiDeviceNode; + PCI_TYPE00 Pci; + QEMU_VIDEO_CARD *Card; + EFI_PCI_IO_PROTOCOL *ChildPciIo; + UINT64 SupportedVgaIo; OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // - // Allocate Private context data for GOP inteface. + // Allocate Private context data for GOP interface. // Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA)); if (Private == NULL) { @@ -193,7 +221,7 @@ QemuVideoControllerDriverStart ( // // Set up context record // - Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE; + Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE; // // Open PCI I/O Protocol @@ -201,7 +229,7 @@ QemuVideoControllerDriverStart ( Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, - (VOID **) &Private->PciIo, + (VOID **)&Private->PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER @@ -214,12 +242,12 @@ QemuVideoControllerDriverStart ( // Read the PCI Configuration Header from the PCI Device // Status = Private->PciIo->Pci.Read ( - Private->PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (Pci) / sizeof (UINT32), - &Pci - ); + Private->PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); if (EFI_ERROR (Status)) { goto ClosePciIo; } @@ -227,36 +255,62 @@ QemuVideoControllerDriverStart ( // // Determine card variant. // - Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId); + Card = QemuVideoDetect (Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId); if (Card == NULL) { Status = EFI_DEVICE_ERROR; goto ClosePciIo; } + Private->Variant = Card->Variant; + // + // IsQxl is based on the detected Card->Variant, which at a later point might + // not match Private->Variant. + // + IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS); + // // Save original PCI attributes // Status = Private->PciIo->Attributes ( - Private->PciIo, - EfiPciIoAttributeOperationGet, - 0, - &Private->OriginalPciAttributes - ); + Private->PciIo, + EfiPciIoAttributeOperationGet, + 0, + &Private->OriginalPciAttributes + ); + + if (EFI_ERROR (Status)) { + goto ClosePciIo; + } + // + // Get supported PCI attributes + // + Status = Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &SupportedVgaIo + ); if (EFI_ERROR (Status)) { goto ClosePciIo; } + SupportedVgaIo &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16); + if ((SupportedVgaIo == 0) && IS_PCI_VGA (&Pci)) { + Status = EFI_UNSUPPORTED; + goto ClosePciIo; + } + // // Set new PCI attributes // Status = Private->PciIo->Attributes ( - Private->PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO, - NULL - ); + Private->PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | SupportedVgaIo, + NULL + ); if (EFI_ERROR (Status)) { goto ClosePciIo; } @@ -265,21 +319,25 @@ QemuVideoControllerDriverStart ( // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+). // if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; Status = Private->PciIo->GetBarAttributes ( - Private->PciIo, - PCI_BAR_IDX2, - NULL, - (VOID**) &MmioDesc - ); + Private->PciIo, + PCI_BAR_IDX2, + NULL, + (VOID **)&MmioDesc + ); if (EFI_ERROR (Status) || - MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) { - DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n")); + (MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM)) + { + DEBUG ((DEBUG_INFO, "QemuVideo: No mmio bar, fallback to port io\n")); Private->Variant = QEMU_VIDEO_BOCHS; } else { - DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n", - MmioDesc->AddrRangeMin)); + DEBUG (( + DEBUG_INFO, + "QemuVideo: Using mmio bar @ 0x%lx\n", + MmioDesc->AddrRangeMin + )); } if (!EFI_ERROR (Status)) { @@ -287,15 +345,24 @@ QemuVideoControllerDriverStart ( } } + // + // VMWare SVGA is handled like Bochs (with port IO only). + // + if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) { + Private->Variant = QEMU_VIDEO_BOCHS; + Private->FrameBufferVramBarIndex = PCI_BAR_IDX1; + } + // // Check if accessing the bochs interface works. // - if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO || - Private->Variant == QEMU_VIDEO_BOCHS) { - UINT16 BochsId; - BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID); + if ((Private->Variant == QEMU_VIDEO_BOCHS_MMIO) || + (Private->Variant == QEMU_VIDEO_BOCHS)) + { + UINT16 BochsId; + BochsId = BochsRead (Private, VBE_DISPI_INDEX_ID); if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) { - DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId)); + DEBUG ((DEBUG_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId)); Status = EFI_DEVICE_ERROR; goto RestoreAttributes; } @@ -307,7 +374,7 @@ QemuVideoControllerDriverStart ( Status = gBS->HandleProtocol ( Controller, &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath + (VOID **)&ParentDevicePath ); if (EFI_ERROR (Status)) { goto RestoreAttributes; @@ -317,15 +384,15 @@ QemuVideoControllerDriverStart ( // Set Gop Device Path // ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); - AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH; + AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH; AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; - AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0); + AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0); SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH)); Private->GopDevicePath = AppendDevicePathNode ( - ParentDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode - ); + ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&AcpiDeviceNode + ); if (Private->GopDevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto RestoreAttributes; @@ -348,19 +415,20 @@ QemuVideoControllerDriverStart ( // Construct video mode buffer // switch (Private->Variant) { - case QEMU_VIDEO_CIRRUS_5430: - case QEMU_VIDEO_CIRRUS_5446: - Status = QemuVideoCirrusModeSetup (Private); - break; - case QEMU_VIDEO_BOCHS_MMIO: - case QEMU_VIDEO_BOCHS: - Status = QemuVideoBochsModeSetup (Private); - break; - default: - ASSERT (FALSE); - Status = EFI_DEVICE_ERROR; - break; + case QEMU_VIDEO_CIRRUS_5430: + case QEMU_VIDEO_CIRRUS_5446: + Status = QemuVideoCirrusModeSetup (Private); + break; + case QEMU_VIDEO_BOCHS_MMIO: + case QEMU_VIDEO_BOCHS: + Status = QemuVideoBochsModeSetup (Private, IsQxl); + break; + default: + ASSERT (FALSE); + Status = EFI_DEVICE_ERROR; + break; } + if (EFI_ERROR (Status)) { goto UninstallGopDevicePath; } @@ -387,28 +455,35 @@ QemuVideoControllerDriverStart ( // Reference parent handle from child handle. // Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &ChildPciIo, - This->DriverBindingHandle, - Private->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); + Controller, + &gEfiPciIoProtocolGuid, + (VOID **)&ChildPciIo, + This->DriverBindingHandle, + Private->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); if (EFI_ERROR (Status)) { goto UninstallGop; } - if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO || - Private->Variant == QEMU_VIDEO_BOCHS) { + #if defined MDE_CPU_IA32 || defined MDE_CPU_X64 + if ((Private->Variant == QEMU_VIDEO_BOCHS_MMIO) || + (Private->Variant == QEMU_VIDEO_BOCHS)) + { InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase); } + #endif + gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; UninstallGop: - gBS->UninstallProtocolInterface (Private->Handle, - &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput); + gBS->UninstallProtocolInterface ( + Private->Handle, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput + ); DestructQemuVideoGraphics: QemuVideoGraphicsOutputDestructor (Private); @@ -417,19 +492,30 @@ FreeModeData: FreePool (Private->ModeData); UninstallGopDevicePath: - gBS->UninstallProtocolInterface (Private->Handle, - &gEfiDevicePathProtocolGuid, Private->GopDevicePath); + gBS->UninstallProtocolInterface ( + Private->Handle, + &gEfiDevicePathProtocolGuid, + Private->GopDevicePath + ); FreeGopDevicePath: FreePool (Private->GopDevicePath); RestoreAttributes: - Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet, - Private->OriginalPciAttributes, NULL); + Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationSet, + Private->OriginalPciAttributes, + NULL + ); ClosePciIo: - gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, Controller); + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); FreePrivate: FreePool (Private); @@ -456,15 +542,15 @@ RestoreTpl: EFI_STATUS EFIAPI QemuVideoControllerDriverStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer ) { - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_STATUS Status; + EFI_STATUS Status; QEMU_VIDEO_PRIVATE_DATA *Private; if (NumberOfChildren == 0) { @@ -472,11 +558,11 @@ QemuVideoControllerDriverStop ( // Close the PCI I/O Protocol // gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); return EFI_SUCCESS; } @@ -488,7 +574,7 @@ QemuVideoControllerDriverStop ( Status = gBS->OpenProtocol ( ChildHandleBuffer[0], &gEfiGraphicsOutputProtocolGuid, - (VOID **) &GraphicsOutput, + (VOID **)&GraphicsOutput, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL @@ -522,22 +608,25 @@ QemuVideoControllerDriverStop ( // Restore original PCI attributes // Private->PciIo->Attributes ( - Private->PciIo, - EfiPciIoAttributeOperationSet, - Private->OriginalPciAttributes, - NULL - ); + Private->PciIo, + EfiPciIoAttributeOperationSet, + Private->OriginalPciAttributes, + NULL + ); gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Private->Handle - ); + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Private->Handle + ); FreePool (Private->ModeData); - gBS->UninstallProtocolInterface (Private->Handle, - &gEfiDevicePathProtocolGuid, Private->GopDevicePath); + gBS->UninstallProtocolInterface ( + Private->Handle, + &gEfiDevicePathProtocolGuid, + Private->GopDevicePath + ); FreePool (Private->GopDevicePath); // @@ -561,18 +650,18 @@ QemuVideoControllerDriverStop ( VOID outb ( QEMU_VIDEO_PRIVATE_DATA *Private, - UINTN Address, - UINT8 Data + UINTN Address, + UINT8 Data ) { Private->PciIo->Io.Write ( - Private->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - Address, - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); } /** @@ -588,18 +677,18 @@ outb ( VOID outw ( QEMU_VIDEO_PRIVATE_DATA *Private, - UINTN Address, - UINT16 Data + UINTN Address, + UINT16 Data ) { Private->PciIo->Io.Write ( - Private->PciIo, - EfiPciIoWidthUint16, - EFI_PCI_IO_PASS_THROUGH_BAR, - Address, - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); } /** @@ -614,19 +703,19 @@ outw ( UINT8 inb ( QEMU_VIDEO_PRIVATE_DATA *Private, - UINTN Address + UINTN Address ) { - UINT8 Data; + UINT8 Data; Private->PciIo->Io.Read ( - Private->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_IO_PASS_THROUGH_BAR, - Address, - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint8, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); return Data; } @@ -642,19 +731,19 @@ inb ( UINT16 inw ( QEMU_VIDEO_PRIVATE_DATA *Private, - UINTN Address + UINTN Address ) { UINT16 Data; Private->PciIo->Io.Read ( - Private->PciIo, - EfiPciIoWidthUint16, - EFI_PCI_IO_PASS_THROUGH_BAR, - Address, - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint16, + EFI_PCI_IO_PASS_THROUGH_BAR, + Address, + 1, + &Data + ); return Data; } @@ -673,16 +762,16 @@ inw ( VOID SetPaletteColor ( QEMU_VIDEO_PRIVATE_DATA *Private, - UINTN Index, - UINT8 Red, - UINT8 Green, - UINT8 Blue + UINTN Index, + UINT8 Red, + UINT8 Green, + UINT8 Blue ) { - VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index); - VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2)); - VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2)); - VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2)); + VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8)Index); + VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8)(Red >> 2)); + VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8)(Green >> 2)); + VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8)(Blue >> 2)); } /** @@ -698,16 +787,16 @@ SetDefaultPalette ( QEMU_VIDEO_PRIVATE_DATA *Private ) { - UINTN Index; - UINTN RedIndex; - UINTN GreenIndex; - UINTN BlueIndex; + UINTN Index; + UINTN RedIndex; + UINTN GreenIndex; + UINTN BlueIndex; Index = 0; for (RedIndex = 0; RedIndex < 8; RedIndex++) { for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) { for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) { - SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6)); + SetPaletteColor (Private, Index, (UINT8)(RedIndex << 5), (UINT8)(GreenIndex << 5), (UINT8)(BlueIndex << 6)); Index++; } } @@ -733,7 +822,7 @@ ClearScreen ( Private->PciIo->Mem.Write ( Private->PciIo, EfiPciIoWidthFillUint32, - 0, + Private->FrameBufferVramBarIndex, 0, 0x400000 >> 2, &Color @@ -751,8 +840,8 @@ ClearScreen ( VOID DrawLogo ( QEMU_VIDEO_PRIVATE_DATA *Private, - UINTN ScreenWidth, - UINTN ScreenHeight + UINTN ScreenWidth, + UINTN ScreenHeight ) { } @@ -772,8 +861,8 @@ InitializeCirrusGraphicsMode ( QEMU_VIDEO_CIRRUS_MODES *ModeData ) { - UINT8 Byte; - UINTN Index; + UINT8 Byte; + UINTN Index; outw (Private, SEQ_ADDRESS_REGISTER, 0x1206); outw (Private, SEQ_ADDRESS_REGISTER, 0x0012); @@ -784,7 +873,7 @@ InitializeCirrusGraphicsMode ( if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) { outb (Private, SEQ_ADDRESS_REGISTER, 0x0f); - Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30); + Byte = (UINT8)((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30); outb (Private, SEQ_DATA_REGISTER, Byte); } @@ -794,17 +883,17 @@ InitializeCirrusGraphicsMode ( outw (Private, CRTC_ADDRESS_REGISTER, 0x2011); for (Index = 0; Index < 28; Index++) { - outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index)); + outw (Private, CRTC_ADDRESS_REGISTER, (UINT16)((ModeData->CrtcSettings[Index] << 8) | Index)); } for (Index = 0; Index < 9; Index++) { - outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index)); + outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16)((GraphicsController[Index] << 8) | Index)); } inb (Private, INPUT_STATUS_1_REGISTER); for (Index = 0; Index < 21; Index++) { - outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index); + outb (Private, ATT_ADDRESS_REGISTER, (UINT8)Index); outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]); } @@ -826,21 +915,21 @@ BochsWrite ( UINT16 Data ) { - EFI_STATUS Status; + EFI_STATUS Status; if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { Status = Private->PciIo->Mem.Write ( - Private->PciIo, - EfiPciIoWidthUint16, - PCI_BAR_IDX2, - 0x500 + (Reg << 1), - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint16, + PCI_BAR_IDX2, + 0x500 + (Reg << 1), + 1, + &Data + ); ASSERT_EFI_ERROR (Status); } else { outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); - outw (Private, VBE_DISPI_IOPORT_DATA, Data); + outw (Private, VBE_DISPI_IOPORT_DATA, Data); } } @@ -850,23 +939,24 @@ BochsRead ( UINT16 Reg ) { - EFI_STATUS Status; - UINT16 Data; + EFI_STATUS Status; + UINT16 Data; if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { Status = Private->PciIo->Mem.Read ( - Private->PciIo, - EfiPciIoWidthUint16, - PCI_BAR_IDX2, - 0x500 + (Reg << 1), - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint16, + PCI_BAR_IDX2, + 0x500 + (Reg << 1), + 1, + &Data + ); ASSERT_EFI_ERROR (Status); } else { outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); Data = inw (Private, VBE_DISPI_IOPORT_DATA); } + return Data; } @@ -877,48 +967,88 @@ VgaOutb ( UINT8 Data ) { - EFI_STATUS Status; + EFI_STATUS Status; if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { Status = Private->PciIo->Mem.Write ( - Private->PciIo, - EfiPciIoWidthUint8, - PCI_BAR_IDX2, - 0x400 - 0x3c0 + Reg, - 1, - &Data - ); + Private->PciIo, + EfiPciIoWidthUint8, + PCI_BAR_IDX2, + 0x400 - 0x3c0 + Reg, + 1, + &Data + ); ASSERT_EFI_ERROR (Status); } else { outb (Private, Reg, Data); } } +STATIC +UINT8 +VgaInb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Reg + ) +{ + EFI_STATUS Status; + UINT8 Data; + + if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { + Data = 0; + Status = Private->PciIo->Mem.Read ( + Private->PciIo, + EfiPciIoWidthUint8, + PCI_BAR_IDX2, + 0x400 - 0x3c0 + Reg, + 1, + &Data + ); + ASSERT_EFI_ERROR (Status); + } else { + Data = inb (Private, Reg); + } + + return Data; +} + VOID InitializeBochsGraphicsMode ( QEMU_VIDEO_PRIVATE_DATA *Private, - QEMU_VIDEO_BOCHS_MODES *ModeData + QEMU_VIDEO_MODE_DATA *ModeData ) { - DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n", - ModeData->Width, ModeData->Height, ModeData->ColorDepth)); - - /* unblank */ + DEBUG (( + DEBUG_INFO, + "InitializeBochsGraphicsMode: %dx%d @ %d\n", + ModeData->HorizontalResolution, + ModeData->VerticalResolution, + ModeData->ColorDepth + )); + + /* set color mode */ + VgaOutb (Private, MISC_OUTPUT_REGISTER, 0x01); + + /* reset flip flop + unblank */ + VgaInb (Private, INPUT_STATUS_1_REGISTER); VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20); - BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0); - BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0); - BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0); - BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0); + BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0); + BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0); + BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0); + BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0); - BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16) ModeData->ColorDepth); - BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData->Width); - BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData->Width); - BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData->Height); - BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Height); + BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16)ModeData->ColorDepth); + BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16)ModeData->HorizontalResolution); + BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16)ModeData->HorizontalResolution); + BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16)ModeData->VerticalResolution); + BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16)ModeData->VerticalResolution); - BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, - VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED); + BochsWrite ( + Private, + VBE_DISPI_INDEX_ENABLE, + VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED + ); SetDefaultPalette (Private); ClearScreen (Private); @@ -927,11 +1057,11 @@ InitializeBochsGraphicsMode ( EFI_STATUS EFIAPI InitializeQemuVideo ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + EFI_STATUS Status; Status = EfiLibInstallDriverBindingComponentName2 ( ImageHandle, @@ -943,18 +1073,5 @@ InitializeQemuVideo ( ); ASSERT_EFI_ERROR (Status); - // - // Install EFI Driver Supported EFI Version Protocol required for - // EFI drivers that are on PCI and other plug in cards. - // - gQemuVideoDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion); - Status = gBS->InstallMultipleProtocolInterfaces ( - &ImageHandle, - &gEfiDriverSupportedEfiVersionProtocolGuid, - &gQemuVideoDriverSupportedEfiVersion, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; }