]> git.proxmox.com Git - mirror_edk2.git/commitdiff
QemuVideo: Add support for the bochs dispi interface
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2012 19:11:29 +0000 (19:11 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2012 19:11:29 +0000 (19:11 +0000)
Add code to handle qemu-emulated vga cards supporting the bochs dispi
interface (standard vga, qxl vga).  This requires qemu 1.3+ which
provides the bochs dispi interface data register on a aligned io
address.  See
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=df9ffb726ff13f850b8829be1bc85ed621b903ac

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@13968 6f19259b-4bc3-4df7-8a09-765794883524

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

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
index bd49ee91391fb6e995465b8868a5eb258e9c5ff8..f6e9b6c14f4790aedfc1f02140eeb360f1cc8025 100644 (file)
@@ -186,6 +186,9 @@ Routine Description:
   case QEMU_VIDEO_CIRRUS_5446:\r
     InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]);\r
     break;\r
+  case QEMU_VIDEO_BOCHS:\r
+    InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->ModeNumber]);\r
+    break;\r
   default:\r
     ASSERT (FALSE);\r
     gBS->FreePool (Private->LineBuffer);\r
index a369e229883b1ebb446c1af3f7124a63192ed10d..305797bd50d20d7202595c57d27e41a2510e4687 100644 (file)
@@ -201,3 +201,55 @@ QemuVideoCirrusModeSetup (
   return EFI_SUCCESS;\r
 }\r
 \r
