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