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"
21 // Hard code: Root Bridge's device path
22 // Root Bridge's resource aperture
25 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath
[1] = {
32 (UINT8
) (sizeof(ACPI_HID_DEVICE_PATH
)),
33 (UINT8
) ((sizeof(ACPI_HID_DEVICE_PATH
)) >> 8)
42 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
44 END_DEVICE_PATH_LENGTH
,
51 PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture
[1] = {
52 {0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}
55 EFI_HANDLE mDriverImageHandle
;
57 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
58 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
59 NULL
, // HostBridgeHandle
60 0, // RootBridgeNumber
62 FALSE
, // ResourceSubiteed
81 Entry point of this driver
83 @param ImageHandle Handle of driver image
84 @param SystemTable Point to EFI_SYSTEM_TABLE
86 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
87 @retval EFI_DEVICE_ERROR Can not install the protocol instance
88 @retval EFI_SUCCESS Success to initialize the Pci host bridge.
92 InitializePciHostBridge (
93 IN EFI_HANDLE ImageHandle
,
94 IN EFI_SYSTEM_TABLE
*SystemTable
99 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
100 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
102 mDriverImageHandle
= ImageHandle
;
105 // Create Host Bridge Device Handle
107 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
),
108 &mPciHostBridgeInstanceTemplate
);
109 if (HostBridge
== NULL
) {
110 return EFI_OUT_OF_RESOURCES
;
113 HostBridge
->RootBridgeNumber
= 1;
114 InitializeListHead (&HostBridge
->Head
);
116 Status
= gBS
->InstallMultipleProtocolInterfaces (
117 &HostBridge
->HostBridgeHandle
,
118 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
119 &HostBridge
->ResAlloc
,
122 if (EFI_ERROR (Status
)) {
123 FreePool (HostBridge
);
124 return EFI_DEVICE_ERROR
;
128 // Create Root Bridge Device Handle in this Host Bridge
131 for (Loop2
= 0; Loop2
< HostBridge
->RootBridgeNumber
; Loop2
++) {
132 PrivateData
= AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE
));
133 if (PrivateData
== NULL
) {
134 return EFI_OUT_OF_RESOURCES
;
137 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
138 PrivateData
->DevicePath
=
139 (EFI_DEVICE_PATH_PROTOCOL
*)&mEfiPciRootBridgeDevicePath
[Loop2
];
141 RootBridgeConstructor (
143 HostBridge
->HostBridgeHandle
,
144 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
,
148 Status
= gBS
->InstallMultipleProtocolInterfaces(
149 &PrivateData
->Handle
,
150 &gEfiDevicePathProtocolGuid
,
151 PrivateData
->DevicePath
,
152 &gEfiPciRootBridgeIoProtocolGuid
,
156 if (EFI_ERROR (Status
)) {
157 FreePool(PrivateData
);
158 return EFI_DEVICE_ERROR
;
161 InsertTailList (&HostBridge
->Head
, &PrivateData
->Link
);
169 These are the notifications from the PCI bus driver that it is about to enter
170 a certain phase of the PCI enumeration process.
172 This member function can be used to notify the host bridge driver to perform
173 specific actions, including any chipset-specific initialization, so that the
174 chipset is ready to enter the next phase. Eight notification points are
175 defined at this time. See belows:
177 EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures
178 and internal data structures. The PCI
179 enumerator should issue this
180 notification before starting a fresh
181 enumeration process. Enumeration
182 cannot be restarted after sending any
183 other notification such as
184 EfiPciHostBridgeBeginBusAllocation.
186 EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to
187 begin. No specific action is required
188 here. This notification can be used to
189 perform any chipset-specific
192 EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming
193 phase is complete. No specific action
194 is required here. This notification
195 can be used to perform any
196 chipset-specific programming.
198 EfiPciHostBridgeBeginResourceAllocation
199 The resource allocation phase is about
200 to begin. No specific action is
201 required here. This notification can
202 be used to perform any
203 chipset-specific programming.
205 EfiPciHostBridgeAllocateResources Allocates resources per previously
206 submitted requests for all the PCI
207 root bridges. These resource settings
208 are returned on the next call to
209 GetProposedResources(). Before calling
210 NotifyPhase() with a Phase of
211 EfiPciHostBridgeAllocateResource, the
212 PCI bus enumerator is responsible for
213 gathering I/O and memory requests for
214 all the PCI root bridges and
215 submitting these requests using
216 SubmitResources(). This function pads
217 the resource amount to suit the root
218 bridge hardware, takes care of
219 dependencies between the PCI root
220 bridges, and calls the Global
221 Coherency Domain (GCD) with the
222 allocation request. In the case of
223 padding, the allocated range could be
224 bigger than what was requested.
226 EfiPciHostBridgeSetResources Programs the host bridge hardware to
227 decode previously allocated resources
228 (proposed resources) for all the PCI
229 root bridges. After the hardware is
230 programmed, reassigning resources will
231 not be supported. The bus settings are
234 EfiPciHostBridgeFreeResources Deallocates resources that were
235 previously allocated for all the PCI
236 root bridges and resets the I/O and
237 memory apertures to their initial
238 state. The bus settings are not
239 affected. If the request to allocate
240 resources fails, the PCI enumerator
241 can use this notification to
242 deallocate previous resources, adjust
243 the requests, and retry allocation.
245 EfiPciHostBridgeEndResourceAllocation The resource allocation phase is
246 completed. No specific action is
247 required here. This notification can
248 be used to perform any chipsetspecific
251 @param[in] This The instance pointer of
252 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
254 @param[in] Phase The phase during enumeration
256 @retval EFI_NOT_READY This phase cannot be entered at this time. For
257 example, this error is valid for a Phase of
258 EfiPciHostBridgeAllocateResources if
259 SubmitResources() has not been called for one
260 or more PCI root bridges before this call
262 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
263 This error is valid for a Phase of
264 EfiPciHostBridgeSetResources.
266 @retval EFI_INVALID_PARAMETER Invalid phase parameter
268 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
269 lack of resources. This error is valid for a
270 Phase of EfiPciHostBridgeAllocateResources if
271 the previously submitted resource requests
272 cannot be fulfilled or were only partially
275 @retval EFI_SUCCESS The notification was accepted without any
281 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
282 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
285 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
286 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
287 PCI_RESOURCE_TYPE Index
;
289 EFI_PHYSICAL_ADDRESS BaseAddress
;
291 UINTN BitsOfAlignment
;
293 EFI_STATUS ReturnStatus
;
295 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
299 case EfiPciHostBridgeBeginEnumeration
:
300 if (HostBridgeInstance
->CanRestarted
) {
302 // Reset the Each Root Bridge
304 List
= HostBridgeInstance
->Head
.ForwardLink
;
306 while (List
!= &HostBridgeInstance
->Head
) {
307 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
308 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
309 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
310 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
311 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
312 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
315 List
= List
->ForwardLink
;
318 HostBridgeInstance
->ResourceSubmited
= FALSE
;
319 HostBridgeInstance
->CanRestarted
= TRUE
;
324 return EFI_NOT_READY
;
328 case EfiPciHostBridgeEndEnumeration
:
331 case EfiPciHostBridgeBeginBusAllocation
:
333 // No specific action is required here, can perform any chipset specific
336 HostBridgeInstance
->CanRestarted
= FALSE
;
339 case EfiPciHostBridgeEndBusAllocation
:
341 // No specific action is required here, can perform any chipset specific
344 //HostBridgeInstance->CanRestarted = FALSE;
347 case EfiPciHostBridgeBeginResourceAllocation
:
349 // No specific action is required here, can perform any chipset specific
352 //HostBridgeInstance->CanRestarted = FALSE;
355 case EfiPciHostBridgeAllocateResources
:
356 ReturnStatus
= EFI_SUCCESS
;
357 if (HostBridgeInstance
->ResourceSubmited
) {
359 // Take care of the resource dependencies between the root bridges
361 List
= HostBridgeInstance
->Head
.ForwardLink
;
363 while (List
!= &HostBridgeInstance
->Head
) {
364 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
365 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
366 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
368 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
371 // Get the number of '1' in Alignment.
374 (UINTN
)(HighBitSet64 (
375 RootBridgeInstance
->ResAllocNode
[Index
].Alignment
382 // It is impossible for this chipset to align 0xFFFF for IO16
385 if (BitsOfAlignment
>= 16) {
389 Status
= gDS
->AllocateIoSpace (
390 EfiGcdAllocateAnySearchBottomUp
,
399 if (!EFI_ERROR (Status
)) {
400 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
402 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
405 ReturnStatus
= Status
;
406 if (Status
!= EFI_OUT_OF_RESOURCES
) {
407 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
416 // It is impossible for this chipset to align 0xFFFFFFFF for
421 if (BitsOfAlignment
>= 32) {
425 Status
= gDS
->AllocateMemorySpace (
426 EfiGcdAllocateAnySearchBottomUp
,
427 EfiGcdMemoryTypeMemoryMappedIo
,
435 if (!EFI_ERROR (Status
)) {
436 // We were able to allocate the PCI memory
437 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
439 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
443 // Not able to allocate enough PCI memory
444 ReturnStatus
= Status
;
446 if (Status
!= EFI_OUT_OF_RESOURCES
) {
447 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
456 ReturnStatus
= EFI_ABORTED
;
465 List
= List
->ForwardLink
;
471 return EFI_NOT_READY
;
475 case EfiPciHostBridgeSetResources
:
478 case EfiPciHostBridgeFreeResources
:
479 ReturnStatus
= EFI_SUCCESS
;
480 List
= HostBridgeInstance
->Head
.ForwardLink
;
481 while (List
!= &HostBridgeInstance
->Head
) {
482 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
483 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
484 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
485 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
486 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
490 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
491 if (EFI_ERROR (Status
)) {
492 ReturnStatus
= Status
;
497 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
498 if (EFI_ERROR (Status
)) {
499 ReturnStatus
= Status
;
517 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
518 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
519 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
520 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
524 List
= List
->ForwardLink
;
527 HostBridgeInstance
->ResourceSubmited
= FALSE
;
528 HostBridgeInstance
->CanRestarted
= TRUE
;
531 case EfiPciHostBridgeEndResourceAllocation
:
532 HostBridgeInstance
->CanRestarted
= FALSE
;
536 return EFI_INVALID_PARAMETER
;
543 Return the device handle of the next PCI root bridge that is associated with
546 This function is called multiple times to retrieve the device handles of all
547 the PCI root bridges that are associated with this PCI host bridge. Each PCI
548 host bridge is associated with one or more PCI root bridges. On each call,
549 the handle that was returned by the previous call is passed into the
550 interface, and on output the interface returns the device handle of the next
551 PCI root bridge. The caller can use the handle to obtain the instance of the
552 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more
553 PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI
554 enumerator must enumerate the PCI root bridges in the order that they are
555 returned by this function.
557 For D945 implementation, there is only one root bridge in PCI host bridge.
559 @param[in] This The instance pointer of
560 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
562 @param[in, out] RootBridgeHandle Returns the device handle of the next PCI
565 @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then
566 return the first Rootbridge handle of the
567 specific Host bridge and return EFI_SUCCESS.
569 @retval EFI_NOT_FOUND Can not find the any more root bridge in
570 specific host bridge.
572 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
573 returned on a previous call to
579 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
580 IN OUT EFI_HANDLE
*RootBridgeHandle
583 BOOLEAN NoRootBridge
;
585 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
586 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
589 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
590 List
= HostBridgeInstance
->Head
.ForwardLink
;
593 while (List
!= &HostBridgeInstance
->Head
) {
594 NoRootBridge
= FALSE
;
595 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
596 if (*RootBridgeHandle
== NULL
) {
598 // Return the first Root Bridge Handle of the Host Bridge
600 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
603 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
607 List
= List
->ForwardLink
;
608 if (List
!=&HostBridgeInstance
->Head
) {
609 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
610 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
613 return EFI_NOT_FOUND
;
618 List
= List
->ForwardLink
;
622 return EFI_NOT_FOUND
;
624 return EFI_INVALID_PARAMETER
;
629 Returns the allocation attributes of a PCI root bridge.
631 The function returns the allocation attributes of a specific PCI root bridge.
632 The attributes can vary from one PCI root bridge to another. These attributes
633 are different from the decode-related attributes that are returned by the
634 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
635 RootBridgeHandle parameter is used to specify the instance of the PCI root
636 bridge. The device handles of all the root bridges that are associated with
637 this host bridge must be obtained by calling GetNextRootBridge(). The
638 attributes are static in the sense that they do not change during or after
639 the enumeration process. The hardware may provide mechanisms to change the
640 attributes on the fly, but such changes must be completed before
641 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted
642 values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
643 "Related Definitions" below. The caller uses these attributes to combine
644 multiple resource requests.
646 For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI
647 bus enumerator needs to include requests for the prefetchable memory in the
648 nonprefetchable memory pool and not request any prefetchable memory.
650 Attribute Description
651 ------------------------------------ ---------------------------------------
652 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root
653 bridge does not support separate
654 windows for nonprefetchable and
655 prefetchable memory. A PCI bus driver
656 needs to include requests for
657 prefetchable memory in the
658 nonprefetchable memory pool.
660 EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root
661 bridge supports 64-bit memory windows.
662 If this bit is not set, the PCI bus
663 driver needs to include requests for a
664 64-bit memory address in the
665 corresponding 32-bit memory pool.
667 @param[in] This The instance pointer of
668 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
670 @param[in] RootBridgeHandle The device handle of the PCI root bridge in
671 which the caller is interested. Type
672 EFI_HANDLE is defined in
673 InstallProtocolInterface() in the UEFI 2.0
676 @param[out] Attributes The pointer to attribte of root bridge, it is
679 @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
681 @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
683 @retval EFI_SUCCESS Success to get attribute of interested root
689 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
690 IN EFI_HANDLE RootBridgeHandle
,
691 OUT UINT64
*Attributes
695 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
696 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
698 if (Attributes
== NULL
) {
699 return EFI_INVALID_PARAMETER
;
702 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
703 List
= HostBridgeInstance
->Head
.ForwardLink
;
705 while (List
!= &HostBridgeInstance
->Head
) {
706 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
707 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
708 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
711 List
= List
->ForwardLink
;
715 // RootBridgeHandle is not an EFI_HANDLE
716 // that was returned on a previous call to GetNextRootBridge()
718 return EFI_INVALID_PARAMETER
;
722 Sets up the specified PCI root bridge for the bus enumeration process.
724 This member function sets up the root bridge for bus enumeration and returns
725 the PCI bus range over which the search should be performed in ACPI 2.0
726 resource descriptor format.
729 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
732 @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
734 @param[out] Configuration Pointer to the pointer to the PCI bus resource
737 @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
739 @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
741 @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
746 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
747 IN EFI_HANDLE RootBridgeHandle
,
748 OUT VOID
**Configuration
752 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
753 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
759 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
760 List
= HostBridgeInstance
->Head
.ForwardLink
;
762 while (List
!= &HostBridgeInstance
->Head
) {
763 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
764 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
766 // Set up the Root Bridge for Bus Enumeration
768 BusStart
= RootBridgeInstance
->BusBase
;
769 BusEnd
= RootBridgeInstance
->BusLimit
;
771 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
774 Buffer
= AllocatePool (
775 sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
776 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
778 if (Buffer
== NULL
) {
779 return EFI_OUT_OF_RESOURCES
;
782 Temp
= (UINT8
*)Buffer
;
784 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
785 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
786 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
787 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
788 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
789 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
790 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
791 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
792 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
793 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
=
794 BusEnd
- BusStart
+ 1;
796 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
797 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
798 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
800 *Configuration
= Buffer
;
803 List
= List
->ForwardLink
;
806 return EFI_INVALID_PARAMETER
;
810 Programs the PCI root bridge hardware so that it decodes the specified PCI
813 This member function programs the specified PCI root bridge to decode the bus
814 range that is specified by the input parameter Configuration.
815 The bus range information is specified in terms of the ACPI 2.0 resource
819 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
822 @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be
825 @param[in] Configuration The pointer to the PCI bus resource descriptor
827 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
830 @retval EFI_INVALID_PARAMETER Configuration is NULL.
832 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
833 2.0 resource descriptor.
835 @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI
836 2.0 bus resource descriptor.
838 @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource
839 descriptors other than bus descriptors.
841 @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid
842 ACPI resource descriptors.
844 @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this
847 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this
850 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
852 @retval EFI_SUCCESS The bus range for the PCI root bridge was
858 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
859 IN EFI_HANDLE RootBridgeHandle
,
860 IN VOID
*Configuration
864 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
865 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
871 if (Configuration
== NULL
) {
872 return EFI_INVALID_PARAMETER
;
878 // Check the Configuration is valid
880 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
881 return EFI_INVALID_PARAMETER
;
884 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
885 return EFI_INVALID_PARAMETER
;
888 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
889 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
890 return EFI_INVALID_PARAMETER
;
893 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
894 List
= HostBridgeInstance
->Head
.ForwardLink
;
898 while (List
!= &HostBridgeInstance
->Head
) {
899 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
900 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
901 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
903 Desc
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
;
904 BusStart
= (UINTN
)Desc
->AddrRangeMin
;
905 BusLen
= (UINTN
)Desc
->AddrLen
;
906 BusEnd
= BusStart
+ BusLen
- 1;
908 if (BusStart
> BusEnd
) {
909 return EFI_INVALID_PARAMETER
;
912 if ((BusStart
< RootBridgeInstance
->BusBase
) ||
913 (BusEnd
> RootBridgeInstance
->BusLimit
)) {
914 return EFI_INVALID_PARAMETER
;
918 // Update the Bus Range
920 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
921 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
922 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
925 // Program the Root Bridge Hardware
931 List
= List
->ForwardLink
;
934 return EFI_INVALID_PARAMETER
;
939 Submits the I/O and memory resource requirements for the specified PCI root
942 This function is used to submit all the I/O and memory resources that are
943 required by the specified PCI root bridge. The input parameter Configuration
944 is used to specify the following:
945 - The various types of resources that are required
946 - The associated lengths in terms of ACPI 2.0 resource descriptor format
948 @param[in] This Pointer to the
949 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
952 @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory
953 resource requirements are being submitted.
955 @param[in] Configuration The pointer to the PCI I/O and PCI memory
958 @retval EFI_SUCCESS The I/O and memory resource requests for a PCI
959 root bridge were accepted.
961 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
964 @retval EFI_INVALID_PARAMETER Configuration is NULL.
966 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
967 2.0 resource descriptor.
969 @retval EFI_INVALID_PARAMETER Configuration includes requests for one or
970 more resource types that are not supported by
971 this PCI root bridge. This error will happen
972 if the caller did not combine resources
973 according to Attributes that were returned by
974 GetAllocAttributes().
976 @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
978 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI
981 @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for
982 this PCI root bridge.
987 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
988 IN EFI_HANDLE RootBridgeHandle
,
989 IN VOID
*Configuration
993 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
994 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
996 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1001 // Check the input parameter: Configuration
1003 if (Configuration
== NULL
) {
1004 return EFI_INVALID_PARAMETER
;
1007 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1008 List
= HostBridgeInstance
->Head
.ForwardLink
;
1010 Temp
= (UINT8
*)Configuration
;
1011 while ( *Temp
== 0x8A) {
1012 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1014 if (*Temp
!= 0x79) {
1015 return EFI_INVALID_PARAMETER
;
1018 Temp
= (UINT8
*)Configuration
;
1019 while (List
!= &HostBridgeInstance
->Head
) {
1020 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1021 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1022 while ( *Temp
== 0x8A) {
1023 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1026 // Check Address Length
1028 if (Ptr
->AddrLen
> 0xffffffff) {
1029 return EFI_INVALID_PARAMETER
;
1033 // Check address range alignment
1035 if (Ptr
->AddrRangeMax
>= 0xffffffff ||
1036 Ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (
1037 Ptr
->AddrRangeMax
+ 1) - 1)) {
1038 return EFI_INVALID_PARAMETER
;
1041 switch (Ptr
->ResType
) {
1046 // Check invalid Address Sapce Granularity
1048 if (Ptr
->AddrSpaceGranularity
!= 32) {
1049 return EFI_INVALID_PARAMETER
;
1053 // check the memory resource request is supported by PCI root bridge
1055 if (RootBridgeInstance
->RootBridgeAttrib
==
1056 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
1057 Ptr
->SpecificFlag
== 0x06) {
1058 return EFI_INVALID_PARAMETER
;
1061 AddrLen
= Ptr
->AddrLen
;
1062 Alignment
= Ptr
->AddrRangeMax
;
1063 if (Ptr
->AddrSpaceGranularity
== 32) {
1064 if (Ptr
->SpecificFlag
== 0x06) {
1068 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
=
1071 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1072 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
=
1074 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
=
1076 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1080 if (Ptr
->AddrSpaceGranularity
== 64) {
1081 if (Ptr
->SpecificFlag
== 0x06) {
1082 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
=
1085 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
=
1092 AddrLen
= (UINTN
) Ptr
->AddrLen
;
1093 Alignment
= (UINTN
) Ptr
->AddrRangeMax
;
1094 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
1095 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
1096 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
1097 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1104 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1110 List
= List
->ForwardLink
;
1113 return EFI_INVALID_PARAMETER
;
1117 Returns the proposed resource settings for the specified PCI root bridge.
1119 This member function returns the proposed resource settings for the
1120 specified PCI root bridge. The proposed resource settings are prepared when
1121 NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.
1122 The output parameter Configuration specifies the following:
1123 - The various types of resources, excluding bus resources, that are
1125 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1127 @param[in] This Pointer to the
1128 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1131 @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is
1132 defined in InstallProtocolInterface() in the
1133 UEFI 2.0 Specification.
1135 @param[out] Configuration The pointer to the pointer to the PCI I/O and
1136 memory resource descriptor.
1138 @retval EFI_SUCCESS The requested parameters were returned.
1140 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1143 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1145 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1150 GetProposedResources(
1151 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1152 IN EFI_HANDLE RootBridgeHandle
,
1153 OUT VOID
**Configuration
1157 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1158 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1163 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1169 // Get the Host Bridge Instance from the resource allocation protocol
1171 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1172 List
= HostBridgeInstance
->Head
.ForwardLink
;
1175 // Enumerate the root bridges in this host bridge
1177 while (List
!= &HostBridgeInstance
->Head
) {
1178 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1179 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1180 for (Index
= 0; Index
< TypeBus
; Index
++) {
1181 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1187 return EFI_INVALID_PARAMETER
;
1190 Buffer
= AllocateZeroPool (
1191 Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
1192 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
1194 if (Buffer
== NULL
) {
1195 return EFI_OUT_OF_RESOURCES
;
1199 for (Index
= 0; Index
< TypeBus
; Index
++) {
1200 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1201 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1202 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1214 Ptr
->SpecificFlag
= 0;
1215 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1216 Ptr
->AddrRangeMax
= 0;
1217 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1218 EFI_RESOURCE_SATISFIED
:
1220 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1231 Ptr
->SpecificFlag
= 0;
1232 Ptr
->AddrSpaceGranularity
= 32;
1233 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1234 Ptr
->AddrRangeMax
= 0;
1235 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1236 EFI_RESOURCE_SATISFIED
:
1238 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1243 // Prefetch memory 32
1249 Ptr
->SpecificFlag
= 6;
1250 Ptr
->AddrSpaceGranularity
= 32;
1251 Ptr
->AddrRangeMin
= 0;
1252 Ptr
->AddrRangeMax
= 0;
1253 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1265 Ptr
->SpecificFlag
= 0;
1266 Ptr
->AddrSpaceGranularity
= 64;
1267 Ptr
->AddrRangeMin
= 0;
1268 Ptr
->AddrRangeMax
= 0;
1269 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1275 // Prefetch memory 64
1281 Ptr
->SpecificFlag
= 6;
1282 Ptr
->AddrSpaceGranularity
= 64;
1283 Ptr
->AddrRangeMin
= 0;
1284 Ptr
->AddrRangeMax
= 0;
1285 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1290 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1294 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1295 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1297 *Configuration
= Buffer
;
1302 List
= List
->ForwardLink
;
1305 return EFI_INVALID_PARAMETER
;
1309 Provides the hooks from the PCI bus driver to every PCI controller
1310 (device/function) at various stages of the PCI enumeration process that allow
1311 the host bridge driver to preinitialize individual PCI controllers before
1314 This function is called during the PCI enumeration process. No specific
1315 action is expected from this member function. It allows the host bridge
1316 driver to preinitialize individual PCI controllers before enumeration.
1318 @param This Pointer to the
1319 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1322 @param RootBridgeHandle The associated PCI root bridge handle. Type
1323 EFI_HANDLE is defined in InstallProtocolInterface()
1324 in the UEFI 2.0 Specification.
1326 @param PciAddress The address of the PCI device on the PCI bus. This
1327 address can be passed to the
1328 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to
1329 access the PCI configuration space of the device.
1330 See Table 12-1 in the UEFI 2.0 Specification for the
1332 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
1334 @param Phase The phase of the PCI device enumeration.
1336 @retval EFI_SUCCESS The requested parameters were returned.
1338 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1341 @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined
1343 EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
1345 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1346 The PCI enumerator should not enumerate this
1347 device, including its child devices if it is
1348 a PCI-to-PCI bridge.
1352 PreprocessController (
1353 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1354 IN EFI_HANDLE RootBridgeHandle
,
1355 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1356 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1359 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1360 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1363 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1364 List
= HostBridgeInstance
->Head
.ForwardLink
;
1367 // Enumerate the root bridges in this host bridge
1369 while (List
!= &HostBridgeInstance
->Head
) {
1370 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1371 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1374 List
= List
->ForwardLink
;
1376 if (List
== &HostBridgeInstance
->Head
) {
1377 return EFI_INVALID_PARAMETER
;
1380 if ((UINT32
)Phase
> EfiPciBeforeResourceCollection
) {
1381 return EFI_INVALID_PARAMETER
;