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