2 Library instance of PciHostBridgeLib library class for coreboot.
4 Copyright (C) 2016, Red Hat, Inc.
5 Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <IndustryStandard/Pci.h>
13 #include <Protocol/PciHostBridgeResourceAllocation.h>
14 #include <Protocol/PciRootBridgeIo.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/DevicePathLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/PciHostBridgeLib.h>
21 #include <Library/PciLib.h>
22 #include <Library/HobLib.h>
24 #include "PciHostBridge.h"
28 CB_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate
= {
34 (UINT8
)(sizeof (ACPI_HID_DEVICE_PATH
)),
35 (UINT8
)((sizeof (ACPI_HID_DEVICE_PATH
)) >> 8)
38 EISA_PNP_ID (0x0A03), // HID
44 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
46 END_DEVICE_PATH_LENGTH
,
53 Initialize a PCI_ROOT_BRIDGE structure.
55 @param[in] Supports Supported attributes.
57 @param[in] Attributes Initial attributes.
59 @param[in] AllocAttributes Allocation attributes.
61 @param[in] RootBusNumber The bus number to store in RootBus.
63 @param[in] MaxSubBusNumber The inclusive maximum bus number that can be
64 assigned to any subordinate bus found behind any
65 PCI bridge hanging off this root bus.
67 The caller is responsible for ensuring that
68 RootBusNumber <= MaxSubBusNumber. If
69 RootBusNumber equals MaxSubBusNumber, then the
70 root bus has no room for subordinate buses.
72 @param[in] Io IO aperture.
74 @param[in] Mem MMIO aperture.
76 @param[in] MemAbove4G MMIO aperture above 4G.
78 @param[in] PMem Prefetchable MMIO aperture.
80 @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
82 @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
83 caller) that should be filled in by this
86 @retval EFI_SUCCESS Initialization successful. A device path
87 consisting of an ACPI device path node, with
88 UID = RootBusNumber, has been allocated and
91 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
97 IN UINT64 AllocAttributes
,
98 IN UINT8 RootBusNumber
,
99 IN UINT8 MaxSubBusNumber
,
100 IN PCI_ROOT_BRIDGE_APERTURE
*Io
,
101 IN PCI_ROOT_BRIDGE_APERTURE
*Mem
,
102 IN PCI_ROOT_BRIDGE_APERTURE
*MemAbove4G
,
103 IN PCI_ROOT_BRIDGE_APERTURE
*PMem
,
104 IN PCI_ROOT_BRIDGE_APERTURE
*PMemAbove4G
,
105 OUT PCI_ROOT_BRIDGE
*RootBus
108 CB_PCI_ROOT_BRIDGE_DEVICE_PATH
*DevicePath
;
111 // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
113 ZeroMem (RootBus
, sizeof *RootBus
);
115 RootBus
->Segment
= 0;
117 RootBus
->Supports
= Supports
;
118 RootBus
->Attributes
= Attributes
;
120 RootBus
->DmaAbove4G
= FALSE
;
122 RootBus
->AllocationAttributes
= AllocAttributes
;
123 RootBus
->Bus
.Base
= RootBusNumber
;
124 RootBus
->Bus
.Limit
= MaxSubBusNumber
;
125 CopyMem (&RootBus
->Io
, Io
, sizeof (*Io
));
126 CopyMem (&RootBus
->Mem
, Mem
, sizeof (*Mem
));
127 CopyMem (&RootBus
->MemAbove4G
, MemAbove4G
, sizeof (*MemAbove4G
));
128 CopyMem (&RootBus
->PMem
, PMem
, sizeof (*PMem
));
129 CopyMem (&RootBus
->PMemAbove4G
, PMemAbove4G
, sizeof (*PMemAbove4G
));
131 RootBus
->NoExtendedConfigSpace
= FALSE
;
133 DevicePath
= AllocateCopyPool (
134 sizeof (mRootBridgeDevicePathTemplate
),
135 &mRootBridgeDevicePathTemplate
137 if (DevicePath
== NULL
) {
138 DEBUG ((DEBUG_ERROR
, "%a: %r\n", __FUNCTION__
, EFI_OUT_OF_RESOURCES
));
139 return EFI_OUT_OF_RESOURCES
;
142 DevicePath
->AcpiDevicePath
.UID
= RootBusNumber
;
143 RootBus
->DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)DevicePath
;
147 "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
150 MaxSubBusNumber
- RootBusNumber
156 Initialize DevicePath for a PCI_ROOT_BRIDGE.
157 @param[in] HID HID for device path
158 @param[in] UID UID for device path
160 @retval A pointer to the new created device patch.
162 EFI_DEVICE_PATH_PROTOCOL
*
163 CreateRootBridgeDevicePath (
168 CB_PCI_ROOT_BRIDGE_DEVICE_PATH
*DevicePath
;
170 DevicePath
= AllocateCopyPool (
171 sizeof (mRootBridgeDevicePathTemplate
),
172 &mRootBridgeDevicePathTemplate
174 ASSERT (DevicePath
!= NULL
);
175 DevicePath
->AcpiDevicePath
.HID
= HID
;
176 DevicePath
->AcpiDevicePath
.UID
= UID
;
177 return (EFI_DEVICE_PATH_PROTOCOL
*)DevicePath
;
181 Return all the root bridge instances in an array.
183 @param Count Return the count of root bridge instances.
185 @return All the root bridge instances in an array.
186 The array should be passed into PciHostBridgeFreeRootBridges()
191 PciHostBridgeGetRootBridges (
195 UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES
*PciRootBridgeInfo
;
196 EFI_HOB_GUID_TYPE
*GuidHob
;
197 UNIVERSAL_PAYLOAD_GENERIC_HEADER
*GenericHeader
;
200 // Find Universal Payload PCI Root Bridge Info hob
202 GuidHob
= GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid
);
203 if (GuidHob
!= NULL
) {
204 GenericHeader
= (UNIVERSAL_PAYLOAD_GENERIC_HEADER
*)GET_GUID_HOB_DATA (GuidHob
);
205 if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER
) <= GET_GUID_HOB_DATA_SIZE (GuidHob
)) && (GenericHeader
->Length
<= GET_GUID_HOB_DATA_SIZE (GuidHob
))) {
206 if ((GenericHeader
->Revision
== UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION
) && (GenericHeader
->Length
>= sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES
))) {
208 // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION
210 PciRootBridgeInfo
= (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES
*)GET_GUID_HOB_DATA (GuidHob
);
211 if (PciRootBridgeInfo
->Count
<= (GET_GUID_HOB_DATA_SIZE (GuidHob
) - sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES
)) / sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE
)) {
212 return RetrieveRootBridgeInfoFromHob (PciRootBridgeInfo
, Count
);
218 return ScanForRootBridges (Count
);
222 Free the root bridge instances array returned from
223 PciHostBridgeGetRootBridges().
225 @param Bridges The root bridge instances array.
226 @param Count The count of the array.
230 PciHostBridgeFreeRootBridges (
231 PCI_ROOT_BRIDGE
*Bridges
,
235 if ((Bridges
== NULL
) || (Count
== 0)) {
239 ASSERT (Bridges
!= NULL
|| Count
> 0);
243 FreePool (Bridges
[Count
].DevicePath
);
250 Inform the platform that the resource conflict happens.
252 @param HostBridgeHandle Handle of the Host Bridge.
253 @param Configuration Pointer to PCI I/O and PCI memory resource
254 descriptors. The Configuration contains the resources
255 for all the root bridges. The resource for each root
256 bridge is terminated with END descriptor and an
257 additional END is appended indicating the end of the
258 entire resources. The resource descriptor field
259 values follow the description in
260 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
265 PciHostBridgeResourceConflict (
266 EFI_HANDLE HostBridgeHandle
,
271 // coreboot UEFI Payload does not do PCI enumeration and should not call this
272 // library interface.