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