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