]> git.proxmox.com Git - mirror_edk2.git/commitdiff
QemuVideo: stdvga mmio bar support
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2012 19:11:45 +0000 (19:11 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2012 19:11:45 +0000 (19:11 +0000)
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 <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13969 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/QemuVideoDxe/Driver.c
OvmfPkg/QemuVideoDxe/Gop.c
OvmfPkg/QemuVideoDxe/Qemu.h

index 04f73f3ba1d335a06cba3ead8a87855da829269b..1dd8899fcf8c0b10a32b61f629bcc8b7dd5be74c 100644 (file)
@@ -15,6 +15,7 @@
 **/\r
 \r
 #include "Qemu.h"\r
+#include <IndustryStandard/Acpi.h>\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {\r
   QemuVideoControllerDriverSupported,\r
@@ -44,7 +45,7 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] = {
     },{\r
         0x1234,\r
         0x1111,\r
-        QEMU_VIDEO_BOCHS,\r
+        QEMU_VIDEO_BOCHS_MMIO,\r
         L"QEMU Standard VGA"\r
     },{\r
         0x1b36,\r
@@ -200,13 +201,14 @@ QemuVideoControllerDriverStart (
   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  QEMU_VIDEO_PRIVATE_DATA  *Private;\r
-  BOOLEAN                         PciAttributesSaved;\r
-  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;\r
-  ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;\r
-  PCI_TYPE00                      Pci;\r
-  QEMU_VIDEO_CARD                 *Card;\r
+  EFI_STATUS                        Status;\r
+  QEMU_VIDEO_PRIVATE_DATA           *Private;\r
+  BOOLEAN                           PciAttributesSaved;\r
+  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
+  ACPI_ADR_DEVICE_PATH              AcpiDeviceNode;\r
+  PCI_TYPE00                        Pci;\r
+  QEMU_VIDEO_CARD                   *Card;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;\r
 \r
   PciAttributesSaved = FALSE;\r
   //\r
@@ -285,10 +287,31 @@ QemuVideoControllerDriverStart (
     goto Error;\r
   }\r
 \r
+  //\r
+  // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+).\r
+  //\r
+  if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {\r
+    Status = Private->PciIo->GetBarAttributes (\r
+                        Private->PciIo,\r
+                        PCI_BAR_IDX2,\r
+                        NULL,\r
+                        (VOID**) &MmioDesc\r
+                        );\r
+    if (EFI_ERROR (Status) ||\r
+        MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+      DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n"));\r
+      Private->Variant = QEMU_VIDEO_BOCHS;\r
+    } else {\r
+      DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n",\r
+              MmioDesc->AddrRangeMin));\r
+    }\r
+  }\r
+\r
   //\r
   // Check if accessing the bochs interface works.\r
   //\r
-  if (Private->Variant == QEMU_VIDEO_BOCHS) {\r
+  if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||\r
+      Private->Variant == QEMU_VIDEO_BOCHS) {\r
     UINT16 BochsId;\r
     BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID);\r
     if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {\r
@@ -359,6 +382,7 @@ QemuVideoControllerDriverStart (
   case QEMU_VIDEO_CIRRUS_5446:\r
     Status = QemuVideoCirrusModeSetup (Private);\r
     break;\r
+  case QEMU_VIDEO_BOCHS_MMIO:\r
   case QEMU_VIDEO_BOCHS:\r
     Status = QemuVideoBochsModeSetup (Private);\r
     break;\r
@@ -644,10 +668,10 @@ SetPaletteColor (
   UINT8                           Blue\r
   )\r
 {\r
-  outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);\r
-  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));\r
-  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));\r
-  outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));\r
+  VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);\r
+  VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));\r
+  VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));\r
+  VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));\r
 }\r
 \r
 /**\r
@@ -791,8 +815,22 @@ BochsWrite (
   UINT16                   Data\r
   )\r
 {\r
-  outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);\r
-  outw (Private, VBE_DISPI_IOPORT_DATA,  Data);\r
+  EFI_STATUS   Status;\r
+\r
+  if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {\r
+    Status = Private->PciIo->Mem.Write (\r
+        Private->PciIo,\r
+        EfiPciIoWidthUint16,\r
+        PCI_BAR_IDX2,\r
+        0x500 + (Reg << 1),\r
+        1,\r
+        &Data\r
+        );\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);\r
+    outw (Private, VBE_DISPI_IOPORT_DATA,  Data);\r
+  }\r
 }\r
 \r
 UINT16\r
@@ -801,13 +839,50 @@ BochsRead (
   UINT16                   Reg\r
   )\r
 {\r
-  UINT16 Data;\r
-\r
-  outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);\r
-  Data = inw (Private, VBE_DISPI_IOPORT_DATA);\r
+  EFI_STATUS   Status;\r
+  UINT16       Data;\r
+\r
+  if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {\r
+    Status = Private->PciIo->Mem.Read (\r
+        Private->PciIo,\r
+        EfiPciIoWidthUint16,\r
+        PCI_BAR_IDX2,\r
+        0x500 + (Reg << 1),\r
+        1,\r
+        &Data\r
+        );\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);\r
+    Data = inw (Private, VBE_DISPI_IOPORT_DATA);\r
+  }\r
   return Data;\r
 }\r
 \r
+VOID\r
+VgaOutb (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  UINTN                    Reg,\r
+  UINT8                    Data\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+\r
+  if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {\r
+    Status = Private->PciIo->Mem.Write (\r
+        Private->PciIo,\r
+        EfiPciIoWidthUint8,\r
+        PCI_BAR_IDX2,\r
+        0x400 - 0x3c0 + Reg,\r
+        1,\r
+        &Data\r
+        );\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    outb (Private, Reg, Data);\r
+  }\r
+}\r
+\r
 VOID\r
 InitializeBochsGraphicsMode (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private,\r
@@ -818,7 +893,7 @@ InitializeBochsGraphicsMode (
           ModeData->Width, ModeData->Height, ModeData->ColorDepth));\r
 \r
   /* unblank */\r
-  outb (Private, ATT_ADDRESS_REGISTER, 0x20);\r
+  VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20);\r
 \r
   BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,      0);\r
   BochsWrite (Private, VBE_DISPI_INDEX_BANK,        0);\r
index f6e9b6c14f4790aedfc1f02140eeb360f1cc8025..1d2402cded49317ec531cdef318293f84bd265c6 100644 (file)
@@ -186,6 +186,7 @@ Routine Description:
   case QEMU_VIDEO_CIRRUS_5446:\r
     InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]);\r
     break;\r
+  case QEMU_VIDEO_BOCHS_MMIO:\r
   case QEMU_VIDEO_BOCHS:\r
     InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->ModeNumber]);\r
     break;\r
index 343fd347b6866f2ce4f090d0f84c7988944e2603..38d68729a0fc5e43e60bb1a979d1e9f469afa1b6 100644 (file)
@@ -90,6 +90,7 @@ typedef enum {
   QEMU_VIDEO_CIRRUS_5430 = 1,\r
   QEMU_VIDEO_CIRRUS_5446,\r
   QEMU_VIDEO_BOCHS,\r
+  QEMU_VIDEO_BOCHS_MMIO,\r
 } QEMU_VIDEO_VARIANT;\r
 \r
 typedef struct {\r
@@ -478,6 +479,13 @@ BochsRead (
   UINT16                   Reg\r
   );\r
 \r
+VOID\r
+VgaOutb (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  UINTN                    Reg,\r
+  UINT8                    Data\r
+  );\r
+\r
 EFI_STATUS\r
 QemuVideoCirrusModeSetup (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private\r