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