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 - 2012, Intel Corporation. All rights reserved.
9 Portions copyright (c) 2016, American Megatrends, Inc. All rights reserved.
10 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include <Library/BaseLib.h>
17 #include <Library/PciExpressLib.h>
18 #include <Library/IoLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
23 /// Module global that contains the base physical address and size of the PCI Express MMIO range.
25 UINTN mSmmPciExpressLibPciExpressBaseAddress
= 0;
26 UINTN mSmmPciExpressLibPciExpressBaseSize
= 0;
29 The constructor function caches the PCI Express Base Address
31 @param ImageHandle The firmware allocated handle for the EFI image.
32 @param SystemTable A pointer to the EFI System Table.
34 @retval EFI_SUCCESS The constructor completed successfully.
38 SmmPciExpressLibConstructor (
39 IN EFI_HANDLE ImageHandle
,
40 IN EFI_SYSTEM_TABLE
*SystemTable
44 // Cache the physical address and size of the PCI Express MMIO range into a module global variable
46 mSmmPciExpressLibPciExpressBaseAddress
= (UINTN
)PcdGet64 (PcdPciExpressBaseAddress
);
47 mSmmPciExpressLibPciExpressBaseSize
= (UINTN
)PcdGet64 (PcdPciExpressBaseSize
);
53 Assert the validity of a PCI address. A valid PCI address should contain 1's
54 only in the low 28 bits.
56 @param A The address to validate.
59 #define ASSERT_INVALID_PCI_ADDRESS(A) \
60 ASSERT (((A) & ~0xfffffff) == 0)
63 Registers a PCI device so PCI configuration registers may be accessed after
64 SetVirtualAddressMap().
66 Registers the PCI device specified by Address so all the PCI configuration
67 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
70 If Address > 0x0FFFFFFF, then ASSERT().
72 @param Address The address that encodes the PCI Bus, Device, Function and
75 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
76 @retval RETURN_UNSUPPORTED An attempt was made to call this function
77 after ExitBootServices().
78 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
79 at runtime could not be mapped.
80 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
81 complete the registration.
86 PciExpressRegisterForRuntimeAccess (
90 ASSERT_INVALID_PCI_ADDRESS (Address
);
91 return RETURN_UNSUPPORTED
;
95 Gets MMIO address that can be used to access PCI Express location defined by Address.
97 This internal functions converts PCI Express address to a CPU MMIO address by adding
98 PCI Express Base Address stored in a global variable mSmmPciExpressLibPciExpressBaseAddress.
99 mSmmPciExpressLibPciExpressBaseAddress is initialized in the library constructor from PCD entry
100 PcdPciExpressBaseAddress.
102 If Address > 0x0FFFFFFF, then ASSERT().
104 @param Address The address that encodes the PCI Bus, Device, Function and Register.
106 @retval (UINTN)-1 Invalid PCI address.
107 @retval other MMIO address corresponding to Address.
111 GetPciExpressAddress (
116 // Make sure Address is valid
118 ASSERT_INVALID_PCI_ADDRESS (Address
);
120 // Make sure the Address is in MMCONF address space
122 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
126 return mSmmPciExpressLibPciExpressBaseAddress
+ Address
;
130 Reads an 8-bit PCI configuration register.
132 Reads and returns the 8-bit PCI configuration register specified by Address.
133 This function must guarantee that all PCI read and write operations are
136 If Address > 0x0FFFFFFF, then ASSERT().
138 @param Address The address that encodes the PCI Bus, Device, Function and
141 @retval 0xFF Invalid PCI address.
142 @retval other The read value from the PCI configuration register.
151 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
155 return MmioRead8 (GetPciExpressAddress (Address
));
159 Writes an 8-bit PCI configuration register.
161 Writes the 8-bit PCI configuration register specified by Address with the
162 value specified by Value. Value is returned. This function must guarantee
163 that all PCI read and write operations are serialized.
165 If Address > 0x0FFFFFFF, then ASSERT().
167 @param Address The address that encodes the PCI Bus, Device, Function and
169 @param Value The value to write.
171 @retval 0xFF Invalid PCI address.
172 @retval other The value written to the PCI configuration register.
182 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
186 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
190 Performs a bitwise OR of an 8-bit PCI configuration register with
193 Reads the 8-bit PCI configuration register specified by Address, performs a
194 bitwise OR between the read result and the value specified by
195 OrData, and writes the result to the 8-bit PCI configuration register
196 specified by Address. The value written to the PCI configuration register is
197 returned. This function must guarantee that all PCI read and write operations
200 If Address > 0x0FFFFFFF, then ASSERT().
202 @param Address The address that encodes the PCI Bus, Device, Function and
204 @param OrData The value to OR with the PCI configuration register.
206 @retval 0xFF Invalid PCI address.
207 @retval other The value written back to the PCI configuration register.
217 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
221 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
225 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
228 Reads the 8-bit PCI configuration register specified by Address, performs a
229 bitwise AND between the read result and the value specified by AndData, and
230 writes the result to the 8-bit PCI configuration register specified by
231 Address. The value written to the PCI configuration register is returned.
232 This function must guarantee that all PCI read and write operations are
235 If Address > 0x0FFFFFFF, then ASSERT().
237 @param Address The address that encodes the PCI Bus, Device, Function and
239 @param AndData The value to AND with the PCI configuration register.
241 @retval 0xFF Invalid PCI address.
242 @retval other The value written back to the PCI configuration register.
252 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
256 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
260 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
261 value, followed a bitwise OR with another 8-bit value.
263 Reads the 8-bit PCI configuration register specified by Address, performs a
264 bitwise AND between the read result and the value specified by AndData,
265 performs a bitwise OR between the result of the AND operation and
266 the value specified by OrData, and writes the result to the 8-bit PCI
267 configuration register specified by Address. The value written to the PCI
268 configuration register is returned. This function must guarantee that all PCI
269 read and write operations are serialized.
271 If Address > 0x0FFFFFFF, then ASSERT().
273 @param Address The address that encodes the PCI Bus, Device, Function and
275 @param AndData The value to AND with the PCI configuration register.
276 @param OrData The value to OR with the result of the AND operation.
278 @retval 0xFF Invalid PCI address.
279 @retval other The value written back to the PCI configuration register.
284 PciExpressAndThenOr8 (
290 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
294 return MmioAndThenOr8 (
295 GetPciExpressAddress (Address
),
302 Reads a bit field of a PCI configuration register.
304 Reads the bit field in an 8-bit PCI configuration register. The bit field is
305 specified by the StartBit and the EndBit. The value of the bit field is
308 If Address > 0x0FFFFFFF, then ASSERT().
309 If StartBit is greater than 7, then ASSERT().
310 If EndBit is greater than 7, then ASSERT().
311 If EndBit is less than StartBit, then ASSERT().
313 @param Address The PCI configuration register to read.
314 @param StartBit The ordinal of the least significant bit in the bit field.
316 @param EndBit The ordinal of the most significant bit in the bit field.
319 @retval 0xFF Invalid PCI address.
320 @retval other The value of the bit field read from the PCI configuration register.
325 PciExpressBitFieldRead8 (
331 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
335 return MmioBitFieldRead8 (
336 GetPciExpressAddress (Address
),
343 Writes a bit field to a PCI configuration register.
345 Writes Value to the bit field of the PCI configuration register. The bit
346 field is specified by the StartBit and the EndBit. All other bits in the
347 destination PCI configuration register are preserved. The new value of the
348 8-bit register is returned.
350 If Address > 0x0FFFFFFF, then ASSERT().
351 If StartBit is greater than 7, then ASSERT().
352 If EndBit is greater than 7, then ASSERT().
353 If EndBit is less than StartBit, then ASSERT().
354 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
356 @param Address The PCI configuration register to write.
357 @param StartBit The ordinal of the least significant bit in the bit field.
359 @param EndBit The ordinal of the most significant bit in the bit field.
361 @param Value The new value of the bit field.
363 @retval 0xFF Invalid PCI address.
364 @retval other The value written back to the PCI configuration register.
369 PciExpressBitFieldWrite8 (
376 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
380 return MmioBitFieldWrite8 (
381 GetPciExpressAddress (Address
),
389 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
390 writes the result back to the bit field in the 8-bit port.
392 Reads the 8-bit PCI configuration register specified by Address, performs a
393 bitwise OR between the read result and the value specified by
394 OrData, and writes the result to the 8-bit PCI configuration register
395 specified by Address. The value written to the PCI configuration register is
396 returned. This function must guarantee that all PCI read and write operations
397 are serialized. Extra left bits in OrData are stripped.
399 If Address > 0x0FFFFFFF, then ASSERT().
400 If StartBit is greater than 7, then ASSERT().
401 If EndBit is greater than 7, then ASSERT().
402 If EndBit is less than StartBit, then ASSERT().
403 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
405 @param Address The PCI configuration register to write.
406 @param StartBit The ordinal of the least significant bit in the bit field.
408 @param EndBit The ordinal of the most significant bit in the bit field.
410 @param OrData The value to OR with the PCI configuration register.
412 @retval 0xFF Invalid PCI address.
413 @retval other The value written back to the PCI configuration register.
418 PciExpressBitFieldOr8 (
425 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
429 return MmioBitFieldOr8 (
430 GetPciExpressAddress (Address
),
438 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
439 AND, and writes the result back to the bit field in the 8-bit register.
441 Reads the 8-bit PCI configuration register specified by Address, performs a
442 bitwise AND between the read result and the value specified by AndData, and
443 writes the result to the 8-bit PCI configuration register specified by
444 Address. The value written to the PCI configuration register is returned.
445 This function must guarantee that all PCI read and write operations are
446 serialized. Extra left bits in AndData are stripped.
448 If Address > 0x0FFFFFFF, then ASSERT().
449 If StartBit is greater than 7, then ASSERT().
450 If EndBit is greater than 7, then ASSERT().
451 If EndBit is less than StartBit, then ASSERT().
452 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
454 @param Address The PCI configuration register to write.
455 @param StartBit The ordinal of the least significant bit in the bit field.
457 @param EndBit The ordinal of the most significant bit in the bit field.
459 @param AndData The value to AND with the PCI configuration register.
461 @retval 0xFF Invalid PCI address.
462 @retval other The value written back to the PCI configuration register.
467 PciExpressBitFieldAnd8 (
474 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
478 return MmioBitFieldAnd8 (
479 GetPciExpressAddress (Address
),
487 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
488 bitwise OR, and writes the result back to the bit field in the
491 Reads the 8-bit PCI configuration register specified by Address, performs a
492 bitwise AND followed by a bitwise OR between the read result and
493 the value specified by AndData, and writes the result to the 8-bit PCI
494 configuration register specified by Address. The value written to the PCI
495 configuration register is returned. This function must guarantee that all PCI
496 read and write operations are serialized. Extra left bits in both AndData and
499 If Address > 0x0FFFFFFF, then ASSERT().
500 If StartBit is greater than 7, then ASSERT().
501 If EndBit is greater than 7, then ASSERT().
502 If EndBit is less than StartBit, then ASSERT().
503 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
504 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
506 @param Address The PCI configuration register to write.
507 @param StartBit The ordinal of the least significant bit in the bit field.
509 @param EndBit The ordinal of the most significant bit in the bit field.
511 @param AndData The value to AND with the PCI configuration register.
512 @param OrData The value to OR with the result of the AND operation.
514 @retval 0xFF Invalid PCI address.
515 @retval other The value written back to the PCI configuration register.
520 PciExpressBitFieldAndThenOr8 (
528 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
532 return MmioBitFieldAndThenOr8 (
533 GetPciExpressAddress (Address
),
542 Reads a 16-bit PCI configuration register.
544 Reads and returns the 16-bit PCI configuration register specified by Address.
545 This function must guarantee that all PCI read and write operations are
548 If Address > 0x0FFFFFFF, then ASSERT().
549 If Address is not aligned on a 16-bit boundary, then ASSERT().
551 @param Address The address that encodes the PCI Bus, Device, Function and
554 @retval 0xFF Invalid PCI address.
555 @retval other The read value from the PCI configuration register.
564 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
568 return MmioRead16 (GetPciExpressAddress (Address
));
572 Writes a 16-bit PCI configuration register.
574 Writes the 16-bit PCI configuration register specified by Address with the
575 value specified by Value. Value is returned. This function must guarantee
576 that all PCI read and write operations are serialized.
578 If Address > 0x0FFFFFFF, then ASSERT().
579 If Address is not aligned on a 16-bit boundary, then ASSERT().
581 @param Address The address that encodes the PCI Bus, Device, Function and
583 @param Value The value to write.
585 @retval 0xFFFF Invalid PCI address.
586 @retval other The value written to the PCI configuration register.
596 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
600 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
604 Performs a bitwise OR of a 16-bit PCI configuration register with
607 Reads the 16-bit PCI configuration register specified by Address, performs a
608 bitwise OR between the read result and the value specified by
609 OrData, and writes the result to the 16-bit PCI configuration register
610 specified by Address. The value written to the PCI configuration register is
611 returned. This function must guarantee that all PCI read and write operations
614 If Address > 0x0FFFFFFF, then ASSERT().
615 If Address is not aligned on a 16-bit boundary, then ASSERT().
617 @param Address The address that encodes the PCI Bus, Device, Function and
619 @param OrData The value to OR with the PCI configuration register.
621 @retval 0xFFFF Invalid PCI address.
622 @retval other The value written back to the PCI configuration register.
632 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
636 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
640 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
643 Reads the 16-bit PCI configuration register specified by Address, performs a
644 bitwise AND between the read result and the value specified by AndData, and
645 writes the result to the 16-bit PCI configuration register specified by
646 Address. The value written to the PCI configuration register is returned.
647 This function must guarantee that all PCI read and write operations are
650 If Address > 0x0FFFFFFF, then ASSERT().
651 If Address is not aligned on a 16-bit boundary, then ASSERT().
653 @param Address The address that encodes the PCI Bus, Device, Function and
655 @param AndData The value to AND with the PCI configuration register.
657 @retval 0xFFFF Invalid PCI address.
658 @retval other The value written back to the PCI configuration register.
668 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
672 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
676 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
677 value, followed a bitwise OR with another 16-bit value.
679 Reads the 16-bit PCI configuration register specified by Address, performs a
680 bitwise AND between the read result and the value specified by AndData,
681 performs a bitwise OR between the result of the AND operation and
682 the value specified by OrData, and writes the result to the 16-bit PCI
683 configuration register specified by Address. The value written to the PCI
684 configuration register is returned. This function must guarantee that all PCI
685 read and write operations are serialized.
687 If Address > 0x0FFFFFFF, then ASSERT().
688 If Address is not aligned on a 16-bit boundary, then ASSERT().
690 @param Address The address that encodes the PCI Bus, Device, Function and
692 @param AndData The value to AND with the PCI configuration register.
693 @param OrData The value to OR with the result of the AND operation.
695 @retval 0xFFFF Invalid PCI address.
696 @retval other The value written back to the PCI configuration register.
701 PciExpressAndThenOr16 (
707 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
711 return MmioAndThenOr16 (
712 GetPciExpressAddress (Address
),
719 Reads a bit field of a PCI configuration register.
721 Reads the bit field in a 16-bit PCI configuration register. The bit field is
722 specified by the StartBit and the EndBit. The value of the bit field is
725 If Address > 0x0FFFFFFF, then ASSERT().
726 If Address is not aligned on a 16-bit boundary, then ASSERT().
727 If StartBit is greater than 15, then ASSERT().
728 If EndBit is greater than 15, then ASSERT().
729 If EndBit is less than StartBit, then ASSERT().
731 @param Address The PCI configuration register to read.
732 @param StartBit The ordinal of the least significant bit in the bit field.
734 @param EndBit The ordinal of the most significant bit in the bit field.
737 @retval 0xFFFF Invalid PCI address.
738 @retval other The value of the bit field read from the PCI configuration register.
743 PciExpressBitFieldRead16 (
749 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
753 return MmioBitFieldRead16 (
754 GetPciExpressAddress (Address
),
761 Writes a bit field to a PCI configuration register.
763 Writes Value to the bit field of the PCI configuration register. The bit
764 field is specified by the StartBit and the EndBit. All other bits in the
765 destination PCI configuration register are preserved. The new value of the
766 16-bit register is returned.
768 If Address > 0x0FFFFFFF, then ASSERT().
769 If Address is not aligned on a 16-bit boundary, then ASSERT().
770 If StartBit is greater than 15, then ASSERT().
771 If EndBit is greater than 15, then ASSERT().
772 If EndBit is less than StartBit, then ASSERT().
773 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
775 @param Address The PCI configuration register to write.
776 @param StartBit The ordinal of the least significant bit in the bit field.
778 @param EndBit The ordinal of the most significant bit in the bit field.
780 @param Value The new value of the bit field.
782 @retval 0xFFFF Invalid PCI address.
783 @retval other The value written back to the PCI configuration register.
788 PciExpressBitFieldWrite16 (
795 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
799 return MmioBitFieldWrite16 (
800 GetPciExpressAddress (Address
),
808 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
809 writes the result back to the bit field in the 16-bit port.
811 Reads the 16-bit PCI configuration register specified by Address, performs a
812 bitwise OR between the read result and the value specified by
813 OrData, and writes the result to the 16-bit PCI configuration register
814 specified by Address. The value written to the PCI configuration register is
815 returned. This function must guarantee that all PCI read and write operations
816 are serialized. Extra left bits in OrData are stripped.
818 If Address > 0x0FFFFFFF, then ASSERT().
819 If Address is not aligned on a 16-bit boundary, then ASSERT().
820 If StartBit is greater than 15, then ASSERT().
821 If EndBit is greater than 15, then ASSERT().
822 If EndBit is less than StartBit, then ASSERT().
823 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
825 @param Address The PCI configuration register to write.
826 @param StartBit The ordinal of the least significant bit in the bit field.
828 @param EndBit The ordinal of the most significant bit in the bit field.
830 @param OrData The value to OR with the PCI configuration register.
832 @retval 0xFFFF Invalid PCI address.
833 @retval other The value written back to the PCI configuration register.
838 PciExpressBitFieldOr16 (
845 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
849 return MmioBitFieldOr16 (
850 GetPciExpressAddress (Address
),
858 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
859 AND, and writes the result back to the bit field in the 16-bit register.
861 Reads the 16-bit PCI configuration register specified by Address, performs a
862 bitwise AND between the read result and the value specified by AndData, and
863 writes the result to the 16-bit PCI configuration register specified by
864 Address. The value written to the PCI configuration register is returned.
865 This function must guarantee that all PCI read and write operations are
866 serialized. Extra left bits in AndData are stripped.
868 If Address > 0x0FFFFFFF, then ASSERT().
869 If Address is not aligned on a 16-bit boundary, then ASSERT().
870 If StartBit is greater than 15, then ASSERT().
871 If EndBit is greater than 15, then ASSERT().
872 If EndBit is less than StartBit, then ASSERT().
873 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
875 @param Address The PCI configuration register to write.
876 @param StartBit The ordinal of the least significant bit in the bit field.
878 @param EndBit The ordinal of the most significant bit in the bit field.
880 @param AndData The value to AND with the PCI configuration register.
882 @retval 0xFFFF Invalid PCI address.
883 @retval other The value written back to the PCI configuration register.
888 PciExpressBitFieldAnd16 (
895 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
899 return MmioBitFieldAnd16 (
900 GetPciExpressAddress (Address
),
908 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
909 bitwise OR, and writes the result back to the bit field in the
912 Reads the 16-bit PCI configuration register specified by Address, performs a
913 bitwise AND followed by a bitwise OR between the read result and
914 the value specified by AndData, and writes the result to the 16-bit PCI
915 configuration register specified by Address. The value written to the PCI
916 configuration register is returned. This function must guarantee that all PCI
917 read and write operations are serialized. Extra left bits in both AndData and
920 If Address > 0x0FFFFFFF, then ASSERT().
921 If Address is not aligned on a 16-bit boundary, then ASSERT().
922 If StartBit is greater than 15, then ASSERT().
923 If EndBit is greater than 15, then ASSERT().
924 If EndBit is less than StartBit, then ASSERT().
925 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
926 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
928 @param Address The PCI configuration register to write.
929 @param StartBit The ordinal of the least significant bit in the bit field.
931 @param EndBit The ordinal of the most significant bit in the bit field.
933 @param AndData The value to AND with the PCI configuration register.
934 @param OrData The value to OR with the result of the AND operation.
936 @retval 0xFFFF Invalid PCI address.
937 @retval other The value written back to the PCI configuration register.
942 PciExpressBitFieldAndThenOr16 (
950 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
954 return MmioBitFieldAndThenOr16 (
955 GetPciExpressAddress (Address
),
964 Reads a 32-bit PCI configuration register.
966 Reads and returns the 32-bit PCI configuration register specified by Address.
967 This function must guarantee that all PCI read and write operations are
970 If Address > 0x0FFFFFFF, then ASSERT().
971 If Address is not aligned on a 32-bit boundary, then ASSERT().
973 @param Address The address that encodes the PCI Bus, Device, Function and
976 @retval 0xFFFFFFFF Invalid PCI address.
977 @retval other The read value from the PCI configuration register.
986 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
990 return MmioRead32 (GetPciExpressAddress (Address
));
994 Writes a 32-bit PCI configuration register.
996 Writes the 32-bit PCI configuration register specified by Address with the
997 value specified by Value. Value is returned. This function must guarantee
998 that all PCI read and write operations are serialized.
1000 If Address > 0x0FFFFFFF, then ASSERT().
1001 If Address is not aligned on a 32-bit boundary, then ASSERT().
1003 @param Address The address that encodes the PCI Bus, Device, Function and
1005 @param Value The value to write.
1007 @retval 0xFFFFFFFF Invalid PCI address.
1008 @retval other The value written to the PCI configuration register.
1018 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1022 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1026 Performs a bitwise OR of a 32-bit PCI configuration register with
1029 Reads the 32-bit PCI configuration register specified by Address, performs a
1030 bitwise OR between the read result and the value specified by
1031 OrData, and writes the result to the 32-bit PCI configuration register
1032 specified by Address. The value written to the PCI configuration register is
1033 returned. This function must guarantee that all PCI read and write operations
1036 If Address > 0x0FFFFFFF, then ASSERT().
1037 If Address is not aligned on a 32-bit boundary, then ASSERT().
1039 @param Address The address that encodes the PCI Bus, Device, Function and
1041 @param OrData The value to OR with the PCI configuration register.
1043 @retval 0xFFFFFFFF Invalid PCI address.
1044 @retval other The value written back to the PCI configuration register.
1054 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1058 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1062 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1065 Reads the 32-bit PCI configuration register specified by Address, performs a
1066 bitwise AND between the read result and the value specified by AndData, and
1067 writes the result to the 32-bit PCI configuration register specified by
1068 Address. The value written to the PCI configuration register is returned.
1069 This function must guarantee that all PCI read and write operations are
1072 If Address > 0x0FFFFFFF, then ASSERT().
1073 If Address is not aligned on a 32-bit boundary, then ASSERT().
1075 @param Address The address that encodes the PCI Bus, Device, Function and
1077 @param AndData The value to AND with the PCI configuration register.
1079 @retval 0xFFFFFFFF Invalid PCI address.
1080 @retval other The value written back to the PCI configuration register.
1090 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1094 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1098 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1099 value, followed a bitwise OR with another 32-bit value.
1101 Reads the 32-bit PCI configuration register specified by Address, performs a
1102 bitwise AND between the read result and the value specified by AndData,
1103 performs a bitwise OR between the result of the AND operation and
1104 the value specified by OrData, and writes the result to the 32-bit PCI
1105 configuration register specified by Address. The value written to the PCI
1106 configuration register is returned. This function must guarantee that all PCI
1107 read and write operations are serialized.
1109 If Address > 0x0FFFFFFF, then ASSERT().
1110 If Address is not aligned on a 32-bit boundary, then ASSERT().
1112 @param Address The address that encodes the PCI Bus, Device, Function and
1114 @param AndData The value to AND with the PCI configuration register.
1115 @param OrData The value to OR with the result of the AND operation.
1117 @retval 0xFFFFFFFF Invalid PCI address.
1118 @retval other The value written back to the PCI configuration register.
1123 PciExpressAndThenOr32 (
1129 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1133 return MmioAndThenOr32 (
1134 GetPciExpressAddress (Address
),
1141 Reads a bit field of a PCI configuration register.
1143 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1144 specified by the StartBit and the EndBit. The value of the bit field is
1147 If Address > 0x0FFFFFFF, then ASSERT().
1148 If Address is not aligned on a 32-bit boundary, then ASSERT().
1149 If StartBit is greater than 31, then ASSERT().
1150 If EndBit is greater than 31, then ASSERT().
1151 If EndBit is less than StartBit, then ASSERT().
1153 @param Address The PCI configuration register to read.
1154 @param StartBit The ordinal of the least significant bit in the bit field.
1156 @param EndBit The ordinal of the most significant bit in the bit field.
1159 @retval 0xFFFFFFFF Invalid PCI address.
1160 @retval other The value of the bit field read from the PCI configuration register.
1165 PciExpressBitFieldRead32 (
1171 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1175 return MmioBitFieldRead32 (
1176 GetPciExpressAddress (Address
),
1183 Writes a bit field to a PCI configuration register.
1185 Writes Value to the bit field of the PCI configuration register. The bit
1186 field is specified by the StartBit and the EndBit. All other bits in the
1187 destination PCI configuration register are preserved. The new value of the
1188 32-bit register is returned.
1190 If Address > 0x0FFFFFFF, then ASSERT().
1191 If Address is not aligned on a 32-bit boundary, then ASSERT().
1192 If StartBit is greater than 31, then ASSERT().
1193 If EndBit is greater than 31, then ASSERT().
1194 If EndBit is less than StartBit, then ASSERT().
1195 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1197 @param Address The PCI configuration register to write.
1198 @param StartBit The ordinal of the least significant bit in the bit field.
1200 @param EndBit The ordinal of the most significant bit in the bit field.
1202 @param Value The new value of the bit field.
1204 @retval 0xFFFFFFFF Invalid PCI address.
1205 @retval other The value written back to the PCI configuration register.
1210 PciExpressBitFieldWrite32 (
1217 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1221 return MmioBitFieldWrite32 (
1222 GetPciExpressAddress (Address
),
1230 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1231 writes the result back to the bit field in the 32-bit port.
1233 Reads the 32-bit PCI configuration register specified by Address, performs a
1234 bitwise OR between the read result and the value specified by
1235 OrData, and writes the result to the 32-bit PCI configuration register
1236 specified by Address. The value written to the PCI configuration register is
1237 returned. This function must guarantee that all PCI read and write operations
1238 are serialized. Extra left bits in OrData are stripped.
1240 If Address > 0x0FFFFFFF, then ASSERT().
1241 If Address is not aligned on a 32-bit boundary, then ASSERT().
1242 If StartBit is greater than 31, then ASSERT().
1243 If EndBit is greater than 31, then ASSERT().
1244 If EndBit is less than StartBit, then ASSERT().
1245 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1247 @param Address The PCI configuration register to write.
1248 @param StartBit The ordinal of the least significant bit in the bit field.
1250 @param EndBit The ordinal of the most significant bit in the bit field.
1252 @param OrData The value to OR with the PCI configuration register.
1254 @retval 0xFFFFFFFF Invalid PCI address.
1255 @retval other The value written back to the PCI configuration register.
1260 PciExpressBitFieldOr32 (
1267 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1271 return MmioBitFieldOr32 (
1272 GetPciExpressAddress (Address
),
1280 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1281 AND, and writes the result back to the bit field in the 32-bit register.
1283 Reads the 32-bit PCI configuration register specified by Address, performs a
1284 bitwise AND between the read result and the value specified by AndData, and
1285 writes the result to the 32-bit PCI configuration register specified by
1286 Address. The value written to the PCI configuration register is returned.
1287 This function must guarantee that all PCI read and write operations are
1288 serialized. Extra left bits in AndData are stripped.
1290 If Address > 0x0FFFFFFF, then ASSERT().
1291 If Address is not aligned on a 32-bit boundary, then ASSERT().
1292 If StartBit is greater than 31, then ASSERT().
1293 If EndBit is greater than 31, then ASSERT().
1294 If EndBit is less than StartBit, then ASSERT().
1295 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1297 @param Address The PCI configuration register to write.
1298 @param StartBit The ordinal of the least significant bit in the bit field.
1300 @param EndBit The ordinal of the most significant bit in the bit field.
1302 @param AndData The value to AND with the PCI configuration register.
1304 @retval 0xFFFFFFFF Invalid PCI address.
1305 @retval other The value written back to the PCI configuration register.
1310 PciExpressBitFieldAnd32 (
1317 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1321 return MmioBitFieldAnd32 (
1322 GetPciExpressAddress (Address
),
1330 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1331 bitwise OR, and writes the result back to the bit field in the
1334 Reads the 32-bit PCI configuration register specified by Address, performs a
1335 bitwise AND followed by a bitwise OR between the read result and
1336 the value specified by AndData, and writes the result to the 32-bit PCI
1337 configuration register specified by Address. The value written to the PCI
1338 configuration register is returned. This function must guarantee that all PCI
1339 read and write operations are serialized. Extra left bits in both AndData and
1340 OrData are stripped.
1342 If Address > 0x0FFFFFFF, then ASSERT().
1343 If Address is not aligned on a 32-bit boundary, then ASSERT().
1344 If StartBit is greater than 31, then ASSERT().
1345 If EndBit is greater than 31, then ASSERT().
1346 If EndBit is less than StartBit, then ASSERT().
1347 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1348 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1350 @param Address The PCI configuration register to write.
1351 @param StartBit The ordinal of the least significant bit in the bit field.
1353 @param EndBit The ordinal of the most significant bit in the bit field.
1355 @param AndData The value to AND with the PCI configuration register.
1356 @param OrData The value to OR with the result of the AND operation.
1358 @retval 0xFFFFFFFF Invalid PCI address.
1359 @retval other The value written back to the PCI configuration register.
1364 PciExpressBitFieldAndThenOr32 (
1372 if (Address
>= mSmmPciExpressLibPciExpressBaseSize
) {
1376 return MmioBitFieldAndThenOr32 (
1377 GetPciExpressAddress (Address
),
1386 Reads a range of PCI configuration registers into a caller supplied buffer.
1388 Reads the range of PCI configuration registers specified by StartAddress and
1389 Size into the buffer specified by Buffer. This function only allows the PCI
1390 configuration registers from a single PCI function to be read. Size is
1391 returned. When possible 32-bit PCI configuration read cycles are used to read
1392 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit
1393 and 16-bit PCI configuration read cycles may be used at the beginning and the
1396 If StartAddress > 0x0FFFFFFF, then ASSERT().
1397 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1398 If Size > 0 and Buffer is NULL, then ASSERT().
1400 @param StartAddress The starting address that encodes the PCI Bus, Device,
1401 Function and Register.
1402 @param Size The size in bytes of the transfer.
1403 @param Buffer The pointer to a buffer receiving the data read.
1405 @retval (UINTN)-1 Invalid PCI address.
1406 @retval other Size read data from StartAddress.
1411 PciExpressReadBuffer (
1412 IN UINTN StartAddress
,
1420 // Make sure Address is valid
1422 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1423 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1426 // Make sure the Address is in MMCONF address space
1428 if (StartAddress
>= mSmmPciExpressLibPciExpressBaseSize
) {
1436 ASSERT (Buffer
!= NULL
);
1439 // Save Size for return
1443 if ((StartAddress
& 1) != 0) {
1445 // Read a byte if StartAddress is byte aligned
1447 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1448 StartAddress
+= sizeof (UINT8
);
1449 Size
-= sizeof (UINT8
);
1450 Buffer
= (UINT8
*)Buffer
+ 1;
1453 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& 2) != 0)) {
1455 // Read a word if StartAddress is word aligned
1457 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
)PciExpressRead16 (StartAddress
));
1459 StartAddress
+= sizeof (UINT16
);
1460 Size
-= sizeof (UINT16
);
1461 Buffer
= (UINT16
*)Buffer
+ 1;
1464 while (Size
>= sizeof (UINT32
)) {
1466 // Read as many double words as possible
1468 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
)PciExpressRead32 (StartAddress
));
1470 StartAddress
+= sizeof (UINT32
);
1471 Size
-= sizeof (UINT32
);
1472 Buffer
= (UINT32
*)Buffer
+ 1;
1475 if (Size
>= sizeof (UINT16
)) {
1477 // Read the last remaining word if exist
1479 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
)PciExpressRead16 (StartAddress
));
1480 StartAddress
+= sizeof (UINT16
);
1481 Size
-= sizeof (UINT16
);
1482 Buffer
= (UINT16
*)Buffer
+ 1;
1485 if (Size
>= sizeof (UINT8
)) {
1487 // Read the last remaining byte if exist
1489 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1496 Copies the data in a caller supplied buffer to a specified range of PCI
1497 configuration space.
1499 Writes the range of PCI configuration registers specified by StartAddress and
1500 Size from the buffer specified by Buffer. This function only allows the PCI
1501 configuration registers from a single PCI function to be written. Size is
1502 returned. When possible 32-bit PCI configuration write cycles are used to
1503 write from StartAddress to StartAddress + Size. Due to alignment restrictions,
1504 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1505 and the end of the range.
1507 If StartAddress > 0x0FFFFFFF, then ASSERT().
1508 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1509 If Size > 0 and Buffer is NULL, then ASSERT().
1511 @param StartAddress The starting address that encodes the PCI Bus, Device,
1512 Function and Register.
1513 @param Size The size in bytes of the transfer.
1514 @param Buffer The pointer to a buffer containing the data to write.
1516 @retval (UINTN)-1 Invalid PCI address.
1517 @retval other Size written to StartAddress.
1522 PciExpressWriteBuffer (
1523 IN UINTN StartAddress
,
1531 // Make sure Address is valid
1533 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1534 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1537 // Make sure the Address is in MMCONF address space
1539 if (StartAddress
>= mSmmPciExpressLibPciExpressBaseSize
) {
1547 ASSERT (Buffer
!= NULL
);
1550 // Save Size for return
1554 if ((StartAddress
& 1) != 0) {
1556 // Write a byte if StartAddress is byte aligned
1558 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1559 StartAddress
+= sizeof (UINT8
);
1560 Size
-= sizeof (UINT8
);
1561 Buffer
= (UINT8
*)Buffer
+ 1;
1564 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& 2) != 0)) {
1566 // Write a word if StartAddress is word aligned
1568 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1569 StartAddress
+= sizeof (UINT16
);
1570 Size
-= sizeof (UINT16
);
1571 Buffer
= (UINT16
*)Buffer
+ 1;
1574 while (Size
>= sizeof (UINT32
)) {
1576 // Write as many double words as possible
1578 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1579 StartAddress
+= sizeof (UINT32
);
1580 Size
-= sizeof (UINT32
);
1581 Buffer
= (UINT32
*)Buffer
+ 1;
1584 if (Size
>= sizeof (UINT16
)) {
1586 // Write the last remaining word if exist
1588 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1589 StartAddress
+= sizeof (UINT16
);
1590 Size
-= sizeof (UINT16
);
1591 Buffer
= (UINT16
*)Buffer
+ 1;
1594 if (Size
>= sizeof (UINT8
)) {
1596 // Write the last remaining byte if exist
1598 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);