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 <Library/QemuFwCfgLib.h>
20 #include "PciHostBridge.h"
24 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate
= {
30 (UINT8
) (sizeof(ACPI_HID_DEVICE_PATH
)),
31 (UINT8
) ((sizeof(ACPI_HID_DEVICE_PATH
)) >> 8)
34 EISA_PNP_ID(0x0A03), // HID
40 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
42 END_DEVICE_PATH_LENGTH
,
48 EFI_HANDLE mDriverImageHandle
;
50 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
51 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
52 NULL
, // HostBridgeHandle
54 FALSE
, // ResourceSubiteed
73 Allocate and initialize a root bridge.
75 param[in] RootBusNumber The bus number of the root bus (root bridge) to
78 param[in] MaxSubBusNumber The inclusive maximum bus number that can be
79 assigned to any subordinate bus found behind any
80 PCI bridge hanging off this root bus.
82 The caller is repsonsible for ensuring that
83 RootBusNumber <= MaxSubBusNumber. If
84 RootBusNumber equals MaxSubBusNumber, then the
85 root bus has no room for subordinate buses.
87 param[in] HostBridgeHandle The EFI_HANDLE corresponding to the host bridge
88 that is the parent of the root bridge to create.
89 HostBridgeHandle is expected to have
90 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
93 param[out] RootBus The private PCI_ROOT_BRIDGE_INSTANCE that has
94 been created as the result of the function call.
96 @retval EFI_SUCCESS Initialization successful. A new
97 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL has been
98 created as the child of HostBridgeHandle. A
99 device path consisting of an ACPI device path
100 node, with UID = RootBusNumber, has been
101 installed on the same new handle.
103 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
105 @return Error codes from
106 gBS->InstallMultipleProtocolInterfaces().
111 IN UINT8 RootBusNumber
,
112 IN UINT8 MaxSubBusNumber
,
113 IN EFI_HANDLE HostBridgeHandle
,
114 OUT PCI_ROOT_BRIDGE_INSTANCE
**RootBus
117 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
118 PCI_ROOT_BRIDGE_RESOURCE_APERTURE ResAperture
;
121 ASSERT (RootBusNumber
<= MaxSubBusNumber
);
123 PrivateData
= AllocateZeroPool (sizeof *PrivateData
);
124 if (PrivateData
== NULL
) {
125 return EFI_OUT_OF_RESOURCES
;
128 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
130 CopyMem (&PrivateData
->DevicePath
, &mRootBridgeDevicePathTemplate
,
131 sizeof mRootBridgeDevicePathTemplate
);
132 PrivateData
->DevicePath
.AcpiDevicePath
.UID
= RootBusNumber
;
134 ResAperture
.BusBase
= RootBusNumber
;
135 ResAperture
.BusLimit
= MaxSubBusNumber
;
136 ResAperture
.MemBase
= BASE_2GB
;
137 ResAperture
.MemLimit
= BASE_4GB
- 1;
138 ResAperture
.IoBase
= 0;
139 ResAperture
.IoLimit
= MAX_UINT16
;
141 // The function call below allocates no resources and performs no actions
142 // that have to be rolled back on later failure. It always succeeds.
144 Status
= RootBridgeConstructor (&PrivateData
->Io
, HostBridgeHandle
,
145 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
, &ResAperture
);
146 ASSERT_EFI_ERROR (Status
);
148 Status
= gBS
->InstallMultipleProtocolInterfaces (&PrivateData
->Handle
,
149 &gEfiDevicePathProtocolGuid
, &PrivateData
->DevicePath
,
150 &gEfiPciRootBridgeIoProtocolGuid
, &PrivateData
->Io
,
152 if (EFI_ERROR (Status
)) {
153 goto FreePrivateData
;
157 "%a: installed root bus %d, with room for %d subordinate bus(es)\n",
158 __FUNCTION__
, RootBusNumber
, MaxSubBusNumber
- RootBusNumber
));
159 *RootBus
= PrivateData
;
163 FreePool (PrivateData
);
169 Uninitialize and free a root bridge set up with InitRootBridge().
171 On return, the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance and the device path
172 will have been released, freeing RootBus->Handle as well.
174 param[in] RootBus The private PCI_ROOT_BRIDGE_INSTANCE that has been created
175 with InitRootBridge(), and should be released.
180 IN PCI_ROOT_BRIDGE_INSTANCE
*RootBus
185 Status
= gBS
->UninstallMultipleProtocolInterfaces (RootBus
->Handle
,
186 &gEfiDevicePathProtocolGuid
, &RootBus
->DevicePath
,
187 &gEfiPciRootBridgeIoProtocolGuid
, &RootBus
->Io
,
189 ASSERT_EFI_ERROR (Status
);
195 Entry point of this driver
197 @param ImageHandle Handle of driver image
198 @param SystemTable Point to EFI_SYSTEM_TABLE
200 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
201 @retval EFI_DEVICE_ERROR Can not install the protocol instance
202 @retval EFI_SUCCESS Success to initialize the Pci host bridge.
206 InitializePciHostBridge (
207 IN EFI_HANDLE ImageHandle
,
208 IN EFI_SYSTEM_TABLE
*SystemTable
212 FIRMWARE_CONFIG_ITEM FwCfgItem
;
214 UINT64 ExtraRootBridgesLeft
;
215 UINTN LastRootBridgeNumber
;
216 UINTN RootBridgeNumber
;
217 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
218 PCI_ROOT_BRIDGE_INSTANCE
*RootBus
;
219 EFI_STATUS UninstallStatus
;
221 mDriverImageHandle
= ImageHandle
;
224 // Create Host Bridge Device Handle
226 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
),
227 &mPciHostBridgeInstanceTemplate
);
228 if (HostBridge
== NULL
) {
229 return EFI_OUT_OF_RESOURCES
;
232 InitializeListHead (&HostBridge
->Head
);
234 Status
= gBS
->InstallMultipleProtocolInterfaces (
235 &HostBridge
->HostBridgeHandle
,
236 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
237 &HostBridge
->ResAlloc
,
240 if (EFI_ERROR (Status
)) {
245 // QEMU provides the number of extra root buses, shortening the exhaustive
246 // search below. If there is no hint, the feature is missing.
248 Status
= QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem
, &FwCfgSize
);
249 if (EFI_ERROR (Status
) || FwCfgSize
!= sizeof ExtraRootBridgesLeft
) {
250 ExtraRootBridgesLeft
= 0;
252 QemuFwCfgSelectItem (FwCfgItem
);
253 QemuFwCfgReadBytes (FwCfgSize
, &ExtraRootBridgesLeft
);
254 DEBUG ((EFI_D_INFO
, "%a: %Lu extra root buses reported by QEMU\n",
255 __FUNCTION__
, ExtraRootBridgesLeft
));
259 // The "main" root bus is always there.
261 LastRootBridgeNumber
= 0;
264 // Scan all other root buses. If function 0 of any device on a bus returns a
265 // VendorId register value different from all-bits-one, then that bus is
268 for (RootBridgeNumber
= 1;
269 RootBridgeNumber
< 256 && ExtraRootBridgesLeft
> 0;
270 ++RootBridgeNumber
) {
273 for (Device
= 0; Device
<= MAX_PCI_DEVICE_NUMBER
; ++Device
) {
274 if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber
, Device
, 0,
275 PCI_VENDOR_ID_OFFSET
)) != MAX_UINT16
) {
279 if (Device
<= MAX_PCI_DEVICE_NUMBER
) {
281 // Found the next root bus. We can now install the *previous* one,
282 // because now we know how big a bus number range *that* one has, for any
283 // subordinate buses that might exist behind PCI bridges hanging off it.
285 Status
= InitRootBridge ((UINT8
)LastRootBridgeNumber
,
286 (UINT8
)(RootBridgeNumber
- 1), HostBridge
->HostBridgeHandle
,
288 if (EFI_ERROR (Status
)) {
289 goto RollbackProtocols
;
291 InsertTailList (&HostBridge
->Head
, &RootBus
->Link
);
292 LastRootBridgeNumber
= RootBridgeNumber
;
293 --ExtraRootBridgesLeft
;
298 // Install the last root bus (which might be the only, ie. main, root bus, if
299 // we've found no extra root buses).
301 Status
= InitRootBridge ((UINT8
)LastRootBridgeNumber
, 255,
302 HostBridge
->HostBridgeHandle
, &RootBus
);
303 if (EFI_ERROR (Status
)) {
304 goto RollbackProtocols
;
306 InsertTailList (&HostBridge
->Head
, &RootBus
->Link
);
311 while (!IsListEmpty (&HostBridge
->Head
)) {
314 Entry
= GetFirstNode (&HostBridge
->Head
);
315 RemoveEntryList (Entry
);
316 RootBus
= DRIVER_INSTANCE_FROM_LIST_ENTRY (Entry
);
317 UninitRootBridge (RootBus
);
319 UninstallStatus
= gBS
->UninstallMultipleProtocolInterfaces (
320 HostBridge
->HostBridgeHandle
,
321 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
322 &HostBridge
->ResAlloc
,
325 ASSERT_EFI_ERROR (UninstallStatus
);
328 FreePool (HostBridge
);
335 These are the notifications from the PCI bus driver that it is about to enter
336 a certain phase of the PCI enumeration process.
338 This member function can be used to notify the host bridge driver to perform
339 specific actions, including any chipset-specific initialization, so that the
340 chipset is ready to enter the next phase. Eight notification points are
341 defined at this time. See belows:
343 EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures
344 and internal data structures. The PCI
345 enumerator should issue this
346 notification before starting a fresh
347 enumeration process. Enumeration
348 cannot be restarted after sending any
349 other notification such as
350 EfiPciHostBridgeBeginBusAllocation.
352 EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to
353 begin. No specific action is required
354 here. This notification can be used to
355 perform any chipset-specific
358 EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming
359 phase is complete. No specific action
360 is required here. This notification
361 can be used to perform any
362 chipset-specific programming.
364 EfiPciHostBridgeBeginResourceAllocation
365 The resource allocation phase is about
366 to begin. No specific action is
367 required here. This notification can
368 be used to perform any
369 chipset-specific programming.
371 EfiPciHostBridgeAllocateResources Allocates resources per previously
372 submitted requests for all the PCI
373 root bridges. These resource settings
374 are returned on the next call to
375 GetProposedResources(). Before calling
376 NotifyPhase() with a Phase of
377 EfiPciHostBridgeAllocateResource, the
378 PCI bus enumerator is responsible for
379 gathering I/O and memory requests for
380 all the PCI root bridges and
381 submitting these requests using
382 SubmitResources(). This function pads
383 the resource amount to suit the root
384 bridge hardware, takes care of
385 dependencies between the PCI root
386 bridges, and calls the Global
387 Coherency Domain (GCD) with the
388 allocation request. In the case of
389 padding, the allocated range could be
390 bigger than what was requested.
392 EfiPciHostBridgeSetResources Programs the host bridge hardware to
393 decode previously allocated resources
394 (proposed resources) for all the PCI
395 root bridges. After the hardware is
396 programmed, reassigning resources will
397 not be supported. The bus settings are
400 EfiPciHostBridgeFreeResources Deallocates resources that were
401 previously allocated for all the PCI
402 root bridges and resets the I/O and
403 memory apertures to their initial
404 state. The bus settings are not
405 affected. If the request to allocate
406 resources fails, the PCI enumerator
407 can use this notification to
408 deallocate previous resources, adjust
409 the requests, and retry allocation.
411 EfiPciHostBridgeEndResourceAllocation The resource allocation phase is
412 completed. No specific action is
413 required here. This notification can
414 be used to perform any chipsetspecific
417 @param[in] This The instance pointer of
418 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
420 @param[in] Phase The phase during enumeration
422 @retval EFI_NOT_READY This phase cannot be entered at this time. For
423 example, this error is valid for a Phase of
424 EfiPciHostBridgeAllocateResources if
425 SubmitResources() has not been called for one
426 or more PCI root bridges before this call
428 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
429 This error is valid for a Phase of
430 EfiPciHostBridgeSetResources.
432 @retval EFI_INVALID_PARAMETER Invalid phase parameter
434 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
435 lack of resources. This error is valid for a
436 Phase of EfiPciHostBridgeAllocateResources if
437 the previously submitted resource requests
438 cannot be fulfilled or were only partially
441 @retval EFI_SUCCESS The notification was accepted without any
447 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
448 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
451 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
452 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
453 PCI_RESOURCE_TYPE Index
;
455 EFI_PHYSICAL_ADDRESS BaseAddress
;
457 UINTN BitsOfAlignment
;
459 EFI_STATUS ReturnStatus
;
461 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
465 case EfiPciHostBridgeBeginEnumeration
:
466 if (HostBridgeInstance
->CanRestarted
) {
468 // Reset the Each Root Bridge
470 List
= HostBridgeInstance
->Head
.ForwardLink
;
472 while (List
!= &HostBridgeInstance
->Head
) {
473 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
474 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
475 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
476 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
477 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
478 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
481 List
= List
->ForwardLink
;
484 HostBridgeInstance
->ResourceSubmited
= FALSE
;
485 HostBridgeInstance
->CanRestarted
= TRUE
;
490 return EFI_NOT_READY
;
494 case EfiPciHostBridgeEndEnumeration
:
497 case EfiPciHostBridgeBeginBusAllocation
:
499 // No specific action is required here, can perform any chipset specific
502 HostBridgeInstance
->CanRestarted
= FALSE
;
505 case EfiPciHostBridgeEndBusAllocation
:
507 // No specific action is required here, can perform any chipset specific
510 //HostBridgeInstance->CanRestarted = FALSE;
513 case EfiPciHostBridgeBeginResourceAllocation
:
515 // No specific action is required here, can perform any chipset specific
518 //HostBridgeInstance->CanRestarted = FALSE;
521 case EfiPciHostBridgeAllocateResources
:
522 ReturnStatus
= EFI_SUCCESS
;
523 if (HostBridgeInstance
->ResourceSubmited
) {
525 // Take care of the resource dependencies between the root bridges
527 List
= HostBridgeInstance
->Head
.ForwardLink
;
529 while (List
!= &HostBridgeInstance
->Head
) {
530 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
531 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
532 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
534 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
537 // Get the number of '1' in Alignment.
540 (UINTN
)(HighBitSet64 (
541 RootBridgeInstance
->ResAllocNode
[Index
].Alignment
548 // It is impossible for this chipset to align 0xFFFF for IO16
551 if (BitsOfAlignment
>= 16) {
555 Status
= gDS
->AllocateIoSpace (
556 EfiGcdAllocateAnySearchBottomUp
,
565 if (!EFI_ERROR (Status
)) {
566 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
568 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
571 ReturnStatus
= Status
;
572 if (Status
!= EFI_OUT_OF_RESOURCES
) {
573 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
582 // It is impossible for this chipset to align 0xFFFFFFFF for
587 if (BitsOfAlignment
>= 32) {
591 Status
= gDS
->AllocateMemorySpace (
592 EfiGcdAllocateAnySearchBottomUp
,
593 EfiGcdMemoryTypeMemoryMappedIo
,
601 if (!EFI_ERROR (Status
)) {
602 // We were able to allocate the PCI memory
603 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
605 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
609 // Not able to allocate enough PCI memory
610 ReturnStatus
= Status
;
612 if (Status
!= EFI_OUT_OF_RESOURCES
) {
613 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
622 ReturnStatus
= EFI_ABORTED
;
631 List
= List
->ForwardLink
;
637 return EFI_NOT_READY
;
641 case EfiPciHostBridgeSetResources
:
644 case EfiPciHostBridgeFreeResources
:
645 ReturnStatus
= EFI_SUCCESS
;
646 List
= HostBridgeInstance
->Head
.ForwardLink
;
647 while (List
!= &HostBridgeInstance
->Head
) {
648 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
649 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
650 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
651 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
652 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
656 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
657 if (EFI_ERROR (Status
)) {
658 ReturnStatus
= Status
;
663 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
664 if (EFI_ERROR (Status
)) {
665 ReturnStatus
= Status
;
683 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
684 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
685 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
686 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
690 List
= List
->ForwardLink
;
693 HostBridgeInstance
->ResourceSubmited
= FALSE
;
694 HostBridgeInstance
->CanRestarted
= TRUE
;
697 case EfiPciHostBridgeEndResourceAllocation
:
698 HostBridgeInstance
->CanRestarted
= FALSE
;
702 return EFI_INVALID_PARAMETER
;
709 Return the device handle of the next PCI root bridge that is associated with
712 This function is called multiple times to retrieve the device handles of all
713 the PCI root bridges that are associated with this PCI host bridge. Each PCI
714 host bridge is associated with one or more PCI root bridges. On each call,
715 the handle that was returned by the previous call is passed into the
716 interface, and on output the interface returns the device handle of the next
717 PCI root bridge. The caller can use the handle to obtain the instance of the
718 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more
719 PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI
720 enumerator must enumerate the PCI root bridges in the order that they are
721 returned by this function.
723 For D945 implementation, there is only one root bridge in PCI host bridge.
725 @param[in] This The instance pointer of
726 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
728 @param[in, out] RootBridgeHandle Returns the device handle of the next PCI
731 @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then
732 return the first Rootbridge handle of the
733 specific Host bridge and return EFI_SUCCESS.
735 @retval EFI_NOT_FOUND Can not find the any more root bridge in
736 specific host bridge.
738 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
739 returned on a previous call to
745 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
746 IN OUT EFI_HANDLE
*RootBridgeHandle
749 BOOLEAN NoRootBridge
;
751 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
752 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
755 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
756 List
= HostBridgeInstance
->Head
.ForwardLink
;
759 while (List
!= &HostBridgeInstance
->Head
) {
760 NoRootBridge
= FALSE
;
761 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
762 if (*RootBridgeHandle
== NULL
) {
764 // Return the first Root Bridge Handle of the Host Bridge
766 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
769 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
773 List
= List
->ForwardLink
;
774 if (List
!=&HostBridgeInstance
->Head
) {
775 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
776 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
779 return EFI_NOT_FOUND
;
784 List
= List
->ForwardLink
;
788 return EFI_NOT_FOUND
;
790 return EFI_INVALID_PARAMETER
;
795 Returns the allocation attributes of a PCI root bridge.
797 The function returns the allocation attributes of a specific PCI root bridge.
798 The attributes can vary from one PCI root bridge to another. These attributes
799 are different from the decode-related attributes that are returned by the
800 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
801 RootBridgeHandle parameter is used to specify the instance of the PCI root
802 bridge. The device handles of all the root bridges that are associated with
803 this host bridge must be obtained by calling GetNextRootBridge(). The
804 attributes are static in the sense that they do not change during or after
805 the enumeration process. The hardware may provide mechanisms to change the
806 attributes on the fly, but such changes must be completed before
807 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted
808 values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
809 "Related Definitions" below. The caller uses these attributes to combine
810 multiple resource requests.
812 For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI
813 bus enumerator needs to include requests for the prefetchable memory in the
814 nonprefetchable memory pool and not request any prefetchable memory.
816 Attribute Description
817 ------------------------------------ ---------------------------------------
818 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root
819 bridge does not support separate
820 windows for nonprefetchable and
821 prefetchable memory. A PCI bus driver
822 needs to include requests for
823 prefetchable memory in the
824 nonprefetchable memory pool.
826 EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root
827 bridge supports 64-bit memory windows.
828 If this bit is not set, the PCI bus
829 driver needs to include requests for a
830 64-bit memory address in the
831 corresponding 32-bit memory pool.
833 @param[in] This The instance pointer of
834 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
836 @param[in] RootBridgeHandle The device handle of the PCI root bridge in
837 which the caller is interested. Type
838 EFI_HANDLE is defined in
839 InstallProtocolInterface() in the UEFI 2.0
842 @param[out] Attributes The pointer to attribte of root bridge, it is
845 @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
847 @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
849 @retval EFI_SUCCESS Success to get attribute of interested root
855 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
856 IN EFI_HANDLE RootBridgeHandle
,
857 OUT UINT64
*Attributes
861 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
862 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
864 if (Attributes
== NULL
) {
865 return EFI_INVALID_PARAMETER
;
868 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
869 List
= HostBridgeInstance
->Head
.ForwardLink
;
871 while (List
!= &HostBridgeInstance
->Head
) {
872 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
873 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
874 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
877 List
= List
->ForwardLink
;
881 // RootBridgeHandle is not an EFI_HANDLE
882 // that was returned on a previous call to GetNextRootBridge()
884 return EFI_INVALID_PARAMETER
;
888 Sets up the specified PCI root bridge for the bus enumeration process.
890 This member function sets up the root bridge for bus enumeration and returns
891 the PCI bus range over which the search should be performed in ACPI 2.0
892 resource descriptor format.
895 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
898 @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
900 @param[out] Configuration Pointer to the pointer to the PCI bus resource
903 @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
905 @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
907 @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
912 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
913 IN EFI_HANDLE RootBridgeHandle
,
914 OUT VOID
**Configuration
918 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
919 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
925 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
926 List
= HostBridgeInstance
->Head
.ForwardLink
;
928 while (List
!= &HostBridgeInstance
->Head
) {
929 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
930 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
932 // Set up the Root Bridge for Bus Enumeration
934 BusStart
= RootBridgeInstance
->BusBase
;
935 BusEnd
= RootBridgeInstance
->BusLimit
;
937 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
940 Buffer
= AllocatePool (
941 sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
942 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
944 if (Buffer
== NULL
) {
945 return EFI_OUT_OF_RESOURCES
;
948 Temp
= (UINT8
*)Buffer
;
950 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
951 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
952 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
953 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
954 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
955 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
956 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
957 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
958 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
959 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
=
960 BusEnd
- BusStart
+ 1;
962 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
963 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
964 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
966 *Configuration
= Buffer
;
969 List
= List
->ForwardLink
;
972 return EFI_INVALID_PARAMETER
;
976 Programs the PCI root bridge hardware so that it decodes the specified PCI
979 This member function programs the specified PCI root bridge to decode the bus
980 range that is specified by the input parameter Configuration.
981 The bus range information is specified in terms of the ACPI 2.0 resource
985 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
988 @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be
991 @param[in] Configuration The pointer to the PCI bus resource descriptor
993 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
996 @retval EFI_INVALID_PARAMETER Configuration is NULL.
998 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
999 2.0 resource descriptor.
1001 @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI
1002 2.0 bus resource descriptor.
1004 @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource
1005 descriptors other than bus descriptors.
1007 @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid
1008 ACPI resource descriptors.
1010 @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this
1013 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this
1016 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1018 @retval EFI_SUCCESS The bus range for the PCI root bridge was
1024 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1025 IN EFI_HANDLE RootBridgeHandle
,
1026 IN VOID
*Configuration
1030 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1031 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1037 if (Configuration
== NULL
) {
1038 return EFI_INVALID_PARAMETER
;
1041 Ptr
= Configuration
;
1044 // Check the Configuration is valid
1046 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1047 return EFI_INVALID_PARAMETER
;
1050 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
1051 return EFI_INVALID_PARAMETER
;
1054 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1055 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
1056 return EFI_INVALID_PARAMETER
;
1059 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1060 List
= HostBridgeInstance
->Head
.ForwardLink
;
1062 Ptr
= Configuration
;
1064 while (List
!= &HostBridgeInstance
->Head
) {
1065 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1066 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1067 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
1069 Desc
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
;
1070 BusStart
= (UINTN
)Desc
->AddrRangeMin
;
1071 BusLen
= (UINTN
)Desc
->AddrLen
;
1072 BusEnd
= BusStart
+ BusLen
- 1;
1074 if (BusStart
> BusEnd
) {
1075 return EFI_INVALID_PARAMETER
;
1078 if ((BusStart
< RootBridgeInstance
->BusBase
) ||
1079 (BusEnd
> RootBridgeInstance
->BusLimit
)) {
1080 return EFI_INVALID_PARAMETER
;
1084 // Update the Bus Range
1086 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
1087 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
1088 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
1091 // Program the Root Bridge Hardware
1097 List
= List
->ForwardLink
;
1100 return EFI_INVALID_PARAMETER
;
1105 Submits the I/O and memory resource requirements for the specified PCI root
1108 This function is used to submit all the I/O and memory resources that are
1109 required by the specified PCI root bridge. The input parameter Configuration
1110 is used to specify the following:
1111 - The various types of resources that are required
1112 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1114 @param[in] This Pointer to the
1115 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1118 @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory
1119 resource requirements are being submitted.
1121 @param[in] Configuration The pointer to the PCI I/O and PCI memory
1122 resource descriptor.
1124 @retval EFI_SUCCESS The I/O and memory resource requests for a PCI
1125 root bridge were accepted.
1127 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1130 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1132 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
1133 2.0 resource descriptor.
1135 @retval EFI_INVALID_PARAMETER Configuration includes requests for one or
1136 more resource types that are not supported by
1137 this PCI root bridge. This error will happen
1138 if the caller did not combine resources
1139 according to Attributes that were returned by
1140 GetAllocAttributes().
1142 @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
1144 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI
1147 @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for
1148 this PCI root bridge.
1153 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1154 IN EFI_HANDLE RootBridgeHandle
,
1155 IN VOID
*Configuration
1159 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1160 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1162 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1167 // Check the input parameter: Configuration
1169 if (Configuration
== NULL
) {
1170 return EFI_INVALID_PARAMETER
;
1173 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1174 List
= HostBridgeInstance
->Head
.ForwardLink
;
1176 Temp
= (UINT8
*)Configuration
;
1177 while ( *Temp
== 0x8A) {
1178 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1180 if (*Temp
!= 0x79) {
1181 return EFI_INVALID_PARAMETER
;
1184 Temp
= (UINT8
*)Configuration
;
1185 while (List
!= &HostBridgeInstance
->Head
) {
1186 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1187 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1188 while ( *Temp
== 0x8A) {
1189 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1192 // Check Address Length
1194 if (Ptr
->AddrLen
> 0xffffffff) {
1195 return EFI_INVALID_PARAMETER
;
1199 // Check address range alignment
1201 if (Ptr
->AddrRangeMax
>= 0xffffffff ||
1202 Ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (
1203 Ptr
->AddrRangeMax
+ 1) - 1)) {
1204 return EFI_INVALID_PARAMETER
;
1207 switch (Ptr
->ResType
) {
1212 // Check invalid Address Sapce Granularity
1214 if (Ptr
->AddrSpaceGranularity
!= 32) {
1215 return EFI_INVALID_PARAMETER
;
1219 // check the memory resource request is supported by PCI root bridge
1221 if (RootBridgeInstance
->RootBridgeAttrib
==
1222 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
1223 Ptr
->SpecificFlag
== 0x06) {
1224 return EFI_INVALID_PARAMETER
;
1227 AddrLen
= Ptr
->AddrLen
;
1228 Alignment
= Ptr
->AddrRangeMax
;
1229 if (Ptr
->AddrSpaceGranularity
== 32) {
1230 if (Ptr
->SpecificFlag
== 0x06) {
1234 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
=
1237 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1238 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
=
1240 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
=
1242 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1246 if (Ptr
->AddrSpaceGranularity
== 64) {
1247 if (Ptr
->SpecificFlag
== 0x06) {
1248 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
=
1251 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
=
1258 AddrLen
= (UINTN
) Ptr
->AddrLen
;
1259 Alignment
= (UINTN
) Ptr
->AddrRangeMax
;
1260 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
1261 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
1262 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
1263 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1270 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1276 List
= List
->ForwardLink
;
1279 return EFI_INVALID_PARAMETER
;
1283 Returns the proposed resource settings for the specified PCI root bridge.
1285 This member function returns the proposed resource settings for the
1286 specified PCI root bridge. The proposed resource settings are prepared when
1287 NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.
1288 The output parameter Configuration specifies the following:
1289 - The various types of resources, excluding bus resources, that are
1291 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1293 @param[in] This Pointer to the
1294 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1297 @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is
1298 defined in InstallProtocolInterface() in the
1299 UEFI 2.0 Specification.
1301 @param[out] Configuration The pointer to the pointer to the PCI I/O and
1302 memory resource descriptor.
1304 @retval EFI_SUCCESS The requested parameters were returned.
1306 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1309 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1311 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1316 GetProposedResources(
1317 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1318 IN EFI_HANDLE RootBridgeHandle
,
1319 OUT VOID
**Configuration
1323 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1324 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1329 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1335 // Get the Host Bridge Instance from the resource allocation protocol
1337 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1338 List
= HostBridgeInstance
->Head
.ForwardLink
;
1341 // Enumerate the root bridges in this host bridge
1343 while (List
!= &HostBridgeInstance
->Head
) {
1344 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1345 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1346 for (Index
= 0; Index
< TypeBus
; Index
++) {
1347 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1353 return EFI_INVALID_PARAMETER
;
1356 Buffer
= AllocateZeroPool (
1357 Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
1358 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
1360 if (Buffer
== NULL
) {
1361 return EFI_OUT_OF_RESOURCES
;
1365 for (Index
= 0; Index
< TypeBus
; Index
++) {
1366 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1367 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1368 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1380 Ptr
->SpecificFlag
= 0;
1381 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1382 Ptr
->AddrRangeMax
= 0;
1383 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1384 EFI_RESOURCE_SATISFIED
:
1386 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1397 Ptr
->SpecificFlag
= 0;
1398 Ptr
->AddrSpaceGranularity
= 32;
1399 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1400 Ptr
->AddrRangeMax
= 0;
1401 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1402 EFI_RESOURCE_SATISFIED
:
1404 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1409 // Prefetch memory 32
1415 Ptr
->SpecificFlag
= 6;
1416 Ptr
->AddrSpaceGranularity
= 32;
1417 Ptr
->AddrRangeMin
= 0;
1418 Ptr
->AddrRangeMax
= 0;
1419 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1431 Ptr
->SpecificFlag
= 0;
1432 Ptr
->AddrSpaceGranularity
= 64;
1433 Ptr
->AddrRangeMin
= 0;
1434 Ptr
->AddrRangeMax
= 0;
1435 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1441 // Prefetch memory 64
1447 Ptr
->SpecificFlag
= 6;
1448 Ptr
->AddrSpaceGranularity
= 64;
1449 Ptr
->AddrRangeMin
= 0;
1450 Ptr
->AddrRangeMax
= 0;
1451 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1456 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1460 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1461 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1463 *Configuration
= Buffer
;
1468 List
= List
->ForwardLink
;
1471 return EFI_INVALID_PARAMETER
;
1475 Provides the hooks from the PCI bus driver to every PCI controller
1476 (device/function) at various stages of the PCI enumeration process that allow
1477 the host bridge driver to preinitialize individual PCI controllers before
1480 This function is called during the PCI enumeration process. No specific
1481 action is expected from this member function. It allows the host bridge
1482 driver to preinitialize individual PCI controllers before enumeration.
1484 @param This Pointer to the
1485 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1488 @param RootBridgeHandle The associated PCI root bridge handle. Type
1489 EFI_HANDLE is defined in InstallProtocolInterface()
1490 in the UEFI 2.0 Specification.
1492 @param PciAddress The address of the PCI device on the PCI bus. This
1493 address can be passed to the
1494 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to
1495 access the PCI configuration space of the device.
1496 See Table 12-1 in the UEFI 2.0 Specification for the
1498 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
1500 @param Phase The phase of the PCI device enumeration.
1502 @retval EFI_SUCCESS The requested parameters were returned.
1504 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1507 @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined
1509 EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
1511 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1512 The PCI enumerator should not enumerate this
1513 device, including its child devices if it is
1514 a PCI-to-PCI bridge.
1518 PreprocessController (
1519 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1520 IN EFI_HANDLE RootBridgeHandle
,
1521 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1522 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1525 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1526 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1529 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1530 List
= HostBridgeInstance
->Head
.ForwardLink
;
1533 // Enumerate the root bridges in this host bridge
1535 while (List
!= &HostBridgeInstance
->Head
) {
1536 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1537 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1540 List
= List
->ForwardLink
;
1542 if (List
== &HostBridgeInstance
->Head
) {
1543 return EFI_INVALID_PARAMETER
;
1546 if ((UINT32
)Phase
> EfiPciBeforeResourceCollection
) {
1547 return EFI_INVALID_PARAMETER
;