]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuVideoDxe/Driver.c
QemuVideo: Add support for the bochs dispi interface
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Driver.c
index 51929803b582e007727729497b57870c716c4e59..04f73f3ba1d335a06cba3ead8a87855da829269b 100644 (file)
@@ -41,6 +41,16 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] = {
         CIRRUS_LOGIC_5446_DEVICE_ID,\r
         QEMU_VIDEO_CIRRUS_5446,\r
         L"Cirrus 5446"\r
+    },{\r
+        0x1234,\r
+        0x1111,\r
+        QEMU_VIDEO_BOCHS,\r
+        L"QEMU Standard VGA"\r
+    },{\r
+        0x1b36,\r
+        0x0100,\r
+        QEMU_VIDEO_BOCHS,\r
+        L"QEMU QXL VGA"\r
     },{\r
         0 /* end of list */\r
     }\r
@@ -197,7 +207,7 @@ QemuVideoControllerDriverStart (
   ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;\r
   PCI_TYPE00                      Pci;\r
   QEMU_VIDEO_CARD                 *Card;\r
-  \r
+\r
   PciAttributesSaved = FALSE;\r
   //\r
   // Allocate Private context data for GOP inteface.\r
@@ -275,6 +285,19 @@ QemuVideoControllerDriverStart (
     goto Error;\r
   }\r
 \r
+  //\r
+  // Check if accessing the bochs interface works.\r
+  //\r
+  if (Private->Variant == QEMU_VIDEO_BOCHS) {\r
+    UINT16 BochsId;\r
+    BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID);\r
+    if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {\r
+      DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId));\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Error;\r
+    }\r
+  }\r
+\r
   //\r
   // Get ParentDevicePath\r
   //\r
@@ -336,6 +359,9 @@ QemuVideoControllerDriverStart (
   case QEMU_VIDEO_CIRRUS_5446:\r
     Status = QemuVideoCirrusModeSetup (Private);\r
     break;\r
+  case QEMU_VIDEO_BOCHS:\r
+    Status = QemuVideoBochsModeSetup (Private);\r
+    break;\r
   default:\r
     ASSERT (FALSE);\r
     Status = EFI_DEVICE_ERROR;\r
@@ -758,6 +784,60 @@ InitializeCirrusGraphicsMode (
   ClearScreen (Private);\r
 }\r
 \r
+VOID\r
+BochsWrite (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  UINT16                   Reg,\r
+  UINT16                   Data\r
+  )\r
+{\r
+  outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);\r
+  outw (Private, VBE_DISPI_IOPORT_DATA,  Data);\r
+}\r
+\r
+UINT16\r
+BochsRead (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  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
+  return Data;\r
+}\r
+\r
+VOID\r
+InitializeBochsGraphicsMode (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  QEMU_VIDEO_BOCHS_MODES  *ModeData\r
+  )\r
+{\r
+  DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n",\r
+          ModeData->Width, ModeData->Height, ModeData->ColorDepth));\r
+\r
+  /* unblank */\r
+  outb (Private, ATT_ADDRESS_REGISTER, 0x20);\r
+\r
+  BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,      0);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_BANK,        0);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET,    0);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET,    0);\r
+\r
+  BochsWrite (Private, VBE_DISPI_INDEX_BPP,         (UINT16) ModeData->ColorDepth);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_XRES,        (UINT16) ModeData->Width);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH,  (UINT16) ModeData->Width);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_YRES,        (UINT16) ModeData->Height);\r
+  BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Height);\r
+\r
+  BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,\r
+              VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);\r
+\r
+  SetDefaultPalette (Private);\r
+  ClearScreen (Private);\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 InitializeQemuVideo (\r