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