From cdb4f5dcb1d4778da71c82cc15cab6e3cf218417 Mon Sep 17 00:00:00 2001 From: jljusten Date: Tue, 27 Nov 2012 19:11:45 +0000 Subject: [PATCH] QemuVideo: stdvga mmio bar support The qemu standard vga has a MMIO bar in qemu 1.3+. Use it if available. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Gerd Hoffmann Reviewed-by: Laszlo Ersek Reviewed-by: Jordan Justen git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13969 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/QemuVideoDxe/Driver.c | 115 ++++++++++++++++++++++++++++------ OvmfPkg/QemuVideoDxe/Gop.c | 1 + OvmfPkg/QemuVideoDxe/Qemu.h | 8 +++ 3 files changed, 104 insertions(+), 20 deletions(-) diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c index 04f73f3ba1..1dd8899fcf 100644 --- a/OvmfPkg/QemuVideoDxe/Driver.c +++ b/OvmfPkg/QemuVideoDxe/Driver.c @@ -15,6 +15,7 @@ **/ #include "Qemu.h" +#include EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = { QemuVideoControllerDriverSupported, @@ -44,7 +45,7 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] = { },{ 0x1234, 0x1111, - QEMU_VIDEO_BOCHS, + QEMU_VIDEO_BOCHS_MMIO, L"QEMU Standard VGA" },{ 0x1b36, @@ -200,13 +201,14 @@ QemuVideoControllerDriverStart ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { - EFI_STATUS Status; - QEMU_VIDEO_PRIVATE_DATA *Private; - BOOLEAN PciAttributesSaved; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - ACPI_ADR_DEVICE_PATH AcpiDeviceNode; - PCI_TYPE00 Pci; - QEMU_VIDEO_CARD *Card; + EFI_STATUS Status; + QEMU_VIDEO_PRIVATE_DATA *Private; + BOOLEAN PciAttributesSaved; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + ACPI_ADR_DEVICE_PATH AcpiDeviceNode; + PCI_TYPE00 Pci; + QEMU_VIDEO_CARD *Card; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; PciAttributesSaved = FALSE; // @@ -285,10 +287,31 @@ QemuVideoControllerDriverStart ( goto Error; } + // + // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+). + // + if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { + Status = Private->PciIo->GetBarAttributes ( + 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")); + Private->Variant = QEMU_VIDEO_BOCHS; + } else { + DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n", + MmioDesc->AddrRangeMin)); + } + } + // // Check if accessing the bochs interface works. // - if (Private->Variant == QEMU_VIDEO_BOCHS) { + 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) { @@ -359,6 +382,7 @@ QemuVideoControllerDriverStart ( case QEMU_VIDEO_CIRRUS_5446: Status = QemuVideoCirrusModeSetup (Private); break; + case QEMU_VIDEO_BOCHS_MMIO: case QEMU_VIDEO_BOCHS: Status = QemuVideoBochsModeSetup (Private); break; @@ -644,10 +668,10 @@ SetPaletteColor ( UINT8 Blue ) { - outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index); - outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2)); - outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2)); - outb (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)); } /** @@ -791,8 +815,22 @@ BochsWrite ( UINT16 Data ) { - outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); - outw (Private, VBE_DISPI_IOPORT_DATA, Data); + 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 + ); + ASSERT_EFI_ERROR (Status); + } else { + outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); + outw (Private, VBE_DISPI_IOPORT_DATA, Data); + } } UINT16 @@ -801,13 +839,50 @@ BochsRead ( UINT16 Reg ) { - UINT16 Data; - - outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); - Data = inw (Private, VBE_DISPI_IOPORT_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 + ); + ASSERT_EFI_ERROR (Status); + } else { + outw (Private, VBE_DISPI_IOPORT_INDEX, Reg); + Data = inw (Private, VBE_DISPI_IOPORT_DATA); + } return Data; } +VOID +VgaOutb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Reg, + UINT8 Data + ) +{ + 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 + ); + ASSERT_EFI_ERROR (Status); + } else { + outb (Private, Reg, Data); + } +} + VOID InitializeBochsGraphicsMode ( QEMU_VIDEO_PRIVATE_DATA *Private, @@ -818,7 +893,7 @@ InitializeBochsGraphicsMode ( ModeData->Width, ModeData->Height, ModeData->ColorDepth)); /* unblank */ - outb (Private, ATT_ADDRESS_REGISTER, 0x20); + VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20); BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0); BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0); diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index f6e9b6c14f..1d2402cded 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -186,6 +186,7 @@ Routine Description: case QEMU_VIDEO_CIRRUS_5446: InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]); break; + case QEMU_VIDEO_BOCHS_MMIO: case QEMU_VIDEO_BOCHS: InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->ModeNumber]); break; diff --git a/OvmfPkg/QemuVideoDxe/Qemu.h b/OvmfPkg/QemuVideoDxe/Qemu.h index 343fd347b6..38d68729a0 100644 --- a/OvmfPkg/QemuVideoDxe/Qemu.h +++ b/OvmfPkg/QemuVideoDxe/Qemu.h @@ -90,6 +90,7 @@ typedef enum { QEMU_VIDEO_CIRRUS_5430 = 1, QEMU_VIDEO_CIRRUS_5446, QEMU_VIDEO_BOCHS, + QEMU_VIDEO_BOCHS_MMIO, } QEMU_VIDEO_VARIANT; typedef struct { @@ -478,6 +479,13 @@ BochsRead ( UINT16 Reg ); +VOID +VgaOutb ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINTN Reg, + UINT8 Data + ); + EFI_STATUS QemuVideoCirrusModeSetup ( QEMU_VIDEO_PRIVATE_DATA *Private -- 2.39.2