]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuVideoDxe/Initialize.c
OvmfPkg: QemuVideoDxe: filter BOCHS modes vs. available frame buffer size
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Initialize.c
index a369e229883b1ebb446c1af3f7124a63192ed10d..80e9b3a936ff571d03ed0d51af7be054695819e8 100644 (file)
@@ -176,17 +176,21 @@ QemuVideoCirrusModeSetup (
   Private->ModeData = AllocatePool (\r
                         sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT\r
                         );\r
+  if (Private->ModeData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
   ModeData = Private->ModeData;\r
   VideoMode = &QemuVideoCirrusModes[0];\r
   for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {\r
-    ModeData->ModeNumber = Index;\r
+    ModeData->InternalModeIndex = Index;\r
     ModeData->HorizontalResolution          = VideoMode->Width;\r
     ModeData->VerticalResolution            = VideoMode->Height;\r
     ModeData->ColorDepth                    = VideoMode->ColorDepth;\r
     ModeData->RefreshRate                   = VideoMode->RefreshRate;\r
     DEBUG ((EFI_D_INFO,\r
-      "Adding Cirrus Video Mode %d: %dx%d, %d-bit, %d Hz\n",\r
-      ModeData->ModeNumber,\r
+      "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit, %d Hz\n",\r
+      (INT32) (ModeData - Private->ModeData),\r
+      ModeData->InternalModeIndex,\r
       ModeData->HorizontalResolution,\r
       ModeData->VerticalResolution,\r
       ModeData->ColorDepth,\r
@@ -196,7 +200,79 @@ QemuVideoCirrusModeSetup (
     ModeData ++ ;\r
     VideoMode ++;\r
   }\r
-  Private->MaxMode = QEMU_VIDEO_CIRRUS_MODE_COUNT;\r
+  Private->MaxMode = ModeData - Private->ModeData;\r
+\r
+  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                                 AvailableFbSize;\r
+  UINT32                                 Index;\r
+  QEMU_VIDEO_MODE_DATA                   *ModeData;\r
+  QEMU_VIDEO_BOCHS_MODES                 *VideoMode;\r
+\r
+  //\r
+  // fetch available framebuffer size\r
+  //\r
+  AvailableFbSize  = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);\r
+  AvailableFbSize *= SIZE_64KB;\r
+  DEBUG ((EFI_D_VERBOSE, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,\r
+    AvailableFbSize));\r
+\r
+  //\r
+  // Setup Video Modes\r
+  //\r
+  Private->ModeData = AllocatePool (\r
+                        sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT\r
+                        );\r
+  if (Private->ModeData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  ModeData = Private->ModeData;\r
+  VideoMode = &QemuVideoBochsModes[0];\r
+  for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {\r
+    UINTN RequiredFbSize;\r
+\r
+    ASSERT (VideoMode->ColorDepth % 8 == 0);\r
+    RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *\r
+                     (VideoMode->ColorDepth / 8);\r
+    if (RequiredFbSize <= AvailableFbSize) {\r
+      ModeData->InternalModeIndex    = 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 Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit, %d Hz\n",\r
+        (INT32) (ModeData - Private->ModeData),\r
+        ModeData->InternalModeIndex,\r
+        ModeData->HorizontalResolution,\r
+        ModeData->VerticalResolution,\r
+        ModeData->ColorDepth,\r
+        ModeData->RefreshRate\r
+        ));\r
+\r
+      ModeData ++ ;\r
+    }\r
+    VideoMode ++;\r
+  }\r
+  Private->MaxMode = ModeData - Private->ModeData;\r
 \r
   return EFI_SUCCESS;\r
 }\r