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 of the PCI Express MMIO range.
25 UINTN mSmmPciExpressLibPciExpressBaseAddress
= 0;
28 The constructor function caches the PCI Express Base Address
30 @param ImageHandle The firmware allocated handle for the EFI image.
31 @param SystemTable A pointer to the EFI System Table.
33 @retval EFI_SUCCESS The constructor completed successfully.
37 SmmPciExpressLibConstructor (
38 IN EFI_HANDLE ImageHandle
,
39 IN EFI_SYSTEM_TABLE
*SystemTable
43 // Cache the physical address of the PCI Express MMIO range into a module global variable
45 mSmmPciExpressLibPciExpressBaseAddress
= (UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
51 Assert the validity of a PCI address. A valid PCI address should contain 1's
52 only in the low 28 bits.
54 @param A The address to validate.
57 #define ASSERT_INVALID_PCI_ADDRESS(A) \
58 ASSERT (((A) & ~0xfffffff) == 0)
61 Registers a PCI device so PCI configuration registers may be accessed after
62 SetVirtualAddressMap().
64 Registers the PCI device specified by Address so all the PCI configuration
65 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
68 If Address > 0x0FFFFFFF, then ASSERT().
70 @param Address The address that encodes the PCI Bus, Device, Function and
73 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
74 @retval RETURN_UNSUPPORTED An attempt was made to call this function
75 after ExitBootServices().
76 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
77 at runtime could not be mapped.
78 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
79 complete the registration.
84 PciExpressRegisterForRuntimeAccess (
88 ASSERT_INVALID_PCI_ADDRESS (Address
);
89 return RETURN_UNSUPPORTED
;
93 Gets MMIO address that can be used to access PCI Express location defined by Address.
95 This internal functions converts PCI Express address to a CPU MMIO address by adding
96 PCI Express Base Address stored in a global variable mSmmPciExpressLibPciExpressBaseAddress.
97 mSmmPciExpressLibPciExpressBaseAddress is initialized in the library constructor from PCD entry
98 PcdPciExpressBaseAddress.
100 @param Address The address that encodes the PCI Bus, Device, Function and Register.
101 @return MMIO address corresponding to Address.
105 GetPciExpressAddress (
110 // Make sure Address is valid
112 ASSERT_INVALID_PCI_ADDRESS (Address
);
113 return mSmmPciExpressLibPciExpressBaseAddress
+ Address
;
117 Reads an 8-bit PCI configuration register.
119 Reads and returns the 8-bit PCI configuration register specified by Address.
120 This function must guarantee that all PCI read and write operations are
123 If Address > 0x0FFFFFFF, then ASSERT().
125 @param Address The address that encodes the PCI Bus, Device, Function and
128 @return The read value from the PCI configuration register.
137 return MmioRead8 (GetPciExpressAddress (Address
));
141 Writes an 8-bit PCI configuration register.
143 Writes the 8-bit PCI configuration register specified by Address with the
144 value specified by Value. Value is returned. This function must guarantee
145 that all PCI read and write operations are serialized.
147 If Address > 0x0FFFFFFF, then ASSERT().
149 @param Address The address that encodes the PCI Bus, Device, Function and
151 @param Value The value to write.
153 @return The value written to the PCI configuration register.
163 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
167 Performs a bitwise OR of an 8-bit PCI configuration register with
170 Reads the 8-bit PCI configuration register specified by Address, performs a
171 bitwise OR between the read result and the value specified by
172 OrData, and writes the result to the 8-bit PCI configuration register
173 specified by Address. The value written to the PCI configuration register is
174 returned. This function must guarantee that all PCI read and write operations
177 If Address > 0x0FFFFFFF, then ASSERT().
179 @param Address The address that encodes the PCI Bus, Device, Function and
181 @param OrData The value to OR with the PCI configuration register.
183 @return The value written back to the PCI configuration register.
193 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
197 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
200 Reads the 8-bit PCI configuration register specified by Address, performs a
201 bitwise AND between the read result and the value specified by AndData, and
202 writes the result to the 8-bit PCI configuration register specified by
203 Address. The value written to the PCI configuration register is returned.
204 This function must guarantee that all PCI read and write operations are
207 If Address > 0x0FFFFFFF, then ASSERT().
209 @param Address The address that encodes the PCI Bus, Device, Function and
211 @param AndData The value to AND with the PCI configuration register.
213 @return The value written back to the PCI configuration register.
223 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
227 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
228 value, followed a bitwise OR with another 8-bit value.
230 Reads the 8-bit PCI configuration register specified by Address, performs a
231 bitwise AND between the read result and the value specified by AndData,
232 performs a bitwise OR between the result of the AND operation and
233 the value specified by OrData, and writes the result to the 8-bit PCI
234 configuration register specified by Address. The value written to the PCI
235 configuration register is returned. This function must guarantee that all PCI
236 read and write operations are serialized.
238 If Address > 0x0FFFFFFF, then ASSERT().
240 @param Address The address that encodes the PCI Bus, Device, Function and
242 @param AndData The value to AND with the PCI configuration register.
243 @param OrData The value to OR with the result of the AND operation.
245 @return The value written back to the PCI configuration register.
250 PciExpressAndThenOr8 (
256 return MmioAndThenOr8 (
257 GetPciExpressAddress (Address
),
264 Reads a bit field of a PCI configuration register.
266 Reads the bit field in an 8-bit PCI configuration register. The bit field is
267 specified by the StartBit and the EndBit. The value of the bit field is
270 If Address > 0x0FFFFFFF, then ASSERT().
271 If StartBit is greater than 7, then ASSERT().
272 If EndBit is greater than 7, then ASSERT().
273 If EndBit is less than StartBit, then ASSERT().
275 @param Address The PCI configuration register to read.
276 @param StartBit The ordinal of the least significant bit in the bit field.
278 @param EndBit The ordinal of the most significant bit in the bit field.
281 @return The value of the bit field read from the PCI configuration register.
286 PciExpressBitFieldRead8 (
292 return MmioBitFieldRead8 (
293 GetPciExpressAddress (Address
),
300 Writes a bit field to a PCI configuration register.
302 Writes Value to the bit field of the PCI configuration register. The bit
303 field is specified by the StartBit and the EndBit. All other bits in the
304 destination PCI configuration register are preserved. The new value of the
305 8-bit register is returned.
307 If Address > 0x0FFFFFFF, then ASSERT().
308 If StartBit is greater than 7, then ASSERT().
309 If EndBit is greater than 7, then ASSERT().
310 If EndBit is less than StartBit, then ASSERT().
311 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
313 @param Address The PCI configuration register to write.
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.
318 @param Value The new value of the bit field.
320 @return The value written back to the PCI configuration register.
325 PciExpressBitFieldWrite8 (
332 return MmioBitFieldWrite8 (
333 GetPciExpressAddress (Address
),
341 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
342 writes the result back to the bit field in the 8-bit port.
344 Reads the 8-bit PCI configuration register specified by Address, performs a
345 bitwise OR between the read result and the value specified by
346 OrData, and writes the result to the 8-bit PCI configuration register
347 specified by Address. The value written to the PCI configuration register is
348 returned. This function must guarantee that all PCI read and write operations
349 are serialized. Extra left bits in OrData are stripped.
351 If Address > 0x0FFFFFFF, then ASSERT().
352 If StartBit is greater than 7, then ASSERT().
353 If EndBit is greater than 7, then ASSERT().
354 If EndBit is less than StartBit, then ASSERT().
355 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
357 @param Address The PCI configuration register to write.
358 @param StartBit The ordinal of the least significant bit in the bit field.
360 @param EndBit The ordinal of the most significant bit in the bit field.
362 @param OrData The value to OR with the PCI configuration register.
364 @return The value written back to the PCI configuration register.
369 PciExpressBitFieldOr8 (
376 return MmioBitFieldOr8 (
377 GetPciExpressAddress (Address
),
385 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
386 AND, and writes the result back to the bit field in the 8-bit register.
388 Reads the 8-bit PCI configuration register specified by Address, performs a
389 bitwise AND between the read result and the value specified by AndData, and
390 writes the result to the 8-bit PCI configuration register specified by
391 Address. The value written to the PCI configuration register is returned.
392 This function must guarantee that all PCI read and write operations are
393 serialized. Extra left bits in AndData are stripped.
395 If Address > 0x0FFFFFFF, then ASSERT().
396 If StartBit is greater than 7, then ASSERT().
397 If EndBit is greater than 7, then ASSERT().
398 If EndBit is less than StartBit, then ASSERT().
399 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
401 @param Address The PCI configuration register to write.
402 @param StartBit The ordinal of the least significant bit in the bit field.
404 @param EndBit The ordinal of the most significant bit in the bit field.
406 @param AndData The value to AND with the PCI configuration register.
408 @return The value written back to the PCI configuration register.
413 PciExpressBitFieldAnd8 (
420 return MmioBitFieldAnd8 (
421 GetPciExpressAddress (Address
),
429 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
430 bitwise OR, and writes the result back to the bit field in the
433 Reads the 8-bit PCI configuration register specified by Address, performs a
434 bitwise AND followed by a bitwise OR between the read result and
435 the value specified by AndData, and writes the result to the 8-bit PCI
436 configuration register specified by Address. The value written to the PCI
437 configuration register is returned. This function must guarantee that all PCI
438 read and write operations are serialized. Extra left bits in both AndData and
441 If Address > 0x0FFFFFFF, then ASSERT().
442 If StartBit is greater than 7, then ASSERT().
443 If EndBit is greater than 7, then ASSERT().
444 If EndBit is less than StartBit, then ASSERT().
445 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
446 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
448 @param Address The PCI configuration register to write.
449 @param StartBit The ordinal of the least significant bit in the bit field.
451 @param EndBit The ordinal of the most significant bit in the bit field.
453 @param AndData The value to AND with the PCI configuration register.
454 @param OrData The value to OR with the result of the AND operation.
456 @return The value written back to the PCI configuration register.
461 PciExpressBitFieldAndThenOr8 (
469 return MmioBitFieldAndThenOr8 (
470 GetPciExpressAddress (Address
),
479 Reads a 16-bit PCI configuration register.
481 Reads and returns the 16-bit PCI configuration register specified by Address.
482 This function must guarantee that all PCI read and write operations are
485 If Address > 0x0FFFFFFF, then ASSERT().
486 If Address is not aligned on a 16-bit boundary, then ASSERT().
488 @param Address The address that encodes the PCI Bus, Device, Function and
491 @return The read value from the PCI configuration register.
500 return MmioRead16 (GetPciExpressAddress (Address
));
504 Writes a 16-bit PCI configuration register.
506 Writes the 16-bit PCI configuration register specified by Address with the
507 value specified by Value. Value is returned. This function must guarantee
508 that all PCI read and write operations are serialized.
510 If Address > 0x0FFFFFFF, then ASSERT().
511 If Address is not aligned on a 16-bit boundary, then ASSERT().
513 @param Address The address that encodes the PCI Bus, Device, Function and
515 @param Value The value to write.
517 @return The value written to the PCI configuration register.
527 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
531 Performs a bitwise OR of a 16-bit PCI configuration register with
534 Reads the 16-bit PCI configuration register specified by Address, performs a
535 bitwise OR between the read result and the value specified by
536 OrData, and writes the result to the 16-bit PCI configuration register
537 specified by Address. The value written to the PCI configuration register is
538 returned. This function must guarantee that all PCI read and write operations
541 If Address > 0x0FFFFFFF, then ASSERT().
542 If Address is not aligned on a 16-bit boundary, then ASSERT().
544 @param Address The address that encodes the PCI Bus, Device, Function and
546 @param OrData The value to OR with the PCI configuration register.
548 @return The value written back to the PCI configuration register.
558 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
562 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
565 Reads the 16-bit PCI configuration register specified by Address, performs a
566 bitwise AND between the read result and the value specified by AndData, and
567 writes the result to the 16-bit PCI configuration register specified by
568 Address. The value written to the PCI configuration register is returned.
569 This function must guarantee that all PCI read and write operations are
572 If Address > 0x0FFFFFFF, then ASSERT().
573 If Address is not aligned on a 16-bit boundary, then ASSERT().
575 @param Address The address that encodes the PCI Bus, Device, Function and
577 @param AndData The value to AND with the PCI configuration register.
579 @return The value written back to the PCI configuration register.
589 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
593 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
594 value, followed a bitwise OR with another 16-bit value.
596 Reads the 16-bit PCI configuration register specified by Address, performs a
597 bitwise AND between the read result and the value specified by AndData,
598 performs a bitwise OR between the result of the AND operation and
599 the value specified by OrData, and writes the result to the 16-bit PCI
600 configuration register specified by Address. The value written to the PCI
601 configuration register is returned. This function must guarantee that all PCI
602 read and write operations are serialized.
604 If Address > 0x0FFFFFFF, then ASSERT().
605 If Address is not aligned on a 16-bit boundary, then ASSERT().
607 @param Address The address that encodes the PCI Bus, Device, Function and
609 @param AndData The value to AND with the PCI configuration register.
610 @param OrData The value to OR with the result of the AND operation.
612 @return The value written back to the PCI configuration register.
617 PciExpressAndThenOr16 (
623 return MmioAndThenOr16 (
624 GetPciExpressAddress (Address
),
631 Reads a bit field of a PCI configuration register.
633 Reads the bit field in a 16-bit PCI configuration register. The bit field is
634 specified by the StartBit and the EndBit. The value of the bit field is
637 If Address > 0x0FFFFFFF, then ASSERT().
638 If Address is not aligned on a 16-bit boundary, then ASSERT().
639 If StartBit is greater than 15, then ASSERT().
640 If EndBit is greater than 15, then ASSERT().
641 If EndBit is less than StartBit, then ASSERT().
643 @param Address The PCI configuration register to read.
644 @param StartBit The ordinal of the least significant bit in the bit field.
646 @param EndBit The ordinal of the most significant bit in the bit field.
649 @return The value of the bit field read from the PCI configuration register.
654 PciExpressBitFieldRead16 (
660 return MmioBitFieldRead16 (
661 GetPciExpressAddress (Address
),
668 Writes a bit field to a PCI configuration register.
670 Writes Value to the bit field of the PCI configuration register. The bit
671 field is specified by the StartBit and the EndBit. All other bits in the
672 destination PCI configuration register are preserved. The new value of the
673 16-bit register is returned.
675 If Address > 0x0FFFFFFF, then ASSERT().
676 If Address is not aligned on a 16-bit boundary, then ASSERT().
677 If StartBit is greater than 15, then ASSERT().
678 If EndBit is greater than 15, then ASSERT().
679 If EndBit is less than StartBit, then ASSERT().
680 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
682 @param Address The PCI configuration register to write.
683 @param StartBit The ordinal of the least significant bit in the bit field.
685 @param EndBit The ordinal of the most significant bit in the bit field.
687 @param Value The new value of the bit field.
689 @return The value written back to the PCI configuration register.
694 PciExpressBitFieldWrite16 (
701 return MmioBitFieldWrite16 (
702 GetPciExpressAddress (Address
),
710 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
711 writes the result back to the bit field in the 16-bit port.
713 Reads the 16-bit PCI configuration register specified by Address, performs a
714 bitwise OR between the read result and the value specified by
715 OrData, and writes the result to the 16-bit PCI configuration register
716 specified by Address. The value written to the PCI configuration register is
717 returned. This function must guarantee that all PCI read and write operations
718 are serialized. Extra left bits in OrData are stripped.
720 If Address > 0x0FFFFFFF, then ASSERT().
721 If Address is not aligned on a 16-bit boundary, then ASSERT().
722 If StartBit is greater than 15, then ASSERT().
723 If EndBit is greater than 15, then ASSERT().
724 If EndBit is less than StartBit, then ASSERT().
725 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
727 @param Address The PCI configuration register to write.
728 @param StartBit The ordinal of the least significant bit in the bit field.
730 @param EndBit The ordinal of the most significant bit in the bit field.
732 @param OrData The value to OR with the PCI configuration register.
734 @return The value written back to the PCI configuration register.
739 PciExpressBitFieldOr16 (
746 return MmioBitFieldOr16 (
747 GetPciExpressAddress (Address
),
755 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
756 AND, and writes the result back to the bit field in the 16-bit register.
758 Reads the 16-bit PCI configuration register specified by Address, performs a
759 bitwise AND between the read result and the value specified by AndData, and
760 writes the result to the 16-bit PCI configuration register specified by
761 Address. The value written to the PCI configuration register is returned.
762 This function must guarantee that all PCI read and write operations are
763 serialized. Extra left bits in AndData are stripped.
765 If Address > 0x0FFFFFFF, then ASSERT().
766 If Address is not aligned on a 16-bit boundary, then ASSERT().
767 If StartBit is greater than 15, then ASSERT().
768 If EndBit is greater than 15, then ASSERT().
769 If EndBit is less than StartBit, then ASSERT().
770 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
772 @param Address The PCI configuration register to write.
773 @param StartBit The ordinal of the least significant bit in the bit field.
775 @param EndBit The ordinal of the most significant bit in the bit field.
777 @param AndData The value to AND with the PCI configuration register.
779 @return The value written back to the PCI configuration register.
784 PciExpressBitFieldAnd16 (
791 return MmioBitFieldAnd16 (
792 GetPciExpressAddress (Address
),
800 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
801 bitwise OR, and writes the result back to the bit field in the
804 Reads the 16-bit PCI configuration register specified by Address, performs a
805 bitwise AND followed by a bitwise OR between the read result and
806 the value specified by AndData, and writes the result to the 16-bit PCI
807 configuration register specified by Address. The value written to the PCI
808 configuration register is returned. This function must guarantee that all PCI
809 read and write operations are serialized. Extra left bits in both AndData and
812 If Address > 0x0FFFFFFF, then ASSERT().
813 If Address is not aligned on a 16-bit boundary, then ASSERT().
814 If StartBit is greater than 15, then ASSERT().
815 If EndBit is greater than 15, then ASSERT().
816 If EndBit is less than StartBit, then ASSERT().
817 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
818 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
820 @param Address The PCI configuration register to write.
821 @param StartBit The ordinal of the least significant bit in the bit field.
823 @param EndBit The ordinal of the most significant bit in the bit field.
825 @param AndData The value to AND with the PCI configuration register.
826 @param OrData The value to OR with the result of the AND operation.
828 @return The value written back to the PCI configuration register.
833 PciExpressBitFieldAndThenOr16 (
841 return MmioBitFieldAndThenOr16 (
842 GetPciExpressAddress (Address
),
851 Reads a 32-bit PCI configuration register.
853 Reads and returns the 32-bit PCI configuration register specified by Address.
854 This function must guarantee that all PCI read and write operations are
857 If Address > 0x0FFFFFFF, then ASSERT().
858 If Address is not aligned on a 32-bit boundary, then ASSERT().
860 @param Address The address that encodes the PCI Bus, Device, Function and
863 @return The read value from the PCI configuration register.
872 return MmioRead32 (GetPciExpressAddress (Address
));
876 Writes a 32-bit PCI configuration register.
878 Writes the 32-bit PCI configuration register specified by Address with the
879 value specified by Value. Value is returned. This function must guarantee
880 that all PCI read and write operations are serialized.
882 If Address > 0x0FFFFFFF, then ASSERT().
883 If Address is not aligned on a 32-bit boundary, then ASSERT().
885 @param Address The address that encodes the PCI Bus, Device, Function and
887 @param Value The value to write.
889 @return The value written to the PCI configuration register.
899 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
903 Performs a bitwise OR of a 32-bit PCI configuration register with
906 Reads the 32-bit PCI configuration register specified by Address, performs a
907 bitwise OR between the read result and the value specified by
908 OrData, and writes the result to the 32-bit PCI configuration register
909 specified by Address. The value written to the PCI configuration register is
910 returned. This function must guarantee that all PCI read and write operations
913 If Address > 0x0FFFFFFF, then ASSERT().
914 If Address is not aligned on a 32-bit boundary, then ASSERT().
916 @param Address The address that encodes the PCI Bus, Device, Function and
918 @param OrData The value to OR with the PCI configuration register.
920 @return The value written back to the PCI configuration register.
930 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
934 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
937 Reads the 32-bit PCI configuration register specified by Address, performs a
938 bitwise AND between the read result and the value specified by AndData, and
939 writes the result to the 32-bit PCI configuration register specified by
940 Address. The value written to the PCI configuration register is returned.
941 This function must guarantee that all PCI read and write operations are
944 If Address > 0x0FFFFFFF, then ASSERT().
945 If Address is not aligned on a 32-bit boundary, then ASSERT().
947 @param Address The address that encodes the PCI Bus, Device, Function and
949 @param AndData The value to AND with the PCI configuration register.
951 @return The value written back to the PCI configuration register.
961 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
965 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
966 value, followed a bitwise OR with another 32-bit value.
968 Reads the 32-bit PCI configuration register specified by Address, performs a
969 bitwise AND between the read result and the value specified by AndData,
970 performs a bitwise OR between the result of the AND operation and
971 the value specified by OrData, and writes the result to the 32-bit PCI
972 configuration register specified by Address. The value written to the PCI
973 configuration register is returned. This function must guarantee that all PCI
974 read and write operations are serialized.
976 If Address > 0x0FFFFFFF, then ASSERT().
977 If Address is not aligned on a 32-bit boundary, then ASSERT().
979 @param Address The address that encodes the PCI Bus, Device, Function and
981 @param AndData The value to AND with the PCI configuration register.
982 @param OrData The value to OR with the result of the AND operation.
984 @return The value written back to the PCI configuration register.
989 PciExpressAndThenOr32 (
995 return MmioAndThenOr32 (
996 GetPciExpressAddress (Address
),
1003 Reads a bit field of a PCI configuration register.
1005 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1006 specified by the StartBit and the EndBit. The value of the bit field is
1009 If Address > 0x0FFFFFFF, then ASSERT().
1010 If Address is not aligned on a 32-bit boundary, then ASSERT().
1011 If StartBit is greater than 31, then ASSERT().
1012 If EndBit is greater than 31, then ASSERT().
1013 If EndBit is less than StartBit, then ASSERT().
1015 @param Address The PCI configuration register to read.
1016 @param StartBit The ordinal of the least significant bit in the bit field.
1018 @param EndBit The ordinal of the most significant bit in the bit field.
1021 @return The value of the bit field read from the PCI configuration register.
1026 PciExpressBitFieldRead32 (
1032 return MmioBitFieldRead32 (
1033 GetPciExpressAddress (Address
),
1040 Writes a bit field to a PCI configuration register.
1042 Writes Value to the bit field of the PCI configuration register. The bit
1043 field is specified by the StartBit and the EndBit. All other bits in the
1044 destination PCI configuration register are preserved. The new value of the
1045 32-bit register is returned.
1047 If Address > 0x0FFFFFFF, then ASSERT().
1048 If Address is not aligned on a 32-bit boundary, then ASSERT().
1049 If StartBit is greater than 31, then ASSERT().
1050 If EndBit is greater than 31, then ASSERT().
1051 If EndBit is less than StartBit, then ASSERT().
1052 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1054 @param Address The PCI configuration register to write.
1055 @param StartBit The ordinal of the least significant bit in the bit field.
1057 @param EndBit The ordinal of the most significant bit in the bit field.
1059 @param Value The new value of the bit field.
1061 @return The value written back to the PCI configuration register.
1066 PciExpressBitFieldWrite32 (
1073 return MmioBitFieldWrite32 (
1074 GetPciExpressAddress (Address
),
1082 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1083 writes the result back to the bit field in the 32-bit port.
1085 Reads the 32-bit PCI configuration register specified by Address, performs a
1086 bitwise OR between the read result and the value specified by
1087 OrData, and writes the result to the 32-bit PCI configuration register
1088 specified by Address. The value written to the PCI configuration register is
1089 returned. This function must guarantee that all PCI read and write operations
1090 are serialized. Extra left bits in OrData are stripped.
1092 If Address > 0x0FFFFFFF, then ASSERT().
1093 If Address is not aligned on a 32-bit boundary, then ASSERT().
1094 If StartBit is greater than 31, then ASSERT().
1095 If EndBit is greater than 31, then ASSERT().
1096 If EndBit is less than StartBit, then ASSERT().
1097 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1099 @param Address The PCI configuration register to write.
1100 @param StartBit The ordinal of the least significant bit in the bit field.
1102 @param EndBit The ordinal of the most significant bit in the bit field.
1104 @param OrData The value to OR with the PCI configuration register.
1106 @return The value written back to the PCI configuration register.
1111 PciExpressBitFieldOr32 (
1118 return MmioBitFieldOr32 (
1119 GetPciExpressAddress (Address
),
1127 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1128 AND, and writes the result back to the bit field in the 32-bit register.
1130 Reads the 32-bit PCI configuration register specified by Address, performs a
1131 bitwise AND between the read result and the value specified by AndData, and
1132 writes the result to the 32-bit PCI configuration register specified by
1133 Address. The value written to the PCI configuration register is returned.
1134 This function must guarantee that all PCI read and write operations are
1135 serialized. Extra left bits in AndData are stripped.
1137 If Address > 0x0FFFFFFF, then ASSERT().
1138 If Address is not aligned on a 32-bit boundary, then ASSERT().
1139 If StartBit is greater than 31, then ASSERT().
1140 If EndBit is greater than 31, then ASSERT().
1141 If EndBit is less than StartBit, then ASSERT().
1142 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1144 @param Address The PCI configuration register to write.
1145 @param StartBit The ordinal of the least significant bit in the bit field.
1147 @param EndBit The ordinal of the most significant bit in the bit field.
1149 @param AndData The value to AND with the PCI configuration register.
1151 @return The value written back to the PCI configuration register.
1156 PciExpressBitFieldAnd32 (
1163 return MmioBitFieldAnd32 (
1164 GetPciExpressAddress (Address
),
1172 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1173 bitwise OR, and writes the result back to the bit field in the
1176 Reads the 32-bit PCI configuration register specified by Address, performs a
1177 bitwise AND followed by a bitwise OR between the read result and
1178 the value specified by AndData, and writes the result to the 32-bit PCI
1179 configuration register specified by Address. The value written to the PCI
1180 configuration register is returned. This function must guarantee that all PCI
1181 read and write operations are serialized. Extra left bits in both AndData and
1182 OrData are stripped.
1184 If Address > 0x0FFFFFFF, then ASSERT().
1185 If Address is not aligned on a 32-bit boundary, then ASSERT().
1186 If StartBit is greater than 31, then ASSERT().
1187 If EndBit is greater than 31, then ASSERT().
1188 If EndBit is less than StartBit, then ASSERT().
1189 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1190 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1192 @param Address The PCI configuration register to write.
1193 @param StartBit The ordinal of the least significant bit in the bit field.
1195 @param EndBit The ordinal of the most significant bit in the bit field.
1197 @param AndData The value to AND with the PCI configuration register.
1198 @param OrData The value to OR with the result of the AND operation.
1200 @return The value written back to the PCI configuration register.
1205 PciExpressBitFieldAndThenOr32 (
1213 return MmioBitFieldAndThenOr32 (
1214 GetPciExpressAddress (Address
),
1223 Reads a range of PCI configuration registers into a caller supplied buffer.
1225 Reads the range of PCI configuration registers specified by StartAddress and
1226 Size into the buffer specified by Buffer. This function only allows the PCI
1227 configuration registers from a single PCI function to be read. Size is
1228 returned. When possible 32-bit PCI configuration read cycles are used to read
1229 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1230 and 16-bit PCI configuration read cycles may be used at the beginning and the
1233 If StartAddress > 0x0FFFFFFF, then ASSERT().
1234 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1235 If Size > 0 and Buffer is NULL, then ASSERT().
1237 @param StartAddress The starting address that encodes the PCI Bus, Device,
1238 Function and Register.
1239 @param Size The size in bytes of the transfer.
1240 @param Buffer The pointer to a buffer receiving the data read.
1242 @return Size read data from StartAddress.
1247 PciExpressReadBuffer (
1248 IN UINTN StartAddress
,
1256 // Make sure Address is valid
1258 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1259 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1265 ASSERT (Buffer
!= NULL
);
1268 // Save Size for return
1272 if ((StartAddress
& 1) != 0) {
1274 // Read a byte if StartAddress is byte aligned
1276 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1277 StartAddress
+= sizeof (UINT8
);
1278 Size
-= sizeof (UINT8
);
1279 Buffer
= (UINT8
*)Buffer
+ 1;
1282 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1284 // Read a word if StartAddress is word aligned
1286 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1288 StartAddress
+= sizeof (UINT16
);
1289 Size
-= sizeof (UINT16
);
1290 Buffer
= (UINT16
*)Buffer
+ 1;
1293 while (Size
>= sizeof (UINT32
)) {
1295 // Read as many double words as possible
1297 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1299 StartAddress
+= sizeof (UINT32
);
1300 Size
-= sizeof (UINT32
);
1301 Buffer
= (UINT32
*)Buffer
+ 1;
1304 if (Size
>= sizeof (UINT16
)) {
1306 // Read the last remaining word if exist
1308 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1309 StartAddress
+= sizeof (UINT16
);
1310 Size
-= sizeof (UINT16
);
1311 Buffer
= (UINT16
*)Buffer
+ 1;
1314 if (Size
>= sizeof (UINT8
)) {
1316 // Read the last remaining byte if exist
1318 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1325 Copies the data in a caller supplied buffer to a specified range of PCI
1326 configuration space.
1328 Writes the range of PCI configuration registers specified by StartAddress and
1329 Size from the buffer specified by Buffer. This function only allows the PCI
1330 configuration registers from a single PCI function to be written. Size is
1331 returned. When possible 32-bit PCI configuration write cycles are used to
1332 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1333 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1334 and the end of the range.
1336 If StartAddress > 0x0FFFFFFF, then ASSERT().
1337 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1338 If Size > 0 and Buffer is NULL, then ASSERT().
1340 @param StartAddress The starting address that encodes the PCI Bus, Device,
1341 Function and Register.
1342 @param Size The size in bytes of the transfer.
1343 @param Buffer The pointer to a buffer containing the data to write.
1345 @return Size written to StartAddress.
1350 PciExpressWriteBuffer (
1351 IN UINTN StartAddress
,
1359 // Make sure Address is valid
1361 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1362 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1369 ASSERT (Buffer
!= NULL
);
1372 // Save Size for return
1376 if ((StartAddress
& 1) != 0) {
1378 // Write a byte if StartAddress is byte aligned
1380 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1381 StartAddress
+= sizeof (UINT8
);
1382 Size
-= sizeof (UINT8
);
1383 Buffer
= (UINT8
*)Buffer
+ 1;
1386 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1388 // Write a word if StartAddress is word aligned
1390 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1391 StartAddress
+= sizeof (UINT16
);
1392 Size
-= sizeof (UINT16
);
1393 Buffer
= (UINT16
*)Buffer
+ 1;
1396 while (Size
>= sizeof (UINT32
)) {
1398 // Write as many double words as possible
1400 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1401 StartAddress
+= sizeof (UINT32
);
1402 Size
-= sizeof (UINT32
);
1403 Buffer
= (UINT32
*)Buffer
+ 1;
1406 if (Size
>= sizeof (UINT16
)) {
1408 // Write the last remaining word if exist
1410 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1411 StartAddress
+= sizeof (UINT16
);
1412 Size
-= sizeof (UINT16
);
1413 Buffer
= (UINT16
*)Buffer
+ 1;
1416 if (Size
>= sizeof (UINT8
)) {
1418 // Write the last remaining byte if exist
1420 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);