--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ PciEnumerator.c\r
+\r
+Abstract:\r
+\r
+ PCI Bus Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+#include "PciEnumerator.h"\r
+#include "PciResourceSupport.h"\r
+#include "PciOptionRomSupport.h"\r
+\r
+EFI_STATUS\r
+PciEnumerator (\r
+ IN EFI_HANDLE Controller\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to enumerate entire pci bus system\r
+ in a given platform\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Controller - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ //\r
+ // If PCI bus has already done the full enumeration, never do it again\r
+ //\r
+ if (!gFullEnumeration) {\r
+ return PciEnumeratorLight (Controller);\r
+ }\r
+\r
+ //\r
+ // If this host bridge has been already enumerated, then return successfully\r
+ //\r
+ if (RootBridgeExisted (Controller)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the host bridge handle\r
+ //\r
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Get the pci host bridge resource allocation protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ HostBridgeHandle,\r
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
+ (VOID **) &PciResAlloc,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Notify the pci bus enumeration is about to begin\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration);\r
+\r
+ //\r
+ // Start the bus allocation phase\r
+ //\r
+ Status = PciHostBridgeEnumerator (PciResAlloc);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Submit the resource request\r
+ //\r
+ Status = PciHostBridgeResourceAllocator (PciResAlloc);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Process P2C\r
+ //\r
+ Status = PciHostBridgeP2CProcess (PciResAlloc);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Process attributes for devices on this host bridge\r
+ //\r
+ Status = PciHostBridgeDeviceAttribute (PciResAlloc);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gFullEnumeration = FALSE;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciRootBridgeEnumerator (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: RootBridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *pConfiguration;\r
+ UINT8 SubBusNumber;\r
+ UINT8 StartBusNumber;\r
+ UINT8 PaddedBusRange;\r
+ EFI_HANDLE RootBridgeHandle;\r
+\r
+ SubBusNumber = 0;\r
+ StartBusNumber = 0;\r
+ PaddedBusRange = 0;\r
+\r
+ //\r
+ // Get the root bridge handle\r
+ //\r
+ RootBridgeHandle = RootBridgeDev->Handle;\r
+\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_BUS_ENUM,\r
+ RootBridgeDev->DevicePath\r
+ );\r
+\r
+ //\r
+ // Get the Bus information\r
+ //\r
+ Status = PciResAlloc->StartBusEnumeration (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ (VOID **) &pConfiguration\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the bus number to start with\r
+ //\r
+ StartBusNumber = (UINT8) (pConfiguration->AddrRangeMin);\r
+\r
+ //\r
+ // Initialize the subordinate bus number\r
+ //\r
+ SubBusNumber = StartBusNumber;\r
+\r
+ //\r
+ // Assign bus number\r
+ //\r
+ Status = PciScanBus (\r
+ RootBridgeDev,\r
+ (UINT8) (pConfiguration->AddrRangeMin),\r
+ &SubBusNumber,\r
+ &PaddedBusRange\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+\r
+ //\r
+ // Assign max bus number scanned\r
+ //\r
+ pConfiguration->AddrLen = SubBusNumber - StartBusNumber + 1 + PaddedBusRange;\r
+\r
+ //\r
+ // Set bus number\r
+ //\r
+ Status = PciResAlloc->SetBusNumbers (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ pConfiguration\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+ProcessOptionRom (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT64 RomBase,\r
+ IN UINT64 MaxLength\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to process option rom on a certain root bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: RomBase - add argument and description to function comment\r
+// TODO: MaxLength - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Go through bridges to reach all devices\r
+ //\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+\r
+ //\r
+ // Go further to process the option rom under this bridge\r
+ //\r
+ Status = ProcessOptionRom (Temp, RomBase, MaxLength);\r
+ }\r
+\r
+ if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) {\r
+\r
+ //\r
+ // Load and process the option rom\r
+ //\r
+ Status = LoadOpRomImage (Temp, RomBase);\r
+ if (Status == EFI_SUCCESS) {\r
+ Status = ProcessOpRomImage (Temp);\r
+ }\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciAssignBusNumber (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber,\r
+ OUT UINT8 *SubBusNumber\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to assign bus number to the given PCI bus system\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: StartBusNumber - add argument and description to function comment\r
+// TODO: SubBusNumber - add argument and description to function comment\r
+// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT64 Address;\r
+ UINTN SecondBus;\r
+ UINT16 Register;\r
+ UINT8 Register8;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+\r
+ PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+\r
+ SecondBus = 0;\r
+ Register = 0;\r
+\r
+ *SubBusNumber = StartBusNumber;\r
+\r
+ //\r
+ // First check to see whether the parent is ppb\r
+ //\r
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
+\r
+ //\r
+ // Check to see whether a pci device is present\r
+ //\r
+\r
+ Status = PciDevicePresent (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ StartBusNumber,\r
+ Device,\r
+ Func\r
+ );\r
+\r
+ if (!EFI_ERROR (Status) &&\r
+ (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
+\r
+ //\r
+ // Reserved one bus for cardbus bridge\r
+ //\r
+ SecondBus = ++(*SubBusNumber);\r
+\r
+ Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
+\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint16,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
+\r
+ //\r
+ // Initialize SubBusNumber to SecondBus\r
+ //\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+ //\r
+ // If it is PPB, resursively search down this bridge\r
+ //\r
+ if (IS_PCI_BRIDGE (&Pci)) {\r
+\r
+ Register8 = 0xFF;\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ &Register8\r
+ );\r
+\r
+ Status = PciAssignBusNumber (\r
+ Bridge,\r
+ (UINT8) (SecondBus),\r
+ SubBusNumber\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set the current maximum bus number under the PPB\r
+ //\r
+\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
+\r
+ Status = PciRootBridgeIoWrite (\r
+ PciRootBridgeIo,\r
+ &Pci,\r
+ EfiPciWidthUint8,\r
+ Address,\r
+ 1,\r
+ SubBusNumber\r
+ );\r
+\r
+ }\r
+\r
+ if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+\r
+ //\r
+ // Skip sub functions, this is not a multi function device\r
+ //\r
+\r
+ Func = PCI_MAX_FUNC;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+DetermineRootBridgeAttributes (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to determine the root bridge attribute by interfacing\r
+ the host bridge resource allocation protocol.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: RootBridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT64 Attributes;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE RootBridgeHandle;\r
+\r
+ Attributes = 0;\r
+ RootBridgeHandle = RootBridgeDev->Handle;\r
+\r
+ //\r
+ // Get root bridge attribute by calling into pci host bridge resource allocation protocol\r
+ //\r
+ Status = PciResAlloc->GetAllocAttributes (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ &Attributes\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Here is the point where PCI bus driver calls HOST bridge allocation protocol\r
+ // Currently we hardcoded for ea815\r
+ //\r
+\r
+ if (Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED;\r
+ }\r
+\r
+ if (Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) {\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
+ }\r
+\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
+ RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+UINT64\r
+GetMaxOptionRomSize (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Max Option Rom size on this bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+{\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+ UINT64 MaxOptionRomSize;\r
+ UINT64 TempOptionRomSize;\r
+\r
+ MaxOptionRomSize = 0;\r
+\r
+ //\r
+ // Go through bridges to reach all devices\r
+ //\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (!IsListEmpty (&Temp->ChildList)) {\r
+\r
+ //\r
+ // Get max option rom size under this bridge\r
+ //\r
+ TempOptionRomSize = GetMaxOptionRomSize (Temp);\r
+\r
+ //\r
+ // Compare with the option rom size of the bridge\r
+ // Get the larger one\r
+ //\r
+ if (Temp->RomSize > TempOptionRomSize) {\r
+ TempOptionRomSize = Temp->RomSize;\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // For devices get the rom size directly\r
+ //\r
+ TempOptionRomSize = Temp->RomSize;\r
+ }\r
+\r
+ //\r
+ // Get the largest rom size on this bridge\r
+ //\r
+ if (TempOptionRomSize > MaxOptionRomSize) {\r
+ MaxOptionRomSize = TempOptionRomSize;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return MaxOptionRomSize;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeDeviceAttribute (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Process attributes of devices on this host bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE RootBridgeHandle;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_STATUS Status;\r
+\r
+ RootBridgeHandle = NULL;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Get RootBridg Device by handle\r
+ //\r
+ RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle);\r
+\r
+ if (RootBridgeDev == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Set the attributes for devcies behind the Root Bridge\r
+ //\r
+ Status = DetermineDeviceAttribute (RootBridgeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceAllocationStatus (\r
+ VOID *AcpiConfig,\r
+ OUT UINT64 *IoResStatus,\r
+ OUT UINT64 *Mem32ResStatus,\r
+ OUT UINT64 *PMem32ResStatus,\r
+ OUT UINT64 *Mem64ResStatus,\r
+ OUT UINT64 *PMem64ResStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get resource allocation status from the ACPI pointer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: AcpiConfig - add argument and description to function comment\r
+// TODO: IoResStatus - add argument and description to function comment\r
+// TODO: Mem32ResStatus - add argument and description to function comment\r
+// TODO: PMem32ResStatus - add argument and description to function comment\r
+// TODO: Mem64ResStatus - add argument and description to function comment\r
+// TODO: PMem64ResStatus - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+\r
+ UINT8 *Temp;\r
+ UINT64 ResStatus;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;\r
+\r
+ Temp = (UINT8 *) AcpiConfig;\r
+\r
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+\r
+ ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
+ ResStatus = ptr->AddrTranslationOffset;\r
+\r
+ switch (ptr->ResType) {\r
+ case 0:\r
+ if (ptr->AddrSpaceGranularity == 32) {\r
+ if (ptr->SpecificFlag == 0x06) {\r
+ //\r
+ // Pmem32\r
+ //\r
+ *PMem32ResStatus = ResStatus;\r
+ } else {\r
+ //\r
+ // Mem32\r
+ //\r
+ *Mem32ResStatus = ResStatus;\r
+ }\r
+ }\r
+\r
+ if (ptr->AddrSpaceGranularity == 64) {\r
+ if (ptr->SpecificFlag == 0x06) {\r
+ //\r
+ // PMem64\r
+ //\r
+ *PMem64ResStatus = ResStatus;\r
+ } else {\r
+ //\r
+ // Mem64\r
+ //\r
+ *Mem64ResStatus = ResStatus;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case 1:\r
+ //\r
+ // Io\r
+ //\r
+ *IoResStatus = ResStatus;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RejectPciDevice (\r
+ IN PCI_IO_DEVICE *PciDevice\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Remove a PCI device from device pool and mark its bar\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciDevice - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Bridge;\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+\r
+ //\r
+ // Remove the padding resource from a bridge\r
+ //\r
+ if ( IS_PCI_BRIDGE(&PciDevice->Pci) && \\r
+ PciDevice->ResourcePaddingDescriptors ) {\r
+ gBS->FreePool (PciDevice->ResourcePaddingDescriptors);\r
+ PciDevice->ResourcePaddingDescriptors = NULL;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Skip RB and PPB\r
+ //\r
+ if (IS_PCI_BRIDGE (&PciDevice->Pci) || (!PciDevice->Parent)) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) {\r
+ //\r
+ // Get the root bridge device\r
+ //\r
+ Bridge = PciDevice;\r
+ while (Bridge->Parent) {\r
+ Bridge = Bridge->Parent;\r
+ }\r
+\r
+ RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice);\r
+\r
+ //\r
+ // Mark its bar\r
+ //\r
+ InitializeP2C (PciDevice);\r
+ }\r
+\r
+ //\r
+ // Remove the device\r
+ //\r
+ Bridge = PciDevice->Parent;\r
+ CurrentLink = Bridge->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &Bridge->ChildList) {\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ if (Temp == PciDevice) {\r
+ InitializePciDevice (Temp);\r
+ RemoveEntryList (CurrentLink);\r
+ FreePciDevice (Temp);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return EFI_ABORTED;\r
+}\r
+\r
+BOOLEAN\r
+IsRejectiveDevice (\r
+ IN PCI_RESOURCE_NODE *PciResNode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Determine whethter a PCI device can be rejected\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResNode - add argument and description to function comment\r
+{\r
+ PCI_IO_DEVICE *Temp;\r
+\r
+ Temp = PciResNode->PciDev;\r
+\r
+ //\r
+ // Ensure the device is present\r
+ //\r
+ if (!Temp) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // PPB and RB should go ahead\r
+ //\r
+ if (IS_PCI_BRIDGE (&Temp->Pci) || (!Temp->Parent)) {\r
+ return TRUE;\r
+ }\r
+\r
+ //\r
+ // Skip device on Bus0\r
+ //\r
+ if ((Temp->Parent) && (Temp->BusNumber == 0)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Skip VGA\r
+ //\r
+ if (IS_PCI_VGA (&Temp->Pci)) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+GetLargerConsumerDevice (\r
+ IN PCI_RESOURCE_NODE *PciResNode1,\r
+ IN PCI_RESOURCE_NODE *PciResNode2\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the larger resource consumer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResNode1 - add argument and description to function comment\r
+// TODO: PciResNode2 - add argument and description to function comment\r
+{\r
+ if (!PciResNode2) {\r
+ return PciResNode1;\r
+ }\r
+\r
+ if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || !(PciResNode2->PciDev->Parent)) \\r
+ && (PciResNode2->ResourceUsage != PciResUsagePadding) )\r
+ {\r
+ return PciResNode1;\r
+ }\r
+\r
+ if (!PciResNode1) {\r
+ return PciResNode2;\r
+ }\r
+\r
+ if ((PciResNode1->Length) > (PciResNode2->Length)) {\r
+ return PciResNode1;\r
+ }\r
+\r
+ return PciResNode2;\r
+\r
+}\r
+\r
+PCI_RESOURCE_NODE *\r
+GetMaxResourceConsumerDevice (\r
+ IN PCI_RESOURCE_NODE *ResPool\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the max resource consumer in the host resource pool\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: ResPool - add argument and description to function comment\r
+{\r
+ PCI_RESOURCE_NODE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *PciResNode;\r
+ PCI_RESOURCE_NODE *PPBResNode;\r
+\r
+ PciResNode = NULL;\r
+\r
+ CurrentLink = ResPool->ChildList.ForwardLink;\r
+ while (CurrentLink && CurrentLink != &ResPool->ChildList) {\r
+\r
+ Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (!IsRejectiveDevice (Temp)) {\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ continue;\r
+ }\r
+\r
+ if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (!Temp->PciDev->Parent)) \\r
+ && (Temp->ResourceUsage != PciResUsagePadding))\r
+ {\r
+ PPBResNode = GetMaxResourceConsumerDevice (Temp);\r
+ PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode);\r
+ } else {\r
+ PciResNode = GetLargerConsumerDevice (PciResNode, Temp);\r
+ }\r
+\r
+ CurrentLink = CurrentLink->ForwardLink;\r
+ }\r
+\r
+ return PciResNode;\r
+}\r
+\r
+EFI_STATUS\r
+PciHostBridgeAdjustAllocation (\r
+ IN PCI_RESOURCE_NODE *IoPool,\r
+ IN PCI_RESOURCE_NODE *Mem32Pool,\r
+ IN PCI_RESOURCE_NODE *PMem32Pool,\r
+ IN PCI_RESOURCE_NODE *Mem64Pool,\r
+ IN PCI_RESOURCE_NODE *PMem64Pool,\r
+ IN UINT64 IoResStatus,\r
+ IN UINT64 Mem32ResStatus,\r
+ IN UINT64 PMem32ResStatus,\r
+ IN UINT64 Mem64ResStatus,\r
+ IN UINT64 PMem64ResStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Adjust host bridge allocation so as to reduce resource requirement\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: IoPool - add argument and description to function comment\r
+// TODO: Mem32Pool - add argument and description to function comment\r
+// TODO: PMem32Pool - add argument and description to function comment\r
+// TODO: Mem64Pool - add argument and description to function comment\r
+// TODO: PMem64Pool - add argument and description to function comment\r
+// TODO: IoResStatus - add argument and description to function comment\r
+// TODO: Mem32ResStatus - add argument and description to function comment\r
+// TODO: PMem32ResStatus - add argument and description to function comment\r
+// TODO: Mem64ResStatus - add argument and description to function comment\r
+// TODO: PMem64ResStatus - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+{\r
+ BOOLEAN AllocationAjusted;\r
+ PCI_RESOURCE_NODE *PciResNode;\r
+ PCI_RESOURCE_NODE *ResPool[5];\r
+ PCI_IO_DEVICE *RemovedPciDev[5];\r
+ UINT64 ResStatus[5];\r
+ UINTN RemovedPciDevNum;\r
+ UINTN DevIndex;\r
+ UINTN ResType;\r
+ EFI_STATUS Status;\r
+ REPORT_STATUS_CODE_LIBRARY_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;\r
+\r
+ PciResNode = NULL;\r
+ ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *));\r
+ RemovedPciDevNum = 0;\r
+\r
+ ResPool[0] = IoPool;\r
+ ResPool[1] = Mem32Pool;\r
+ ResPool[2] = PMem32Pool;\r
+ ResPool[3] = Mem64Pool;\r
+ ResPool[4] = PMem64Pool;\r
+\r
+ ResStatus[0] = IoResStatus;\r
+ ResStatus[1] = Mem32ResStatus;\r
+ ResStatus[2] = PMem32ResStatus;\r
+ ResStatus[3] = Mem64ResStatus;\r
+ ResStatus[4] = PMem64ResStatus;\r
+\r
+ AllocationAjusted = FALSE;\r
+\r
+ for (ResType = 0; ResType < 5; ResType++) {\r
+\r
+ if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) {\r
+ continue;\r
+ }\r
+\r
+ if (ResStatus[ResType] == EFI_RESOURCE_NONEXISTENT) {\r
+ //\r
+ // Hostbridge hasn't this resource type\r
+ //\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ //\r
+ // Hostbridge hasn't enough resource\r
+ //\r
+ PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]);\r
+ if (!PciResNode) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check if the device has been removed before\r
+ //\r
+ for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) {\r
+ if (PciResNode->PciDev == RemovedPciDev[DevIndex]) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Remove the device if it isn't in the array\r
+ //\r
+ Status = RejectPciDevice (PciResNode->PciDev);\r
+ if (Status == EFI_SUCCESS) {\r
+\r
+ //\r
+ // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code\r
+ //\r
+ //\r
+ // Have no way to get ReqRes, AllocRes & Bar here\r
+ //\r
+ ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData));\r
+ AllocFailExtendedData.DevicePathSize = sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+ AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath;\r
+ AllocFailExtendedData.Bar = PciResNode->Bar;\r
+\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,\r
+ (VOID *) &AllocFailExtendedData,\r
+ sizeof (AllocFailExtendedData)\r
+ );\r
+\r
+ //\r
+ // Add it to the array and indicate at least a device has been rejected\r
+ //\r
+ RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;\r
+ AllocationAjusted = TRUE;\r
+ }\r
+ }\r
+ //\r
+ // End for\r
+ //\r
+\r
+ if (AllocationAjusted) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_ABORTED;\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+ConstructAcpiResourceRequestor (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_RESOURCE_NODE *IoNode,\r
+ IN PCI_RESOURCE_NODE *Mem32Node,\r
+ IN PCI_RESOURCE_NODE *PMem32Node,\r
+ IN PCI_RESOURCE_NODE *Mem64Node,\r
+ IN PCI_RESOURCE_NODE *PMem64Node,\r
+ OUT VOID **pConfig\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: IoNode - add argument and description to function comment\r
+// TODO: Mem32Node - add argument and description to function comment\r
+// TODO: PMem32Node - add argument and description to function comment\r
+// TODO: Mem64Node - add argument and description to function comment\r
+// TODO: PMem64Node - add argument and description to function comment\r
+// TODO: pConfig - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 NumConfig;\r
+ UINT8 Aperture;\r
+ UINT8 *Configuration;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
+\r
+ NumConfig = 0;\r
+ Aperture = 0;\r
+\r
+ *pConfig = NULL;\r
+\r
+ //\r
+ // if there is io request, add to the io aperture\r
+ //\r
+ if (ResourceRequestExisted (IoNode)) {\r
+ NumConfig++;\r
+ Aperture |= 0x01;\r
+ }\r
+\r
+ //\r
+ // if there is mem32 request, add to the mem32 aperture\r
+ //\r
+ if (ResourceRequestExisted (Mem32Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x02;\r
+ }\r
+\r
+ //\r
+ // if there is pmem32 request, add to the pmem32 aperture\r
+ //\r
+ if (ResourceRequestExisted (PMem32Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x04;\r
+ }\r
+\r
+ //\r
+ // if there is mem64 request, add to the mem64 aperture\r
+ //\r
+ if (ResourceRequestExisted (Mem64Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x08;\r
+ }\r
+\r
+ //\r
+ // if there is pmem64 request, add to the pmem64 aperture\r
+ //\r
+ if (ResourceRequestExisted (PMem64Node)) {\r
+ NumConfig++;\r
+ Aperture |= 0x10;\r
+ }\r
+\r
+ if (NumConfig != 0) {\r
+\r
+ //\r
+ // If there is at least one type of resource request,\r
+ // allocate a acpi resource node\r
+ //\r
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (\r
+ Configuration,\r
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
+ );\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+\r
+ //\r
+ // Deal with io aperture\r
+ //\r
+ if (Aperture & 0x01) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Io\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+ //\r
+ // non ISA range\r
+ //\r
+ Ptr->SpecificFlag = 1;\r
+ Ptr->AddrLen = IoNode->Length;\r
+ Ptr->AddrRangeMax = IoNode->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ //\r
+ // Deal with mem32 aperture\r
+ //\r
+ if (Aperture & 0x02) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // Nonprefechable\r
+ //\r
+ Ptr->SpecificFlag = 0;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ Ptr->AddrLen = Mem32Node->Length;\r
+ Ptr->AddrRangeMax = Mem32Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+\r
+ //\r
+ // Deal with Pmem32 aperture\r
+ //\r
+ if (Aperture & 0x04) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x6;\r
+ //\r
+ // 32 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 32;\r
+ Ptr->AddrLen = PMem32Node->Length;\r
+ Ptr->AddrRangeMax = PMem32Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ //\r
+ // Deal with mem64 aperture\r
+ //\r
+ if (Aperture & 0x08) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // nonprefechable\r
+ //\r
+ Ptr->SpecificFlag = 0;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ Ptr->AddrLen = Mem64Node->Length;\r
+ Ptr->AddrRangeMax = Mem64Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+ //\r
+ // Deal with Pmem64 aperture\r
+ //\r
+ if (Aperture & 0x10) {\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+ Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
+ //\r
+ // Mem\r
+ //\r
+ Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+ //\r
+ // prefechable\r
+ //\r
+ Ptr->SpecificFlag = 0x06;\r
+ //\r
+ // 64 bit\r
+ //\r
+ Ptr->AddrSpaceGranularity = 64;\r
+ Ptr->AddrLen = PMem64Node->Length;\r
+ Ptr->AddrRangeMax = PMem64Node->Alignment;\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ }\r
+\r
+ //\r
+ // put the checksum\r
+ //\r
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
+\r
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
+ PtrEnd->Checksum = 0;\r
+\r
+ } else {\r
+\r
+ //\r
+ // If there is no resource request\r
+ //\r
+ Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);\r
+ Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+\r
+ PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+ PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
+ PtrEnd->Checksum = 0;\r
+ }\r
+\r
+ *pConfig = Configuration;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceBase (\r
+ IN VOID *pConfig,\r
+ OUT UINT64 *IoBase,\r
+ OUT UINT64 *Mem32Base,\r
+ OUT UINT64 *PMem32Base,\r
+ OUT UINT64 *Mem64Base,\r
+ OUT UINT64 *PMem64Base\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: pConfig - add argument and description to function comment\r
+// TODO: IoBase - add argument and description to function comment\r
+// TODO: Mem32Base - add argument and description to function comment\r
+// TODO: PMem32Base - add argument and description to function comment\r
+// TODO: Mem64Base - add argument and description to function comment\r
+// TODO: PMem64Base - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 *Temp;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ UINT64 ResStatus;\r
+\r
+ *IoBase = 0xFFFFFFFFFFFFFFFFULL;\r
+ *Mem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
+ *PMem32Base = 0xFFFFFFFFFFFFFFFFULL;\r
+ *Mem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
+ *PMem64Base = 0xFFFFFFFFFFFFFFFFULL;\r
+\r
+ Temp = (UINT8 *) pConfig;\r
+\r
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;\r
+ ResStatus = Ptr->AddrTranslationOffset;\r
+\r
+ if (ResStatus == EFI_RESOURCE_SATISFIED) {\r
+\r
+ switch (Ptr->ResType) {\r
+\r
+ //\r
+ // Memory type aperture\r
+ //\r
+ case 0:\r
+\r
+ //\r
+ // Check to see the granularity\r
+ //\r
+ if (Ptr->AddrSpaceGranularity == 32) {\r
+ if (Ptr->SpecificFlag & 0x06) {\r
+ *PMem32Base = Ptr->AddrRangeMin;\r
+ } else {\r
+ *Mem32Base = Ptr->AddrRangeMin;\r
+ }\r
+ }\r
+\r
+ if (Ptr->AddrSpaceGranularity == 64) {\r
+ if (Ptr->SpecificFlag & 0x06) {\r
+ *PMem64Base = Ptr->AddrRangeMin;\r
+ } else {\r
+ *Mem64Base = Ptr->AddrRangeMin;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case 1:\r
+\r
+ //\r
+ // Io type aperture\r
+ //\r
+ *IoBase = Ptr->AddrRangeMin;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+\r
+ }\r
+ //\r
+ // End switch\r
+ //\r
+ }\r
+ //\r
+ // End for\r
+ //\r
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciBridgeEnumerator (\r
+ IN PCI_IO_DEVICE *BridgeDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: BridgeDev - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINT8 SubBusNumber;\r
+ UINT8 StartBusNumber;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+\r
+ SubBusNumber = 0;\r
+ StartBusNumber = 0;\r
+ PciIo = &(BridgeDev->PciIo);\r
+ Status = PciIoRead (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciAssignBusNumber (\r
+ BridgeDev,\r
+ StartBusNumber,\r
+ &SubBusNumber\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = PciBridgeResourceAllocator (BridgeDev);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = DetermineDeviceAttribute (BridgeDev);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+PciBridgeResourceAllocator (\r
+ IN PCI_IO_DEVICE *Bridge\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_RESOURCE_NODE *IoBridge;\r
+ PCI_RESOURCE_NODE *Mem32Bridge;\r
+ PCI_RESOURCE_NODE *PMem32Bridge;\r
+ PCI_RESOURCE_NODE *Mem64Bridge;\r
+ PCI_RESOURCE_NODE *PMem64Bridge;\r
+ UINT64 IoBase;\r
+ UINT64 Mem32Base;\r
+ UINT64 PMem32Base;\r
+ UINT64 Mem64Base;\r
+ UINT64 PMem64Base;\r
+ EFI_STATUS Status;\r
+\r
+ IoBridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFF,\r
+ 0,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem32Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem32Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem64Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem64Bridge = CreateResourceNode (\r
+ Bridge,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ //\r
+ // Create resourcemap by going through all the devices subject to this root bridge\r
+ //\r
+ Status = CreateResourceMap (\r
+ Bridge,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = GetResourceBaseFromBridge (\r
+ Bridge,\r
+ &IoBase,\r
+ &Mem32Base,\r
+ &PMem32Base,\r
+ &Mem64Base,\r
+ &PMem64Base\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Program IO resources\r
+ //\r
+ ProgramResource (\r
+ IoBase,\r
+ IoBridge\r
+ );\r
+\r
+ //\r
+ // Program Mem32 resources\r
+ //\r
+ ProgramResource (\r
+ Mem32Base,\r
+ Mem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem32 resources\r
+ //\r
+ ProgramResource (\r
+ PMem32Base,\r
+ PMem32Bridge\r
+ );\r
+\r
+ //\r
+ // Program Mem64 resources\r
+ //\r
+ ProgramResource (\r
+ Mem64Base,\r
+ Mem64Bridge\r
+ );\r
+\r
+ //\r
+ // Program PMem64 resources\r
+ //\r
+ ProgramResource (\r
+ PMem64Base,\r
+ PMem64Bridge\r
+ );\r
+\r
+ DestroyResourceTree (IoBridge);\r
+ DestroyResourceTree (Mem32Bridge);\r
+ DestroyResourceTree (PMem32Bridge);\r
+ DestroyResourceTree (PMem64Bridge);\r
+ DestroyResourceTree (Mem64Bridge);\r
+\r
+ gBS->FreePool (IoBridge);\r
+ gBS->FreePool (Mem32Bridge);\r
+ gBS->FreePool (PMem32Bridge);\r
+ gBS->FreePool (PMem64Bridge);\r
+ gBS->FreePool (Mem64Bridge);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetResourceBaseFromBridge (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ OUT UINT64 *IoBase,\r
+ OUT UINT64 *Mem32Base,\r
+ OUT UINT64 *PMem32Base,\r
+ OUT UINT64 *Mem64Base,\r
+ OUT UINT64 *PMem64Base\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: IoBase - add argument and description to function comment\r
+// TODO: Mem32Base - add argument and description to function comment\r
+// TODO: PMem32Base - add argument and description to function comment\r
+// TODO: Mem64Base - add argument and description to function comment\r
+// TODO: PMem64Base - add argument and description to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ if (!Bridge->Allocated) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ *IoBase = gAllOne;\r
+ *Mem32Base = gAllOne;\r
+ *PMem32Base = gAllOne;\r
+ *Mem64Base = gAllOne;\r
+ *PMem64Base = gAllOne;\r
+\r
+ if (IS_PCI_BRIDGE (&Bridge->Pci)) {\r
+\r
+ if (Bridge->PciBar[PPB_IO_RANGE].Length) {\r
+ *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {\r
+ *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {\r
+ *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {\r
+ *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;\r
+ } else {\r
+ *PMem64Base = gAllOne;\r
+ }\r
+\r
+ }\r
+\r
+ if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {\r
+ if (Bridge->PciBar[P2C_IO_1].Length) {\r
+ *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;\r
+ } else {\r
+ if (Bridge->PciBar[P2C_IO_2].Length) {\r
+ *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;\r
+ }\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_1].Length) {\r
+ if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {\r
+ *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {\r
+ *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;\r
+ }\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_2].Length) {\r
+ if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {\r
+ *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
+ }\r
+\r
+ if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {\r
+ *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+NotifyPhase (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: PciResAlloc - add argument and description to function comment\r
+// TODO: Phase - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_STATUS Status;\r
+\r
+ HostBridgeHandle = NULL;\r
+ RootBridgeHandle = NULL;\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Get Host Bridge Handle.\r
+ //\r
+ PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);\r
+\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Call PlatformPci::PhaseNotify() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PhaseNotify (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ Phase,\r
+ ChipsetEntry\r
+ );\r
+ }\r
+\r
+ Status = PciResAlloc->NotifyPhase (\r
+ PciResAlloc,\r
+ Phase\r
+ );\r
+\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Call PlatformPci::PhaseNotify() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PhaseNotify (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ Phase,\r
+ ChipsetExit\r
+ );\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PreprocessController (\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func,\r
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: Bridge - add argument and description to function comment\r
+// TODO: Bus - add argument and description to function comment\r
+// TODO: Device - add argument and description to function comment\r
+// TODO: Func - add argument and description to function comment\r
+// TODO: Phase - add argument and description to function comment\r
+// TODO: EFI_UNSUPPORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress;\r
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Get the host bridge handle\r
+ //\r
+ HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Get the pci host bridge resource allocation protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ HostBridgeHandle,\r
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,\r
+ (VOID **) &PciResAlloc,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Get Root Brige Handle\r
+ //\r
+ while (Bridge->Parent) {\r
+ Bridge = Bridge->Parent;\r
+ }\r
+\r
+ RootBridgeHandle = Bridge->Handle;\r
+\r
+ RootBridgePciAddress.Register = 0;\r
+ RootBridgePciAddress.Function = Func;\r
+ RootBridgePciAddress.Device = Device;\r
+ RootBridgePciAddress.Bus = Bus;\r
+ RootBridgePciAddress.ExtendedRegister = 0;\r
+\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Call PlatformPci::PrepController() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PlatformPrepController (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ RootBridgeHandle,\r
+ RootBridgePciAddress,\r
+ Phase,\r
+ ChipsetEntry\r
+ );\r
+ }\r
+\r
+ Status = PciResAlloc->PreprocessController (\r
+ PciResAlloc,\r
+ RootBridgeHandle,\r
+ RootBridgePciAddress,\r
+ Phase\r
+ );\r
+\r
+ if (gPciPlatformProtocol != NULL) {\r
+ //\r
+ // Call PlatformPci::PrepController() if the protocol is present.\r
+ //\r
+ gPciPlatformProtocol->PlatformPrepController (\r
+ gPciPlatformProtocol,\r
+ HostBridgeHandle,\r
+ RootBridgeHandle,\r
+ RootBridgePciAddress,\r
+ Phase,\r
+ ChipsetExit\r
+ );\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciHotPlugRequestNotify (\r
+ IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,\r
+ IN EFI_PCI_HOTPLUG_OPERATION Operation,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,\r
+ IN OUT UINT8 *NumberOfChildren,\r
+ IN OUT EFI_HANDLE * ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Hot plug request notify.\r
+\r
+Arguments:\r
+\r
+ This - A pointer to the hot plug request protocol.\r
+ Operation - The operation.\r
+ Controller - A pointer to the controller.\r
+ RemainningDevicePath - A pointer to the device path.\r
+ NumberOfChildren - A the number of child handle in the ChildHandleBuffer.\r
+ ChildHandleBuffer - A pointer to the array contain the child handle.\r
+\r
+Returns:\r
+\r
+ Status code.\r
+\r
+--*/\r
+// TODO: RemainingDevicePath - add argument and description to function comment\r
+// TODO: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ PCI_IO_DEVICE *Bridge;\r
+ PCI_IO_DEVICE *Temp;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINTN Index;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+ //\r
+ // Get root bridge handle\r
+ //\r
+ Temp = Bridge;\r
+ while (Temp->Parent) {\r
+ Temp = Temp->Parent;\r
+ }\r
+\r
+ RootBridgeHandle = Temp->Handle;\r
+\r
+ if (Operation == EfiPciHotPlugRequestAdd) {\r
+\r
+ if (NumberOfChildren != NULL) {\r
+ *NumberOfChildren = 0;\r
+ }\r
+\r
+ if (IsListEmpty (&Bridge->ChildList)) {\r
+\r
+ Status = PciBridgeEnumerator (Bridge);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ Status = StartPciDevicesOnBridge (\r
+ RootBridgeHandle,\r
+ Bridge,\r
+ RemainingDevicePath,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (Operation == EfiPciHotplugRequestRemove) {\r
+\r
+ if (*NumberOfChildren == 0) {\r
+ //\r
+ // Remove all devices on the bridge\r
+ //\r
+ Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);\r
+ return Status;\r
+\r
+ }\r
+\r
+ for (Index = 0; Index < *NumberOfChildren; Index++) {\r
+ //\r
+ // De register all the pci device\r
+ //\r
+ Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ }\r
+ //\r
+ // End for\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+SearchHostBridgeHandle (\r
+ IN EFI_HANDLE RootBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: RootBridgeHandle - add argument and description to function comment\r
+{\r
+ EFI_HANDLE HostBridgeHandle;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Get the rootbridge Io protocol to find the host bridge handle\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ RootBridgeHandle,\r
+ &gEfiPciRootBridgeIoProtocolGuid,\r
+ (VOID **) &PciRootBridgeIo,\r
+ gPciBusDriverBinding.DriverBindingHandle,\r
+ RootBridgeHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ HostBridgeHandle = PciRootBridgeIo->ParentHandle;\r
+ for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
+ if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+AddHostBridgeEnumerator (\r
+ IN EFI_HANDLE HostBridgeHandle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+// TODO: HostBridgeHandle - add argument and description to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_ABORTED - add return value to function comment\r
+// TODO: EFI_SUCCESS - add return value to function comment\r
+{\r
+ UINTN Index;\r
+\r
+ if (!HostBridgeHandle) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ for (Index = 0; Index < gPciHostBridgeNumber; Index++) {\r
+ if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+\r
+ if (Index < PCI_MAX_HOST_BRIDGE_NUM) {\r
+ gPciHostBrigeHandles[Index] = HostBridgeHandle;\r
+ gPciHostBridgeNumber++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r