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
,
47 // Hard code: Root Bridge's resource aperture
50 PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture
[1] = {
51 {0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}
54 EFI_HANDLE mDriverImageHandle
;
56 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
57 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
58 NULL
, // HostBridgeHandle
59 0, // RootBridgeNumber
61 FALSE
, // ResourceSubiteed
80 Allocate and initialize a root bridge.
82 param[in] RootBusNumber The bus number of the root bus (root bridge) to
84 RootBusNumber is expected to fall into the valid
85 offset range of mResAperture.
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 EFI_HANDLE HostBridgeHandle
,
113 OUT PCI_ROOT_BRIDGE_INSTANCE
**RootBus
116 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
119 PrivateData
= AllocateZeroPool (sizeof *PrivateData
);
120 if (PrivateData
== NULL
) {
121 return EFI_OUT_OF_RESOURCES
;
124 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
126 CopyMem (&PrivateData
->DevicePath
, &mRootBridgeDevicePathTemplate
,
127 sizeof mRootBridgeDevicePathTemplate
);
128 PrivateData
->DevicePath
.AcpiDevicePath
.UID
= RootBusNumber
;
131 // The function call below allocates no resources and performs no actions
132 // that have to be rolled back on later failure. It always succeeds.
134 Status
= RootBridgeConstructor (&PrivateData
->Io
, HostBridgeHandle
,
135 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
,
136 &mResAperture
[RootBusNumber
]);
137 ASSERT_EFI_ERROR (Status
);
139 Status
= gBS
->InstallMultipleProtocolInterfaces (&PrivateData
->Handle
,
140 &gEfiDevicePathProtocolGuid
, &PrivateData
->DevicePath
,
141 &gEfiPciRootBridgeIoProtocolGuid
, &PrivateData
->Io
,
143 if (EFI_ERROR (Status
)) {
144 goto FreePrivateData
;
147 *RootBus
= PrivateData
;
151 FreePool (PrivateData
);
157 Entry point of this driver
159 @param ImageHandle Handle of driver image
160 @param SystemTable Point to EFI_SYSTEM_TABLE
162 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
163 @retval EFI_DEVICE_ERROR Can not install the protocol instance
164 @retval EFI_SUCCESS Success to initialize the Pci host bridge.
168 InitializePciHostBridge (
169 IN EFI_HANDLE ImageHandle
,
170 IN EFI_SYSTEM_TABLE
*SystemTable
174 UINTN RootBridgeNumber
;
175 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
176 PCI_ROOT_BRIDGE_INSTANCE
*RootBus
;
178 mDriverImageHandle
= ImageHandle
;
181 // Create Host Bridge Device Handle
183 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
),
184 &mPciHostBridgeInstanceTemplate
);
185 if (HostBridge
== NULL
) {
186 return EFI_OUT_OF_RESOURCES
;
189 HostBridge
->RootBridgeNumber
= 1;
190 InitializeListHead (&HostBridge
->Head
);
192 Status
= gBS
->InstallMultipleProtocolInterfaces (
193 &HostBridge
->HostBridgeHandle
,
194 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
195 &HostBridge
->ResAlloc
,
198 if (EFI_ERROR (Status
)) {
199 FreePool (HostBridge
);
200 return EFI_DEVICE_ERROR
;
203 for (RootBridgeNumber
= 0;
204 RootBridgeNumber
< HostBridge
->RootBridgeNumber
;
205 ++RootBridgeNumber
) {
206 Status
= InitRootBridge (
207 (UINT8
)RootBridgeNumber
,
208 HostBridge
->HostBridgeHandle
,
211 if (EFI_ERROR (Status
)) {
214 InsertTailList (&HostBridge
->Head
, &RootBus
->Link
);
222 These are the notifications from the PCI bus driver that it is about to enter
223 a certain phase of the PCI enumeration process.
225 This member function can be used to notify the host bridge driver to perform
226 specific actions, including any chipset-specific initialization, so that the
227 chipset is ready to enter the next phase. Eight notification points are
228 defined at this time. See belows:
230 EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures
231 and internal data structures. The PCI
232 enumerator should issue this
233 notification before starting a fresh
234 enumeration process. Enumeration
235 cannot be restarted after sending any
236 other notification such as
237 EfiPciHostBridgeBeginBusAllocation.
239 EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to
240 begin. No specific action is required
241 here. This notification can be used to
242 perform any chipset-specific
245 EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming
246 phase is complete. No specific action
247 is required here. This notification
248 can be used to perform any
249 chipset-specific programming.
251 EfiPciHostBridgeBeginResourceAllocation
252 The resource allocation phase is about
253 to begin. No specific action is
254 required here. This notification can
255 be used to perform any
256 chipset-specific programming.
258 EfiPciHostBridgeAllocateResources Allocates resources per previously
259 submitted requests for all the PCI
260 root bridges. These resource settings
261 are returned on the next call to
262 GetProposedResources(). Before calling
263 NotifyPhase() with a Phase of
264 EfiPciHostBridgeAllocateResource, the
265 PCI bus enumerator is responsible for
266 gathering I/O and memory requests for
267 all the PCI root bridges and
268 submitting these requests using
269 SubmitResources(). This function pads
270 the resource amount to suit the root
271 bridge hardware, takes care of
272 dependencies between the PCI root
273 bridges, and calls the Global
274 Coherency Domain (GCD) with the
275 allocation request. In the case of
276 padding, the allocated range could be
277 bigger than what was requested.
279 EfiPciHostBridgeSetResources Programs the host bridge hardware to
280 decode previously allocated resources
281 (proposed resources) for all the PCI
282 root bridges. After the hardware is
283 programmed, reassigning resources will
284 not be supported. The bus settings are
287 EfiPciHostBridgeFreeResources Deallocates resources that were
288 previously allocated for all the PCI
289 root bridges and resets the I/O and
290 memory apertures to their initial
291 state. The bus settings are not
292 affected. If the request to allocate
293 resources fails, the PCI enumerator
294 can use this notification to
295 deallocate previous resources, adjust
296 the requests, and retry allocation.
298 EfiPciHostBridgeEndResourceAllocation The resource allocation phase is
299 completed. No specific action is
300 required here. This notification can
301 be used to perform any chipsetspecific
304 @param[in] This The instance pointer of
305 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
307 @param[in] Phase The phase during enumeration
309 @retval EFI_NOT_READY This phase cannot be entered at this time. For
310 example, this error is valid for a Phase of
311 EfiPciHostBridgeAllocateResources if
312 SubmitResources() has not been called for one
313 or more PCI root bridges before this call
315 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
316 This error is valid for a Phase of
317 EfiPciHostBridgeSetResources.
319 @retval EFI_INVALID_PARAMETER Invalid phase parameter
321 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
322 lack of resources. This error is valid for a
323 Phase of EfiPciHostBridgeAllocateResources if
324 the previously submitted resource requests
325 cannot be fulfilled or were only partially
328 @retval EFI_SUCCESS The notification was accepted without any
334 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
335 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
338 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
339 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
340 PCI_RESOURCE_TYPE Index
;
342 EFI_PHYSICAL_ADDRESS BaseAddress
;
344 UINTN BitsOfAlignment
;
346 EFI_STATUS ReturnStatus
;
348 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
352 case EfiPciHostBridgeBeginEnumeration
:
353 if (HostBridgeInstance
->CanRestarted
) {
355 // Reset the Each Root Bridge
357 List
= HostBridgeInstance
->Head
.ForwardLink
;
359 while (List
!= &HostBridgeInstance
->Head
) {
360 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
361 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
362 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
363 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
364 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
365 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
368 List
= List
->ForwardLink
;
371 HostBridgeInstance
->ResourceSubmited
= FALSE
;
372 HostBridgeInstance
->CanRestarted
= TRUE
;
377 return EFI_NOT_READY
;
381 case EfiPciHostBridgeEndEnumeration
:
384 case EfiPciHostBridgeBeginBusAllocation
:
386 // No specific action is required here, can perform any chipset specific
389 HostBridgeInstance
->CanRestarted
= FALSE
;
392 case EfiPciHostBridgeEndBusAllocation
:
394 // No specific action is required here, can perform any chipset specific
397 //HostBridgeInstance->CanRestarted = FALSE;
400 case EfiPciHostBridgeBeginResourceAllocation
:
402 // No specific action is required here, can perform any chipset specific
405 //HostBridgeInstance->CanRestarted = FALSE;
408 case EfiPciHostBridgeAllocateResources
:
409 ReturnStatus
= EFI_SUCCESS
;
410 if (HostBridgeInstance
->ResourceSubmited
) {
412 // Take care of the resource dependencies between the root bridges
414 List
= HostBridgeInstance
->Head
.ForwardLink
;
416 while (List
!= &HostBridgeInstance
->Head
) {
417 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
418 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
419 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
421 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
424 // Get the number of '1' in Alignment.
427 (UINTN
)(HighBitSet64 (
428 RootBridgeInstance
->ResAllocNode
[Index
].Alignment
435 // It is impossible for this chipset to align 0xFFFF for IO16
438 if (BitsOfAlignment
>= 16) {
442 Status
= gDS
->AllocateIoSpace (
443 EfiGcdAllocateAnySearchBottomUp
,
452 if (!EFI_ERROR (Status
)) {
453 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
455 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
458 ReturnStatus
= Status
;
459 if (Status
!= EFI_OUT_OF_RESOURCES
) {
460 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
469 // It is impossible for this chipset to align 0xFFFFFFFF for
474 if (BitsOfAlignment
>= 32) {
478 Status
= gDS
->AllocateMemorySpace (
479 EfiGcdAllocateAnySearchBottomUp
,
480 EfiGcdMemoryTypeMemoryMappedIo
,
488 if (!EFI_ERROR (Status
)) {
489 // We were able to allocate the PCI memory
490 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
492 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
496 // Not able to allocate enough PCI memory
497 ReturnStatus
= Status
;
499 if (Status
!= EFI_OUT_OF_RESOURCES
) {
500 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
509 ReturnStatus
= EFI_ABORTED
;
518 List
= List
->ForwardLink
;
524 return EFI_NOT_READY
;
528 case EfiPciHostBridgeSetResources
:
531 case EfiPciHostBridgeFreeResources
:
532 ReturnStatus
= EFI_SUCCESS
;
533 List
= HostBridgeInstance
->Head
.ForwardLink
;
534 while (List
!= &HostBridgeInstance
->Head
) {
535 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
536 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
537 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
538 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
539 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
543 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
544 if (EFI_ERROR (Status
)) {
545 ReturnStatus
= Status
;
550 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
551 if (EFI_ERROR (Status
)) {
552 ReturnStatus
= Status
;
570 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
571 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
572 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
573 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
577 List
= List
->ForwardLink
;
580 HostBridgeInstance
->ResourceSubmited
= FALSE
;
581 HostBridgeInstance
->CanRestarted
= TRUE
;
584 case EfiPciHostBridgeEndResourceAllocation
:
585 HostBridgeInstance
->CanRestarted
= FALSE
;
589 return EFI_INVALID_PARAMETER
;
596 Return the device handle of the next PCI root bridge that is associated with
599 This function is called multiple times to retrieve the device handles of all
600 the PCI root bridges that are associated with this PCI host bridge. Each PCI
601 host bridge is associated with one or more PCI root bridges. On each call,
602 the handle that was returned by the previous call is passed into the
603 interface, and on output the interface returns the device handle of the next
604 PCI root bridge. The caller can use the handle to obtain the instance of the
605 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more
606 PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI
607 enumerator must enumerate the PCI root bridges in the order that they are
608 returned by this function.
610 For D945 implementation, there is only one root bridge in PCI host bridge.
612 @param[in] This The instance pointer of
613 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
615 @param[in, out] RootBridgeHandle Returns the device handle of the next PCI
618 @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then
619 return the first Rootbridge handle of the
620 specific Host bridge and return EFI_SUCCESS.
622 @retval EFI_NOT_FOUND Can not find the any more root bridge in
623 specific host bridge.
625 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
626 returned on a previous call to
632 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
633 IN OUT EFI_HANDLE
*RootBridgeHandle
636 BOOLEAN NoRootBridge
;
638 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
639 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
642 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
643 List
= HostBridgeInstance
->Head
.ForwardLink
;
646 while (List
!= &HostBridgeInstance
->Head
) {
647 NoRootBridge
= FALSE
;
648 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
649 if (*RootBridgeHandle
== NULL
) {
651 // Return the first Root Bridge Handle of the Host Bridge
653 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
656 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
660 List
= List
->ForwardLink
;
661 if (List
!=&HostBridgeInstance
->Head
) {
662 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
663 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
666 return EFI_NOT_FOUND
;
671 List
= List
->ForwardLink
;
675 return EFI_NOT_FOUND
;
677 return EFI_INVALID_PARAMETER
;
682 Returns the allocation attributes of a PCI root bridge.
684 The function returns the allocation attributes of a specific PCI root bridge.
685 The attributes can vary from one PCI root bridge to another. These attributes
686 are different from the decode-related attributes that are returned by the
687 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
688 RootBridgeHandle parameter is used to specify the instance of the PCI root
689 bridge. The device handles of all the root bridges that are associated with
690 this host bridge must be obtained by calling GetNextRootBridge(). The
691 attributes are static in the sense that they do not change during or after
692 the enumeration process. The hardware may provide mechanisms to change the
693 attributes on the fly, but such changes must be completed before
694 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted
695 values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
696 "Related Definitions" below. The caller uses these attributes to combine
697 multiple resource requests.
699 For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI
700 bus enumerator needs to include requests for the prefetchable memory in the
701 nonprefetchable memory pool and not request any prefetchable memory.
703 Attribute Description
704 ------------------------------------ ---------------------------------------
705 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root
706 bridge does not support separate
707 windows for nonprefetchable and
708 prefetchable memory. A PCI bus driver
709 needs to include requests for
710 prefetchable memory in the
711 nonprefetchable memory pool.
713 EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root
714 bridge supports 64-bit memory windows.
715 If this bit is not set, the PCI bus
716 driver needs to include requests for a
717 64-bit memory address in the
718 corresponding 32-bit memory pool.
720 @param[in] This The instance pointer of
721 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
723 @param[in] RootBridgeHandle The device handle of the PCI root bridge in
724 which the caller is interested. Type
725 EFI_HANDLE is defined in
726 InstallProtocolInterface() in the UEFI 2.0
729 @param[out] Attributes The pointer to attribte of root bridge, it is
732 @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
734 @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
736 @retval EFI_SUCCESS Success to get attribute of interested root
742 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
743 IN EFI_HANDLE RootBridgeHandle
,
744 OUT UINT64
*Attributes
748 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
749 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
751 if (Attributes
== NULL
) {
752 return EFI_INVALID_PARAMETER
;
755 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
756 List
= HostBridgeInstance
->Head
.ForwardLink
;
758 while (List
!= &HostBridgeInstance
->Head
) {
759 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
760 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
761 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
764 List
= List
->ForwardLink
;
768 // RootBridgeHandle is not an EFI_HANDLE
769 // that was returned on a previous call to GetNextRootBridge()
771 return EFI_INVALID_PARAMETER
;
775 Sets up the specified PCI root bridge for the bus enumeration process.
777 This member function sets up the root bridge for bus enumeration and returns
778 the PCI bus range over which the search should be performed in ACPI 2.0
779 resource descriptor format.
782 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
785 @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
787 @param[out] Configuration Pointer to the pointer to the PCI bus resource
790 @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
792 @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
794 @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
799 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
800 IN EFI_HANDLE RootBridgeHandle
,
801 OUT VOID
**Configuration
805 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
806 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
812 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
813 List
= HostBridgeInstance
->Head
.ForwardLink
;
815 while (List
!= &HostBridgeInstance
->Head
) {
816 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
817 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
819 // Set up the Root Bridge for Bus Enumeration
821 BusStart
= RootBridgeInstance
->BusBase
;
822 BusEnd
= RootBridgeInstance
->BusLimit
;
824 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
827 Buffer
= AllocatePool (
828 sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
829 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
831 if (Buffer
== NULL
) {
832 return EFI_OUT_OF_RESOURCES
;
835 Temp
= (UINT8
*)Buffer
;
837 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
838 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
839 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
840 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
841 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
842 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
843 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
844 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
845 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
846 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
=
847 BusEnd
- BusStart
+ 1;
849 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
850 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
851 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
853 *Configuration
= Buffer
;
856 List
= List
->ForwardLink
;
859 return EFI_INVALID_PARAMETER
;
863 Programs the PCI root bridge hardware so that it decodes the specified PCI
866 This member function programs the specified PCI root bridge to decode the bus
867 range that is specified by the input parameter Configuration.
868 The bus range information is specified in terms of the ACPI 2.0 resource
872 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
875 @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be
878 @param[in] Configuration The pointer to the PCI bus resource descriptor
880 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
883 @retval EFI_INVALID_PARAMETER Configuration is NULL.
885 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
886 2.0 resource descriptor.
888 @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI
889 2.0 bus resource descriptor.
891 @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource
892 descriptors other than bus descriptors.
894 @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid
895 ACPI resource descriptors.
897 @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this
900 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this
903 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
905 @retval EFI_SUCCESS The bus range for the PCI root bridge was
911 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
912 IN EFI_HANDLE RootBridgeHandle
,
913 IN VOID
*Configuration
917 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
918 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
924 if (Configuration
== NULL
) {
925 return EFI_INVALID_PARAMETER
;
931 // Check the Configuration is valid
933 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
934 return EFI_INVALID_PARAMETER
;
937 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
938 return EFI_INVALID_PARAMETER
;
941 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
942 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
943 return EFI_INVALID_PARAMETER
;
946 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
947 List
= HostBridgeInstance
->Head
.ForwardLink
;
951 while (List
!= &HostBridgeInstance
->Head
) {
952 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
953 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
954 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
956 Desc
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
;
957 BusStart
= (UINTN
)Desc
->AddrRangeMin
;
958 BusLen
= (UINTN
)Desc
->AddrLen
;
959 BusEnd
= BusStart
+ BusLen
- 1;
961 if (BusStart
> BusEnd
) {
962 return EFI_INVALID_PARAMETER
;
965 if ((BusStart
< RootBridgeInstance
->BusBase
) ||
966 (BusEnd
> RootBridgeInstance
->BusLimit
)) {
967 return EFI_INVALID_PARAMETER
;
971 // Update the Bus Range
973 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
974 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
975 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
978 // Program the Root Bridge Hardware
984 List
= List
->ForwardLink
;
987 return EFI_INVALID_PARAMETER
;
992 Submits the I/O and memory resource requirements for the specified PCI root
995 This function is used to submit all the I/O and memory resources that are
996 required by the specified PCI root bridge. The input parameter Configuration
997 is used to specify the following:
998 - The various types of resources that are required
999 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1001 @param[in] This Pointer to the
1002 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1005 @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory
1006 resource requirements are being submitted.
1008 @param[in] Configuration The pointer to the PCI I/O and PCI memory
1009 resource descriptor.
1011 @retval EFI_SUCCESS The I/O and memory resource requests for a PCI
1012 root bridge were accepted.
1014 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1017 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1019 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
1020 2.0 resource descriptor.
1022 @retval EFI_INVALID_PARAMETER Configuration includes requests for one or
1023 more resource types that are not supported by
1024 this PCI root bridge. This error will happen
1025 if the caller did not combine resources
1026 according to Attributes that were returned by
1027 GetAllocAttributes().
1029 @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
1031 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI
1034 @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for
1035 this PCI root bridge.
1040 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1041 IN EFI_HANDLE RootBridgeHandle
,
1042 IN VOID
*Configuration
1046 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1047 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1049 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1054 // Check the input parameter: Configuration
1056 if (Configuration
== NULL
) {
1057 return EFI_INVALID_PARAMETER
;
1060 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1061 List
= HostBridgeInstance
->Head
.ForwardLink
;
1063 Temp
= (UINT8
*)Configuration
;
1064 while ( *Temp
== 0x8A) {
1065 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1067 if (*Temp
!= 0x79) {
1068 return EFI_INVALID_PARAMETER
;
1071 Temp
= (UINT8
*)Configuration
;
1072 while (List
!= &HostBridgeInstance
->Head
) {
1073 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1074 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1075 while ( *Temp
== 0x8A) {
1076 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1079 // Check Address Length
1081 if (Ptr
->AddrLen
> 0xffffffff) {
1082 return EFI_INVALID_PARAMETER
;
1086 // Check address range alignment
1088 if (Ptr
->AddrRangeMax
>= 0xffffffff ||
1089 Ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (
1090 Ptr
->AddrRangeMax
+ 1) - 1)) {
1091 return EFI_INVALID_PARAMETER
;
1094 switch (Ptr
->ResType
) {
1099 // Check invalid Address Sapce Granularity
1101 if (Ptr
->AddrSpaceGranularity
!= 32) {
1102 return EFI_INVALID_PARAMETER
;
1106 // check the memory resource request is supported by PCI root bridge
1108 if (RootBridgeInstance
->RootBridgeAttrib
==
1109 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
1110 Ptr
->SpecificFlag
== 0x06) {
1111 return EFI_INVALID_PARAMETER
;
1114 AddrLen
= Ptr
->AddrLen
;
1115 Alignment
= Ptr
->AddrRangeMax
;
1116 if (Ptr
->AddrSpaceGranularity
== 32) {
1117 if (Ptr
->SpecificFlag
== 0x06) {
1121 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
=
1124 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1125 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
=
1127 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
=
1129 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1133 if (Ptr
->AddrSpaceGranularity
== 64) {
1134 if (Ptr
->SpecificFlag
== 0x06) {
1135 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
=
1138 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
=
1145 AddrLen
= (UINTN
) Ptr
->AddrLen
;
1146 Alignment
= (UINTN
) Ptr
->AddrRangeMax
;
1147 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
1148 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
1149 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
1150 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1157 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1163 List
= List
->ForwardLink
;
1166 return EFI_INVALID_PARAMETER
;
1170 Returns the proposed resource settings for the specified PCI root bridge.
1172 This member function returns the proposed resource settings for the
1173 specified PCI root bridge. The proposed resource settings are prepared when
1174 NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.
1175 The output parameter Configuration specifies the following:
1176 - The various types of resources, excluding bus resources, that are
1178 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1180 @param[in] This Pointer to the
1181 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1184 @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is
1185 defined in InstallProtocolInterface() in the
1186 UEFI 2.0 Specification.
1188 @param[out] Configuration The pointer to the pointer to the PCI I/O and
1189 memory resource descriptor.
1191 @retval EFI_SUCCESS The requested parameters were returned.
1193 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1196 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1198 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1203 GetProposedResources(
1204 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1205 IN EFI_HANDLE RootBridgeHandle
,
1206 OUT VOID
**Configuration
1210 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1211 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1216 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1222 // Get the Host Bridge Instance from the resource allocation protocol
1224 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1225 List
= HostBridgeInstance
->Head
.ForwardLink
;
1228 // Enumerate the root bridges in this host bridge
1230 while (List
!= &HostBridgeInstance
->Head
) {
1231 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1232 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1233 for (Index
= 0; Index
< TypeBus
; Index
++) {
1234 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1240 return EFI_INVALID_PARAMETER
;
1243 Buffer
= AllocateZeroPool (
1244 Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
1245 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
1247 if (Buffer
== NULL
) {
1248 return EFI_OUT_OF_RESOURCES
;
1252 for (Index
= 0; Index
< TypeBus
; Index
++) {
1253 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1254 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1255 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1267 Ptr
->SpecificFlag
= 0;
1268 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1269 Ptr
->AddrRangeMax
= 0;
1270 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1271 EFI_RESOURCE_SATISFIED
:
1273 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1284 Ptr
->SpecificFlag
= 0;
1285 Ptr
->AddrSpaceGranularity
= 32;
1286 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1287 Ptr
->AddrRangeMax
= 0;
1288 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1289 EFI_RESOURCE_SATISFIED
:
1291 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1296 // Prefetch memory 32
1302 Ptr
->SpecificFlag
= 6;
1303 Ptr
->AddrSpaceGranularity
= 32;
1304 Ptr
->AddrRangeMin
= 0;
1305 Ptr
->AddrRangeMax
= 0;
1306 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1318 Ptr
->SpecificFlag
= 0;
1319 Ptr
->AddrSpaceGranularity
= 64;
1320 Ptr
->AddrRangeMin
= 0;
1321 Ptr
->AddrRangeMax
= 0;
1322 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1328 // Prefetch memory 64
1334 Ptr
->SpecificFlag
= 6;
1335 Ptr
->AddrSpaceGranularity
= 64;
1336 Ptr
->AddrRangeMin
= 0;
1337 Ptr
->AddrRangeMax
= 0;
1338 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1343 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1347 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1348 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1350 *Configuration
= Buffer
;
1355 List
= List
->ForwardLink
;
1358 return EFI_INVALID_PARAMETER
;
1362 Provides the hooks from the PCI bus driver to every PCI controller
1363 (device/function) at various stages of the PCI enumeration process that allow
1364 the host bridge driver to preinitialize individual PCI controllers before
1367 This function is called during the PCI enumeration process. No specific
1368 action is expected from this member function. It allows the host bridge
1369 driver to preinitialize individual PCI controllers before enumeration.
1371 @param This Pointer to the
1372 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1375 @param RootBridgeHandle The associated PCI root bridge handle. Type
1376 EFI_HANDLE is defined in InstallProtocolInterface()
1377 in the UEFI 2.0 Specification.
1379 @param PciAddress The address of the PCI device on the PCI bus. This
1380 address can be passed to the
1381 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to
1382 access the PCI configuration space of the device.
1383 See Table 12-1 in the UEFI 2.0 Specification for the
1385 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
1387 @param Phase The phase of the PCI device enumeration.
1389 @retval EFI_SUCCESS The requested parameters were returned.
1391 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1394 @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined
1396 EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
1398 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1399 The PCI enumerator should not enumerate this
1400 device, including its child devices if it is
1401 a PCI-to-PCI bridge.
1405 PreprocessController (
1406 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1407 IN EFI_HANDLE RootBridgeHandle
,
1408 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1409 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1412 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1413 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1416 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1417 List
= HostBridgeInstance
->Head
.ForwardLink
;
1420 // Enumerate the root bridges in this host bridge
1422 while (List
!= &HostBridgeInstance
->Head
) {
1423 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1424 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1427 List
= List
->ForwardLink
;
1429 if (List
== &HostBridgeInstance
->Head
) {
1430 return EFI_INVALID_PARAMETER
;
1433 if ((UINT32
)Phase
> EfiPciBeforeResourceCollection
) {
1434 return EFI_INVALID_PARAMETER
;