]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/SmmPciExpressLib/PciExpressLib.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / SmmPciExpressLib / PciExpressLib.c
CommitLineData
84ace59f
LG
1/** @file\r
2 Functions in this library instance make use of MMIO functions in IoLib to\r
3 access memory mapped PCI configuration space.\r
4\r
5 All assertions for I/O operations are handled in MMIO functions in the IoLib\r
6 Library.\r
7\r
8 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.\r
9 Portions copyright (c) 2016, American Megatrends, Inc. All rights reserved.\r
9344f092 10 SPDX-License-Identifier: BSD-2-Clause-Patent\r
84ace59f
LG
11\r
12**/\r
13\r
14#include <PiDxe.h>\r
15\r
16#include <Library/BaseLib.h>\r
17#include <Library/PciExpressLib.h>\r
18#include <Library/IoLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/PcdLib.h>\r
21\r
22///\r
5c065855 23/// Module global that contains the base physical address and size of the PCI Express MMIO range.\r
84ace59f 24///\r
2f88bd3a
MK
25UINTN mSmmPciExpressLibPciExpressBaseAddress = 0;\r
26UINTN mSmmPciExpressLibPciExpressBaseSize = 0;\r
84ace59f
LG
27\r
28/**\r
29 The constructor function caches the PCI Express Base Address\r
30\r
31 @param ImageHandle The firmware allocated handle for the EFI image.\r
32 @param SystemTable A pointer to the EFI System Table.\r
33\r
34 @retval EFI_SUCCESS The constructor completed successfully.\r
35**/\r
36EFI_STATUS\r
37EFIAPI\r
38SmmPciExpressLibConstructor (\r
2f88bd3a
MK
39 IN EFI_HANDLE ImageHandle,\r
40 IN EFI_SYSTEM_TABLE *SystemTable\r
41 )\r
84ace59f 42{\r
2f88bd3a
MK
43 //\r
44 // Cache the physical address and size of the PCI Express MMIO range into a module global variable\r
45 //\r
46 mSmmPciExpressLibPciExpressBaseAddress = (UINTN)PcdGet64 (PcdPciExpressBaseAddress);\r
47 mSmmPciExpressLibPciExpressBaseSize = (UINTN)PcdGet64 (PcdPciExpressBaseSize);\r
84ace59f 48\r
2f88bd3a 49 return EFI_SUCCESS;\r
84ace59f
LG
50}\r
51\r
52/**\r
53 Assert the validity of a PCI address. A valid PCI address should contain 1's\r
54 only in the low 28 bits.\r
55\r
56 @param A The address to validate.\r
57\r
58**/\r
59#define ASSERT_INVALID_PCI_ADDRESS(A) \\r
60 ASSERT (((A) & ~0xfffffff) == 0)\r
61\r
62/**\r
63 Registers a PCI device so PCI configuration registers may be accessed after\r
64 SetVirtualAddressMap().\r
65\r
66 Registers the PCI device specified by Address so all the PCI configuration\r
67 registers associated with that PCI device may be accessed after SetVirtualAddressMap()\r
68 is called.\r
69\r
70 If Address > 0x0FFFFFFF, then ASSERT().\r
71\r
72 @param Address The address that encodes the PCI Bus, Device, Function and\r
73 Register.\r
74\r
75 @retval RETURN_SUCCESS The PCI device was registered for runtime access.\r
76 @retval RETURN_UNSUPPORTED An attempt was made to call this function\r
77 after ExitBootServices().\r
78 @retval RETURN_UNSUPPORTED The resources required to access the PCI device\r
79 at runtime could not be mapped.\r
80 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to\r
81 complete the registration.\r
82\r
83**/\r
84RETURN_STATUS\r
85EFIAPI\r
86PciExpressRegisterForRuntimeAccess (\r
2f88bd3a
MK
87 IN UINTN Address\r
88 )\r
84ace59f 89{\r
2f88bd3a
MK
90 ASSERT_INVALID_PCI_ADDRESS (Address);\r
91 return RETURN_UNSUPPORTED;\r
84ace59f
LG
92}\r
93\r
94/**\r
95 Gets MMIO address that can be used to access PCI Express location defined by Address.\r
96\r
97 This internal functions converts PCI Express address to a CPU MMIO address by adding\r
98 PCI Express Base Address stored in a global variable mSmmPciExpressLibPciExpressBaseAddress.\r
99 mSmmPciExpressLibPciExpressBaseAddress is initialized in the library constructor from PCD entry\r
100 PcdPciExpressBaseAddress.\r
101\r
5c065855
MSB
102 If Address > 0x0FFFFFFF, then ASSERT().\r
103\r
84ace59f 104 @param Address The address that encodes the PCI Bus, Device, Function and Register.\r
5c065855
MSB
105\r
106 @retval (UINTN)-1 Invalid PCI address.\r
107 @retval other MMIO address corresponding to Address.\r
84ace59f
LG
108\r
109**/\r
110UINTN\r
111GetPciExpressAddress (\r
2f88bd3a
MK
112 IN UINTN Address\r
113 )\r
84ace59f 114{\r
2f88bd3a
MK
115 //\r
116 // Make sure Address is valid\r
117 //\r
118 ASSERT_INVALID_PCI_ADDRESS (Address);\r
119 //\r
120 // Make sure the Address is in MMCONF address space\r
121 //\r
122 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
123 return (UINTN)-1;\r
124 }\r
125\r
126 return mSmmPciExpressLibPciExpressBaseAddress + Address;\r
84ace59f
LG
127}\r
128\r
129/**\r
130 Reads an 8-bit PCI configuration register.\r
131\r
132 Reads and returns the 8-bit PCI configuration register specified by Address.\r
133 This function must guarantee that all PCI read and write operations are\r
134 serialized.\r
135\r
136 If Address > 0x0FFFFFFF, then ASSERT().\r
137\r
138 @param Address The address that encodes the PCI Bus, Device, Function and\r
139 Register.\r
140\r
5c065855
MSB
141 @retval 0xFF Invalid PCI address.\r
142 @retval other The read value from the PCI configuration register.\r
84ace59f
LG
143\r
144**/\r
145UINT8\r
146EFIAPI\r
147PciExpressRead8 (\r
2f88bd3a
MK
148 IN UINTN Address\r
149 )\r
84ace59f 150{\r
2f88bd3a
MK
151 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
152 return (UINT8)-1;\r
153 }\r
154\r
155 return MmioRead8 (GetPciExpressAddress (Address));\r
84ace59f
LG
156}\r
157\r
158/**\r
159 Writes an 8-bit PCI configuration register.\r
160\r
161 Writes the 8-bit PCI configuration register specified by Address with the\r
162 value specified by Value. Value is returned. This function must guarantee\r
163 that all PCI read and write operations are serialized.\r
164\r
165 If Address > 0x0FFFFFFF, then ASSERT().\r
166\r
167 @param Address The address that encodes the PCI Bus, Device, Function and\r
168 Register.\r
169 @param Value The value to write.\r
170\r
5c065855
MSB
171 @retval 0xFF Invalid PCI address.\r
172 @retval other The value written to the PCI configuration register.\r
84ace59f
LG
173\r
174**/\r
175UINT8\r
176EFIAPI\r
177PciExpressWrite8 (\r
2f88bd3a
MK
178 IN UINTN Address,\r
179 IN UINT8 Value\r
180 )\r
84ace59f 181{\r
2f88bd3a
MK
182 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
183 return (UINT8)-1;\r
184 }\r
185\r
186 return MmioWrite8 (GetPciExpressAddress (Address), Value);\r
84ace59f
LG
187}\r
188\r
189/**\r
190 Performs a bitwise OR of an 8-bit PCI configuration register with\r
191 an 8-bit value.\r
192\r
193 Reads the 8-bit PCI configuration register specified by Address, performs a\r
194 bitwise OR between the read result and the value specified by\r
195 OrData, and writes the result to the 8-bit PCI configuration register\r
196 specified by Address. The value written to the PCI configuration register is\r
197 returned. This function must guarantee that all PCI read and write operations\r
198 are serialized.\r
199\r
200 If Address > 0x0FFFFFFF, then ASSERT().\r
201\r
202 @param Address The address that encodes the PCI Bus, Device, Function and\r
203 Register.\r
204 @param OrData The value to OR with the PCI configuration register.\r
205\r
5c065855
MSB
206 @retval 0xFF Invalid PCI address.\r
207 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
208\r
209**/\r
210UINT8\r
211EFIAPI\r
212PciExpressOr8 (\r
2f88bd3a
MK
213 IN UINTN Address,\r
214 IN UINT8 OrData\r
215 )\r
84ace59f 216{\r
2f88bd3a
MK
217 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
218 return (UINT8)-1;\r
219 }\r
220\r
221 return MmioOr8 (GetPciExpressAddress (Address), OrData);\r
84ace59f
LG
222}\r
223\r
224/**\r
225 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
226 value.\r
227\r
228 Reads the 8-bit PCI configuration register specified by Address, performs a\r
229 bitwise AND between the read result and the value specified by AndData, and\r
230 writes the result to the 8-bit PCI configuration register specified by\r
231 Address. The value written to the PCI configuration register is returned.\r
232 This function must guarantee that all PCI read and write operations are\r
233 serialized.\r
234\r
235 If Address > 0x0FFFFFFF, then ASSERT().\r
236\r
237 @param Address The address that encodes the PCI Bus, Device, Function and\r
238 Register.\r
239 @param AndData The value to AND with the PCI configuration register.\r
240\r
5c065855
MSB
241 @retval 0xFF Invalid PCI address.\r
242 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
243\r
244**/\r
245UINT8\r
246EFIAPI\r
247PciExpressAnd8 (\r
2f88bd3a
MK
248 IN UINTN Address,\r
249 IN UINT8 AndData\r
250 )\r
84ace59f 251{\r
2f88bd3a
MK
252 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
253 return (UINT8)-1;\r
254 }\r
255\r
256 return MmioAnd8 (GetPciExpressAddress (Address), AndData);\r
84ace59f
LG
257}\r
258\r
259/**\r
260 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
261 value, followed a bitwise OR with another 8-bit value.\r
262\r
263 Reads the 8-bit PCI configuration register specified by Address, performs a\r
264 bitwise AND between the read result and the value specified by AndData,\r
265 performs a bitwise OR between the result of the AND operation and\r
266 the value specified by OrData, and writes the result to the 8-bit PCI\r
267 configuration register specified by Address. The value written to the PCI\r
268 configuration register is returned. This function must guarantee that all PCI\r
269 read and write operations are serialized.\r
270\r
271 If Address > 0x0FFFFFFF, then ASSERT().\r
272\r
273 @param Address The address that encodes the PCI Bus, Device, Function and\r
274 Register.\r
275 @param AndData The value to AND with the PCI configuration register.\r
276 @param OrData The value to OR with the result of the AND operation.\r
277\r
5c065855
MSB
278 @retval 0xFF Invalid PCI address.\r
279 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
280\r
281**/\r
282UINT8\r
283EFIAPI\r
284PciExpressAndThenOr8 (\r
2f88bd3a
MK
285 IN UINTN Address,\r
286 IN UINT8 AndData,\r
287 IN UINT8 OrData\r
288 )\r
84ace59f 289{\r
2f88bd3a
MK
290 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
291 return (UINT8)-1;\r
292 }\r
293\r
294 return MmioAndThenOr8 (\r
295 GetPciExpressAddress (Address),\r
296 AndData,\r
297 OrData\r
298 );\r
84ace59f
LG
299}\r
300\r
301/**\r
302 Reads a bit field of a PCI configuration register.\r
303\r
304 Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
305 specified by the StartBit and the EndBit. The value of the bit field is\r
306 returned.\r
307\r
308 If Address > 0x0FFFFFFF, then ASSERT().\r
309 If StartBit is greater than 7, then ASSERT().\r
310 If EndBit is greater than 7, then ASSERT().\r
311 If EndBit is less than StartBit, then ASSERT().\r
312\r
313 @param Address The PCI configuration register to read.\r
314 @param StartBit The ordinal of the least significant bit in the bit field.\r
315 Range 0..7.\r
316 @param EndBit The ordinal of the most significant bit in the bit field.\r
317 Range 0..7.\r
318\r
5c065855
MSB
319 @retval 0xFF Invalid PCI address.\r
320 @retval other The value of the bit field read from the PCI configuration register.\r
84ace59f
LG
321\r
322**/\r
323UINT8\r
324EFIAPI\r
325PciExpressBitFieldRead8 (\r
2f88bd3a
MK
326 IN UINTN Address,\r
327 IN UINTN StartBit,\r
328 IN UINTN EndBit\r
329 )\r
84ace59f 330{\r
2f88bd3a
MK
331 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
332 return (UINT8)-1;\r
333 }\r
334\r
335 return MmioBitFieldRead8 (\r
336 GetPciExpressAddress (Address),\r
337 StartBit,\r
338 EndBit\r
339 );\r
84ace59f
LG
340}\r
341\r
342/**\r
343 Writes a bit field to a PCI configuration register.\r
344\r
345 Writes Value to the bit field of the PCI configuration register. The bit\r
346 field is specified by the StartBit and the EndBit. All other bits in the\r
347 destination PCI configuration register are preserved. The new value of the\r
348 8-bit register is returned.\r
349\r
350 If Address > 0x0FFFFFFF, then ASSERT().\r
351 If StartBit is greater than 7, then ASSERT().\r
352 If EndBit is greater than 7, then ASSERT().\r
353 If EndBit is less than StartBit, then ASSERT().\r
354 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
355\r
356 @param Address The PCI configuration register to write.\r
357 @param StartBit The ordinal of the least significant bit in the bit field.\r
358 Range 0..7.\r
359 @param EndBit The ordinal of the most significant bit in the bit field.\r
360 Range 0..7.\r
361 @param Value The new value of the bit field.\r
362\r
5c065855
MSB
363 @retval 0xFF Invalid PCI address.\r
364 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
365\r
366**/\r
367UINT8\r
368EFIAPI\r
369PciExpressBitFieldWrite8 (\r
2f88bd3a
MK
370 IN UINTN Address,\r
371 IN UINTN StartBit,\r
372 IN UINTN EndBit,\r
373 IN UINT8 Value\r
374 )\r
84ace59f 375{\r
2f88bd3a
MK
376 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
377 return (UINT8)-1;\r
378 }\r
379\r
380 return MmioBitFieldWrite8 (\r
381 GetPciExpressAddress (Address),\r
382 StartBit,\r
383 EndBit,\r
384 Value\r
385 );\r
84ace59f
LG
386}\r
387\r
388/**\r
389 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
390 writes the result back to the bit field in the 8-bit port.\r
391\r
392 Reads the 8-bit PCI configuration register specified by Address, performs a\r
393 bitwise OR between the read result and the value specified by\r
394 OrData, and writes the result to the 8-bit PCI configuration register\r
395 specified by Address. The value written to the PCI configuration register is\r
396 returned. This function must guarantee that all PCI read and write operations\r
397 are serialized. Extra left bits in OrData are stripped.\r
398\r
399 If Address > 0x0FFFFFFF, then ASSERT().\r
400 If StartBit is greater than 7, then ASSERT().\r
401 If EndBit is greater than 7, then ASSERT().\r
402 If EndBit is less than StartBit, then ASSERT().\r
403 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
404\r
405 @param Address The PCI configuration register to write.\r
406 @param StartBit The ordinal of the least significant bit in the bit field.\r
407 Range 0..7.\r
408 @param EndBit The ordinal of the most significant bit in the bit field.\r
409 Range 0..7.\r
410 @param OrData The value to OR with the PCI configuration register.\r
411\r
5c065855
MSB
412 @retval 0xFF Invalid PCI address.\r
413 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
414\r
415**/\r
416UINT8\r
417EFIAPI\r
418PciExpressBitFieldOr8 (\r
2f88bd3a
MK
419 IN UINTN Address,\r
420 IN UINTN StartBit,\r
421 IN UINTN EndBit,\r
422 IN UINT8 OrData\r
423 )\r
84ace59f 424{\r
2f88bd3a
MK
425 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
426 return (UINT8)-1;\r
427 }\r
428\r
429 return MmioBitFieldOr8 (\r
430 GetPciExpressAddress (Address),\r
431 StartBit,\r
432 EndBit,\r
433 OrData\r
434 );\r
84ace59f
LG
435}\r
436\r
437/**\r
438 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
439 AND, and writes the result back to the bit field in the 8-bit register.\r
440\r
441 Reads the 8-bit PCI configuration register specified by Address, performs a\r
442 bitwise AND between the read result and the value specified by AndData, and\r
443 writes the result to the 8-bit PCI configuration register specified by\r
444 Address. The value written to the PCI configuration register is returned.\r
445 This function must guarantee that all PCI read and write operations are\r
446 serialized. Extra left bits in AndData are stripped.\r
447\r
448 If Address > 0x0FFFFFFF, then ASSERT().\r
449 If StartBit is greater than 7, then ASSERT().\r
450 If EndBit is greater than 7, then ASSERT().\r
451 If EndBit is less than StartBit, then ASSERT().\r
452 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
453\r
454 @param Address The PCI configuration register to write.\r
455 @param StartBit The ordinal of the least significant bit in the bit field.\r
456 Range 0..7.\r
457 @param EndBit The ordinal of the most significant bit in the bit field.\r
458 Range 0..7.\r
459 @param AndData The value to AND with the PCI configuration register.\r
460\r
5c065855
MSB
461 @retval 0xFF Invalid PCI address.\r
462 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
463\r
464**/\r
465UINT8\r
466EFIAPI\r
467PciExpressBitFieldAnd8 (\r
2f88bd3a
MK
468 IN UINTN Address,\r
469 IN UINTN StartBit,\r
470 IN UINTN EndBit,\r
471 IN UINT8 AndData\r
472 )\r
84ace59f 473{\r
2f88bd3a
MK
474 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
475 return (UINT8)-1;\r
476 }\r
477\r
478 return MmioBitFieldAnd8 (\r
479 GetPciExpressAddress (Address),\r
480 StartBit,\r
481 EndBit,\r
482 AndData\r
483 );\r
84ace59f
LG
484}\r
485\r
486/**\r
487 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
488 bitwise OR, and writes the result back to the bit field in the\r
489 8-bit port.\r
490\r
491 Reads the 8-bit PCI configuration register specified by Address, performs a\r
492 bitwise AND followed by a bitwise OR between the read result and\r
493 the value specified by AndData, and writes the result to the 8-bit PCI\r
494 configuration register specified by Address. The value written to the PCI\r
495 configuration register is returned. This function must guarantee that all PCI\r
496 read and write operations are serialized. Extra left bits in both AndData and\r
497 OrData are stripped.\r
498\r
499 If Address > 0x0FFFFFFF, then ASSERT().\r
500 If StartBit is greater than 7, then ASSERT().\r
501 If EndBit is greater than 7, then ASSERT().\r
502 If EndBit is less than StartBit, then ASSERT().\r
503 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
504 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
505\r
506 @param Address The PCI configuration register to write.\r
507 @param StartBit The ordinal of the least significant bit in the bit field.\r
508 Range 0..7.\r
509 @param EndBit The ordinal of the most significant bit in the bit field.\r
510 Range 0..7.\r
511 @param AndData The value to AND with the PCI configuration register.\r
512 @param OrData The value to OR with the result of the AND operation.\r
513\r
5c065855
MSB
514 @retval 0xFF Invalid PCI address.\r
515 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
516\r
517**/\r
518UINT8\r
519EFIAPI\r
520PciExpressBitFieldAndThenOr8 (\r
2f88bd3a
MK
521 IN UINTN Address,\r
522 IN UINTN StartBit,\r
523 IN UINTN EndBit,\r
524 IN UINT8 AndData,\r
525 IN UINT8 OrData\r
526 )\r
84ace59f 527{\r
2f88bd3a
MK
528 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
529 return (UINT8)-1;\r
530 }\r
531\r
532 return MmioBitFieldAndThenOr8 (\r
533 GetPciExpressAddress (Address),\r
534 StartBit,\r
535 EndBit,\r
536 AndData,\r
537 OrData\r
538 );\r
84ace59f
LG
539}\r
540\r
541/**\r
542 Reads a 16-bit PCI configuration register.\r
543\r
544 Reads and returns the 16-bit PCI configuration register specified by Address.\r
545 This function must guarantee that all PCI read and write operations are\r
546 serialized.\r
547\r
548 If Address > 0x0FFFFFFF, then ASSERT().\r
549 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
550\r
551 @param Address The address that encodes the PCI Bus, Device, Function and\r
552 Register.\r
553\r
5c065855
MSB
554 @retval 0xFF Invalid PCI address.\r
555 @retval other The read value from the PCI configuration register.\r
84ace59f
LG
556\r
557**/\r
558UINT16\r
559EFIAPI\r
560PciExpressRead16 (\r
2f88bd3a
MK
561 IN UINTN Address\r
562 )\r
84ace59f 563{\r
2f88bd3a
MK
564 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
565 return (UINT16)-1;\r
566 }\r
567\r
568 return MmioRead16 (GetPciExpressAddress (Address));\r
84ace59f
LG
569}\r
570\r
571/**\r
572 Writes a 16-bit PCI configuration register.\r
573\r
574 Writes the 16-bit PCI configuration register specified by Address with the\r
575 value specified by Value. Value is returned. This function must guarantee\r
576 that all PCI read and write operations are serialized.\r
577\r
578 If Address > 0x0FFFFFFF, then ASSERT().\r
579 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
580\r
581 @param Address The address that encodes the PCI Bus, Device, Function and\r
582 Register.\r
583 @param Value The value to write.\r
584\r
5c065855
MSB
585 @retval 0xFFFF Invalid PCI address.\r
586 @retval other The value written to the PCI configuration register.\r
84ace59f
LG
587\r
588**/\r
589UINT16\r
590EFIAPI\r
591PciExpressWrite16 (\r
2f88bd3a
MK
592 IN UINTN Address,\r
593 IN UINT16 Value\r
594 )\r
84ace59f 595{\r
2f88bd3a
MK
596 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
597 return (UINT16)-1;\r
598 }\r
599\r
600 return MmioWrite16 (GetPciExpressAddress (Address), Value);\r
84ace59f
LG
601}\r
602\r
603/**\r
604 Performs a bitwise OR of a 16-bit PCI configuration register with\r
605 a 16-bit value.\r
606\r
607 Reads the 16-bit PCI configuration register specified by Address, performs a\r
608 bitwise OR between the read result and the value specified by\r
609 OrData, and writes the result to the 16-bit PCI configuration register\r
610 specified by Address. The value written to the PCI configuration register is\r
611 returned. This function must guarantee that all PCI read and write operations\r
612 are serialized.\r
613\r
614 If Address > 0x0FFFFFFF, then ASSERT().\r
615 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
616\r
617 @param Address The address that encodes the PCI Bus, Device, Function and\r
618 Register.\r
619 @param OrData The value to OR with the PCI configuration register.\r
620\r
5c065855
MSB
621 @retval 0xFFFF Invalid PCI address.\r
622 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
623\r
624**/\r
625UINT16\r
626EFIAPI\r
627PciExpressOr16 (\r
2f88bd3a
MK
628 IN UINTN Address,\r
629 IN UINT16 OrData\r
630 )\r
84ace59f 631{\r
2f88bd3a
MK
632 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
633 return (UINT16)-1;\r
634 }\r
635\r
636 return MmioOr16 (GetPciExpressAddress (Address), OrData);\r
84ace59f
LG
637}\r
638\r
639/**\r
640 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
641 value.\r
642\r
643 Reads the 16-bit PCI configuration register specified by Address, performs a\r
644 bitwise AND between the read result and the value specified by AndData, and\r
645 writes the result to the 16-bit PCI configuration register specified by\r
646 Address. The value written to the PCI configuration register is returned.\r
647 This function must guarantee that all PCI read and write operations are\r
648 serialized.\r
649\r
650 If Address > 0x0FFFFFFF, then ASSERT().\r
651 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
652\r
653 @param Address The address that encodes the PCI Bus, Device, Function and\r
654 Register.\r
655 @param AndData The value to AND with the PCI configuration register.\r
656\r
5c065855
MSB
657 @retval 0xFFFF Invalid PCI address.\r
658 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
659\r
660**/\r
661UINT16\r
662EFIAPI\r
663PciExpressAnd16 (\r
2f88bd3a
MK
664 IN UINTN Address,\r
665 IN UINT16 AndData\r
666 )\r
84ace59f 667{\r
2f88bd3a
MK
668 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
669 return (UINT16)-1;\r
670 }\r
671\r
672 return MmioAnd16 (GetPciExpressAddress (Address), AndData);\r
84ace59f
LG
673}\r
674\r
675/**\r
676 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
677 value, followed a bitwise OR with another 16-bit value.\r
678\r
679 Reads the 16-bit PCI configuration register specified by Address, performs a\r
680 bitwise AND between the read result and the value specified by AndData,\r
681 performs a bitwise OR between the result of the AND operation and\r
682 the value specified by OrData, and writes the result to the 16-bit PCI\r
683 configuration register specified by Address. The value written to the PCI\r
684 configuration register is returned. This function must guarantee that all PCI\r
685 read and write operations are serialized.\r
686\r
687 If Address > 0x0FFFFFFF, then ASSERT().\r
688 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
689\r
690 @param Address The address that encodes the PCI Bus, Device, Function and\r
691 Register.\r
692 @param AndData The value to AND with the PCI configuration register.\r
693 @param OrData The value to OR with the result of the AND operation.\r
694\r
5c065855
MSB
695 @retval 0xFFFF Invalid PCI address.\r
696 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
697\r
698**/\r
699UINT16\r
700EFIAPI\r
701PciExpressAndThenOr16 (\r
2f88bd3a
MK
702 IN UINTN Address,\r
703 IN UINT16 AndData,\r
704 IN UINT16 OrData\r
705 )\r
84ace59f 706{\r
2f88bd3a
MK
707 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
708 return (UINT16)-1;\r
709 }\r
710\r
711 return MmioAndThenOr16 (\r
712 GetPciExpressAddress (Address),\r
713 AndData,\r
714 OrData\r
715 );\r
84ace59f
LG
716}\r
717\r
718/**\r
719 Reads a bit field of a PCI configuration register.\r
720\r
721 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
722 specified by the StartBit and the EndBit. The value of the bit field is\r
723 returned.\r
724\r
725 If Address > 0x0FFFFFFF, then ASSERT().\r
726 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
727 If StartBit is greater than 15, then ASSERT().\r
728 If EndBit is greater than 15, then ASSERT().\r
729 If EndBit is less than StartBit, then ASSERT().\r
730\r
731 @param Address The PCI configuration register to read.\r
732 @param StartBit The ordinal of the least significant bit in the bit field.\r
733 Range 0..15.\r
734 @param EndBit The ordinal of the most significant bit in the bit field.\r
735 Range 0..15.\r
736\r
5c065855
MSB
737 @retval 0xFFFF Invalid PCI address.\r
738 @retval other The value of the bit field read from the PCI configuration register.\r
84ace59f
LG
739\r
740**/\r
741UINT16\r
742EFIAPI\r
743PciExpressBitFieldRead16 (\r
2f88bd3a
MK
744 IN UINTN Address,\r
745 IN UINTN StartBit,\r
746 IN UINTN EndBit\r
747 )\r
84ace59f 748{\r
2f88bd3a
MK
749 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
750 return (UINT16)-1;\r
751 }\r
752\r
753 return MmioBitFieldRead16 (\r
754 GetPciExpressAddress (Address),\r
755 StartBit,\r
756 EndBit\r
757 );\r
84ace59f
LG
758}\r
759\r
760/**\r
761 Writes a bit field to a PCI configuration register.\r
762\r
763 Writes Value to the bit field of the PCI configuration register. The bit\r
764 field is specified by the StartBit and the EndBit. All other bits in the\r
765 destination PCI configuration register are preserved. The new value of the\r
766 16-bit register is returned.\r
767\r
768 If Address > 0x0FFFFFFF, then ASSERT().\r
769 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
770 If StartBit is greater than 15, then ASSERT().\r
771 If EndBit is greater than 15, then ASSERT().\r
772 If EndBit is less than StartBit, then ASSERT().\r
773 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
774\r
775 @param Address The PCI configuration register to write.\r
776 @param StartBit The ordinal of the least significant bit in the bit field.\r
777 Range 0..15.\r
778 @param EndBit The ordinal of the most significant bit in the bit field.\r
779 Range 0..15.\r
780 @param Value The new value of the bit field.\r
781\r
5c065855
MSB
782 @retval 0xFFFF Invalid PCI address.\r
783 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
784\r
785**/\r
786UINT16\r
787EFIAPI\r
788PciExpressBitFieldWrite16 (\r
2f88bd3a
MK
789 IN UINTN Address,\r
790 IN UINTN StartBit,\r
791 IN UINTN EndBit,\r
792 IN UINT16 Value\r
793 )\r
84ace59f 794{\r
2f88bd3a
MK
795 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
796 return (UINT16)-1;\r
797 }\r
798\r
799 return MmioBitFieldWrite16 (\r
800 GetPciExpressAddress (Address),\r
801 StartBit,\r
802 EndBit,\r
803 Value\r
804 );\r
84ace59f
LG
805}\r
806\r
807/**\r
808 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
809 writes the result back to the bit field in the 16-bit port.\r
810\r
811 Reads the 16-bit PCI configuration register specified by Address, performs a\r
812 bitwise OR between the read result and the value specified by\r
813 OrData, and writes the result to the 16-bit PCI configuration register\r
814 specified by Address. The value written to the PCI configuration register is\r
815 returned. This function must guarantee that all PCI read and write operations\r
816 are serialized. Extra left bits in OrData are stripped.\r
817\r
818 If Address > 0x0FFFFFFF, then ASSERT().\r
819 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
820 If StartBit is greater than 15, then ASSERT().\r
821 If EndBit is greater than 15, then ASSERT().\r
822 If EndBit is less than StartBit, then ASSERT().\r
823 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
824\r
825 @param Address The PCI configuration register to write.\r
826 @param StartBit The ordinal of the least significant bit in the bit field.\r
827 Range 0..15.\r
828 @param EndBit The ordinal of the most significant bit in the bit field.\r
829 Range 0..15.\r
830 @param OrData The value to OR with the PCI configuration register.\r
831\r
5c065855
MSB
832 @retval 0xFFFF Invalid PCI address.\r
833 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
834\r
835**/\r
836UINT16\r
837EFIAPI\r
838PciExpressBitFieldOr16 (\r
2f88bd3a
MK
839 IN UINTN Address,\r
840 IN UINTN StartBit,\r
841 IN UINTN EndBit,\r
842 IN UINT16 OrData\r
843 )\r
84ace59f 844{\r
2f88bd3a
MK
845 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
846 return (UINT16)-1;\r
847 }\r
848\r
849 return MmioBitFieldOr16 (\r
850 GetPciExpressAddress (Address),\r
851 StartBit,\r
852 EndBit,\r
853 OrData\r
854 );\r
84ace59f
LG
855}\r
856\r
857/**\r
858 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
859 AND, and writes the result back to the bit field in the 16-bit register.\r
860\r
861 Reads the 16-bit PCI configuration register specified by Address, performs a\r
862 bitwise AND between the read result and the value specified by AndData, and\r
863 writes the result to the 16-bit PCI configuration register specified by\r
864 Address. The value written to the PCI configuration register is returned.\r
865 This function must guarantee that all PCI read and write operations are\r
866 serialized. Extra left bits in AndData are stripped.\r
867\r
868 If Address > 0x0FFFFFFF, then ASSERT().\r
869 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
870 If StartBit is greater than 15, then ASSERT().\r
871 If EndBit is greater than 15, then ASSERT().\r
872 If EndBit is less than StartBit, then ASSERT().\r
873 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
874\r
875 @param Address The PCI configuration register to write.\r
876 @param StartBit The ordinal of the least significant bit in the bit field.\r
877 Range 0..15.\r
878 @param EndBit The ordinal of the most significant bit in the bit field.\r
879 Range 0..15.\r
880 @param AndData The value to AND with the PCI configuration register.\r
881\r
5c065855
MSB
882 @retval 0xFFFF Invalid PCI address.\r
883 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
884\r
885**/\r
886UINT16\r
887EFIAPI\r
888PciExpressBitFieldAnd16 (\r
2f88bd3a
MK
889 IN UINTN Address,\r
890 IN UINTN StartBit,\r
891 IN UINTN EndBit,\r
892 IN UINT16 AndData\r
893 )\r
84ace59f 894{\r
2f88bd3a
MK
895 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
896 return (UINT16)-1;\r
897 }\r
898\r
899 return MmioBitFieldAnd16 (\r
900 GetPciExpressAddress (Address),\r
901 StartBit,\r
902 EndBit,\r
903 AndData\r
904 );\r
84ace59f
LG
905}\r
906\r
907/**\r
908 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
909 bitwise OR, and writes the result back to the bit field in the\r
910 16-bit port.\r
911\r
912 Reads the 16-bit PCI configuration register specified by Address, performs a\r
913 bitwise AND followed by a bitwise OR between the read result and\r
914 the value specified by AndData, and writes the result to the 16-bit PCI\r
915 configuration register specified by Address. The value written to the PCI\r
916 configuration register is returned. This function must guarantee that all PCI\r
917 read and write operations are serialized. Extra left bits in both AndData and\r
918 OrData are stripped.\r
919\r
920 If Address > 0x0FFFFFFF, then ASSERT().\r
921 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
922 If StartBit is greater than 15, then ASSERT().\r
923 If EndBit is greater than 15, then ASSERT().\r
924 If EndBit is less than StartBit, then ASSERT().\r
925 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
926 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
927\r
928 @param Address The PCI configuration register to write.\r
929 @param StartBit The ordinal of the least significant bit in the bit field.\r
930 Range 0..15.\r
931 @param EndBit The ordinal of the most significant bit in the bit field.\r
932 Range 0..15.\r
933 @param AndData The value to AND with the PCI configuration register.\r
934 @param OrData The value to OR with the result of the AND operation.\r
935\r
5c065855
MSB
936 @retval 0xFFFF Invalid PCI address.\r
937 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
938\r
939**/\r
940UINT16\r
941EFIAPI\r
942PciExpressBitFieldAndThenOr16 (\r
2f88bd3a
MK
943 IN UINTN Address,\r
944 IN UINTN StartBit,\r
945 IN UINTN EndBit,\r
946 IN UINT16 AndData,\r
947 IN UINT16 OrData\r
948 )\r
84ace59f 949{\r
2f88bd3a
MK
950 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
951 return (UINT16)-1;\r
952 }\r
953\r
954 return MmioBitFieldAndThenOr16 (\r
955 GetPciExpressAddress (Address),\r
956 StartBit,\r
957 EndBit,\r
958 AndData,\r
959 OrData\r
960 );\r
84ace59f
LG
961}\r
962\r
963/**\r
964 Reads a 32-bit PCI configuration register.\r
965\r
966 Reads and returns the 32-bit PCI configuration register specified by Address.\r
967 This function must guarantee that all PCI read and write operations are\r
968 serialized.\r
969\r
970 If Address > 0x0FFFFFFF, then ASSERT().\r
971 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
972\r
973 @param Address The address that encodes the PCI Bus, Device, Function and\r
974 Register.\r
975\r
5c065855
MSB
976 @retval 0xFFFFFFFF Invalid PCI address.\r
977 @retval other The read value from the PCI configuration register.\r
84ace59f
LG
978\r
979**/\r
980UINT32\r
981EFIAPI\r
982PciExpressRead32 (\r
2f88bd3a
MK
983 IN UINTN Address\r
984 )\r
84ace59f 985{\r
2f88bd3a
MK
986 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
987 return (UINT32)-1;\r
988 }\r
989\r
990 return MmioRead32 (GetPciExpressAddress (Address));\r
84ace59f
LG
991}\r
992\r
993/**\r
994 Writes a 32-bit PCI configuration register.\r
995\r
996 Writes the 32-bit PCI configuration register specified by Address with the\r
997 value specified by Value. Value is returned. This function must guarantee\r
998 that all PCI read and write operations are serialized.\r
999\r
1000 If Address > 0x0FFFFFFF, then ASSERT().\r
1001 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1002\r
1003 @param Address The address that encodes the PCI Bus, Device, Function and\r
1004 Register.\r
1005 @param Value The value to write.\r
1006\r
5c065855
MSB
1007 @retval 0xFFFFFFFF Invalid PCI address.\r
1008 @retval other The value written to the PCI configuration register.\r
84ace59f
LG
1009\r
1010**/\r
1011UINT32\r
1012EFIAPI\r
1013PciExpressWrite32 (\r
2f88bd3a
MK
1014 IN UINTN Address,\r
1015 IN UINT32 Value\r
1016 )\r
84ace59f 1017{\r
2f88bd3a
MK
1018 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1019 return (UINT32)-1;\r
1020 }\r
1021\r
1022 return MmioWrite32 (GetPciExpressAddress (Address), Value);\r
84ace59f
LG
1023}\r
1024\r
1025/**\r
1026 Performs a bitwise OR of a 32-bit PCI configuration register with\r
1027 a 32-bit value.\r
1028\r
1029 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1030 bitwise OR between the read result and the value specified by\r
1031 OrData, and writes the result to the 32-bit PCI configuration register\r
1032 specified by Address. The value written to the PCI configuration register is\r
1033 returned. This function must guarantee that all PCI read and write operations\r
1034 are serialized.\r
1035\r
1036 If Address > 0x0FFFFFFF, then ASSERT().\r
1037 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1038\r
1039 @param Address The address that encodes the PCI Bus, Device, Function and\r
1040 Register.\r
1041 @param OrData The value to OR with the PCI configuration register.\r
1042\r
5c065855
MSB
1043 @retval 0xFFFFFFFF Invalid PCI address.\r
1044 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1045\r
1046**/\r
1047UINT32\r
1048EFIAPI\r
1049PciExpressOr32 (\r
2f88bd3a
MK
1050 IN UINTN Address,\r
1051 IN UINT32 OrData\r
1052 )\r
84ace59f 1053{\r
2f88bd3a
MK
1054 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1055 return (UINT32)-1;\r
1056 }\r
1057\r
1058 return MmioOr32 (GetPciExpressAddress (Address), OrData);\r
84ace59f
LG
1059}\r
1060\r
1061/**\r
1062 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
1063 value.\r
1064\r
1065 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1066 bitwise AND between the read result and the value specified by AndData, and\r
1067 writes the result to the 32-bit PCI configuration register specified by\r
1068 Address. The value written to the PCI configuration register is returned.\r
1069 This function must guarantee that all PCI read and write operations are\r
1070 serialized.\r
1071\r
1072 If Address > 0x0FFFFFFF, then ASSERT().\r
1073 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1074\r
1075 @param Address The address that encodes the PCI Bus, Device, Function and\r
1076 Register.\r
1077 @param AndData The value to AND with the PCI configuration register.\r
1078\r
5c065855
MSB
1079 @retval 0xFFFFFFFF Invalid PCI address.\r
1080 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1081\r
1082**/\r
1083UINT32\r
1084EFIAPI\r
1085PciExpressAnd32 (\r
2f88bd3a
MK
1086 IN UINTN Address,\r
1087 IN UINT32 AndData\r
1088 )\r
84ace59f 1089{\r
2f88bd3a
MK
1090 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1091 return (UINT32)-1;\r
1092 }\r
1093\r
1094 return MmioAnd32 (GetPciExpressAddress (Address), AndData);\r
84ace59f
LG
1095}\r
1096\r
1097/**\r
1098 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
1099 value, followed a bitwise OR with another 32-bit value.\r
1100\r
1101 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1102 bitwise AND between the read result and the value specified by AndData,\r
1103 performs a bitwise OR between the result of the AND operation and\r
1104 the value specified by OrData, and writes the result to the 32-bit PCI\r
1105 configuration register specified by Address. The value written to the PCI\r
1106 configuration register is returned. This function must guarantee that all PCI\r
1107 read and write operations are serialized.\r
1108\r
1109 If Address > 0x0FFFFFFF, then ASSERT().\r
1110 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1111\r
1112 @param Address The address that encodes the PCI Bus, Device, Function and\r
1113 Register.\r
1114 @param AndData The value to AND with the PCI configuration register.\r
1115 @param OrData The value to OR with the result of the AND operation.\r
1116\r
5c065855
MSB
1117 @retval 0xFFFFFFFF Invalid PCI address.\r
1118 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1119\r
1120**/\r
1121UINT32\r
1122EFIAPI\r
1123PciExpressAndThenOr32 (\r
2f88bd3a
MK
1124 IN UINTN Address,\r
1125 IN UINT32 AndData,\r
1126 IN UINT32 OrData\r
1127 )\r
84ace59f 1128{\r
2f88bd3a
MK
1129 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1130 return (UINT32)-1;\r
1131 }\r
1132\r
1133 return MmioAndThenOr32 (\r
1134 GetPciExpressAddress (Address),\r
1135 AndData,\r
1136 OrData\r
1137 );\r
84ace59f
LG
1138}\r
1139\r
1140/**\r
1141 Reads a bit field of a PCI configuration register.\r
1142\r
1143 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1144 specified by the StartBit and the EndBit. The value of the bit field is\r
1145 returned.\r
1146\r
1147 If Address > 0x0FFFFFFF, then ASSERT().\r
1148 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1149 If StartBit is greater than 31, then ASSERT().\r
1150 If EndBit is greater than 31, then ASSERT().\r
1151 If EndBit is less than StartBit, then ASSERT().\r
1152\r
1153 @param Address The PCI configuration register to read.\r
1154 @param StartBit The ordinal of the least significant bit in the bit field.\r
1155 Range 0..31.\r
1156 @param EndBit The ordinal of the most significant bit in the bit field.\r
1157 Range 0..31.\r
1158\r
5c065855
MSB
1159 @retval 0xFFFFFFFF Invalid PCI address.\r
1160 @retval other The value of the bit field read from the PCI configuration register.\r
84ace59f
LG
1161\r
1162**/\r
1163UINT32\r
1164EFIAPI\r
1165PciExpressBitFieldRead32 (\r
2f88bd3a
MK
1166 IN UINTN Address,\r
1167 IN UINTN StartBit,\r
1168 IN UINTN EndBit\r
1169 )\r
84ace59f 1170{\r
2f88bd3a
MK
1171 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1172 return (UINT32)-1;\r
1173 }\r
1174\r
1175 return MmioBitFieldRead32 (\r
1176 GetPciExpressAddress (Address),\r
1177 StartBit,\r
1178 EndBit\r
1179 );\r
84ace59f
LG
1180}\r
1181\r
1182/**\r
1183 Writes a bit field to a PCI configuration register.\r
1184\r
1185 Writes Value to the bit field of the PCI configuration register. The bit\r
1186 field is specified by the StartBit and the EndBit. All other bits in the\r
1187 destination PCI configuration register are preserved. The new value of the\r
1188 32-bit register is returned.\r
1189\r
1190 If Address > 0x0FFFFFFF, then ASSERT().\r
1191 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1192 If StartBit is greater than 31, then ASSERT().\r
1193 If EndBit is greater than 31, then ASSERT().\r
1194 If EndBit is less than StartBit, then ASSERT().\r
1195 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1196\r
1197 @param Address The PCI configuration register to write.\r
1198 @param StartBit The ordinal of the least significant bit in the bit field.\r
1199 Range 0..31.\r
1200 @param EndBit The ordinal of the most significant bit in the bit field.\r
1201 Range 0..31.\r
1202 @param Value The new value of the bit field.\r
1203\r
5c065855
MSB
1204 @retval 0xFFFFFFFF Invalid PCI address.\r
1205 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1206\r
1207**/\r
1208UINT32\r
1209EFIAPI\r
1210PciExpressBitFieldWrite32 (\r
2f88bd3a
MK
1211 IN UINTN Address,\r
1212 IN UINTN StartBit,\r
1213 IN UINTN EndBit,\r
1214 IN UINT32 Value\r
1215 )\r
84ace59f 1216{\r
2f88bd3a
MK
1217 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1218 return (UINT32)-1;\r
1219 }\r
1220\r
1221 return MmioBitFieldWrite32 (\r
1222 GetPciExpressAddress (Address),\r
1223 StartBit,\r
1224 EndBit,\r
1225 Value\r
1226 );\r
84ace59f
LG
1227}\r
1228\r
1229/**\r
1230 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1231 writes the result back to the bit field in the 32-bit port.\r
1232\r
1233 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1234 bitwise OR between the read result and the value specified by\r
1235 OrData, and writes the result to the 32-bit PCI configuration register\r
1236 specified by Address. The value written to the PCI configuration register is\r
1237 returned. This function must guarantee that all PCI read and write operations\r
1238 are serialized. Extra left bits in OrData are stripped.\r
1239\r
1240 If Address > 0x0FFFFFFF, then ASSERT().\r
1241 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1242 If StartBit is greater than 31, then ASSERT().\r
1243 If EndBit is greater than 31, then ASSERT().\r
1244 If EndBit is less than StartBit, then ASSERT().\r
1245 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1246\r
1247 @param Address The PCI configuration register to write.\r
1248 @param StartBit The ordinal of the least significant bit in the bit field.\r
1249 Range 0..31.\r
1250 @param EndBit The ordinal of the most significant bit in the bit field.\r
1251 Range 0..31.\r
1252 @param OrData The value to OR with the PCI configuration register.\r
1253\r
5c065855
MSB
1254 @retval 0xFFFFFFFF Invalid PCI address.\r
1255 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1256\r
1257**/\r
1258UINT32\r
1259EFIAPI\r
1260PciExpressBitFieldOr32 (\r
2f88bd3a
MK
1261 IN UINTN Address,\r
1262 IN UINTN StartBit,\r
1263 IN UINTN EndBit,\r
1264 IN UINT32 OrData\r
1265 )\r
84ace59f 1266{\r
2f88bd3a
MK
1267 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1268 return (UINT32)-1;\r
1269 }\r
1270\r
1271 return MmioBitFieldOr32 (\r
1272 GetPciExpressAddress (Address),\r
1273 StartBit,\r
1274 EndBit,\r
1275 OrData\r
1276 );\r
84ace59f
LG
1277}\r
1278\r
1279/**\r
1280 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1281 AND, and writes the result back to the bit field in the 32-bit register.\r
1282\r
1283 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1284 bitwise AND between the read result and the value specified by AndData, and\r
1285 writes the result to the 32-bit PCI configuration register specified by\r
1286 Address. The value written to the PCI configuration register is returned.\r
1287 This function must guarantee that all PCI read and write operations are\r
1288 serialized. Extra left bits in AndData are stripped.\r
1289\r
1290 If Address > 0x0FFFFFFF, then ASSERT().\r
1291 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1292 If StartBit is greater than 31, then ASSERT().\r
1293 If EndBit is greater than 31, then ASSERT().\r
1294 If EndBit is less than StartBit, then ASSERT().\r
1295 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1296\r
1297 @param Address The PCI configuration register to write.\r
1298 @param StartBit The ordinal of the least significant bit in the bit field.\r
1299 Range 0..31.\r
1300 @param EndBit The ordinal of the most significant bit in the bit field.\r
1301 Range 0..31.\r
1302 @param AndData The value to AND with the PCI configuration register.\r
1303\r
5c065855
MSB
1304 @retval 0xFFFFFFFF Invalid PCI address.\r
1305 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1306\r
1307**/\r
1308UINT32\r
1309EFIAPI\r
1310PciExpressBitFieldAnd32 (\r
2f88bd3a
MK
1311 IN UINTN Address,\r
1312 IN UINTN StartBit,\r
1313 IN UINTN EndBit,\r
1314 IN UINT32 AndData\r
1315 )\r
84ace59f 1316{\r
2f88bd3a
MK
1317 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1318 return (UINT32)-1;\r
1319 }\r
1320\r
1321 return MmioBitFieldAnd32 (\r
1322 GetPciExpressAddress (Address),\r
1323 StartBit,\r
1324 EndBit,\r
1325 AndData\r
1326 );\r
84ace59f
LG
1327}\r
1328\r
1329/**\r
1330 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
1331 bitwise OR, and writes the result back to the bit field in the\r
1332 32-bit port.\r
1333\r
1334 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1335 bitwise AND followed by a bitwise OR between the read result and\r
1336 the value specified by AndData, and writes the result to the 32-bit PCI\r
1337 configuration register specified by Address. The value written to the PCI\r
1338 configuration register is returned. This function must guarantee that all PCI\r
1339 read and write operations are serialized. Extra left bits in both AndData and\r
1340 OrData are stripped.\r
1341\r
1342 If Address > 0x0FFFFFFF, then ASSERT().\r
1343 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1344 If StartBit is greater than 31, then ASSERT().\r
1345 If EndBit is greater than 31, then ASSERT().\r
1346 If EndBit is less than StartBit, then ASSERT().\r
1347 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1348 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1349\r
1350 @param Address The PCI configuration register to write.\r
1351 @param StartBit The ordinal of the least significant bit in the bit field.\r
1352 Range 0..31.\r
1353 @param EndBit The ordinal of the most significant bit in the bit field.\r
1354 Range 0..31.\r
1355 @param AndData The value to AND with the PCI configuration register.\r
1356 @param OrData The value to OR with the result of the AND operation.\r
1357\r
5c065855
MSB
1358 @retval 0xFFFFFFFF Invalid PCI address.\r
1359 @retval other The value written back to the PCI configuration register.\r
84ace59f
LG
1360\r
1361**/\r
1362UINT32\r
1363EFIAPI\r
1364PciExpressBitFieldAndThenOr32 (\r
2f88bd3a
MK
1365 IN UINTN Address,\r
1366 IN UINTN StartBit,\r
1367 IN UINTN EndBit,\r
1368 IN UINT32 AndData,\r
1369 IN UINT32 OrData\r
1370 )\r
84ace59f 1371{\r
2f88bd3a
MK
1372 if (Address >= mSmmPciExpressLibPciExpressBaseSize) {\r
1373 return (UINT32)-1;\r
1374 }\r
1375\r
1376 return MmioBitFieldAndThenOr32 (\r
1377 GetPciExpressAddress (Address),\r
1378 StartBit,\r
1379 EndBit,\r
1380 AndData,\r
1381 OrData\r
1382 );\r
84ace59f
LG
1383}\r
1384\r
1385/**\r
1386 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1387\r
1388 Reads the range of PCI configuration registers specified by StartAddress and\r
1389 Size into the buffer specified by Buffer. This function only allows the PCI\r
1390 configuration registers from a single PCI function to be read. Size is\r
1391 returned. When possible 32-bit PCI configuration read cycles are used to read\r
fae43d06 1392 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
84ace59f
LG
1393 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1394 end of the range.\r
1395\r
1396 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1397 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1398 If Size > 0 and Buffer is NULL, then ASSERT().\r
1399\r
1400 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
1401 Function and Register.\r
1402 @param Size The size in bytes of the transfer.\r
1403 @param Buffer The pointer to a buffer receiving the data read.\r
1404\r
5c065855
MSB
1405 @retval (UINTN)-1 Invalid PCI address.\r
1406 @retval other Size read data from StartAddress.\r
84ace59f
LG
1407\r
1408**/\r
1409UINTN\r
1410EFIAPI\r
1411PciExpressReadBuffer (\r
2f88bd3a
MK
1412 IN UINTN StartAddress,\r
1413 IN UINTN Size,\r
1414 OUT VOID *Buffer\r
1415 )\r
84ace59f 1416{\r
2f88bd3a
MK
1417 UINTN ReturnValue;\r
1418\r
1419 //\r
1420 // Make sure Address is valid\r
1421 //\r
1422 ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
1423 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1424\r
1425 //\r
1426 // Make sure the Address is in MMCONF address space\r
1427 //\r
1428 if (StartAddress >= mSmmPciExpressLibPciExpressBaseSize) {\r
1429 return (UINTN)-1;\r
1430 }\r
1431\r
1432 if (Size == 0) {\r
1433 return Size;\r
1434 }\r
1435\r
1436 ASSERT (Buffer != NULL);\r
1437\r
1438 //\r
1439 // Save Size for return\r
1440 //\r
1441 ReturnValue = Size;\r
1442\r
1443 if ((StartAddress & 1) != 0) {\r
1444 //\r
1445 // Read a byte if StartAddress is byte aligned\r
1446 //\r
1447 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
1448 StartAddress += sizeof (UINT8);\r
1449 Size -= sizeof (UINT8);\r
1450 Buffer = (UINT8 *)Buffer + 1;\r
1451 }\r
1452\r
1453 if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {\r
1454 //\r
1455 // Read a word if StartAddress is word aligned\r
1456 //\r
1457 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));\r
1458\r
1459 StartAddress += sizeof (UINT16);\r
1460 Size -= sizeof (UINT16);\r
1461 Buffer = (UINT16 *)Buffer + 1;\r
1462 }\r
1463\r
1464 while (Size >= sizeof (UINT32)) {\r
1465 //\r
1466 // Read as many double words as possible\r
1467 //\r
1468 WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)PciExpressRead32 (StartAddress));\r
1469\r
1470 StartAddress += sizeof (UINT32);\r
1471 Size -= sizeof (UINT32);\r
1472 Buffer = (UINT32 *)Buffer + 1;\r
1473 }\r
1474\r
1475 if (Size >= sizeof (UINT16)) {\r
1476 //\r
1477 // Read the last remaining word if exist\r
1478 //\r
1479 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartAddress));\r
1480 StartAddress += sizeof (UINT16);\r
1481 Size -= sizeof (UINT16);\r
1482 Buffer = (UINT16 *)Buffer + 1;\r
1483 }\r
1484\r
1485 if (Size >= sizeof (UINT8)) {\r
1486 //\r
1487 // Read the last remaining byte if exist\r
1488 //\r
1489 *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
1490 }\r
1491\r
1492 return ReturnValue;\r
84ace59f
LG
1493}\r
1494\r
1495/**\r
1496 Copies the data in a caller supplied buffer to a specified range of PCI\r
1497 configuration space.\r
1498\r
1499 Writes the range of PCI configuration registers specified by StartAddress and\r
1500 Size from the buffer specified by Buffer. This function only allows the PCI\r
1501 configuration registers from a single PCI function to be written. Size is\r
1502 returned. When possible 32-bit PCI configuration write cycles are used to\r
fae43d06 1503 write from StartAddress to StartAddress + Size. Due to alignment restrictions,\r
84ace59f
LG
1504 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1505 and the end of the range.\r
1506\r
1507 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1508 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1509 If Size > 0 and Buffer is NULL, then ASSERT().\r
1510\r
1511 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
1512 Function and Register.\r
1513 @param Size The size in bytes of the transfer.\r
1514 @param Buffer The pointer to a buffer containing the data to write.\r
1515\r
5c065855
MSB
1516 @retval (UINTN)-1 Invalid PCI address.\r
1517 @retval other Size written to StartAddress.\r
84ace59f
LG
1518\r
1519**/\r
1520UINTN\r
1521EFIAPI\r
1522PciExpressWriteBuffer (\r
2f88bd3a
MK
1523 IN UINTN StartAddress,\r
1524 IN UINTN Size,\r
1525 IN VOID *Buffer\r
1526 )\r
84ace59f 1527{\r
2f88bd3a
MK
1528 UINTN ReturnValue;\r
1529\r
1530 //\r
1531 // Make sure Address is valid\r
1532 //\r
1533 ASSERT_INVALID_PCI_ADDRESS (StartAddress);\r
1534 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1535\r
1536 //\r
1537 // Make sure the Address is in MMCONF address space\r
1538 //\r
1539 if (StartAddress >= mSmmPciExpressLibPciExpressBaseSize) {\r
1540 return (UINTN)-1;\r
1541 }\r
1542\r
1543 if (Size == 0) {\r
1544 return 0;\r
1545 }\r
1546\r
1547 ASSERT (Buffer != NULL);\r
1548\r
1549 //\r
1550 // Save Size for return\r
1551 //\r
1552 ReturnValue = Size;\r
1553\r
1554 if ((StartAddress & 1) != 0) {\r
1555 //\r
1556 // Write a byte if StartAddress is byte aligned\r
1557 //\r
1558 PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);\r
1559 StartAddress += sizeof (UINT8);\r
1560 Size -= sizeof (UINT8);\r
1561 Buffer = (UINT8 *)Buffer + 1;\r
1562 }\r
1563\r
1564 if ((Size >= sizeof (UINT16)) && ((StartAddress & 2) != 0)) {\r
1565 //\r
1566 // Write a word if StartAddress is word aligned\r
1567 //\r
1568 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));\r
1569 StartAddress += sizeof (UINT16);\r
1570 Size -= sizeof (UINT16);\r
1571 Buffer = (UINT16 *)Buffer + 1;\r
1572 }\r
1573\r
1574 while (Size >= sizeof (UINT32)) {\r
1575 //\r
1576 // Write as many double words as possible\r
1577 //\r
1578 PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32 *)Buffer));\r
1579 StartAddress += sizeof (UINT32);\r
1580 Size -= sizeof (UINT32);\r
1581 Buffer = (UINT32 *)Buffer + 1;\r
1582 }\r
1583\r
1584 if (Size >= sizeof (UINT16)) {\r
1585 //\r
1586 // Write the last remaining word if exist\r
1587 //\r
1588 PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer));\r
1589 StartAddress += sizeof (UINT16);\r
1590 Size -= sizeof (UINT16);\r
1591 Buffer = (UINT16 *)Buffer + 1;\r
1592 }\r
1593\r
1594 if (Size >= sizeof (UINT8)) {\r
1595 //\r
1596 // Write the last remaining byte if exist\r
1597 //\r
1598 PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer);\r
1599 }\r
1600\r
1601 return ReturnValue;\r
84ace59f 1602}\r