mirror of https://github.com/acidanthera/audk.git
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:
parent
212aac55fd
commit
54f9b9accb
|
@ -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 (
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -376,6 +412,12 @@ InitializeCirrusGraphicsMode (
|
|||
QEMU_VIDEO_CIRRUS_MODES *ModeData
|
||||
);
|
||||
|
||||
VOID
|
||||
InitializeBochsGraphicsMode (
|
||||
QEMU_VIDEO_PRIVATE_DATA *Private,
|
||||
QEMU_VIDEO_BOCHS_MODES *ModeData
|
||||
);
|
||||
|
||||
VOID
|
||||
SetPaletteColor (
|
||||
QEMU_VIDEO_PRIVATE_DATA *Private,
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue