+STATIC\r
+VOID\r
+QemuVideoBochsAddMode (\r
+ QEMU_VIDEO_PRIVATE_DATA *Private,\r
+ UINT32 AvailableFbSize,\r
+ UINT32 Width,\r
+ UINT32 Height\r
+ )\r
+{\r
+ QEMU_VIDEO_MODE_DATA *ModeData = Private->ModeData + Private->MaxMode;\r
+ UINTN RequiredFbSize;\r
+\r
+ RequiredFbSize = (UINTN)Width * Height * 4;\r
+ if (RequiredFbSize > AvailableFbSize) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "Skipping Bochs Mode %dx%d, 32-bit (not enough vram)\n",\r
+ Width,\r
+ Height\r
+ ));\r
+ return;\r
+ }\r
+\r
+ ModeData->InternalModeIndex = (UINT32)Private->MaxMode;\r
+ ModeData->HorizontalResolution = Width;\r
+ ModeData->VerticalResolution = Height;\r
+ ModeData->ColorDepth = 32;\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "Adding Bochs Internal Mode %d: %dx%d, %d-bit\n",\r
+ ModeData->InternalModeIndex,\r
+ ModeData->HorizontalResolution,\r
+ ModeData->VerticalResolution,\r
+ ModeData->ColorDepth\r
+ ));\r
+\r
+ Private->MaxMode++;\r
+}\r
+\r
+STATIC\r
+VOID\r
+QemuVideoBochsEdid (\r
+ QEMU_VIDEO_PRIVATE_DATA *Private,\r
+ UINT32 *XRes,\r
+ UINT32 *YRes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (Private->Variant != QEMU_VIDEO_BOCHS_MMIO) {\r
+ return;\r
+ }\r
+\r
+ Status = Private->PciIo->Mem.Read (\r
+ Private->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ PCI_BAR_IDX2,\r
+ 0,\r
+ sizeof (Private->Edid),\r
+ Private->Edid\r
+ );\r
+ if (Status != EFI_SUCCESS) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: mmio read failed\n",\r
+ __FUNCTION__\r
+ ));\r
+ return;\r
+ }\r
+\r
+ if ((Private->Edid[0] != 0x00) ||\r
+ (Private->Edid[1] != 0xff))\r
+ {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: magic check failed\n",\r
+ __FUNCTION__\r
+ ));\r
+ return;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: blob found (extensions: %d)\n",\r
+ __FUNCTION__,\r
+ Private->Edid[126]\r
+ ));\r
+\r
+ if ((Private->Edid[54] == 0x00) &&\r
+ (Private->Edid[55] == 0x00))\r
+ {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: no detailed timing descriptor\n",\r
+ __FUNCTION__\r
+ ));\r
+ return;\r
+ }\r
+\r
+ *XRes = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4);\r
+ *YRes = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4);\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: default resolution: %dx%d\n",\r
+ __FUNCTION__,\r
+ *XRes,\r
+ *YRes\r
+ ));\r
+\r
+ if (PcdGet8 (PcdVideoResolutionSource) == 0) {\r
+ Status = PcdSet32S (PcdVideoHorizontalResolution, *XRes);\r
+ ASSERT_RETURN_ERROR (Status);\r
+ Status = PcdSet32S (PcdVideoVerticalResolution, *YRes);\r
+ ASSERT_RETURN_ERROR (Status);\r
+ Status = PcdSet8S (PcdVideoResolutionSource, 2);\r
+ ASSERT_RETURN_ERROR (Status);\r
+ }\r
+\r
+ // TODO: register edid as gEfiEdidDiscoveredProtocolGuid ?\r
+}\r
+\r