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
This commit is contained in:
jljusten
2012-11-27 19:11:29 +00:00
parent 212aac55fd
commit 54f9b9accb
4 changed files with 196 additions and 1 deletions

View File

@@ -41,6 +41,16 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] = {
CIRRUS_LOGIC_5446_DEVICE_ID,
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.
@@ -275,6 +285,19 @@ QemuVideoControllerDriverStart (
goto Error;
}
//
// 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
//
@@ -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 (