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.
|
# 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.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -96,6 +96,7 @@
|
||||||
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
||||||
gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
|
gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiLoadedImageDevicePathProtocolGuid ## CONSUMES
|
||||||
|
|
||||||
[FeaturePcd]
|
[FeaturePcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Functions implementation for Bus Specific Driver Override protoocl.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -28,6 +28,56 @@ InitializePciDriverOverrideInstance (
|
||||||
PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
|
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.
|
Uses a bus specific algorithm to retrieve a driver image handle for a controller.
|
||||||
|
@ -53,49 +103,60 @@ GetDriver (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PCI_IO_DEVICE *PciIoDevice;
|
PCI_IO_DEVICE *PciIoDevice;
|
||||||
LIST_ENTRY *CurrentLink;
|
LIST_ENTRY *Link;
|
||||||
PCI_DRIVER_OVERRIDE_LIST *Node;
|
PCI_DRIVER_OVERRIDE_LIST *Override;
|
||||||
|
BOOLEAN ReturnNext;
|
||||||
|
|
||||||
|
Override = NULL;
|
||||||
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
|
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) {
|
if (ReturnNext) {
|
||||||
|
if (Override->DriverImageHandle == NULL) {
|
||||||
Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
|
Override->DriverImageHandle = LocateImageHandle (Override->DriverImagePath);
|
||||||
|
|
||||||
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 (Override->DriverImageHandle == NULL) {
|
||||||
// Get next node
|
//
|
||||||
//
|
// The Option ROM identified by Override->DriverImagePath is not loaded.
|
||||||
Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
|
//
|
||||||
*DriverImageHandle = Node->DriverImageHandle;
|
continue;
|
||||||
return EFI_SUCCESS;
|
} 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.
|
Add an overriding driver image.
|
||||||
|
|
||||||
@param PciIoDevice Instance of PciIo device.
|
@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_SUCCESS Successfully added driver.
|
||||||
@retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
|
@retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
|
||||||
|
@ -104,40 +165,30 @@ GetDriver (
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
AddDriver (
|
AddDriver (
|
||||||
IN PCI_IO_DEVICE *PciIoDevice,
|
IN PCI_IO_DEVICE *PciIoDevice,
|
||||||
IN EFI_HANDLE DriverImageHandle
|
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;
|
PCI_DRIVER_OVERRIDE_LIST *Node;
|
||||||
|
|
||||||
Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
|
//
|
||||||
if (EFI_ERROR (Status)) {
|
// Caller should pass in either Image Handle or Image Path, but not both.
|
||||||
return Status;
|
//
|
||||||
}
|
ASSERT ((DriverImageHandle == NULL) || (DriverImagePath == NULL));
|
||||||
|
|
||||||
Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
|
Node = AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
|
||||||
if (Node == NULL) {
|
if (Node == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node->Signature = DRIVER_OVERRIDE_SIGNATURE;
|
Node->Signature = DRIVER_OVERRIDE_SIGNATURE;
|
||||||
Node->DriverImageHandle = DriverImageHandle;
|
Node->DriverImageHandle = DriverImageHandle;
|
||||||
|
Node->DriverImagePath = DuplicateDevicePath (DriverImagePath);
|
||||||
|
|
||||||
InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
|
InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link);
|
||||||
|
|
||||||
PciIoDevice->BusOverride = TRUE;
|
PciIoDevice->BusOverride = TRUE;
|
||||||
|
|
||||||
ImageContext.Handle = LoadedImage->ImageBase;
|
|
||||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get information about the image
|
|
||||||
//
|
|
||||||
PeCoffLoaderGetImageInfo (&ImageContext);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Functions declaration for Bus Specific Driver Override protoocl.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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
|
// PCI driver override driver image list
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
LIST_ENTRY Link;
|
LIST_ENTRY Link;
|
||||||
EFI_HANDLE DriverImageHandle;
|
EFI_HANDLE DriverImageHandle;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DriverImagePath;
|
||||||
} PCI_DRIVER_OVERRIDE_LIST;
|
} PCI_DRIVER_OVERRIDE_LIST;
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +47,8 @@ InitializePciDriverOverrideInstance (
|
||||||
Add an overriding driver image.
|
Add an overriding driver image.
|
||||||
|
|
||||||
@param PciIoDevice Instance of PciIo device.
|
@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_SUCCESS Successfully added driver.
|
||||||
@retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
|
@retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
|
||||||
|
@ -55,8 +57,9 @@ InitializePciDriverOverrideInstance (
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
AddDriver (
|
AddDriver (
|
||||||
IN PCI_IO_DEVICE *PciIoDevice,
|
IN PCI_IO_DEVICE *PciIoDevice,
|
||||||
IN EFI_HANDLE DriverImageHandle
|
IN EFI_HANDLE DriverImageHandle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -753,13 +753,19 @@ ProcessOpRomImage (
|
||||||
BufferSize,
|
BufferSize,
|
||||||
&ImageHandle
|
&ImageHandle
|
||||||
);
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
FreePool (PciOptionRomImageDevicePath);
|
//
|
||||||
|
// Record the Option ROM Image device path when LoadImage fails.
|
||||||
if (!EFI_ERROR (Status)) {
|
// 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);
|
Status = gBS->StartImage (ImageHandle, NULL, NULL);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
AddDriver (PciDevice, ImageHandle);
|
//
|
||||||
|
// Record the Option ROM Image Handle
|
||||||
|
//
|
||||||
|
AddDriver (PciDevice, ImageHandle, NULL);
|
||||||
PciRomAddImageMapping (
|
PciRomAddImageMapping (
|
||||||
ImageHandle,
|
ImageHandle,
|
||||||
PciDevice->PciRootBridgeIo->SegmentNumber,
|
PciDevice->PciRootBridgeIo->SegmentNumber,
|
||||||
|
@ -772,6 +778,7 @@ ProcessOpRomImage (
|
||||||
RetStatus = EFI_SUCCESS;
|
RetStatus = EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FreePool (PciOptionRomImageDevicePath);
|
||||||
|
|
||||||
NextImage:
|
NextImage:
|
||||||
RomBarOffset += ImageSize;
|
RomBarOffset += ImageSize;
|
||||||
|
|
|
@ -129,7 +129,7 @@ PciRomGetImageMapping (
|
||||||
mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {
|
mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) {
|
||||||
|
|
||||||
if (mRomImageTable[Index].ImageHandle != NULL) {
|
if (mRomImageTable[Index].ImageHandle != NULL) {
|
||||||
AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle);
|
AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle, NULL);
|
||||||
}
|
}
|
||||||
PciIoDevice->PciIo.RomImage = mRomImageTable[Index].RomImage;
|
PciIoDevice->PciIo.RomImage = mRomImageTable[Index].RomImage;
|
||||||
PciIoDevice->PciIo.RomSize = mRomImageTable[Index].RomSize;
|
PciIoDevice->PciIo.RomSize = mRomImageTable[Index].RomSize;
|
||||||
|
|
Loading…
Reference in New Issue