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