+///\r
+/// Table of supported video modes\r
+///\r
+QEMU_VIDEO_BOCHS_MODES  QemuVideoBochsModes[] = {\r
+  {  640, 480, 32 },\r
+  {  800, 600, 32 },\r
+  { 1024, 768, 24 },\r
+};\r
+\r
+#define QEMU_VIDEO_BOCHS_MODE_COUNT \\r
+  (sizeof (QemuVideoBochsModes) / sizeof (QemuVideoBochsModes[0]))\r
+\r
+EFI_STATUS\r
+QemuVideoBochsModeSetup (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private\r
+  )\r
+{\r
+  UINT32                                 Index;\r
+  QEMU_VIDEO_MODE_DATA                   *ModeData;\r
+  QEMU_VIDEO_BOCHS_MODES                 *VideoMode;\r
+\r
+  //\r
+  // Setup Video Modes\r
+  //\r
+  Private->ModeData = AllocatePool (\r
+                        sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT\r
+                        );\r
+  ModeData = Private->ModeData;\r
+  VideoMode = &QemuVideoBochsModes[0];\r
+  for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {\r
+    ModeData->ModeNumber = Index;\r
+    ModeData->HorizontalResolution          = VideoMode->Width;\r
+    ModeData->VerticalResolution            = VideoMode->Height;\r
+    ModeData->ColorDepth                    = VideoMode->ColorDepth;\r
+    ModeData->RefreshRate                   = 60;\r
+    DEBUG ((EFI_D_INFO,\r
+      "Adding Bochs Video Mode %d: %dx%d, %d-bit, %d Hz\n",\r
+      ModeData->ModeNumber,\r
+      ModeData->HorizontalResolution,\r
+      ModeData->VerticalResolution,\r
+      ModeData->ColorDepth,\r
+      ModeData->RefreshRate\r
+      ));\r
+\r
+    ModeData ++ ;\r
+    VideoMode ++;\r
+  }\r
+  Private->MaxMode = QEMU_VIDEO_BOCHS_MODE_COUNT;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
index f294901fa6a14c6140d05241989f3b29c849aa4b..343fd347b6866f2ce4f090d0f84c7988944e2603 100644 (file)
@@ -89,6 +89,7 @@ typedef struct {
 typedef enum {\r
   QEMU_VIDEO_CIRRUS_5430 = 1,\r
   QEMU_VIDEO_CIRRUS_5446,\r
+  QEMU_VIDEO_BOCHS,\r
 } QEMU_VIDEO_VARIANT;\r
 \r
 typedef struct {\r
@@ -126,6 +127,12 @@ typedef struct {
   UINT8   MiscSetting;\r
 } QEMU_VIDEO_CIRRUS_MODES;\r
 \r
+typedef struct {\r
+  UINT32  Width;\r
+  UINT32  Height;\r
+  UINT32  ColorDepth;\r
+} QEMU_VIDEO_BOCHS_MODES;\r
+\r
 #define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \\r
   CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)\r
 \r
@@ -142,6 +149,7 @@ extern UINT16                                     Seq_800_600_256_60[];
 extern UINT8                                      Crtc_1024_768_256_60[];\r
 extern UINT16                                     Seq_1024_768_256_60[];\r
 extern QEMU_VIDEO_CIRRUS_MODES                    QemuVideoCirrusModes[];\r
+extern QEMU_VIDEO_BOCHS_MODES                     QemuVideoBochsModes[];\r
 extern EFI_DRIVER_BINDING_PROTOCOL                gQemuVideoDriverBinding;\r
 extern EFI_COMPONENT_NAME_PROTOCOL                gQemuVideoComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL               gQemuVideoComponentName2;\r
@@ -163,6 +171,34 @@ extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gQemuVideoDriverSupportedEfiVe
 #define PALETTE_INDEX_REGISTER  0x3c8\r
 #define PALETTE_DATA_REGISTER   0x3c9\r
 \r
+#define VBE_DISPI_IOPORT_INDEX           0x01CE\r
+#define VBE_DISPI_IOPORT_DATA            0x01D0\r
+\r
+#define VBE_DISPI_INDEX_ID               0x0\r
+#define VBE_DISPI_INDEX_XRES             0x1\r
+#define VBE_DISPI_INDEX_YRES             0x2\r
+#define VBE_DISPI_INDEX_BPP              0x3\r
+#define VBE_DISPI_INDEX_ENABLE           0x4\r
+#define VBE_DISPI_INDEX_BANK             0x5\r
+#define VBE_DISPI_INDEX_VIRT_WIDTH       0x6\r
+#define VBE_DISPI_INDEX_VIRT_HEIGHT      0x7\r
+#define VBE_DISPI_INDEX_X_OFFSET         0x8\r
+#define VBE_DISPI_INDEX_Y_OFFSET         0x9\r
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa\r
+\r
+#define VBE_DISPI_ID0                    0xB0C0\r
+#define VBE_DISPI_ID1                    0xB0C1\r
+#define VBE_DISPI_ID2                    0xB0C2\r
+#define VBE_DISPI_ID3                    0xB0C3\r
+#define VBE_DISPI_ID4                    0xB0C4\r
+#define VBE_DISPI_ID5                    0xB0C5\r
+\r
+#define VBE_DISPI_DISABLED               0x00\r
+#define VBE_DISPI_ENABLED                0x01\r
+#define VBE_DISPI_GETCAPS                0x02\r
+#define VBE_DISPI_8BIT_DAC               0x20\r
+#define VBE_DISPI_LFB_ENABLED            0x40\r
+#define VBE_DISPI_NOCLEARMEM             0x80\r
 \r
 //\r
 // Graphics Output Hardware abstraction internal worker functions\r
@@ -376,6 +412,12 @@ InitializeCirrusGraphicsMode (
   QEMU_VIDEO_CIRRUS_MODES  *ModeData\r
   );\r
 \r
+VOID\r
+InitializeBochsGraphicsMode (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  QEMU_VIDEO_BOCHS_MODES   *ModeData\r
+  );\r
+\r
 VOID\r
 SetPaletteColor (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private,\r
@@ -423,9 +465,27 @@ inw (
   UINTN                           Address\r
   );\r
 \r
+VOID\r
+BochsWrite (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  UINT16                   Reg,\r
+  UINT16                   Data\r
+  );\r
+\r
+UINT16\r
+BochsRead (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  UINT16                   Reg\r
+  );\r
+\r
 EFI_STATUS\r
 QemuVideoCirrusModeSetup (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private\r
   );\r
 \r
+EFI_STATUS\r
+QemuVideoBochsModeSetup (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private\r
+  );\r
+\r
 #endif\r