2 Provides the basic interfaces to abstract a PCI Host Bridge Resource
5 Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials are licensed and made available
8 under the terms and conditions of the BSD License which accompanies this
9 distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "PciHostBridge.h"
20 // Hard code: Root Bridge Number within the host bridge
21 // Root Bridge's attribute
22 // Root Bridge's device path
23 // Root Bridge's resource aperture
25 UINTN RootBridgeNumber
[1] = { 1 };
27 UINT64 RootBridgeAttribute
[1][1] = {
28 { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
}
31 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath
[1][1] = {
39 (UINT8
) (sizeof(ACPI_HID_DEVICE_PATH
)),
40 (UINT8
) ((sizeof(ACPI_HID_DEVICE_PATH
)) >> 8)
49 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
51 END_DEVICE_PATH_LENGTH
,
59 PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture
[1][1] = {
60 {{0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}}
63 EFI_HANDLE mDriverImageHandle
;
65 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
66 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
67 NULL
, // HostBridgeHandle
68 0, // RootBridgeNumber
70 FALSE
, // ResourceSubiteed
89 Entry point of this driver
91 @param ImageHandle Handle of driver image
92 @param SystemTable Point to EFI_SYSTEM_TABLE
94 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
95 @retval EFI_DEVICE_ERROR Can not install the protocol instance
96 @retval EFI_SUCCESS Success to initialize the Pci host bridge.
100 InitializePciHostBridge (
101 IN EFI_HANDLE ImageHandle
,
102 IN EFI_SYSTEM_TABLE
*SystemTable
108 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
109 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
111 mDriverImageHandle
= ImageHandle
;
114 // Create Host Bridge Device Handle
116 for (Loop1
= 0; Loop1
< HOST_BRIDGE_NUMBER
; Loop1
++) {
117 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
),
118 &mPciHostBridgeInstanceTemplate
);
119 if (HostBridge
== NULL
) {
120 return EFI_OUT_OF_RESOURCES
;
123 HostBridge
->RootBridgeNumber
= RootBridgeNumber
[Loop1
];
124 InitializeListHead (&HostBridge
->Head
);
126 Status
= gBS
->InstallMultipleProtocolInterfaces (
127 &HostBridge
->HostBridgeHandle
,
128 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
129 &HostBridge
->ResAlloc
,
132 if (EFI_ERROR (Status
)) {
133 FreePool (HostBridge
);
134 return EFI_DEVICE_ERROR
;
138 // Create Root Bridge Device Handle in this Host Bridge
141 for (Loop2
= 0; Loop2
< HostBridge
->RootBridgeNumber
; Loop2
++) {
142 PrivateData
= AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE
));
143 if (PrivateData
== NULL
) {
144 return EFI_OUT_OF_RESOURCES
;
147 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
148 PrivateData
->DevicePath
=
149 (EFI_DEVICE_PATH_PROTOCOL
*)&mEfiPciRootBridgeDevicePath
[Loop1
][Loop2
];
151 RootBridgeConstructor (
153 HostBridge
->HostBridgeHandle
,
154 RootBridgeAttribute
[Loop1
][Loop2
],
155 &mResAperture
[Loop1
][Loop2
]
158 Status
= gBS
->InstallMultipleProtocolInterfaces(
159 &PrivateData
->Handle
,
160 &gEfiDevicePathProtocolGuid
,
161 PrivateData
->DevicePath
,
162 &gEfiPciRootBridgeIoProtocolGuid
,
166 if (EFI_ERROR (Status
)) {
167 FreePool(PrivateData
);
168 return EFI_DEVICE_ERROR
;
171 InsertTailList (&HostBridge
->Head
, &PrivateData
->Link
);
180 These are the notifications from the PCI bus driver that it is about to enter
181 a certain phase of the PCI enumeration process.
183 This member function can be used to notify the host bridge driver to perform
184 specific actions, including any chipset-specific initialization, so that the
185 chipset is ready to enter the next phase. Eight notification points are
186 defined at this time. See belows:
188 EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures
189 and internal data structures. The PCI
190 enumerator should issue this
191 notification before starting a fresh
192 enumeration process. Enumeration
193 cannot be restarted after sending any
194 other notification such as
195 EfiPciHostBridgeBeginBusAllocation.
197 EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to
198 begin. No specific action is required
199 here. This notification can be used to
200 perform any chipset-specific
203 EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming
204 phase is complete. No specific action
205 is required here. This notification
206 can be used to perform any
207 chipset-specific programming.
209 EfiPciHostBridgeBeginResourceAllocation
210 The resource allocation phase is about
211 to begin. No specific action is
212 required here. This notification can
213 be used to perform any
214 chipset-specific programming.
216 EfiPciHostBridgeAllocateResources Allocates resources per previously
217 submitted requests for all the PCI
218 root bridges. These resource settings
219 are returned on the next call to
220 GetProposedResources(). Before calling
221 NotifyPhase() with a Phase of
222 EfiPciHostBridgeAllocateResource, the
223 PCI bus enumerator is responsible for
224 gathering I/O and memory requests for
225 all the PCI root bridges and
226 submitting these requests using
227 SubmitResources(). This function pads
228 the resource amount to suit the root
229 bridge hardware, takes care of
230 dependencies between the PCI root
231 bridges, and calls the Global
232 Coherency Domain (GCD) with the
233 allocation request. In the case of
234 padding, the allocated range could be
235 bigger than what was requested.
237 EfiPciHostBridgeSetResources Programs the host bridge hardware to
238 decode previously allocated resources
239 (proposed resources) for all the PCI
240 root bridges. After the hardware is
241 programmed, reassigning resources will
242 not be supported. The bus settings are
245 EfiPciHostBridgeFreeResources Deallocates resources that were
246 previously allocated for all the PCI
247 root bridges and resets the I/O and
248 memory apertures to their initial
249 state. The bus settings are not
250 affected. If the request to allocate
251 resources fails, the PCI enumerator
252 can use this notification to
253 deallocate previous resources, adjust
254 the requests, and retry allocation.
256 EfiPciHostBridgeEndResourceAllocation The resource allocation phase is
257 completed. No specific action is
258 required here. This notification can
259 be used to perform any chipsetspecific
262 @param[in] This The instance pointer of
263 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
265 @param[in] Phase The phase during enumeration
267 @retval EFI_NOT_READY This phase cannot be entered at this time. For
268 example, this error is valid for a Phase of
269 EfiPciHostBridgeAllocateResources if
270 SubmitResources() has not been called for one
271 or more PCI root bridges before this call
273 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
274 This error is valid for a Phase of
275 EfiPciHostBridgeSetResources.
277 @retval EFI_INVALID_PARAMETER Invalid phase parameter
279 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
280 lack of resources. This error is valid for a
281 Phase of EfiPciHostBridgeAllocateResources if
282 the previously submitted resource requests
283 cannot be fulfilled or were only partially
286 @retval EFI_SUCCESS The notification was accepted without any
292 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
293 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
296 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
297 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
298 PCI_RESOURCE_TYPE Index
;
300 EFI_PHYSICAL_ADDRESS BaseAddress
;
302 UINTN BitsOfAlignment
;
304 EFI_STATUS ReturnStatus
;
306 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
310 case EfiPciHostBridgeBeginEnumeration
:
311 if (HostBridgeInstance
->CanRestarted
) {
313 // Reset the Each Root Bridge
315 List
= HostBridgeInstance
->Head
.ForwardLink
;
317 while (List
!= &HostBridgeInstance
->Head
) {
318 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
319 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
320 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
321 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
322 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
323 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
326 List
= List
->ForwardLink
;
329 HostBridgeInstance
->ResourceSubmited
= FALSE
;
330 HostBridgeInstance
->CanRestarted
= TRUE
;
335 return EFI_NOT_READY
;
339 case EfiPciHostBridgeEndEnumeration
:
342 case EfiPciHostBridgeBeginBusAllocation
:
344 // No specific action is required here, can perform any chipset specific
347 HostBridgeInstance
->CanRestarted
= FALSE
;
350 case EfiPciHostBridgeEndBusAllocation
:
352 // No specific action is required here, can perform any chipset specific
355 //HostBridgeInstance->CanRestarted = FALSE;
358 case EfiPciHostBridgeBeginResourceAllocation
:
360 // No specific action is required here, can perform any chipset specific
363 //HostBridgeInstance->CanRestarted = FALSE;
366 case EfiPciHostBridgeAllocateResources
:
367 ReturnStatus
= EFI_SUCCESS
;
368 if (HostBridgeInstance
->ResourceSubmited
) {
370 // Take care of the resource dependencies between the root bridges
372 List
= HostBridgeInstance
->Head
.ForwardLink
;
374 while (List
!= &HostBridgeInstance
->Head
) {
375 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
376 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
377 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
379 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
382 // Get the number of '1' in Alignment.
385 (UINTN
)(HighBitSet64 (
386 RootBridgeInstance
->ResAllocNode
[Index
].Alignment
393 // It is impossible for this chipset to align 0xFFFF for IO16
396 if (BitsOfAlignment
>= 16) {
400 Status
= gDS
->AllocateIoSpace (
401 EfiGcdAllocateAnySearchBottomUp
,
410 if (!EFI_ERROR (Status
)) {
411 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
413 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
416 ReturnStatus
= Status
;
417 if (Status
!= EFI_OUT_OF_RESOURCES
) {
418 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
427 // It is impossible for this chipset to align 0xFFFFFFFF for
432 if (BitsOfAlignment
>= 32) {
436 Status
= gDS
->AllocateMemorySpace (
437 EfiGcdAllocateAnySearchBottomUp
,
438 EfiGcdMemoryTypeMemoryMappedIo
,
446 if (!EFI_ERROR (Status
)) {
447 // We were able to allocate the PCI memory
448 RootBridgeInstance
->ResAllocNode
[Index
].Base
=
450 RootBridgeInstance
->ResAllocNode
[Index
].Status
=
454 // Not able to allocate enough PCI memory
455 ReturnStatus
= Status
;
457 if (Status
!= EFI_OUT_OF_RESOURCES
) {
458 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
467 ReturnStatus
= EFI_ABORTED
;
476 List
= List
->ForwardLink
;
482 return EFI_NOT_READY
;
486 case EfiPciHostBridgeSetResources
:
489 case EfiPciHostBridgeFreeResources
:
490 ReturnStatus
= EFI_SUCCESS
;
491 List
= HostBridgeInstance
->Head
.ForwardLink
;
492 while (List
!= &HostBridgeInstance
->Head
) {
493 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
494 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
495 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
496 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
497 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
501 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
502 if (EFI_ERROR (Status
)) {
503 ReturnStatus
= Status
;
508 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
509 if (EFI_ERROR (Status
)) {
510 ReturnStatus
= Status
;
528 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
529 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
530 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
531 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
535 List
= List
->ForwardLink
;
538 HostBridgeInstance
->ResourceSubmited
= FALSE
;
539 HostBridgeInstance
->CanRestarted
= TRUE
;
542 case EfiPciHostBridgeEndResourceAllocation
:
543 HostBridgeInstance
->CanRestarted
= FALSE
;
547 return EFI_INVALID_PARAMETER
;
554 Return the device handle of the next PCI root bridge that is associated with
557 This function is called multiple times to retrieve the device handles of all
558 the PCI root bridges that are associated with this PCI host bridge. Each PCI
559 host bridge is associated with one or more PCI root bridges. On each call,
560 the handle that was returned by the previous call is passed into the
561 interface, and on output the interface returns the device handle of the next
562 PCI root bridge. The caller can use the handle to obtain the instance of the
563 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more
564 PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI
565 enumerator must enumerate the PCI root bridges in the order that they are
566 returned by this function.
568 For D945 implementation, there is only one root bridge in PCI host bridge.
570 @param[in] This The instance pointer of
571 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
573 @param[in, out] RootBridgeHandle Returns the device handle of the next PCI
576 @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then
577 return the first Rootbridge handle of the
578 specific Host bridge and return EFI_SUCCESS.
580 @retval EFI_NOT_FOUND Can not find the any more root bridge in
581 specific host bridge.
583 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
584 returned on a previous call to
590 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
591 IN OUT EFI_HANDLE
*RootBridgeHandle
594 BOOLEAN NoRootBridge
;
596 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
597 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
600 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
601 List
= HostBridgeInstance
->Head
.ForwardLink
;
604 while (List
!= &HostBridgeInstance
->Head
) {
605 NoRootBridge
= FALSE
;
606 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
607 if (*RootBridgeHandle
== NULL
) {
609 // Return the first Root Bridge Handle of the Host Bridge
611 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
614 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
618 List
= List
->ForwardLink
;
619 if (List
!=&HostBridgeInstance
->Head
) {
620 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
621 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
624 return EFI_NOT_FOUND
;
629 List
= List
->ForwardLink
;
633 return EFI_NOT_FOUND
;
635 return EFI_INVALID_PARAMETER
;
640 Returns the allocation attributes of a PCI root bridge.
642 The function returns the allocation attributes of a specific PCI root bridge.
643 The attributes can vary from one PCI root bridge to another. These attributes
644 are different from the decode-related attributes that are returned by the
645 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
646 RootBridgeHandle parameter is used to specify the instance of the PCI root
647 bridge. The device handles of all the root bridges that are associated with
648 this host bridge must be obtained by calling GetNextRootBridge(). The
649 attributes are static in the sense that they do not change during or after
650 the enumeration process. The hardware may provide mechanisms to change the
651 attributes on the fly, but such changes must be completed before
652 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted
653 values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
654 "Related Definitions" below. The caller uses these attributes to combine
655 multiple resource requests.
657 For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI
658 bus enumerator needs to include requests for the prefetchable memory in the
659 nonprefetchable memory pool and not request any prefetchable memory.
661 Attribute Description
662 ------------------------------------ ---------------------------------------
663 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root
664 bridge does not support separate
665 windows for nonprefetchable and
666 prefetchable memory. A PCI bus driver
667 needs to include requests for
668 prefetchable memory in the
669 nonprefetchable memory pool.
671 EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root
672 bridge supports 64-bit memory windows.
673 If this bit is not set, the PCI bus
674 driver needs to include requests for a
675 64-bit memory address in the
676 corresponding 32-bit memory pool.
678 @param[in] This The instance pointer of
679 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
681 @param[in] RootBridgeHandle The device handle of the PCI root bridge in
682 which the caller is interested. Type
683 EFI_HANDLE is defined in
684 InstallProtocolInterface() in the UEFI 2.0
687 @param[out] Attributes The pointer to attribte of root bridge, it is
690 @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
692 @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
694 @retval EFI_SUCCESS Success to get attribute of interested root
700 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
701 IN EFI_HANDLE RootBridgeHandle
,
702 OUT UINT64
*Attributes
706 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
707 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
709 if (Attributes
== NULL
) {
710 return EFI_INVALID_PARAMETER
;
713 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
714 List
= HostBridgeInstance
->Head
.ForwardLink
;
716 while (List
!= &HostBridgeInstance
->Head
) {
717 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
718 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
719 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
722 List
= List
->ForwardLink
;
726 // RootBridgeHandle is not an EFI_HANDLE
727 // that was returned on a previous call to GetNextRootBridge()
729 return EFI_INVALID_PARAMETER
;
733 Sets up the specified PCI root bridge for the bus enumeration process.
735 This member function sets up the root bridge for bus enumeration and returns
736 the PCI bus range over which the search should be performed in ACPI 2.0
737 resource descriptor format.
740 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
743 @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
745 @param[out] Configuration Pointer to the pointer to the PCI bus resource
748 @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
750 @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
752 @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
757 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
758 IN EFI_HANDLE RootBridgeHandle
,
759 OUT VOID
**Configuration
763 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
764 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
770 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
771 List
= HostBridgeInstance
->Head
.ForwardLink
;
773 while (List
!= &HostBridgeInstance
->Head
) {
774 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
775 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
777 // Set up the Root Bridge for Bus Enumeration
779 BusStart
= RootBridgeInstance
->BusBase
;
780 BusEnd
= RootBridgeInstance
->BusLimit
;
782 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
785 Buffer
= AllocatePool (
786 sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
787 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
789 if (Buffer
== NULL
) {
790 return EFI_OUT_OF_RESOURCES
;
793 Temp
= (UINT8
*)Buffer
;
795 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
796 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
797 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
798 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
799 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
800 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
801 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
802 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
803 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
804 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
=
805 BusEnd
- BusStart
+ 1;
807 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
808 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
809 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
811 *Configuration
= Buffer
;
814 List
= List
->ForwardLink
;
817 return EFI_INVALID_PARAMETER
;
821 Programs the PCI root bridge hardware so that it decodes the specified PCI
824 This member function programs the specified PCI root bridge to decode the bus
825 range that is specified by the input parameter Configuration.
826 The bus range information is specified in terms of the ACPI 2.0 resource
830 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
833 @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be
836 @param[in] Configuration The pointer to the PCI bus resource descriptor
838 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
841 @retval EFI_INVALID_PARAMETER Configuration is NULL.
843 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
844 2.0 resource descriptor.
846 @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI
847 2.0 bus resource descriptor.
849 @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource
850 descriptors other than bus descriptors.
852 @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid
853 ACPI resource descriptors.
855 @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this
858 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this
861 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
863 @retval EFI_SUCCESS The bus range for the PCI root bridge was
869 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
870 IN EFI_HANDLE RootBridgeHandle
,
871 IN VOID
*Configuration
875 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
876 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
882 if (Configuration
== NULL
) {
883 return EFI_INVALID_PARAMETER
;
889 // Check the Configuration is valid
891 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
892 return EFI_INVALID_PARAMETER
;
895 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
896 return EFI_INVALID_PARAMETER
;
899 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
900 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
901 return EFI_INVALID_PARAMETER
;
904 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
905 List
= HostBridgeInstance
->Head
.ForwardLink
;
909 while (List
!= &HostBridgeInstance
->Head
) {
910 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
911 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
912 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Desc
;
914 Desc
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
;
915 BusStart
= (UINTN
)Desc
->AddrRangeMin
;
916 BusLen
= (UINTN
)Desc
->AddrLen
;
917 BusEnd
= BusStart
+ BusLen
- 1;
919 if (BusStart
> BusEnd
) {
920 return EFI_INVALID_PARAMETER
;
923 if ((BusStart
< RootBridgeInstance
->BusBase
) ||
924 (BusEnd
> RootBridgeInstance
->BusLimit
)) {
925 return EFI_INVALID_PARAMETER
;
929 // Update the Bus Range
931 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
932 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
933 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
936 // Program the Root Bridge Hardware
942 List
= List
->ForwardLink
;
945 return EFI_INVALID_PARAMETER
;
950 Submits the I/O and memory resource requirements for the specified PCI root
953 This function is used to submit all the I/O and memory resources that are
954 required by the specified PCI root bridge. The input parameter Configuration
955 is used to specify the following:
956 - The various types of resources that are required
957 - The associated lengths in terms of ACPI 2.0 resource descriptor format
959 @param[in] This Pointer to the
960 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
963 @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory
964 resource requirements are being submitted.
966 @param[in] Configuration The pointer to the PCI I/O and PCI memory
969 @retval EFI_SUCCESS The I/O and memory resource requests for a PCI
970 root bridge were accepted.
972 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
975 @retval EFI_INVALID_PARAMETER Configuration is NULL.
977 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
978 2.0 resource descriptor.
980 @retval EFI_INVALID_PARAMETER Configuration includes requests for one or
981 more resource types that are not supported by
982 this PCI root bridge. This error will happen
983 if the caller did not combine resources
984 according to Attributes that were returned by
985 GetAllocAttributes().
987 @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
989 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI
992 @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for
993 this PCI root bridge.
998 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
999 IN EFI_HANDLE RootBridgeHandle
,
1000 IN VOID
*Configuration
1004 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1005 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1007 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1012 // Check the input parameter: Configuration
1014 if (Configuration
== NULL
) {
1015 return EFI_INVALID_PARAMETER
;
1018 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1019 List
= HostBridgeInstance
->Head
.ForwardLink
;
1021 Temp
= (UINT8
*)Configuration
;
1022 while ( *Temp
== 0x8A) {
1023 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1025 if (*Temp
!= 0x79) {
1026 return EFI_INVALID_PARAMETER
;
1029 Temp
= (UINT8
*)Configuration
;
1030 while (List
!= &HostBridgeInstance
->Head
) {
1031 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1032 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1033 while ( *Temp
== 0x8A) {
1034 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1037 // Check Address Length
1039 if (Ptr
->AddrLen
> 0xffffffff) {
1040 return EFI_INVALID_PARAMETER
;
1044 // Check address range alignment
1046 if (Ptr
->AddrRangeMax
>= 0xffffffff ||
1047 Ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (
1048 Ptr
->AddrRangeMax
+ 1) - 1)) {
1049 return EFI_INVALID_PARAMETER
;
1052 switch (Ptr
->ResType
) {
1057 // Check invalid Address Sapce Granularity
1059 if (Ptr
->AddrSpaceGranularity
!= 32) {
1060 return EFI_INVALID_PARAMETER
;
1064 // check the memory resource request is supported by PCI root bridge
1066 if (RootBridgeInstance
->RootBridgeAttrib
==
1067 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
1068 Ptr
->SpecificFlag
== 0x06) {
1069 return EFI_INVALID_PARAMETER
;
1072 AddrLen
= Ptr
->AddrLen
;
1073 Alignment
= Ptr
->AddrRangeMax
;
1074 if (Ptr
->AddrSpaceGranularity
== 32) {
1075 if (Ptr
->SpecificFlag
== 0x06) {
1079 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
=
1082 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1083 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
=
1085 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
=
1087 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1091 if (Ptr
->AddrSpaceGranularity
== 64) {
1092 if (Ptr
->SpecificFlag
== 0x06) {
1093 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
=
1096 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
=
1103 AddrLen
= (UINTN
) Ptr
->AddrLen
;
1104 Alignment
= (UINTN
) Ptr
->AddrRangeMax
;
1105 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
1106 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
1107 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
1108 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1115 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1121 List
= List
->ForwardLink
;
1124 return EFI_INVALID_PARAMETER
;
1128 Returns the proposed resource settings for the specified PCI root bridge.
1130 This member function returns the proposed resource settings for the
1131 specified PCI root bridge. The proposed resource settings are prepared when
1132 NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.
1133 The output parameter Configuration specifies the following:
1134 - The various types of resources, excluding bus resources, that are
1136 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1138 @param[in] This Pointer to the
1139 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1142 @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is
1143 defined in InstallProtocolInterface() in the
1144 UEFI 2.0 Specification.
1146 @param[out] Configuration The pointer to the pointer to the PCI I/O and
1147 memory resource descriptor.
1149 @retval EFI_SUCCESS The requested parameters were returned.
1151 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1154 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1156 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1161 GetProposedResources(
1162 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1163 IN EFI_HANDLE RootBridgeHandle
,
1164 OUT VOID
**Configuration
1168 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1169 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1174 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1180 // Get the Host Bridge Instance from the resource allocation protocol
1182 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1183 List
= HostBridgeInstance
->Head
.ForwardLink
;
1186 // Enumerate the root bridges in this host bridge
1188 while (List
!= &HostBridgeInstance
->Head
) {
1189 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1190 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1191 for (Index
= 0; Index
< TypeBus
; Index
++) {
1192 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1198 return EFI_INVALID_PARAMETER
;
1201 Buffer
= AllocateZeroPool (
1202 Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) +
1203 sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
)
1205 if (Buffer
== NULL
) {
1206 return EFI_OUT_OF_RESOURCES
;
1210 for (Index
= 0; Index
< TypeBus
; Index
++) {
1211 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1212 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1213 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1225 Ptr
->SpecificFlag
= 0;
1226 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1227 Ptr
->AddrRangeMax
= 0;
1228 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1229 EFI_RESOURCE_SATISFIED
:
1231 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1242 Ptr
->SpecificFlag
= 0;
1243 Ptr
->AddrSpaceGranularity
= 32;
1244 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1245 Ptr
->AddrRangeMax
= 0;
1246 Ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ?
1247 EFI_RESOURCE_SATISFIED
:
1249 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1254 // Prefetch memory 32
1260 Ptr
->SpecificFlag
= 6;
1261 Ptr
->AddrSpaceGranularity
= 32;
1262 Ptr
->AddrRangeMin
= 0;
1263 Ptr
->AddrRangeMax
= 0;
1264 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1276 Ptr
->SpecificFlag
= 0;
1277 Ptr
->AddrSpaceGranularity
= 64;
1278 Ptr
->AddrRangeMin
= 0;
1279 Ptr
->AddrRangeMax
= 0;
1280 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1286 // Prefetch memory 64
1292 Ptr
->SpecificFlag
= 6;
1293 Ptr
->AddrSpaceGranularity
= 64;
1294 Ptr
->AddrRangeMin
= 0;
1295 Ptr
->AddrRangeMax
= 0;
1296 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1301 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1305 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1306 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1308 *Configuration
= Buffer
;
1313 List
= List
->ForwardLink
;
1316 return EFI_INVALID_PARAMETER
;
1320 Provides the hooks from the PCI bus driver to every PCI controller
1321 (device/function) at various stages of the PCI enumeration process that allow
1322 the host bridge driver to preinitialize individual PCI controllers before
1325 This function is called during the PCI enumeration process. No specific
1326 action is expected from this member function. It allows the host bridge
1327 driver to preinitialize individual PCI controllers before enumeration.
1329 @param This Pointer to the
1330 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1333 @param RootBridgeHandle The associated PCI root bridge handle. Type
1334 EFI_HANDLE is defined in InstallProtocolInterface()
1335 in the UEFI 2.0 Specification.
1337 @param PciAddress The address of the PCI device on the PCI bus. This
1338 address can be passed to the
1339 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to
1340 access the PCI configuration space of the device.
1341 See Table 12-1 in the UEFI 2.0 Specification for the
1343 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
1345 @param Phase The phase of the PCI device enumeration.
1347 @retval EFI_SUCCESS The requested parameters were returned.
1349 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1352 @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined
1354 EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
1356 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1357 The PCI enumerator should not enumerate this
1358 device, including its child devices if it is
1359 a PCI-to-PCI bridge.
1363 PreprocessController (
1364 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1365 IN EFI_HANDLE RootBridgeHandle
,
1366 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1367 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1370 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1371 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1374 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1375 List
= HostBridgeInstance
->Head
.ForwardLink
;
1378 // Enumerate the root bridges in this host bridge
1380 while (List
!= &HostBridgeInstance
->Head
) {
1381 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1382 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1385 List
= List
->ForwardLink
;
1387 if (List
== &HostBridgeInstance
->Head
) {
1388 return EFI_INVALID_PARAMETER
;
1391 if ((UINT32
)Phase
> EfiPciBeforeResourceCollection
) {
1392 return EFI_INVALID_PARAMETER
;