2 Internal library implementation for PCI Bus module.
4 Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 GLOBAL_REMOVE_IF_UNREFERENCED
13 CHAR16
*mBarTypeStr
[] = {
28 Retrieve the max bus number that is assigned to the Root Bridge hierarchy.
29 It can support the case that there are multiple bus ranges.
31 @param Bridge Bridge device instance.
33 @retval The max bus number that is assigned to this Root Bridge hierarchy.
38 IN PCI_IO_DEVICE
*Bridge
41 PCI_IO_DEVICE
*RootBridge
;
42 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*BusNumberRanges
;
43 UINT64 MaxNumberInRange
;
46 // Get PCI Root Bridge device
49 while (RootBridge
->Parent
!= NULL
) {
50 RootBridge
= RootBridge
->Parent
;
54 // Iterate the bus number ranges to get max PCI bus number
56 BusNumberRanges
= RootBridge
->BusNumberRanges
;
57 while (BusNumberRanges
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
58 MaxNumberInRange
= BusNumberRanges
->AddrRangeMin
+ BusNumberRanges
->AddrLen
- 1;
61 return (UINT16
) MaxNumberInRange
;
65 Retrieve the PCI Card device BAR information via PciIo interface.
67 @param PciIoDevice PCI Card device instance.
72 IN PCI_IO_DEVICE
*PciIoDevice
77 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
82 // Read PciBar information from the bar register
84 if (!gFullEnumeration
) {
86 PciIoDevice
->PciIo
.Pci
.Read (
87 &(PciIoDevice
->PciIo
),
89 PCI_CARD_MEMORY_BASE_0
,
94 (PciIoDevice
->PciBar
)[P2C_MEM_1
].BaseAddress
= (UINT64
) (Address
);
95 (PciIoDevice
->PciBar
)[P2C_MEM_1
].Length
= 0x2000000;
96 (PciIoDevice
->PciBar
)[P2C_MEM_1
].BarType
= PciBarTypeMem32
;
99 PciIoDevice
->PciIo
.Pci
.Read (
100 &(PciIoDevice
->PciIo
),
102 PCI_CARD_MEMORY_BASE_1
,
106 (PciIoDevice
->PciBar
)[P2C_MEM_2
].BaseAddress
= (UINT64
) (Address
);
107 (PciIoDevice
->PciBar
)[P2C_MEM_2
].Length
= 0x2000000;
108 (PciIoDevice
->PciBar
)[P2C_MEM_2
].BarType
= PciBarTypePMem32
;
111 PciIoDevice
->PciIo
.Pci
.Read (
112 &(PciIoDevice
->PciIo
),
114 PCI_CARD_IO_BASE_0_LOWER
,
118 (PciIoDevice
->PciBar
)[P2C_IO_1
].BaseAddress
= (UINT64
) (Address
);
119 (PciIoDevice
->PciBar
)[P2C_IO_1
].Length
= 0x100;
120 (PciIoDevice
->PciBar
)[P2C_IO_1
].BarType
= PciBarTypeIo16
;
123 PciIoDevice
->PciIo
.Pci
.Read (
124 &(PciIoDevice
->PciIo
),
126 PCI_CARD_IO_BASE_1_LOWER
,
130 (PciIoDevice
->PciBar
)[P2C_IO_2
].BaseAddress
= (UINT64
) (Address
);
131 (PciIoDevice
->PciBar
)[P2C_IO_2
].Length
= 0x100;
132 (PciIoDevice
->PciBar
)[P2C_IO_2
].BarType
= PciBarTypeIo16
;
136 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
137 GetResourcePaddingForHpb (PciIoDevice
);
142 Remove rejected pci device from specific root bridge
145 @param RootBridgeHandle Specific parent root bridge handle.
146 @param Bridge Bridge device instance.
150 RemoveRejectedPciDevices (
151 IN EFI_HANDLE RootBridgeHandle
,
152 IN PCI_IO_DEVICE
*Bridge
156 LIST_ENTRY
*CurrentLink
;
157 LIST_ENTRY
*LastLink
;
159 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
163 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
165 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
167 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
169 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
171 // Remove rejected devices recusively
173 RemoveRejectedPciDevices (RootBridgeHandle
, Temp
);
176 // Skip rejection for all PPBs, while detect rejection for others
178 if (IsPciDeviceRejected (Temp
)) {
181 // For P2C, remove all devices on it
183 if (!IsListEmpty (&Temp
->ChildList
)) {
184 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
188 // Finally remove itself
190 LastLink
= CurrentLink
->BackLink
;
191 RemoveEntryList (CurrentLink
);
192 FreePciDevice (Temp
);
194 CurrentLink
= LastLink
;
198 CurrentLink
= CurrentLink
->ForwardLink
;
203 Dump the resourc map of the bridge device.
205 @param[in] BridgeResource Resource descriptor of the bridge device.
209 IN PCI_RESOURCE_NODE
*BridgeResource
213 PCI_RESOURCE_NODE
*Resource
;
216 if ((BridgeResource
!= NULL
) && (BridgeResource
->Length
!= 0)) {
218 EFI_D_INFO
, "Type = %s; Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 0x%lx\n",
219 mBarTypeStr
[MIN (BridgeResource
->ResType
, PciBarTypeMaxType
)],
220 BridgeResource
->PciDev
->PciBar
[BridgeResource
->Bar
].BaseAddress
,
221 BridgeResource
->Length
, BridgeResource
->Alignment
223 for ( Link
= GetFirstNode (&BridgeResource
->ChildList
)
224 ; !IsNull (&BridgeResource
->ChildList
, Link
)
225 ; Link
= GetNextNode (&BridgeResource
->ChildList
, Link
)
227 Resource
= RESOURCE_NODE_FROM_LINK (Link
);
228 if (Resource
->ResourceUsage
== PciResUsageTypical
) {
229 Bar
= Resource
->Virtual
? Resource
->PciDev
->VfPciBar
: Resource
->PciDev
->PciBar
;
231 EFI_D_INFO
, " Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 0x%lx;\tOwner = %s [%02x|%02x|%02x:",
232 Bar
[Resource
->Bar
].BaseAddress
, Resource
->Length
, Resource
->Alignment
,
233 IS_PCI_BRIDGE (&Resource
->PciDev
->Pci
) ? L
"PPB" :
234 IS_CARDBUS_BRIDGE (&Resource
->PciDev
->Pci
) ? L
"P2C" :
236 Resource
->PciDev
->BusNumber
, Resource
->PciDev
->DeviceNumber
,
237 Resource
->PciDev
->FunctionNumber
240 if ((!IS_PCI_BRIDGE (&Resource
->PciDev
->Pci
) && !IS_CARDBUS_BRIDGE (&Resource
->PciDev
->Pci
)) ||
241 (IS_PCI_BRIDGE (&Resource
->PciDev
->Pci
) && (Resource
->Bar
< PPB_IO_RANGE
)) ||
242 (IS_CARDBUS_BRIDGE (&Resource
->PciDev
->Pci
) && (Resource
->Bar
< P2C_MEM_1
))
245 // The resource requirement comes from the device itself.
247 DEBUG ((EFI_D_INFO
, "%02x]", Bar
[Resource
->Bar
].Offset
));
250 // The resource requirement comes from the subordinate devices.
252 DEBUG ((EFI_D_INFO
, "**]"));
255 DEBUG ((EFI_D_INFO
, " Base = Padding;\tLength = 0x%lx;\tAlignment = 0x%lx", Resource
->Length
, Resource
->Alignment
));
257 if (BridgeResource
->ResType
!= Resource
->ResType
) {
258 DEBUG ((EFI_D_INFO
, "; Type = %s", mBarTypeStr
[MIN (Resource
->ResType
, PciBarTypeMaxType
)]));
260 DEBUG ((EFI_D_INFO
, "\n"));
266 Find the corresponding resource node for the Device in child list of BridgeResource.
268 @param[in] Device Pointer to PCI_IO_DEVICE.
269 @param[in] BridgeResource Pointer to PCI_RESOURCE_NODE.
270 @param[out] DeviceResources Pointer to a buffer to receive resources for the Device.
272 @return Count of the resource descriptors returned.
276 IN PCI_IO_DEVICE
*Device
,
277 IN PCI_RESOURCE_NODE
*BridgeResource
,
278 OUT PCI_RESOURCE_NODE
**DeviceResources OPTIONAL
282 PCI_RESOURCE_NODE
*Resource
;
286 for ( Link
= BridgeResource
->ChildList
.ForwardLink
287 ; Link
!= &BridgeResource
->ChildList
288 ; Link
= Link
->ForwardLink
290 Resource
= RESOURCE_NODE_FROM_LINK (Link
);
291 if (Resource
->PciDev
== Device
) {
292 if (DeviceResources
!= NULL
) {
293 DeviceResources
[Count
] = Resource
;
303 Dump the resource map of all the devices under Bridge.
305 @param[in] Bridge Bridge device instance.
306 @param[in] Resources Resource descriptors for the bridge device.
307 @param[in] ResourceCount Count of resource descriptors.
311 IN PCI_IO_DEVICE
*Bridge
,
312 IN PCI_RESOURCE_NODE
**Resources
,
313 IN UINTN ResourceCount
318 PCI_IO_DEVICE
*Device
;
321 PCI_RESOURCE_NODE
**ChildResources
;
322 UINTN ChildResourceCount
;
324 DEBUG ((EFI_D_INFO
, "PciBus: Resource Map for "));
326 Status
= gBS
->OpenProtocol (
328 &gEfiPciRootBridgeIoProtocolGuid
,
332 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
334 if (EFI_ERROR (Status
)) {
336 EFI_D_INFO
, "Bridge [%02x|%02x|%02x]\n",
337 Bridge
->BusNumber
, Bridge
->DeviceNumber
, Bridge
->FunctionNumber
340 Str
= ConvertDevicePathToText (
341 DevicePathFromHandle (Bridge
->Handle
),
345 DEBUG ((EFI_D_INFO
, "Root Bridge %s\n", Str
!= NULL
? Str
: L
""));
351 for (Index
= 0; Index
< ResourceCount
; Index
++) {
352 DumpBridgeResource (Resources
[Index
]);
354 DEBUG ((EFI_D_INFO
, "\n"));
356 for ( Link
= Bridge
->ChildList
.ForwardLink
357 ; Link
!= &Bridge
->ChildList
358 ; Link
= Link
->ForwardLink
360 Device
= PCI_IO_DEVICE_FROM_LINK (Link
);
361 if (IS_PCI_BRIDGE (&Device
->Pci
)) {
363 ChildResourceCount
= 0;
364 for (Index
= 0; Index
< ResourceCount
; Index
++) {
365 ChildResourceCount
+= FindResourceNode (Device
, Resources
[Index
], NULL
);
367 ChildResources
= AllocatePool (sizeof (PCI_RESOURCE_NODE
*) * ChildResourceCount
);
368 ASSERT (ChildResources
!= NULL
);
369 ChildResourceCount
= 0;
370 for (Index
= 0; Index
< ResourceCount
; Index
++) {
371 ChildResourceCount
+= FindResourceNode (Device
, Resources
[Index
], &ChildResources
[ChildResourceCount
]);
374 DumpResourceMap (Device
, ChildResources
, ChildResourceCount
);
375 FreePool (ChildResources
);
381 Adjust the Devices' BAR size to minimum value if it support Resizeable BAR capability.
383 @param RootBridgeDev Pointer to instance of PCI_IO_DEVICE..
385 @return TRUE if BAR size is adjusted.
389 AdjustPciDeviceBarSize (
390 IN PCI_IO_DEVICE
*RootBridgeDev
393 PCI_IO_DEVICE
*PciIoDevice
;
394 LIST_ENTRY
*CurrentLink
;
400 CurrentLink
= RootBridgeDev
->ChildList
.ForwardLink
;
402 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridgeDev
->ChildList
) {
403 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
405 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
406 if (AdjustPciDeviceBarSize (PciIoDevice
)) {
410 if (PciIoDevice
->ResizableBarOffset
!= 0) {
413 "PciBus: [%02x|%02x|%02x] Adjust Pci Device Bar Size\n",
414 PciIoDevice
->BusNumber
, PciIoDevice
->DeviceNumber
, PciIoDevice
->FunctionNumber
416 PciProgramResizableBar (PciIoDevice
, PciResizableBarMin
);
418 // Start to parse the bars
420 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24 && BarIndex
< PCI_MAX_BAR
; BarIndex
++) {
421 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
424 DEBUG_CODE (DumpPciBars (PciIoDevice
););
428 CurrentLink
= CurrentLink
->ForwardLink
;
435 Submits the I/O and memory resource requirements for the specified PCI Host Bridge.
437 @param PciResAlloc Point to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.
439 @retval EFI_SUCCESS Successfully finished resource allocation.
440 @retval EFI_NOT_FOUND Cannot get root bridge instance.
441 @retval EFI_OUT_OF_RESOURCES Platform failed to program the resources if no hot plug supported.
442 @retval other Some error occurred when allocating resources for the PCI Host Bridge.
444 @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug.
448 PciHostBridgeResourceAllocator (
449 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
452 PCI_IO_DEVICE
*RootBridgeDev
;
453 EFI_HANDLE RootBridgeHandle
;
462 UINT64 Mem32ResStatus
;
463 UINT64 PMem32ResStatus
;
464 UINT64 Mem64ResStatus
;
465 UINT64 PMem64ResStatus
;
466 UINT32 MaxOptionRomSize
;
467 PCI_RESOURCE_NODE
*IoBridge
;
468 PCI_RESOURCE_NODE
*Mem32Bridge
;
469 PCI_RESOURCE_NODE
*PMem32Bridge
;
470 PCI_RESOURCE_NODE
*Mem64Bridge
;
471 PCI_RESOURCE_NODE
*PMem64Bridge
;
472 PCI_RESOURCE_NODE IoPool
;
473 PCI_RESOURCE_NODE Mem32Pool
;
474 PCI_RESOURCE_NODE PMem32Pool
;
475 PCI_RESOURCE_NODE Mem64Pool
;
476 PCI_RESOURCE_NODE PMem64Pool
;
477 EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData
;
478 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData
;
479 BOOLEAN ResizableBarNeedAdjust
;
480 BOOLEAN ResizableBarAdjusted
;
482 ResizableBarNeedAdjust
= PcdGetBool (PcdPcieResizableBarSupport
);
485 // It may try several times if the resource allocation fails
489 // Initialize resource pool
491 InitializeResourcePool (&IoPool
, PciBarTypeIo16
);
492 InitializeResourcePool (&Mem32Pool
, PciBarTypeMem32
);
493 InitializeResourcePool (&PMem32Pool
, PciBarTypePMem32
);
494 InitializeResourcePool (&Mem64Pool
, PciBarTypeMem64
);
495 InitializeResourcePool (&PMem64Pool
, PciBarTypePMem64
);
497 RootBridgeDev
= NULL
;
498 RootBridgeHandle
= 0;
500 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
502 // Get Root Bridge Device by handle
504 RootBridgeDev
= GetRootBridgeByHandle (RootBridgeHandle
);
506 if (RootBridgeDev
== NULL
) {
507 return EFI_NOT_FOUND
;
511 // Create the entire system resource map from the information collected by
512 // enumerator. Several resource tree was created
516 // If non-standard PCI Bridge I/O window alignment is supported,
517 // set I/O aligment to minimum possible alignment for root bridge.
519 IoBridge
= CreateResourceNode (
522 FeaturePcdGet (PcdPciBridgeIoAlignmentProbe
) ? 0x1FF: 0xFFF,
528 Mem32Bridge
= CreateResourceNode (
537 PMem32Bridge
= CreateResourceNode (
546 Mem64Bridge
= CreateResourceNode (
555 PMem64Bridge
= CreateResourceNode (
565 // Get the max ROM size that the root bridge can process
566 // Insert to resource map so that there will be dedicate MEM32 resource range for Option ROM.
567 // All devices' Option ROM share the same MEM32 resource.
569 MaxOptionRomSize
= GetMaxOptionRomSize (RootBridgeDev
);
570 if (MaxOptionRomSize
!= 0) {
571 RootBridgeDev
->PciBar
[0].BarType
= PciBarTypeOpRom
;
572 RootBridgeDev
->PciBar
[0].Length
= MaxOptionRomSize
;
573 RootBridgeDev
->PciBar
[0].Alignment
= MaxOptionRomSize
- 1;
574 GetResourceFromDevice (RootBridgeDev
, IoBridge
, Mem32Bridge
, PMem32Bridge
, Mem64Bridge
, PMem64Bridge
);
578 // Create resourcemap by going through all the devices subject to this root bridge
590 // Based on the all the resource tree, construct ACPI resource node to
591 // submit the resource aperture to pci host bridge protocol
593 Status
= ConstructAcpiResourceRequestor (
604 // Insert these resource nodes into the database
606 InsertResourceNode (&IoPool
, IoBridge
);
607 InsertResourceNode (&Mem32Pool
, Mem32Bridge
);
608 InsertResourceNode (&PMem32Pool
, PMem32Bridge
);
609 InsertResourceNode (&Mem64Pool
, Mem64Bridge
);
610 InsertResourceNode (&PMem64Pool
, PMem64Bridge
);
612 if (Status
== EFI_SUCCESS
) {
614 // Submit the resource requirement
616 Status
= PciResAlloc
->SubmitResources (
618 RootBridgeDev
->Handle
,
622 // If SubmitResources returns error, PciBus isn't able to start.
623 // It's a fatal error so assertion is added.
625 DEBUG ((EFI_D_INFO
, "PciBus: HostBridge->SubmitResources() - %r\n", Status
));
626 ASSERT_EFI_ERROR (Status
);
630 // Free acpi resource node
632 if (AcpiConfig
!= NULL
) {
633 FreePool (AcpiConfig
);
636 if (EFI_ERROR (Status
)) {
638 // Destroy all the resource tree
640 DestroyResourceTree (&IoPool
);
641 DestroyResourceTree (&Mem32Pool
);
642 DestroyResourceTree (&PMem32Pool
);
643 DestroyResourceTree (&Mem64Pool
);
644 DestroyResourceTree (&PMem64Pool
);
649 // End while, at least one Root Bridge should be found.
651 ASSERT (RootBridgeDev
!= NULL
);
654 // Notify platform to start to program the resource
656 Status
= NotifyPhase (PciResAlloc
, EfiPciHostBridgeAllocateResources
);
657 DEBUG ((EFI_D_INFO
, "PciBus: HostBridge->NotifyPhase(AllocateResources) - %r\n", Status
));
658 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
660 // If Hot Plug is not supported
662 if (EFI_ERROR (Status
)) {
664 // Allocation failed, then return
666 return EFI_OUT_OF_RESOURCES
;
669 // Allocation succeed.
670 // Get host bridge handle for status report, and then skip the main while
672 HandleExtendedData
.Handle
= RootBridgeDev
->PciRootBridgeIo
->ParentHandle
;
678 // If Hot Plug is supported
680 if (!EFI_ERROR (Status
)) {
682 // Allocation succeed, then continue the following
688 // If the resource allocation is unsuccessful, free resources on bridge
691 RootBridgeDev
= NULL
;
692 RootBridgeHandle
= 0;
694 IoResStatus
= EFI_RESOURCE_SATISFIED
;
695 Mem32ResStatus
= EFI_RESOURCE_SATISFIED
;
696 PMem32ResStatus
= EFI_RESOURCE_SATISFIED
;
697 Mem64ResStatus
= EFI_RESOURCE_SATISFIED
;
698 PMem64ResStatus
= EFI_RESOURCE_SATISFIED
;
700 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
702 // Get RootBridg Device by handle
704 RootBridgeDev
= GetRootBridgeByHandle (RootBridgeHandle
);
705 if (RootBridgeDev
== NULL
) {
706 return EFI_NOT_FOUND
;
710 // Get host bridge handle for status report
712 HandleExtendedData
.Handle
= RootBridgeDev
->PciRootBridgeIo
->ParentHandle
;
715 // Get acpi resource node for all the resource types
719 Status
= PciResAlloc
->GetProposedResources (
721 RootBridgeDev
->Handle
,
725 if (EFI_ERROR (Status
)) {
729 if (AcpiConfig
!= NULL
) {
731 // Adjust resource allocation policy for each RB
733 GetResourceAllocationStatus (
741 FreePool (AcpiConfig
);
749 // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code
752 // It is very difficult to follow the spec here
753 // Device path , Bar index can not be get here
755 ZeroMem (&AllocFailExtendedData
, sizeof (AllocFailExtendedData
));
757 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
759 EFI_IO_BUS_PCI
| EFI_IOB_EC_RESOURCE_CONFLICT
,
760 (VOID
*) &AllocFailExtendedData
,
761 sizeof (AllocFailExtendedData
)
765 // When resource conflict happens, adjust the BAR size first.
766 // Only when adjusting BAR size doesn't help or BAR size cannot be adjusted,
767 // reject the device who requests largest resource that causes conflict.
769 ResizableBarAdjusted
= FALSE
;
770 if (ResizableBarNeedAdjust
) {
771 ResizableBarAdjusted
= AdjustPciDeviceBarSize (RootBridgeDev
);
772 ResizableBarNeedAdjust
= FALSE
;
774 if (!ResizableBarAdjusted
) {
775 Status
= PciHostBridgeAdjustAllocation (
789 // Destroy all the resource tree
791 DestroyResourceTree (&IoPool
);
792 DestroyResourceTree (&Mem32Pool
);
793 DestroyResourceTree (&PMem32Pool
);
794 DestroyResourceTree (&Mem64Pool
);
795 DestroyResourceTree (&PMem64Pool
);
797 NotifyPhase (PciResAlloc
, EfiPciHostBridgeFreeResources
);
799 if (EFI_ERROR (Status
)) {
809 // Raise the EFI_IOB_PCI_RES_ALLOC status code
811 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
813 EFI_IO_BUS_PCI
| EFI_IOB_PCI_RES_ALLOC
,
814 (VOID
*) &HandleExtendedData
,
815 sizeof (HandleExtendedData
)
819 // Notify pci bus driver starts to program the resource
821 Status
= NotifyPhase (PciResAlloc
, EfiPciHostBridgeSetResources
);
823 if (EFI_ERROR (Status
)) {
827 RootBridgeDev
= NULL
;
829 RootBridgeHandle
= 0;
831 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
833 // Get RootBridg Device by handle
835 RootBridgeDev
= GetRootBridgeByHandle (RootBridgeHandle
);
837 if (RootBridgeDev
== NULL
) {
838 return EFI_NOT_FOUND
;
842 // Get acpi resource node for all the resource types
845 Status
= PciResAlloc
->GetProposedResources (
847 RootBridgeDev
->Handle
,
851 if (EFI_ERROR (Status
)) {
856 // Get the resource base by interpreting acpi resource node
869 // Create the entire system resource map from the information collected by
870 // enumerator. Several resource tree was created
872 FindResourceNode (RootBridgeDev
, &IoPool
, &IoBridge
);
873 FindResourceNode (RootBridgeDev
, &Mem32Pool
, &Mem32Bridge
);
874 FindResourceNode (RootBridgeDev
, &PMem32Pool
, &PMem32Bridge
);
875 FindResourceNode (RootBridgeDev
, &Mem64Pool
, &Mem64Bridge
);
876 FindResourceNode (RootBridgeDev
, &PMem64Pool
, &PMem64Bridge
);
878 ASSERT (IoBridge
!= NULL
);
879 ASSERT (Mem32Bridge
!= NULL
);
880 ASSERT (PMem32Bridge
!= NULL
);
881 ASSERT (Mem64Bridge
!= NULL
);
882 ASSERT (PMem64Bridge
!= NULL
);
885 // Program IO resources
893 // Program Mem32 resources
901 // Program PMem32 resources
909 // Program Mem64 resources
917 // Program PMem64 resources
925 // Process Option ROM for this root bridge after all BARs are programmed.
926 // The PPB's MEM32 RANGE BAR is re-programmed to the Option ROM BAR Base in order to
927 // shadow the Option ROM of the devices under the PPB.
928 // After the shadow, Option ROM BAR decoding is turned off and the PPB's MEM32 RANGE
929 // BAR is restored back to the original value.
930 // The original value is programmed by ProgramResource() above.
933 DEBUG_INFO
, "Process Option ROM: BAR Base/Length = %lx/%lx\n",
934 RootBridgeDev
->PciBar
[0].BaseAddress
, RootBridgeDev
->PciBar
[0].Length
936 ProcessOptionRom (RootBridgeDev
, RootBridgeDev
->PciBar
[0].BaseAddress
, RootBridgeDev
->PciBar
[0].Length
);
938 IoBridge
->PciDev
->PciBar
[IoBridge
->Bar
].BaseAddress
= IoBase
;
939 Mem32Bridge
->PciDev
->PciBar
[Mem32Bridge
->Bar
].BaseAddress
= Mem32Base
;
940 PMem32Bridge
->PciDev
->PciBar
[PMem32Bridge
->Bar
].BaseAddress
= PMem32Base
;
941 Mem64Bridge
->PciDev
->PciBar
[Mem64Bridge
->Bar
].BaseAddress
= Mem64Base
;
942 PMem64Bridge
->PciDev
->PciBar
[PMem64Bridge
->Bar
].BaseAddress
= PMem64Base
;
945 // Dump the resource map for current root bridge
948 PCI_RESOURCE_NODE
*Resources
[5];
949 Resources
[0] = IoBridge
;
950 Resources
[1] = Mem32Bridge
;
951 Resources
[2] = PMem32Bridge
;
952 Resources
[3] = Mem64Bridge
;
953 Resources
[4] = PMem64Bridge
;
954 DumpResourceMap (RootBridgeDev
, Resources
, ARRAY_SIZE (Resources
));
957 FreePool (AcpiConfig
);
961 // Destroy all the resource tree
963 DestroyResourceTree (&IoPool
);
964 DestroyResourceTree (&Mem32Pool
);
965 DestroyResourceTree (&PMem32Pool
);
966 DestroyResourceTree (&Mem64Pool
);
967 DestroyResourceTree (&PMem64Pool
);
970 // Notify the resource allocation phase is to end
972 Status
= NotifyPhase (PciResAlloc
, EfiPciHostBridgeEndResourceAllocation
);
978 Allocate NumberOfBuses buses and return the next available PCI bus number.
980 @param Bridge Bridge device instance.
981 @param StartBusNumber Current available PCI bus number.
982 @param NumberOfBuses Number of buses enumerated below the StartBusNumber.
983 @param NextBusNumber Next available PCI bus number.
985 @retval EFI_SUCCESS Available bus number resource is enough. Next available PCI bus number
986 is returned in NextBusNumber.
987 @retval EFI_OUT_OF_RESOURCES Available bus number resource is not enough for allocation.
991 PciAllocateBusNumber (
992 IN PCI_IO_DEVICE
*Bridge
,
993 IN UINT8 StartBusNumber
,
994 IN UINT8 NumberOfBuses
,
995 OUT UINT8
*NextBusNumber
998 PCI_IO_DEVICE
*RootBridge
;
999 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*BusNumberRanges
;
1001 UINT64 MaxNumberInRange
;
1004 // Get PCI Root Bridge device
1006 RootBridge
= Bridge
;
1007 while (RootBridge
->Parent
!= NULL
) {
1008 RootBridge
= RootBridge
->Parent
;
1012 // Get next available PCI bus number
1014 BusNumberRanges
= RootBridge
->BusNumberRanges
;
1015 while (BusNumberRanges
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1016 MaxNumberInRange
= BusNumberRanges
->AddrRangeMin
+ BusNumberRanges
->AddrLen
- 1;
1017 if (StartBusNumber
>= BusNumberRanges
->AddrRangeMin
&& StartBusNumber
<= MaxNumberInRange
) {
1018 NextNumber
= (UINT8
)(StartBusNumber
+ NumberOfBuses
);
1019 while (NextNumber
> MaxNumberInRange
) {
1021 if (BusNumberRanges
->Desc
== ACPI_END_TAG_DESCRIPTOR
) {
1022 return EFI_OUT_OF_RESOURCES
;
1024 NextNumber
= (UINT8
)(NextNumber
+ (BusNumberRanges
->AddrRangeMin
- (MaxNumberInRange
+ 1)));
1025 MaxNumberInRange
= BusNumberRanges
->AddrRangeMin
+ BusNumberRanges
->AddrLen
- 1;
1027 *NextBusNumber
= NextNumber
;
1032 return EFI_OUT_OF_RESOURCES
;
1036 Scan pci bus and assign bus number to the given PCI bus system.
1038 @param Bridge Bridge device instance.
1039 @param StartBusNumber start point.
1040 @param SubBusNumber Point to sub bus number.
1041 @param PaddedBusRange Customized bus number.
1043 @retval EFI_SUCCESS Successfully scanned and assigned bus number.
1044 @retval other Some error occurred when scanning pci bus.
1046 @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug.
1051 IN PCI_IO_DEVICE
*Bridge
,
1052 IN UINT8 StartBusNumber
,
1053 OUT UINT8
*SubBusNumber
,
1054 OUT UINT8
*PaddedBusRange
1066 PCI_IO_DEVICE
*PciDevice
;
1068 EFI_HPC_STATE State
;
1070 EFI_HPC_PADDING_ATTRIBUTES Attributes
;
1071 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1072 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*NextDescriptors
;
1074 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1076 UINT32 TempReservedBusNum
;
1078 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
1082 Attributes
= (EFI_HPC_PADDING_ATTRIBUTES
) 0;
1088 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
1089 TempReservedBusNum
= 0;
1090 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
1093 // Check to see whether a pci device is present
1095 Status
= PciDevicePresent (
1103 if (EFI_ERROR (Status
) && Func
== 0) {
1105 // go to next device if there is no Function 0
1110 if (EFI_ERROR (Status
)) {
1115 // Get the PCI device information
1117 Status
= PciSearchDevice (
1126 if (EFI_ERROR (Status
)) {
1130 PciAddress
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, 0);
1132 if (!IS_PCI_BRIDGE (&Pci
)) {
1134 // PCI bridges will be called later
1135 // Here just need for PCI device or PCI to cardbus controller
1136 // EfiPciBeforeChildBusEnumeration for PCI Device Node
1138 PreprocessController (
1140 PciDevice
->BusNumber
,
1141 PciDevice
->DeviceNumber
,
1142 PciDevice
->FunctionNumber
,
1143 EfiPciBeforeChildBusEnumeration
1147 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1149 // For Pci Hotplug controller devcie only
1151 if (gPciHotPlugInit
!= NULL
) {
1153 // Check if it is a Hotplug PCI controller
1155 if (IsRootPciHotPlugController (PciDevice
->DevicePath
, &HpIndex
)) {
1156 gPciRootHpcData
[HpIndex
].Found
= TRUE
;
1158 if (!gPciRootHpcData
[HpIndex
].Initialized
) {
1160 Status
= CreateEventForHpc (HpIndex
, &Event
);
1162 ASSERT (!EFI_ERROR (Status
));
1164 Status
= gPciHotPlugInit
->InitializeRootHpc (
1166 gPciRootHpcPool
[HpIndex
].HpcDevicePath
,
1172 PreprocessController (
1174 PciDevice
->BusNumber
,
1175 PciDevice
->DeviceNumber
,
1176 PciDevice
->FunctionNumber
,
1177 EfiPciBeforeChildBusEnumeration
1184 if (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
)) {
1188 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1190 // If Hot Plug is supported,
1191 // Get the bridge information
1194 if (gPciHotPlugInit
!= NULL
) {
1196 if (IsPciHotPlugBus (PciDevice
)) {
1199 // If it is initialized, get the padded bus range
1201 Status
= gPciHotPlugInit
->GetResourcePadding (
1203 PciDevice
->DevicePath
,
1206 (VOID
**) &Descriptors
,
1210 if (EFI_ERROR (Status
)) {
1215 NextDescriptors
= Descriptors
;
1216 Status
= PciGetBusRange (
1223 FreePool (Descriptors
);
1225 if (!EFI_ERROR (Status
)) {
1227 } else if (Status
!= EFI_NOT_FOUND
) {
1229 // EFI_NOT_FOUND is not a real error. It indicates no bus number padding requested.
1237 Status
= PciAllocateBusNumber (Bridge
, *SubBusNumber
, 1, SubBusNumber
);
1238 if (EFI_ERROR (Status
)) {
1241 SecondBus
= *SubBusNumber
;
1243 Register
= (UINT16
) ((SecondBus
<< 8) | (UINT16
) StartBusNumber
);
1244 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET
);
1246 Status
= PciRootBridgeIo
->Pci
.Write (
1256 // If it is PPB, resursively search down this bridge
1258 if (IS_PCI_BRIDGE (&Pci
)) {
1261 // Temporarily initialize SubBusNumber to maximum bus number to ensure the
1262 // PCI configuration transaction to go through any PPB
1264 Register
= PciGetMaxBusNumber (Bridge
);
1265 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET
);
1266 Status
= PciRootBridgeIo
->Pci
.Write (
1275 // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige
1277 PreprocessController (
1279 PciDevice
->BusNumber
,
1280 PciDevice
->DeviceNumber
,
1281 PciDevice
->FunctionNumber
,
1282 EfiPciBeforeChildBusEnumeration
1285 Status
= PciScanBus (
1291 if (EFI_ERROR (Status
)) {
1296 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport
) && BusPadding
) {
1298 // Ensure the device is enabled and initialized
1300 if ((Attributes
== EfiPaddingPciRootBridge
) &&
1301 (State
& EFI_HPC_STATE_ENABLED
) != 0 &&
1302 (State
& EFI_HPC_STATE_INITIALIZED
) != 0) {
1303 *PaddedBusRange
= (UINT8
) ((UINT8
) (BusRange
) + *PaddedBusRange
);
1306 // Reserve the larger one between the actual occupied bus number and padded bus number
1308 Status
= PciAllocateBusNumber (PciDevice
, SecondBus
, (UINT8
) (BusRange
), &PaddedSubBus
);
1309 if (EFI_ERROR (Status
)) {
1312 *SubBusNumber
= MAX (PaddedSubBus
, *SubBusNumber
);
1317 // Set the current maximum bus number under the PPB
1319 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET
);
1321 Status
= PciRootBridgeIo
->Pci
.Write (
1330 // It is device. Check PCI IOV for Bus reservation
1331 // Go through each function, just reserve the MAX ReservedBusNum for one device
1333 if (PcdGetBool (PcdSrIovSupport
) && PciDevice
->SrIovCapabilityOffset
!= 0) {
1334 if (TempReservedBusNum
< PciDevice
->ReservedBusNum
) {
1336 Status
= PciAllocateBusNumber (PciDevice
, *SubBusNumber
, (UINT8
) (PciDevice
->ReservedBusNum
- TempReservedBusNum
), SubBusNumber
);
1337 if (EFI_ERROR (Status
)) {
1340 TempReservedBusNum
= PciDevice
->ReservedBusNum
;
1343 DEBUG ((EFI_D_INFO
, "PCI-IOV ScanBus - SubBusNumber - 0x%x\n", *SubBusNumber
));
1345 DEBUG ((EFI_D_INFO
, "PCI-IOV ScanBus - SubBusNumber - 0x%x (Update)\n", *SubBusNumber
));
1351 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
1354 // Skip sub functions, this is not a multi function device
1357 Func
= PCI_MAX_FUNC
;
1366 Process Option Rom on the specified root bridge.
1368 @param Bridge Pci root bridge device instance.
1370 @retval EFI_SUCCESS Success process.
1371 @retval other Some error occurred when processing Option Rom on the root bridge.
1375 PciRootBridgeP2CProcess (
1376 IN PCI_IO_DEVICE
*Bridge
1379 LIST_ENTRY
*CurrentLink
;
1380 PCI_IO_DEVICE
*Temp
;
1381 EFI_HPC_STATE State
;
1385 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1387 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
1389 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1391 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
1393 if (gPciHotPlugInit
!= NULL
&& Temp
->Allocated
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1396 // Raise the EFI_IOB_PCI_HPC_INIT status code
1398 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1400 EFI_IO_BUS_PCI
| EFI_IOB_PCI_HPC_INIT
,
1404 PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);
1405 Status
= gPciHotPlugInit
->InitializeRootHpc (
1413 if (!EFI_ERROR (Status
)) {
1414 Status
= PciBridgeEnumerator (Temp
);
1416 if (EFI_ERROR (Status
)) {
1421 CurrentLink
= CurrentLink
->ForwardLink
;
1427 if (!IsListEmpty (&Temp
->ChildList
)) {
1428 Status
= PciRootBridgeP2CProcess (Temp
);
1431 CurrentLink
= CurrentLink
->ForwardLink
;
1438 Process Option Rom on the specified host bridge.
1440 @param PciResAlloc Pointer to instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL.
1442 @retval EFI_SUCCESS Success process.
1443 @retval EFI_NOT_FOUND Can not find the root bridge instance.
1444 @retval other Some error occurred when processing Option Rom on the host bridge.
1448 PciHostBridgeP2CProcess (
1449 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
1452 EFI_HANDLE RootBridgeHandle
;
1453 PCI_IO_DEVICE
*RootBridgeDev
;
1456 if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1460 RootBridgeHandle
= NULL
;
1462 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
1465 // Get RootBridg Device by handle
1467 RootBridgeDev
= GetRootBridgeByHandle (RootBridgeHandle
);
1469 if (RootBridgeDev
== NULL
) {
1470 return EFI_NOT_FOUND
;
1473 Status
= PciRootBridgeP2CProcess (RootBridgeDev
);
1474 if (EFI_ERROR (Status
)) {
1484 This function is used to enumerate the entire host bridge
1485 in a given platform.
1487 @param PciResAlloc A pointer to the PCI Host Resource Allocation protocol.
1489 @retval EFI_SUCCESS Successfully enumerated the host bridge.
1490 @retval EFI_OUT_OF_RESOURCES No enough memory available.
1491 @retval other Some error occurred when enumerating the host bridge.
1495 PciHostBridgeEnumerator (
1496 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
1499 EFI_HANDLE RootBridgeHandle
;
1500 PCI_IO_DEVICE
*RootBridgeDev
;
1502 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1504 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1505 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Configuration
;
1506 UINT8 StartBusNumber
;
1507 LIST_ENTRY RootBridgeList
;
1510 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1511 InitializeHotPlugSupport ();
1514 InitializeListHead (&RootBridgeList
);
1517 // Notify the bus allocation phase is about to start
1519 Status
= NotifyPhase (PciResAlloc
, EfiPciHostBridgeBeginBusAllocation
);
1521 if (EFI_ERROR (Status
)) {
1525 DEBUG((EFI_D_INFO
, "PCI Bus First Scanning\n"));
1526 RootBridgeHandle
= NULL
;
1527 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
1530 // if a root bridge instance is found, create root bridge device for it
1533 RootBridgeDev
= CreateRootBridge (RootBridgeHandle
);
1535 if (RootBridgeDev
== NULL
) {
1536 return EFI_OUT_OF_RESOURCES
;
1540 // Enumerate all the buses under this root bridge
1542 Status
= PciRootBridgeEnumerator (
1547 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1548 InsertTailList (&RootBridgeList
, &(RootBridgeDev
->Link
));
1550 DestroyRootBridge (RootBridgeDev
);
1552 if (EFI_ERROR (Status
)) {
1558 // Notify the bus allocation phase is finished for the first time
1560 NotifyPhase (PciResAlloc
, EfiPciHostBridgeEndBusAllocation
);
1562 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
1564 // Reset all assigned PCI bus number in all PPB
1566 RootBridgeHandle
= NULL
;
1567 Link
= GetFirstNode (&RootBridgeList
);
1568 while ((PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) &&
1569 (!IsNull (&RootBridgeList
, Link
))) {
1570 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (Link
);
1572 // Get the Bus information
1574 Status
= PciResAlloc
->StartBusEnumeration (
1577 (VOID
**) &Configuration
1579 if (EFI_ERROR (Status
)) {
1584 // Get the bus number to start with
1586 StartBusNumber
= (UINT8
) (Configuration
->AddrRangeMin
);
1588 ResetAllPpbBusNumber (
1593 FreePool (Configuration
);
1594 Link
= RemoveEntryList (Link
);
1595 DestroyRootBridge (RootBridgeDev
);
1599 // Wait for all HPC initialized
1601 Status
= AllRootHPCInitialized (STALL_1_SECOND
* 15);
1603 if (EFI_ERROR (Status
)) {
1604 DEBUG ((EFI_D_ERROR
, "Some root HPC failed to initialize\n"));
1609 // Notify the bus allocation phase is about to start for the 2nd time
1611 Status
= NotifyPhase (PciResAlloc
, EfiPciHostBridgeBeginBusAllocation
);
1613 if (EFI_ERROR (Status
)) {
1617 DEBUG((EFI_D_INFO
, "PCI Bus Second Scanning\n"));
1618 RootBridgeHandle
= NULL
;
1619 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
1622 // if a root bridge instance is found, create root bridge device for it
1624 RootBridgeDev
= CreateRootBridge (RootBridgeHandle
);
1626 if (RootBridgeDev
== NULL
) {
1627 return EFI_OUT_OF_RESOURCES
;
1631 // Enumerate all the buses under this root bridge
1633 Status
= PciRootBridgeEnumerator (
1638 DestroyRootBridge (RootBridgeDev
);
1639 if (EFI_ERROR (Status
)) {
1645 // Notify the bus allocation phase is to end for the 2nd time
1647 NotifyPhase (PciResAlloc
, EfiPciHostBridgeEndBusAllocation
);
1651 // Notify the resource allocation phase is to start
1653 Status
= NotifyPhase (PciResAlloc
, EfiPciHostBridgeBeginResourceAllocation
);
1655 if (EFI_ERROR (Status
)) {
1659 RootBridgeHandle
= NULL
;
1660 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
1663 // if a root bridge instance is found, create root bridge device for it
1665 RootBridgeDev
= CreateRootBridge (RootBridgeHandle
);
1667 if (RootBridgeDev
== NULL
) {
1668 return EFI_OUT_OF_RESOURCES
;
1671 Status
= StartManagingRootBridge (RootBridgeDev
);
1673 if (EFI_ERROR (Status
)) {
1677 PciRootBridgeIo
= RootBridgeDev
->PciRootBridgeIo
;
1678 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1680 if (EFI_ERROR (Status
)) {
1684 Status
= PciGetBusRange (&Descriptors
, &MinBus
, NULL
, NULL
);
1686 if (EFI_ERROR (Status
)) {
1691 // Determine root bridge attribute by calling interface of Pcihostbridge
1694 DetermineRootBridgeAttributes (
1700 // Collect all the resource information under this root bridge
1701 // A database that records all the information about pci device subject to this
1702 // root bridge will then be created
1704 Status
= PciPciDeviceInfoCollector (
1709 if (EFI_ERROR (Status
)) {
1713 InsertRootBridge (RootBridgeDev
);
1716 // Record the hostbridge handle
1718 AddHostBridgeEnumerator (RootBridgeDev
->PciRootBridgeIo
->ParentHandle
);
1725 This function is used to program the Resizable BAR Register.
1727 @param PciIoDevice A pointer to the PCI_IO_DEVICE.
1728 @param ResizableBarOp PciResizableBarMax: Set BAR to max size
1729 PciResizableBarMin: set BAR to min size.
1731 @retval EFI_SUCCESS Successfully enumerated the host bridge.
1732 @retval other Some error occurred when enumerating the host bridge.
1736 PciProgramResizableBar (
1737 IN PCI_IO_DEVICE
*PciIoDevice
,
1738 IN PCI_RESIZABLE_BAR_OPERATION ResizableBarOp
1741 EFI_PCI_IO_PROTOCOL
*PciIo
;
1742 UINT64 Capabilities
;
1746 UINTN ResizableBarNumber
;
1748 PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY Entries
[PCI_MAX_BAR
];
1750 ASSERT (PciIoDevice
->ResizableBarOffset
!= 0);
1752 DEBUG ((DEBUG_INFO
, " Programs Resizable BAR register, offset: 0x%08x, number: %d\n",
1753 PciIoDevice
->ResizableBarOffset
, PciIoDevice
->ResizableBarNumber
));
1755 ResizableBarNumber
= MIN (PciIoDevice
->ResizableBarNumber
, PCI_MAX_BAR
);
1756 PciIo
= &PciIoDevice
->PciIo
;
1757 Status
= PciIo
->Pci
.Read (
1760 PciIoDevice
->ResizableBarOffset
+ sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER
),
1761 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY
) * ResizableBarNumber
,
1764 ASSERT_EFI_ERROR (Status
);
1766 for (Index
= 0; Index
< ResizableBarNumber
; Index
++) {
1769 // When the bit of Capabilities Set, indicates that the Function supports
1770 // operating with the BAR sized to (2^Bit) MB.
1772 // Bit 0 is set: supports operating with the BAR sized to 1 MB
1773 // Bit 1 is set: supports operating with the BAR sized to 2 MB
1774 // Bit n is set: supports operating with the BAR sized to (2^n) MB
1776 Capabilities
= LShiftU64(Entries
[Index
].ResizableBarControl
.Bits
.BarSizeCapability
, 28)
1777 | Entries
[Index
].ResizableBarCapability
.Bits
.BarSizeCapability
;
1779 if (ResizableBarOp
== PciResizableBarMax
) {
1780 Bit
= HighBitSet64(Capabilities
);
1782 ASSERT (ResizableBarOp
== PciResizableBarMin
);
1783 Bit
= LowBitSet64(Capabilities
);
1788 Offset
= PciIoDevice
->ResizableBarOffset
+ sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER
)
1789 + Index
* sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY
)
1790 + OFFSET_OF (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY
, ResizableBarControl
);
1792 Entries
[Index
].ResizableBarControl
.Bits
.BarSize
= (UINT32
) Bit
;
1795 " Resizable Bar: Offset = 0x%x, Bar Size Capability = 0x%016lx, New Bar Size = 0x%lx\n",
1796 OFFSET_OF (PCI_TYPE00
, Device
.Bar
[Entries
[Index
].ResizableBarControl
.Bits
.BarIndex
]),
1797 Capabilities
, LShiftU64 (SIZE_1MB
, Bit
)
1801 EfiPciIoWidthUint32
,
1804 &Entries
[Index
].ResizableBarControl
.Uint32