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.<BR>
9 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>
24 Assert the validity of a PCI address. A valid PCI address should contain 1's
25 only in the low 28 bits.
27 @param A The address to validate.
30 #define ASSERT_INVALID_PCI_ADDRESS(A) \
31 ASSERT (((A) & ~0xfffffff) == 0)
34 Registers a PCI device so PCI configuration registers may be accessed after
35 SetVirtualAddressMap().
37 Registers the PCI device specified by Address so all the PCI configuration
38 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
41 If Address > 0x0FFFFFFF, then ASSERT().
43 @param Address The address that encodes the PCI Bus, Device, Function and
46 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
47 @retval RETURN_UNSUPPORTED An attempt was made to call this function
48 after ExitBootServices().
49 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
50 at runtime could not be mapped.
51 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
52 complete the registration.
57 PciExpressRegisterForRuntimeAccess (
61 ASSERT_INVALID_PCI_ADDRESS (Address
);
62 return RETURN_UNSUPPORTED
;
65 STATIC UINT64 mPciExpressBaseAddress
;
69 PciExpressLibInitialize (
73 mPciExpressBaseAddress
= PcdGet64 (PcdPciExpressBaseAddress
);
74 return RETURN_SUCCESS
;
79 Gets the base address of PCI Express.
81 @return The base address of PCI Express.
85 GetPciExpressBaseAddress (
89 return (VOID
*)(UINTN
) mPciExpressBaseAddress
;
93 Reads an 8-bit PCI configuration register.
95 Reads and returns the 8-bit PCI configuration register specified by Address.
96 This function must guarantee that all PCI read and write operations are
99 If Address > 0x0FFFFFFF, then ASSERT().
101 @param Address The address that encodes the PCI Bus, Device, Function and
104 @return The read value from the PCI configuration register.
113 ASSERT_INVALID_PCI_ADDRESS (Address
);
114 return MmioRead8 ((UINTN
) GetPciExpressBaseAddress () + Address
);
118 Writes an 8-bit PCI configuration register.
120 Writes the 8-bit PCI configuration register specified by Address with the
121 value specified by Value. Value is returned. This function must guarantee
122 that all PCI read and write operations are serialized.
124 If Address > 0x0FFFFFFF, then ASSERT().
126 @param Address The address that encodes the PCI Bus, Device, Function and
128 @param Value The value to write.
130 @return The value written to the PCI configuration register.
140 ASSERT_INVALID_PCI_ADDRESS (Address
);
141 return MmioWrite8 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
145 Performs a bitwise OR of an 8-bit PCI configuration register with
148 Reads the 8-bit PCI configuration register specified by Address, performs a
149 bitwise OR between the read result and the value specified by
150 OrData, and writes the result to the 8-bit PCI configuration register
151 specified by Address. The value written to the PCI configuration register is
152 returned. This function must guarantee that all PCI read and write operations
155 If Address > 0x0FFFFFFF, then ASSERT().
157 @param Address The address that encodes the PCI Bus, Device, Function and
159 @param OrData The value to OR with the PCI configuration register.
161 @return The value written back to the PCI configuration register.
171 ASSERT_INVALID_PCI_ADDRESS (Address
);
172 return MmioOr8 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
176 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
179 Reads the 8-bit PCI configuration register specified by Address, performs a
180 bitwise AND between the read result and the value specified by AndData, and
181 writes the result to the 8-bit PCI configuration register specified by
182 Address. The value written to the PCI configuration register is returned.
183 This function must guarantee that all PCI read and write operations are
186 If Address > 0x0FFFFFFF, then ASSERT().
188 @param Address The address that encodes the PCI Bus, Device, Function and
190 @param AndData The value to AND with the PCI configuration register.
192 @return The value written back to the PCI configuration register.
202 ASSERT_INVALID_PCI_ADDRESS (Address
);
203 return MmioAnd8 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
207 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
208 value, followed a bitwise OR with another 8-bit value.
210 Reads the 8-bit PCI configuration register specified by Address, performs a
211 bitwise AND between the read result and the value specified by AndData,
212 performs a bitwise OR between the result of the AND operation and
213 the value specified by OrData, and writes the result to the 8-bit PCI
214 configuration register specified by Address. The value written to the PCI
215 configuration register is returned. This function must guarantee that all PCI
216 read and write operations are serialized.
218 If Address > 0x0FFFFFFF, then ASSERT().
220 @param Address The address that encodes the PCI Bus, Device, Function and
222 @param AndData The value to AND with the PCI configuration register.
223 @param OrData The value to OR with the result of the AND operation.
225 @return The value written back to the PCI configuration register.
230 PciExpressAndThenOr8 (
236 ASSERT_INVALID_PCI_ADDRESS (Address
);
237 return MmioAndThenOr8 (
238 (UINTN
) GetPciExpressBaseAddress () + Address
,
245 Reads a bit field of a PCI configuration register.
247 Reads the bit field in an 8-bit PCI configuration register. The bit field is
248 specified by the StartBit and the EndBit. The value of the bit field is
251 If Address > 0x0FFFFFFF, then ASSERT().
252 If StartBit is greater than 7, then ASSERT().
253 If EndBit is greater than 7, then ASSERT().
254 If EndBit is less than StartBit, then ASSERT().
256 @param Address The PCI configuration register to read.
257 @param StartBit The ordinal of the least significant bit in the bit field.
259 @param EndBit The ordinal of the most significant bit in the bit field.
262 @return The value of the bit field read from the PCI configuration register.
267 PciExpressBitFieldRead8 (
273 ASSERT_INVALID_PCI_ADDRESS (Address
);
274 return MmioBitFieldRead8 (
275 (UINTN
) GetPciExpressBaseAddress () + Address
,
282 Writes a bit field to a PCI configuration register.
284 Writes Value to the bit field of the PCI configuration register. The bit
285 field is specified by the StartBit and the EndBit. All other bits in the
286 destination PCI configuration register are preserved. The new value of the
287 8-bit register is returned.
289 If Address > 0x0FFFFFFF, then ASSERT().
290 If StartBit is greater than 7, then ASSERT().
291 If EndBit is greater than 7, then ASSERT().
292 If EndBit is less than StartBit, then ASSERT().
293 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
295 @param Address The PCI configuration register to write.
296 @param StartBit The ordinal of the least significant bit in the bit field.
298 @param EndBit The ordinal of the most significant bit in the bit field.
300 @param Value The new value of the bit field.
302 @return The value written back to the PCI configuration register.
307 PciExpressBitFieldWrite8 (
314 ASSERT_INVALID_PCI_ADDRESS (Address
);
315 return MmioBitFieldWrite8 (
316 (UINTN
) GetPciExpressBaseAddress () + Address
,
324 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
325 writes the result back to the bit field in the 8-bit port.
327 Reads the 8-bit PCI configuration register specified by Address, performs a
328 bitwise OR between the read result and the value specified by
329 OrData, and writes the result to the 8-bit PCI configuration register
330 specified by Address. The value written to the PCI configuration register is
331 returned. This function must guarantee that all PCI read and write operations
332 are serialized. Extra left bits in OrData are stripped.
334 If Address > 0x0FFFFFFF, then ASSERT().
335 If StartBit is greater than 7, then ASSERT().
336 If EndBit is greater than 7, then ASSERT().
337 If EndBit is less than StartBit, then ASSERT().
338 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
340 @param Address The PCI configuration register to write.
341 @param StartBit The ordinal of the least significant bit in the bit field.
343 @param EndBit The ordinal of the most significant bit in the bit field.
345 @param OrData The value to OR with the PCI configuration register.
347 @return The value written back to the PCI configuration register.
352 PciExpressBitFieldOr8 (
359 ASSERT_INVALID_PCI_ADDRESS (Address
);
360 return MmioBitFieldOr8 (
361 (UINTN
) GetPciExpressBaseAddress () + Address
,
369 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
370 AND, and writes the result back to the bit field in the 8-bit register.
372 Reads the 8-bit PCI configuration register specified by Address, performs a
373 bitwise AND between the read result and the value specified by AndData, and
374 writes the result to the 8-bit PCI configuration register specified by
375 Address. The value written to the PCI configuration register is returned.
376 This function must guarantee that all PCI read and write operations are
377 serialized. Extra left bits in AndData are stripped.
379 If Address > 0x0FFFFFFF, then ASSERT().
380 If StartBit is greater than 7, then ASSERT().
381 If EndBit is greater than 7, then ASSERT().
382 If EndBit is less than StartBit, then ASSERT().
383 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
385 @param Address The PCI configuration register to write.
386 @param StartBit The ordinal of the least significant bit in the bit field.
388 @param EndBit The ordinal of the most significant bit in the bit field.
390 @param AndData The value to AND with the PCI configuration register.
392 @return The value written back to the PCI configuration register.
397 PciExpressBitFieldAnd8 (
404 ASSERT_INVALID_PCI_ADDRESS (Address
);
405 return MmioBitFieldAnd8 (
406 (UINTN
) GetPciExpressBaseAddress () + Address
,
414 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
415 bitwise OR, and writes the result back to the bit field in the
418 Reads the 8-bit PCI configuration register specified by Address, performs a
419 bitwise AND followed by a bitwise OR between the read result and
420 the value specified by AndData, and writes the result to the 8-bit PCI
421 configuration register specified by Address. The value written to the PCI
422 configuration register is returned. This function must guarantee that all PCI
423 read and write operations are serialized. Extra left bits in both AndData and
426 If Address > 0x0FFFFFFF, then ASSERT().
427 If StartBit is greater than 7, then ASSERT().
428 If EndBit is greater than 7, then ASSERT().
429 If EndBit is less than StartBit, then ASSERT().
430 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
431 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
433 @param Address The PCI configuration register to write.
434 @param StartBit The ordinal of the least significant bit in the bit field.
436 @param EndBit The ordinal of the most significant bit in the bit field.
438 @param AndData The value to AND with the PCI configuration register.
439 @param OrData The value to OR with the result of the AND operation.
441 @return The value written back to the PCI configuration register.
446 PciExpressBitFieldAndThenOr8 (
454 ASSERT_INVALID_PCI_ADDRESS (Address
);
455 return MmioBitFieldAndThenOr8 (
456 (UINTN
) GetPciExpressBaseAddress () + Address
,
465 Reads a 16-bit PCI configuration register.
467 Reads and returns the 16-bit PCI configuration register specified by Address.
468 This function must guarantee that all PCI read and write operations are
471 If Address > 0x0FFFFFFF, then ASSERT().
472 If Address is not aligned on a 16-bit boundary, then ASSERT().
474 @param Address The address that encodes the PCI Bus, Device, Function and
477 @return The read value from the PCI configuration register.
486 ASSERT_INVALID_PCI_ADDRESS (Address
);
487 return MmioRead16 ((UINTN
) GetPciExpressBaseAddress () + Address
);
491 Writes a 16-bit PCI configuration register.
493 Writes the 16-bit PCI configuration register specified by Address with the
494 value specified by Value. Value is returned. This function must guarantee
495 that all PCI read and write operations are serialized.
497 If Address > 0x0FFFFFFF, then ASSERT().
498 If Address is not aligned on a 16-bit boundary, then ASSERT().
500 @param Address The address that encodes the PCI Bus, Device, Function and
502 @param Value The value to write.
504 @return The value written to the PCI configuration register.
514 ASSERT_INVALID_PCI_ADDRESS (Address
);
515 return MmioWrite16 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
519 Performs a bitwise OR of a 16-bit PCI configuration register with
522 Reads the 16-bit PCI configuration register specified by Address, performs a
523 bitwise OR between the read result and the value specified by
524 OrData, and writes the result to the 16-bit PCI configuration register
525 specified by Address. The value written to the PCI configuration register is
526 returned. This function must guarantee that all PCI read and write operations
529 If Address > 0x0FFFFFFF, then ASSERT().
530 If Address is not aligned on a 16-bit boundary, then ASSERT().
532 @param Address The address that encodes the PCI Bus, Device, Function and
534 @param OrData The value to OR with the PCI configuration register.
536 @return The value written back to the PCI configuration register.
546 ASSERT_INVALID_PCI_ADDRESS (Address
);
547 return MmioOr16 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
551 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
554 Reads the 16-bit PCI configuration register specified by Address, performs a
555 bitwise AND between the read result and the value specified by AndData, and
556 writes the result to the 16-bit PCI configuration register specified by
557 Address. The value written to the PCI configuration register is returned.
558 This function must guarantee that all PCI read and write operations are
561 If Address > 0x0FFFFFFF, then ASSERT().
562 If Address is not aligned on a 16-bit boundary, then ASSERT().
564 @param Address The address that encodes the PCI Bus, Device, Function and
566 @param AndData The value to AND with the PCI configuration register.
568 @return The value written back to the PCI configuration register.
578 ASSERT_INVALID_PCI_ADDRESS (Address
);
579 return MmioAnd16 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
583 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
584 value, followed a bitwise OR with another 16-bit value.
586 Reads the 16-bit PCI configuration register specified by Address, performs a
587 bitwise AND between the read result and the value specified by AndData,
588 performs a bitwise OR between the result of the AND operation and
589 the value specified by OrData, and writes the result to the 16-bit PCI
590 configuration register specified by Address. The value written to the PCI
591 configuration register is returned. This function must guarantee that all PCI
592 read and write operations are serialized.
594 If Address > 0x0FFFFFFF, then ASSERT().
595 If Address is not aligned on a 16-bit boundary, then ASSERT().
597 @param Address The address that encodes the PCI Bus, Device, Function and
599 @param AndData The value to AND with the PCI configuration register.
600 @param OrData The value to OR with the result of the AND operation.
602 @return The value written back to the PCI configuration register.
607 PciExpressAndThenOr16 (
613 ASSERT_INVALID_PCI_ADDRESS (Address
);
614 return MmioAndThenOr16 (
615 (UINTN
) GetPciExpressBaseAddress () + Address
,
622 Reads a bit field of a PCI configuration register.
624 Reads the bit field in a 16-bit PCI configuration register. The bit field is
625 specified by the StartBit and the EndBit. The value of the bit field is
628 If Address > 0x0FFFFFFF, then ASSERT().
629 If Address is not aligned on a 16-bit boundary, then ASSERT().
630 If StartBit is greater than 15, then ASSERT().
631 If EndBit is greater than 15, then ASSERT().
632 If EndBit is less than StartBit, then ASSERT().
634 @param Address The PCI configuration register to read.
635 @param StartBit The ordinal of the least significant bit in the bit field.
637 @param EndBit The ordinal of the most significant bit in the bit field.
640 @return The value of the bit field read from the PCI configuration register.
645 PciExpressBitFieldRead16 (
651 ASSERT_INVALID_PCI_ADDRESS (Address
);
652 return MmioBitFieldRead16 (
653 (UINTN
) GetPciExpressBaseAddress () + Address
,
660 Writes a bit field to a PCI configuration register.
662 Writes Value to the bit field of the PCI configuration register. The bit
663 field is specified by the StartBit and the EndBit. All other bits in the
664 destination PCI configuration register are preserved. The new value of the
665 16-bit register is returned.
667 If Address > 0x0FFFFFFF, then ASSERT().
668 If Address is not aligned on a 16-bit boundary, then ASSERT().
669 If StartBit is greater than 15, then ASSERT().
670 If EndBit is greater than 15, then ASSERT().
671 If EndBit is less than StartBit, then ASSERT().
672 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
674 @param Address The PCI configuration register to write.
675 @param StartBit The ordinal of the least significant bit in the bit field.
677 @param EndBit The ordinal of the most significant bit in the bit field.
679 @param Value The new value of the bit field.
681 @return The value written back to the PCI configuration register.
686 PciExpressBitFieldWrite16 (
693 ASSERT_INVALID_PCI_ADDRESS (Address
);
694 return MmioBitFieldWrite16 (
695 (UINTN
) GetPciExpressBaseAddress () + Address
,
703 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
704 writes the result back to the bit field in the 16-bit port.
706 Reads the 16-bit PCI configuration register specified by Address, performs a
707 bitwise OR between the read result and the value specified by
708 OrData, and writes the result to the 16-bit PCI configuration register
709 specified by Address. The value written to the PCI configuration register is
710 returned. This function must guarantee that all PCI read and write operations
711 are serialized. Extra left bits in OrData are stripped.
713 If Address > 0x0FFFFFFF, then ASSERT().
714 If Address is not aligned on a 16-bit boundary, then ASSERT().
715 If StartBit is greater than 15, then ASSERT().
716 If EndBit is greater than 15, then ASSERT().
717 If EndBit is less than StartBit, then ASSERT().
718 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
720 @param Address The PCI configuration register to write.
721 @param StartBit The ordinal of the least significant bit in the bit field.
723 @param EndBit The ordinal of the most significant bit in the bit field.
725 @param OrData The value to OR with the PCI configuration register.
727 @return The value written back to the PCI configuration register.
732 PciExpressBitFieldOr16 (
739 ASSERT_INVALID_PCI_ADDRESS (Address
);
740 return MmioBitFieldOr16 (
741 (UINTN
) GetPciExpressBaseAddress () + Address
,
749 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
750 AND, and writes the result back to the bit field in the 16-bit register.
752 Reads the 16-bit PCI configuration register specified by Address, performs a
753 bitwise AND between the read result and the value specified by AndData, and
754 writes the result to the 16-bit PCI configuration register specified by
755 Address. The value written to the PCI configuration register is returned.
756 This function must guarantee that all PCI read and write operations are
757 serialized. Extra left bits in AndData are stripped.
759 If Address > 0x0FFFFFFF, then ASSERT().
760 If Address is not aligned on a 16-bit boundary, then ASSERT().
761 If StartBit is greater than 15, then ASSERT().
762 If EndBit is greater than 15, then ASSERT().
763 If EndBit is less than StartBit, then ASSERT().
764 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
766 @param Address The PCI configuration register to write.
767 @param StartBit The ordinal of the least significant bit in the bit field.
769 @param EndBit The ordinal of the most significant bit in the bit field.
771 @param AndData The value to AND with the PCI configuration register.
773 @return The value written back to the PCI configuration register.
778 PciExpressBitFieldAnd16 (
785 ASSERT_INVALID_PCI_ADDRESS (Address
);
786 return MmioBitFieldAnd16 (
787 (UINTN
) GetPciExpressBaseAddress () + Address
,
795 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
796 bitwise OR, and writes the result back to the bit field in the
799 Reads the 16-bit PCI configuration register specified by Address, performs a
800 bitwise AND followed by a bitwise OR between the read result and
801 the value specified by AndData, and writes the result to the 16-bit PCI
802 configuration register specified by Address. The value written to the PCI
803 configuration register is returned. This function must guarantee that all PCI
804 read and write operations are serialized. Extra left bits in both AndData and
807 If Address > 0x0FFFFFFF, then ASSERT().
808 If Address is not aligned on a 16-bit boundary, then ASSERT().
809 If StartBit is greater than 15, then ASSERT().
810 If EndBit is greater than 15, then ASSERT().
811 If EndBit is less than StartBit, then ASSERT().
812 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
813 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
815 @param Address The PCI configuration register to write.
816 @param StartBit The ordinal of the least significant bit in the bit field.
818 @param EndBit The ordinal of the most significant bit in the bit field.
820 @param AndData The value to AND with the PCI configuration register.
821 @param OrData The value to OR with the result of the AND operation.
823 @return The value written back to the PCI configuration register.
828 PciExpressBitFieldAndThenOr16 (
836 ASSERT_INVALID_PCI_ADDRESS (Address
);
837 return MmioBitFieldAndThenOr16 (
838 (UINTN
) GetPciExpressBaseAddress () + Address
,
847 Reads a 32-bit PCI configuration register.
849 Reads and returns the 32-bit PCI configuration register specified by Address.
850 This function must guarantee that all PCI read and write operations are
853 If Address > 0x0FFFFFFF, then ASSERT().
854 If Address is not aligned on a 32-bit boundary, then ASSERT().
856 @param Address The address that encodes the PCI Bus, Device, Function and
859 @return The read value from the PCI configuration register.
868 ASSERT_INVALID_PCI_ADDRESS (Address
);
869 return MmioRead32 ((UINTN
) GetPciExpressBaseAddress () + Address
);
873 Writes a 32-bit PCI configuration register.
875 Writes the 32-bit PCI configuration register specified by Address with the
876 value specified by Value. Value is returned. This function must guarantee
877 that all PCI read and write operations are serialized.
879 If Address > 0x0FFFFFFF, then ASSERT().
880 If Address is not aligned on a 32-bit boundary, then ASSERT().
882 @param Address The address that encodes the PCI Bus, Device, Function and
884 @param Value The value to write.
886 @return The value written to the PCI configuration register.
896 ASSERT_INVALID_PCI_ADDRESS (Address
);
897 return MmioWrite32 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
901 Performs a bitwise OR of a 32-bit PCI configuration register with
904 Reads the 32-bit PCI configuration register specified by Address, performs a
905 bitwise OR between the read result and the value specified by
906 OrData, and writes the result to the 32-bit PCI configuration register
907 specified by Address. The value written to the PCI configuration register is
908 returned. This function must guarantee that all PCI read and write operations
911 If Address > 0x0FFFFFFF, then ASSERT().
912 If Address is not aligned on a 32-bit boundary, then ASSERT().
914 @param Address The address that encodes the PCI Bus, Device, Function and
916 @param OrData The value to OR with the PCI configuration register.
918 @return The value written back to the PCI configuration register.
928 ASSERT_INVALID_PCI_ADDRESS (Address
);
929 return MmioOr32 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
933 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
936 Reads the 32-bit PCI configuration register specified by Address, performs a
937 bitwise AND between the read result and the value specified by AndData, and
938 writes the result to the 32-bit PCI configuration register specified by
939 Address. The value written to the PCI configuration register is returned.
940 This function must guarantee that all PCI read and write operations are
943 If Address > 0x0FFFFFFF, then ASSERT().
944 If Address is not aligned on a 32-bit boundary, then ASSERT().
946 @param Address The address that encodes the PCI Bus, Device, Function and
948 @param AndData The value to AND with the PCI configuration register.
950 @return The value written back to the PCI configuration register.
960 ASSERT_INVALID_PCI_ADDRESS (Address
);
961 return MmioAnd32 ((UINTN
) GetPciExpressBaseAddress () + 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 ASSERT_INVALID_PCI_ADDRESS (Address
);
996 return MmioAndThenOr32 (
997 (UINTN
) GetPciExpressBaseAddress () + Address
,
1004 Reads a bit field of a PCI configuration register.
1006 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1007 specified by the StartBit and the EndBit. The value of the bit field is
1010 If Address > 0x0FFFFFFF, then ASSERT().
1011 If Address is not aligned on a 32-bit boundary, then ASSERT().
1012 If StartBit is greater than 31, then ASSERT().
1013 If EndBit is greater than 31, then ASSERT().
1014 If EndBit is less than StartBit, then ASSERT().
1016 @param Address The PCI configuration register to read.
1017 @param StartBit The ordinal of the least significant bit in the bit field.
1019 @param EndBit The ordinal of the most significant bit in the bit field.
1022 @return The value of the bit field read from the PCI configuration register.
1027 PciExpressBitFieldRead32 (
1033 ASSERT_INVALID_PCI_ADDRESS (Address
);
1034 return MmioBitFieldRead32 (
1035 (UINTN
) GetPciExpressBaseAddress () + Address
,
1042 Writes a bit field to a PCI configuration register.
1044 Writes Value to the bit field of the PCI configuration register. The bit
1045 field is specified by the StartBit and the EndBit. All other bits in the
1046 destination PCI configuration register are preserved. The new value of the
1047 32-bit register is returned.
1049 If Address > 0x0FFFFFFF, then ASSERT().
1050 If Address is not aligned on a 32-bit boundary, then ASSERT().
1051 If StartBit is greater than 31, then ASSERT().
1052 If EndBit is greater than 31, then ASSERT().
1053 If EndBit is less than StartBit, then ASSERT().
1054 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1056 @param Address The PCI configuration register to write.
1057 @param StartBit The ordinal of the least significant bit in the bit field.
1059 @param EndBit The ordinal of the most significant bit in the bit field.
1061 @param Value The new value of the bit field.
1063 @return The value written back to the PCI configuration register.
1068 PciExpressBitFieldWrite32 (
1075 ASSERT_INVALID_PCI_ADDRESS (Address
);
1076 return MmioBitFieldWrite32 (
1077 (UINTN
) GetPciExpressBaseAddress () + Address
,
1085 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1086 writes the result back to the bit field in the 32-bit port.
1088 Reads the 32-bit PCI configuration register specified by Address, performs a
1089 bitwise OR between the read result and the value specified by
1090 OrData, and writes the result to the 32-bit PCI configuration register
1091 specified by Address. The value written to the PCI configuration register is
1092 returned. This function must guarantee that all PCI read and write operations
1093 are serialized. Extra left bits in OrData are stripped.
1095 If Address > 0x0FFFFFFF, then ASSERT().
1096 If Address is not aligned on a 32-bit boundary, then ASSERT().
1097 If StartBit is greater than 31, then ASSERT().
1098 If EndBit is greater than 31, then ASSERT().
1099 If EndBit is less than StartBit, then ASSERT().
1100 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1102 @param Address The PCI configuration register to write.
1103 @param StartBit The ordinal of the least significant bit in the bit field.
1105 @param EndBit The ordinal of the most significant bit in the bit field.
1107 @param OrData The value to OR with the PCI configuration register.
1109 @return The value written back to the PCI configuration register.
1114 PciExpressBitFieldOr32 (
1121 ASSERT_INVALID_PCI_ADDRESS (Address
);
1122 return MmioBitFieldOr32 (
1123 (UINTN
) GetPciExpressBaseAddress () + Address
,
1131 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1132 AND, and writes the result back to the bit field in the 32-bit register.
1134 Reads the 32-bit PCI configuration register specified by Address, performs a
1135 bitwise AND between the read result and the value specified by AndData, and
1136 writes the result to the 32-bit PCI configuration register specified by
1137 Address. The value written to the PCI configuration register is returned.
1138 This function must guarantee that all PCI read and write operations are
1139 serialized. Extra left bits in AndData are stripped.
1141 If Address > 0x0FFFFFFF, then ASSERT().
1142 If Address is not aligned on a 32-bit boundary, then ASSERT().
1143 If StartBit is greater than 31, then ASSERT().
1144 If EndBit is greater than 31, then ASSERT().
1145 If EndBit is less than StartBit, then ASSERT().
1146 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1148 @param Address The PCI configuration register to write.
1149 @param StartBit The ordinal of the least significant bit in the bit field.
1151 @param EndBit The ordinal of the most significant bit in the bit field.
1153 @param AndData The value to AND with the PCI configuration register.
1155 @return The value written back to the PCI configuration register.
1160 PciExpressBitFieldAnd32 (
1167 ASSERT_INVALID_PCI_ADDRESS (Address
);
1168 return MmioBitFieldAnd32 (
1169 (UINTN
) GetPciExpressBaseAddress () + Address
,
1177 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1178 bitwise OR, and writes the result back to the bit field in the
1181 Reads the 32-bit PCI configuration register specified by Address, performs a
1182 bitwise AND followed by a bitwise OR between the read result and
1183 the value specified by AndData, and writes the result to the 32-bit PCI
1184 configuration register specified by Address. The value written to the PCI
1185 configuration register is returned. This function must guarantee that all PCI
1186 read and write operations are serialized. Extra left bits in both AndData and
1187 OrData are stripped.
1189 If Address > 0x0FFFFFFF, then ASSERT().
1190 If Address is not aligned on a 32-bit boundary, then ASSERT().
1191 If StartBit is greater than 31, then ASSERT().
1192 If EndBit is greater than 31, then ASSERT().
1193 If EndBit is less than StartBit, then ASSERT().
1194 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1195 If OrData 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 AndData The value to AND with the PCI configuration register.
1203 @param OrData The value to OR with the result of the AND operation.
1205 @return The value written back to the PCI configuration register.
1210 PciExpressBitFieldAndThenOr32 (
1218 ASSERT_INVALID_PCI_ADDRESS (Address
);
1219 return MmioBitFieldAndThenOr32 (
1220 (UINTN
) GetPciExpressBaseAddress () + Address
,
1229 Reads a range of PCI configuration registers into a caller supplied buffer.
1231 Reads the range of PCI configuration registers specified by StartAddress and
1232 Size into the buffer specified by Buffer. This function only allows the PCI
1233 configuration registers from a single PCI function to be read. Size is
1234 returned. When possible 32-bit PCI configuration read cycles are used to read
1235 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit
1236 and 16-bit PCI configuration read cycles may be used at the beginning and the
1239 If StartAddress > 0x0FFFFFFF, then ASSERT().
1240 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1241 If Size > 0 and Buffer is NULL, then ASSERT().
1243 @param StartAddress The starting address that encodes the PCI Bus, Device,
1244 Function and Register.
1245 @param Size The size in bytes of the transfer.
1246 @param Buffer The pointer to a buffer receiving the data read.
1248 @return Size read data from StartAddress.
1253 PciExpressReadBuffer (
1254 IN UINTN StartAddress
,
1261 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1262 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1268 ASSERT (Buffer
!= NULL
);
1271 // Save Size for return
1275 if ((StartAddress
& 1) != 0) {
1277 // Read a byte if StartAddress is byte aligned
1279 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1280 StartAddress
+= sizeof (UINT8
);
1281 Size
-= sizeof (UINT8
);
1282 Buffer
= (UINT8
*)Buffer
+ 1;
1285 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1287 // Read a word if StartAddress is word aligned
1289 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1291 StartAddress
+= sizeof (UINT16
);
1292 Size
-= sizeof (UINT16
);
1293 Buffer
= (UINT16
*)Buffer
+ 1;
1296 while (Size
>= sizeof (UINT32
)) {
1298 // Read as many double words as possible
1300 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1302 StartAddress
+= sizeof (UINT32
);
1303 Size
-= sizeof (UINT32
);
1304 Buffer
= (UINT32
*)Buffer
+ 1;
1307 if (Size
>= sizeof (UINT16
)) {
1309 // Read the last remaining word if exist
1311 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1312 StartAddress
+= sizeof (UINT16
);
1313 Size
-= sizeof (UINT16
);
1314 Buffer
= (UINT16
*)Buffer
+ 1;
1317 if (Size
>= sizeof (UINT8
)) {
1319 // Read the last remaining byte if exist
1321 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1328 Copies the data in a caller supplied buffer to a specified range of PCI
1329 configuration space.
1331 Writes the range of PCI configuration registers specified by StartAddress and
1332 Size from the buffer specified by Buffer. This function only allows the PCI
1333 configuration registers from a single PCI function to be written. Size is
1334 returned. When possible 32-bit PCI configuration write cycles are used to
1335 write from StartAddress to StartAddress + Size. Due to alignment restrictions,
1336 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1337 and the end of the range.
1339 If StartAddress > 0x0FFFFFFF, then ASSERT().
1340 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1341 If Size > 0 and Buffer is NULL, then ASSERT().
1343 @param StartAddress The starting address that encodes the PCI Bus, Device,
1344 Function and Register.
1345 @param Size The size in bytes of the transfer.
1346 @param Buffer The pointer to a buffer containing the data to write.
1348 @return Size written to StartAddress.
1353 PciExpressWriteBuffer (
1354 IN UINTN StartAddress
,
1361 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1362 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1368 ASSERT (Buffer
!= NULL
);
1371 // Save Size for return
1375 if ((StartAddress
& 1) != 0) {
1377 // Write a byte if StartAddress is byte aligned
1379 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1380 StartAddress
+= sizeof (UINT8
);
1381 Size
-= sizeof (UINT8
);
1382 Buffer
= (UINT8
*)Buffer
+ 1;
1385 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1387 // Write a word if StartAddress is word aligned
1389 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1390 StartAddress
+= sizeof (UINT16
);
1391 Size
-= sizeof (UINT16
);
1392 Buffer
= (UINT16
*)Buffer
+ 1;
1395 while (Size
>= sizeof (UINT32
)) {
1397 // Write as many double words as possible
1399 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1400 StartAddress
+= sizeof (UINT32
);
1401 Size
-= sizeof (UINT32
);
1402 Buffer
= (UINT32
*)Buffer
+ 1;
1405 if (Size
>= sizeof (UINT16
)) {
1407 // Write the last remaining word if exist
1409 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1410 StartAddress
+= sizeof (UINT16
);
1411 Size
-= sizeof (UINT16
);
1412 Buffer
= (UINT16
*)Buffer
+ 1;
1415 if (Size
>= sizeof (UINT8
)) {
1417 // Write the last remaining byte if exist
1419 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);