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:
qhuang8
2008-02-19 04:17:05 +00:00
parent 23f642e80a
commit eb9a9a5e23
5 changed files with 122 additions and 182 deletions

View File

@ -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,

View File

@ -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:

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }