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