mirror of https://github.com/acidanthera/audk.git
CorebootPayloadPkg/FbGop: Locate correct framebuffer device
BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1628 Current FbGop driver might bind to the wrong PCI device if a system has multiple PCI display devices. The original idea was to reuse the generic GraphicsOutputDxe to address this issue. However, after exploring different approaches discussed in the bugzilla, it turned out that the best approach is to enhance the current FbGop driver to match the PCI device BAR value with the framebuffer base address. This patch implemented this enhancement by selecting the PCI device with matched framebuffer base in its PCI BAR. This has been tested with coreboot on QEMU and Apollo Lake platform. Cc: Prince Agyeman <prince.agyeman@intel.com> Cc: Benjamin You <benjamin.you@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Maurice Ma <maurice.ma@intel.com> Reviewed-by: Benjamin You <benjamin.you@intel.com>
This commit is contained in:
parent
a281361014
commit
ae2fb9ead4
|
@ -16,7 +16,7 @@ EFI_PIXEL_BITMASK mPixelBitMask = {0x0000FF, 0x00FF00, 0xFF0000, 0x000000};
|
|||
//
|
||||
UINT64 mOriginalPciAttributes;
|
||||
BOOLEAN mPciAttributesSaved = FALSE;
|
||||
|
||||
FRAME_BUFFER_INFO *mFrameBufferInfo;
|
||||
|
||||
//
|
||||
// EFI Driver Binding Protocol Instance
|
||||
|
@ -57,10 +57,12 @@ FbGopDriverBindingSupported (
|
|||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
PCI_TYPE00 Pci;
|
||||
PCI_TYPE00 Pci;
|
||||
EFI_DEV_PATH *Node;
|
||||
UINT8 Index;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources;
|
||||
|
||||
//
|
||||
// Open the IO Abstraction(s) needed to perform the supported test
|
||||
|
@ -94,28 +96,45 @@ FbGopDriverBindingSupported (
|
|||
}
|
||||
|
||||
Status = EFI_UNSUPPORTED;
|
||||
if (Pci.Hdr.ClassCode[2] == 0x03 || (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01)) {
|
||||
if (IS_PCI_DISPLAY (&Pci) || IS_PCI_OLD_VGA (&Pci)) {
|
||||
//
|
||||
// Check if PCI BAR matches the framebuffer base
|
||||
//
|
||||
Status = EFI_UNSUPPORTED;
|
||||
for (Index = 0; Index < PCI_MAX_BAR; Index++) {
|
||||
Status = PciIo->GetBarAttributes (PciIo, Index, NULL, (VOID**) &Resources);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
if ((Resources->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) &&
|
||||
(Resources->Len == (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3)) &&
|
||||
(Resources->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) &&
|
||||
(Resources->AddrRangeMin == mFrameBufferInfo->LinearFrameBuffer)) {
|
||||
DEBUG ((DEBUG_INFO, "Found matched framebuffer PCI BAR !\n"));
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
//
|
||||
// If this is a graphics controller,
|
||||
// go further check RemainingDevicePath validation
|
||||
//
|
||||
if (RemainingDevicePath != NULL) {
|
||||
Node = (EFI_DEV_PATH *) RemainingDevicePath;
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Check if RemainingDevicePath is the End of Device Path Node,
|
||||
// if yes, return EFI_SUCCESS
|
||||
// If this is a graphics controller,
|
||||
// go further check RemainingDevicePath
|
||||
//
|
||||
if (!IsDevicePathEnd (Node)) {
|
||||
if (RemainingDevicePath != NULL) {
|
||||
Node = (EFI_DEV_PATH *) RemainingDevicePath;
|
||||
//
|
||||
// If RemainingDevicePath isn't the End of Device Path Node,
|
||||
// check its validation
|
||||
// Check if RemainingDevicePath is the End of Device Path Node,
|
||||
// if yes, return EFI_SUCCESS
|
||||
//
|
||||
if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
|
||||
Node->DevPath.SubType != ACPI_ADR_DP ||
|
||||
DevicePathNodeLength(&Node->DevPath) < sizeof(ACPI_ADR_DEVICE_PATH)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
if (!IsDevicePathEnd (Node)) {
|
||||
//
|
||||
// Verify RemainingDevicePath
|
||||
//
|
||||
if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
|
||||
Node->DevPath.SubType != ACPI_ADR_DP ||
|
||||
DevicePathNodeLength(&Node->DevPath) < sizeof(ACPI_ADR_DEVICE_PATH)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +176,7 @@ FbGopDriverBindingStart (
|
|||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT64 Supports;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "GOP START\n"));
|
||||
DEBUG ((DEBUG_INFO, "GOP START\n"));
|
||||
|
||||
//
|
||||
// Initialize local variables
|
||||
|
@ -544,7 +563,7 @@ FbGopChildHandleInstall (
|
|||
// Check for VESA BIOS Extensions for modes that are compatible with Graphics Output
|
||||
//
|
||||
Status = FbGopCheckForVbe (FbGopPrivate);
|
||||
DEBUG ((EFI_D_INFO, "FbGopCheckForVbe - %r\n", Status));
|
||||
DEBUG ((DEBUG_INFO, "FbGopCheckForVbe - %r\n", Status));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
|
@ -794,16 +813,11 @@ FbGopCheckForVbe (
|
|||
UINT32 HorizontalResolution;
|
||||
UINT32 VerticalResolution;
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
FRAME_BUFFER_INFO *pFbInfo;
|
||||
FRAME_BUFFER_INFO *FbInfo;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
//
|
||||
// Find the frame buffer information guid hob
|
||||
//
|
||||
GuidHob = GetFirstGuidHob (&gUefiFrameBufferInfoGuid);
|
||||
ASSERT (GuidHob != NULL);
|
||||
pFbInfo = (FRAME_BUFFER_INFO *)GET_GUID_HOB_DATA (GuidHob);
|
||||
|
||||
FbInfo = mFrameBufferInfo;
|
||||
|
||||
//
|
||||
// Add mode to the list of available modes
|
||||
|
@ -812,10 +826,10 @@ FbGopCheckForVbe (
|
|||
ModeBuffer = NULL;
|
||||
|
||||
ModeNumber = 1;
|
||||
BitsPerPixel = pFbInfo->BitsPerPixel;
|
||||
HorizontalResolution = pFbInfo->HorizontalResolution;
|
||||
VerticalResolution = pFbInfo->VerticalResolution;
|
||||
BytesPerScanLine = pFbInfo->BytesPerScanLine;
|
||||
BitsPerPixel = FbInfo->BitsPerPixel;
|
||||
HorizontalResolution = FbInfo->HorizontalResolution;
|
||||
VerticalResolution = FbInfo->VerticalResolution;
|
||||
BytesPerScanLine = FbInfo->BytesPerScanLine;
|
||||
|
||||
ModeBuffer = (FB_VIDEO_MODE_DATA *) AllocatePool (
|
||||
ModeNumber * sizeof (FB_VIDEO_MODE_DATA)
|
||||
|
@ -845,16 +859,16 @@ FbGopCheckForVbe (
|
|||
CurrentModeData = &ModeBuffer[ModeNumber - 1];
|
||||
CurrentModeData->BytesPerScanLine = (UINT16)BytesPerScanLine;
|
||||
|
||||
CurrentModeData->Red = *(FB_VIDEO_COLOR_PLACEMENT *)&(pFbInfo->Red);
|
||||
CurrentModeData->Blue = *(FB_VIDEO_COLOR_PLACEMENT *)&(pFbInfo->Blue);
|
||||
CurrentModeData->Green = *(FB_VIDEO_COLOR_PLACEMENT *)&(pFbInfo->Green);
|
||||
CurrentModeData->Reserved = *(FB_VIDEO_COLOR_PLACEMENT *)&(pFbInfo->Reserved);
|
||||
CurrentModeData->Red = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Red);
|
||||
CurrentModeData->Blue = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Blue);
|
||||
CurrentModeData->Green = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Green);
|
||||
CurrentModeData->Reserved = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Reserved);
|
||||
|
||||
CurrentModeData->BitsPerPixel = (UINT32)BitsPerPixel;
|
||||
CurrentModeData->HorizontalResolution = HorizontalResolution;
|
||||
CurrentModeData->VerticalResolution = VerticalResolution;
|
||||
CurrentModeData->FrameBufferSize = CurrentModeData->BytesPerScanLine * CurrentModeData->VerticalResolution;
|
||||
CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN) pFbInfo->LinearFrameBuffer;
|
||||
CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN) FbInfo->LinearFrameBuffer;
|
||||
CurrentModeData->VbeModeNumber = 0;
|
||||
CurrentModeData->ColorDepth = 32;
|
||||
CurrentModeData->RefreshRate = 60;
|
||||
|
@ -1499,6 +1513,8 @@ FbGopEntryPoint(
|
|||
//
|
||||
GuidHob = GetFirstGuidHob (&gUefiFrameBufferInfoGuid);
|
||||
if (GuidHob != NULL) {
|
||||
mFrameBufferInfo = (FRAME_BUFFER_INFO *)GET_GUID_HOB_DATA (GuidHob);
|
||||
|
||||
//
|
||||
// Install driver model protocol(s).
|
||||
//
|
||||
|
@ -1512,7 +1528,7 @@ FbGopEntryPoint(
|
|||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
} else {
|
||||
DEBUG ((EFI_D_ERROR, "No FrameBuffer information from coreboot. NO GOP driver !!!\n"));
|
||||
DEBUG ((DEBUG_ERROR, "No FrameBuffer information from coreboot. NO GOP driver !!!\n"));
|
||||
Status = EFI_ABORTED;
|
||||
}
|
||||
return Status;
|
||||
|
|
Loading…
Reference in New Issue