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
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
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
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
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
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
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
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
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
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
#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
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
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