mirror of https://github.com/acidanthera/audk.git
QemuVideo: prepare to support more hardware
Move to a table-driven hardware detection. Add a table with PCI IDs, card name and variant enum. Use the table for hardware detection and initialization. Rename Cirrus-specific data and code to carry "cirrus" in the name. 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@13967 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
8e4585bb6c
commit
212aac55fd
|
@ -25,6 +25,45 @@ EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QEMU_VIDEO_CARD gQemuVideoCardList[] = {
|
||||||
|
{
|
||||||
|
CIRRUS_LOGIC_VENDOR_ID,
|
||||||
|
CIRRUS_LOGIC_5430_DEVICE_ID,
|
||||||
|
QEMU_VIDEO_CIRRUS_5430,
|
||||||
|
L"Cirrus 5430"
|
||||||
|
},{
|
||||||
|
CIRRUS_LOGIC_VENDOR_ID,
|
||||||
|
CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,
|
||||||
|
QEMU_VIDEO_CIRRUS_5430,
|
||||||
|
L"Cirrus 5430"
|
||||||
|
},{
|
||||||
|
CIRRUS_LOGIC_VENDOR_ID,
|
||||||
|
CIRRUS_LOGIC_5446_DEVICE_ID,
|
||||||
|
QEMU_VIDEO_CIRRUS_5446,
|
||||||
|
L"Cirrus 5446"
|
||||||
|
},{
|
||||||
|
0 /* end of list */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static QEMU_VIDEO_CARD*
|
||||||
|
QemuVideoDetect(
|
||||||
|
IN UINT16 VendorId,
|
||||||
|
IN UINT16 DeviceId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Index = 0;
|
||||||
|
|
||||||
|
while (gQemuVideoCardList[Index].VendorId != 0) {
|
||||||
|
if (gQemuVideoCardList[Index].VendorId == VendorId &&
|
||||||
|
gQemuVideoCardList[Index].DeviceId == DeviceId) {
|
||||||
|
return gQemuVideoCardList + Index;
|
||||||
|
}
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check if this device is supported.
|
Check if this device is supported.
|
||||||
|
|
||||||
|
@ -48,6 +87,7 @@ QemuVideoControllerDriverSupported (
|
||||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
PCI_TYPE00 Pci;
|
PCI_TYPE00 Pci;
|
||||||
EFI_DEV_PATH *Node;
|
EFI_DEV_PATH *Node;
|
||||||
|
QEMU_VIDEO_CARD *Card;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Open the PCI I/O Protocol
|
// Open the PCI I/O Protocol
|
||||||
|
@ -87,14 +127,9 @@ QemuVideoControllerDriverSupported (
|
||||||
//
|
//
|
||||||
// See if this is a Cirrus Logic PCI controller
|
// See if this is a Cirrus Logic PCI controller
|
||||||
//
|
//
|
||||||
if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {
|
Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
|
||||||
//
|
if (Card != NULL) {
|
||||||
// See if this is a 5430 or a 5446 PCI controller
|
DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));
|
||||||
//
|
|
||||||
if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID ||
|
|
||||||
Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||
|
|
||||||
Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
//
|
//
|
||||||
// If this is an Intel 945 graphics controller,
|
// If this is an Intel 945 graphics controller,
|
||||||
|
@ -119,7 +154,6 @@ QemuVideoControllerDriverSupported (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
//
|
//
|
||||||
|
@ -161,6 +195,8 @@ QemuVideoControllerDriverStart (
|
||||||
BOOLEAN PciAttributesSaved;
|
BOOLEAN PciAttributesSaved;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||||
ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
|
ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
|
||||||
|
PCI_TYPE00 Pci;
|
||||||
|
QEMU_VIDEO_CARD *Card;
|
||||||
|
|
||||||
PciAttributesSaved = FALSE;
|
PciAttributesSaved = FALSE;
|
||||||
//
|
//
|
||||||
|
@ -193,6 +229,27 @@ QemuVideoControllerDriverStart (
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the PCI Configuration Header from the PCI Device
|
||||||
|
//
|
||||||
|
Status = Private->PciIo->Pci.Read (
|
||||||
|
Private->PciIo,
|
||||||
|
EfiPciIoWidthUint32,
|
||||||
|
0,
|
||||||
|
sizeof (Pci) / sizeof (UINT32),
|
||||||
|
&Pci
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
|
||||||
|
if (Card == NULL) {
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
Private->Variant = Card->Variant;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Save original PCI attributes
|
// Save original PCI attributes
|
||||||
//
|
//
|
||||||
|
@ -274,7 +331,16 @@ QemuVideoControllerDriverStart (
|
||||||
//
|
//
|
||||||
// Construct video mode buffer
|
// Construct video mode buffer
|
||||||
//
|
//
|
||||||
Status = QemuVideoVideoModeSetup (Private);
|
switch (Private->Variant) {
|
||||||
|
case QEMU_VIDEO_CIRRUS_5430:
|
||||||
|
case QEMU_VIDEO_CIRRUS_5446:
|
||||||
|
Status = QemuVideoCirrusModeSetup (Private);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT (FALSE);
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
@ -640,27 +706,13 @@ DrawLogo (
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
InitializeGraphicsMode (
|
InitializeCirrusGraphicsMode (
|
||||||
QEMU_VIDEO_PRIVATE_DATA *Private,
|
QEMU_VIDEO_PRIVATE_DATA *Private,
|
||||||
QEMU_VIDEO_VIDEO_MODES *ModeData
|
QEMU_VIDEO_CIRRUS_MODES *ModeData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT8 Byte;
|
UINT8 Byte;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT16 DeviceId;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = Private->PciIo->Pci.Read (
|
|
||||||
Private->PciIo,
|
|
||||||
EfiPciIoWidthUint16,
|
|
||||||
PCI_DEVICE_ID_OFFSET,
|
|
||||||
1,
|
|
||||||
&DeviceId
|
|
||||||
);
|
|
||||||
//
|
|
||||||
// Read the PCI Configuration Header from the PCI Device
|
|
||||||
//
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
|
outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
|
||||||
outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
|
outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
|
||||||
|
@ -669,7 +721,7 @@ InitializeGraphicsMode (
|
||||||
outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
|
outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {
|
if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {
|
||||||
outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
|
outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
|
||||||
Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
|
Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
|
||||||
outb (Private, SEQ_DATA_REGISTER, Byte);
|
outb (Private, SEQ_DATA_REGISTER, Byte);
|
||||||
|
|
|
@ -181,7 +181,17 @@ Routine Description:
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeGraphicsMode (Private, &QemuVideoVideoModes[ModeData->ModeNumber]);
|
switch (Private->Variant) {
|
||||||
|
case QEMU_VIDEO_CIRRUS_5430:
|
||||||
|
case QEMU_VIDEO_CIRRUS_5446:
|
||||||
|
InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT (FALSE);
|
||||||
|
gBS->FreePool (Private->LineBuffer);
|
||||||
|
Private->LineBuffer = NULL;
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
This->Mode->Mode = ModeNumber;
|
This->Mode->Mode = ModeNumber;
|
||||||
This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
|
This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
|
||||||
|
|
|
@ -143,7 +143,7 @@ UINT16 Seq_1024_768_32bpp_60[15] = {
|
||||||
///
|
///
|
||||||
/// Table of supported video modes
|
/// Table of supported video modes
|
||||||
///
|
///
|
||||||
QEMU_VIDEO_VIDEO_MODES QemuVideoVideoModes[] = {
|
QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {
|
||||||
// { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
|
// { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
|
||||||
// { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
|
// { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
|
||||||
{ 640, 480, 32, 60, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },
|
{ 640, 480, 32, 60, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },
|
||||||
|
@ -154,38 +154,38 @@ QEMU_VIDEO_VIDEO_MODES QemuVideoVideoModes[] = {
|
||||||
// { 960, 720, 32, 60, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
|
// { 960, 720, 32, 60, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QEMU_VIDEO_MODE_COUNT \
|
#define QEMU_VIDEO_CIRRUS_MODE_COUNT \
|
||||||
(sizeof (QemuVideoVideoModes) / sizeof (QemuVideoVideoModes[0]))
|
(sizeof (QemuVideoCirrusModes) / sizeof (QemuVideoCirrusModes[0]))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Construct the valid video modes for QemuVideo.
|
Construct the valid video modes for QemuVideo.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
QemuVideoVideoModeSetup (
|
QemuVideoCirrusModeSetup (
|
||||||
QEMU_VIDEO_PRIVATE_DATA *Private
|
QEMU_VIDEO_PRIVATE_DATA *Private
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
QEMU_VIDEO_MODE_DATA *ModeData;
|
QEMU_VIDEO_MODE_DATA *ModeData;
|
||||||
QEMU_VIDEO_VIDEO_MODES *VideoMode;
|
QEMU_VIDEO_CIRRUS_MODES *VideoMode;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setup Video Modes
|
// Setup Video Modes
|
||||||
//
|
//
|
||||||
Private->ModeData = AllocatePool (
|
Private->ModeData = AllocatePool (
|
||||||
sizeof (Private->ModeData[0]) * QEMU_VIDEO_MODE_COUNT
|
sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT
|
||||||
);
|
);
|
||||||
ModeData = Private->ModeData;
|
ModeData = Private->ModeData;
|
||||||
VideoMode = &QemuVideoVideoModes[0];
|
VideoMode = &QemuVideoCirrusModes[0];
|
||||||
for (Index = 0; Index < QEMU_VIDEO_MODE_COUNT; Index ++) {
|
for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {
|
||||||
ModeData->ModeNumber = Index;
|
ModeData->ModeNumber = Index;
|
||||||
ModeData->HorizontalResolution = VideoMode->Width;
|
ModeData->HorizontalResolution = VideoMode->Width;
|
||||||
ModeData->VerticalResolution = VideoMode->Height;
|
ModeData->VerticalResolution = VideoMode->Height;
|
||||||
ModeData->ColorDepth = VideoMode->ColorDepth;
|
ModeData->ColorDepth = VideoMode->ColorDepth;
|
||||||
ModeData->RefreshRate = VideoMode->RefreshRate;
|
ModeData->RefreshRate = VideoMode->RefreshRate;
|
||||||
DEBUG ((EFI_D_INFO,
|
DEBUG ((EFI_D_INFO,
|
||||||
"Adding Video Mode %d: %dx%d, %d-bit, %d Hz\n",
|
"Adding Cirrus Video Mode %d: %dx%d, %d-bit, %d Hz\n",
|
||||||
ModeData->ModeNumber,
|
ModeData->ModeNumber,
|
||||||
ModeData->HorizontalResolution,
|
ModeData->HorizontalResolution,
|
||||||
ModeData->VerticalResolution,
|
ModeData->VerticalResolution,
|
||||||
|
@ -196,7 +196,7 @@ QemuVideoVideoModeSetup (
|
||||||
ModeData ++ ;
|
ModeData ++ ;
|
||||||
VideoMode ++;
|
VideoMode ++;
|
||||||
}
|
}
|
||||||
Private->MaxMode = QEMU_VIDEO_MODE_COUNT;
|
Private->MaxMode = QEMU_VIDEO_CIRRUS_MODE_COUNT;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,18 @@ typedef struct {
|
||||||
//
|
//
|
||||||
#define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('Q', 'V', 'I', 'D')
|
#define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('Q', 'V', 'I', 'D')
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QEMU_VIDEO_CIRRUS_5430 = 1,
|
||||||
|
QEMU_VIDEO_CIRRUS_5446,
|
||||||
|
} QEMU_VIDEO_VARIANT;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT16 VendorId;
|
||||||
|
UINT16 DeviceId;
|
||||||
|
QEMU_VIDEO_VARIANT Variant;
|
||||||
|
CHAR16 *Name;
|
||||||
|
} QEMU_VIDEO_CARD;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT64 Signature;
|
UINT64 Signature;
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
|
@ -98,6 +110,7 @@ typedef struct {
|
||||||
QEMU_VIDEO_MODE_DATA *ModeData;
|
QEMU_VIDEO_MODE_DATA *ModeData;
|
||||||
UINT8 *LineBuffer;
|
UINT8 *LineBuffer;
|
||||||
BOOLEAN HardwareNeedsStarting;
|
BOOLEAN HardwareNeedsStarting;
|
||||||
|
QEMU_VIDEO_VARIANT Variant;
|
||||||
} QEMU_VIDEO_PRIVATE_DATA;
|
} QEMU_VIDEO_PRIVATE_DATA;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -111,7 +124,7 @@ typedef struct {
|
||||||
UINT8 *CrtcSettings;
|
UINT8 *CrtcSettings;
|
||||||
UINT16 *SeqSettings;
|
UINT16 *SeqSettings;
|
||||||
UINT8 MiscSetting;
|
UINT8 MiscSetting;
|
||||||
} QEMU_VIDEO_VIDEO_MODES;
|
} QEMU_VIDEO_CIRRUS_MODES;
|
||||||
|
|
||||||
#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
|
#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
|
||||||
CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)
|
CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)
|
||||||
|
@ -128,7 +141,7 @@ extern UINT8 Crtc_800_600_256_60[];
|
||||||
extern UINT16 Seq_800_600_256_60[];
|
extern UINT16 Seq_800_600_256_60[];
|
||||||
extern UINT8 Crtc_1024_768_256_60[];
|
extern UINT8 Crtc_1024_768_256_60[];
|
||||||
extern UINT16 Seq_1024_768_256_60[];
|
extern UINT16 Seq_1024_768_256_60[];
|
||||||
extern QEMU_VIDEO_VIDEO_MODES QemuVideoVideoModes[];
|
extern QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[];
|
||||||
extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding;
|
extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding;
|
||||||
extern EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName;
|
extern EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName;
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2;
|
extern EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2;
|
||||||
|
@ -358,9 +371,9 @@ QemuVideoComponentNameGetControllerName (
|
||||||
// Local Function Prototypes
|
// Local Function Prototypes
|
||||||
//
|
//
|
||||||
VOID
|
VOID
|
||||||
InitializeGraphicsMode (
|
InitializeCirrusGraphicsMode (
|
||||||
QEMU_VIDEO_PRIVATE_DATA *Private,
|
QEMU_VIDEO_PRIVATE_DATA *Private,
|
||||||
QEMU_VIDEO_VIDEO_MODES *ModeData
|
QEMU_VIDEO_CIRRUS_MODES *ModeData
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -411,7 +424,7 @@ inw (
|
||||||
);
|
);
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
QemuVideoVideoModeSetup (
|
QemuVideoCirrusModeSetup (
|
||||||
QEMU_VIDEO_PRIVATE_DATA *Private
|
QEMU_VIDEO_PRIVATE_DATA *Private
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,6 @@
|
||||||
|
|
||||||
ENTRY_POINT = InitializeQemuVideo
|
ENTRY_POINT = InitializeQemuVideo
|
||||||
|
|
||||||
PCI_VENDOR_ID = 0x1013
|
|
||||||
PCI_DEVICE_ID = 0x00A8
|
|
||||||
PCI_CLASS_CODE = 0x030000
|
|
||||||
PCI_REVISION = 0x00
|
|
||||||
PCI_COMPRESS = TRUE
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# The following information is for reference only and not required by the build tools.
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue