mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/PciBus: Fix bug that doesn't produce BusOverride
It's a regression of below commit:
SHA-1: 8be37a5cee
* MdeModulePkg/SecurityStubDxe: Defer 3rd party image before EndOfDxe
When PciBus driver fails to load the Option ROM, it doesn't produce
BusOverride protocol. It was a correct behavior before the above
commit. But due to the above commit, BusOverride protocol never is
produced by PciBus driver.
The patch fixes this issue using the following solution:
1. PciBus records the image device path when LoadImage fails.
2. Override.GetDriver() tries to look for the image handle using
the stored image device path.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
parent
84ed8edff1
commit
b5cbef4eff
|
@ -2,7 +2,7 @@
|
|||
# The PCI bus driver will probe all PCI devices and allocate MMIO and IO space for these devices.
|
||||
# Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable hot plug supporting.
|
||||
#
|
||||
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -96,6 +96,7 @@
|
|||
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
||||
gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiLoadedImageDevicePathProtocolGuid ## CONSUMES
|
||||
|
||||
[FeaturePcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Functions implementation for Bus Specific Driver Override protoocl.
|
||||
|
||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -28,6 +28,56 @@ InitializePciDriverOverrideInstance (
|
|||
PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the image handle whose path equals to ImagePath.
|
||||
|
||||
@param ImagePath Image path.
|
||||
|
||||
@return Image handle.
|
||||
**/
|
||||
EFI_HANDLE
|
||||
LocateImageHandle (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *ImagePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *Handles;
|
||||
UINTN Index;
|
||||
UINTN HandleNum;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
UINTN ImagePathSize;
|
||||
EFI_HANDLE ImageHandle;
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiLoadedImageDevicePathProtocolGuid,
|
||||
NULL,
|
||||
&HandleNum,
|
||||
&Handles
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ImageHandle = NULL;
|
||||
ImagePathSize = GetDevicePathSize (ImagePath);
|
||||
|
||||
for (Index = 0; Index < HandleNum; Index++) {
|
||||
Status = gBS->HandleProtocol (Handles[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &DevicePath);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
if ((ImagePathSize == GetDevicePathSize (DevicePath)) &&
|
||||
(CompareMem (ImagePath, DevicePath, ImagePathSize) == 0)
|
||||
) {
|
||||
ImageHandle = Handles[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreePool (Handles);
|
||||
return ImageHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
Uses a bus specific algorithm to retrieve a driver image handle for a controller.
|
||||
|
@ -53,49 +103,60 @@ GetDriver (
|
|||
)
|
||||
{
|
||||
PCI_IO_DEVICE *PciIoDevice;
|
||||
LIST_ENTRY *CurrentLink;
|
||||
PCI_DRIVER_OVERRIDE_LIST *Node;
|
||||
LIST_ENTRY *Link;
|
||||
PCI_DRIVER_OVERRIDE_LIST *Override;
|
||||
BOOLEAN ReturnNext;
|
||||
|
||||
Override = NULL;
|
||||
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
|
||||
ReturnNext = (BOOLEAN) (*DriverImageHandle == NULL);
|
||||
for ( Link = GetFirstNode (&PciIoDevice->OptionRomDriverList)
|
||||
; !IsNull (&PciIoDevice->OptionRomDriverList, Link)
|
||||
; Link = GetNextNode (&PciIoDevice->OptionRomDriverList, Link)
|
||||
) {
|
||||
|
||||
CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;
|
||||
Override = DRIVER_OVERRIDE_FROM_LINK (Link);
|
||||
|
||||
while (CurrentLink != NULL && CurrentLink != &PciIoDevice->OptionRomDriverList) {
|
||||
|
||||
Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
|
||||
|
||||
if (*DriverImageHandle == NULL) {
|
||||
|
||||
*DriverImageHandle = Node->DriverImageHandle;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (*DriverImageHandle == Node->DriverImageHandle) {
|
||||
|
||||
if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||
|
||||
CurrentLink->ForwardLink == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
if (ReturnNext) {
|
||||
if (Override->DriverImageHandle == NULL) {
|
||||
Override->DriverImageHandle = LocateImageHandle (Override->DriverImagePath);
|
||||
}
|
||||
|
||||
//
|
||||
// Get next node
|
||||
//
|
||||
Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
|
||||
*DriverImageHandle = Node->DriverImageHandle;
|
||||
return EFI_SUCCESS;
|
||||
if (Override->DriverImageHandle == NULL) {
|
||||
//
|
||||
// The Option ROM identified by Override->DriverImagePath is not loaded.
|
||||
//
|
||||
continue;
|
||||
} else {
|
||||
*DriverImageHandle = Override->DriverImageHandle;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentLink = CurrentLink->ForwardLink;
|
||||
if (*DriverImageHandle == Override->DriverImageHandle) {
|
||||
ReturnNext = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
ASSERT (IsNull (&PciIoDevice->OptionRomDriverList, Link));
|
||||
//
|
||||
// ReturnNext indicates a handle match happens.
|
||||
// If all nodes are checked without handle match happening,
|
||||
// the DriverImageHandle should be a invalid handle.
|
||||
//
|
||||
if (ReturnNext) {
|
||||
return EFI_NOT_FOUND;
|
||||
} else {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Add an overriding driver image.
|
||||
|
||||
@param PciIoDevice Instance of PciIo device.
|
||||
@param DriverImageHandle new added driver image.
|
||||
@param DriverImageHandle Image handle of newly added driver image.
|
||||
@param DriverImagePath Device path of newly added driver image.
|
||||
|
||||
@retval EFI_SUCCESS Successfully added driver.
|
||||
@retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
|
||||
|
@ -104,40 +165,30 @@ GetDriver (
|
|||
**/
|
||||
EFI_STATUS
|
||||
AddDriver (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN EFI_HANDLE DriverImageHandle
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN EFI_HANDLE DriverImageHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
PCI_DRIVER_OVERRIDE_LIST *Node;
|
||||
|
||||
Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Caller should pass in either Image Handle or Image Path, but not both.
|
||||
//
|
||||
ASSERT ((DriverImageHandle == NULL) || (DriverImagePath == NULL));
|
||||
|
||||
Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
|
||||
Node = AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
|
||||
if (Node == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Node->Signature = DRIVER_OVERRIDE_SIGNATURE;
|
||||
Node->DriverImageHandle = DriverImageHandle;
|
||||
Node->DriverImagePath = DuplicateDevicePath (DriverImagePath);
|
||||
|
||||
InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
|
||||
InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link);
|
||||
|
||||
PciIoDevice->BusOverride = TRUE;
|
||||
|
||||
ImageContext.Handle = LoadedImage->ImageBase;
|
||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
||||
|
||||
//
|
||||
// Get information about the image
|
||||
//
|
||||
PeCoffLoaderGetImageInfo (&ImageContext);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Functions declaration for Bus Specific Driver Override protoocl.
|
||||
|
||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -22,9 +22,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
// PCI driver override driver image list
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
LIST_ENTRY Link;
|
||||
EFI_HANDLE DriverImageHandle;
|
||||
UINT32 Signature;
|
||||
LIST_ENTRY Link;
|
||||
EFI_HANDLE DriverImageHandle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DriverImagePath;
|
||||
} PCI_DRIVER_OVERRIDE_LIST;
|
||||
|
||||
|
||||
|
@ -46,7 +47,8 @@ InitializePciDriverOverrideInstance (
|
|||
Add an overriding driver image.
|
||||
|
||||
@param PciIoDevice Instance of PciIo device.
|
||||
@param DriverImageHandle new added driver image.
|
||||
@param DriverImageHandle Image handle of newly added driver image.
|
||||
@param DriverImagePath Device path of newly added driver image.
|
||||
|
||||
@retval EFI_SUCCESS Successfully added driver.
|
||||
@retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
|
||||
|
@ -55,8 +57,9 @@ InitializePciDriverOverrideInstance (
|
|||
**/
|
||||
EFI_STATUS
|
||||
AddDriver (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN EFI_HANDLE DriverImageHandle
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN EFI_HANDLE DriverImageHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -753,13 +753,19 @@ ProcessOpRomImage (
|
|||
BufferSize,
|
||||
&ImageHandle
|
||||
);
|
||||
|
||||
FreePool (PciOptionRomImageDevicePath);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Record the Option ROM Image device path when LoadImage fails.
|
||||
// PciOverride.GetDriver() will try to look for the Image Handle using the device path later.
|
||||
//
|
||||
AddDriver (PciDevice, NULL, PciOptionRomImageDevicePath);
|
||||
} else {
|
||||
Status = gBS->StartImage (ImageHandle, NULL, NULL);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
AddDriver (PciDevice, ImageHandle);
|
||||
//
|
||||
// Record the Option ROM Image Handle
|
||||
//
|
||||
AddDriver (PciDevice, ImageHandle, NULL);
|
||||
PciRomAddImageMapping (
|
||||
ImageHandle,
|
||||
PciDevice->PciRootBridgeIo->SegmentNumber,
|
||||
|
@ -772,6 +778,7 @@ ProcessOpRomImage (
|
|||
RetStatus = EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
FreePool (PciOptionRomImageDevicePath);
|
||||
|
||||
NextImage:
|
||||
RomBarOffset += ImageSize;
|
||||
|
|
|
@ -129,7 +129,7 @@ PciRomGetImageMapping (
|
|||
mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {
|
||||
|
||||
if (mRomImageTable[Index].ImageHandle != NULL) {
|
||||
AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
|
||||
AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle, NULL);
|
||||
}
|
||||
PciIoDevice->PciIo.RomImage = mRomImageTable[Index].RomImage;
|
||||
PciIoDevice->PciIo.RomSize = mRomImageTable[Index].RomSize;
|
||||
|
|
Loading…
Reference in New Issue