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 - 2018, 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
;
66 Gets the base address of PCI Express.
68 This internal functions retrieves PCI Express Base Address via a PCD entry
69 PcdPciExpressBaseAddress.
71 @return The base address of PCI Express.
75 GetPciExpressBaseAddress (
79 return (VOID
*)(UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
83 Reads an 8-bit PCI configuration register.
85 Reads and returns the 8-bit PCI configuration register specified by Address.
86 This function must guarantee that all PCI read and write operations are
89 If Address > 0x0FFFFFFF, then ASSERT().
91 @param Address The address that encodes the PCI Bus, Device, Function and
94 @return The read value from the PCI configuration register.
103 ASSERT_INVALID_PCI_ADDRESS (Address
);
104 return MmioRead8 ((UINTN
) GetPciExpressBaseAddress () + Address
);
108 Writes an 8-bit PCI configuration register.
110 Writes the 8-bit PCI configuration register specified by Address with the
111 value specified by Value. Value is returned. This function must guarantee
112 that all PCI read and write operations are serialized.
114 If Address > 0x0FFFFFFF, then ASSERT().
116 @param Address The address that encodes the PCI Bus, Device, Function and
118 @param Value The value to write.
120 @return The value written to the PCI configuration register.
130 ASSERT_INVALID_PCI_ADDRESS (Address
);
131 return MmioWrite8 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
135 Performs a bitwise OR of an 8-bit PCI configuration register with
138 Reads the 8-bit PCI configuration register specified by Address, performs a
139 bitwise OR between the read result and the value specified by
140 OrData, and writes the result to the 8-bit PCI configuration register
141 specified by Address. The value written to the PCI configuration register is
142 returned. This function must guarantee that all PCI read and write operations
145 If Address > 0x0FFFFFFF, then ASSERT().
147 @param Address The address that encodes the PCI Bus, Device, Function and
149 @param OrData The value to OR with the PCI configuration register.
151 @return The value written back to the PCI configuration register.
161 ASSERT_INVALID_PCI_ADDRESS (Address
);
162 return MmioOr8 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
166 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
169 Reads the 8-bit PCI configuration register specified by Address, performs a
170 bitwise AND between the read result and the value specified by AndData, and
171 writes the result to the 8-bit PCI configuration register specified by
172 Address. The value written to the PCI configuration register is returned.
173 This function must guarantee that all PCI read and write operations are
176 If Address > 0x0FFFFFFF, then ASSERT().
178 @param Address The address that encodes the PCI Bus, Device, Function and
180 @param AndData The value to AND with the PCI configuration register.
182 @return The value written back to the PCI configuration register.
192 ASSERT_INVALID_PCI_ADDRESS (Address
);
193 return MmioAnd8 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
197 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
198 value, followed a bitwise OR with another 8-bit value.
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,
202 performs a bitwise OR between the result of the AND operation and
203 the value specified by OrData, and writes the result to the 8-bit PCI
204 configuration register specified by Address. The value written to the PCI
205 configuration register is returned. This function must guarantee that all PCI
206 read and write operations are serialized.
208 If Address > 0x0FFFFFFF, then ASSERT().
210 @param Address The address that encodes the PCI Bus, Device, Function and
212 @param AndData The value to AND with the PCI configuration register.
213 @param OrData The value to OR with the result of the AND operation.
215 @return The value written back to the PCI configuration register.
220 PciExpressAndThenOr8 (
226 ASSERT_INVALID_PCI_ADDRESS (Address
);
227 return MmioAndThenOr8 (
228 (UINTN
) GetPciExpressBaseAddress () + Address
,
235 Reads a bit field of a PCI configuration register.
237 Reads the bit field in an 8-bit PCI configuration register. The bit field is
238 specified by the StartBit and the EndBit. The value of the bit field is
241 If Address > 0x0FFFFFFF, then ASSERT().
242 If StartBit is greater than 7, then ASSERT().
243 If EndBit is greater than 7, then ASSERT().
244 If EndBit is less than StartBit, then ASSERT().
246 @param Address The PCI configuration register to read.
247 @param StartBit The ordinal of the least significant bit in the bit field.
249 @param EndBit The ordinal of the most significant bit in the bit field.
252 @return The value of the bit field read from the PCI configuration register.
257 PciExpressBitFieldRead8 (
263 ASSERT_INVALID_PCI_ADDRESS (Address
);
264 return MmioBitFieldRead8 (
265 (UINTN
) GetPciExpressBaseAddress () + Address
,
272 Writes a bit field to a PCI configuration register.
274 Writes Value to the bit field of the PCI configuration register. The bit
275 field is specified by the StartBit and the EndBit. All other bits in the
276 destination PCI configuration register are preserved. The new value of the
277 8-bit register is returned.
279 If Address > 0x0FFFFFFF, then ASSERT().
280 If StartBit is greater than 7, then ASSERT().
281 If EndBit is greater than 7, then ASSERT().
282 If EndBit is less than StartBit, then ASSERT().
283 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
285 @param Address The PCI configuration register to write.
286 @param StartBit The ordinal of the least significant bit in the bit field.
288 @param EndBit The ordinal of the most significant bit in the bit field.
290 @param Value The new value of the bit field.
292 @return The value written back to the PCI configuration register.
297 PciExpressBitFieldWrite8 (
304 ASSERT_INVALID_PCI_ADDRESS (Address
);
305 return MmioBitFieldWrite8 (
306 (UINTN
) GetPciExpressBaseAddress () + Address
,
314 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
315 writes the result back to the bit field in the 8-bit port.
317 Reads the 8-bit PCI configuration register specified by Address, performs a
318 bitwise OR between the read result and the value specified by
319 OrData, and writes the result to the 8-bit PCI configuration register
320 specified by Address. The value written to the PCI configuration register is
321 returned. This function must guarantee that all PCI read and write operations
322 are serialized. Extra left bits in OrData are stripped.
324 If Address > 0x0FFFFFFF, then ASSERT().
325 If StartBit is greater than 7, then ASSERT().
326 If EndBit is greater than 7, then ASSERT().
327 If EndBit is less than StartBit, then ASSERT().
328 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
330 @param Address The PCI configuration register to write.
331 @param StartBit The ordinal of the least significant bit in the bit field.
333 @param EndBit The ordinal of the most significant bit in the bit field.
335 @param OrData The value to OR with the PCI configuration register.
337 @return The value written back to the PCI configuration register.
342 PciExpressBitFieldOr8 (
349 ASSERT_INVALID_PCI_ADDRESS (Address
);
350 return MmioBitFieldOr8 (
351 (UINTN
) GetPciExpressBaseAddress () + Address
,
359 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
360 AND, and writes the result back to the bit field in the 8-bit register.
362 Reads the 8-bit PCI configuration register specified by Address, performs a
363 bitwise AND between the read result and the value specified by AndData, and
364 writes the result to the 8-bit PCI configuration register specified by
365 Address. The value written to the PCI configuration register is returned.
366 This function must guarantee that all PCI read and write operations are
367 serialized. Extra left bits in AndData are stripped.
369 If Address > 0x0FFFFFFF, then ASSERT().
370 If StartBit is greater than 7, then ASSERT().
371 If EndBit is greater than 7, then ASSERT().
372 If EndBit is less than StartBit, then ASSERT().
373 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
375 @param Address The PCI configuration register to write.
376 @param StartBit The ordinal of the least significant bit in the bit field.
378 @param EndBit The ordinal of the most significant bit in the bit field.
380 @param AndData The value to AND with the PCI configuration register.
382 @return The value written back to the PCI configuration register.
387 PciExpressBitFieldAnd8 (
394 ASSERT_INVALID_PCI_ADDRESS (Address
);
395 return MmioBitFieldAnd8 (
396 (UINTN
) GetPciExpressBaseAddress () + Address
,
404 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
405 bitwise OR, and writes the result back to the bit field in the
408 Reads the 8-bit PCI configuration register specified by Address, performs a
409 bitwise AND followed by a bitwise OR between the read result and
410 the value specified by AndData, and writes the result to the 8-bit PCI
411 configuration register specified by Address. The value written to the PCI
412 configuration register is returned. This function must guarantee that all PCI
413 read and write operations are serialized. Extra left bits in both AndData and
416 If Address > 0x0FFFFFFF, then ASSERT().
417 If StartBit is greater than 7, then ASSERT().
418 If EndBit is greater than 7, then ASSERT().
419 If EndBit is less than StartBit, then ASSERT().
420 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
421 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
423 @param Address The PCI configuration register to write.
424 @param StartBit The ordinal of the least significant bit in the bit field.
426 @param EndBit The ordinal of the most significant bit in the bit field.
428 @param AndData The value to AND with the PCI configuration register.
429 @param OrData The value to OR with the result of the AND operation.
431 @return The value written back to the PCI configuration register.
436 PciExpressBitFieldAndThenOr8 (
444 ASSERT_INVALID_PCI_ADDRESS (Address
);
445 return MmioBitFieldAndThenOr8 (
446 (UINTN
) GetPciExpressBaseAddress () + Address
,
455 Reads a 16-bit PCI configuration register.
457 Reads and returns the 16-bit PCI configuration register specified by Address.
458 This function must guarantee that all PCI read and write operations are
461 If Address > 0x0FFFFFFF, then ASSERT().
462 If Address is not aligned on a 16-bit boundary, then ASSERT().
464 @param Address The address that encodes the PCI Bus, Device, Function and
467 @return The read value from the PCI configuration register.
476 ASSERT_INVALID_PCI_ADDRESS (Address
);
477 return MmioRead16 ((UINTN
) GetPciExpressBaseAddress () + Address
);
481 Writes a 16-bit PCI configuration register.
483 Writes the 16-bit PCI configuration register specified by Address with the
484 value specified by Value. Value is returned. This function must guarantee
485 that all PCI read and write operations are serialized.
487 If Address > 0x0FFFFFFF, then ASSERT().
488 If Address is not aligned on a 16-bit boundary, then ASSERT().
490 @param Address The address that encodes the PCI Bus, Device, Function and
492 @param Value The value to write.
494 @return The value written to the PCI configuration register.
504 ASSERT_INVALID_PCI_ADDRESS (Address
);
505 return MmioWrite16 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
509 Performs a bitwise OR of a 16-bit PCI configuration register with
512 Reads the 16-bit PCI configuration register specified by Address, performs a
513 bitwise OR between the read result and the value specified by
514 OrData, and writes the result to the 16-bit PCI configuration register
515 specified by Address. The value written to the PCI configuration register is
516 returned. This function must guarantee that all PCI read and write operations
519 If Address > 0x0FFFFFFF, then ASSERT().
520 If Address is not aligned on a 16-bit boundary, then ASSERT().
522 @param Address The address that encodes the PCI Bus, Device, Function and
524 @param OrData The value to OR with the PCI configuration register.
526 @return The value written back to the PCI configuration register.
536 ASSERT_INVALID_PCI_ADDRESS (Address
);
537 return MmioOr16 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
541 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
544 Reads the 16-bit PCI configuration register specified by Address, performs a
545 bitwise AND between the read result and the value specified by AndData, and
546 writes the result to the 16-bit PCI configuration register specified by
547 Address. The value written to the PCI configuration register is returned.
548 This function must guarantee that all PCI read and write operations are
551 If Address > 0x0FFFFFFF, then ASSERT().
552 If Address is not aligned on a 16-bit boundary, then ASSERT().
554 @param Address The address that encodes the PCI Bus, Device, Function and
556 @param AndData The value to AND with the PCI configuration register.
558 @return The value written back to the PCI configuration register.
568 ASSERT_INVALID_PCI_ADDRESS (Address
);
569 return MmioAnd16 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
573 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
574 value, followed a bitwise OR with another 16-bit value.
576 Reads the 16-bit PCI configuration register specified by Address, performs a
577 bitwise AND between the read result and the value specified by AndData,
578 performs a bitwise OR between the result of the AND operation and
579 the value specified by OrData, and writes the result to the 16-bit PCI
580 configuration register specified by Address. The value written to the PCI
581 configuration register is returned. This function must guarantee that all PCI
582 read and write operations are serialized.
584 If Address > 0x0FFFFFFF, then ASSERT().
585 If Address is not aligned on a 16-bit boundary, then ASSERT().
587 @param Address The address that encodes the PCI Bus, Device, Function and
589 @param AndData The value to AND with the PCI configuration register.
590 @param OrData The value to OR with the result of the AND operation.
592 @return The value written back to the PCI configuration register.
597 PciExpressAndThenOr16 (
603 ASSERT_INVALID_PCI_ADDRESS (Address
);
604 return MmioAndThenOr16 (
605 (UINTN
) GetPciExpressBaseAddress () + Address
,
612 Reads a bit field of a PCI configuration register.
614 Reads the bit field in a 16-bit PCI configuration register. The bit field is
615 specified by the StartBit and the EndBit. The value of the bit field is
618 If Address > 0x0FFFFFFF, then ASSERT().
619 If Address is not aligned on a 16-bit boundary, then ASSERT().
620 If StartBit is greater than 15, then ASSERT().
621 If EndBit is greater than 15, then ASSERT().
622 If EndBit is less than StartBit, then ASSERT().
624 @param Address The PCI configuration register to read.
625 @param StartBit The ordinal of the least significant bit in the bit field.
627 @param EndBit The ordinal of the most significant bit in the bit field.
630 @return The value of the bit field read from the PCI configuration register.
635 PciExpressBitFieldRead16 (
641 ASSERT_INVALID_PCI_ADDRESS (Address
);
642 return MmioBitFieldRead16 (
643 (UINTN
) GetPciExpressBaseAddress () + Address
,
650 Writes a bit field to a PCI configuration register.
652 Writes Value to the bit field of the PCI configuration register. The bit
653 field is specified by the StartBit and the EndBit. All other bits in the
654 destination PCI configuration register are preserved. The new value of the
655 16-bit register is returned.
657 If Address > 0x0FFFFFFF, then ASSERT().
658 If Address is not aligned on a 16-bit boundary, then ASSERT().
659 If StartBit is greater than 15, then ASSERT().
660 If EndBit is greater than 15, then ASSERT().
661 If EndBit is less than StartBit, then ASSERT().
662 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
664 @param Address The PCI configuration register to write.
665 @param StartBit The ordinal of the least significant bit in the bit field.
667 @param EndBit The ordinal of the most significant bit in the bit field.
669 @param Value The new value of the bit field.
671 @return The value written back to the PCI configuration register.
676 PciExpressBitFieldWrite16 (
683 ASSERT_INVALID_PCI_ADDRESS (Address
);
684 return MmioBitFieldWrite16 (
685 (UINTN
) GetPciExpressBaseAddress () + Address
,
693 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
694 writes the result back to the bit field in the 16-bit port.
696 Reads the 16-bit PCI configuration register specified by Address, performs a
697 bitwise OR between the read result and the value specified by
698 OrData, and writes the result to the 16-bit PCI configuration register
699 specified by Address. The value written to the PCI configuration register is
700 returned. This function must guarantee that all PCI read and write operations
701 are serialized. Extra left bits in OrData are stripped.
703 If Address > 0x0FFFFFFF, then ASSERT().
704 If Address is not aligned on a 16-bit boundary, then ASSERT().
705 If StartBit is greater than 15, then ASSERT().
706 If EndBit is greater than 15, then ASSERT().
707 If EndBit is less than StartBit, then ASSERT().
708 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
710 @param Address The PCI configuration register to write.
711 @param StartBit The ordinal of the least significant bit in the bit field.
713 @param EndBit The ordinal of the most significant bit in the bit field.
715 @param OrData The value to OR with the PCI configuration register.
717 @return The value written back to the PCI configuration register.
722 PciExpressBitFieldOr16 (
729 ASSERT_INVALID_PCI_ADDRESS (Address
);
730 return MmioBitFieldOr16 (
731 (UINTN
) GetPciExpressBaseAddress () + Address
,
739 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
740 AND, and writes the result back to the bit field in the 16-bit register.
742 Reads the 16-bit PCI configuration register specified by Address, performs a
743 bitwise AND between the read result and the value specified by AndData, and
744 writes the result to the 16-bit PCI configuration register specified by
745 Address. The value written to the PCI configuration register is returned.
746 This function must guarantee that all PCI read and write operations are
747 serialized. Extra left bits in AndData are stripped.
749 If Address > 0x0FFFFFFF, then ASSERT().
750 If Address is not aligned on a 16-bit boundary, then ASSERT().
751 If StartBit is greater than 15, then ASSERT().
752 If EndBit is greater than 15, then ASSERT().
753 If EndBit is less than StartBit, then ASSERT().
754 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
756 @param Address The PCI configuration register to write.
757 @param StartBit The ordinal of the least significant bit in the bit field.
759 @param EndBit The ordinal of the most significant bit in the bit field.
761 @param AndData The value to AND with the PCI configuration register.
763 @return The value written back to the PCI configuration register.
768 PciExpressBitFieldAnd16 (
775 ASSERT_INVALID_PCI_ADDRESS (Address
);
776 return MmioBitFieldAnd16 (
777 (UINTN
) GetPciExpressBaseAddress () + Address
,
785 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
786 bitwise OR, and writes the result back to the bit field in the
789 Reads the 16-bit PCI configuration register specified by Address, performs a
790 bitwise AND followed by a bitwise OR between the read result and
791 the value specified by AndData, and writes the result to the 16-bit PCI
792 configuration register specified by Address. The value written to the PCI
793 configuration register is returned. This function must guarantee that all PCI
794 read and write operations are serialized. Extra left bits in both AndData and
797 If Address > 0x0FFFFFFF, then ASSERT().
798 If Address is not aligned on a 16-bit boundary, then ASSERT().
799 If StartBit is greater than 15, then ASSERT().
800 If EndBit is greater than 15, then ASSERT().
801 If EndBit is less than StartBit, then ASSERT().
802 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
803 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
805 @param Address The PCI configuration register to write.
806 @param StartBit The ordinal of the least significant bit in the bit field.
808 @param EndBit The ordinal of the most significant bit in the bit field.
810 @param AndData The value to AND with the PCI configuration register.
811 @param OrData The value to OR with the result of the AND operation.
813 @return The value written back to the PCI configuration register.
818 PciExpressBitFieldAndThenOr16 (
826 ASSERT_INVALID_PCI_ADDRESS (Address
);
827 return MmioBitFieldAndThenOr16 (
828 (UINTN
) GetPciExpressBaseAddress () + Address
,
837 Reads a 32-bit PCI configuration register.
839 Reads and returns the 32-bit PCI configuration register specified by Address.
840 This function must guarantee that all PCI read and write operations are
843 If Address > 0x0FFFFFFF, then ASSERT().
844 If Address is not aligned on a 32-bit boundary, then ASSERT().
846 @param Address The address that encodes the PCI Bus, Device, Function and
849 @return The read value from the PCI configuration register.
858 ASSERT_INVALID_PCI_ADDRESS (Address
);
859 return MmioRead32 ((UINTN
) GetPciExpressBaseAddress () + Address
);
863 Writes a 32-bit PCI configuration register.
865 Writes the 32-bit PCI configuration register specified by Address with the
866 value specified by Value. Value is returned. This function must guarantee
867 that all PCI read and write operations are serialized.
869 If Address > 0x0FFFFFFF, then ASSERT().
870 If Address is not aligned on a 32-bit boundary, then ASSERT().
872 @param Address The address that encodes the PCI Bus, Device, Function and
874 @param Value The value to write.
876 @return The value written to the PCI configuration register.
886 ASSERT_INVALID_PCI_ADDRESS (Address
);
887 return MmioWrite32 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
891 Performs a bitwise OR of a 32-bit PCI configuration register with
894 Reads the 32-bit PCI configuration register specified by Address, performs a
895 bitwise OR between the read result and the value specified by
896 OrData, and writes the result to the 32-bit PCI configuration register
897 specified by Address. The value written to the PCI configuration register is
898 returned. This function must guarantee that all PCI read and write operations
901 If Address > 0x0FFFFFFF, then ASSERT().
902 If Address is not aligned on a 32-bit boundary, then ASSERT().
904 @param Address The address that encodes the PCI Bus, Device, Function and
906 @param OrData The value to OR with the PCI configuration register.
908 @return The value written back to the PCI configuration register.
918 ASSERT_INVALID_PCI_ADDRESS (Address
);
919 return MmioOr32 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
923 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
926 Reads the 32-bit PCI configuration register specified by Address, performs a
927 bitwise AND between the read result and the value specified by AndData, and
928 writes the result to the 32-bit PCI configuration register specified by
929 Address. The value written to the PCI configuration register is returned.
930 This function must guarantee that all PCI read and write operations are
933 If Address > 0x0FFFFFFF, then ASSERT().
934 If Address is not aligned on a 32-bit boundary, then ASSERT().
936 @param Address The address that encodes the PCI Bus, Device, Function and
938 @param AndData The value to AND with the PCI configuration register.
940 @return The value written back to the PCI configuration register.
950 ASSERT_INVALID_PCI_ADDRESS (Address
);
951 return MmioAnd32 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
955 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
956 value, followed a bitwise OR with another 32-bit value.
958 Reads the 32-bit PCI configuration register specified by Address, performs a
959 bitwise AND between the read result and the value specified by AndData,
960 performs a bitwise OR between the result of the AND operation and
961 the value specified by OrData, and writes the result to the 32-bit PCI
962 configuration register specified by Address. The value written to the PCI
963 configuration register is returned. This function must guarantee that all PCI
964 read and write operations are serialized.
966 If Address > 0x0FFFFFFF, then ASSERT().
967 If Address is not aligned on a 32-bit boundary, then ASSERT().
969 @param Address The address that encodes the PCI Bus, Device, Function and
971 @param AndData The value to AND with the PCI configuration register.
972 @param OrData The value to OR with the result of the AND operation.
974 @return The value written back to the PCI configuration register.
979 PciExpressAndThenOr32 (
985 ASSERT_INVALID_PCI_ADDRESS (Address
);
986 return MmioAndThenOr32 (
987 (UINTN
) GetPciExpressBaseAddress () + Address
,
994 Reads a bit field of a PCI configuration register.
996 Reads the bit field in a 32-bit PCI configuration register. The bit field is
997 specified by the StartBit and the EndBit. The value of the bit field is
1000 If Address > 0x0FFFFFFF, then ASSERT().
1001 If Address is not aligned on a 32-bit boundary, then ASSERT().
1002 If StartBit is greater than 31, then ASSERT().
1003 If EndBit is greater than 31, then ASSERT().
1004 If EndBit is less than StartBit, then ASSERT().
1006 @param Address The PCI configuration register to read.
1007 @param StartBit The ordinal of the least significant bit in the bit field.
1009 @param EndBit The ordinal of the most significant bit in the bit field.
1012 @return The value of the bit field read from the PCI configuration register.
1017 PciExpressBitFieldRead32 (
1023 ASSERT_INVALID_PCI_ADDRESS (Address
);
1024 return MmioBitFieldRead32 (
1025 (UINTN
) GetPciExpressBaseAddress () + Address
,
1032 Writes a bit field to a PCI configuration register.
1034 Writes Value to the bit field of the PCI configuration register. The bit
1035 field is specified by the StartBit and the EndBit. All other bits in the
1036 destination PCI configuration register are preserved. The new value of the
1037 32-bit register is returned.
1039 If Address > 0x0FFFFFFF, then ASSERT().
1040 If Address is not aligned on a 32-bit boundary, then ASSERT().
1041 If StartBit is greater than 31, then ASSERT().
1042 If EndBit is greater than 31, then ASSERT().
1043 If EndBit is less than StartBit, then ASSERT().
1044 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1046 @param Address The PCI configuration register to write.
1047 @param StartBit The ordinal of the least significant bit in the bit field.
1049 @param EndBit The ordinal of the most significant bit in the bit field.
1051 @param Value The new value of the bit field.
1053 @return The value written back to the PCI configuration register.
1058 PciExpressBitFieldWrite32 (
1065 ASSERT_INVALID_PCI_ADDRESS (Address
);
1066 return MmioBitFieldWrite32 (
1067 (UINTN
) GetPciExpressBaseAddress () + Address
,
1075 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1076 writes the result back to the bit field in the 32-bit port.
1078 Reads the 32-bit PCI configuration register specified by Address, performs a
1079 bitwise OR between the read result and the value specified by
1080 OrData, and writes the result to the 32-bit PCI configuration register
1081 specified by Address. The value written to the PCI configuration register is
1082 returned. This function must guarantee that all PCI read and write operations
1083 are serialized. Extra left bits in OrData are stripped.
1085 If Address > 0x0FFFFFFF, then ASSERT().
1086 If Address is not aligned on a 32-bit boundary, then ASSERT().
1087 If StartBit is greater than 31, then ASSERT().
1088 If EndBit is greater than 31, then ASSERT().
1089 If EndBit is less than StartBit, then ASSERT().
1090 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1092 @param Address The PCI configuration register to write.
1093 @param StartBit The ordinal of the least significant bit in the bit field.
1095 @param EndBit The ordinal of the most significant bit in the bit field.
1097 @param OrData The value to OR with the PCI configuration register.
1099 @return The value written back to the PCI configuration register.
1104 PciExpressBitFieldOr32 (
1111 ASSERT_INVALID_PCI_ADDRESS (Address
);
1112 return MmioBitFieldOr32 (
1113 (UINTN
) GetPciExpressBaseAddress () + Address
,
1121 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1122 AND, and writes the result back to the bit field in the 32-bit register.
1124 Reads the 32-bit PCI configuration register specified by Address, performs a
1125 bitwise AND between the read result and the value specified by AndData, and
1126 writes the result to the 32-bit PCI configuration register specified by
1127 Address. The value written to the PCI configuration register is returned.
1128 This function must guarantee that all PCI read and write operations are
1129 serialized. Extra left bits in AndData are stripped.
1131 If Address > 0x0FFFFFFF, then ASSERT().
1132 If Address is not aligned on a 32-bit boundary, then ASSERT().
1133 If StartBit is greater than 31, then ASSERT().
1134 If EndBit is greater than 31, then ASSERT().
1135 If EndBit is less than StartBit, then ASSERT().
1136 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1138 @param Address The PCI configuration register to write.
1139 @param StartBit The ordinal of the least significant bit in the bit field.
1141 @param EndBit The ordinal of the most significant bit in the bit field.
1143 @param AndData The value to AND with the PCI configuration register.
1145 @return The value written back to the PCI configuration register.
1150 PciExpressBitFieldAnd32 (
1157 ASSERT_INVALID_PCI_ADDRESS (Address
);
1158 return MmioBitFieldAnd32 (
1159 (UINTN
) GetPciExpressBaseAddress () + Address
,
1167 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1168 bitwise OR, and writes the result back to the bit field in the
1171 Reads the 32-bit PCI configuration register specified by Address, performs a
1172 bitwise AND followed by a bitwise OR between the read result and
1173 the value specified by AndData, and writes the result to the 32-bit PCI
1174 configuration register specified by Address. The value written to the PCI
1175 configuration register is returned. This function must guarantee that all PCI
1176 read and write operations are serialized. Extra left bits in both AndData and
1177 OrData are stripped.
1179 If Address > 0x0FFFFFFF, then ASSERT().
1180 If Address is not aligned on a 32-bit boundary, then ASSERT().
1181 If StartBit is greater than 31, then ASSERT().
1182 If EndBit is greater than 31, then ASSERT().
1183 If EndBit is less than StartBit, then ASSERT().
1184 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1185 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1187 @param Address The PCI configuration register to write.
1188 @param StartBit The ordinal of the least significant bit in the bit field.
1190 @param EndBit The ordinal of the most significant bit in the bit field.
1192 @param AndData The value to AND with the PCI configuration register.
1193 @param OrData The value to OR with the result of the AND operation.
1195 @return The value written back to the PCI configuration register.
1200 PciExpressBitFieldAndThenOr32 (
1208 ASSERT_INVALID_PCI_ADDRESS (Address
);
1209 return MmioBitFieldAndThenOr32 (
1210 (UINTN
) GetPciExpressBaseAddress () + Address
,
1219 Reads a range of PCI configuration registers into a caller supplied buffer.
1221 Reads the range of PCI configuration registers specified by StartAddress and
1222 Size into the buffer specified by Buffer. This function only allows the PCI
1223 configuration registers from a single PCI function to be read. Size is
1224 returned. When possible 32-bit PCI configuration read cycles are used to read
1225 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1226 and 16-bit PCI configuration read cycles may be used at the beginning and the
1229 If StartAddress > 0x0FFFFFFF, then ASSERT().
1230 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1231 If Size > 0 and Buffer is NULL, then ASSERT().
1233 @param StartAddress The starting address that encodes the PCI Bus, Device,
1234 Function and Register.
1235 @param Size The size in bytes of the transfer.
1236 @param Buffer The pointer to a buffer receiving the data read.
1238 @return Size read data from StartAddress.
1243 PciExpressReadBuffer (
1244 IN UINTN StartAddress
,
1251 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1252 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1258 ASSERT (Buffer
!= NULL
);
1261 // Save Size for return
1265 if ((StartAddress
& 1) != 0) {
1267 // Read a byte if StartAddress is byte aligned
1269 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1270 StartAddress
+= sizeof (UINT8
);
1271 Size
-= sizeof (UINT8
);
1272 Buffer
= (UINT8
*)Buffer
+ 1;
1275 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1277 // Read a word if StartAddress is word aligned
1279 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1281 StartAddress
+= sizeof (UINT16
);
1282 Size
-= sizeof (UINT16
);
1283 Buffer
= (UINT16
*)Buffer
+ 1;
1286 while (Size
>= sizeof (UINT32
)) {
1288 // Read as many double words as possible
1290 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1292 StartAddress
+= sizeof (UINT32
);
1293 Size
-= sizeof (UINT32
);
1294 Buffer
= (UINT32
*)Buffer
+ 1;
1297 if (Size
>= sizeof (UINT16
)) {
1299 // Read the last remaining word if exist
1301 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1302 StartAddress
+= sizeof (UINT16
);
1303 Size
-= sizeof (UINT16
);
1304 Buffer
= (UINT16
*)Buffer
+ 1;
1307 if (Size
>= sizeof (UINT8
)) {
1309 // Read the last remaining byte if exist
1311 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1318 Copies the data in a caller supplied buffer to a specified range of PCI
1319 configuration space.
1321 Writes the range of PCI configuration registers specified by StartAddress and
1322 Size from the buffer specified by Buffer. This function only allows the PCI
1323 configuration registers from a single PCI function to be written. Size is
1324 returned. When possible 32-bit PCI configuration write cycles are used to
1325 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1326 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1327 and the end of the range.
1329 If StartAddress > 0x0FFFFFFF, then ASSERT().
1330 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1331 If Size > 0 and Buffer is NULL, then ASSERT().
1333 @param StartAddress The starting address that encodes the PCI Bus, Device,
1334 Function and Register.
1335 @param Size The size in bytes of the transfer.
1336 @param Buffer The pointer to a buffer containing the data to write.
1338 @return Size written to StartAddress.
1343 PciExpressWriteBuffer (
1344 IN UINTN StartAddress
,
1351 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1352 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1358 ASSERT (Buffer
!= NULL
);
1361 // Save Size for return
1365 if ((StartAddress
& 1) != 0) {
1367 // Write a byte if StartAddress is byte aligned
1369 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1370 StartAddress
+= sizeof (UINT8
);
1371 Size
-= sizeof (UINT8
);
1372 Buffer
= (UINT8
*)Buffer
+ 1;
1375 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1377 // Write a word if StartAddress is word aligned
1379 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1380 StartAddress
+= sizeof (UINT16
);
1381 Size
-= sizeof (UINT16
);
1382 Buffer
= (UINT16
*)Buffer
+ 1;
1385 while (Size
>= sizeof (UINT32
)) {
1387 // Write as many double words as possible
1389 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1390 StartAddress
+= sizeof (UINT32
);
1391 Size
-= sizeof (UINT32
);
1392 Buffer
= (UINT32
*)Buffer
+ 1;
1395 if (Size
>= sizeof (UINT16
)) {
1397 // Write the last remaining word if exist
1399 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1400 StartAddress
+= sizeof (UINT16
);
1401 Size
-= sizeof (UINT16
);
1402 Buffer
= (UINT16
*)Buffer
+ 1;
1405 if (Size
>= sizeof (UINT8
)) {
1407 // Write the last remaining byte if exist
1409 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);