]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Include/Library/PciCapLib.h
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Include / Library / PciCapLib.h
CommitLineData
392a3146
LE
1/** @file\r
2 Library class to work with PCI capabilities in PCI config space.\r
3\r
4 Provides functions to parse capabilities lists, and to locate, describe, read\r
5 and write capabilities. PCI config space access is abstracted away.\r
6\r
7 Copyright (C) 2018, Red Hat, Inc.\r
8\r
b26f0cf9 9 SPDX-License-Identifier: BSD-2-Clause-Patent\r
392a3146
LE
10**/\r
11\r
12#ifndef __PCI_CAP_LIB_H__\r
13#define __PCI_CAP_LIB_H__\r
14\r
15#include <Uefi/UefiBaseType.h>\r
16\r
17//\r
18// Base structure for representing a PCI device -- down to the PCI function\r
19// level -- for the purposes of this library class. This is a forward\r
20// declaration that is completed below. Concrete implementations are supposed\r
21// to inherit and extend this type.\r
22//\r
23typedef struct PCI_CAP_DEV PCI_CAP_DEV;\r
24\r
25/**\r
26 Read the config space of a given PCI device (both normal and extended).\r
27\r
28 PCI_CAP_DEV_READ_CONFIG performs as few config space accesses as possible\r
29 (without attempting 64-bit wide accesses).\r
30\r
31 PCI_CAP_DEV_READ_CONFIG returns an unspecified error if accessing Size bytes\r
32 from SourceOffset exceeds the config space limit of the PCI device. Fewer\r
33 than Size bytes may have been read in this case.\r
34\r
35 @param[in] PciDevice Implementation-specific unique representation\r
36 of the PCI device in the PCI hierarchy.\r
37\r
38 @param[in] SourceOffset Source offset in the config space of the PCI\r
39 device to start reading from.\r
40\r
41 @param[out] DestinationBuffer Buffer to store the read data to.\r
42\r
43 @param[in] Size The number of bytes to transfer.\r
44\r
45 @retval RETURN_SUCCESS Size bytes have been transferred from config space to\r
46 DestinationBuffer.\r
47\r
48 @return Unspecified error codes. Fewer than Size bytes may\r
49 have been read.\r
50**/\r
51typedef\r
52RETURN_STATUS\r
ac0a286f 53(EFIAPI *PCI_CAP_DEV_READ_CONFIG)(\r
392a3146
LE
54 IN PCI_CAP_DEV *PciDevice,\r
55 IN UINT16 SourceOffset,\r
56 OUT VOID *DestinationBuffer,\r
57 IN UINT16 Size\r
58 );\r
59\r
60/**\r
61 Write the config space of a given PCI device (both normal and extended).\r
62\r
63 PCI_CAP_DEV_WRITE_CONFIG performs as few config space accesses as possible\r
64 (without attempting 64-bit wide accesses).\r
65\r
66 PCI_CAP_DEV_WRITE_CONFIG returns an unspecified error if accessing Size bytes\r
67 at DestinationOffset exceeds the config space limit of the PCI device. Fewer\r
68 than Size bytes may have been written in this case.\r
69\r
70 @param[in] PciDevice Implementation-specific unique representation\r
71 of the PCI device in the PCI hierarchy.\r
72\r
73 @param[in] DestinationOffset Destination offset in the config space of the\r
74 PCI device to start writing at.\r
75\r
76 @param[in] SourceBuffer Buffer to read the data to be stored from.\r
77\r
78 @param[in] Size The number of bytes to transfer.\r
79\r
80 @retval RETURN_SUCCESS Size bytes have been transferred from SourceBuffer to\r
81 config space.\r
82\r
83 @return Unspecified error codes. Fewer than Size bytes may\r
84 have been written.\r
85**/\r
86typedef\r
87RETURN_STATUS\r
ac0a286f 88(EFIAPI *PCI_CAP_DEV_WRITE_CONFIG)(\r
392a3146
LE
89 IN PCI_CAP_DEV *PciDevice,\r
90 IN UINT16 DestinationOffset,\r
91 IN VOID *SourceBuffer,\r
92 IN UINT16 Size\r
93 );\r
94\r
95//\r
96// Complete the PCI_CAP_DEV type here. The base abstraction only requires\r
97// config space accessors.\r
98//\r
99struct PCI_CAP_DEV {\r
ac0a286f
MK
100 PCI_CAP_DEV_READ_CONFIG ReadConfig;\r
101 PCI_CAP_DEV_WRITE_CONFIG WriteConfig;\r
392a3146
LE
102};\r
103\r
104//\r
105// Opaque data structure representing parsed PCI Capabilities Lists.\r
106//\r
107typedef struct PCI_CAP_LIST PCI_CAP_LIST;\r
108\r
109//\r
110// Opaque data structure representing a PCI Capability in a parsed Capability\r
111// List.\r
112//\r
113typedef struct PCI_CAP PCI_CAP;\r
114\r
115//\r
116// Distinguishes whether a Capability ID is 8-bit wide and interpreted in\r
117// normal config space, or 16-bit wide and interpreted in extended config\r
118// space. Capability ID definitions are relative to domain.\r
119//\r
120typedef enum {\r
121 PciCapNormal,\r
122 PciCapExtended\r
123} PCI_CAP_DOMAIN;\r
124\r
125//\r
126// Public data structure that PciCapGetInfo() fills in about a PCI_CAP object.\r
127//\r
128typedef struct {\r
ac0a286f
MK
129 PCI_CAP_DOMAIN Domain;\r
130 UINT16 CapId;\r
392a3146
LE
131 //\r
132 // The capability identified by Domain and CapId may have multiple instances\r
133 // in config space. NumInstances provides the total count of occurrences of\r
134 // the capability. It is always positive.\r
135 //\r
ac0a286f 136 UINT16 NumInstances;\r
392a3146
LE
137 //\r
138 // Instance is the serial number, in capabilities list traversal order (not\r
139 // necessarily config space offset order), of the one capability instance\r
140 // that PciCapGetInfo() is reporting about. Instance is always smaller than\r
141 // NumInstances.\r
142 //\r
ac0a286f 143 UINT16 Instance;\r
392a3146
LE
144 //\r
145 // The offset in config space at which the capability header of the\r
146 // capability instance starts.\r
147 //\r
ac0a286f 148 UINT16 Offset;\r
392a3146
LE
149 //\r
150 // The deduced maximum size of the capability instance, including the\r
151 // capability header. This hint is an upper bound, calculated -- without\r
152 // regard to the internal structure of the capability -- from (a) the next\r
153 // lowest offset in configuration space that is known to be used by another\r
154 // capability, and (b) from the end of the config space identified by Domain,\r
155 // whichever is lower.\r
156 //\r
ac0a286f 157 UINT16 MaxSizeHint;\r
392a3146
LE
158 //\r
159 // The version number of the capability instance. Always zero when Domain is\r
160 // PciCapNormal.\r
161 //\r
ac0a286f 162 UINT8 Version;\r
392a3146
LE
163} PCI_CAP_INFO;\r
164\r
392a3146
LE
165/**\r
166 Parse the capabilities lists (both normal and extended, as applicable) of a\r
167 PCI device.\r
168\r
169 If the PCI device has no capabilities, that per se will not fail\r
170 PciCapListInit(); an empty capabilities list will be represented.\r
171\r
172 If the PCI device is found to be PCI Express, then an attempt will be made to\r
173 parse the extended capabilities list as well. If the first extended config\r
174 space access -- via PciDevice->ReadConfig() with SourceOffset=0x100 and\r
175 Size=4 -- fails, that per se will not fail PciCapListInit(); the device will\r
176 be assumed to have no extended capabilities.\r
177\r
178 @param[in] PciDevice Implementation-specific unique representation of the\r
179 PCI device in the PCI hierarchy.\r
180\r
181 @param[out] CapList Opaque data structure that holds an in-memory\r
182 representation of the parsed capabilities lists of\r
183 PciDevice.\r
184\r
185 @retval RETURN_SUCCESS The capabilities lists have been parsed from\r
186 config space.\r
187\r
188 @retval RETURN_OUT_OF_RESOURCES Memory allocation failed.\r
189\r
190 @retval RETURN_DEVICE_ERROR A loop or some other kind of invalid pointer\r
191 was detected in the capabilities lists of\r
192 PciDevice.\r
193\r
194 @return Error codes propagated from\r
195 PciDevice->ReadConfig().\r
196**/\r
197RETURN_STATUS\r
198EFIAPI\r
199PciCapListInit (\r
ac0a286f
MK
200 IN PCI_CAP_DEV *PciDevice,\r
201 OUT PCI_CAP_LIST **CapList\r
392a3146
LE
202 );\r
203\r
392a3146
LE
204/**\r
205 Free the resources used by CapList.\r
206\r
207 @param[in] CapList The PCI_CAP_LIST object to free, originally produced by\r
208 PciCapListInit().\r
209**/\r
210VOID\r
211EFIAPI\r
212PciCapListUninit (\r
ac0a286f 213 IN PCI_CAP_LIST *CapList\r
392a3146
LE
214 );\r
215\r
392a3146
LE
216/**\r
217 Locate a capability instance in the parsed capabilities lists.\r
218\r
219 @param[in] CapList The PCI_CAP_LIST object produced by PciCapListInit().\r
220\r
221 @param[in] Domain Distinguishes whether CapId is 8-bit wide and\r
222 interpreted in normal config space, or 16-bit wide and\r
223 interpreted in extended config space. Capability ID\r
224 definitions are relative to domain.\r
225\r
226 @param[in] CapId Capability identifier to look up.\r
227\r
228 @param[in] Instance Domain and CapId may identify a multi-instance\r
229 capability. When Instance is zero, the first instance of\r
230 the capability is located (in list traversal order --\r
231 which may not mean increasing config space offset\r
232 order). Higher Instance values locate subsequent\r
233 instances of the same capability (in list traversal\r
234 order).\r
235\r
236 @param[out] Cap The capability instance that matches the search\r
237 criteria. Cap is owned by CapList and becomes invalid\r
238 when CapList is freed with PciCapListUninit().\r
239 PciCapListFindCap() may be called with Cap set to NULL,\r
240 in order to test the existence of a specific capability\r
241 instance.\r
242\r
243 @retval RETURN_SUCCESS The capability instance identified by (Domain,\r
244 CapId, Instance) has been found.\r
245\r
246 @retval RETURN_NOT_FOUND The requested (Domain, CapId, Instance) capability\r
247 instance does not exist.\r
248**/\r
249RETURN_STATUS\r
250EFIAPI\r
251PciCapListFindCap (\r
ac0a286f
MK
252 IN PCI_CAP_LIST *CapList,\r
253 IN PCI_CAP_DOMAIN Domain,\r
254 IN UINT16 CapId,\r
255 IN UINT16 Instance,\r
256 OUT PCI_CAP **Cap OPTIONAL\r
392a3146
LE
257 );\r
258\r
392a3146
LE
259/**\r
260 Locate the first instance of the capability given by (Domain, CapId) such\r
261 that the instance's Version is greater than or equal to MinVersion.\r
262\r
263 This is a convenience function that may save client code calls to\r
264 PciCapListFindCap() and PciCapGetInfo().\r
265\r
266 @param[in] CapList The PCI_CAP_LIST object produced by PciCapListInit().\r
267\r
268 @param[in] Domain Distinguishes whether CapId is 8-bit wide and\r
269 interpreted in normal config space, or 16-bit wide and\r
270 interpreted in extended config space. Capability ID\r
271 definitions are relative to domain.\r
272\r
273 @param[in] CapId Capability identifier to look up.\r
274\r
275 @param[in] MinVersion The minimum version that the capability instance is\r
276 required to have. Note that all capability instances\r
277 in Domain=PciCapNormal have Version=0.\r
278\r
279 @param[out] Cap The first capability instance that matches the search\r
280 criteria. Cap is owned by CapList and becomes invalid\r
281 when CapList is freed with PciCapListUninit().\r
282 PciCapListFindCapVersion() may be called with Cap set\r
283 to NULL, in order just to test whether the search\r
284 criteria are satisfiable.\r
285\r
286 @retval RETURN_SUCCESS The first capability instance matching (Domain,\r
287 CapId, MinVersion) has been located.\r
288\r
289 @retval RETURN_NOT_FOUND No capability instance matches (Domain, CapId,\r
290 MinVersion).\r
291**/\r
292RETURN_STATUS\r
293EFIAPI\r
294PciCapListFindCapVersion (\r
ac0a286f
MK
295 IN PCI_CAP_LIST *CapList,\r
296 IN PCI_CAP_DOMAIN Domain,\r
297 IN UINT16 CapId,\r
298 IN UINT8 MinVersion,\r
299 OUT PCI_CAP **Cap OPTIONAL\r
392a3146
LE
300 );\r
301\r
392a3146
LE
302/**\r
303 Get information about a PCI Capability instance.\r
304\r
305 @param[in] Cap The capability instance to get info about, located with\r
306 PciCapListFindCap*().\r
307\r
308 @param[out] Info A PCI_CAP_INFO structure that describes the properties of\r
309 Cap.\r
310\r
311 @retval RETURN_SUCCESS Fields of Info have been set.\r
312\r
313 @return Unspecified error codes, if filling in Info failed\r
314 for some reason.\r
315**/\r
316RETURN_STATUS\r
317EFIAPI\r
318PciCapGetInfo (\r
ac0a286f
MK
319 IN PCI_CAP *Cap,\r
320 OUT PCI_CAP_INFO *Info\r
392a3146
LE
321 );\r
322\r
392a3146
LE
323/**\r
324 Read a slice of a capability instance.\r
325\r
326 The function performs as few config space accesses as possible (without\r
327 attempting 64-bit wide accesses). PciCapRead() performs bounds checking on\r
328 SourceOffsetInCap and Size, and only invokes PciDevice->ReadConfig() if the\r
329 requested transfer falls within Cap.\r
330\r
331 @param[in] PciDevice Implementation-specific unique representation\r
332 of the PCI device in the PCI hierarchy.\r
333\r
334 @param[in] Cap The capability instance to read, located with\r
335 PciCapListFindCap*().\r
336\r
337 @param[in] SourceOffsetInCap Source offset relative to the capability\r
338 header to start reading from. A zero value\r
339 refers to the first byte of the capability\r
340 header.\r
341\r
342 @param[out] DestinationBuffer Buffer to store the read data to.\r
343\r
344 @param[in] Size The number of bytes to transfer.\r
345\r
346 @retval RETURN_SUCCESS Size bytes have been transferred from Cap to\r
347 DestinationBuffer.\r
348\r
349 @retval RETURN_BAD_BUFFER_SIZE Reading Size bytes starting from\r
350 SourceOffsetInCap would not (entirely) be\r
351 contained within Cap, as suggested by\r
352 PCI_CAP_INFO.MaxSizeHint. No bytes have been\r
353 read.\r
354\r
355 @return Error codes propagated from\r
356 PciDevice->ReadConfig(). Fewer than Size\r
357 bytes may have been read.\r
358**/\r
359RETURN_STATUS\r
360EFIAPI\r
361PciCapRead (\r
ac0a286f
MK
362 IN PCI_CAP_DEV *PciDevice,\r
363 IN PCI_CAP *Cap,\r
364 IN UINT16 SourceOffsetInCap,\r
365 OUT VOID *DestinationBuffer,\r
366 IN UINT16 Size\r
392a3146
LE
367 );\r
368\r
392a3146
LE
369/**\r
370 Write a slice of a capability instance.\r
371\r
372 The function performs as few config space accesses as possible (without\r
373 attempting 64-bit wide accesses). PciCapWrite() performs bounds checking on\r
374 DestinationOffsetInCap and Size, and only invokes PciDevice->WriteConfig() if\r
375 the requested transfer falls within Cap.\r
376\r
377 @param[in] PciDevice Implementation-specific unique\r
378 representation of the PCI device in the\r
379 PCI hierarchy.\r
380\r
381 @param[in] Cap The capability instance to write, located\r
382 with PciCapListFindCap*().\r
383\r
384 @param[in] DestinationOffsetInCap Destination offset relative to the\r
385 capability header to start writing at. A\r
386 zero value refers to the first byte of the\r
387 capability header.\r
388\r
389 @param[in] SourceBuffer Buffer to read the data to be stored from.\r
390\r
391 @param[in] Size The number of bytes to transfer.\r
392\r
393 @retval RETURN_SUCCESS Size bytes have been transferred from\r
394 SourceBuffer to Cap.\r
395\r
396 @retval RETURN_BAD_BUFFER_SIZE Writing Size bytes starting at\r
397 DestinationOffsetInCap would not (entirely)\r
398 be contained within Cap, as suggested by\r
399 PCI_CAP_INFO.MaxSizeHint. No bytes have been\r
400 written.\r
401\r
402 @return Error codes propagated from\r
403 PciDevice->WriteConfig(). Fewer than Size\r
404 bytes may have been written.\r
405**/\r
406RETURN_STATUS\r
407EFIAPI\r
408PciCapWrite (\r
ac0a286f
MK
409 IN PCI_CAP_DEV *PciDevice,\r
410 IN PCI_CAP *Cap,\r
411 IN UINT16 DestinationOffsetInCap,\r
412 IN VOID *SourceBuffer,\r
413 IN UINT16 Size\r
392a3146
LE
414 );\r
415\r
416#endif // __PCI_CAP_LIB_H__\r