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] = { { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
} };
29 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath
[1][1] = {
37 (UINT8
) (sizeof(ACPI_HID_DEVICE_PATH
)),
38 (UINT8
) ((sizeof(ACPI_HID_DEVICE_PATH
)) >> 8)
47 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 END_DEVICE_PATH_LENGTH
,
57 PCI_ROOT_BRIDGE_RESOURCE_APERTURE mResAperture
[1][1] = {
58 {{0, 0xff, 0x80000000, 0xffffffff, 0, 0xffff}}
61 EFI_HANDLE mDriverImageHandle
;
63 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
64 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
65 NULL
, // HostBridgeHandle
66 0, // RootBridgeNumber
68 FALSE
, // ResourceSubiteed
87 Entry point of this driver
89 @param ImageHandle Handle of driver image
90 @param SystemTable Point to EFI_SYSTEM_TABLE
92 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
93 @retval EFI_DEVICE_ERROR Can not install the protocol instance
94 @retval EFI_SUCCESS Success to initialize the Pci host bridge.
98 InitializePciHostBridge (
99 IN EFI_HANDLE ImageHandle
,
100 IN EFI_SYSTEM_TABLE
*SystemTable
106 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
107 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
109 mDriverImageHandle
= ImageHandle
;
112 // Create Host Bridge Device Handle
114 for (Loop1
= 0; Loop1
< HOST_BRIDGE_NUMBER
; Loop1
++) {
115 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
), &mPciHostBridgeInstanceTemplate
);
116 if (HostBridge
== NULL
) {
117 return EFI_OUT_OF_RESOURCES
;
120 HostBridge
->RootBridgeNumber
= RootBridgeNumber
[Loop1
];
121 InitializeListHead (&HostBridge
->Head
);
123 Status
= gBS
->InstallMultipleProtocolInterfaces (
124 &HostBridge
->HostBridgeHandle
,
125 &gEfiPciHostBridgeResourceAllocationProtocolGuid
, &HostBridge
->ResAlloc
,
128 if (EFI_ERROR (Status
)) {
129 FreePool (HostBridge
);
130 return EFI_DEVICE_ERROR
;
134 // Create Root Bridge Device Handle in this Host Bridge
137 for (Loop2
= 0; Loop2
< HostBridge
->RootBridgeNumber
; Loop2
++) {
138 PrivateData
= AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE
));
139 if (PrivateData
== NULL
) {
140 return EFI_OUT_OF_RESOURCES
;
143 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
144 PrivateData
->DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)&mEfiPciRootBridgeDevicePath
[Loop1
][Loop2
];
146 RootBridgeConstructor (
148 HostBridge
->HostBridgeHandle
,
149 RootBridgeAttribute
[Loop1
][Loop2
],
150 &mResAperture
[Loop1
][Loop2
]
153 Status
= gBS
->InstallMultipleProtocolInterfaces(
154 &PrivateData
->Handle
,
155 &gEfiDevicePathProtocolGuid
, PrivateData
->DevicePath
,
156 &gEfiPciRootBridgeIoProtocolGuid
, &PrivateData
->Io
,
159 if (EFI_ERROR (Status
)) {
160 FreePool(PrivateData
);
161 return EFI_DEVICE_ERROR
;
164 InsertTailList (&HostBridge
->Head
, &PrivateData
->Link
);
173 These are the notifications from the PCI bus driver that it is about to enter
174 a certain phase of the PCI enumeration process.
176 This member function can be used to notify the host bridge driver to perform
177 specific actions, including any chipset-specific initialization, so that the
178 chipset is ready to enter the next phase. Eight notification points are
179 defined at this time. See belows:
181 EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures
182 and internal data structures. The PCI
183 enumerator should issue this
184 notification before starting a fresh
185 enumeration process. Enumeration
186 cannot be restarted after sending any
187 other notification such as
188 EfiPciHostBridgeBeginBusAllocation.
190 EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to
191 begin. No specific action is required
192 here. This notification can be used to
193 perform any chipset-specific
196 EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming
197 phase is complete. No specific action
198 is required here. This notification
199 can be used to perform any
200 chipset-specific programming.
202 EfiPciHostBridgeBeginResourceAllocation
203 The resource allocation phase is about
204 to begin. No specific action is
205 required here. This notification can
206 be used to perform any
207 chipset-specific programming.
209 EfiPciHostBridgeAllocateResources Allocates resources per previously
210 submitted requests for all the PCI
211 root bridges. These resource settings
212 are returned on the next call to
213 GetProposedResources(). Before calling
214 NotifyPhase() with a Phase of
215 EfiPciHostBridgeAllocateResource, the
216 PCI bus enumerator is responsible for
217 gathering I/O and memory requests for
218 all the PCI root bridges and
219 submitting these requests using
220 SubmitResources(). This function pads
221 the resource amount to suit the root
222 bridge hardware, takes care of
223 dependencies between the PCI root
224 bridges, and calls the Global
225 Coherency Domain (GCD) with the
226 allocation request. In the case of
227 padding, the allocated range could be
228 bigger than what was requested.
230 EfiPciHostBridgeSetResources Programs the host bridge hardware to
231 decode previously allocated resources
232 (proposed resources) for all the PCI
233 root bridges. After the hardware is
234 programmed, reassigning resources will
235 not be supported. The bus settings are
238 EfiPciHostBridgeFreeResources Deallocates resources that were
239 previously allocated for all the PCI
240 root bridges and resets the I/O and
241 memory apertures to their initial
242 state. The bus settings are not
243 affected. If the request to allocate
244 resources fails, the PCI enumerator
245 can use this notification to
246 deallocate previous resources, adjust
247 the requests, and retry allocation.
249 EfiPciHostBridgeEndResourceAllocation The resource allocation phase is
250 completed. No specific action is
251 required here. This notification can
252 be used to perform any chipsetspecific
255 @param[in] This The instance pointer of
256 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
258 @param[in] Phase The phase during enumeration
260 @retval EFI_NOT_READY This phase cannot be entered at this time. For
261 example, this error is valid for a Phase of
262 EfiPciHostBridgeAllocateResources if
263 SubmitResources() has not been called for one
264 or more PCI root bridges before this call
266 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
267 This error is valid for a Phase of
268 EfiPciHostBridgeSetResources.
270 @retval EFI_INVALID_PARAMETER Invalid phase parameter
272 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
273 lack of resources. This error is valid for a
274 Phase of EfiPciHostBridgeAllocateResources if
275 the previously submitted resource requests
276 cannot be fulfilled or were only partially
279 @retval EFI_SUCCESS The notification was accepted without any
285 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
286 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
289 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
290 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
291 PCI_RESOURCE_TYPE Index
;
293 EFI_PHYSICAL_ADDRESS BaseAddress
;
295 UINTN BitsOfAlignment
;
297 EFI_STATUS ReturnStatus
;
299 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
303 case EfiPciHostBridgeBeginEnumeration
:
304 if (HostBridgeInstance
->CanRestarted
) {
306 // Reset the Each Root Bridge
308 List
= HostBridgeInstance
->Head
.ForwardLink
;
310 while (List
!= &HostBridgeInstance
->Head
) {
311 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
312 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
313 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
314 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
315 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
316 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
319 List
= List
->ForwardLink
;
322 HostBridgeInstance
->ResourceSubmited
= FALSE
;
323 HostBridgeInstance
->CanRestarted
= TRUE
;
328 return EFI_NOT_READY
;
332 case EfiPciHostBridgeEndEnumeration
:
335 case EfiPciHostBridgeBeginBusAllocation
:
337 // No specific action is required here, can perform any chipset specific programing
339 HostBridgeInstance
->CanRestarted
= FALSE
;
342 case EfiPciHostBridgeEndBusAllocation
:
344 // No specific action is required here, can perform any chipset specific programing
346 //HostBridgeInstance->CanRestarted = FALSE;
349 case EfiPciHostBridgeBeginResourceAllocation
:
351 // No specific action is required here, can perform any chipset specific programing
353 //HostBridgeInstance->CanRestarted = FALSE;
356 case EfiPciHostBridgeAllocateResources
:
357 ReturnStatus
= EFI_SUCCESS
;
358 if (HostBridgeInstance
->ResourceSubmited
) {
360 // Take care of the resource dependencies between the root bridges
362 List
= HostBridgeInstance
->Head
.ForwardLink
;
364 while (List
!= &HostBridgeInstance
->Head
) {
365 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
366 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
367 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
369 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
372 // Get the number of '1' in Alignment.
374 BitsOfAlignment
= (UINTN
) (HighBitSet64 (RootBridgeInstance
->ResAllocNode
[Index
].Alignment
) + 1);
380 // It is impossible for this chipset to align 0xFFFF for IO16
383 if (BitsOfAlignment
>= 16) {
387 Status
= gDS
->AllocateIoSpace (
388 EfiGcdAllocateAnySearchBottomUp
,
397 if (!EFI_ERROR (Status
)) {
398 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINTN
)BaseAddress
;
399 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
401 ReturnStatus
= Status
;
402 if (Status
!= EFI_OUT_OF_RESOURCES
) {
403 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
412 // It is impossible for this chipset to align 0xFFFFFFFF for Mem32
416 if (BitsOfAlignment
>= 32) {
420 Status
= gDS
->AllocateMemorySpace (
421 EfiGcdAllocateAnySearchBottomUp
,
422 EfiGcdMemoryTypeMemoryMappedIo
,
430 if (!EFI_ERROR (Status
)) {
431 // We were able to allocate the PCI memory
432 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINTN
)BaseAddress
;
433 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
436 // Not able to allocate enough PCI memory
437 ReturnStatus
= Status
;
439 if (Status
!= EFI_OUT_OF_RESOURCES
) {
440 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
449 ReturnStatus
= EFI_ABORTED
;
458 List
= List
->ForwardLink
;
464 return EFI_NOT_READY
;
468 case EfiPciHostBridgeSetResources
:
471 case EfiPciHostBridgeFreeResources
:
472 ReturnStatus
= EFI_SUCCESS
;
473 List
= HostBridgeInstance
->Head
.ForwardLink
;
474 while (List
!= &HostBridgeInstance
->Head
) {
475 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
476 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
477 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
478 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
479 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
483 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
484 if (EFI_ERROR (Status
)) {
485 ReturnStatus
= Status
;
490 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
491 if (EFI_ERROR (Status
)) {
492 ReturnStatus
= Status
;
510 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
511 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
512 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
513 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
517 List
= List
->ForwardLink
;
520 HostBridgeInstance
->ResourceSubmited
= FALSE
;
521 HostBridgeInstance
->CanRestarted
= TRUE
;
524 case EfiPciHostBridgeEndResourceAllocation
:
525 HostBridgeInstance
->CanRestarted
= FALSE
;
529 return EFI_INVALID_PARAMETER
;
536 Return the device handle of the next PCI root bridge that is associated with
539 This function is called multiple times to retrieve the device handles of all
540 the PCI root bridges that are associated with this PCI host bridge. Each PCI
541 host bridge is associated with one or more PCI root bridges. On each call,
542 the handle that was returned by the previous call is passed into the
543 interface, and on output the interface returns the device handle of the next
544 PCI root bridge. The caller can use the handle to obtain the instance of the
545 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for that root bridge. When there are no more
546 PCI root bridges to report, the interface returns EFI_NOT_FOUND. A PCI
547 enumerator must enumerate the PCI root bridges in the order that they are
548 returned by this function.
550 For D945 implementation, there is only one root bridge in PCI host bridge.
552 @param[in] This The instance pointer of
553 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
555 @param[in, out] RootBridgeHandle Returns the device handle of the next PCI
558 @retval EFI_SUCCESS If parameter RootBridgeHandle = NULL, then
559 return the first Rootbridge handle of the
560 specific Host bridge and return EFI_SUCCESS.
562 @retval EFI_NOT_FOUND Can not find the any more root bridge in
563 specific host bridge.
565 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE that was
566 returned on a previous call to
572 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
573 IN OUT EFI_HANDLE
*RootBridgeHandle
576 BOOLEAN NoRootBridge
;
578 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
579 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
582 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
583 List
= HostBridgeInstance
->Head
.ForwardLink
;
586 while (List
!= &HostBridgeInstance
->Head
) {
587 NoRootBridge
= FALSE
;
588 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
589 if (*RootBridgeHandle
== NULL
) {
591 // Return the first Root Bridge Handle of the Host Bridge
593 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
596 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
600 List
= List
->ForwardLink
;
601 if (List
!=&HostBridgeInstance
->Head
) {
602 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
603 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
606 return EFI_NOT_FOUND
;
611 List
= List
->ForwardLink
;
615 return EFI_NOT_FOUND
;
617 return EFI_INVALID_PARAMETER
;
622 Returns the allocation attributes of a PCI root bridge.
624 The function returns the allocation attributes of a specific PCI root bridge.
625 The attributes can vary from one PCI root bridge to another. These attributes
626 are different from the decode-related attributes that are returned by the
627 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
628 RootBridgeHandle parameter is used to specify the instance of the PCI root
629 bridge. The device handles of all the root bridges that are associated with
630 this host bridge must be obtained by calling GetNextRootBridge(). The
631 attributes are static in the sense that they do not change during or after
632 the enumeration process. The hardware may provide mechanisms to change the
633 attributes on the fly, but such changes must be completed before
634 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is installed. The permitted
635 values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
636 "Related Definitions" below. The caller uses these attributes to combine
637 multiple resource requests.
639 For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI
640 bus enumerator needs to include requests for the prefetchable memory in the
641 nonprefetchable memory pool and not request any prefetchable memory.
643 Attribute Description
644 ------------------------------------ ---------------------------------------
645 EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then the PCI root
646 bridge does not support separate
647 windows for nonprefetchable and
648 prefetchable memory. A PCI bus driver
649 needs to include requests for
650 prefetchable memory in the
651 nonprefetchable memory pool.
653 EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then the PCI root
654 bridge supports 64-bit memory windows.
655 If this bit is not set, the PCI bus
656 driver needs to include requests for a
657 64-bit memory address in the
658 corresponding 32-bit memory pool.
660 @param[in] This The instance pointer of
661 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
663 @param[in] RootBridgeHandle The device handle of the PCI root bridge in
664 which the caller is interested. Type
665 EFI_HANDLE is defined in
666 InstallProtocolInterface() in the UEFI 2.0
669 @param[out] Attributes The pointer to attribte of root bridge, it is
672 @retval EFI_INVALID_PARAMETER Attribute pointer is NULL
674 @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid.
676 @retval EFI_SUCCESS Success to get attribute of interested root
682 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
683 IN EFI_HANDLE RootBridgeHandle
,
684 OUT UINT64
*Attributes
688 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
689 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
691 if (Attributes
== NULL
) {
692 return EFI_INVALID_PARAMETER
;
695 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
696 List
= HostBridgeInstance
->Head
.ForwardLink
;
698 while (List
!= &HostBridgeInstance
->Head
) {
699 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
700 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
701 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
704 List
= List
->ForwardLink
;
708 // RootBridgeHandle is not an EFI_HANDLE
709 // that was returned on a previous call to GetNextRootBridge()
711 return EFI_INVALID_PARAMETER
;
715 Sets up the specified PCI root bridge for the bus enumeration process.
717 This member function sets up the root bridge for bus enumeration and returns
718 the PCI bus range over which the search should be performed in ACPI 2.0
719 resource descriptor format.
722 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
725 @param[in] RootBridgeHandle The PCI Root Bridge to be set up.
727 @param[out] Configuration Pointer to the pointer to the PCI bus resource
730 @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
732 @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor tag.
734 @retval EFI_SUCCESS Sucess to allocate ACPI resource descriptor.
739 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
740 IN EFI_HANDLE RootBridgeHandle
,
741 OUT VOID
**Configuration
745 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
746 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
752 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
753 List
= HostBridgeInstance
->Head
.ForwardLink
;
755 while (List
!= &HostBridgeInstance
->Head
) {
756 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
757 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
759 // Set up the Root Bridge for Bus Enumeration
761 BusStart
= RootBridgeInstance
->BusBase
;
762 BusEnd
= RootBridgeInstance
->BusLimit
;
764 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
767 Buffer
= AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
));
768 if (Buffer
== NULL
) {
769 return EFI_OUT_OF_RESOURCES
;
772 Temp
= (UINT8
*)Buffer
;
774 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
775 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
776 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
777 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
778 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
779 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
780 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
781 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
782 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
783 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
= BusEnd
- BusStart
+ 1;
785 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
786 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
787 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
789 *Configuration
= Buffer
;
792 List
= List
->ForwardLink
;
795 return EFI_INVALID_PARAMETER
;
799 Programs the PCI root bridge hardware so that it decodes the specified PCI
802 This member function programs the specified PCI root bridge to decode the bus
803 range that is specified by the input parameter Configuration.
804 The bus range information is specified in terms of the ACPI 2.0 resource
808 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
811 @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to be
814 @param[in] Configuration The pointer to the PCI bus resource descriptor
816 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
819 @retval EFI_INVALID_PARAMETER Configuration is NULL.
821 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
822 2.0 resource descriptor.
824 @retval EFI_INVALID_PARAMETER Configuration does not include a valid ACPI
825 2.0 bus resource descriptor.
827 @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 resource
828 descriptors other than bus descriptors.
830 @retval EFI_INVALID_PARAMETER Configuration contains one or more invalid
831 ACPI resource descriptors.
833 @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for this
836 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this
839 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
841 @retval EFI_SUCCESS The bus range for the PCI root bridge was
847 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
848 IN EFI_HANDLE RootBridgeHandle
,
849 IN VOID
*Configuration
853 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
854 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
860 if (Configuration
== NULL
) {
861 return EFI_INVALID_PARAMETER
;
867 // Check the Configuration is valid
869 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
870 return EFI_INVALID_PARAMETER
;
873 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
874 return EFI_INVALID_PARAMETER
;
877 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
878 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
879 return EFI_INVALID_PARAMETER
;
882 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
883 List
= HostBridgeInstance
->Head
.ForwardLink
;
887 while (List
!= &HostBridgeInstance
->Head
) {
888 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
889 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
890 BusStart
= (UINTN
)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->AddrRangeMin
;
891 BusLen
= (UINTN
)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->AddrLen
;
892 BusEnd
= BusStart
+ BusLen
- 1;
894 if (BusStart
> BusEnd
) {
895 return EFI_INVALID_PARAMETER
;
898 if ((BusStart
< RootBridgeInstance
->BusBase
) || (BusEnd
> RootBridgeInstance
->BusLimit
)) {
899 return EFI_INVALID_PARAMETER
;
903 // Update the Bus Range
905 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
906 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
907 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
910 // Program the Root Bridge Hardware
916 List
= List
->ForwardLink
;
919 return EFI_INVALID_PARAMETER
;
924 Submits the I/O and memory resource requirements for the specified PCI root
927 This function is used to submit all the I/O and memory resources that are
928 required by the specified PCI root bridge. The input parameter Configuration
929 is used to specify the following:
930 - The various types of resources that are required
931 - The associated lengths in terms of ACPI 2.0 resource descriptor format
933 @param[in] This Pointer to the
934 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
937 @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory
938 resource requirements are being submitted.
940 @param[in] Configuration The pointer to the PCI I/O and PCI memory
943 @retval EFI_SUCCESS The I/O and memory resource requests for a PCI
944 root bridge were accepted.
946 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
949 @retval EFI_INVALID_PARAMETER Configuration is NULL.
951 @retval EFI_INVALID_PARAMETER Configuration does not point to a valid ACPI
952 2.0 resource descriptor.
954 @retval EFI_INVALID_PARAMETER Configuration includes requests for one or
955 more resource types that are not supported by
956 this PCI root bridge. This error will happen
957 if the caller did not combine resources
958 according to Attributes that were returned by
959 GetAllocAttributes().
961 @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid.
963 @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for this PCI
966 @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid for
967 this PCI root bridge.
972 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
973 IN EFI_HANDLE RootBridgeHandle
,
974 IN VOID
*Configuration
978 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
979 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
981 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
986 // Check the input parameter: Configuration
988 if (Configuration
== NULL
) {
989 return EFI_INVALID_PARAMETER
;
992 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
993 List
= HostBridgeInstance
->Head
.ForwardLink
;
995 Temp
= (UINT8
*)Configuration
;
996 while ( *Temp
== 0x8A) {
997 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1000 return EFI_INVALID_PARAMETER
;
1003 Temp
= (UINT8
*)Configuration
;
1004 while (List
!= &HostBridgeInstance
->Head
) {
1005 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1006 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1007 while ( *Temp
== 0x8A) {
1008 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1011 // Check Address Length
1013 if (Ptr
->AddrLen
> 0xffffffff) {
1014 return EFI_INVALID_PARAMETER
;
1018 // Check address range alignment
1020 if (Ptr
->AddrRangeMax
>= 0xffffffff || Ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (Ptr
->AddrRangeMax
+ 1) - 1)) {
1021 return EFI_INVALID_PARAMETER
;
1024 switch (Ptr
->ResType
) {
1029 // Check invalid Address Sapce Granularity
1031 if (Ptr
->AddrSpaceGranularity
!= 32) {
1032 return EFI_INVALID_PARAMETER
;
1036 // check the memory resource request is supported by PCI root bridge
1038 if (RootBridgeInstance
->RootBridgeAttrib
== EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
1039 Ptr
->SpecificFlag
== 0x06) {
1040 return EFI_INVALID_PARAMETER
;
1043 AddrLen
= Ptr
->AddrLen
;
1044 Alignment
= Ptr
->AddrRangeMax
;
1045 if (Ptr
->AddrSpaceGranularity
== 32) {
1046 if (Ptr
->SpecificFlag
== 0x06) {
1050 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
= ResSubmitted
;
1052 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1053 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
= Alignment
;
1054 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
= ResRequested
;
1055 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1059 if (Ptr
->AddrSpaceGranularity
== 64) {
1060 if (Ptr
->SpecificFlag
== 0x06) {
1061 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
= ResSubmitted
;
1063 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
= ResSubmitted
;
1069 AddrLen
= (UINTN
) Ptr
->AddrLen
;
1070 Alignment
= (UINTN
) Ptr
->AddrRangeMax
;
1071 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
1072 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
1073 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
1074 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1081 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1087 List
= List
->ForwardLink
;
1090 return EFI_INVALID_PARAMETER
;
1094 Returns the proposed resource settings for the specified PCI root bridge.
1096 This member function returns the proposed resource settings for the
1097 specified PCI root bridge. The proposed resource settings are prepared when
1098 NotifyPhase() is called with a Phase of EfiPciHostBridgeAllocateResources.
1099 The output parameter Configuration specifies the following:
1100 - The various types of resources, excluding bus resources, that are
1102 - The associated lengths in terms of ACPI 2.0 resource descriptor format
1104 @param[in] This Pointer to the
1105 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1108 @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HANDLE is
1109 defined in InstallProtocolInterface() in the
1110 UEFI 2.0 Specification.
1112 @param[out] Configuration The pointer to the pointer to the PCI I/O and
1113 memory resource descriptor.
1115 @retval EFI_SUCCESS The requested parameters were returned.
1117 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1120 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1122 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
1127 GetProposedResources(
1128 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1129 IN EFI_HANDLE RootBridgeHandle
,
1130 OUT VOID
**Configuration
1134 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1135 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1140 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1146 // Get the Host Bridge Instance from the resource allocation protocol
1148 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1149 List
= HostBridgeInstance
->Head
.ForwardLink
;
1152 // Enumerate the root bridges in this host bridge
1154 while (List
!= &HostBridgeInstance
->Head
) {
1155 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1156 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1157 for (Index
= 0; Index
< TypeBus
; Index
++) {
1158 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1164 return EFI_INVALID_PARAMETER
;
1167 Buffer
= AllocateZeroPool (Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
));
1168 if (Buffer
== NULL
) {
1169 return EFI_OUT_OF_RESOURCES
;
1173 for (Index
= 0; Index
< TypeBus
; Index
++) {
1174 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1175 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1176 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1188 Ptr
->SpecificFlag
= 0;
1189 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1190 Ptr
->AddrRangeMax
= 0;
1191 Ptr
->AddrTranslationOffset
= \
1192 (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
1193 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1204 Ptr
->SpecificFlag
= 0;
1205 Ptr
->AddrSpaceGranularity
= 32;
1206 Ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1207 Ptr
->AddrRangeMax
= 0;
1208 Ptr
->AddrTranslationOffset
= \
1209 (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
1210 Ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1215 // Prefetch memory 32
1221 Ptr
->SpecificFlag
= 6;
1222 Ptr
->AddrSpaceGranularity
= 32;
1223 Ptr
->AddrRangeMin
= 0;
1224 Ptr
->AddrRangeMax
= 0;
1225 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1237 Ptr
->SpecificFlag
= 0;
1238 Ptr
->AddrSpaceGranularity
= 64;
1239 Ptr
->AddrRangeMin
= 0;
1240 Ptr
->AddrRangeMax
= 0;
1241 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1247 // Prefetch memory 64
1253 Ptr
->SpecificFlag
= 6;
1254 Ptr
->AddrSpaceGranularity
= 64;
1255 Ptr
->AddrRangeMin
= 0;
1256 Ptr
->AddrRangeMax
= 0;
1257 Ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1262 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1266 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1267 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1269 *Configuration
= Buffer
;
1274 List
= List
->ForwardLink
;
1277 return EFI_INVALID_PARAMETER
;
1281 Provides the hooks from the PCI bus driver to every PCI controller
1282 (device/function) at various stages of the PCI enumeration process that allow
1283 the host bridge driver to preinitialize individual PCI controllers before
1286 This function is called during the PCI enumeration process. No specific
1287 action is expected from this member function. It allows the host bridge
1288 driver to preinitialize individual PCI controllers before enumeration.
1290 @param This Pointer to the
1291 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
1294 @param RootBridgeHandle The associated PCI root bridge handle. Type
1295 EFI_HANDLE is defined in InstallProtocolInterface()
1296 in the UEFI 2.0 Specification.
1298 @param PciAddress The address of the PCI device on the PCI bus. This
1299 address can be passed to the
1300 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to
1301 access the PCI configuration space of the device.
1302 See Table 12-1 in the UEFI 2.0 Specification for the
1304 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
1306 @param Phase The phase of the PCI device enumeration.
1308 @retval EFI_SUCCESS The requested parameters were returned.
1310 @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge
1313 @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined
1315 EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
1317 @retval EFI_DEVICE_ERROR Programming failed due to a hardware error.
1318 The PCI enumerator should not enumerate this
1319 device, including its child devices if it is
1320 a PCI-to-PCI bridge.
1324 PreprocessController (
1325 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1326 IN EFI_HANDLE RootBridgeHandle
,
1327 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1328 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1331 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1332 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1335 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1336 List
= HostBridgeInstance
->Head
.ForwardLink
;
1339 // Enumerate the root bridges in this host bridge
1341 while (List
!= &HostBridgeInstance
->Head
) {
1342 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1343 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1346 List
= List
->ForwardLink
;
1348 if (List
== &HostBridgeInstance
->Head
) {
1349 return EFI_INVALID_PARAMETER
;
1352 if ((UINT32
)Phase
> EfiPciBeforeResourceCollection
) {
1353 return EFI_INVALID_PARAMETER
;