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