2 Provides the basic interfaces to abstract a PCI Host Bridge Resource
5 Copyright (C) 2015, Red Hat, Inc.
6 Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials are licensed and made available
9 under the terms and conditions of the BSD License which accompanies this
10 distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "PciHostBridge.h"
22 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate
= {
28 (UINT8
) (sizeof(ACPI_HID_DEVICE_PATH
)),
29 (UINT8
) ((sizeof(ACPI_HID_DEVICE_PATH
)) >> 8)
32 EISA_PNP_ID(0x0A03), // HID
38 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
40 END_DEVICE_PATH_LENGTH
,
46 EFI_HANDLE mDriverImageHandle
;
48 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
49 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
50 NULL
, // HostBridgeHandle
52 FALSE
, // ResourceSubiteed
71 Allocate and initialize a root bridge.
73 param[in] RootBusNumber The bus number of the root bus (root bridge) to
76 param[in] MaxSubBusNumber The inclusive maximum bus number that can be
77 assigned to any subordinate bus found behind any
78 PCI bridge hanging off this root bus.
80 The caller is repsonsible for ensuring that
81 RootBusNumber <= MaxSubBusNumber. If
82 RootBusNumber equals MaxSubBusNumber, then the
83 root bus has no room for subordinate buses.
85 param[in] HostBridgeHandle The EFI_HANDLE corresponding to the host bridge
86 that is the parent of the root bridge to create.
87 HostBridgeHandle is expected to have
88 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
91 param[out] RootBus The private PCI_ROOT_BRIDGE_INSTANCE that has
92 been created as the result of the function call.
94 @retval EFI_SUCCESS Initialization successful. A new
95 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL has been
96 created as the child of HostBridgeHandle. A
97 device path consisting of an ACPI device path
98 node, with UID = RootBusNumber, has been
99 installed on the same new handle.
101 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
103 @return Error codes from
104 gBS->InstallMultipleProtocolInterfaces().
109 IN UINT8 RootBusNumber
,
110 IN UINT8 MaxSubBusNumber
,
111 IN EFI_HANDLE HostBridgeHandle
,
112 OUT PCI_ROOT_BRIDGE_INSTANCE
**RootBus
115 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
116 PCI_ROOT_BRIDGE_RESOURCE_APERTURE ResAperture
;
119 ASSERT (RootBusNumber
<= MaxSubBusNumber
);
121 PrivateData
= AllocateZeroPool (sizeof *PrivateData
);
122 if (PrivateData
== NULL
) {
123 return EFI_OUT_OF_RESOURCES
;
126 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
128 CopyMem (&PrivateData
->DevicePath
, &mRootBridgeDevicePathTemplate
,
129 sizeof mRootBridgeDevicePathTemplate
);
130 PrivateData
->DevicePath
.AcpiDevicePath
.UID
= RootBusNumber
;
132 ResAperture
.BusBase
= RootBusNumber
;
133 ResAperture
.BusLimit
= MaxSubBusNumber
;
134 ResAperture
.MemBase
= BASE_2GB
;
135 ResAperture
.MemLimit
= BASE_4GB
- 1;
136 ResAperture
.IoBase
= 0;
137 ResAperture
.IoLimit
= MAX_UINT16
;
139 // The function call below allocates no resources and performs no actions
140 // that have to be rolled back on later failure. It always succeeds.
142 Status
= RootBridgeConstructor (&PrivateData
->Io
, HostBridgeHandle
,
143 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
, &ResAperture
);
144 ASSERT_EFI_ERROR (Status
);
146 Status
= gBS
->InstallMultipleProtocolInterfaces (&PrivateData
->Handle
,
147 &gEfiDevicePathProtocolGuid
, &PrivateData
->DevicePath
,
148 &gEfiPciRootBridgeIoProtocolGuid
, &PrivateData
->Io
,
150 if (EFI_ERROR (Status
)) {
151 goto FreePrivateData
;
155 "%a: installed root bus %d, with room for %d subordinate bus(es)\n",
156 __FUNCTION__
, RootBusNumber
, MaxSubBusNumber
- RootBusNumber
));
157 *RootBus
= PrivateData
;
161 FreePool (PrivateData
);
167 Uninitialize and free a root bridge set up with InitRootBridge().
169 On return, the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance and the device path
170 will have been released, freeing RootBus->Handle as well.
172 param[in] RootBus The private PCI_ROOT_BRIDGE_INSTANCE that has been created
173 with InitRootBridge(), and should be released.
178 IN PCI_ROOT_BRIDGE_INSTANCE
*RootBus
183 Status
= gBS
->UninstallMultipleProtocolInterfaces (RootBus
->Handle
,
184 &gEfiDevicePathProtocolGuid
, &RootBus
->DevicePath
,
185 &gEfiPciRootBridgeIoProtocolGuid
, &RootBus
->Io
,
187 ASSERT_EFI_ERROR (Status
);
193 Entry point of this driver
195 @param ImageHandle Handle of driver image
196 @param SystemTable Point to EFI_SYSTEM_TABLE
198 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
199 @retval EFI_DEVICE_ERROR Can not install the protocol instance
200 @retval EFI_SUCCESS Success to initialize the Pci host bridge.
204 InitializePciHostBridge (
205 IN EFI_HANDLE ImageHandle
,
206 IN EFI_SYSTEM_TABLE
*SystemTable
210 UINTN LastRootBridgeNumber
;
211 UINTN RootBridgeNumber
;
212 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
213 PCI_ROOT_BRIDGE_INSTANCE
*RootBus
;
214 EFI_STATUS UninstallStatus
;
216 mDriverImageHandle
= ImageHandle
;
219 // Create Host Bridge Device Handle
221 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
),
222 &mPciHostBridgeInstanceTemplate
);
223 if (HostBridge
== NULL
) {
224 return EFI_OUT_OF_RESOURCES
;
227 InitializeListHead (&HostBridge
->Head
);
229 Status
= gBS
->InstallMultipleProtocolInterfaces (
230 &HostBridge
->HostBridgeHandle
,
231 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
232 &HostBridge
->ResAlloc
,
235 if (EFI_ERROR (Status
)) {
240 // The "main" root bus is always there.
242 LastRootBridgeNumber
= 0;
245 // Scan all other root buses. If function 0 of any device on a bus returns a
246 // VendorId register value different from all-bits-one, then that bus is
249 for (RootBridgeNumber
= 1;
250 RootBridgeNumber
< 256;
251 ++RootBridgeNumber
) {
254 for (Device
= 0; Device
<= MAX_PCI_DEVICE_NUMBER
; ++Device
) {
255 if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber
, Device
, 0,
256 PCI_VENDOR_ID_OFFSET
)) != MAX_UINT16
) {
260 if (Device
<= MAX_PCI_DEVICE_NUMBER
) {
262 // Found the next root bus. We can now install the *previous* one,
263 // because now we know how big a bus number range *that* one has, for any
264 // subordinate buses that might exist behind PCI bridges hanging off it.
266 Status
= InitRootBridge ((UINT8
)LastRootBridgeNumber
,
267 (UINT8
)(RootBridgeNumber
- 1), HostBridge
->HostBridgeHandle
,
269 if (EFI_ERROR (Status
)) {
270 goto RollbackProtocols
;
272 InsertTailList (&HostBridge
->Head
, &RootBus
->Link
);
273 LastRootBridgeNumber
= RootBridgeNumber
;
278 // Install the last root bus (which might be the only, ie. main, root bus, if
279 // we've found no extra root buses).
281 Status
= InitRootBridge ((UINT8
)LastRootBridgeNumber
, 255,
282 HostBridge
->HostBridgeHandle
, &RootBus
);
283 if (EFI_ERROR (Status
)) {
284 goto RollbackProtocols
;
286 InsertTailList (&HostBridge
->Head
, &RootBus
->Link
);
291 while (!IsListEmpty (&HostBridge
->Head
)) {
294 Entry
= GetFirstNode (&HostBridge
->Head
);
295 RemoveEntryList (Entry
);
296 RootBus
= DRIVER_INSTANCE_FROM_LIST_ENTRY (Entry
);
297 UninitRootBridge (RootBus
);
299 UninstallStatus
= gBS
->UninstallMultipleProtocolInterfaces (
300 HostBridge
->HostBridgeHandle
,
301 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
302 &HostBridge
->ResAlloc
,
305 ASSERT_EFI_ERROR (UninstallStatus
);
308 FreePool (HostBridge
);
315 These are the notifications from the PCI bus driver that it is about to enter
316 a certain phase of the PCI enumeration process.
318 This member function can be used to notify the host bridge driver to perform
319 specific actions, including any chipset-specific initialization, so that the
320 chipset is ready to enter the next phase. Eight notification points are
321 defined at this time. See belows:
323 EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures
324 and internal data structures. The PCI
325 enumerator should issue this
326 notification before starting a fresh
327 enumeration process. Enumeration
328 cannot be restarted after sending any
329 other notification such as
330 EfiPciHostBridgeBeginBusAllocation.
332 EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to
333 begin. No specific action is required
334 here. This notification can be used to
335 perform any chipset-specific
338 EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming
339 phase is complete. No specific action
340 is required here. This notification
341 can be used to perform any
342 chipset-specific programming.
344 EfiPciHostBridgeBeginResourceAllocation
345 The resource allocation phase is about
346 to begin. No specific action is
347 required here. This notification can
348 be used to perform any
349 chipset-specific programming.
351 EfiPciHostBridgeAllocateResources Allocates resources per previously
352 submitted requests for all the PCI
353 root bridges. These resource settings
354 are returned on the next call to
355 GetProposedResources(). Before calling
356 NotifyPhase() with a Phase of
357 EfiPciHostBridgeAllocateResource, the
358 PCI bus enumerator is responsible for
359 gathering I/O and memory requests for
360 all the PCI root bridges and
361 submitting these requests using
362 SubmitResources(). This function pads
363 the resource amount to suit the root
364 bridge hardware, takes care of
365 dependencies between the PCI root
366 bridges, and calls the Global
367 Coherency Domain (GCD) with the
368 allocation request. In the case of
369 padding, the allocated range could be
370 bigger than what was requested.
372 EfiPciHostBridgeSetResources Programs the host bridge hardware to
373 decode previously allocated resources
374 (proposed resources) for all the PCI
375 root bridges. After the hardware is
376 programmed, reassigning resources will
377 not be supported. The bus settings are
380 EfiPciHostBridgeFreeResources Deallocates resources that were
381 previously allocated for all the PCI
382 root bridges and resets the I/O and
383 memory apertures to their initial
384 state. The bus settings are not
385 affected. If the request to allocate
386 resources fails, the PCI enumerator
387 can use this notification to
388 deallocate previous resources, adjust
389 the requests, and retry allocation.
391 EfiPciHostBridgeEndResourceAllocation The resource allocation phase is
392 completed. No specific action is
393 required here. This notification can
394 be used to perform any chipsetspecific
397 @param[in] This The instance pointer of
398 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
400 @param[in] Phase The phase during enumeration
402 @retval EFI_NOT_READY This phase cannot be entered at this time. For
403 example, this error is valid for a Phase of
404 EfiPciHostBridgeAllocateResources if
405 SubmitResources() has not been called for one
406 or more PCI root bridges before this call
408 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
409 This error is valid for a Phase of
410 EfiPciHostBridgeSetResources.
412 @retval EFI_INVALID_PARAMETER Invalid phase parameter
414 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
415 lack of resources. This error is valid for a
416 Phase of EfiPciHostBridgeAllocateResources if
417 the previously submitted resource requests
418 cannot be fulfilled or were only partially
421 @retval EFI_SUCCESS The notification was accepted without any
427 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
428 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
431 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
432 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
433 PCI_RESOURCE_TYPE Index
;
435 EFI_PHYSICAL_ADDRESS BaseAddress
;
437 UINTN BitsOfAlignment
;
439 EFI_STATUS ReturnStatus
;
441 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
445 case EfiPciHostBridgeBeginEnumeration
:
446 if (HostBridgeInstance
->CanRestarted
) {
448 // Reset the Each Root Bridge
450 List
= HostBridgeInstance
->Head
.ForwardLink
;
452 while (List
!= &HostBridgeInstance
->Head
) {
453 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
454 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
455 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
456 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
457 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
458 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
461 List
= List
->ForwardLink
;
464 HostBridgeInstance
->ResourceSubmited
= FALSE
;
465 HostBridgeInstance
->CanRestarted
= TRUE
;
470 return EFI_NOT_READY
;
474 case EfiPciHostBridgeEndEnumeration
:
477 case EfiPciHostBridgeBeginBusAllocation
:
479 // No specific action is required here, can perform any chipset specific
482 HostBridgeInstance
->CanRestarted
= FALSE
;
485 case EfiPciHostBridgeEndBusAllocation
:
487 // No specific action is required here, can perform any chipset specific
490 //HostBridgeInstance->CanRestarted = FALSE;
493 case EfiPciHostBridgeBeginResourceAllocation
:
495 // No specific action is required here, can perform any chipset specific
498 //HostBridgeInstance->CanRestarted = FALSE;
501 case EfiPciHostBridgeAllocateResources
:
502 ReturnStatus
= EFI_SUCCESS
;
503 if (HostBridgeInstance
->ResourceSubmited
) {
505 // Take care of the resource dependencies between the root bridges
507 List
= HostBridgeInstance
->Head
.ForwardLink
;
509 while (List
!= &HostBridgeInstance
->Head
) {
510 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
511 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
512 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
514 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
517 // Get the number of '1' in Alignment.
520 (UINTN
)(HighBitSet64 (
521 RootBridgeInstance
->ResAllocNode
[Index
].Alignment
528 // It is impossible for this chipset to align 0xFFFF for IO16
531 if (BitsOfAlignment
>= 16) {
535 Status
= gDS
->AllocateIoSpace (
536 EfiGcdAllocateAnySearchBottomUp
,
545 if (!EFI_ERROR (Status
)) {
546 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
548 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
551 ReturnStatus
= Status
;
552 if (Status
!= EFI_OUT_OF_RESOURCES
) {
553 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
562 // It is impossible for this chipset to align 0xFFFFFFFF for
567 if (BitsOfAlignment
>= 32) {
571 Status
= gDS
->AllocateMemorySpace (
572 EfiGcdAllocateAnySearchBottomUp
,
573 EfiGcdMemoryTypeMemoryMappedIo
,
581 if (!EFI_ERROR (Status
)) {
582 // We were able to allocate the PCI memory
583 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
585 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
589 // Not able to allocate enough PCI memory
590 ReturnStatus
= Status
;
592 if (Status
!= EFI_OUT_OF_RESOURCES
) {
593 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
602 ReturnStatus
= EFI_ABORTED
;
611 List
= List
->ForwardLink
;
617 return EFI_NOT_READY
;
621 case EfiPciHostBridgeSetResources
:
624 case EfiPciHostBridgeFreeResources
:
625 ReturnStatus
= EFI_SUCCESS
;
626 List
= HostBridgeInstance
->Head
.ForwardLink
;
627 while (List
!= &HostBridgeInstance
->Head
) {
628 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
629 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
630 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
631 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
632 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
636 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
637 if (EFI_ERROR (Status
)) {
638 ReturnStatus
= Status
;
643 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
644 if (EFI_ERROR (Status
)) {
645 ReturnStatus
= Status
;
663 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
664 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
665 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
666 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
670 List
= List
->ForwardLink
;
673 HostBridgeInstance
->ResourceSubmited
= FALSE
;
674 HostBridgeInstance
->CanRestarted
= TRUE
;
677 case EfiPciHostBridgeEndResourceAllocation
:
678 HostBridgeInstance
->CanRestarted
= FALSE
;
682 return EFI_INVALID_PARAMETER
;
689 Return the device handle of the next PCI root bridge that is associated with
692 This function is called multiple times to retrieve the device handles of all
693 the PCI root bridges that are associated with this PCI host bridge. Each PCI
694 host bridge is associated with one or more PCI root bridges. On each call,
695 the handle that was returned by the previous call is passed into the
696 interface, and on output the interface returns the device handle of the next
697 PCI root bridge. The caller can use the handle to obtain the instance of the
698 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more
699 PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI
700 enumerator must enumerate the PCI root bridges in the order that they are
701 returned by this function.
703 For D945 implementation, there is only one root bridge in PCI host bridge.
705 @param[in] This The instance pointer of
706 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
708 @param[in, out] RootBridgeHandle Returns the device handle of the next PCI
711 @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then
712 return the first Rootbridge handle of the
713 specific Host bridge and return EFI_SUCCESS.
715 @retval EFI_NOT_FOUND Can not find the any more root bridge in
716 specific host bridge.
718 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
719 returned on a previous call to
725 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
726 IN OUT EFI_HANDLE
*RootBridgeHandle
729 BOOLEAN NoRootBridge
;
731 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
732 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
735 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
736 List
= HostBridgeInstance
->Head
.ForwardLink
;
739 while (List
!= &HostBridgeInstance
->Head
) {
740 NoRootBridge
= FALSE
;
741 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
742 if (*RootBridgeHandle
== NULL
) {
744 // Return the first Root Bridge Handle of the Host Bridge
746 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
749 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
753 List
= List
->ForwardLink
;
754 if (List
!=&HostBridgeInstance
->Head
) {
755 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
756 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
759 return EFI_NOT_FOUND
;
764 List
= List
->ForwardLink
;
768 return EFI_NOT_FOUND
;
770 return EFI_INVALID_PARAMETER
;
775 Returns the allocation attributes of a PCI root bridge.
777 The function returns the allocation attributes of a specific PCI root bridge.
778 The attributes can vary from one PCI root bridge to another. These attributes
779 are different from the decode-related attributes that are returned by the
780 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
781 RootBridgeHandle parameter is used to specify the instance of the PCI root
782 bridge. The device handles of all the root bridges that are associated with
783 this host bridge must be obtained by calling GetNextRootBridge(). The
784 attributes are static in the sense that they do not change during or after
785 the enumeration process. The hardware may provide mechanisms to change the
786 attributes on the fly, but such changes must be completed before
787 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted
788 values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
789 "Related Definitions" below. The caller uses these attributes to combine
790 multiple resource requests.
792 For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI
793 bus enumerator needs to include requests for the prefetchable memory in the
794 nonprefetchable memory pool and not request any prefetchable memory.
796 Attribute Description
797 ------------------------------------ ---------------------------------------
798 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root
799 bridge does not support separate
800 windows for nonprefetchable and
801 prefetchable memory. A PCI bus driver
802 needs to include requests for
803 prefetchable memory in the
804 nonprefetchable memory pool.
806 EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root
807 bridge supports 64-bit memory windows.
808 If this bit is not set, the PCI bus
809 driver needs to include requests for a
810 64-bit memory address in the
811 corresponding 32-bit memory pool.
813 @param[in] This The instance pointer of
814 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
816 @param[in] RootBridgeHandle The device handle of the PCI root bridge in
817 which the caller is interested. Type
818 EFI_HANDLE is defined in
819 InstallProtocolInterface() in the UEFI 2.0
822 @param[out] Attributes The pointer to attribte of root bridge, it is
825 @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
827 @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
829 @retval EFI_SUCCESS Success to get attribute of interested root
835 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
836 IN EFI_HANDLE RootBridgeHandle
,
837 OUT UINT64
*Attributes
841 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
842 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
844 if (Attributes
== NULL
) {
845 return EFI_INVALID_PARAMETER
;
848 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
849 List
= HostBridgeInstance
->Head
.ForwardLink
;
851 while (List
!= &HostBridgeInstance
->Head
) {
852 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
853 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
854 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
857 List
= List
->ForwardLink
;
861 // RootBridgeHandle is not an EFI_HANDLE
862 // that was returned on a previous call to GetNextRootBridge()
864 return EFI_INVALID_PARAMETER
;
868 Sets up the specified PCI root bridge for the bus enumeration process.
870 This member function sets up the root bridge for bus enumeration and returns
871 the PCI bus range over which the search should be performed in ACPI 2.0
872 resource descriptor format.
875 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
878 @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
880 @param[out] Configuration Pointer to the pointer to the PCI bus resource
883 @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
885 @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
887 @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
892 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
893 IN EFI_HANDLE RootBridgeHandle
,
894 OUT VOID
**Configuration
898 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
899 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
905 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
906 List
= HostBridgeInstance
->Head
.ForwardLink
;
908 while (List
!= &HostBridgeInstance
->Head
) {
909 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
910 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
912 // Set up the Root Bridge for Bus Enumeration
914 BusStart
= RootBridgeInstance
->BusBase
;
915 BusEnd
= RootBridgeInstance
->BusLimit
;
917 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
920 Buffer
= AllocatePool (
921 sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
922 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
924 if (Buffer
== NULL
) {
925 return EFI_OUT_OF_RESOURCES
;
928 Temp
= (UINT8
*)Buffer
;
930 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
931 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
932 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
933 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
934 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
935 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
936 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
937 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
938 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
939 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
=
940 BusEnd
- BusStart
+ 1;
942 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
943 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
944 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
946 *Configuration
= Buffer
;
949 List
= List
->ForwardLink
;
952 return EFI_INVALID_PARAMETER
;
956 Programs the PCI root bridge hardware so that it decodes the specified PCI
959 This member function programs the specified PCI root bridge to decode the bus
960 range that is specified by the input parameter Configuration.
961 The bus range information is specified in terms of the ACPI 2.0 resource
965 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
968 @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be
971 @param[in] Configuration The pointer to the PCI bus resource descriptor
973 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
976 @retval EFI_INVALID_PARAMETER Configuration is NULL.
978 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
979 2.0 resource descriptor.
981 @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI
982 2.0 bus resource descriptor.
984 @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource
985 descriptors other than bus descriptors.
987 @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid
988 ACPI resource descriptors.
990 @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this
993 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this
996 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
998 @retval EFI_SUCCESS The bus range for the PCI root bridge was
1004 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1005 IN EFI_HANDLE RootBridgeHandle
,
1006 IN VOID
*Configuration
1010 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1011 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1017 if (Configuration
== NULL
) {
1018 return EFI_INVALID_PARAMETER
;
1021 Ptr
= Configuration
;
1024 // Check the Configuration is valid
1026 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1027 return EFI_INVALID_PARAMETER
;
1030 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
1031 return EFI_INVALID_PARAMETER
;
1034 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1035 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
1036 return EFI_INVALID_PARAMETER
;
1039 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1040 List
= HostBridgeInstance
->Head
.ForwardLink
;
1042 Ptr
= Configuration
;
1044 while (List
!= &HostBridgeInstance
->Head
) {
1045 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1046 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1047 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
1049 Desc
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
;
1050 BusStart
= (UINTN
)Desc
->AddrRangeMin
;
1051 BusLen
= (UINTN
)Desc
->AddrLen
;
1052 BusEnd
= BusStart
+ BusLen
- 1;
1054 if (BusStart
> BusEnd
) {
1055 return EFI_INVALID_PARAMETER
;
1058 if ((BusStart
< RootBridgeInstance
->BusBase
) ||
1059 (BusEnd
> RootBridgeInstance
->BusLimit
)) {
1060 return EFI_INVALID_PARAMETER
;
1064 // Update the Bus Range
1066 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
1067 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
1068 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
1071 // Program the Root Bridge Hardware
1077 List
= List
->ForwardLink
;
1080 return EFI_INVALID_PARAMETER
;
1085 Submits the I/O and memory resource requirements for the specified PCI root
1088 This function is used to submit all the I/O and memory resources that are
1089 required by the specified PCI root bridge. The input parameter Configuration
1090 is used to specify the following:
1091 - The various types of resources that are required
1092 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1094 @param[in] This Pointer to the
1095 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1098 @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory
1099 resource requirements are being submitted.
1101 @param[in] Configuration The pointer to the PCI I/O and PCI memory
1102 resource descriptor.
1104 @retval EFI_SUCCESS The I/O and memory resource requests for a PCI
1105 root bridge were accepted.
1107 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1110 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1112 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
1113 2.0 resource descriptor.
1115 @retval EFI_INVALID_PARAMETER Configuration includes requests for one or
1116 more resource types that are not supported by
1117 this PCI root bridge. This error will happen
1118 if the caller did not combine resources
1119 according to Attributes that were returned by
1120 GetAllocAttributes().
1122 @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
1124 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI
1127 @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for
1128 this PCI root bridge.
1133 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1134 IN EFI_HANDLE RootBridgeHandle
,
1135 IN VOID
*Configuration
1139 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1140 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1142 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1147 // Check the input parameter: Configuration
1149 if (Configuration
== NULL
) {
1150 return EFI_INVALID_PARAMETER
;
1153 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1154 List
= HostBridgeInstance
->Head
.ForwardLink
;
1156 Temp
= (UINT8
*)Configuration
;
1157 while ( *Temp
== 0x8A) {
1158 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1160 if (*Temp
!= 0x79) {
1161 return EFI_INVALID_PARAMETER
;
1164 Temp
= (UINT8
*)Configuration
;
1165 while (List
!= &HostBridgeInstance
->Head
) {
1166 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1167 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1168 while ( *Temp
== 0x8A) {
1169 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1172 // Check Address Length
1174 if (Ptr
->AddrLen
> 0xffffffff) {
1175 return EFI_INVALID_PARAMETER
;
1179 // Check address range alignment
1181 if (Ptr
->AddrRangeMax
>= 0xffffffff ||
1182 Ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (
1183 Ptr
->AddrRangeMax
+ 1) - 1)) {
1184 return EFI_INVALID_PARAMETER
;
1187 switch (Ptr
->ResType
) {
1192 // Check invalid Address Sapce Granularity
1194 if (Ptr
->AddrSpaceGranularity
!= 32) {
1195 return EFI_INVALID_PARAMETER
;
1199 // check the memory resource request is supported by PCI root bridge
1201 if (RootBridgeInstance
->RootBridgeAttrib
==
1202 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
1203 Ptr
->SpecificFlag
== 0x06) {
1204 return EFI_INVALID_PARAMETER
;
1207 AddrLen
= Ptr
->AddrLen
;
1208 Alignment
= Ptr
->AddrRangeMax
;
1209 if (Ptr
->AddrSpaceGranularity
== 32) {
1210 if (Ptr
->SpecificFlag
== 0x06) {
1214 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
=
1217 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1218 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
=
1220 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
=
1222 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1226 if (Ptr
->AddrSpaceGranularity
== 64) {
1227 if (Ptr
->SpecificFlag
== 0x06) {
1228 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
=
1231 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
=
1238 AddrLen
= (UINTN
) Ptr
->AddrLen
;
1239 Alignment
= (UINTN
) Ptr
->AddrRangeMax
;
1240 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
1241 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
1242 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
1243 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1250 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1256 List
= List
->ForwardLink
;
1259 return EFI_INVALID_PARAMETER
;
1263 Returns the proposed resource settings for the specified PCI root bridge.
1265 This member function returns the proposed resource settings for the
1266 specified PCI root bridge. The proposed resource settings are prepared when
1267 NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.
1268 The output parameter Configuration specifies the following:
1269 - The various types of resources, excluding bus resources, that are
1271 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1273 @param[in] This Pointer to the
1274 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1277 @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is
1278 defined in InstallProtocolInterface() in the
1279 UEFI 2.0 Specification.
1281 @param[out] Configuration The pointer to the pointer to the PCI I/O and
1282 memory resource descriptor.
1284 @retval EFI_SUCCESS The requested parameters were returned.
1286 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1289 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1291 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1296 GetProposedResources(
1297 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1298 IN EFI_HANDLE RootBridgeHandle
,
1299 OUT VOID
**Configuration
1303 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1304 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1309 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1315 // Get the Host Bridge Instance from the resource allocation protocol
1317 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1318 List
= HostBridgeInstance
->Head
.ForwardLink
;
1321 // Enumerate the root bridges in this host bridge
1323 while (List
!= &HostBridgeInstance
->Head
) {
1324 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1325 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1326 for (Index
= 0; Index
< TypeBus
; Index
++) {
1327 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1333 return EFI_INVALID_PARAMETER
;
1336 Buffer
= AllocateZeroPool (
1337 Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
1338 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
1340 if (Buffer
== NULL
) {
1341 return EFI_OUT_OF_RESOURCES
;
1345 for (Index
= 0; Index
< TypeBus
; Index
++) {
1346 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1347 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1348 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1360 Ptr
->SpecificFlag
= 0;
1361 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1362 Ptr
->AddrRangeMax
= 0;
1363 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1364 EFI_RESOURCE_SATISFIED
:
1366 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1377 Ptr
->SpecificFlag
= 0;
1378 Ptr
->AddrSpaceGranularity
= 32;
1379 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1380 Ptr
->AddrRangeMax
= 0;
1381 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1382 EFI_RESOURCE_SATISFIED
:
1384 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1389 // Prefetch memory 32
1395 Ptr
->SpecificFlag
= 6;
1396 Ptr
->AddrSpaceGranularity
= 32;
1397 Ptr
->AddrRangeMin
= 0;
1398 Ptr
->AddrRangeMax
= 0;
1399 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1411 Ptr
->SpecificFlag
= 0;
1412 Ptr
->AddrSpaceGranularity
= 64;
1413 Ptr
->AddrRangeMin
= 0;
1414 Ptr
->AddrRangeMax
= 0;
1415 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1421 // Prefetch memory 64
1427 Ptr
->SpecificFlag
= 6;
1428 Ptr
->AddrSpaceGranularity
= 64;
1429 Ptr
->AddrRangeMin
= 0;
1430 Ptr
->AddrRangeMax
= 0;
1431 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1436 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1440 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1441 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1443 *Configuration
= Buffer
;
1448 List
= List
->ForwardLink
;
1451 return EFI_INVALID_PARAMETER
;
1455 Provides the hooks from the PCI bus driver to every PCI controller
1456 (device/function) at various stages of the PCI enumeration process that allow
1457 the host bridge driver to preinitialize individual PCI controllers before
1460 This function is called during the PCI enumeration process. No specific
1461 action is expected from this member function. It allows the host bridge
1462 driver to preinitialize individual PCI controllers before enumeration.
1464 @param This Pointer to the
1465 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1468 @param RootBridgeHandle The associated PCI root bridge handle. Type
1469 EFI_HANDLE is defined in InstallProtocolInterface()
1470 in the UEFI 2.0 Specification.
1472 @param PciAddress The address of the PCI device on the PCI bus. This
1473 address can be passed to the
1474 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to
1475 access the PCI configuration space of the device.
1476 See Table 12-1 in the UEFI 2.0 Specification for the
1478 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
1480 @param Phase The phase of the PCI device enumeration.
1482 @retval EFI_SUCCESS The requested parameters were returned.
1484 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1487 @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined
1489 EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
1491 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1492 The PCI enumerator should not enumerate this
1493 device, including its child devices if it is
1494 a PCI-to-PCI bridge.
1498 PreprocessController (
1499 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1500 IN EFI_HANDLE RootBridgeHandle
,
1501 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1502 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1505 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1506 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1509 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1510 List
= HostBridgeInstance
->Head
.ForwardLink
;
1513 // Enumerate the root bridges in this host bridge
1515 while (List
!= &HostBridgeInstance
->Head
) {
1516 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1517 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1520 List
= List
->ForwardLink
;
1522 if (List
== &HostBridgeInstance
->Head
) {
1523 return EFI_INVALID_PARAMETER
;
1526 if ((UINT32
)Phase
> EfiPciBeforeResourceCollection
) {
1527 return EFI_INVALID_PARAMETER
;