2 Functions in this library instance make use of MMIO functions in IoLib to
3 access memory mapped PCI configuration space.
5 All assertions for I/O operations are handled in MMIO functions in the IoLib
8 Copyright (c) 2006 - 2008, Intel Corporation<BR>
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include <Library/BaseLib.h>
23 #include <Library/PciExpressLib.h>
24 #include <Library/IoLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/DxeServicesTableLib.h>
30 #include <Library/UefiRuntimeLib.h>
33 /// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime
36 UINTN PhysicalAddress
;
38 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
;
41 /// Set Virtual Address Map Event
43 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent
= NULL
;
46 /// Module global that contains the base physical address of the PCI Express MMIO range
48 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress
= 0;
51 /// The number of PCI devices that have been registered for runtime access
53 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges
= 0;
56 /// The table of PCI devices that have been registered for runtime access
58 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
*mDxeRuntimePciExpressLibRegistrationTable
= NULL
;
61 /// The table index of the most recent virtual address lookup
63 UINTN mDxeRuntimePciExpressLibLastRuntimeRange
= 0;
67 Convert the physical PCI Express MMIO addresses for all registered PCI devices
70 @param[in] Event The Event that is being processed
71 @param[in] Context Event Context
75 DxeRuntimePciExpressLibVirtualNotify (
83 // If there have been no runtime registrations, then just return
85 if (mDxeRuntimePciExpressLibRegistrationTable
== NULL
) {
90 // Convert physical addresses associated with the set of registered PCI devices to
93 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
94 EfiConvertPointer (0, (VOID
**) &(mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
));
98 // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.
100 EfiConvertPointer (0, (VOID
**) &mDxeRuntimePciExpressLibRegistrationTable
);
104 The constructor function caches the PCI Express Base Address and creates a
105 Set Virtual Address Map event to convert physical address to virtual addresses.
107 @param ImageHandle The firmware allocated handle for the EFI image.
108 @param SystemTable A pointer to the EFI System Table.
110 @retval EFI_SUCCESS The constructor completed successfully.
111 @retval Other value The constructor did not complete successfully.
116 DxeRuntimePciExpressLibConstructor (
117 IN EFI_HANDLE ImageHandle
,
118 IN EFI_SYSTEM_TABLE
*SystemTable
124 // Cache the physical address of the PCI Express MMIO range into a module global variable
126 mDxeRuntimePciExpressLibPciExpressBaseAddress
= (UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
129 // Register SetVirtualAddressMap () notify function
131 Status
= gBS
->CreateEvent (
132 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
134 DxeRuntimePciExpressLibVirtualNotify
,
136 &mDxeRuntimePciExpressLibVirtualNotifyEvent
138 ASSERT_EFI_ERROR (Status
);
144 The destructor function frees any allocated buffers and closes the Set Virtual
147 @param ImageHandle The firmware allocated handle for the EFI image.
148 @param SystemTable A pointer to the EFI System Table.
150 @retval EFI_SUCCESS The destructor completed successfully.
151 @retval Other value The destructor did not complete successfully.
156 DxeRuntimePciExpressLibDestructor (
157 IN EFI_HANDLE ImageHandle
,
158 IN EFI_SYSTEM_TABLE
*SystemTable
164 // If one or more PCI devices have been registered for runtime access, then
165 // free the registration table.
167 if (mDxeRuntimePciExpressLibRegistrationTable
!= NULL
) {
168 FreePool (mDxeRuntimePciExpressLibRegistrationTable
);
172 // Close the Set Virtual Address Map event
174 Status
= gBS
->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent
);
175 ASSERT_EFI_ERROR (Status
);
181 Gets the base address of PCI Express.
183 This internal functions retrieves PCI Express Base Address via a PCD entry
184 PcdPciExpressBaseAddress.
186 @param Address Address that encodes the PCI Bus, Device, Function and Register.
187 @return The base address of PCI Express.
191 GetPciExpressAddress (
198 // Make sure Address is valid
200 ASSERT (((Address
) & ~0xfffffff) == 0);
203 // Convert Address to a physical address in the MMIO PCI Express range
205 Address
+= mDxeRuntimePciExpressLibPciExpressBaseAddress
;
208 // If SetVirtualAddressMap() has not been called, then just return the physical address
210 if (!EfiGoneVirtual ()) {
215 // See if there is a physical address match at the exact same index as the last address match
217 if (mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].PhysicalAddress
== (Address
& 0x0ffff000)) {
219 // Convert the physical address to a virtual address and return the virtual address
221 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].VirtualAddress
;
225 // Search the entire table for a phyical address match
227 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
228 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== (Address
& 0x0ffff000)) {
230 // Cache the matching index value
232 mDxeRuntimePciExpressLibLastRuntimeRange
= Index
;
234 // Convert the physical address to a virtual address and return the virtual address
236 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
;
241 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
247 // Return the physical address
253 Registers a PCI device so PCI configuration registers may be accessed after
254 SetVirtualAddressMap().
256 Registers the PCI device specified by Address so all the PCI configuration
257 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
260 If Address > 0x0FFFFFFF, then ASSERT().
262 @param Address Address that encodes the PCI Bus, Device, Function and
265 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
266 @retval RETURN_UNSUPPORTED An attempt was made to call this function
267 after ExitBootServices().
268 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
269 at runtime could not be mapped.
270 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
271 complete the registration.
276 PciExpressRegisterForRuntimeAccess (
281 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
286 // Return an error if this function is called after ExitBootServices().
288 if (EfiAtRuntime ()) {
289 return RETURN_UNSUPPORTED
;
293 // Make sure Address is valid
295 ASSERT (((Address
) & ~0xfffffff) == 0);
298 // Convert Address to a physical address in the MMIO PCI Express range
299 // at the beginning of the PCI Configuration header for the specified
302 Address
= GetPciExpressAddress (Address
& 0x0ffff000);
305 // See if Address has already been registerd for runtime access
307 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
308 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== Address
) {
309 return RETURN_SUCCESS
;
314 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
316 Status
= gDS
->GetMemorySpaceDescriptor (Address
, &Descriptor
);
317 if (EFI_ERROR (Status
)) {
318 return RETURN_UNSUPPORTED
;
322 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
323 // will allocate a virtual address range for the 4KB PCI Configuration Header.
325 Status
= gDS
->SetMemorySpaceAttributes (Address
, 0x1000, Descriptor
.Attributes
| EFI_MEMORY_RUNTIME
);
326 if (EFI_ERROR (Status
)) {
327 return RETURN_UNSUPPORTED
;
331 // Grow the size of the registration table
333 NewTable
= ReallocateRuntimePool (
334 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
335 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
336 mDxeRuntimePciExpressLibRegistrationTable
338 if (NewTable
== NULL
) {
339 return RETURN_OUT_OF_RESOURCES
;
341 mDxeRuntimePciExpressLibRegistrationTable
= NewTable
;
342 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].PhysicalAddress
= Address
;
343 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].VirtualAddress
= Address
;
344 mDxeRuntimePciExpressLibNumberOfRuntimeRanges
++;
346 return RETURN_SUCCESS
;
351 Reads an 8-bit PCI configuration register.
353 Reads and returns the 8-bit PCI configuration register specified by Address.
354 This function must guarantee that all PCI read and write operations are
357 If Address > 0x0FFFFFFF, then ASSERT().
359 @param Address Address that encodes the PCI Bus, Device, Function and
362 @return The read value from the PCI configuration register.
371 return MmioRead8 (GetPciExpressAddress (Address
));
375 Writes an 8-bit PCI configuration register.
377 Writes the 8-bit PCI configuration register specified by Address with the
378 value specified by Value. Value is returned. This function must guarantee
379 that all PCI read and write operations are serialized.
381 If Address > 0x0FFFFFFF, then ASSERT().
383 @param Address Address that encodes the PCI Bus, Device, Function and
385 @param Value The value to write.
387 @return The value written to the PCI configuration register.
397 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
401 Performs a bitwise OR of an 8-bit PCI configuration register with
404 Reads the 8-bit PCI configuration register specified by Address, performs a
405 bitwise OR between the read result and the value specified by
406 OrData, and writes the result to the 8-bit PCI configuration register
407 specified by Address. The value written to the PCI configuration register is
408 returned. This function must guarantee that all PCI read and write operations
411 If Address > 0x0FFFFFFF, then ASSERT().
413 @param Address Address that encodes the PCI Bus, Device, Function and
415 @param OrData The value to OR with the PCI configuration register.
417 @return The value written back to the PCI configuration register.
427 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
431 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
434 Reads the 8-bit PCI configuration register specified by Address, performs a
435 bitwise AND between the read result and the value specified by AndData, and
436 writes the result to the 8-bit PCI configuration register specified by
437 Address. The value written to the PCI configuration register is returned.
438 This function must guarantee that all PCI read and write operations are
441 If Address > 0x0FFFFFFF, then ASSERT().
443 @param Address Address that encodes the PCI Bus, Device, Function and
445 @param AndData The value to AND with the PCI configuration register.
447 @return The value written back to the PCI configuration register.
457 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
461 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
462 value, followed a bitwise OR with another 8-bit value.
464 Reads the 8-bit PCI configuration register specified by Address, performs a
465 bitwise AND between the read result and the value specified by AndData,
466 performs a bitwise OR between the result of the AND operation and
467 the value specified by OrData, and writes the result to the 8-bit PCI
468 configuration register specified by Address. The value written to the PCI
469 configuration register is returned. This function must guarantee that all PCI
470 read and write operations are serialized.
472 If Address > 0x0FFFFFFF, then ASSERT().
474 @param Address Address that encodes the PCI Bus, Device, Function and
476 @param AndData The value to AND with the PCI configuration register.
477 @param OrData The value to OR with the result of the AND operation.
479 @return The value written back to the PCI configuration register.
484 PciExpressAndThenOr8 (
490 return MmioAndThenOr8 (
491 GetPciExpressAddress (Address
),
498 Reads a bit field of a PCI configuration register.
500 Reads the bit field in an 8-bit PCI configuration register. The bit field is
501 specified by the StartBit and the EndBit. The value of the bit field is
504 If Address > 0x0FFFFFFF, then ASSERT().
505 If StartBit is greater than 7, then ASSERT().
506 If EndBit is greater than 7, then ASSERT().
507 If EndBit is less than StartBit, then ASSERT().
509 @param Address PCI configuration register to read.
510 @param StartBit The ordinal of the least significant bit in the bit field.
512 @param EndBit The ordinal of the most significant bit in the bit field.
515 @return The value of the bit field read from the PCI configuration register.
520 PciExpressBitFieldRead8 (
526 return MmioBitFieldRead8 (
527 GetPciExpressAddress (Address
),
534 Writes a bit field to a PCI configuration register.
536 Writes Value to the bit field of the PCI configuration register. The bit
537 field is specified by the StartBit and the EndBit. All other bits in the
538 destination PCI configuration register are preserved. The new value of the
539 8-bit register is returned.
541 If Address > 0x0FFFFFFF, then ASSERT().
542 If StartBit is greater than 7, then ASSERT().
543 If EndBit is greater than 7, then ASSERT().
544 If EndBit is less than StartBit, then ASSERT().
546 @param Address PCI configuration register to write.
547 @param StartBit The ordinal of the least significant bit in the bit field.
549 @param EndBit The ordinal of the most significant bit in the bit field.
551 @param Value New value of the bit field.
553 @return The value written back to the PCI configuration register.
558 PciExpressBitFieldWrite8 (
565 return MmioBitFieldWrite8 (
566 GetPciExpressAddress (Address
),
574 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
575 writes the result back to the bit field in the 8-bit port.
577 Reads the 8-bit PCI configuration register specified by Address, performs a
578 bitwise OR between the read result and the value specified by
579 OrData, and writes the result to the 8-bit PCI configuration register
580 specified by Address. The value written to the PCI configuration register is
581 returned. This function must guarantee that all PCI read and write operations
582 are serialized. Extra left bits in OrData are stripped.
584 If Address > 0x0FFFFFFF, then ASSERT().
585 If StartBit is greater than 7, then ASSERT().
586 If EndBit is greater than 7, then ASSERT().
587 If EndBit is less than StartBit, then ASSERT().
589 @param Address PCI configuration register to write.
590 @param StartBit The ordinal of the least significant bit in the bit field.
592 @param EndBit The ordinal of the most significant bit in the bit field.
594 @param OrData The value to OR with the PCI configuration register.
596 @return The value written back to the PCI configuration register.
601 PciExpressBitFieldOr8 (
608 return MmioBitFieldOr8 (
609 GetPciExpressAddress (Address
),
617 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
618 AND, and writes the result back to the bit field in the 8-bit register.
620 Reads the 8-bit PCI configuration register specified by Address, performs a
621 bitwise AND between the read result and the value specified by AndData, and
622 writes the result to the 8-bit PCI configuration register specified by
623 Address. The value written to the PCI configuration register is returned.
624 This function must guarantee that all PCI read and write operations are
625 serialized. Extra left bits in AndData are stripped.
627 If Address > 0x0FFFFFFF, then ASSERT().
628 If StartBit is greater than 7, then ASSERT().
629 If EndBit is greater than 7, then ASSERT().
630 If EndBit is less than StartBit, then ASSERT().
632 @param Address PCI configuration register to write.
633 @param StartBit The ordinal of the least significant bit in the bit field.
635 @param EndBit The ordinal of the most significant bit in the bit field.
637 @param AndData The value to AND with the PCI configuration register.
639 @return The value written back to the PCI configuration register.
644 PciExpressBitFieldAnd8 (
651 return MmioBitFieldAnd8 (
652 GetPciExpressAddress (Address
),
660 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
661 bitwise OR, and writes the result back to the bit field in the
664 Reads the 8-bit PCI configuration register specified by Address, performs a
665 bitwise AND followed by a bitwise OR between the read result and
666 the value specified by AndData, and writes the result to the 8-bit PCI
667 configuration register specified by Address. The value written to the PCI
668 configuration register is returned. This function must guarantee that all PCI
669 read and write operations are serialized. Extra left bits in both AndData and
672 If Address > 0x0FFFFFFF, then ASSERT().
673 If StartBit is greater than 7, then ASSERT().
674 If EndBit is greater than 7, then ASSERT().
675 If EndBit is less than StartBit, then ASSERT().
677 @param Address PCI configuration register to write.
678 @param StartBit The ordinal of the least significant bit in the bit field.
680 @param EndBit The ordinal of the most significant bit in the bit field.
682 @param AndData The value to AND with the PCI configuration register.
683 @param OrData The value to OR with the result of the AND operation.
685 @return The value written back to the PCI configuration register.
690 PciExpressBitFieldAndThenOr8 (
698 return MmioBitFieldAndThenOr8 (
699 GetPciExpressAddress (Address
),
708 Reads a 16-bit PCI configuration register.
710 Reads and returns the 16-bit PCI configuration register specified by Address.
711 This function must guarantee that all PCI read and write operations are
714 If Address > 0x0FFFFFFF, then ASSERT().
715 If Address is not aligned on a 16-bit boundary, then ASSERT().
717 @param Address Address that encodes the PCI Bus, Device, Function and
720 @return The read value from the PCI configuration register.
729 return MmioRead16 (GetPciExpressAddress (Address
));
733 Writes a 16-bit PCI configuration register.
735 Writes the 16-bit PCI configuration register specified by Address with the
736 value specified by Value. Value is returned. This function must guarantee
737 that all PCI read and write operations are serialized.
739 If Address > 0x0FFFFFFF, then ASSERT().
740 If Address is not aligned on a 16-bit boundary, then ASSERT().
742 @param Address Address that encodes the PCI Bus, Device, Function and
744 @param Value The value to write.
746 @return The value written to the PCI configuration register.
756 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
760 Performs a bitwise OR of a 16-bit PCI configuration register with
763 Reads the 16-bit PCI configuration register specified by Address, performs a
764 bitwise OR between the read result and the value specified by
765 OrData, and writes the result to the 16-bit PCI configuration register
766 specified by Address. The value written to the PCI configuration register is
767 returned. This function must guarantee that all PCI read and write operations
770 If Address > 0x0FFFFFFF, then ASSERT().
771 If Address is not aligned on a 16-bit boundary, then ASSERT().
773 @param Address Address that encodes the PCI Bus, Device, Function and
775 @param OrData The value to OR with the PCI configuration register.
777 @return The value written back to the PCI configuration register.
787 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
791 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
794 Reads the 16-bit PCI configuration register specified by Address, performs a
795 bitwise AND between the read result and the value specified by AndData, and
796 writes the result to the 16-bit PCI configuration register specified by
797 Address. The value written to the PCI configuration register is returned.
798 This function must guarantee that all PCI read and write operations are
801 If Address > 0x0FFFFFFF, then ASSERT().
802 If Address is not aligned on a 16-bit boundary, then ASSERT().
804 @param Address Address that encodes the PCI Bus, Device, Function and
806 @param AndData The value to AND with the PCI configuration register.
808 @return The value written back to the PCI configuration register.
818 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
822 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
823 value, followed a bitwise OR with another 16-bit value.
825 Reads the 16-bit PCI configuration register specified by Address, performs a
826 bitwise AND between the read result and the value specified by AndData,
827 performs a bitwise OR between the result of the AND operation and
828 the value specified by OrData, and writes the result to the 16-bit PCI
829 configuration register specified by Address. The value written to the PCI
830 configuration register is returned. This function must guarantee that all PCI
831 read and write operations are serialized.
833 If Address > 0x0FFFFFFF, then ASSERT().
834 If Address is not aligned on a 16-bit boundary, then ASSERT().
836 @param Address Address that encodes the PCI Bus, Device, Function and
838 @param AndData The value to AND with the PCI configuration register.
839 @param OrData The value to OR with the result of the AND operation.
841 @return The value written back to the PCI configuration register.
846 PciExpressAndThenOr16 (
852 return MmioAndThenOr16 (
853 GetPciExpressAddress (Address
),
860 Reads a bit field of a PCI configuration register.
862 Reads the bit field in a 16-bit PCI configuration register. The bit field is
863 specified by the StartBit and the EndBit. The value of the bit field is
866 If Address > 0x0FFFFFFF, then ASSERT().
867 If Address is not aligned on a 16-bit boundary, then ASSERT().
868 If StartBit is greater than 15, then ASSERT().
869 If EndBit is greater than 15, then ASSERT().
870 If EndBit is less than StartBit, then ASSERT().
872 @param Address PCI configuration register to read.
873 @param StartBit The ordinal of the least significant bit in the bit field.
875 @param EndBit The ordinal of the most significant bit in the bit field.
878 @return The value of the bit field read from the PCI configuration register.
883 PciExpressBitFieldRead16 (
889 return MmioBitFieldRead16 (
890 GetPciExpressAddress (Address
),
897 Writes a bit field to a PCI configuration register.
899 Writes Value to the bit field of the PCI configuration register. The bit
900 field is specified by the StartBit and the EndBit. All other bits in the
901 destination PCI configuration register are preserved. The new value of the
902 16-bit register is returned.
904 If Address > 0x0FFFFFFF, then ASSERT().
905 If Address is not aligned on a 16-bit boundary, then ASSERT().
906 If StartBit is greater than 15, then ASSERT().
907 If EndBit is greater than 15, then ASSERT().
908 If EndBit is less than StartBit, then ASSERT().
910 @param Address PCI configuration register to write.
911 @param StartBit The ordinal of the least significant bit in the bit field.
913 @param EndBit The ordinal of the most significant bit in the bit field.
915 @param Value New value of the bit field.
917 @return The value written back to the PCI configuration register.
922 PciExpressBitFieldWrite16 (
929 return MmioBitFieldWrite16 (
930 GetPciExpressAddress (Address
),
938 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
939 writes the result back to the bit field in the 16-bit port.
941 Reads the 16-bit PCI configuration register specified by Address, performs a
942 bitwise OR between the read result and the value specified by
943 OrData, and writes the result to the 16-bit PCI configuration register
944 specified by Address. The value written to the PCI configuration register is
945 returned. This function must guarantee that all PCI read and write operations
946 are serialized. Extra left bits in OrData are stripped.
948 If Address > 0x0FFFFFFF, then ASSERT().
949 If Address is not aligned on a 16-bit boundary, then ASSERT().
950 If StartBit is greater than 15, then ASSERT().
951 If EndBit is greater than 15, then ASSERT().
952 If EndBit is less than StartBit, then ASSERT().
954 @param Address PCI configuration register to write.
955 @param StartBit The ordinal of the least significant bit in the bit field.
957 @param EndBit The ordinal of the most significant bit in the bit field.
959 @param OrData The value to OR with the PCI configuration register.
961 @return The value written back to the PCI configuration register.
966 PciExpressBitFieldOr16 (
973 return MmioBitFieldOr16 (
974 GetPciExpressAddress (Address
),
982 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
983 AND, and writes the result back to the bit field in the 16-bit register.
985 Reads the 16-bit PCI configuration register specified by Address, performs a
986 bitwise AND between the read result and the value specified by AndData, and
987 writes the result to the 16-bit PCI configuration register specified by
988 Address. The value written to the PCI configuration register is returned.
989 This function must guarantee that all PCI read and write operations are
990 serialized. Extra left bits in AndData are stripped.
992 If Address > 0x0FFFFFFF, then ASSERT().
993 If Address is not aligned on a 16-bit boundary, then ASSERT().
994 If StartBit is greater than 15, then ASSERT().
995 If EndBit is greater than 15, then ASSERT().
996 If EndBit is less than StartBit, then ASSERT().
998 @param Address PCI configuration register to write.
999 @param StartBit The ordinal of the least significant bit in the bit field.
1001 @param EndBit The ordinal of the most significant bit in the bit field.
1003 @param AndData The value to AND with the PCI configuration register.
1005 @return The value written back to the PCI configuration register.
1010 PciExpressBitFieldAnd16 (
1017 return MmioBitFieldAnd16 (
1018 GetPciExpressAddress (Address
),
1026 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1027 bitwise OR, and writes the result back to the bit field in the
1030 Reads the 16-bit PCI configuration register specified by Address, performs a
1031 bitwise AND followed by a bitwise OR between the read result and
1032 the value specified by AndData, and writes the result to the 16-bit PCI
1033 configuration register specified by Address. The value written to the PCI
1034 configuration register is returned. This function must guarantee that all PCI
1035 read and write operations are serialized. Extra left bits in both AndData and
1036 OrData are stripped.
1038 If Address > 0x0FFFFFFF, then ASSERT().
1039 If Address is not aligned on a 16-bit boundary, then ASSERT().
1040 If StartBit is greater than 15, then ASSERT().
1041 If EndBit is greater than 15, then ASSERT().
1042 If EndBit is less than StartBit, then ASSERT().
1044 @param Address PCI configuration register to write.
1045 @param StartBit The ordinal of the least significant bit in the bit field.
1047 @param EndBit The ordinal of the most significant bit in the bit field.
1049 @param AndData The value to AND with the PCI configuration register.
1050 @param OrData The value to OR with the result of the AND operation.
1052 @return The value written back to the PCI configuration register.
1057 PciExpressBitFieldAndThenOr16 (
1065 return MmioBitFieldAndThenOr16 (
1066 GetPciExpressAddress (Address
),
1075 Reads a 32-bit PCI configuration register.
1077 Reads and returns the 32-bit PCI configuration register specified by Address.
1078 This function must guarantee that all PCI read and write operations are
1081 If Address > 0x0FFFFFFF, then ASSERT().
1082 If Address is not aligned on a 32-bit boundary, then ASSERT().
1084 @param Address Address that encodes the PCI Bus, Device, Function and
1087 @return The read value from the PCI configuration register.
1096 return MmioRead32 (GetPciExpressAddress (Address
));
1100 Writes a 32-bit PCI configuration register.
1102 Writes the 32-bit PCI configuration register specified by Address with the
1103 value specified by Value. Value is returned. This function must guarantee
1104 that all PCI read and write operations are serialized.
1106 If Address > 0x0FFFFFFF, then ASSERT().
1107 If Address is not aligned on a 32-bit boundary, then ASSERT().
1109 @param Address Address that encodes the PCI Bus, Device, Function and
1111 @param Value The value to write.
1113 @return The value written to the PCI configuration register.
1123 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1127 Performs a bitwise OR of a 32-bit PCI configuration register with
1130 Reads the 32-bit PCI configuration register specified by Address, performs a
1131 bitwise OR between the read result and the value specified by
1132 OrData, and writes the result to the 32-bit PCI configuration register
1133 specified by Address. The value written to the PCI configuration register is
1134 returned. This function must guarantee that all PCI read and write operations
1137 If Address > 0x0FFFFFFF, then ASSERT().
1138 If Address is not aligned on a 32-bit boundary, then ASSERT().
1140 @param Address Address that encodes the PCI Bus, Device, Function and
1142 @param OrData The value to OR with the PCI configuration register.
1144 @return The value written back to the PCI configuration register.
1154 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1158 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1161 Reads the 32-bit PCI configuration register specified by Address, performs a
1162 bitwise AND between the read result and the value specified by AndData, and
1163 writes the result to the 32-bit PCI configuration register specified by
1164 Address. The value written to the PCI configuration register is returned.
1165 This function must guarantee that all PCI read and write operations are
1168 If Address > 0x0FFFFFFF, then ASSERT().
1169 If Address is not aligned on a 32-bit boundary, then ASSERT().
1171 @param Address Address that encodes the PCI Bus, Device, Function and
1173 @param AndData The value to AND with the PCI configuration register.
1175 @return The value written back to the PCI configuration register.
1185 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1189 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1190 value, followed a bitwise OR with another 32-bit value.
1192 Reads the 32-bit PCI configuration register specified by Address, performs a
1193 bitwise AND between the read result and the value specified by AndData,
1194 performs a bitwise OR between the result of the AND operation and
1195 the value specified by OrData, and writes the result to the 32-bit PCI
1196 configuration register specified by Address. The value written to the PCI
1197 configuration register is returned. This function must guarantee that all PCI
1198 read and write operations are serialized.
1200 If Address > 0x0FFFFFFF, then ASSERT().
1201 If Address is not aligned on a 32-bit boundary, then ASSERT().
1203 @param Address Address that encodes the PCI Bus, Device, Function and
1205 @param AndData The value to AND with the PCI configuration register.
1206 @param OrData The value to OR with the result of the AND operation.
1208 @return The value written back to the PCI configuration register.
1213 PciExpressAndThenOr32 (
1219 return MmioAndThenOr32 (
1220 GetPciExpressAddress (Address
),
1227 Reads a bit field of a PCI configuration register.
1229 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1230 specified by the StartBit and the EndBit. The value of the bit field is
1233 If Address > 0x0FFFFFFF, then ASSERT().
1234 If Address is not aligned on a 32-bit boundary, then ASSERT().
1235 If StartBit is greater than 31, then ASSERT().
1236 If EndBit is greater than 31, then ASSERT().
1237 If EndBit is less than StartBit, then ASSERT().
1239 @param Address PCI configuration register to read.
1240 @param StartBit The ordinal of the least significant bit in the bit field.
1242 @param EndBit The ordinal of the most significant bit in the bit field.
1245 @return The value of the bit field read from the PCI configuration register.
1250 PciExpressBitFieldRead32 (
1256 return MmioBitFieldRead32 (
1257 GetPciExpressAddress (Address
),
1264 Writes a bit field to a PCI configuration register.
1266 Writes Value to the bit field of the PCI configuration register. The bit
1267 field is specified by the StartBit and the EndBit. All other bits in the
1268 destination PCI configuration register are preserved. The new value of the
1269 32-bit register is returned.
1271 If Address > 0x0FFFFFFF, then ASSERT().
1272 If Address is not aligned on a 32-bit boundary, then ASSERT().
1273 If StartBit is greater than 31, then ASSERT().
1274 If EndBit is greater than 31, then ASSERT().
1275 If EndBit is less than StartBit, then ASSERT().
1277 @param Address PCI configuration register to write.
1278 @param StartBit The ordinal of the least significant bit in the bit field.
1280 @param EndBit The ordinal of the most significant bit in the bit field.
1282 @param Value New value of the bit field.
1284 @return The value written back to the PCI configuration register.
1289 PciExpressBitFieldWrite32 (
1296 return MmioBitFieldWrite32 (
1297 GetPciExpressAddress (Address
),
1305 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1306 writes the result back to the bit field in the 32-bit port.
1308 Reads the 32-bit PCI configuration register specified by Address, performs a
1309 bitwise OR between the read result and the value specified by
1310 OrData, and writes the result to the 32-bit PCI configuration register
1311 specified by Address. The value written to the PCI configuration register is
1312 returned. This function must guarantee that all PCI read and write operations
1313 are serialized. Extra left bits in OrData are stripped.
1315 If Address > 0x0FFFFFFF, then ASSERT().
1316 If Address is not aligned on a 32-bit boundary, then ASSERT().
1317 If StartBit is greater than 31, then ASSERT().
1318 If EndBit is greater than 31, then ASSERT().
1319 If EndBit is less than StartBit, then ASSERT().
1321 @param Address PCI configuration register to write.
1322 @param StartBit The ordinal of the least significant bit in the bit field.
1324 @param EndBit The ordinal of the most significant bit in the bit field.
1326 @param OrData The value to OR with the PCI configuration register.
1328 @return The value written back to the PCI configuration register.
1333 PciExpressBitFieldOr32 (
1340 return MmioBitFieldOr32 (
1341 GetPciExpressAddress (Address
),
1349 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1350 AND, and writes the result back to the bit field in the 32-bit register.
1352 Reads the 32-bit PCI configuration register specified by Address, performs a
1353 bitwise AND between the read result and the value specified by AndData, and
1354 writes the result to the 32-bit PCI configuration register specified by
1355 Address. The value written to the PCI configuration register is returned.
1356 This function must guarantee that all PCI read and write operations are
1357 serialized. Extra left bits in AndData are stripped.
1359 If Address > 0x0FFFFFFF, then ASSERT().
1360 If Address is not aligned on a 32-bit boundary, then ASSERT().
1361 If StartBit is greater than 31, then ASSERT().
1362 If EndBit is greater than 31, then ASSERT().
1363 If EndBit is less than StartBit, then ASSERT().
1365 @param Address PCI configuration register to write.
1366 @param StartBit The ordinal of the least significant bit in the bit field.
1368 @param EndBit The ordinal of the most significant bit in the bit field.
1370 @param AndData The value to AND with the PCI configuration register.
1372 @return The value written back to the PCI configuration register.
1377 PciExpressBitFieldAnd32 (
1384 return MmioBitFieldAnd32 (
1385 GetPciExpressAddress (Address
),
1393 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1394 bitwise OR, and writes the result back to the bit field in the
1397 Reads the 32-bit PCI configuration register specified by Address, performs a
1398 bitwise AND followed by a bitwise OR between the read result and
1399 the value specified by AndData, and writes the result to the 32-bit PCI
1400 configuration register specified by Address. The value written to the PCI
1401 configuration register is returned. This function must guarantee that all PCI
1402 read and write operations are serialized. Extra left bits in both AndData and
1403 OrData are stripped.
1405 If Address > 0x0FFFFFFF, then ASSERT().
1406 If Address is not aligned on a 32-bit boundary, then ASSERT().
1407 If StartBit is greater than 31, then ASSERT().
1408 If EndBit is greater than 31, then ASSERT().
1409 If EndBit is less than StartBit, then ASSERT().
1411 @param Address PCI configuration register to write.
1412 @param StartBit The ordinal of the least significant bit in the bit field.
1414 @param EndBit The ordinal of the most significant bit in the bit field.
1416 @param AndData The value to AND with the PCI configuration register.
1417 @param OrData The value to OR with the result of the AND operation.
1419 @return The value written back to the PCI configuration register.
1424 PciExpressBitFieldAndThenOr32 (
1432 return MmioBitFieldAndThenOr32 (
1433 GetPciExpressAddress (Address
),
1442 Reads a range of PCI configuration registers into a caller supplied buffer.
1444 Reads the range of PCI configuration registers specified by StartAddress and
1445 Size into the buffer specified by Buffer. This function only allows the PCI
1446 configuration registers from a single PCI function to be read. Size is
1447 returned. When possible 32-bit PCI configuration read cycles are used to read
1448 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1449 and 16-bit PCI configuration read cycles may be used at the beginning and the
1452 If StartAddress > 0x0FFFFFFF, then ASSERT().
1453 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1454 If Size > 0 and Buffer is NULL, then ASSERT().
1456 @param StartAddress Starting address that encodes the PCI Bus, Device,
1457 Function and Register.
1458 @param Size Size in bytes of the transfer.
1459 @param Buffer Pointer to a buffer receiving the data read.
1461 @return Size read data from StartAddress.
1466 PciExpressReadBuffer (
1467 IN UINTN StartAddress
,
1474 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1480 ASSERT (Buffer
!= NULL
);
1483 // Save Size for return
1487 if ((StartAddress
& 1) != 0) {
1489 // Read a byte if StartAddress is byte aligned
1491 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1492 StartAddress
+= sizeof (UINT8
);
1493 Size
-= sizeof (UINT8
);
1494 Buffer
= (UINT8
*)Buffer
+ 1;
1497 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1499 // Read a word if StartAddress is word aligned
1501 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1503 StartAddress
+= sizeof (UINT16
);
1504 Size
-= sizeof (UINT16
);
1505 Buffer
= (UINT16
*)Buffer
+ 1;
1508 while (Size
>= sizeof (UINT32
)) {
1510 // Read as many double words as possible
1512 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1514 StartAddress
+= sizeof (UINT32
);
1515 Size
-= sizeof (UINT32
);
1516 Buffer
= (UINT32
*)Buffer
+ 1;
1519 if (Size
>= sizeof (UINT16
)) {
1521 // Read the last remaining word if exist
1523 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1524 StartAddress
+= sizeof (UINT16
);
1525 Size
-= sizeof (UINT16
);
1526 Buffer
= (UINT16
*)Buffer
+ 1;
1529 if (Size
>= sizeof (UINT8
)) {
1531 // Read the last remaining byte if exist
1533 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1540 Copies the data in a caller supplied buffer to a specified range of PCI
1541 configuration space.
1543 Writes the range of PCI configuration registers specified by StartAddress and
1544 Size from the buffer specified by Buffer. This function only allows the PCI
1545 configuration registers from a single PCI function to be written. Size is
1546 returned. When possible 32-bit PCI configuration write cycles are used to
1547 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1548 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1549 and the end of the range.
1551 If StartAddress > 0x0FFFFFFF, then ASSERT().
1552 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1553 If Size > 0 and Buffer is NULL, then ASSERT().
1555 @param StartAddress Starting address that encodes the PCI Bus, Device,
1556 Function and Register.
1557 @param Size Size in bytes of the transfer.
1558 @param Buffer Pointer to a buffer containing the data to write.
1560 @return Size written to StartAddress.
1565 PciExpressWriteBuffer (
1566 IN UINTN StartAddress
,
1573 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1579 ASSERT (Buffer
!= NULL
);
1582 // Save Size for return
1586 if ((StartAddress
& 1) != 0) {
1588 // Write a byte if StartAddress is byte aligned
1590 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1591 StartAddress
+= sizeof (UINT8
);
1592 Size
-= sizeof (UINT8
);
1593 Buffer
= (UINT8
*)Buffer
+ 1;
1596 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1598 // Write a word if StartAddress is word aligned
1600 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1601 StartAddress
+= sizeof (UINT16
);
1602 Size
-= sizeof (UINT16
);
1603 Buffer
= (UINT16
*)Buffer
+ 1;
1606 while (Size
>= sizeof (UINT32
)) {
1608 // Write as many double words as possible
1610 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1611 StartAddress
+= sizeof (UINT32
);
1612 Size
-= sizeof (UINT32
);
1613 Buffer
= (UINT32
*)Buffer
+ 1;
1616 if (Size
>= sizeof (UINT16
)) {
1618 // Write the last remaining word if exist
1620 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1621 StartAddress
+= sizeof (UINT16
);
1622 Size
-= sizeof (UINT16
);
1623 Buffer
= (UINT16
*)Buffer
+ 1;
1626 if (Size
>= sizeof (UINT8
)) {
1628 // Write the last remaining byte if exist
1630 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);