Produce all the PciIo & Dpath protocol for all the pci devices under the current host bridge.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4703 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -335,44 +335,48 @@ Returns:
|
|||||||
PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);
|
PciIoWrite (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Process Platform OpRom
|
// Process OpRom
|
||||||
//
|
//
|
||||||
if (gPciPlatformProtocol != NULL && !PciIoDevice->AllOpRomProcessed) {
|
if (!PciIoDevice->AllOpRomProcessed) {
|
||||||
PciIoDevice->AllOpRomProcessed = TRUE;
|
PciIoDevice->AllOpRomProcessed = TRUE;
|
||||||
|
|
||||||
Status = gPciPlatformProtocol->GetPciRom (
|
//
|
||||||
gPciPlatformProtocol,
|
// Get the OpRom provided by platform
|
||||||
PciIoDevice->Handle,
|
//
|
||||||
&PlatformOpRomBuffer,
|
if (gPciPlatformProtocol != NULL) {
|
||||||
&PlatformOpRomSize
|
Status = gPciPlatformProtocol->GetPciRom (
|
||||||
);
|
gPciPlatformProtocol,
|
||||||
|
PciIoDevice->Handle,
|
||||||
|
&PlatformOpRomBuffer,
|
||||||
|
&PlatformOpRomSize
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
PciIoDevice->RomSize = PlatformOpRomSize;
|
||||||
|
PciIoDevice->PciIo.RomSize = PlatformOpRomSize;
|
||||||
|
PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;
|
||||||
|
//
|
||||||
|
// For OpROM read from gPciPlatformProtocol:
|
||||||
|
// Add the Rom Image to internal database for later PCI light enumeration
|
||||||
|
//
|
||||||
|
PciRomAddImageMapping (
|
||||||
|
NULL,
|
||||||
|
PciIoDevice->PciRootBridgeIo->SegmentNumber,
|
||||||
|
PciIoDevice->BusNumber,
|
||||||
|
PciIoDevice->DeviceNumber,
|
||||||
|
PciIoDevice->FunctionNumber,
|
||||||
|
(UINT64) (UINTN) PciIoDevice->PciIo.RomImage,
|
||||||
|
PciIoDevice->PciIo.RomSize
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
//
|
||||||
|
// Dispatch the EFI OpRom for the PCI device.
|
||||||
//
|
// The OpRom is got from platform in the above code
|
||||||
// Have Platform OpRom
|
// or loaded from device in previous bus enumeration
|
||||||
//
|
//
|
||||||
PciIoDevice->RomSize = PlatformOpRomSize;
|
if (PciIoDevice->RomSize > 0) {
|
||||||
PciIoDevice->PciIo.RomSize = PlatformOpRomSize;
|
|
||||||
PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer;
|
|
||||||
|
|
||||||
//
|
|
||||||
// For OpROM read from gPciPlatformProtocol:
|
|
||||||
// Add the Rom Image to internal database for later PCI light enumeration
|
|
||||||
//
|
|
||||||
PciRomAddImageMapping (
|
|
||||||
NULL,
|
|
||||||
PciIoDevice->PciRootBridgeIo->SegmentNumber,
|
|
||||||
PciIoDevice->BusNumber,
|
|
||||||
PciIoDevice->DeviceNumber,
|
|
||||||
PciIoDevice->FunctionNumber,
|
|
||||||
(UINT64) (UINTN) PciIoDevice->PciIo.RomImage,
|
|
||||||
PciIoDevice->PciIo.RomSize
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Process Image
|
|
||||||
//
|
|
||||||
ProcessOpRomImage (PciIoDevice);
|
ProcessOpRomImage (PciIoDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -659,7 +663,6 @@ Returns:
|
|||||||
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
||||||
// TODO: EFI_NOT_FOUND - add return value to function comment
|
// TODO: EFI_NOT_FOUND - add return value to function comment
|
||||||
{
|
{
|
||||||
PCI_IO_DEVICE *Temp;
|
|
||||||
PCI_IO_DEVICE *PciIoDevice;
|
PCI_IO_DEVICE *PciIoDevice;
|
||||||
EFI_DEV_PATH_PTR Node;
|
EFI_DEV_PATH_PTR Node;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
|
||||||
@ -671,13 +674,13 @@ Returns:
|
|||||||
|
|
||||||
while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
|
while (CurrentLink && CurrentLink != &RootBridge->ChildList) {
|
||||||
|
|
||||||
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
|
PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
|
||||||
if (RemainingDevicePath != NULL) {
|
if (RemainingDevicePath != NULL) {
|
||||||
|
|
||||||
Node.DevPath = RemainingDevicePath;
|
Node.DevPath = RemainingDevicePath;
|
||||||
|
|
||||||
if (Node.Pci->Device != Temp->DeviceNumber ||
|
if (Node.Pci->Device != PciIoDevice->DeviceNumber ||
|
||||||
Node.Pci->Function != Temp->FunctionNumber) {
|
Node.Pci->Function != PciIoDevice->FunctionNumber) {
|
||||||
CurrentLink = CurrentLink->ForwardLink;
|
CurrentLink = CurrentLink->ForwardLink;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -685,30 +688,28 @@ Returns:
|
|||||||
//
|
//
|
||||||
// Check if the device has been assigned with required resource
|
// Check if the device has been assigned with required resource
|
||||||
//
|
//
|
||||||
if (!Temp->Allocated) {
|
if (!PciIoDevice->Allocated) {
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if the current node has been registered before
|
// Check if the current node has been registered before
|
||||||
// If it is not, register it
|
// If it is not, register it
|
||||||
//
|
//
|
||||||
if (!Temp->Registered) {
|
if (!PciIoDevice->Registered) {
|
||||||
PciIoDevice = Temp;
|
|
||||||
|
|
||||||
Status = RegisterPciDevice (
|
Status = RegisterPciDevice (
|
||||||
Controller,
|
Controller,
|
||||||
PciIoDevice,
|
PciIoDevice,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {
|
if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && PciIoDevice->Registered) {
|
||||||
ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;
|
ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle;
|
||||||
(*NumberOfChildren)++;
|
(*NumberOfChildren)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the next device path
|
// Get the next device path
|
||||||
//
|
//
|
||||||
@ -720,28 +721,28 @@ Returns:
|
|||||||
//
|
//
|
||||||
// If it is a PPB
|
// If it is a PPB
|
||||||
//
|
//
|
||||||
if (!IsListEmpty (&Temp->ChildList)) {
|
if (!IsListEmpty (&PciIoDevice->ChildList)) {
|
||||||
Status = StartPciDevicesOnBridge (
|
Status = StartPciDevicesOnBridge (
|
||||||
Controller,
|
Controller,
|
||||||
Temp,
|
PciIoDevice,
|
||||||
CurrentDevicePath,
|
CurrentDevicePath,
|
||||||
NumberOfChildren,
|
NumberOfChildren,
|
||||||
ChildHandleBuffer
|
ChildHandleBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
Temp->PciIo.Attributes (
|
PciIoDevice->PciIo.Attributes (
|
||||||
&(Temp->PciIo),
|
&(PciIoDevice->PciIo),
|
||||||
EfiPciIoAttributeOperationSupported,
|
EfiPciIoAttributeOperationSupported,
|
||||||
0,
|
0,
|
||||||
&Supports
|
&Supports
|
||||||
);
|
);
|
||||||
Supports &= EFI_PCI_DEVICE_ENABLE;
|
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||||
Temp->PciIo.Attributes (
|
PciIoDevice->PciIo.Attributes (
|
||||||
&(Temp->PciIo),
|
&(PciIoDevice->PciIo),
|
||||||
EfiPciIoAttributeOperationEnable,
|
EfiPciIoAttributeOperationEnable,
|
||||||
Supports,
|
Supports,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
} else {
|
} else {
|
||||||
@ -759,50 +760,46 @@ Returns:
|
|||||||
// try to enable all the pci devices under this bridge
|
// try to enable all the pci devices under this bridge
|
||||||
//
|
//
|
||||||
|
|
||||||
if (!Temp->Registered && Temp->Allocated) {
|
if (!PciIoDevice->Registered && PciIoDevice->Allocated) {
|
||||||
|
|
||||||
PciIoDevice = Temp;
|
|
||||||
|
|
||||||
Status = RegisterPciDevice (
|
Status = RegisterPciDevice (
|
||||||
Controller,
|
Controller,
|
||||||
PciIoDevice,
|
PciIoDevice,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && Temp->Registered) {
|
if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && PciIoDevice->Registered) {
|
||||||
ChildHandleBuffer[*NumberOfChildren] = Temp->Handle;
|
ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle;
|
||||||
(*NumberOfChildren)++;
|
(*NumberOfChildren)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsListEmpty (&Temp->ChildList)) {
|
if (!IsListEmpty (&PciIoDevice->ChildList)) {
|
||||||
Status = StartPciDevicesOnBridge (
|
Status = StartPciDevicesOnBridge (
|
||||||
Controller,
|
Controller,
|
||||||
Temp,
|
PciIoDevice,
|
||||||
RemainingDevicePath,
|
RemainingDevicePath,
|
||||||
NumberOfChildren,
|
NumberOfChildren,
|
||||||
ChildHandleBuffer
|
ChildHandleBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
Temp->PciIo.Attributes (
|
PciIoDevice->PciIo.Attributes (
|
||||||
&(Temp->PciIo),
|
&(PciIoDevice->PciIo),
|
||||||
EfiPciIoAttributeOperationSupported,
|
EfiPciIoAttributeOperationSupported,
|
||||||
0,
|
0,
|
||||||
&Supports
|
&Supports
|
||||||
);
|
);
|
||||||
Supports &= EFI_PCI_DEVICE_ENABLE;
|
Supports &= EFI_PCI_DEVICE_ENABLE;
|
||||||
Temp->PciIo.Attributes (
|
PciIoDevice->PciIo.Attributes (
|
||||||
&(Temp->PciIo),
|
&(PciIoDevice->PciIo),
|
||||||
EfiPciIoAttributeOperationEnable,
|
EfiPciIoAttributeOperationEnable,
|
||||||
Supports,
|
Supports,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentLink = CurrentLink->ForwardLink;
|
CurrentLink = CurrentLink->ForwardLink;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -811,46 +808,31 @@ Returns:
|
|||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
StartPciDevices (
|
StartPciDevices (
|
||||||
IN EFI_HANDLE Controller,
|
IN EFI_HANDLE Controller
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Start to manage the PCI device according to RemainingDevicePath
|
Start to manage all the PCI devices it found previously under
|
||||||
If RemainingDevicePath == NULL, the PCI bus driver will start
|
the entire host bridge.
|
||||||
to manage all the PCI devices it found previously
|
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
Controller - An efi handle.
|
Controller - root bridge handle.
|
||||||
RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
None
|
None
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
||||||
// TODO: EFI_SUCCESS - add return value to function comment
|
|
||||||
{
|
{
|
||||||
EFI_DEV_PATH_PTR Node;
|
|
||||||
PCI_IO_DEVICE *RootBridge;
|
PCI_IO_DEVICE *RootBridge;
|
||||||
|
EFI_HANDLE ThisHostBridge;
|
||||||
LIST_ENTRY *CurrentLink;
|
LIST_ENTRY *CurrentLink;
|
||||||
|
|
||||||
if (RemainingDevicePath != NULL) {
|
RootBridge = GetRootBridgeByHandle (Controller);
|
||||||
|
ASSERT (RootBridge != NULL);
|
||||||
//
|
ThisHostBridge = RootBridge->PciRootBridgeIo->ParentHandle;
|
||||||
// Check if the RemainingDevicePath is valid
|
|
||||||
//
|
|
||||||
Node.DevPath = RemainingDevicePath;
|
|
||||||
if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||
|
|
||||||
((Node.DevPath->SubType != HW_PCI_DP) &&
|
|
||||||
(DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))
|
|
||||||
) {
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentLink = gPciDevicePool.ForwardLink;
|
CurrentLink = gPciDevicePool.ForwardLink;
|
||||||
|
|
||||||
@ -860,11 +842,11 @@ Returns:
|
|||||||
//
|
//
|
||||||
// Locate the right root bridge to start
|
// Locate the right root bridge to start
|
||||||
//
|
//
|
||||||
if (RootBridge->Handle == Controller) {
|
if (RootBridge->PciRootBridgeIo->ParentHandle == ThisHostBridge) {
|
||||||
StartPciDevicesOnBridge (
|
StartPciDevicesOnBridge (
|
||||||
Controller,
|
RootBridge->Handle,
|
||||||
RootBridge,
|
RootBridge,
|
||||||
RemainingDevicePath,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
@ -1007,40 +989,6 @@ Returns:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
RootBridgeExisted (
|
|
||||||
IN EFI_HANDLE RootBridgeHandle
|
|
||||||
)
|
|
||||||
/*++
|
|
||||||
|
|
||||||
Routine Description:
|
|
||||||
|
|
||||||
This function searches if RootBridgeHandle has already existed
|
|
||||||
in current device pool.
|
|
||||||
|
|
||||||
If so, it means the given root bridge has been already enumerated.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
RootBridgeHandle - An efi handle.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
None
|
|
||||||
|
|
||||||
--*/
|
|
||||||
{
|
|
||||||
PCI_IO_DEVICE *Bridge;
|
|
||||||
|
|
||||||
Bridge = GetRootBridgeByHandle (RootBridgeHandle);
|
|
||||||
|
|
||||||
if (Bridge != NULL) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
PciDeviceExisted (
|
PciDeviceExisted (
|
||||||
IN PCI_IO_DEVICE *Bridge,
|
IN PCI_IO_DEVICE *Bridge,
|
||||||
|
@ -244,8 +244,7 @@ Returns:
|
|||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
StartPciDevices (
|
StartPciDevices (
|
||||||
IN EFI_HANDLE Controller,
|
IN EFI_HANDLE Controller
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
@ -256,7 +255,6 @@ Routine Description:
|
|||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Controller - TODO: add argument description
|
Controller - TODO: add argument description
|
||||||
RemainingDevicePath - TODO: add argument description
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
|
@ -52,13 +52,6 @@ Returns:
|
|||||||
return PciEnumeratorLight (Controller);
|
return PciEnumeratorLight (Controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// If this host bridge has been already enumerated, then return successfully
|
|
||||||
//
|
|
||||||
if (RootBridgeExisted (Controller)) {
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the rootbridge Io protocol to find the host bridge handle
|
// Get the rootbridge Io protocol to find the host bridge handle
|
||||||
//
|
//
|
||||||
@ -277,7 +270,6 @@ Returns:
|
|||||||
{
|
{
|
||||||
LIST_ENTRY *CurrentLink;
|
LIST_ENTRY *CurrentLink;
|
||||||
PCI_IO_DEVICE *Temp;
|
PCI_IO_DEVICE *Temp;
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Go through bridges to reach all devices
|
// Go through bridges to reach all devices
|
||||||
@ -290,7 +282,7 @@ Returns:
|
|||||||
//
|
//
|
||||||
// Go further to process the option rom under this bridge
|
// Go further to process the option rom under this bridge
|
||||||
//
|
//
|
||||||
Status = ProcessOptionRom (Temp, RomBase, MaxLength);
|
ProcessOptionRom (Temp, RomBase, MaxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {
|
if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {
|
||||||
@ -298,10 +290,7 @@ Returns:
|
|||||||
//
|
//
|
||||||
// Load and process the option rom
|
// Load and process the option rom
|
||||||
//
|
//
|
||||||
Status = LoadOpRomImage (Temp, RomBase);
|
LoadOpRomImage (Temp, RomBase);
|
||||||
if (Status == EFI_SUCCESS) {
|
|
||||||
Status = ProcessOpRomImage (Temp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentLink = CurrentLink->ForwardLink;
|
CurrentLink = CurrentLink->ForwardLink;
|
||||||
|
@ -1000,6 +1000,12 @@ Returns:
|
|||||||
}
|
}
|
||||||
|
|
||||||
PciRomGetImageMapping (Temp);
|
PciRomGetImageMapping (Temp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// The OpRom has already been processed in the first round
|
||||||
|
//
|
||||||
|
Temp->AllOpRomProcessed = TRUE;
|
||||||
|
|
||||||
CurrentLink = CurrentLink->ForwardLink;
|
CurrentLink = CurrentLink->ForwardLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1856,6 +1862,7 @@ Routine Description:
|
|||||||
|
|
||||||
This routine is used to enumerate entire pci bus system
|
This routine is used to enumerate entire pci bus system
|
||||||
in a given platform
|
in a given platform
|
||||||
|
It is only called on the second start on the same Root Bridge.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
@ -1881,9 +1888,9 @@ Returns:
|
|||||||
Descriptors = NULL;
|
Descriptors = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If this host bridge has been already enumerated, then return successfully
|
// If this root bridge has been already enumerated, then return successfully
|
||||||
//
|
//
|
||||||
if (RootBridgeExisted (Controller)) {
|
if (GetRootBridgeByHandle (Controller) != NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,13 +245,11 @@ Returns:
|
|||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enable PCI device specified by remaining device path. BDS or other driver can call the
|
// Start all the devices under the entire host bridge.
|
||||||
// start more than once.
|
|
||||||
//
|
//
|
||||||
|
StartPciDevices (Controller);
|
||||||
StartPciDevices (Controller, RemainingDevicePath);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user