+{\r
+ if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
+ return PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+ PciResAlloc\r
+ );\r
+ } else {\r
+ return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+ PciResAlloc\r
+ );\r
+ } \r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\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: EFI_NOT_FOUND - add return value to function comment\r
+// TODO: EFI_OUT_OF_RESOURCES - add return value 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
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ VOID *AcpiConfig;\r
+ EFI_STATUS Status;\r
+ UINT64 IoBase;\r
+ UINT64 Mem32Base;\r
+ UINT64 PMem32Base;\r
+ UINT64 Mem64Base;\r
+ UINT64 PMem64Base;\r
+ UINT64 MaxOptionRomSize;\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
+ PCI_RESOURCE_NODE IoPool;\r
+ PCI_RESOURCE_NODE Mem32Pool;\r
+ PCI_RESOURCE_NODE PMem32Pool;\r
+ PCI_RESOURCE_NODE Mem64Pool;\r
+ PCI_RESOURCE_NODE PMem64Pool;\r
+ REPORT_STATUS_CODE_LIBRARY_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;\r
+\r
+ //\r
+ // Initialize resource pool\r
+ //\r
+ \r
+ InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
+ InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
+ InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
+ InitializeResourcePool (&Mem64Pool, PciBarTypeMem64);\r
+ InitializeResourcePool (&PMem64Pool, PciBarTypePMem64);\r
+\r
+ RootBridgeDev = NULL;\r
+ RootBridgeHandle = 0;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\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
+ // Get host bridge handle for status report\r
+ //\r
+ ExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle;\r
+\r
+ //\r
+ // Create the entire system resource map from the information collected by\r
+ // enumerator. Several resource tree was created\r
+ //\r
+\r
+ IoBridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFF,\r
+ 0,\r
+ PciBarTypeIo16,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem32Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem32Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypePMem32,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ Mem64Bridge = CreateResourceNode (\r
+ RootBridgeDev,\r
+ 0,\r
+ 0xFFFFF,\r
+ 0,\r
+ PciBarTypeMem64,\r
+ PciResUsageTypical\r
+ );\r
+\r
+ PMem64Bridge = CreateResourceNode (\r
+ RootBridgeDev,\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
+ RootBridgeDev,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge\r
+ );\r
+\r
+ //\r
+ // Get the max ROM size that the root bridge can process\r
+ //\r
+ RootBridgeDev->RomSize = Mem32Bridge->Length;\r
+\r
+ //\r
+ // Get Max Option Rom size for current root bridge\r
+ //\r
+ MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev);\r
+\r
+ //\r
+ // Enlarger the mem32 resource to accomdate the option rom\r
+ // if the mem32 resource is not enough to hold the rom\r
+ //\r
+ if (MaxOptionRomSize > Mem32Bridge->Length) {\r
+\r
+ Mem32Bridge->Length = MaxOptionRomSize;\r
+ RootBridgeDev->RomSize = MaxOptionRomSize;\r
+\r
+ //\r
+ // Alignment should be adjusted as well\r
+ //\r
+ if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) {\r
+ Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Based on the all the resource tree, contruct ACPI resource node to\r
+ // submit the resource aperture to pci host bridge protocol\r
+ //\r
+ Status = ConstructAcpiResourceRequestor (\r
+ RootBridgeDev,\r
+ IoBridge,\r
+ Mem32Bridge,\r
+ PMem32Bridge,\r
+ Mem64Bridge,\r
+ PMem64Bridge,\r
+ &AcpiConfig\r
+ );\r
+\r
+ //\r
+ // Insert these resource nodes into the database\r
+ //\r
+ InsertResourceNode (&IoPool, IoBridge);\r
+ InsertResourceNode (&Mem32Pool, Mem32Bridge);\r
+ InsertResourceNode (&PMem32Pool, PMem32Bridge);\r
+ InsertResourceNode (&Mem64Pool, Mem64Bridge);\r
+ InsertResourceNode (&PMem64Pool, PMem64Bridge);\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // Submit the resource requirement\r
+ //\r
+ Status = PciResAlloc->SubmitResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ AcpiConfig\r
+ );\r
+ }\r
+ //\r
+ // Free acpi resource node\r
+ //\r
+ if (AcpiConfig) {\r
+ gBS->FreePool (AcpiConfig);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+ return Status;\r
+ }\r
+ }\r
+ //\r
+ // End while\r
+ //\r
+\r
+ //\r
+ // Notify pci bus driver starts to program the resource\r
+ //\r
+ Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Allocation failed, then return\r
+ //\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Raise the EFI_IOB_PCI_RES_ALLOC status code\r
+ //\r
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_PCI | EFI_IOB_PCI_PC_RES_ALLOC,\r
+ (VOID *) &ExtendedData,\r
+ sizeof (ExtendedData)\r
+ );\r
+\r
+ //\r
+ // Notify pci bus driver starts to program the resource\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources);\r
+\r
+ RootBridgeDev = NULL;\r
+\r
+ RootBridgeHandle = 0;\r
+\r
+ while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\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
+ // Get acpi resource node for all the resource types\r
+ //\r
+ AcpiConfig = NULL;\r
+ Status = PciResAlloc->GetProposedResources (\r
+ PciResAlloc,\r
+ RootBridgeDev->Handle,\r
+ &AcpiConfig\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the resource base by interpreting acpi resource node\r
+ //\r
+ //\r
+ GetResourceBase (\r
+ AcpiConfig,\r
+ &IoBase,\r
+ &Mem32Base,\r
+ &PMem32Base,\r
+ &Mem64Base,\r
+ &PMem64Base\r
+ );\r
+\r
+ //\r
+ // Process option rom for this root bridge\r
+ //\r
+ Status = ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize);\r
+\r
+ //\r
+ // Create the entire system resource map from the information collected by\r
+ // enumerator. Several resource tree was created\r
+ //\r
+ Status = GetResourceMap (\r
+ RootBridgeDev,\r
+ &IoBridge,\r
+ &Mem32Bridge,\r
+ &PMem32Bridge,\r
+ &Mem64Bridge,\r
+ &PMem64Bridge,\r
+ &IoPool,\r
+ &Mem32Pool,\r
+ &PMem32Pool,\r
+ &Mem64Pool,\r
+ &PMem64Pool\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
+ if (AcpiConfig != NULL) {\r
+ gBS->FreePool (AcpiConfig);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Destroy all the resource tree\r
+ //\r
+ DestroyResourceTree (&IoPool);\r
+ DestroyResourceTree (&Mem32Pool);\r
+ DestroyResourceTree (&PMem32Pool);\r
+ DestroyResourceTree (&Mem64Pool);\r
+ DestroyResourceTree (&PMem64Pool);\r
+\r
+ //\r
+ // Notify the resource allocation phase is to end\r
+ //\r
+ NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PciHostBridgeResourceAllocator_WithHotPlugDeviceSupport (\r
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc\r
+ )\r