]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / SmmPciLibPciRootBridgeIo / PciLib.c
CommitLineData
b7c5912a 1/** @file\r
2 PCI Library using SMM PCI Root Bridge I/O Protocol.\r
3\r
9095d37b 4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
b7c5912a 6\r
7**/\r
8#include <PiSmm.h>\r
b7c5912a 9#include <Protocol/SmmPciRootBridgeIo.h>\r
10#include <Library/PciLib.h>\r
11#include <Library/DebugLib.h>\r
12#include <Library/BaseLib.h>\r
13#include <Library/SmmServicesTableLib.h>\r
14\r
b7c5912a 15/**\r
16 Assert the validity of a PCI address. A valid PCI address should contain 1's\r
17 only in the low 28 bits.\r
18\r
19 @param A The address to validate.\r
20 @param M Additional bits to assert to be zero.\r
21\r
22**/\r
2f88bd3a 23#define ASSERT_INVALID_PCI_ADDRESS(A, M) \\r
b7c5912a 24 ASSERT (((A) & (~0xfffffff | (M))) == 0)\r
25\r
26/**\r
27 Translate PCI Lib address into format of PCI Root Bridge I/O Protocol.\r
28\r
2fc59a00 29 @param A The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 30 Register.\r
31\r
32**/\r
33#define PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS(A) \\r
34 ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))\r
35\r
36//\r
fae43d06 37// Global variable to cache pointer to PCI Root Bridge I/O protocol.\r
b7c5912a 38//\r
2f88bd3a 39EFI_SMM_PCI_ROOT_BRIDGE_IO_PROTOCOL *mSmmPciRootBridgeIo = NULL;\r
b7c5912a 40\r
41/**\r
42 The constructor function caches the pointer to PCI Root Bridge I/O protocol.\r
9095d37b 43\r
b7c5912a 44 The constructor function locates PCI Root Bridge I/O protocol from protocol database.\r
9095d37b 45 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
b7c5912a 46\r
47 @param ImageHandle The firmware allocated handle for the EFI image.\r
48 @param SystemTable A pointer to the EFI System Table.\r
9095d37b 49\r
b7c5912a 50 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
51\r
52**/\r
53EFI_STATUS\r
54EFIAPI\r
55PciLibConstructor (\r
2f88bd3a
MK
56 IN EFI_HANDLE ImageHandle,\r
57 IN EFI_SYSTEM_TABLE *SystemTable\r
b7c5912a 58 )\r
59{\r
60 EFI_STATUS Status;\r
9095d37b 61\r
2f88bd3a 62 Status = gSmst->SmmLocateProtocol (&gEfiSmmPciRootBridgeIoProtocolGuid, NULL, (VOID **)&mSmmPciRootBridgeIo);\r
b7c5912a 63 ASSERT_EFI_ERROR (Status);\r
64 ASSERT (mSmmPciRootBridgeIo != NULL);\r
65\r
66 return EFI_SUCCESS;\r
67}\r
68\r
69/**\r
70 Internal worker function to read a PCI configuration register.\r
71\r
72 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.\r
73 It reads and returns the PCI configuration register specified by Address,\r
74 the width of data is specified by Width.\r
75\r
2fc59a00 76 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 77 Register.\r
58380e9c 78 @param Width The width of data to read\r
b7c5912a 79\r
80 @return The value read from the PCI configuration register.\r
81\r
82**/\r
83UINT32\r
84SmmPciLibPciRootBridgeIoReadWorker (\r
85 IN UINTN Address,\r
86 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width\r
87 )\r
88{\r
89 UINT32 Data;\r
90\r
91 mSmmPciRootBridgeIo->Pci.Read (\r
2f88bd3a
MK
92 mSmmPciRootBridgeIo,\r
93 Width,\r
94 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),\r
95 1,\r
96 &Data\r
97 );\r
b7c5912a 98\r
99 return Data;\r
100}\r
101\r
102/**\r
103 Internal worker function to writes a PCI configuration register.\r
104\r
105 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.\r
106 It writes the PCI configuration register specified by Address with the\r
a750b4ae 107 value specified by Data. The width of data is specified by Width.\r
b7c5912a 108 Data is returned.\r
109\r
2fc59a00 110 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 111 Register.\r
58380e9c 112 @param Width The width of data to write\r
b7c5912a 113 @param Data The value to write.\r
114\r
115 @return The value written to the PCI configuration register.\r
116\r
117**/\r
118UINT32\r
119SmmPciLibPciRootBridgeIoWriteWorker (\r
120 IN UINTN Address,\r
121 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
122 IN UINT32 Data\r
123 )\r
124{\r
125 mSmmPciRootBridgeIo->Pci.Write (\r
2f88bd3a
MK
126 mSmmPciRootBridgeIo,\r
127 Width,\r
128 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),\r
129 1,\r
130 &Data\r
131 );\r
b7c5912a 132 return Data;\r
133}\r
134\r
135/**\r
9095d37b 136 Registers a PCI device so PCI configuration registers may be accessed after\r
b7c5912a 137 SetVirtualAddressMap().\r
9095d37b
LG
138\r
139 Registers the PCI device specified by Address so all the PCI configuration registers\r
b7c5912a 140 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.\r
9095d37b 141\r
b7c5912a 142 If Address > 0x0FFFFFFF, then ASSERT().\r
143\r
2fc59a00 144 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 145 Register.\r
9095d37b 146\r
b7c5912a 147 @retval RETURN_SUCCESS The PCI device was registered for runtime access.\r
9095d37b 148 @retval RETURN_UNSUPPORTED An attempt was made to call this function\r
b7c5912a 149 after ExitBootServices().\r
150 @retval RETURN_UNSUPPORTED The resources required to access the PCI device\r
151 at runtime could not be mapped.\r
152 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to\r
153 complete the registration.\r
154\r
155**/\r
156RETURN_STATUS\r
157EFIAPI\r
158PciRegisterForRuntimeAccess (\r
159 IN UINTN Address\r
160 )\r
161{\r
162 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
163 return RETURN_UNSUPPORTED;\r
164}\r
165\r
166/**\r
167 Reads an 8-bit PCI configuration register.\r
168\r
169 Reads and returns the 8-bit PCI configuration register specified by Address.\r
170 This function must guarantee that all PCI read and write operations are\r
171 serialized.\r
172\r
173 If Address > 0x0FFFFFFF, then ASSERT().\r
174\r
2fc59a00 175 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 176 Register.\r
177\r
178 @return The read value from the PCI configuration register.\r
179\r
180**/\r
181UINT8\r
182EFIAPI\r
183PciRead8 (\r
2f88bd3a 184 IN UINTN Address\r
b7c5912a 185 )\r
186{\r
187 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
188\r
2f88bd3a 189 return (UINT8)SmmPciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);\r
b7c5912a 190}\r
191\r
192/**\r
193 Writes an 8-bit PCI configuration register.\r
194\r
195 Writes the 8-bit PCI configuration register specified by Address with the\r
196 value specified by Value. Value is returned. This function must guarantee\r
197 that all PCI read and write operations are serialized.\r
198\r
199 If Address > 0x0FFFFFFF, then ASSERT().\r
200\r
2fc59a00 201 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 202 Register.\r
203 @param Value The value to write.\r
204\r
205 @return The value written to the PCI configuration register.\r
206\r
207**/\r
208UINT8\r
209EFIAPI\r
210PciWrite8 (\r
2f88bd3a
MK
211 IN UINTN Address,\r
212 IN UINT8 Value\r
b7c5912a 213 )\r
214{\r
215 ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
216\r
2f88bd3a 217 return (UINT8)SmmPciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Value);\r
b7c5912a 218}\r
219\r
220/**\r
221 Performs a bitwise OR of an 8-bit PCI configuration register with\r
222 an 8-bit value.\r
223\r
224 Reads the 8-bit PCI configuration register specified by Address, performs a\r
225 bitwise OR between the read result and the value specified by\r
226 OrData, and writes the result to the 8-bit PCI configuration register\r
227 specified by Address. The value written to the PCI configuration register is\r
228 returned. This function must guarantee that all PCI read and write operations\r
229 are serialized.\r
230\r
231 If Address > 0x0FFFFFFF, then ASSERT().\r
232\r
2fc59a00 233 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 234 Register.\r
235 @param OrData The value to OR with the PCI configuration register.\r
236\r
237 @return The value written back to the PCI configuration register.\r
238\r
239**/\r
240UINT8\r
241EFIAPI\r
242PciOr8 (\r
2f88bd3a
MK
243 IN UINTN Address,\r
244 IN UINT8 OrData\r
b7c5912a 245 )\r
246{\r
2f88bd3a 247 return PciWrite8 (Address, (UINT8)(PciRead8 (Address) | OrData));\r
b7c5912a 248}\r
249\r
250/**\r
251 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
252 value.\r
253\r
254 Reads the 8-bit PCI configuration register specified by Address, performs a\r
255 bitwise AND between the read result and the value specified by AndData, and\r
256 writes the result to the 8-bit PCI configuration register specified by\r
257 Address. The value written to the PCI configuration register is returned.\r
258 This function must guarantee that all PCI read and write operations are\r
259 serialized.\r
260\r
261 If Address > 0x0FFFFFFF, then ASSERT().\r
262\r
2fc59a00 263 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 264 Register.\r
265 @param AndData The value to AND with the PCI configuration register.\r
266\r
267 @return The value written back to the PCI configuration register.\r
268\r
269**/\r
270UINT8\r
271EFIAPI\r
272PciAnd8 (\r
2f88bd3a
MK
273 IN UINTN Address,\r
274 IN UINT8 AndData\r
b7c5912a 275 )\r
276{\r
2f88bd3a 277 return PciWrite8 (Address, (UINT8)(PciRead8 (Address) & AndData));\r
b7c5912a 278}\r
279\r
280/**\r
281 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
282 value, followed a bitwise OR with another 8-bit value.\r
283\r
284 Reads the 8-bit PCI configuration register specified by Address, performs a\r
285 bitwise AND between the read result and the value specified by AndData,\r
286 performs a bitwise OR between the result of the AND operation and\r
287 the value specified by OrData, and writes the result to the 8-bit PCI\r
288 configuration register specified by Address. The value written to the PCI\r
289 configuration register is returned. This function must guarantee that all PCI\r
290 read and write operations are serialized.\r
291\r
292 If Address > 0x0FFFFFFF, then ASSERT().\r
293\r
2fc59a00 294 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 295 Register.\r
296 @param AndData The value to AND with the PCI configuration register.\r
297 @param OrData The value to OR with the result of the AND operation.\r
298\r
299 @return The value written back to the PCI configuration register.\r
300\r
301**/\r
302UINT8\r
303EFIAPI\r
304PciAndThenOr8 (\r
2f88bd3a
MK
305 IN UINTN Address,\r
306 IN UINT8 AndData,\r
307 IN UINT8 OrData\r
b7c5912a 308 )\r
309{\r
2f88bd3a 310 return PciWrite8 (Address, (UINT8)((PciRead8 (Address) & AndData) | OrData));\r
b7c5912a 311}\r
312\r
313/**\r
314 Reads a bit field of a PCI configuration register.\r
315\r
316 Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
317 specified by the StartBit and the EndBit. The value of the bit field is\r
318 returned.\r
319\r
320 If Address > 0x0FFFFFFF, then ASSERT().\r
321 If StartBit is greater than 7, then ASSERT().\r
322 If EndBit is greater than 7, then ASSERT().\r
323 If EndBit is less than StartBit, then ASSERT().\r
324\r
2fc59a00 325 @param Address The PCI configuration register to read.\r
b7c5912a 326 @param StartBit The ordinal of the least significant bit in the bit field.\r
327 Range 0..7.\r
328 @param EndBit The ordinal of the most significant bit in the bit field.\r
329 Range 0..7.\r
330\r
331 @return The value of the bit field read from the PCI configuration register.\r
332\r
333**/\r
334UINT8\r
335EFIAPI\r
336PciBitFieldRead8 (\r
2f88bd3a
MK
337 IN UINTN Address,\r
338 IN UINTN StartBit,\r
339 IN UINTN EndBit\r
b7c5912a 340 )\r
341{\r
342 return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);\r
343}\r
344\r
345/**\r
346 Writes a bit field to a PCI configuration register.\r
347\r
348 Writes Value to the bit field of the PCI configuration register. The bit\r
349 field is specified by the StartBit and the EndBit. All other bits in the\r
350 destination PCI configuration register are preserved. The new value of the\r
351 8-bit register is returned.\r
352\r
353 If Address > 0x0FFFFFFF, then ASSERT().\r
354 If StartBit is greater than 7, then ASSERT().\r
355 If EndBit is greater than 7, then ASSERT().\r
356 If EndBit is less than StartBit, then ASSERT().\r
94952554 357 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 358\r
2fc59a00 359 @param Address The PCI configuration register to write.\r
b7c5912a 360 @param StartBit The ordinal of the least significant bit in the bit field.\r
361 Range 0..7.\r
362 @param EndBit The ordinal of the most significant bit in the bit field.\r
363 Range 0..7.\r
2fc59a00 364 @param Value The new value of the bit field.\r
b7c5912a 365\r
366 @return The value written back to the PCI configuration register.\r
367\r
368**/\r
369UINT8\r
370EFIAPI\r
371PciBitFieldWrite8 (\r
2f88bd3a
MK
372 IN UINTN Address,\r
373 IN UINTN StartBit,\r
374 IN UINTN EndBit,\r
375 IN UINT8 Value\r
b7c5912a 376 )\r
377{\r
378 return PciWrite8 (\r
379 Address,\r
380 BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)\r
381 );\r
382}\r
383\r
384/**\r
385 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
386 writes the result back to the bit field in the 8-bit port.\r
387\r
388 Reads the 8-bit PCI configuration register specified by Address, performs a\r
389 bitwise OR between the read result and the value specified by\r
390 OrData, and writes the result to the 8-bit PCI configuration register\r
391 specified by Address. The value written to the PCI configuration register is\r
392 returned. This function must guarantee that all PCI read and write operations\r
393 are serialized. Extra left bits in OrData are stripped.\r
394\r
395 If Address > 0x0FFFFFFF, then ASSERT().\r
396 If StartBit is greater than 7, then ASSERT().\r
397 If EndBit is greater than 7, then ASSERT().\r
398 If EndBit is less than StartBit, then ASSERT().\r
94952554 399 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 400\r
2fc59a00 401 @param Address The PCI configuration register to write.\r
b7c5912a 402 @param StartBit The ordinal of the least significant bit in the bit field.\r
403 Range 0..7.\r
404 @param EndBit The ordinal of the most significant bit in the bit field.\r
405 Range 0..7.\r
406 @param OrData The value to OR with the PCI configuration register.\r
407\r
408 @return The value written back to the PCI configuration register.\r
409\r
410**/\r
411UINT8\r
412EFIAPI\r
413PciBitFieldOr8 (\r
2f88bd3a
MK
414 IN UINTN Address,\r
415 IN UINTN StartBit,\r
416 IN UINTN EndBit,\r
417 IN UINT8 OrData\r
b7c5912a 418 )\r
419{\r
420 return PciWrite8 (\r
421 Address,\r
422 BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)\r
423 );\r
424}\r
425\r
426/**\r
427 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
428 AND, and writes the result back to the bit field in the 8-bit register.\r
429\r
430 Reads the 8-bit PCI configuration register specified by Address, performs a\r
431 bitwise AND between the read result and the value specified by AndData, and\r
432 writes the result to the 8-bit PCI configuration register specified by\r
433 Address. The value written to the PCI configuration register is returned.\r
434 This function must guarantee that all PCI read and write operations are\r
435 serialized. Extra left bits in AndData are stripped.\r
436\r
437 If Address > 0x0FFFFFFF, then ASSERT().\r
438 If StartBit is greater than 7, then ASSERT().\r
439 If EndBit is greater than 7, then ASSERT().\r
440 If EndBit is less than StartBit, then ASSERT().\r
94952554 441 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 442\r
2fc59a00 443 @param Address The PCI configuration register to write.\r
b7c5912a 444 @param StartBit The ordinal of the least significant bit in the bit field.\r
445 Range 0..7.\r
446 @param EndBit The ordinal of the most significant bit in the bit field.\r
447 Range 0..7.\r
448 @param AndData The value to AND with the PCI configuration register.\r
449\r
450 @return The value written back to the PCI configuration register.\r
451\r
452**/\r
453UINT8\r
454EFIAPI\r
455PciBitFieldAnd8 (\r
2f88bd3a
MK
456 IN UINTN Address,\r
457 IN UINTN StartBit,\r
458 IN UINTN EndBit,\r
459 IN UINT8 AndData\r
b7c5912a 460 )\r
461{\r
462 return PciWrite8 (\r
463 Address,\r
464 BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)\r
465 );\r
466}\r
467\r
468/**\r
469 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
470 bitwise OR, and writes the result back to the bit field in the\r
471 8-bit port.\r
472\r
473 Reads the 8-bit PCI configuration register specified by Address, performs a\r
474 bitwise AND followed by a bitwise OR between the read result and\r
475 the value specified by AndData, and writes the result to the 8-bit PCI\r
476 configuration register specified by Address. The value written to the PCI\r
477 configuration register is returned. This function must guarantee that all PCI\r
478 read and write operations are serialized. Extra left bits in both AndData and\r
479 OrData are stripped.\r
480\r
481 If Address > 0x0FFFFFFF, then ASSERT().\r
482 If StartBit is greater than 7, then ASSERT().\r
483 If EndBit is greater than 7, then ASSERT().\r
484 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
485 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
486 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 487\r
2fc59a00 488 @param Address The PCI configuration register to write.\r
b7c5912a 489 @param StartBit The ordinal of the least significant bit in the bit field.\r
490 Range 0..7.\r
491 @param EndBit The ordinal of the most significant bit in the bit field.\r
492 Range 0..7.\r
493 @param AndData The value to AND with the PCI configuration register.\r
494 @param OrData The value to OR with the result of the AND operation.\r
495\r
496 @return The value written back to the PCI configuration register.\r
497\r
498**/\r
499UINT8\r
500EFIAPI\r
501PciBitFieldAndThenOr8 (\r
2f88bd3a
MK
502 IN UINTN Address,\r
503 IN UINTN StartBit,\r
504 IN UINTN EndBit,\r
505 IN UINT8 AndData,\r
506 IN UINT8 OrData\r
b7c5912a 507 )\r
508{\r
509 return PciWrite8 (\r
510 Address,\r
511 BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)\r
512 );\r
513}\r
514\r
515/**\r
516 Reads a 16-bit PCI configuration register.\r
517\r
518 Reads and returns the 16-bit PCI configuration register specified by Address.\r
519 This function must guarantee that all PCI read and write operations are\r
520 serialized.\r
521\r
522 If Address > 0x0FFFFFFF, then ASSERT().\r
523 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
524\r
2fc59a00 525 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 526 Register.\r
527\r
528 @return The read value from the PCI configuration register.\r
529\r
530**/\r
531UINT16\r
532EFIAPI\r
533PciRead16 (\r
2f88bd3a 534 IN UINTN Address\r
b7c5912a 535 )\r
536{\r
537 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
538\r
2f88bd3a 539 return (UINT16)SmmPciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);\r
b7c5912a 540}\r
541\r
542/**\r
543 Writes a 16-bit PCI configuration register.\r
544\r
545 Writes the 16-bit PCI configuration register specified by Address with the\r
546 value specified by Value. Value is returned. This function must guarantee\r
547 that all PCI read and write operations are serialized.\r
548\r
549 If Address > 0x0FFFFFFF, then ASSERT().\r
550 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
551\r
2fc59a00 552 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 553 Register.\r
554 @param Value The value to write.\r
555\r
556 @return The value written to the PCI configuration register.\r
557\r
558**/\r
559UINT16\r
560EFIAPI\r
561PciWrite16 (\r
2f88bd3a
MK
562 IN UINTN Address,\r
563 IN UINT16 Value\r
b7c5912a 564 )\r
565{\r
566 ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
567\r
2f88bd3a 568 return (UINT16)SmmPciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);\r
b7c5912a 569}\r
570\r
571/**\r
572 Performs a bitwise OR of a 16-bit PCI configuration register with\r
573 a 16-bit value.\r
574\r
575 Reads the 16-bit PCI configuration register specified by Address, performs a\r
576 bitwise OR between the read result and the value specified by\r
577 OrData, and writes the result to the 16-bit PCI configuration register\r
578 specified by Address. The value written to the PCI configuration register is\r
579 returned. This function must guarantee that all PCI read and write operations\r
580 are serialized.\r
581\r
582 If Address > 0x0FFFFFFF, then ASSERT().\r
583 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
584\r
2fc59a00 585 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 586 Register.\r
587 @param OrData The value to OR with the PCI configuration register.\r
588\r
589 @return The value written back to the PCI configuration register.\r
590\r
591**/\r
592UINT16\r
593EFIAPI\r
594PciOr16 (\r
2f88bd3a
MK
595 IN UINTN Address,\r
596 IN UINT16 OrData\r
b7c5912a 597 )\r
598{\r
2f88bd3a 599 return PciWrite16 (Address, (UINT16)(PciRead16 (Address) | OrData));\r
b7c5912a 600}\r
601\r
602/**\r
603 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
604 value.\r
605\r
606 Reads the 16-bit PCI configuration register specified by Address, performs a\r
607 bitwise AND between the read result and the value specified by AndData, and\r
608 writes the result to the 16-bit PCI configuration register specified by\r
609 Address. The value written to the PCI configuration register is returned.\r
610 This function must guarantee that all PCI read and write operations are\r
611 serialized.\r
612\r
613 If Address > 0x0FFFFFFF, then ASSERT().\r
614 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
615\r
2fc59a00 616 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 617 Register.\r
618 @param AndData The value to AND with the PCI configuration register.\r
619\r
620 @return The value written back to the PCI configuration register.\r
621\r
622**/\r
623UINT16\r
624EFIAPI\r
625PciAnd16 (\r
2f88bd3a
MK
626 IN UINTN Address,\r
627 IN UINT16 AndData\r
b7c5912a 628 )\r
629{\r
2f88bd3a 630 return PciWrite16 (Address, (UINT16)(PciRead16 (Address) & AndData));\r
b7c5912a 631}\r
632\r
633/**\r
634 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
635 value, followed a bitwise OR with another 16-bit value.\r
636\r
637 Reads the 16-bit PCI configuration register specified by Address, performs a\r
638 bitwise AND between the read result and the value specified by AndData,\r
639 performs a bitwise OR between the result of the AND operation and\r
640 the value specified by OrData, and writes the result to the 16-bit PCI\r
641 configuration register specified by Address. The value written to the PCI\r
642 configuration register is returned. This function must guarantee that all PCI\r
643 read and write operations are serialized.\r
644\r
645 If Address > 0x0FFFFFFF, then ASSERT().\r
646 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
647\r
2fc59a00 648 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 649 Register.\r
650 @param AndData The value to AND with the PCI configuration register.\r
651 @param OrData The value to OR with the result of the AND operation.\r
652\r
653 @return The value written back to the PCI configuration register.\r
654\r
655**/\r
656UINT16\r
657EFIAPI\r
658PciAndThenOr16 (\r
2f88bd3a
MK
659 IN UINTN Address,\r
660 IN UINT16 AndData,\r
661 IN UINT16 OrData\r
b7c5912a 662 )\r
663{\r
2f88bd3a 664 return PciWrite16 (Address, (UINT16)((PciRead16 (Address) & AndData) | OrData));\r
b7c5912a 665}\r
666\r
667/**\r
668 Reads a bit field of a PCI configuration register.\r
669\r
670 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
671 specified by the StartBit and the EndBit. The value of the bit field is\r
672 returned.\r
673\r
674 If Address > 0x0FFFFFFF, then ASSERT().\r
675 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
676 If StartBit is greater than 15, then ASSERT().\r
677 If EndBit is greater than 15, then ASSERT().\r
678 If EndBit is less than StartBit, then ASSERT().\r
679\r
2fc59a00 680 @param Address The PCI configuration register to read.\r
b7c5912a 681 @param StartBit The ordinal of the least significant bit in the bit field.\r
682 Range 0..15.\r
683 @param EndBit The ordinal of the most significant bit in the bit field.\r
684 Range 0..15.\r
685\r
686 @return The value of the bit field read from the PCI configuration register.\r
687\r
688**/\r
689UINT16\r
690EFIAPI\r
691PciBitFieldRead16 (\r
2f88bd3a
MK
692 IN UINTN Address,\r
693 IN UINTN StartBit,\r
694 IN UINTN EndBit\r
b7c5912a 695 )\r
696{\r
697 return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);\r
698}\r
699\r
700/**\r
701 Writes a bit field to a PCI configuration register.\r
702\r
703 Writes Value to the bit field of the PCI configuration register. The bit\r
704 field is specified by the StartBit and the EndBit. All other bits in the\r
705 destination PCI configuration register are preserved. The new value of the\r
706 16-bit register is returned.\r
707\r
708 If Address > 0x0FFFFFFF, then ASSERT().\r
709 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
710 If StartBit is greater than 15, then ASSERT().\r
711 If EndBit is greater than 15, then ASSERT().\r
712 If EndBit is less than StartBit, then ASSERT().\r
94952554 713 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 714\r
2fc59a00 715 @param Address The PCI configuration register to write.\r
b7c5912a 716 @param StartBit The ordinal of the least significant bit in the bit field.\r
717 Range 0..15.\r
718 @param EndBit The ordinal of the most significant bit in the bit field.\r
719 Range 0..15.\r
2fc59a00 720 @param Value The new value of the bit field.\r
b7c5912a 721\r
722 @return The value written back to the PCI configuration register.\r
723\r
724**/\r
725UINT16\r
726EFIAPI\r
727PciBitFieldWrite16 (\r
2f88bd3a
MK
728 IN UINTN Address,\r
729 IN UINTN StartBit,\r
730 IN UINTN EndBit,\r
731 IN UINT16 Value\r
b7c5912a 732 )\r
733{\r
734 return PciWrite16 (\r
735 Address,\r
736 BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)\r
737 );\r
738}\r
739\r
740/**\r
741 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
742 writes the result back to the bit field in the 16-bit port.\r
743\r
744 Reads the 16-bit PCI configuration register specified by Address, performs a\r
745 bitwise OR between the read result and the value specified by\r
746 OrData, and writes the result to the 16-bit PCI configuration register\r
747 specified by Address. The value written to the PCI configuration register is\r
748 returned. This function must guarantee that all PCI read and write operations\r
749 are serialized. Extra left bits in OrData are stripped.\r
750\r
751 If Address > 0x0FFFFFFF, then ASSERT().\r
752 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
753 If StartBit is greater than 15, then ASSERT().\r
754 If EndBit is greater than 15, then ASSERT().\r
755 If EndBit is less than StartBit, then ASSERT().\r
94952554 756 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 757\r
2fc59a00 758 @param Address The PCI configuration register to write.\r
b7c5912a 759 @param StartBit The ordinal of the least significant bit in the bit field.\r
760 Range 0..15.\r
761 @param EndBit The ordinal of the most significant bit in the bit field.\r
762 Range 0..15.\r
763 @param OrData The value to OR with the PCI configuration register.\r
764\r
765 @return The value written back to the PCI configuration register.\r
766\r
767**/\r
768UINT16\r
769EFIAPI\r
770PciBitFieldOr16 (\r
2f88bd3a
MK
771 IN UINTN Address,\r
772 IN UINTN StartBit,\r
773 IN UINTN EndBit,\r
774 IN UINT16 OrData\r
b7c5912a 775 )\r
776{\r
777 return PciWrite16 (\r
778 Address,\r
779 BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)\r
780 );\r
781}\r
782\r
783/**\r
784 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
785 AND, and writes the result back to the bit field in the 16-bit register.\r
786\r
787 Reads the 16-bit PCI configuration register specified by Address, performs a\r
788 bitwise AND between the read result and the value specified by AndData, and\r
789 writes the result to the 16-bit PCI configuration register specified by\r
790 Address. The value written to the PCI configuration register is returned.\r
791 This function must guarantee that all PCI read and write operations are\r
792 serialized. Extra left bits in AndData are stripped.\r
793\r
794 If Address > 0x0FFFFFFF, then ASSERT().\r
795 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
796 If StartBit is greater than 15, then ASSERT().\r
797 If EndBit is greater than 15, then ASSERT().\r
798 If EndBit is less than StartBit, then ASSERT().\r
94952554 799 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 800\r
2fc59a00 801 @param Address The PCI configuration register to write.\r
b7c5912a 802 @param StartBit The ordinal of the least significant bit in the bit field.\r
803 Range 0..15.\r
804 @param EndBit The ordinal of the most significant bit in the bit field.\r
805 Range 0..15.\r
806 @param AndData The value to AND with the PCI configuration register.\r
807\r
808 @return The value written back to the PCI configuration register.\r
809\r
810**/\r
811UINT16\r
812EFIAPI\r
813PciBitFieldAnd16 (\r
2f88bd3a
MK
814 IN UINTN Address,\r
815 IN UINTN StartBit,\r
816 IN UINTN EndBit,\r
817 IN UINT16 AndData\r
b7c5912a 818 )\r
819{\r
820 return PciWrite16 (\r
821 Address,\r
822 BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)\r
823 );\r
824}\r
825\r
826/**\r
827 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
828 bitwise OR, and writes the result back to the bit field in the\r
829 16-bit port.\r
830\r
831 Reads the 16-bit PCI configuration register specified by Address, performs a\r
832 bitwise AND followed by a bitwise OR between the read result and\r
833 the value specified by AndData, and writes the result to the 16-bit PCI\r
834 configuration register specified by Address. The value written to the PCI\r
835 configuration register is returned. This function must guarantee that all PCI\r
836 read and write operations are serialized. Extra left bits in both AndData and\r
837 OrData are stripped.\r
838\r
839 If Address > 0x0FFFFFFF, then ASSERT().\r
840 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
841 If StartBit is greater than 15, then ASSERT().\r
842 If EndBit is greater than 15, then ASSERT().\r
843 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
844 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
845 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 846\r
2fc59a00 847 @param Address The PCI configuration register to write.\r
b7c5912a 848 @param StartBit The ordinal of the least significant bit in the bit field.\r
849 Range 0..15.\r
850 @param EndBit The ordinal of the most significant bit in the bit field.\r
851 Range 0..15.\r
852 @param AndData The value to AND with the PCI configuration register.\r
853 @param OrData The value to OR with the result of the AND operation.\r
854\r
855 @return The value written back to the PCI configuration register.\r
856\r
857**/\r
858UINT16\r
859EFIAPI\r
860PciBitFieldAndThenOr16 (\r
2f88bd3a
MK
861 IN UINTN Address,\r
862 IN UINTN StartBit,\r
863 IN UINTN EndBit,\r
864 IN UINT16 AndData,\r
865 IN UINT16 OrData\r
b7c5912a 866 )\r
867{\r
868 return PciWrite16 (\r
869 Address,\r
870 BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)\r
871 );\r
872}\r
873\r
874/**\r
875 Reads a 32-bit PCI configuration register.\r
876\r
877 Reads and returns the 32-bit PCI configuration register specified by Address.\r
878 This function must guarantee that all PCI read and write operations are\r
879 serialized.\r
880\r
881 If Address > 0x0FFFFFFF, then ASSERT().\r
882 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
883\r
2fc59a00 884 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 885 Register.\r
886\r
887 @return The read value from the PCI configuration register.\r
888\r
889**/\r
890UINT32\r
891EFIAPI\r
892PciRead32 (\r
2f88bd3a 893 IN UINTN Address\r
b7c5912a 894 )\r
895{\r
896 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
897\r
898 return SmmPciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);\r
899}\r
900\r
901/**\r
902 Writes a 32-bit PCI configuration register.\r
903\r
904 Writes the 32-bit PCI configuration register specified by Address with the\r
905 value specified by Value. Value is returned. This function must guarantee\r
906 that all PCI read and write operations are serialized.\r
907\r
908 If Address > 0x0FFFFFFF, then ASSERT().\r
909 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
910\r
2fc59a00 911 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 912 Register.\r
913 @param Value The value to write.\r
914\r
915 @return The value written to the PCI configuration register.\r
916\r
917**/\r
918UINT32\r
919EFIAPI\r
920PciWrite32 (\r
2f88bd3a
MK
921 IN UINTN Address,\r
922 IN UINT32 Value\r
b7c5912a 923 )\r
924{\r
925 ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
926\r
927 return SmmPciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);\r
928}\r
929\r
930/**\r
931 Performs a bitwise OR of a 32-bit PCI configuration register with\r
932 a 32-bit value.\r
933\r
934 Reads the 32-bit PCI configuration register specified by Address, performs a\r
935 bitwise OR between the read result and the value specified by\r
936 OrData, and writes the result to the 32-bit PCI configuration register\r
937 specified by Address. The value written to the PCI configuration register is\r
938 returned. This function must guarantee that all PCI read and write operations\r
939 are serialized.\r
940\r
941 If Address > 0x0FFFFFFF, then ASSERT().\r
942 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
943\r
2fc59a00 944 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 945 Register.\r
946 @param OrData The value to OR with the PCI configuration register.\r
947\r
948 @return The value written back to the PCI configuration register.\r
949\r
950**/\r
951UINT32\r
952EFIAPI\r
953PciOr32 (\r
2f88bd3a
MK
954 IN UINTN Address,\r
955 IN UINT32 OrData\r
b7c5912a 956 )\r
957{\r
958 return PciWrite32 (Address, PciRead32 (Address) | OrData);\r
959}\r
960\r
961/**\r
962 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
963 value.\r
964\r
965 Reads the 32-bit PCI configuration register specified by Address, performs a\r
966 bitwise AND between the read result and the value specified by AndData, and\r
967 writes the result to the 32-bit PCI configuration register specified by\r
968 Address. The value written to the PCI configuration register is returned.\r
969 This function must guarantee that all PCI read and write operations are\r
970 serialized.\r
971\r
972 If Address > 0x0FFFFFFF, then ASSERT().\r
973 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
974\r
2fc59a00 975 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 976 Register.\r
977 @param AndData The value to AND with the PCI configuration register.\r
978\r
979 @return The value written back to the PCI configuration register.\r
980\r
981**/\r
982UINT32\r
983EFIAPI\r
984PciAnd32 (\r
2f88bd3a
MK
985 IN UINTN Address,\r
986 IN UINT32 AndData\r
b7c5912a 987 )\r
988{\r
989 return PciWrite32 (Address, PciRead32 (Address) & AndData);\r
990}\r
991\r
992/**\r
993 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
994 value, followed a bitwise OR with another 32-bit value.\r
995\r
996 Reads the 32-bit PCI configuration register specified by Address, performs a\r
997 bitwise AND between the read result and the value specified by AndData,\r
998 performs a bitwise OR between the result of the AND operation and\r
999 the value specified by OrData, and writes the result to the 32-bit PCI\r
1000 configuration register specified by Address. The value written to the PCI\r
1001 configuration register is returned. This function must guarantee that all PCI\r
1002 read and write operations are serialized.\r
1003\r
1004 If Address > 0x0FFFFFFF, then ASSERT().\r
1005 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1006\r
2fc59a00 1007 @param Address The address that encodes the PCI Bus, Device, Function and\r
b7c5912a 1008 Register.\r
1009 @param AndData The value to AND with the PCI configuration register.\r
1010 @param OrData The value to OR with the result of the AND operation.\r
1011\r
1012 @return The value written back to the PCI configuration register.\r
1013\r
1014**/\r
1015UINT32\r
1016EFIAPI\r
1017PciAndThenOr32 (\r
2f88bd3a
MK
1018 IN UINTN Address,\r
1019 IN UINT32 AndData,\r
1020 IN UINT32 OrData\r
b7c5912a 1021 )\r
1022{\r
1023 return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);\r
1024}\r
1025\r
1026/**\r
1027 Reads a bit field of a PCI configuration register.\r
1028\r
1029 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1030 specified by the StartBit and the EndBit. The value of the bit field is\r
1031 returned.\r
1032\r
1033 If Address > 0x0FFFFFFF, then ASSERT().\r
1034 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1035 If StartBit is greater than 31, then ASSERT().\r
1036 If EndBit is greater than 31, then ASSERT().\r
1037 If EndBit is less than StartBit, then ASSERT().\r
1038\r
2fc59a00 1039 @param Address The PCI configuration register to read.\r
b7c5912a 1040 @param StartBit The ordinal of the least significant bit in the bit field.\r
1041 Range 0..31.\r
1042 @param EndBit The ordinal of the most significant bit in the bit field.\r
1043 Range 0..31.\r
1044\r
1045 @return The value of the bit field read from the PCI configuration register.\r
1046\r
1047**/\r
1048UINT32\r
1049EFIAPI\r
1050PciBitFieldRead32 (\r
2f88bd3a
MK
1051 IN UINTN Address,\r
1052 IN UINTN StartBit,\r
1053 IN UINTN EndBit\r
b7c5912a 1054 )\r
1055{\r
1056 return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);\r
1057}\r
1058\r
1059/**\r
1060 Writes a bit field to a PCI configuration register.\r
1061\r
1062 Writes Value to the bit field of the PCI configuration register. The bit\r
1063 field is specified by the StartBit and the EndBit. All other bits in the\r
1064 destination PCI configuration register are preserved. The new value of the\r
1065 32-bit register is returned.\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 If StartBit is greater than 31, then ASSERT().\r
1070 If EndBit is greater than 31, then ASSERT().\r
1071 If EndBit is less than StartBit, then ASSERT().\r
94952554 1072 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 1073\r
2fc59a00 1074 @param Address The PCI configuration register to write.\r
b7c5912a 1075 @param StartBit The ordinal of the least significant bit in the bit field.\r
1076 Range 0..31.\r
1077 @param EndBit The ordinal of the most significant bit in the bit field.\r
1078 Range 0..31.\r
2fc59a00 1079 @param Value The new value of the bit field.\r
b7c5912a 1080\r
1081 @return The value written back to the PCI configuration register.\r
1082\r
1083**/\r
1084UINT32\r
1085EFIAPI\r
1086PciBitFieldWrite32 (\r
2f88bd3a
MK
1087 IN UINTN Address,\r
1088 IN UINTN StartBit,\r
1089 IN UINTN EndBit,\r
1090 IN UINT32 Value\r
b7c5912a 1091 )\r
1092{\r
1093 return PciWrite32 (\r
1094 Address,\r
1095 BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)\r
1096 );\r
1097}\r
1098\r
1099/**\r
1100 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1101 writes the result back to the bit field in the 32-bit port.\r
1102\r
1103 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1104 bitwise OR between the read result and the value specified by\r
1105 OrData, and writes the result to the 32-bit PCI configuration register\r
1106 specified by Address. The value written to the PCI configuration register is\r
1107 returned. This function must guarantee that all PCI read and write operations\r
1108 are serialized. Extra left bits in OrData are stripped.\r
1109\r
1110 If Address > 0x0FFFFFFF, then ASSERT().\r
1111 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1112 If StartBit is greater than 31, then ASSERT().\r
1113 If EndBit is greater than 31, then ASSERT().\r
1114 If EndBit is less than StartBit, then ASSERT().\r
94952554 1115 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 1116\r
2fc59a00 1117 @param Address The PCI configuration register to write.\r
b7c5912a 1118 @param StartBit The ordinal of the least significant bit in the bit field.\r
1119 Range 0..31.\r
1120 @param EndBit The ordinal of the most significant bit in the bit field.\r
1121 Range 0..31.\r
1122 @param OrData The value to OR with the PCI configuration register.\r
1123\r
1124 @return The value written back to the PCI configuration register.\r
1125\r
1126**/\r
1127UINT32\r
1128EFIAPI\r
1129PciBitFieldOr32 (\r
2f88bd3a
MK
1130 IN UINTN Address,\r
1131 IN UINTN StartBit,\r
1132 IN UINTN EndBit,\r
1133 IN UINT32 OrData\r
b7c5912a 1134 )\r
1135{\r
1136 return PciWrite32 (\r
1137 Address,\r
1138 BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)\r
1139 );\r
1140}\r
1141\r
1142/**\r
1143 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1144 AND, and writes the result back to the bit field in the 32-bit register.\r
1145\r
1146 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1147 bitwise AND between the read result and the value specified by AndData, and\r
1148 writes the result to the 32-bit PCI configuration register specified by\r
1149 Address. The value written to the PCI configuration register is returned.\r
1150 This function must guarantee that all PCI read and write operations are\r
1151 serialized. Extra left bits in AndData are stripped.\r
1152\r
1153 If Address > 0x0FFFFFFF, then ASSERT().\r
1154 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1155 If StartBit is greater than 31, then ASSERT().\r
1156 If EndBit is greater than 31, then ASSERT().\r
1157 If EndBit is less than StartBit, then ASSERT().\r
94952554 1158 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 1159\r
2fc59a00 1160 @param Address The PCI configuration register to write.\r
b7c5912a 1161 @param StartBit The ordinal of the least significant bit in the bit field.\r
1162 Range 0..31.\r
1163 @param EndBit The ordinal of the most significant bit in the bit field.\r
1164 Range 0..31.\r
1165 @param AndData The value to AND with the PCI configuration register.\r
1166\r
1167 @return The value written back to the PCI configuration register.\r
1168\r
1169**/\r
1170UINT32\r
1171EFIAPI\r
1172PciBitFieldAnd32 (\r
2f88bd3a
MK
1173 IN UINTN Address,\r
1174 IN UINTN StartBit,\r
1175 IN UINTN EndBit,\r
1176 IN UINT32 AndData\r
b7c5912a 1177 )\r
1178{\r
1179 return PciWrite32 (\r
1180 Address,\r
1181 BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)\r
1182 );\r
1183}\r
1184\r
1185/**\r
1186 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
1187 bitwise OR, and writes the result back to the bit field in the\r
1188 32-bit port.\r
1189\r
1190 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1191 bitwise AND followed by a bitwise OR between the read result and\r
1192 the value specified by AndData, and writes the result to the 32-bit PCI\r
1193 configuration register specified by Address. The value written to the PCI\r
1194 configuration register is returned. This function must guarantee that all PCI\r
1195 read and write operations are serialized. Extra left bits in both AndData and\r
1196 OrData are stripped.\r
1197\r
1198 If Address > 0x0FFFFFFF, then ASSERT().\r
1199 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1200 If StartBit is greater than 31, then ASSERT().\r
1201 If EndBit is greater than 31, then ASSERT().\r
1202 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
1203 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1204 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
b7c5912a 1205\r
2fc59a00 1206 @param Address The PCI configuration register to write.\r
b7c5912a 1207 @param StartBit The ordinal of the least significant bit in the bit field.\r
1208 Range 0..31.\r
1209 @param EndBit The ordinal of the most significant bit in the bit field.\r
1210 Range 0..31.\r
1211 @param AndData The value to AND with the PCI configuration register.\r
1212 @param OrData The value to OR with the result of the AND operation.\r
1213\r
1214 @return The value written back to the PCI configuration register.\r
1215\r
1216**/\r
1217UINT32\r
1218EFIAPI\r
1219PciBitFieldAndThenOr32 (\r
2f88bd3a
MK
1220 IN UINTN Address,\r
1221 IN UINTN StartBit,\r
1222 IN UINTN EndBit,\r
1223 IN UINT32 AndData,\r
1224 IN UINT32 OrData\r
b7c5912a 1225 )\r
1226{\r
1227 return PciWrite32 (\r
1228 Address,\r
1229 BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)\r
1230 );\r
1231}\r
1232\r
1233/**\r
1234 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1235\r
1236 Reads the range of PCI configuration registers specified by StartAddress and\r
1237 Size into the buffer specified by Buffer. This function only allows the PCI\r
1238 configuration registers from a single PCI function to be read. Size is\r
1239 returned. When possible 32-bit PCI configuration read cycles are used to read\r
fae43d06 1240 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
b7c5912a 1241 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1242 end of the range.\r
1243\r
1244 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1245 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1246 If Size > 0 and Buffer is NULL, then ASSERT().\r
1247\r
2fc59a00 1248 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
b7c5912a 1249 Function and Register.\r
2fc59a00 1250 @param Size The size in bytes of the transfer.\r
1251 @param Buffer The pointer to a buffer receiving the data read.\r
b7c5912a 1252\r
1253 @return Size\r
1254\r
1255**/\r
1256UINTN\r
1257EFIAPI\r
1258PciReadBuffer (\r
2f88bd3a
MK
1259 IN UINTN StartAddress,\r
1260 IN UINTN Size,\r
1261 OUT VOID *Buffer\r
b7c5912a 1262 )\r
1263{\r
2f88bd3a 1264 UINTN ReturnValue;\r
b7c5912a 1265\r
1266 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
1267 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1268\r
1269 if (Size == 0) {\r
1270 return Size;\r
1271 }\r
1272\r
1273 ASSERT (Buffer != NULL);\r
1274\r
1275 //\r
1276 // Save Size for return\r
1277 //\r
1278 ReturnValue = Size;\r
1279\r
1280 if ((StartAddress & BIT0) != 0) {\r
1281 //\r
1282 // Read a byte if StartAddress is byte aligned\r
1283 //\r
1284 *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);\r
2f88bd3a
MK
1285 StartAddress += sizeof (UINT8);\r
1286 Size -= sizeof (UINT8);\r
1287 Buffer = (UINT8 *)Buffer + 1;\r
b7c5912a 1288 }\r
1289\r
2f88bd3a 1290 if ((Size >= sizeof (UINT16)) && ((StartAddress & BIT1) != 0)) {\r
b7c5912a 1291 //\r
1292 // Read a word if StartAddress is word aligned\r
1293 //\r
1294 WriteUnaligned16 (Buffer, PciRead16 (StartAddress));\r
1295 StartAddress += sizeof (UINT16);\r
2f88bd3a
MK
1296 Size -= sizeof (UINT16);\r
1297 Buffer = (UINT16 *)Buffer + 1;\r
b7c5912a 1298 }\r
1299\r
1300 while (Size >= sizeof (UINT32)) {\r
1301 //\r
1302 // Read as many double words as possible\r
1303 //\r
1304 WriteUnaligned32 (Buffer, PciRead32 (StartAddress));\r
1305 StartAddress += sizeof (UINT32);\r
2f88bd3a
MK
1306 Size -= sizeof (UINT32);\r
1307 Buffer = (UINT32 *)Buffer + 1;\r
b7c5912a 1308 }\r
1309\r
1310 if (Size >= sizeof (UINT16)) {\r
1311 //\r
1312 // Read the last remaining word if exist\r
1313 //\r
1314 WriteUnaligned16 (Buffer, PciRead16 (StartAddress));\r
1315 StartAddress += sizeof (UINT16);\r
2f88bd3a
MK
1316 Size -= sizeof (UINT16);\r
1317 Buffer = (UINT16 *)Buffer + 1;\r
b7c5912a 1318 }\r
1319\r
1320 if (Size >= sizeof (UINT8)) {\r
1321 //\r
1322 // Read the last remaining byte if exist\r
1323 //\r
1324 *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);\r
1325 }\r
1326\r
1327 return ReturnValue;\r
1328}\r
1329\r
1330/**\r
1331 Copies the data in a caller supplied buffer to a specified range of PCI\r
1332 configuration space.\r
1333\r
1334 Writes the range of PCI configuration registers specified by StartAddress and\r
1335 Size from the buffer specified by Buffer. This function only allows the PCI\r
1336 configuration registers from a single PCI function to be written. Size is\r
1337 returned. When possible 32-bit PCI configuration write cycles are used to\r
fae43d06 1338 write from StartAddress to StartAddress + Size. Due to alignment restrictions,\r
b7c5912a 1339 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1340 and the end of the range.\r
1341\r
1342 If StartAddress > 0x0FFFFFFF, then ASSERT().\r
1343 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1344 If Size > 0 and Buffer is NULL, then ASSERT().\r
1345\r
2fc59a00 1346 @param StartAddress The starting address that encodes the PCI Bus, Device,\r
b7c5912a 1347 Function and Register.\r
2fc59a00 1348 @param Size The size in bytes of the transfer.\r
1349 @param Buffer The pointer to a buffer containing the data to write.\r
b7c5912a 1350\r
1351 @return Size written to StartAddress.\r
1352\r
1353**/\r
1354UINTN\r
1355EFIAPI\r
1356PciWriteBuffer (\r
2f88bd3a
MK
1357 IN UINTN StartAddress,\r
1358 IN UINTN Size,\r
1359 IN VOID *Buffer\r
b7c5912a 1360 )\r
1361{\r
2f88bd3a 1362 UINTN ReturnValue;\r
b7c5912a 1363\r
1364 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
1365 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1366\r
1367 if (Size == 0) {\r
1368 return 0;\r
1369 }\r
1370\r
1371 ASSERT (Buffer != NULL);\r
1372\r
1373 //\r
1374 // Save Size for return\r
1375 //\r
1376 ReturnValue = Size;\r
1377\r
1378 if ((StartAddress & BIT0) != 0) {\r
1379 //\r
1380 // Write a byte if StartAddress is byte aligned\r
1381 //\r
2f88bd3a 1382 PciWrite8 (StartAddress, *(UINT8 *)Buffer);\r
b7c5912a 1383 StartAddress += sizeof (UINT8);\r
2f88bd3a
MK
1384 Size -= sizeof (UINT8);\r
1385 Buffer = (UINT8 *)Buffer + 1;\r
b7c5912a 1386 }\r
1387\r
2f88bd3a 1388 if ((Size >= sizeof (UINT16)) && ((StartAddress & BIT1) != 0)) {\r
b7c5912a 1389 //\r
1390 // Write a word if StartAddress is word aligned\r
1391 //\r
1392 PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1393 StartAddress += sizeof (UINT16);\r
2f88bd3a
MK
1394 Size -= sizeof (UINT16);\r
1395 Buffer = (UINT16 *)Buffer + 1;\r
b7c5912a 1396 }\r
1397\r
1398 while (Size >= sizeof (UINT32)) {\r
1399 //\r
1400 // Write as many double words as possible\r
1401 //\r
1402 PciWrite32 (StartAddress, ReadUnaligned32 (Buffer));\r
1403 StartAddress += sizeof (UINT32);\r
2f88bd3a
MK
1404 Size -= sizeof (UINT32);\r
1405 Buffer = (UINT32 *)Buffer + 1;\r
b7c5912a 1406 }\r
1407\r
1408 if (Size >= sizeof (UINT16)) {\r
1409 //\r
1410 // Write the last remaining word if exist\r
1411 //\r
1412 PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1413 StartAddress += sizeof (UINT16);\r
2f88bd3a
MK
1414 Size -= sizeof (UINT16);\r
1415 Buffer = (UINT16 *)Buffer + 1;\r
b7c5912a 1416 }\r
1417\r
1418 if (Size >= sizeof (UINT8)) {\r
1419 //\r
1420 // Write the last remaining byte if exist\r
1421 //\r
2f88bd3a 1422 PciWrite8 (StartAddress, *(UINT8 *)Buffer);\r
b7c5912a 1423 }\r
1424\r
1425 return ReturnValue;\r
1426}\r