UefiPayloadPkg: Enhance UEFI payload for coreboot and Slim Bootloader
[mirror_edk2.git] / UefiPayloadPkg / Library / PciHostBridgeLib / PciHostBridgeLib.c
CommitLineData
04af8bf2
DG
1/** @file\r
2 Library instance of PciHostBridgeLib library class for coreboot.\r
3\r
4 Copyright (C) 2016, Red Hat, Inc.\r
5 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
6\r
7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
8\r
9**/\r
10#include <PiDxe.h>\r
11\r
12#include <IndustryStandard/Pci.h>\r
13#include <Protocol/PciHostBridgeResourceAllocation.h>\r
14#include <Protocol/PciRootBridgeIo.h>\r
15\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/DevicePathLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/PciHostBridgeLib.h>\r
21#include <Library/PciLib.h>\r
22\r
23#include "PciHostBridge.h"\r
24\r
25STATIC\r
26CONST\r
27CB_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {\r
28 {\r
29 {\r
30 ACPI_DEVICE_PATH,\r
31 ACPI_DP,\r
32 {\r
33 (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),\r
34 (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)\r
35 }\r
36 },\r
37 EISA_PNP_ID(0x0A03), // HID\r
38 0 // UID\r
39 },\r
40\r
41 {\r
42 END_DEVICE_PATH_TYPE,\r
43 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
44 {\r
45 END_DEVICE_PATH_LENGTH,\r
46 0\r
47 }\r
48 }\r
49};\r
50\r
51\r
52/**\r
53 Initialize a PCI_ROOT_BRIDGE structure.\r
54\r
55 @param[in] Supports Supported attributes.\r
56\r
57 @param[in] Attributes Initial attributes.\r
58\r
59 @param[in] AllocAttributes Allocation attributes.\r
60\r
61 @param[in] RootBusNumber The bus number to store in RootBus.\r
62\r
63 @param[in] MaxSubBusNumber The inclusive maximum bus number that can be\r
64 assigned to any subordinate bus found behind any\r
65 PCI bridge hanging off this root bus.\r
66\r
67 The caller is responsible for ensuring that\r
68 RootBusNumber <= MaxSubBusNumber. If\r
69 RootBusNumber equals MaxSubBusNumber, then the\r
70 root bus has no room for subordinate buses.\r
71\r
72 @param[in] Io IO aperture.\r
73\r
74 @param[in] Mem MMIO aperture.\r
75\r
76 @param[in] MemAbove4G MMIO aperture above 4G.\r
77\r
78 @param[in] PMem Prefetchable MMIO aperture.\r
79\r
80 @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.\r
81\r
82 @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the\r
83 caller) that should be filled in by this\r
84 function.\r
85\r
86 @retval EFI_SUCCESS Initialization successful. A device path\r
87 consisting of an ACPI device path node, with\r
88 UID = RootBusNumber, has been allocated and\r
89 linked into RootBus.\r
90\r
91 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
92**/\r
93EFI_STATUS\r
94InitRootBridge (\r
95 IN UINT64 Supports,\r
96 IN UINT64 Attributes,\r
97 IN UINT64 AllocAttributes,\r
98 IN UINT8 RootBusNumber,\r
99 IN UINT8 MaxSubBusNumber,\r
100 IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
101 IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
102 IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
103 IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
104 IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,\r
105 OUT PCI_ROOT_BRIDGE *RootBus\r
106)\r
107{\r
108 CB_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;\r
109\r
110 //\r
111 // Be safe if other fields are added to PCI_ROOT_BRIDGE later.\r
112 //\r
113 ZeroMem (RootBus, sizeof *RootBus);\r
114\r
115 RootBus->Segment = 0;\r
116\r
117 RootBus->Supports = Supports;\r
118 RootBus->Attributes = Attributes;\r
119\r
120 RootBus->DmaAbove4G = FALSE;\r
121\r
122 RootBus->AllocationAttributes = AllocAttributes;\r
123 RootBus->Bus.Base = RootBusNumber;\r
124 RootBus->Bus.Limit = MaxSubBusNumber;\r
125 CopyMem (&RootBus->Io, Io, sizeof (*Io));\r
126 CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));\r
127 CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));\r
128 CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));\r
129 CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));\r
130\r
131 RootBus->NoExtendedConfigSpace = FALSE;\r
132\r
133 DevicePath = AllocateCopyPool (sizeof (mRootBridgeDevicePathTemplate),\r
134 &mRootBridgeDevicePathTemplate);\r
135 if (DevicePath == NULL) {\r
136 DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));\r
137 return EFI_OUT_OF_RESOURCES;\r
138 }\r
139 DevicePath->AcpiDevicePath.UID = RootBusNumber;\r
140 RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;\r
141\r
142 DEBUG ((DEBUG_INFO,\r
143 "%a: populated root bus %d, with room for %d subordinate bus(es)\n",\r
144 __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));\r
145 return EFI_SUCCESS;\r
146}\r
147\r
148\r
149/**\r
150 Return all the root bridge instances in an array.\r
151\r
152 @param Count Return the count of root bridge instances.\r
153\r
154 @return All the root bridge instances in an array.\r
155 The array should be passed into PciHostBridgeFreeRootBridges()\r
156 when it's not used.\r
157**/\r
158PCI_ROOT_BRIDGE *\r
159EFIAPI\r
160PciHostBridgeGetRootBridges (\r
161 UINTN *Count\r
162)\r
163{\r
164 return ScanForRootBridges (Count);\r
165}\r
166\r
167\r
168/**\r
169 Free the root bridge instances array returned from\r
170 PciHostBridgeGetRootBridges().\r
171\r
172 @param The root bridge instances array.\r
173 @param The count of the array.\r
174**/\r
175VOID\r
176EFIAPI\r
177PciHostBridgeFreeRootBridges (\r
178 PCI_ROOT_BRIDGE *Bridges,\r
179 UINTN Count\r
180)\r
181{\r
182 if (Bridges == NULL && Count == 0) {\r
183 return;\r
184 }\r
185 ASSERT (Bridges != NULL && Count > 0);\r
186\r
187 do {\r
188 --Count;\r
189 FreePool (Bridges[Count].DevicePath);\r
190 } while (Count > 0);\r
191\r
192 FreePool (Bridges);\r
193}\r
194\r
195\r
196/**\r
197 Inform the platform that the resource conflict happens.\r
198\r
199 @param HostBridgeHandle Handle of the Host Bridge.\r
200 @param Configuration Pointer to PCI I/O and PCI memory resource\r
201 descriptors. The Configuration contains the resources\r
202 for all the root bridges. The resource for each root\r
203 bridge is terminated with END descriptor and an\r
204 additional END is appended indicating the end of the\r
205 entire resources. The resource descriptor field\r
206 values follow the description in\r
207 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL\r
208 .SubmitResources().\r
209**/\r
210VOID\r
211EFIAPI\r
212PciHostBridgeResourceConflict (\r
213 EFI_HANDLE HostBridgeHandle,\r
214 VOID *Configuration\r
215)\r
216{\r
217 //\r
218 // coreboot UEFI Payload does not do PCI enumeration and should not call this\r
219 // library interface.\r
220 //\r
221 ASSERT (FALSE);\r
222}\r