2 Pci Host Bridge driver for a simple IIO. There is only one PCI Root Bridge in the system.
3 Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation.
5 Copyright (c) 2013-2015 Intel Corporation.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "PciHostBridge.h"
13 #include <IntelQNCRegs.h>
16 // We can hardcode the following for a Simple IIO -
17 // Root Bridge Count within the host bridge
18 // Root Bridge's device path
19 // Root Bridge's resource appeture
21 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath
[ROOT_BRIDGE_COUNT
] = {
28 (UINT8
) (sizeof (ACPI_HID_DEVICE_PATH
)),
29 (UINT8
) ((sizeof (ACPI_HID_DEVICE_PATH
)) >> 8)
37 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
39 END_DEVICE_PATH_LENGTH
,
46 EFI_HANDLE mDriverImageHandle
;
47 PCI_ROOT_BRIDGE_RESOURCE_APERTURE
*mResAperture
;
54 InitializePciHostBridge (
55 IN EFI_HANDLE ImageHandle
,
56 IN EFI_SYSTEM_TABLE
*SystemTable
62 Entry point of this driver.
66 ImageHandle - Image handle of this driver.
67 SystemTable - Pointer to standard EFI system table.
71 EFI_SUCCESS - Succeed.
72 EFI_DEVICE_ERROR - Fail to install PCI_ROOT_BRIDGE_IO protocol.
77 UINTN TotalRootBridgeFound
;
78 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
79 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
80 UINT64 AllocAttributes
;
81 EFI_PHYSICAL_ADDRESS BaseAddress
;
85 mDriverImageHandle
= ImageHandle
;
88 // Most systems in the world including complex servers
89 // have only one Host Bridge. Create Host Bridge Device Handle
91 Status
= gBS
->AllocatePool(EfiBootServicesData
, sizeof(PCI_HOST_BRIDGE_INSTANCE
), (VOID
**) &HostBridge
);
92 ASSERT_EFI_ERROR (Status
);
93 ZeroMem (HostBridge
, sizeof (PCI_HOST_BRIDGE_INSTANCE
));
95 HostBridge
->Signature
= PCI_HOST_BRIDGE_SIGNATURE
;
96 HostBridge
->RootBridgeCount
= 1;
97 HostBridge
->ResourceSubmited
= FALSE
;
98 HostBridge
->CanRestarted
= TRUE
;
100 // InitializeListHead (&HostBridge->Head);
102 HostBridge
->ResAlloc
.NotifyPhase
= NotifyPhase
;
103 HostBridge
->ResAlloc
.GetNextRootBridge
= GetNextRootBridge
;
104 HostBridge
->ResAlloc
.GetAllocAttributes
= GetAttributes
;
105 HostBridge
->ResAlloc
.StartBusEnumeration
= StartBusEnumeration
;
106 HostBridge
->ResAlloc
.SetBusNumbers
= SetBusNumbers
;
107 HostBridge
->ResAlloc
.SubmitResources
= SubmitResources
;
108 HostBridge
->ResAlloc
.GetProposedResources
= GetProposedResources
;
109 HostBridge
->ResAlloc
.PreprocessController
= PreprocessController
;
111 Status
= gBS
->InstallProtocolInterface (
112 &HostBridge
->HostBridgeHandle
,
113 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
114 EFI_NATIVE_INTERFACE
,
115 &HostBridge
->ResAlloc
117 if (EFI_ERROR (Status
)) {
118 gBS
->FreePool (HostBridge
);
119 return EFI_DEVICE_ERROR
;
122 Status
= gBS
->AllocatePool (EfiBootServicesData
,
123 HostBridge
->RootBridgeCount
* sizeof(PCI_ROOT_BRIDGE_RESOURCE_APERTURE
),
124 (VOID
**) &mResAperture
);
125 ASSERT_EFI_ERROR (Status
);
126 ZeroMem (mResAperture
, HostBridge
->RootBridgeCount
* sizeof(PCI_ROOT_BRIDGE_RESOURCE_APERTURE
));
128 DEBUG ((EFI_D_INFO
, "Address of resource Aperture: %x\n", mResAperture
));
131 // Create Root Bridge Device Handle in this Host Bridge
133 InitializeListHead (&HostBridge
->Head
);
135 TotalRootBridgeFound
= 0;
137 Status
= gBS
->AllocatePool ( EfiBootServicesData
,sizeof (PCI_ROOT_BRIDGE_INSTANCE
), (VOID
**) &PrivateData
);
138 ASSERT_EFI_ERROR (Status
);
139 ZeroMem (PrivateData
, sizeof (PCI_ROOT_BRIDGE_INSTANCE
));
141 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
142 PrivateData
->DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) &mEfiPciRootBridgeDevicePath
[TotalRootBridgeFound
];
143 AllocAttributes
= GetAllocAttributes (TotalRootBridgeFound
);
145 SimpleIioRootBridgeConstructor (
147 HostBridge
->HostBridgeHandle
,
148 &(mResAperture
[TotalRootBridgeFound
]),
152 // Update Root Bridge with UDS resource information
154 PrivateData
->Aperture
.BusBase
= QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE
;
155 PrivateData
->Aperture
.BusLimit
= QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT
;
156 PrivateData
->Aperture
.Mem32Base
= PcdGet32 (PcdPciHostBridgeMemory32Base
);
157 PrivateData
->Aperture
.Mem32Limit
= PcdGet32 (PcdPciHostBridgeMemory32Base
) + (PcdGet32 (PcdPciHostBridgeMemory32Size
) - 1);
158 PrivateData
->Aperture
.IoBase
= PcdGet16 (PcdPciHostBridgeIoBase
);
159 PrivateData
->Aperture
.IoLimit
= PcdGet16 (PcdPciHostBridgeIoBase
) + (PcdGet16 (PcdPciHostBridgeIoSize
) - 1);
161 DEBUG ((EFI_D_INFO
, "PCI Host Bridge BusBase: %x\n", QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE
));
162 DEBUG ((EFI_D_INFO
, "PCI Host Bridge BusLimit: %x\n", QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT
));
163 DEBUG ((EFI_D_INFO
, "PCI Host Bridge PciResourceMem32Base: %x\n", PcdGet32 (PcdPciHostBridgeMemory32Base
)));
164 DEBUG ((EFI_D_INFO
, "PCI Host Bridge PciResourceMem32Limit: %x\n", PcdGet32 (PcdPciHostBridgeMemory32Base
) + (PcdGet32 (PcdPciHostBridgeMemory32Size
) - 1)));
165 DEBUG ((EFI_D_INFO
, "PCI Host Bridge PciResourceMem64Base: %lX\n", PcdGet64 (PcdPciHostBridgeMemory64Base
)));
166 DEBUG ((EFI_D_INFO
, "PCI Host Bridge PciResourceMem64Limit: %lX\n", PcdGet64 (PcdPciHostBridgeMemory64Base
) + (PcdGet64 (PcdPciHostBridgeMemory64Size
) - 1)));
167 DEBUG ((EFI_D_INFO
, "PCI Host Bridge PciResourceIoBase: %x\n", PcdGet16 (PcdPciHostBridgeIoBase
)));
168 DEBUG ((EFI_D_INFO
, "PCI Host Bridge PciResourceIoLimit: %x\n", PcdGet16 (PcdPciHostBridgeIoBase
) + (PcdGet16 (PcdPciHostBridgeIoSize
) - 1)));
170 PrivateData
->Handle
= NULL
;
171 Status
= gBS
->InstallMultipleProtocolInterfaces (
172 &PrivateData
->Handle
,
173 &gEfiDevicePathProtocolGuid
,
174 PrivateData
->DevicePath
,
175 &gEfiPciRootBridgeIoProtocolGuid
,
179 ASSERT_EFI_ERROR (Status
);
181 InsertTailList (&HostBridge
->Head
, &PrivateData
->Link
);
182 TotalRootBridgeFound
++; // This is a valid rootbridge so imcrement total root bridges found
185 // Add PCIE base into Runtime memory so that it can be reported in E820 table
187 Status
= gDS
->AddMemorySpace (
188 EfiGcdMemoryTypeMemoryMappedIo
,
189 PcdGet64 (PcdPciExpressBaseAddress
),
190 PcdGet64 (PcdPciExpressSize
),
191 EFI_MEMORY_RUNTIME
| EFI_MEMORY_UC
193 ASSERT_EFI_ERROR(Status
);
195 BaseAddress
= PcdGet64 (PcdPciExpressBaseAddress
);
197 Status
= gDS
->AllocateMemorySpace (
198 EfiGcdAllocateAddress
,
199 EfiGcdMemoryTypeMemoryMappedIo
,
201 PcdGet64 (PcdPciExpressSize
),
206 ASSERT_EFI_ERROR(Status
);
208 Status
= gDS
->SetMemorySpaceAttributes (
209 PcdGet64 (PcdPciExpressBaseAddress
),
210 PcdGet64 (PcdPciExpressSize
),
213 ASSERT_EFI_ERROR (Status
);
215 if (PcdGet16 (PcdPciHostBridgeIoSize
) > 0) {
217 // At present, we use up the first 4k for fixed ranges like
218 // ICH GPIO, ACPI and ISA devices. The first 4k is not
219 // tracked through GCD. It should be.
221 Status
= gDS
->AddIoSpace (
223 PcdGet16(PcdPciHostBridgeIoBase
),
224 PcdGet16(PcdPciHostBridgeIoSize
)
226 ASSERT_EFI_ERROR (Status
);
229 if (PcdGet32(PcdPciHostBridgeMemory32Size
) > 0) {
231 // Shouldn't the capabilities be UC?
233 Status
= gDS
->AddMemorySpace (
234 EfiGcdMemoryTypeMemoryMappedIo
,
235 PcdGet32(PcdPciHostBridgeMemory32Base
),
236 PcdGet32(PcdPciHostBridgeMemory32Size
),
239 ASSERT_EFI_ERROR (Status
);
248 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
249 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
255 Enter a certain phase of the PCI enumeration process.
259 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
260 Phase - The phase during enumeration.
264 EFI_SUCCESS - Succeed.
265 EFI_INVALID_PARAMETER - Wrong phase parameter passed in.
266 EFI_NOT_READY - Resources have not been submitted yet.
270 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
271 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
272 PCI_RESOURCE_TYPE Index
;
273 EFI_LIST_ENTRY
*List
;
274 EFI_PHYSICAL_ADDRESS BaseAddress
;
276 UINTN BitsOfAlignment
;
279 EFI_STATUS ReturnStatus
;
280 PCI_RESOURCE_TYPE Index1
;
281 PCI_RESOURCE_TYPE Index2
;
282 BOOLEAN ResNodeHandled
[TypeMax
];
285 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
288 case EfiPciHostBridgeBeginEnumeration
:
289 if (HostBridgeInstance
->CanRestarted
) {
293 List
= HostBridgeInstance
->Head
.ForwardLink
;
295 while (List
!= &HostBridgeInstance
->Head
) {
296 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
297 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
298 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
299 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
300 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
301 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
304 List
= List
->ForwardLink
;
307 HostBridgeInstance
->ResourceSubmited
= FALSE
;
308 HostBridgeInstance
->CanRestarted
= TRUE
;
313 return EFI_NOT_READY
;
317 case EfiPciHostBridgeEndEnumeration
:
321 case EfiPciHostBridgeBeginBusAllocation
:
323 // No specific action is required here, can perform any chipset specific programing
325 HostBridgeInstance
->CanRestarted
= FALSE
;
329 case EfiPciHostBridgeEndBusAllocation
:
331 // No specific action is required here, can perform any chipset specific programing
333 // HostBridgeInstance->CanRestarted = FALSE;
338 case EfiPciHostBridgeBeginResourceAllocation
:
340 // No specific action is required here, can perform any chipset specific programing
342 // HostBridgeInstance->CanRestarted = FALSE;
347 case EfiPciHostBridgeAllocateResources
:
348 ReturnStatus
= EFI_SUCCESS
;
349 if (HostBridgeInstance
->ResourceSubmited
) {
350 List
= HostBridgeInstance
->Head
.ForwardLink
;
351 while (List
!= &HostBridgeInstance
->Head
) {
352 for (Index1
= TypeIo
; Index1
< TypeBus
; Index1
++) {
353 ResNodeHandled
[Index1
] = FALSE
;
356 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
357 DEBUG ((EFI_D_INFO
, "Address of RootBridgeInstance: %x)\n", RootBridgeInstance
));
358 DEBUG ((EFI_D_INFO
, " Signature: %x\n", RootBridgeInstance
->Signature
));
359 DEBUG ((EFI_D_INFO
, " Bus Number Assigned: %x\n", RootBridgeInstance
->BusNumberAssigned
));
360 DEBUG ((EFI_D_INFO
, " Bus Scan Count: %x\n", RootBridgeInstance
->BusScanCount
));
362 for (Index1
= TypeIo
; Index1
< TypeBus
; Index1
++) {
363 if (RootBridgeInstance
->ResAllocNode
[Index1
].Status
== ResNone
) {
364 ResNodeHandled
[Index1
] = TRUE
;
367 // Allocate the resource node with max alignment at first
371 for (Index2
= TypeIo
; Index2
< TypeBus
; Index2
++) {
372 if (ResNodeHandled
[Index2
]) {
375 if (MaxAlignment
<= RootBridgeInstance
->ResAllocNode
[Index2
].Alignment
) {
376 MaxAlignment
= RootBridgeInstance
->ResAllocNode
[Index2
].Alignment
;
381 if (Index
< TypeMax
) {
382 ResNodeHandled
[Index
] = TRUE
;
387 Alignment
= RootBridgeInstance
->ResAllocNode
[Index
].Alignment
;
390 // Get the number of '1' in Alignment.
392 for (BitsOfAlignment
= 0; Alignment
!= 0; BitsOfAlignment
++) {
393 Alignment
= RShiftU64 (Alignment
, 1);
396 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
397 Alignment
= RootBridgeInstance
->ResAllocNode
[Index
].Alignment
;
399 DEBUG ((EFI_D_INFO
, "\n\nResource Type to assign : %x\n", Index
));
400 DEBUG ((EFI_D_INFO
, " Length to allocate: %x\n", RootBridgeInstance
->ResAllocNode
[Index
].Length
));
401 DEBUG ((EFI_D_INFO
, " Aligment: %x\n", Alignment
));
405 if (RootBridgeInstance
->Aperture
.IoBase
< RootBridgeInstance
->Aperture
.IoLimit
) {
407 // It is impossible for 0xFFFF Alignment for IO16
409 if (BitsOfAlignment
>= 16)
412 BaseAddress
= RootBridgeInstance
->Aperture
.IoBase
;
415 // Have to make sure Aligment is handled seeing we are doing direct address allocation
417 if ((BaseAddress
& ~(Alignment
)) != BaseAddress
)
418 BaseAddress
= ((BaseAddress
+ Alignment
) & ~(Alignment
));
420 while((BaseAddress
+ AddrLen
) <= RootBridgeInstance
->Aperture
.IoLimit
+ 1) {
422 Status
= gDS
->AllocateIoSpace ( EfiGcdAllocateAddress
, EfiGcdIoTypeIo
, BitsOfAlignment
,
423 AddrLen
, &BaseAddress
, mDriverImageHandle
, NULL
);
425 if (!EFI_ERROR (Status
)) {
426 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINT64
) BaseAddress
;
427 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
431 BaseAddress
+= (Alignment
+ 1);
437 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResAllocated
) {
439 // No Room at the Inn for this resources request
441 ReturnStatus
= EFI_OUT_OF_RESOURCES
;
447 if (RootBridgeInstance
->Aperture
.Mem32Base
< RootBridgeInstance
->Aperture
.Mem32Limit
) {
449 BaseAddress
= RootBridgeInstance
->Aperture
.Mem32Base
;
451 // Have to make sure Aligment is handled seeing we are doing direct address allocation
453 if ((BaseAddress
& ~(Alignment
)) != BaseAddress
)
454 BaseAddress
= ((BaseAddress
+ Alignment
) & ~(Alignment
));
456 while((BaseAddress
+ AddrLen
) <= RootBridgeInstance
->Aperture
.Mem32Limit
+ 1) {
458 Status
= gDS
->AllocateMemorySpace ( EfiGcdAllocateAddress
, EfiGcdMemoryTypeMemoryMappedIo
,
459 BitsOfAlignment
, AddrLen
, &BaseAddress
, mDriverImageHandle
, NULL
);
461 if (!EFI_ERROR (Status
)) {
462 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINT64
) BaseAddress
;
463 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
467 BaseAddress
+= (Alignment
+ 1);
472 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResAllocated
) {
474 // No Room at the Inn for this resources request
476 ReturnStatus
= EFI_OUT_OF_RESOURCES
;
483 if (RootBridgeInstance
->Aperture
.Mem32Base
< RootBridgeInstance
->Aperture
.Mem32Limit
) {
485 BaseAddress
= RootBridgeInstance
->Aperture
.Mem32Limit
+ 1;
486 BaseAddress
-= AddrLen
;
489 // Have to make sure Aligment is handled seeing we are doing direct address allocation
491 if ((BaseAddress
& ~(Alignment
)) != BaseAddress
)
492 BaseAddress
= ((BaseAddress
) & ~(Alignment
));
494 while(RootBridgeInstance
->Aperture
.Mem32Base
<= BaseAddress
) {
496 DEBUG ((EFI_D_INFO
, " Attempting %x allocation at 0x%lx .....", Index
, BaseAddress
));
497 Status
= gDS
->AllocateMemorySpace ( EfiGcdAllocateAddress
, EfiGcdMemoryTypeMemoryMappedIo
,
498 BitsOfAlignment
, AddrLen
, &BaseAddress
, mDriverImageHandle
, NULL
);
500 if (!EFI_ERROR (Status
)) {
501 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINT64
) BaseAddress
;
502 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
503 DEBUG ((EFI_D_INFO
, "... Passed!!\n"));
504 goto TypePMem32Found
;
506 DEBUG ((EFI_D_INFO
, "... Failed!!\n"));
507 BaseAddress
-= (Alignment
+ 1);
512 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResAllocated
) {
514 // No Room at the Inn for this resources request
516 ReturnStatus
= EFI_OUT_OF_RESOURCES
;
523 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResAllocated
) {
525 // If 64-bit resourcing is not available, then try as PMem32
527 goto StartTypePMem32
;
534 } // End switch (Index)
536 DEBUG ((EFI_D_INFO
, "Resource Type Assigned: %x\n", Index
));
537 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
538 DEBUG ((EFI_D_INFO
, " Base Address Assigned: %x\n", RootBridgeInstance
->ResAllocNode
[Index
].Base
));
539 DEBUG ((EFI_D_INFO
, " Length Assigned: %x\n", RootBridgeInstance
->ResAllocNode
[Index
].Length
));
541 DEBUG ((DEBUG_ERROR
, " Resource Allocation failed! There was no room at the inn\n"));
547 List
= List
->ForwardLink
;
550 if (ReturnStatus
== EFI_OUT_OF_RESOURCES
) {
551 DEBUG ((DEBUG_ERROR
, "Resource allocation Failed. Continue booting the system.\n"));
555 // Set resource to zero for nodes where allocation fails
557 List
= HostBridgeInstance
->Head
.ForwardLink
;
558 while (List
!= &HostBridgeInstance
->Head
) {
559 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
560 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
561 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResAllocated
) {
562 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
565 List
= List
->ForwardLink
;
569 return EFI_NOT_READY
;
572 // HostBridgeInstance->CanRestarted = FALSE;
576 case EfiPciHostBridgeSetResources
:
578 // HostBridgeInstance->CanRestarted = FALSE;
582 case EfiPciHostBridgeFreeResources
:
584 // HostBridgeInstance->CanRestarted = FALSE;
586 ReturnStatus
= EFI_SUCCESS
;
587 List
= HostBridgeInstance
->Head
.ForwardLink
;
588 while (List
!= &HostBridgeInstance
->Head
) {
589 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
590 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
591 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
592 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
593 BaseAddress
= (EFI_PHYSICAL_ADDRESS
) RootBridgeInstance
->ResAllocNode
[Index
].Base
;
596 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
597 if (EFI_ERROR (Status
)) {
598 ReturnStatus
= Status
;
603 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
604 if (EFI_ERROR (Status
)) {
605 ReturnStatus
= Status
;
616 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
617 if (EFI_ERROR (Status
)) {
618 ReturnStatus
= Status
;
624 } // end switch (Index)
626 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
627 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
628 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
629 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
633 List
= List
->ForwardLink
;
636 HostBridgeInstance
->ResourceSubmited
= FALSE
;
637 HostBridgeInstance
->CanRestarted
= TRUE
;
641 case EfiPciHostBridgeEndResourceAllocation
:
643 // Resource enumeration is done. Perform any activities that
644 // must wait until that time.
649 return EFI_INVALID_PARAMETER
;
650 } // End switch (Phase)
658 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
659 IN OUT EFI_HANDLE
*RootBridgeHandle
664 Return the device handle of the next PCI root bridge that is associated with
669 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
670 RootBridgeHandle - Returns the device handle of the next PCI Root Bridge.
671 On input, it holds the RootBridgeHandle returned by the most
672 recent call to GetNextRootBridge().The handle for the first
673 PCI Root Bridge is returned if RootBridgeHandle is NULL on input.
677 EFI_SUCCESS - Succeed.
678 EFI_NOT_FOUND - Next PCI root bridge not found.
679 EFI_INVALID_PARAMETER - Wrong parameter passed in.
683 BOOLEAN NoRootBridge
;
684 EFI_LIST_ENTRY
*List
;
685 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
686 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
689 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
690 List
= HostBridgeInstance
->Head
.ForwardLink
;
692 while (List
!= &HostBridgeInstance
->Head
) {
693 NoRootBridge
= FALSE
;
694 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
695 if (*RootBridgeHandle
== NULL
) {
697 // Return the first Root Bridge Handle of the Host Bridge
699 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
702 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
706 List
= List
->ForwardLink
;
707 if (List
!= &HostBridgeInstance
->Head
) {
708 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
709 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
712 return EFI_NOT_FOUND
;
717 List
= List
->ForwardLink
;
724 return EFI_NOT_FOUND
;
726 return EFI_INVALID_PARAMETER
;
733 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
734 IN EFI_HANDLE RootBridgeHandle
,
735 OUT UINT64
*Attributes
740 Returns the attributes of a PCI Root Bridge.
744 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
745 RootBridgeHandle - The device handle of the PCI Root Bridge
746 that the caller is interested in.
747 Attributes - The pointer to attributes of the PCI Root Bridge.
751 EFI_SUCCESS - Succeed.
752 EFI_INVALID_PARAMETER - Attributes parameter passed in is NULL or
753 RootBridgeHandle is not an EFI_HANDLE
754 that was returned on a previous call to
759 EFI_LIST_ENTRY
*List
;
760 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
761 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
763 if (Attributes
== NULL
) {
764 return EFI_INVALID_PARAMETER
;
767 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
768 List
= HostBridgeInstance
->Head
.ForwardLink
;
770 while (List
!= &HostBridgeInstance
->Head
) {
771 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
772 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
773 *Attributes
= RootBridgeInstance
->RootBridgeAllocAttrib
;
777 List
= List
->ForwardLink
;
780 // RootBridgeHandle is not an EFI_HANDLE
781 // that was returned on a previous call to GetNextRootBridge()
783 return EFI_INVALID_PARAMETER
;
788 StartBusEnumeration (
789 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
790 IN EFI_HANDLE RootBridgeHandle
,
791 OUT VOID
**Configuration
796 This is the request from the PCI enumerator to set up
797 the specified PCI Root Bridge for bus enumeration process.
801 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
802 RootBridgeHandle - The PCI Root Bridge to be set up.
803 Configuration - Pointer to the pointer to the PCI bus resource descriptor.
807 EFI_SUCCESS - Succeed.
808 EFI_OUT_OF_RESOURCES - Not enough pool to be allocated.
809 EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
813 EFI_LIST_ENTRY
*List
;
814 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
815 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
823 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
824 List
= HostBridgeInstance
->Head
.ForwardLink
;
826 while (List
!= &HostBridgeInstance
->Head
) {
827 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
828 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
830 // Set up the Root Bridge for Bus Enumeration
832 BusStart
= RootBridgeInstance
->Aperture
.BusBase
;
833 BusEnd
= RootBridgeInstance
->Aperture
.BusLimit
;
834 BusReserve
= RootBridgeInstance
->Aperture
.BusReserve
;
836 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
838 Status
= gBS
->AllocatePool (
840 sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
),
843 if (EFI_ERROR (Status
)) {
844 return EFI_OUT_OF_RESOURCES
;
847 Temp
= (UINT8
*) Buffer
;
849 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
850 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->Len
= 0x2B;
851 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->ResType
= ACPI_ADDRESS_SPACE_TYPE_BUS
;
852 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->GenFlag
= 0;
853 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->SpecificFlag
= 0;
854 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->AddrSpaceGranularity
= 0;
855 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->AddrRangeMin
= BusStart
;
856 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->AddrRangeMax
= BusReserve
;
857 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->AddrTranslationOffset
= 0;
858 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
)->AddrLen
= BusEnd
- BusStart
+ 1;
860 Temp
= Temp
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
861 ((EFI_ACPI_END_TAG_DESCRIPTOR
*) Temp
)->Desc
= ACPI_END_TAG_DESCRIPTOR
;
862 ((EFI_ACPI_END_TAG_DESCRIPTOR
*) Temp
)->Checksum
= 0x0;
864 *Configuration
= Buffer
;
868 List
= List
->ForwardLink
;
871 return EFI_INVALID_PARAMETER
;
877 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
878 IN EFI_HANDLE RootBridgeHandle
,
879 IN VOID
*Configuration
884 This function programs the PCI Root Bridge hardware so that
885 it decodes the specified PCI bus range.
889 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
890 RootBridgeHandle - The PCI Root Bridge whose bus range is to be programmed.
891 Configuration - The pointer to the PCI bus resource descriptor.
895 EFI_SUCCESS - Succeed.
896 EFI_INVALID_PARAMETER - Wrong parameters passed in.
900 EFI_LIST_ENTRY
*List
;
901 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
902 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
908 if (Configuration
== NULL
) {
909 return EFI_INVALID_PARAMETER
;
915 // Check the Configuration is valid
917 if (*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
918 return EFI_INVALID_PARAMETER
;
921 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Ptr
)->ResType
!= ACPI_ADDRESS_SPACE_TYPE_BUS
) {
922 return EFI_INVALID_PARAMETER
;
925 Ptr
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
926 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
927 return EFI_INVALID_PARAMETER
;
930 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
931 List
= HostBridgeInstance
->Head
.ForwardLink
;
935 while (List
!= &HostBridgeInstance
->Head
) {
936 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
937 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
938 BusStart
= (UINTN
) ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Ptr
)->AddrRangeMin
;
939 BusLen
= (UINTN
) ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Ptr
)->AddrLen
;
940 BusEnd
= BusStart
+ BusLen
- 1;
942 if (BusStart
> BusEnd
) {
943 return EFI_INVALID_PARAMETER
;
946 if ((BusStart
< RootBridgeInstance
->Aperture
.BusBase
) || (BusEnd
> RootBridgeInstance
->Aperture
.BusLimit
)) {
947 return EFI_INVALID_PARAMETER
;
950 // Update the Bus Range
952 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
953 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
954 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
955 RootBridgeInstance
->BusScanCount
++;
956 if (RootBridgeInstance
->BusScanCount
> 0) {
958 // Only care about the 2nd PCI bus scanning
960 RootBridgeInstance
->BusNumberAssigned
= TRUE
;
966 List
= List
->ForwardLink
;
969 return EFI_INVALID_PARAMETER
;
975 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
976 IN EFI_HANDLE RootBridgeHandle
,
977 IN VOID
*Configuration
983 Submits the I/O and memory resource requirements for the specified PCI Root Bridge.
986 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
987 RootBridgeHandle - The PCI Root Bridge whose I/O and memory resource requirements.
989 Configuration - The pointer to the PCI I/O and PCI memory resource descriptor.
993 EFI_SUCCESS - Succeed.
994 EFI_INVALID_PARAMETER - Wrong parameters passed in.
998 EFI_LIST_ENTRY
*List
;
999 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1000 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1002 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*ptr
;
1008 // Check the input parameter: Configuration
1010 if (Configuration
== NULL
) {
1011 return EFI_INVALID_PARAMETER
;
1014 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1015 List
= HostBridgeInstance
->Head
.ForwardLink
;
1017 Temp
= (UINT8
*) Configuration
;
1018 while (List
!= &HostBridgeInstance
->Head
) {
1019 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1020 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1022 // Check the resource descriptors.
1023 // If the Configuration includes one or more invalid resource descriptors, all the resource
1024 // descriptors are ignored and the function returns EFI_INVALID_PARAMETER.
1026 while (*Temp
== ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1027 ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1028 DEBUG ((EFI_D_INFO
, " ptr->ResType:%x \n",ptr
->ResType
));
1029 DEBUG ((EFI_D_INFO
, " ptr->AddrLen:0x%lx AddrRangeMin:0x%lx AddrRangeMax:0x%lx\n\n",ptr
->AddrLen
,ptr
->AddrRangeMin
,ptr
->AddrRangeMax
));
1031 switch (ptr
->ResType
) {
1032 case ACPI_ADDRESS_SPACE_TYPE_MEM
:
1033 if (ptr
->AddrSpaceGranularity
!= 32 && ptr
->AddrSpaceGranularity
!= 64) {
1034 return EFI_INVALID_PARAMETER
;
1036 if (ptr
->AddrSpaceGranularity
== 32 && ptr
->AddrLen
> 0xffffffff) {
1037 return EFI_INVALID_PARAMETER
;
1040 // If the PCI root bridge does not support separate windows for nonprefetchable and
1041 // prefetchable memory, then the PCI bus driver needs to include requests for
1042 // prefetchable memory in the nonprefetchable memory pool.
1044 if ((RootBridgeInstance
->RootBridgeAllocAttrib
& EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
) != 0 &&
1045 ((ptr
->SpecificFlag
& (BIT2
| BIT1
)) != 0)) {
1046 return EFI_INVALID_PARAMETER
;
1048 case ACPI_ADDRESS_SPACE_TYPE_IO
:
1050 // Check aligment, it should be of the form 2^n-1
1052 Value
= Power2MaxMemory (ptr
->AddrRangeMax
+ 1);
1053 if (Value
!= (ptr
->AddrRangeMax
+ 1)) {
1055 return EFI_INVALID_PARAMETER
;
1058 case ACPI_ADDRESS_SPACE_TYPE_BUS
:
1060 return EFI_INVALID_PARAMETER
;
1062 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
1064 if (*Temp
!= ACPI_END_TAG_DESCRIPTOR
) {
1065 return EFI_INVALID_PARAMETER
;
1068 Temp
= (UINT8
*) Configuration
;
1069 while (*Temp
== ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1070 ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1072 switch (ptr
->ResType
) {
1073 case ACPI_ADDRESS_SPACE_TYPE_MEM
:
1074 AddrLen
= (UINT64
) ptr
->AddrLen
;
1075 Alignment
= (UINT64
) ptr
->AddrRangeMax
;
1076 if (ptr
->AddrSpaceGranularity
== 32) {
1077 if (ptr
->SpecificFlag
== 0x06) {
1081 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
= ResSubmitted
;
1083 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
1084 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
= Alignment
;
1085 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
= ResRequested
;
1086 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1090 if (ptr
->AddrSpaceGranularity
== 64) {
1091 if (ptr
->SpecificFlag
== 0x06) {
1092 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
= ResSubmitted
;
1094 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Length
= AddrLen
;
1095 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Alignment
= Alignment
;
1096 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
= ResSubmitted
;
1097 HostBridgeInstance
->ResourceSubmited
= TRUE
;
1102 case ACPI_ADDRESS_SPACE_TYPE_IO
:
1103 AddrLen
= (UINT64
) ptr
->AddrLen
;
1104 Alignment
= (UINT64
) 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
;
1129 GetProposedResources (
1130 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1131 IN EFI_HANDLE RootBridgeHandle
,
1132 OUT VOID
**Configuration
1136 Routine Description:
1137 This function returns the proposed resource settings for the specified
1142 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
1143 RootBridgeHandle - The PCI Root Bridge handle.
1144 Configuration - The pointer to the pointer to the PCI I/O
1145 and memory resource descriptor.
1149 EFI_SUCCESS - Succeed.
1150 EFI_OUT_OF_RESOURCES - Not enough pool to be allocated.
1151 EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
1155 EFI_LIST_ENTRY
*List
;
1156 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1157 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1162 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 Status
= gBS
->AllocatePool (
1188 EfiBootServicesData
,
1189 Number
* sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
),
1193 if (EFI_ERROR (Status
)) {
1194 return EFI_OUT_OF_RESOURCES
;
1197 ZeroMem (Buffer
, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) * Number
+ sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
));
1200 ASSERT (Buffer
!= NULL
);
1202 for (Index
= 0; Index
< TypeBus
; Index
++) {
1203 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
1204 ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1205 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
1217 ptr
->SpecificFlag
= 0;
1218 ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1219 ptr
->AddrRangeMax
= 0;
1220 ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
1221 ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1232 ptr
->SpecificFlag
= 0;
1233 ptr
->AddrSpaceGranularity
= 32;
1234 ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1235 ptr
->AddrRangeMax
= 0;
1236 ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
1237 ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1242 // Prefetch memory 32
1248 ptr
->SpecificFlag
= 6;
1249 ptr
->AddrSpaceGranularity
= 32;
1250 ptr
->AddrRangeMin
= 0;
1251 ptr
->AddrRangeMax
= 0;
1252 ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1264 ptr
->SpecificFlag
= 0;
1265 ptr
->AddrSpaceGranularity
= 64;
1266 ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
1267 ptr
->AddrRangeMax
= 0;
1268 ptr
->AddrTranslationOffset
= (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
1269 ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
1274 // Prefetch memory 64
1280 ptr
->SpecificFlag
= 6;
1281 ptr
->AddrSpaceGranularity
= 64;
1282 ptr
->AddrRangeMin
= 0;
1283 ptr
->AddrRangeMax
= 0;
1284 ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1289 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1293 ((EFI_ACPI_END_TAG_DESCRIPTOR
*) Temp
)->Desc
= 0x79;
1294 ((EFI_ACPI_END_TAG_DESCRIPTOR
*) Temp
)->Checksum
= 0x0;
1296 *Configuration
= Buffer
;
1301 List
= List
->ForwardLink
;
1304 return EFI_INVALID_PARAMETER
;
1309 PreprocessController (
1310 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1311 IN EFI_HANDLE RootBridgeHandle
,
1312 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1313 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1317 Routine Description:
1318 This function is called for all the PCI controllers that the PCI
1319 bus driver finds. Can be used to Preprogram the controller.
1323 This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
1324 RootBridgeHandle - The PCI Root Bridge handle.
1325 PciAddress - Address of the controller on the PCI bus.
1326 Phase - The Phase during resource allocation.
1330 EFI_SUCCESS - Succeed.
1331 EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
1335 BOOLEAN RootBridgeFound
;
1336 EFI_LIST_ENTRY
*List
;
1337 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1338 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1340 if (RootBridgeHandle
== NULL
) {
1341 return EFI_INVALID_PARAMETER
;
1344 RootBridgeFound
= FALSE
;
1345 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1346 List
= HostBridgeInstance
->Head
.ForwardLink
;
1348 while (List
!= &HostBridgeInstance
->Head
) {
1349 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1351 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1352 RootBridgeFound
= TRUE
;
1358 List
= List
->ForwardLink
;
1361 if (RootBridgeFound
== FALSE
) {
1362 return EFI_INVALID_PARAMETER
;
1370 IN UINT64 MemoryLength
1374 Routine Description:
1376 Calculate maximum memory length that can be fit to a mtrr.
1380 MemoryLength - Input memory length.
1384 Returned Maximum length.
1390 if (RShiftU64 (MemoryLength
, 32)) {
1391 Result
= LShiftU64 ((UINT64
) GetPowerOfTwo64 ((UINT32
) RShiftU64 (MemoryLength
, 32)), 32);
1393 Result
= (UINT64
) GetPowerOfTwo64 ((UINT32
) MemoryLength
);