summaryrefslogtreecommitdiff
path: root/OvmfPkg
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2012-11-27 19:11:29 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2012-11-27 19:11:29 +0000
commit54f9b9accbcb6dc7f965342fc75b478464de21a3 (patch)
treed62d082081fe0e04607077e4636f6bfa6b49b800 /OvmfPkg
parent212aac55fd13e985cebf88042f40479c01ac2e44 (diff)
QemuVideo: Add support for the bochs dispi interface
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
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/QemuVideoDxe/Driver.c82
-rw-r--r--OvmfPkg/QemuVideoDxe/Gop.c3
-rw-r--r--OvmfPkg/QemuVideoDxe/Initialize.c52
-rw-r--r--OvmfPkg/QemuVideoDxe/Qemu.h60
4 files changed, 196 insertions, 1 deletions
diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c
index 51929803b5..04f73f3ba1 100644
--- a/OvmfPkg/QemuVideoDxe/Driver.c
+++ b/OvmfPkg/QemuVideoDxe/Driver.c
@@ -42,6 +42,16 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] = {
QEMU_VIDEO_CIRRUS_5446,
L"Cirrus 5446"
},{
+ 0x1234,
+ 0x1111,
+ QEMU_VIDEO_BOCHS,
+ L"QEMU Standard VGA"
+ },{
+ 0x1b36,
+ 0x0100,
+ QEMU_VIDEO_BOCHS,
+ L"QEMU QXL VGA"
+ },{
0 /* end of list */
}
};
@@ -197,7 +207,7 @@ QemuVideoControllerDriverStart (
ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
PCI_TYPE00 Pci;
QEMU_VIDEO_CARD *Card;
-
+
PciAttributesSaved = FALSE;
//
// Allocate Private context data for GOP inteface.
@@ -276,6 +286,19 @@ QemuVideoControllerDriverStart (
}
//
+ // Check if accessing the bochs interface works.
+ //
+ if (Private->Variant == QEMU_VIDEO_BOCHS) {
+ UINT16 BochsId;
+ BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID);
+ if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId));
+ Status = EFI_DEVICE_ERROR;
+ goto Error;
+ }
+ }
+
+ //
// Get ParentDevicePath
//
Status = gBS->HandleProtocol (
@@ -336,6 +359,9 @@ QemuVideoControllerDriverStart (
case QEMU_VIDEO_CIRRUS_5446:
Status = QemuVideoCirrusModeSetup (Private);
break;
+ case QEMU_VIDEO_BOCHS:
+ Status = QemuVideoBochsModeSetup (Private);
+ break;
default:
ASSERT (FALSE);
Status = EFI_DEVICE_ERROR;
@@ -758,6 +784,60 @@ InitializeCirrusGraphicsMode (
ClearScreen (Private);
}
+VOID
+BochsWrite (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg,
+ UINT16 Data
+ )
+{
+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
+ outw (Private, VBE_DISPI_IOPORT_DATA, Data);
+}
+
+UINT16
+BochsRead (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg
+ )
+{
+ UINT16 Data;
+
+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
+ Data = inw (Private, VBE_DISPI_IOPORT_DATA);
+ return Data;
+}
+
+VOID
+InitializeBochsGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_BOCHS_MODES *ModeData
+ )
+{
+ DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n",
+ ModeData->Width, ModeData->Height, ModeData->ColorDepth));
+
+ /* unblank */
+ outb (Private, ATT_ADDRESS_REGISTER, 0x20);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16) ModeData->ColorDepth);
+ BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData->Width);
+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData->Width);
+ BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData->Height);
+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Height);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,
+ VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+
+ SetDefaultPalette (Private);
+ ClearScreen (Private);
+}
+
EFI_STATUS
EFIAPI
InitializeQemuVideo (
diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c
index bd49ee9139..f6e9b6c14f 100644
--- a/OvmfPkg/QemuVideoDxe/Gop.c
+++ b/OvmfPkg/QemuVideoDxe/Gop.c
@@ -186,6 +186,9 @@ Routine Description:
case QEMU_VIDEO_CIRRUS_5446:
InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]);
break;
+ case QEMU_VIDEO_BOCHS:
+ InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->ModeNumber]);
+ break;
default:
ASSERT (FALSE);
gBS->FreePool (Private->LineBuffer);
diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initialize.c
index a369e22988..305797bd50 100644
--- a/OvmfPkg/QemuVideoDxe/Initialize.c
+++ b/OvmfPkg/QemuVideoDxe/Initialize.c
@@ -201,3 +201,55 @@ QemuVideoCirrusModeSetup (
return EFI_SUCCESS;
}
+///
+/// Table of supported video modes
+///
+QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {
+ { 640, 480, 32 },
+ { 800, 600, 32 },
+ { 1024, 768, 24 },
+};
+
+#define QEMU_VIDEO_BOCHS_MODE_COUNT \
+ (sizeof (QemuVideoBochsModes) / sizeof (QemuVideoBochsModes[0]))
+
+EFI_STATUS
+QemuVideoBochsModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINT32 Index;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ QEMU_VIDEO_BOCHS_MODES *VideoMode;
+
+ //
+ // Setup Video Modes
+ //
+ Private->ModeData = AllocatePool (
+ sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT
+ );
+ ModeData = Private->ModeData;
+ VideoMode = &QemuVideoBochsModes[0];
+ for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {
+ ModeData->ModeNumber = Index;
+ ModeData->HorizontalResolution = VideoMode->Width;
+ ModeData->VerticalResolution = VideoMode->Height;
+ ModeData->ColorDepth = VideoMode->ColorDepth;
+ ModeData->RefreshRate = 60;
+ DEBUG ((EFI_D_INFO,
+ "Adding Bochs Video Mode %d: %dx%d, %d-bit, %d Hz\n",
+ ModeData->ModeNumber,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->ColorDepth,
+ ModeData->RefreshRate
+ ));
+
+ ModeData ++ ;
+ VideoMode ++;
+ }
+ Private->MaxMode = QEMU_VIDEO_BOCHS_MODE_COUNT;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/OvmfPkg/QemuVideoDxe/Qemu.h b/OvmfPkg/QemuVideoDxe/Qemu.h
index f294901fa6..343fd347b6 100644
--- a/OvmfPkg/QemuVideoDxe/Qemu.h
+++ b/OvmfPkg/QemuVideoDxe/Qemu.h
@@ -89,6 +89,7 @@ typedef struct {
typedef enum {
QEMU_VIDEO_CIRRUS_5430 = 1,
QEMU_VIDEO_CIRRUS_5446,
+ QEMU_VIDEO_BOCHS,
} QEMU_VIDEO_VARIANT;
typedef struct {
@@ -126,6 +127,12 @@ typedef struct {
UINT8 MiscSetting;
} QEMU_VIDEO_CIRRUS_MODES;
+typedef struct {
+ UINT32 Width;
+ UINT32 Height;
+ UINT32 ColorDepth;
+} QEMU_VIDEO_BOCHS_MODES;
+
#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)
@@ -142,6 +149,7 @@ extern UINT16 Seq_800_600_256_60[];
extern UINT8 Crtc_1024_768_256_60[];
extern UINT16 Seq_1024_768_256_60[];
extern QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[];
+extern QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[];
extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2;
@@ -163,6 +171,34 @@ extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVe
#define PALETTE_INDEX_REGISTER 0x3c8
#define PALETTE_DATA_REGISTER 0x3c9
+#define VBE_DISPI_IOPORT_INDEX 0x01CE
+#define VBE_DISPI_IOPORT_DATA 0x01D0
+
+#define VBE_DISPI_INDEX_ID 0x0
+#define VBE_DISPI_INDEX_XRES 0x1
+#define VBE_DISPI_INDEX_YRES 0x2
+#define VBE_DISPI_INDEX_BPP 0x3
+#define VBE_DISPI_INDEX_ENABLE 0x4
+#define VBE_DISPI_INDEX_BANK 0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+#define VBE_DISPI_INDEX_X_OFFSET 0x8
+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
+
+#define VBE_DISPI_ID0 0xB0C0
+#define VBE_DISPI_ID1 0xB0C1
+#define VBE_DISPI_ID2 0xB0C2
+#define VBE_DISPI_ID3 0xB0C3
+#define VBE_DISPI_ID4 0xB0C4
+#define VBE_DISPI_ID5 0xB0C5
+
+#define VBE_DISPI_DISABLED 0x00
+#define VBE_DISPI_ENABLED 0x01
+#define VBE_DISPI_GETCAPS 0x02
+#define VBE_DISPI_8BIT_DAC 0x20
+#define VBE_DISPI_LFB_ENABLED 0x40
+#define VBE_DISPI_NOCLEARMEM 0x80
//
// Graphics Output Hardware abstraction internal worker functions
@@ -377,6 +413,12 @@ InitializeCirrusGraphicsMode (
);
VOID
+InitializeBochsGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_BOCHS_MODES *ModeData
+ );
+
+VOID
SetPaletteColor (
QEMU_VIDEO_PRIVATE_DATA *Private,
UINTN Index,
@@ -423,9 +465,27 @@ inw (
UINTN Address
);
+VOID
+BochsWrite (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg,
+ UINT16 Data
+ );
+
+UINT16
+BochsRead (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg
+ );
+
EFI_STATUS
QemuVideoCirrusModeSetup (
QEMU_VIDEO_PRIVATE_DATA *Private
);
+EFI_STATUS
+QemuVideoBochsModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
#endif