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