]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / IncompatiblePciDeviceSupportDxe / IncompatiblePciDeviceSupport.c
CommitLineData
9060e3ec 1/** @file\r
2 This module is one template module for Incompatible PCI Device Support protocol.\r
c1a247b8 3 It includes one incompatible pci devices list template.\r
d1102dba 4\r
9060e3ec 5 Incompatible PCI Device Support protocol allows the PCI bus driver to support\r
6 resource allocation for some PCI devices that do not comply with the PCI Specification.\r
7\r
e03a460f 8Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 9SPDX-License-Identifier: BSD-2-Clause-Patent\r
9060e3ec 10\r
11**/\r
12\r
13#include <PiDxe.h>\r
14#include <Protocol/IncompatiblePciDeviceSupport.h>\r
15\r
16#include <Library/UefiBootServicesTableLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18#include <Library/DebugLib.h>\r
19\r
20#include <IndustryStandard/Pci.h>\r
21#include <IndustryStandard/Acpi.h>\r
22\r
23typedef struct {\r
1436aea4
MK
24 UINT64 VendorId;\r
25 UINT64 DeviceId;\r
26 UINT64 RevisionId;\r
27 UINT64 SubsystemVendorId;\r
28 UINT64 SubsystemDeviceId;\r
9060e3ec 29} EFI_PCI_DEVICE_HEADER_INFO;\r
30\r
31typedef struct {\r
1436aea4
MK
32 UINT64 ResType;\r
33 UINT64 GenFlag;\r
34 UINT64 SpecificFlag;\r
35 UINT64 AddrSpaceGranularity;\r
36 UINT64 AddrRangeMin;\r
37 UINT64 AddrRangeMax;\r
38 UINT64 AddrTranslationOffset;\r
39 UINT64 AddrLen;\r
9060e3ec 40} EFI_PCI_RESOUCE_DESCRIPTOR;\r
41\r
42#define PCI_DEVICE_ID(VendorId, DeviceId, Revision, SubVendorId, SubDeviceId) \\r
43 VendorId, DeviceId, Revision, SubVendorId, SubDeviceId\r
44\r
1436aea4
MK
45#define DEVICE_INF_TAG 0xFFF2\r
46#define DEVICE_RES_TAG 0xFFF1\r
47#define LIST_END_TAG 0x0000\r
9060e3ec 48\r
1436aea4 49#define EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL\r
9060e3ec 50\r
51/**\r
52 Returns a list of ACPI resource descriptors that detail the special\r
53 resource configuration requirements for an incompatible PCI device.\r
54\r
55 @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance.\r
56 @param VendorId A unique ID to identify the manufacturer of the PCI device.\r
57 @param DeviceId A unique ID to identify the particular PCI device.\r
58 @param RevisionId A PCI device-specific revision identifier.\r
59 @param SubsystemVendorId Specifies the subsystem vendor ID.\r
60 @param SubsystemDeviceId Specifies the subsystem device ID.\r
61 @param Configuration A list of ACPI resource descriptors returned that detail\r
62 the configuration requirement.\r
63\r
64 @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device.\r
d1102dba 65 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
9060e3ec 66 @retval EFI_OUT_OF_RESOURCES No memory available.\r
67 @retval EFI_UNSUPPORTED The specified PCI device wasn't supported.\r
68\r
69**/\r
70EFI_STATUS\r
71EFIAPI\r
72PCheckDevice (\r
73 IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This,\r
74 IN UINTN VendorId,\r
75 IN UINTN DeviceId,\r
76 IN UINTN RevisionId,\r
77 IN UINTN SubsystemVendorId,\r
78 IN UINTN SubsystemDeviceId,\r
79 OUT VOID **Configuration\r
80 );\r
81\r
82//\r
83// Handle onto which the Incompatible PCI Device List is installed\r
84//\r
1436aea4 85EFI_HANDLE mIncompatiblePciDeviceSupportHandle = NULL;\r
9060e3ec 86\r
87//\r
88// The Incompatible PCI Device Support Protocol instance produced by this driver\r
89//\r
90EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL mIncompatiblePciDeviceSupport = {\r
91 PCheckDevice\r
92};\r
93\r
94//\r
95// The incompatible PCI devices list template\r
96//\r
1436aea4 97GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mIncompatiblePciDeviceList[] = {\r
9060e3ec 98 //\r
99 // DEVICE_INF_TAG,\r
100 // PCI_DEVICE_ID (VendorID, DeviceID, Revision, SubVendorId, SubDeviceId),\r
101 // DEVICE_RES_TAG,\r
102 // ResType, GFlag , SFlag, Granularity, RangeMin,\r
103 // RangeMax, Offset, AddrLen\r
104 //\r
105 //\r
106 // Device Adaptec 9004\r
107 //\r
108 DEVICE_INF_TAG,\r
1436aea4 109 PCI_DEVICE_ID (0x9004, MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64),\r
9060e3ec 110 DEVICE_RES_TAG,\r
c1a247b8
RN
111 ACPI_ADDRESS_SPACE_TYPE_IO,\r
112 0,\r
113 0,\r
114 0,\r
115 0,\r
116 EVEN_ALIGN,\r
117 MAX_UINT64,\r
118 0,\r
9060e3ec 119 //\r
120 // Device Adaptec 9005\r
121 //\r
122 DEVICE_INF_TAG,\r
1436aea4 123 PCI_DEVICE_ID (0x9005, MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64),\r
9060e3ec 124 DEVICE_RES_TAG,\r
c1a247b8
RN
125 ACPI_ADDRESS_SPACE_TYPE_IO,\r
126 0,\r
127 0,\r
128 0,\r
129 0,\r
130 EVEN_ALIGN,\r
131 MAX_UINT64,\r
132 0,\r
9060e3ec 133 //\r
134 // Device QLogic 1007\r
135 //\r
136 DEVICE_INF_TAG,\r
1436aea4 137 PCI_DEVICE_ID (0x1077, MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64),\r
9060e3ec 138 DEVICE_RES_TAG,\r
c1a247b8
RN
139 ACPI_ADDRESS_SPACE_TYPE_IO,\r
140 0,\r
141 0,\r
142 0,\r
143 0,\r
144 EVEN_ALIGN,\r
145 MAX_UINT64,\r
146 0,\r
9060e3ec 147 //\r
148 // Device Agilent 103C\r
149 //\r
150 DEVICE_INF_TAG,\r
1436aea4 151 PCI_DEVICE_ID (0x103C, MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64),\r
9060e3ec 152 DEVICE_RES_TAG,\r
c1a247b8
RN
153 ACPI_ADDRESS_SPACE_TYPE_IO,\r
154 0,\r
155 0,\r
156 0,\r
157 0,\r
158 EVEN_ALIGN,\r
159 MAX_UINT64,\r
160 0,\r
9060e3ec 161 //\r
162 // Device Agilent 15BC\r
163 //\r
164 DEVICE_INF_TAG,\r
1436aea4 165 PCI_DEVICE_ID (0x15BC, MAX_UINT64, MAX_UINT64, MAX_UINT64, MAX_UINT64),\r
9060e3ec 166 DEVICE_RES_TAG,\r
c1a247b8
RN
167 ACPI_ADDRESS_SPACE_TYPE_IO,\r
168 0,\r
169 0,\r
170 0,\r
171 0,\r
172 EVEN_ALIGN,\r
173 MAX_UINT64,\r
174 0,\r
9060e3ec 175 //\r
176 // The end of the list\r
177 //\r
178 LIST_END_TAG\r
179};\r
180\r
9060e3ec 181/**\r
182 Entry point of the incompatible pci device support code. Setup an incompatible device list template\r
183 and install EFI Incompatible PCI Device Support protocol.\r
184\r
185 @param ImageHandle A handle for the image that is initializing this driver.\r
186 @param SystemTable A pointer to the EFI system table.\r
187\r
188 @retval EFI_SUCCESS Installed EFI Incompatible PCI Device Support Protocol successfully.\r
189 @retval others Failed to install protocol.\r
190\r
191**/\r
192EFI_STATUS\r
193EFIAPI\r
194IncompatiblePciDeviceSupportEntryPoint (\r
1436aea4
MK
195 IN EFI_HANDLE ImageHandle,\r
196 IN EFI_SYSTEM_TABLE *SystemTable\r
9060e3ec 197 )\r
198{\r
1436aea4 199 EFI_STATUS Status;\r
9060e3ec 200\r
201 //\r
202 // Install EFI Incompatible PCI Device Support Protocol on a new handle\r
203 //\r
204 Status = gBS->InstallProtocolInterface (\r
205 &mIncompatiblePciDeviceSupportHandle,\r
206 &gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
207 EFI_NATIVE_INTERFACE,\r
208 &mIncompatiblePciDeviceSupport\r
209 );\r
210 ASSERT_EFI_ERROR (Status);\r
211\r
212 return Status;\r
213}\r
214\r
215/**\r
216 Returns a list of ACPI resource descriptors that detail the special\r
217 resource configuration requirements for an incompatible PCI device.\r
218\r
219 @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance.\r
220 @param VendorId A unique ID to identify the manufacturer of the PCI device.\r
221 @param DeviceId A unique ID to identify the particular PCI device.\r
222 @param RevisionId A PCI device-specific revision identifier.\r
223 @param SubsystemVendorId Specifies the subsystem vendor ID.\r
224 @param SubsystemDeviceId Specifies the subsystem device ID.\r
225 @param Configuration A list of ACPI resource descriptors returned that detail\r
226 the configuration requirement.\r
227\r
228 @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device.\r
d1102dba 229 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
9060e3ec 230 @retval EFI_OUT_OF_RESOURCES No memory available.\r
231 @retval EFI_UNSUPPORTED The specified PCI device wasn't supported.\r
232\r
233**/\r
234EFI_STATUS\r
235EFIAPI\r
236PCheckDevice (\r
237 IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This,\r
238 IN UINTN VendorId,\r
239 IN UINTN DeviceId,\r
240 IN UINTN RevisionId,\r
241 IN UINTN SubsystemVendorId,\r
242 IN UINTN SubsystemDeviceId,\r
243 OUT VOID **Configuration\r
244 )\r
245{\r
1436aea4
MK
246 UINT64 Tag;\r
247 UINT64 *ListPtr;\r
248 UINT64 *TempListPtr;\r
249 EFI_PCI_DEVICE_HEADER_INFO *Header;\r
250 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AcpiPtr;\r
251 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *OldAcpiPtr;\r
252 EFI_PCI_RESOUCE_DESCRIPTOR *Dsc;\r
253 EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
254 UINTN Index;\r
9060e3ec 255\r
256 //\r
257 // Validate the parameters\r
258 //\r
259 if (Configuration == NULL) {\r
260 return EFI_INVALID_PARAMETER;\r
261 }\r
1436aea4 262\r
9060e3ec 263 //\r
264 // Initialize the return value to NULL\r
265 //\r
1436aea4 266 *(VOID **)Configuration = NULL;\r
9060e3ec 267\r
1436aea4 268 ListPtr = mIncompatiblePciDeviceList;\r
9060e3ec 269 while (*ListPtr != LIST_END_TAG) {\r
9060e3ec 270 Tag = *ListPtr;\r
271\r
272 switch (Tag) {\r
1436aea4
MK
273 case DEVICE_INF_TAG:\r
274 Header = (EFI_PCI_DEVICE_HEADER_INFO *)(ListPtr + 1);\r
275 ListPtr = ListPtr + 1 + sizeof (EFI_PCI_DEVICE_HEADER_INFO) / sizeof (UINT64);\r
276 //\r
277 // See if the Header matches the parameters passed in\r
278 //\r
279 if ((Header->VendorId != MAX_UINT64) && (VendorId != MAX_UINTN)) {\r
280 if (Header->VendorId != VendorId) {\r
281 continue;\r
282 }\r
9060e3ec 283 }\r
9060e3ec 284\r
1436aea4
MK
285 if ((Header->DeviceId != MAX_UINT64) && (DeviceId != MAX_UINTN)) {\r
286 if (DeviceId != Header->DeviceId) {\r
287 continue;\r
288 }\r
9060e3ec 289 }\r
9060e3ec 290\r
1436aea4
MK
291 if ((Header->RevisionId != MAX_UINT64) && (RevisionId != MAX_UINTN)) {\r
292 if (RevisionId != Header->RevisionId) {\r
293 continue;\r
294 }\r
9060e3ec 295 }\r
9060e3ec 296\r
1436aea4
MK
297 if ((Header->SubsystemVendorId != MAX_UINT64) && (SubsystemVendorId != MAX_UINTN)) {\r
298 if (SubsystemVendorId != Header->SubsystemVendorId) {\r
299 continue;\r
300 }\r
9060e3ec 301 }\r
9060e3ec 302\r
1436aea4
MK
303 if ((Header->SubsystemDeviceId != MAX_UINT64) && (SubsystemDeviceId != MAX_UINTN)) {\r
304 if (SubsystemDeviceId != Header->SubsystemDeviceId) {\r
305 continue;\r
306 }\r
9060e3ec 307 }\r
9060e3ec 308\r
1436aea4
MK
309 //\r
310 // Matched an item, so construct the ACPI descriptor for the resource.\r
311 //\r
312 //\r
313 // Count the resource items so that to allocate space\r
314 //\r
315 for (Index = 0, TempListPtr = ListPtr; *TempListPtr == DEVICE_RES_TAG; Index++) {\r
316 TempListPtr = TempListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64));\r
317 }\r
318\r
319 //\r
320 // If there is at least one type of resource request,\r
321 // allocate an acpi resource node\r
322 //\r
323 if (Index == 0) {\r
324 return EFI_UNSUPPORTED;\r
325 }\r
326\r
327 AcpiPtr = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Index + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
328 if (AcpiPtr == NULL) {\r
329 return EFI_OUT_OF_RESOURCES;\r
330 }\r
331\r
332 OldAcpiPtr = AcpiPtr;\r
333 //\r
334 // Fill the EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR structure\r
335 // according to the EFI_PCI_RESOUCE_DESCRIPTOR structure\r
336 //\r
337 for ( ; *ListPtr == DEVICE_RES_TAG;) {\r
338 Dsc = (EFI_PCI_RESOUCE_DESCRIPTOR *)(ListPtr + 1);\r
339\r
340 AcpiPtr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
341 AcpiPtr->Len = (UINT16)sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
342 AcpiPtr->ResType = (UINT8)Dsc->ResType;\r
343 AcpiPtr->GenFlag = (UINT8)Dsc->GenFlag;\r
344 AcpiPtr->SpecificFlag = (UINT8)Dsc->SpecificFlag;\r
345 AcpiPtr->AddrSpaceGranularity = Dsc->AddrSpaceGranularity;\r
346 AcpiPtr->AddrRangeMin = Dsc->AddrRangeMin;\r
347 AcpiPtr->AddrRangeMax = Dsc->AddrRangeMax;\r
348 AcpiPtr->AddrTranslationOffset = Dsc->AddrTranslationOffset;\r
349 AcpiPtr->AddrLen = Dsc->AddrLen;\r
350\r
351 ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64));\r
352 AcpiPtr++;\r
353 }\r
354\r
355 //\r
356 // Put the checksum\r
357 //\r
358 PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *)(AcpiPtr);\r
359 PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
360 PtrEnd->Checksum = 0;\r
361\r
362 *(VOID **)Configuration = OldAcpiPtr;\r
363\r
364 return EFI_SUCCESS;\r
365\r
366 case DEVICE_RES_TAG:\r
367 //\r
368 // Adjust the pointer to the next PCI resource descriptor item\r
369 //\r
9060e3ec 370 ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64));\r
1436aea4
MK
371 break;\r
372\r
373 default:\r
374 return EFI_UNSUPPORTED;\r
9060e3ec 375 }\r
376 }\r
377\r
378 return EFI_UNSUPPORTED;\r
379}\r