]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BasePciExpressLib/PciExpressLib.c
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. PcdPciExpressBaseSize limits the size to the real
26 number of PCI busses in this segment.
28 @param A The address to validate.
31 #define ASSERT_INVALID_PCI_ADDRESS(A) \
32 ASSERT (((A) & ~0xfffffff) == 0)
35 Registers a PCI device so PCI configuration registers may be accessed after
36 SetVirtualAddressMap().
38 Registers the PCI device specified by Address so all the PCI configuration
39 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
42 If Address > 0x0FFFFFFF, then ASSERT().
44 @param Address The address that encodes the PCI Bus, Device, Function and
47 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
48 @retval RETURN_UNSUPPORTED An attempt was made to call this function
49 after ExitBootServices().
50 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
51 at runtime could not be mapped.
52 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
53 complete the registration.
58 PciExpressRegisterForRuntimeAccess (
62 ASSERT_INVALID_PCI_ADDRESS (Address
);
63 return RETURN_UNSUPPORTED
;
67 Gets the base address of PCI Express.
69 This internal functions retrieves PCI Express Base Address via a PCD entry
70 PcdPciExpressBaseAddress.
72 @return The base address of PCI Express.
76 GetPciExpressBaseAddress (
80 return (VOID
*)(UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
84 Gets the size of PCI Express.
86 This internal functions retrieves PCI Express Base Size via a PCD entry
87 PcdPciExpressBaseSize.
89 @return The base size of PCI Express.
94 PcdPciExpressBaseSize (
98 return (UINTN
) PcdGet64 (PcdPciExpressBaseSize
);
102 Reads an 8-bit PCI configuration register.
104 Reads and returns the 8-bit PCI configuration register specified by Address.
105 This function must guarantee that all PCI read and write operations are
108 If Address > 0x0FFFFFFF, then ASSERT().
110 @param Address The address that encodes the PCI Bus, Device, Function and
113 @retval 0xFF Invalid PCI address.
114 @retval other The read value from the PCI configuration register.
123 ASSERT_INVALID_PCI_ADDRESS (Address
);
124 if (Address
>= PcdPciExpressBaseSize()) {
127 return MmioRead8 ((UINTN
) GetPciExpressBaseAddress () + Address
);
131 Writes an 8-bit PCI configuration register.
133 Writes the 8-bit PCI configuration register specified by Address with the
134 value specified by Value. Value is returned. This function must guarantee
135 that all PCI read and write operations are serialized.
137 If Address > 0x0FFFFFFF, then ASSERT().
139 @param Address The address that encodes the PCI Bus, Device, Function and
141 @param Value The value to write.
143 @retval 0xFF Invalid PCI address.
144 @retval other The value written to the PCI configuration register.
154 ASSERT_INVALID_PCI_ADDRESS (Address
);
155 if (Address
>= PcdPciExpressBaseSize()) {
158 return MmioWrite8 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
162 Performs a bitwise OR of an 8-bit PCI configuration register with
165 Reads the 8-bit PCI configuration register specified by Address, performs a
166 bitwise OR between the read result and the value specified by
167 OrData, and writes the result to the 8-bit PCI configuration register
168 specified by Address. The value written to the PCI configuration register is
169 returned. This function must guarantee that all PCI read and write operations
172 If Address > 0x0FFFFFFF, then ASSERT().
174 @param Address The address that encodes the PCI Bus, Device, Function and
176 @param OrData The value to OR with the PCI configuration register.
178 @retval 0xFF Invalid PCI address.
179 @retval other The value written to the PCI configuration register.
189 ASSERT_INVALID_PCI_ADDRESS (Address
);
190 if (Address
>= PcdPciExpressBaseSize()) {
193 return MmioOr8 ((UINTN
) GetPciExpressBaseAddress () + 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 @retval 0xFF Invalid PCI address.
214 @retval other The value written back to the PCI configuration register.
224 ASSERT_INVALID_PCI_ADDRESS (Address
);
225 if (Address
>= PcdPciExpressBaseSize()) {
228 return MmioAnd8 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
232 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
233 value, followed a bitwise OR with another 8-bit value.
235 Reads the 8-bit PCI configuration register specified by Address, performs a
236 bitwise AND between the read result and the value specified by AndData,
237 performs a bitwise OR between the result of the AND operation and
238 the value specified by OrData, and writes the result to the 8-bit PCI
239 configuration register specified by Address. The value written to the PCI
240 configuration register is returned. This function must guarantee that all PCI
241 read and write operations are serialized.
243 If Address > 0x0FFFFFFF, then ASSERT().
245 @param Address The address that encodes the PCI Bus, Device, Function and
247 @param AndData The value to AND with the PCI configuration register.
248 @param OrData The value to OR with the result of the AND operation.
250 @retval 0xFF Invalid PCI address.
251 @retval other The value written back to the PCI configuration register.
256 PciExpressAndThenOr8 (
262 ASSERT_INVALID_PCI_ADDRESS (Address
);
263 if (Address
>= PcdPciExpressBaseSize()) {
266 return MmioAndThenOr8 (
267 (UINTN
) GetPciExpressBaseAddress () + Address
,
274 Reads a bit field of a PCI configuration register.
276 Reads the bit field in an 8-bit PCI configuration register. The bit field is
277 specified by the StartBit and the EndBit. The value of the bit field is
280 If Address > 0x0FFFFFFF, then ASSERT().
281 If StartBit is greater than 7, then ASSERT().
282 If EndBit is greater than 7, then ASSERT().
283 If EndBit is less than StartBit, then ASSERT().
285 @param Address The PCI configuration register to read.
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.
291 @retval 0xFF Invalid PCI address.
292 @retval other The value of the bit field read from the PCI configuration
298 PciExpressBitFieldRead8 (
304 ASSERT_INVALID_PCI_ADDRESS (Address
);
305 if (Address
>= PcdPciExpressBaseSize()) {
308 return MmioBitFieldRead8 (
309 (UINTN
) GetPciExpressBaseAddress () + Address
,
316 Writes a bit field to a PCI configuration register.
318 Writes Value to the bit field of the PCI configuration register. The bit
319 field is specified by the StartBit and the EndBit. All other bits in the
320 destination PCI configuration register are preserved. The new value of the
321 8-bit register is returned.
323 If Address > 0x0FFFFFFF, then ASSERT().
324 If StartBit is greater than 7, then ASSERT().
325 If EndBit is greater than 7, then ASSERT().
326 If EndBit is less than StartBit, then ASSERT().
327 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
329 @param Address The PCI configuration register to write.
330 @param StartBit The ordinal of the least significant bit in the bit field.
332 @param EndBit The ordinal of the most significant bit in the bit field.
334 @param Value The new value of the bit field.
336 @retval 0xFF Invalid PCI address.
337 @retval other The value written back to the PCI configuration register.
342 PciExpressBitFieldWrite8 (
349 ASSERT_INVALID_PCI_ADDRESS (Address
);
350 if (Address
>= PcdPciExpressBaseSize()) {
353 return MmioBitFieldWrite8 (
354 (UINTN
) GetPciExpressBaseAddress () + Address
,
362 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
363 writes the result back to the bit field in the 8-bit port.
365 Reads the 8-bit PCI configuration register specified by Address, performs a
366 bitwise OR between the read result and the value specified by
367 OrData, and writes the result to the 8-bit PCI configuration register
368 specified by Address. The value written to the PCI configuration register is
369 returned. This function must guarantee that all PCI read and write operations
370 are serialized. Extra left bits in OrData are stripped.
372 If Address > 0x0FFFFFFF, then ASSERT().
373 If StartBit is greater than 7, then ASSERT().
374 If EndBit is greater than 7, then ASSERT().
375 If EndBit is less than StartBit, then ASSERT().
376 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
378 @param Address The PCI configuration register to write.
379 @param StartBit The ordinal of the least significant bit in the bit field.
381 @param EndBit The ordinal of the most significant bit in the bit field.
383 @param OrData The value to OR with the PCI configuration register.
385 @retval 0xFF Invalid PCI address.
386 @retval other The value written back to the PCI configuration register.
391 PciExpressBitFieldOr8 (
398 ASSERT_INVALID_PCI_ADDRESS (Address
);
399 if (Address
>= PcdPciExpressBaseSize()) {
402 return MmioBitFieldOr8 (
403 (UINTN
) GetPciExpressBaseAddress () + Address
,
411 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
412 AND, and writes the result back to the bit field in the 8-bit register.
414 Reads the 8-bit PCI configuration register specified by Address, performs a
415 bitwise AND between the read result and the value specified by AndData, and
416 writes the result to the 8-bit PCI configuration register specified by
417 Address. The value written to the PCI configuration register is returned.
418 This function must guarantee that all PCI read and write operations are
419 serialized. Extra left bits in AndData are stripped.
421 If Address > 0x0FFFFFFF, then ASSERT().
422 If StartBit is greater than 7, then ASSERT().
423 If EndBit is greater than 7, then ASSERT().
424 If EndBit is less than StartBit, then ASSERT().
425 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
427 @param Address The PCI configuration register to write.
428 @param StartBit The ordinal of the least significant bit in the bit field.
430 @param EndBit The ordinal of the most significant bit in the bit field.
432 @param AndData The value to AND with the PCI configuration register.
434 @retval 0xFF Invalid PCI address.
435 @retval other The value written back to the PCI configuration register.
440 PciExpressBitFieldAnd8 (
447 ASSERT_INVALID_PCI_ADDRESS (Address
);
448 if (Address
>= PcdPciExpressBaseSize()) {
451 return MmioBitFieldAnd8 (
452 (UINTN
) GetPciExpressBaseAddress () + Address
,
460 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
461 bitwise OR, and writes the result back to the bit field in the
464 Reads the 8-bit PCI configuration register specified by Address, performs a
465 bitwise AND followed by a bitwise OR between the read result and
466 the value specified by AndData, and writes the result to the 8-bit PCI
467 configuration register specified by Address. The value written to the PCI
468 configuration register is returned. This function must guarantee that all PCI
469 read and write operations are serialized. Extra left bits in both AndData and
472 If Address > 0x0FFFFFFF, then ASSERT().
473 If StartBit is greater than 7, then ASSERT().
474 If EndBit is greater than 7, then ASSERT().
475 If EndBit is less than StartBit, then ASSERT().
476 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
477 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
479 @param Address The PCI configuration register to write.
480 @param StartBit The ordinal of the least significant bit in the bit field.
482 @param EndBit The ordinal of the most significant bit in the bit field.
484 @param AndData The value to AND with the PCI configuration register.
485 @param OrData The value to OR with the result of the AND operation.
487 @retval 0xFF Invalid PCI address.
488 @retval other The value written back to the PCI configuration register.
493 PciExpressBitFieldAndThenOr8 (
501 ASSERT_INVALID_PCI_ADDRESS (Address
);
502 if (Address
>= PcdPciExpressBaseSize()) {
505 return MmioBitFieldAndThenOr8 (
506 (UINTN
) GetPciExpressBaseAddress () + Address
,
515 Reads a 16-bit PCI configuration register.
517 Reads and returns the 16-bit PCI configuration register specified by Address.
518 This function must guarantee that all PCI read and write operations are
521 If Address > 0x0FFFFFFF, then ASSERT().
522 If Address is not aligned on a 16-bit boundary, then ASSERT().
524 @param Address The address that encodes the PCI Bus, Device, Function and
527 @retval 0xFF Invalid PCI address.
528 @retval other The read value from the PCI configuration register.
537 ASSERT_INVALID_PCI_ADDRESS (Address
);
538 if (Address
>= PcdPciExpressBaseSize()) {
541 return MmioRead16 ((UINTN
) GetPciExpressBaseAddress () + Address
);
545 Writes a 16-bit PCI configuration register.
547 Writes the 16-bit PCI configuration register specified by Address with the
548 value specified by Value. Value is returned. This function must guarantee
549 that all PCI read and write operations are serialized.
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 Value The value to write.
558 @retval 0xFFFF Invalid PCI address.
559 @retval other The value written to the PCI configuration register.
569 ASSERT_INVALID_PCI_ADDRESS (Address
);
570 if (Address
>= PcdPciExpressBaseSize()) {
573 return MmioWrite16 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
577 Performs a bitwise OR of a 16-bit PCI configuration register with
580 Reads the 16-bit PCI configuration register specified by Address, performs a
581 bitwise OR between the read result and the value specified by
582 OrData, and writes the result to the 16-bit PCI configuration register
583 specified by Address. The value written to the PCI configuration register is
584 returned. This function must guarantee that all PCI read and write operations
587 If Address > 0x0FFFFFFF, then ASSERT().
588 If Address is not aligned on a 16-bit boundary, then ASSERT().
590 @param Address The address that encodes the PCI Bus, Device, Function and
592 @param OrData The value to OR with the PCI configuration register.
594 @retval 0xFFFF Invalid PCI address.
595 @retval other The value written back to the PCI configuration register.
605 ASSERT_INVALID_PCI_ADDRESS (Address
);
606 if (Address
>= PcdPciExpressBaseSize()) {
609 return MmioOr16 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
613 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
616 Reads the 16-bit PCI configuration register specified by Address, performs a
617 bitwise AND between the read result and the value specified by AndData, and
618 writes the result to the 16-bit PCI configuration register specified by
619 Address. The value written to the PCI configuration register is returned.
620 This function must guarantee that all PCI read and write operations are
623 If Address > 0x0FFFFFFF, then ASSERT().
624 If Address is not aligned on a 16-bit boundary, then ASSERT().
626 @param Address The address that encodes the PCI Bus, Device, Function and
628 @param AndData The value to AND with the PCI configuration register.
630 @retval 0xFFFF Invalid PCI address.
631 @retval other The value written back to the PCI configuration register.
641 ASSERT_INVALID_PCI_ADDRESS (Address
);
642 if (Address
>= PcdPciExpressBaseSize()) {
645 return MmioAnd16 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
649 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
650 value, followed a bitwise OR with another 16-bit value.
652 Reads the 16-bit PCI configuration register specified by Address, performs a
653 bitwise AND between the read result and the value specified by AndData,
654 performs a bitwise OR between the result of the AND operation and
655 the value specified by OrData, and writes the result to the 16-bit PCI
656 configuration register specified by Address. The value written to the PCI
657 configuration register is returned. This function must guarantee that all PCI
658 read and write operations are serialized.
660 If Address > 0x0FFFFFFF, then ASSERT().
661 If Address is not aligned on a 16-bit boundary, then ASSERT().
663 @param Address The address that encodes the PCI Bus, Device, Function and
665 @param AndData The value to AND with the PCI configuration register.
666 @param OrData The value to OR with the result of the AND operation.
668 @retval 0xFFFF Invalid PCI address.
669 @retval other The value written back to the PCI configuration register.
674 PciExpressAndThenOr16 (
680 ASSERT_INVALID_PCI_ADDRESS (Address
);
681 if (Address
>= PcdPciExpressBaseSize()) {
684 return MmioAndThenOr16 (
685 (UINTN
) GetPciExpressBaseAddress () + Address
,
692 Reads a bit field of a PCI configuration register.
694 Reads the bit field in a 16-bit PCI configuration register. The bit field is
695 specified by the StartBit and the EndBit. The value of the bit field is
698 If Address > 0x0FFFFFFF, then ASSERT().
699 If Address is not aligned on a 16-bit boundary, then ASSERT().
700 If StartBit is greater than 15, then ASSERT().
701 If EndBit is greater than 15, then ASSERT().
702 If EndBit is less than StartBit, then ASSERT().
704 @param Address The PCI configuration register to read.
705 @param StartBit The ordinal of the least significant bit in the bit field.
707 @param EndBit The ordinal of the most significant bit in the bit field.
710 @retval 0xFFFF Invalid PCI address.
711 @retval other The value of the bit field read from the PCI configuration
717 PciExpressBitFieldRead16 (
723 ASSERT_INVALID_PCI_ADDRESS (Address
);
724 if (Address
>= PcdPciExpressBaseSize()) {
727 return MmioBitFieldRead16 (
728 (UINTN
) GetPciExpressBaseAddress () + Address
,
735 Writes a bit field to a PCI configuration register.
737 Writes Value to the bit field of the PCI configuration register. The bit
738 field is specified by the StartBit and the EndBit. All other bits in the
739 destination PCI configuration register are preserved. The new value of the
740 16-bit register is returned.
742 If Address > 0x0FFFFFFF, then ASSERT().
743 If Address is not aligned on a 16-bit boundary, then ASSERT().
744 If StartBit is greater than 15, then ASSERT().
745 If EndBit is greater than 15, then ASSERT().
746 If EndBit is less than StartBit, then ASSERT().
747 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
749 @param Address The PCI configuration register to write.
750 @param StartBit The ordinal of the least significant bit in the bit field.
752 @param EndBit The ordinal of the most significant bit in the bit field.
754 @param Value The new value of the bit field.
756 @retval 0xFFFF Invalid PCI address.
757 @retval other The value written back to the PCI configuration register.
762 PciExpressBitFieldWrite16 (
769 ASSERT_INVALID_PCI_ADDRESS (Address
);
770 if (Address
>= PcdPciExpressBaseSize()) {
773 return MmioBitFieldWrite16 (
774 (UINTN
) GetPciExpressBaseAddress () + Address
,
782 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
783 writes the result back to the bit field in the 16-bit port.
785 Reads the 16-bit PCI configuration register specified by Address, performs a
786 bitwise OR between the read result and the value specified by
787 OrData, and writes the result to the 16-bit PCI configuration register
788 specified by Address. The value written to the PCI configuration register is
789 returned. This function must guarantee that all PCI read and write operations
790 are serialized. Extra left bits in OrData are stripped.
792 If Address > 0x0FFFFFFF, then ASSERT().
793 If Address is not aligned on a 16-bit boundary, then ASSERT().
794 If StartBit is greater than 15, then ASSERT().
795 If EndBit is greater than 15, then ASSERT().
796 If EndBit is less than StartBit, then ASSERT().
797 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
799 @param Address The PCI configuration register to write.
800 @param StartBit The ordinal of the least significant bit in the bit field.
802 @param EndBit The ordinal of the most significant bit in the bit field.
804 @param OrData The value to OR with the PCI configuration register.
806 @retval 0xFFFF Invalid PCI address.
807 @retval other The value written back to the PCI configuration register.
812 PciExpressBitFieldOr16 (
819 ASSERT_INVALID_PCI_ADDRESS (Address
);
820 if (Address
>= PcdPciExpressBaseSize()) {
823 return MmioBitFieldOr16 (
824 (UINTN
) GetPciExpressBaseAddress () + Address
,
832 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
833 AND, and writes the result back to the bit field in the 16-bit register.
835 Reads the 16-bit PCI configuration register specified by Address, performs a
836 bitwise AND between the read result and the value specified by AndData, and
837 writes the result to the 16-bit PCI configuration register specified by
838 Address. The value written to the PCI configuration register is returned.
839 This function must guarantee that all PCI read and write operations are
840 serialized. Extra left bits in AndData are stripped.
842 If Address > 0x0FFFFFFF, then ASSERT().
843 If Address is not aligned on a 16-bit boundary, then ASSERT().
844 If StartBit is greater than 15, then ASSERT().
845 If EndBit is greater than 15, then ASSERT().
846 If EndBit is less than StartBit, then ASSERT().
847 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
849 @param Address The PCI configuration register to write.
850 @param StartBit The ordinal of the least significant bit in the bit field.
852 @param EndBit The ordinal of the most significant bit in the bit field.
854 @param AndData The value to AND with the PCI configuration register.
856 @retval 0xFFFF Invalid PCI address.
857 @retval other The value written back to the PCI configuration register.
862 PciExpressBitFieldAnd16 (
869 ASSERT_INVALID_PCI_ADDRESS (Address
);
870 if (Address
>= PcdPciExpressBaseSize()) {
873 return MmioBitFieldAnd16 (
874 (UINTN
) GetPciExpressBaseAddress () + Address
,
882 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
883 bitwise OR, and writes the result back to the bit field in the
886 Reads the 16-bit PCI configuration register specified by Address, performs a
887 bitwise AND followed by a bitwise OR between the read result and
888 the value specified by AndData, and writes the result to the 16-bit PCI
889 configuration register specified by Address. The value written to the PCI
890 configuration register is returned. This function must guarantee that all PCI
891 read and write operations are serialized. Extra left bits in both AndData and
894 If Address > 0x0FFFFFFF, then ASSERT().
895 If Address is not aligned on a 16-bit boundary, then ASSERT().
896 If StartBit is greater than 15, then ASSERT().
897 If EndBit is greater than 15, then ASSERT().
898 If EndBit is less than StartBit, then ASSERT().
899 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
900 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
902 @param Address The PCI configuration register to write.
903 @param StartBit The ordinal of the least significant bit in the bit field.
905 @param EndBit The ordinal of the most significant bit in the bit field.
907 @param AndData The value to AND with the PCI configuration register.
908 @param OrData The value to OR with the result of the AND operation.
910 @retval 0xFFFF Invalid PCI address.
911 @retval other The value written back to the PCI configuration register.
916 PciExpressBitFieldAndThenOr16 (
924 ASSERT_INVALID_PCI_ADDRESS (Address
);
925 if (Address
>= PcdPciExpressBaseSize()) {
928 return MmioBitFieldAndThenOr16 (
929 (UINTN
) GetPciExpressBaseAddress () + Address
,
938 Reads a 32-bit PCI configuration register.
940 Reads and returns the 32-bit PCI configuration register specified by Address.
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
950 @retval 0xFFFF Invalid PCI address.
951 @retval other The read value from the PCI configuration register.
960 ASSERT_INVALID_PCI_ADDRESS (Address
);
961 if (Address
>= PcdPciExpressBaseSize()) {
964 return MmioRead32 ((UINTN
) GetPciExpressBaseAddress () + Address
);
968 Writes a 32-bit PCI configuration register.
970 Writes the 32-bit PCI configuration register specified by Address with the
971 value specified by Value. Value is returned. This function must guarantee
972 that all PCI read and write operations are serialized.
974 If Address > 0x0FFFFFFF, then ASSERT().
975 If Address is not aligned on a 32-bit boundary, then ASSERT().
977 @param Address The address that encodes the PCI Bus, Device, Function and
979 @param Value The value to write.
981 @retval 0xFFFFFFFF Invalid PCI address.
982 @retval other The value written to the PCI configuration register.
992 ASSERT_INVALID_PCI_ADDRESS (Address
);
993 if (Address
>= PcdPciExpressBaseSize()) {
996 return MmioWrite32 ((UINTN
) GetPciExpressBaseAddress () + Address
, Value
);
1000 Performs a bitwise OR of a 32-bit PCI configuration register with
1003 Reads the 32-bit PCI configuration register specified by Address, performs a
1004 bitwise OR between the read result and the value specified by
1005 OrData, and writes the result to the 32-bit PCI configuration register
1006 specified by Address. The value written to the PCI configuration register is
1007 returned. This function must guarantee that all PCI read and write operations
1010 If Address > 0x0FFFFFFF, then ASSERT().
1011 If Address is not aligned on a 32-bit boundary, then ASSERT().
1013 @param Address The address that encodes the PCI Bus, Device, Function and
1015 @param OrData The value to OR with the PCI configuration register.
1017 @retval 0xFFFFFFFF Invalid PCI address.
1018 @retval other The value written back to the PCI configuration register.
1028 ASSERT_INVALID_PCI_ADDRESS (Address
);
1029 if (Address
>= PcdPciExpressBaseSize()) {
1032 return MmioOr32 ((UINTN
) GetPciExpressBaseAddress () + Address
, OrData
);
1036 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1039 Reads the 32-bit PCI configuration register specified by Address, performs a
1040 bitwise AND between the read result and the value specified by AndData, and
1041 writes the result to the 32-bit PCI configuration register specified by
1042 Address. The value written to the PCI configuration register is returned.
1043 This function must guarantee that all PCI read and write operations are
1046 If Address > 0x0FFFFFFF, then ASSERT().
1047 If Address is not aligned on a 32-bit boundary, then ASSERT().
1049 @param Address The address that encodes the PCI Bus, Device, Function and
1051 @param AndData The value to AND with the PCI configuration register.
1053 @retval 0xFFFFFFFF Invalid PCI address.
1054 @retval other The value written back to the PCI configuration register.
1064 ASSERT_INVALID_PCI_ADDRESS (Address
);
1065 if (Address
>= PcdPciExpressBaseSize()) {
1068 return MmioAnd32 ((UINTN
) GetPciExpressBaseAddress () + Address
, AndData
);
1072 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1073 value, followed a bitwise OR with another 32-bit value.
1075 Reads the 32-bit PCI configuration register specified by Address, performs a
1076 bitwise AND between the read result and the value specified by AndData,
1077 performs a bitwise OR between the result of the AND operation and
1078 the value specified by OrData, and writes the result to the 32-bit PCI
1079 configuration register specified by Address. The value written to the PCI
1080 configuration register is returned. This function must guarantee that all PCI
1081 read and write operations are serialized.
1083 If Address > 0x0FFFFFFF, then ASSERT().
1084 If Address is not aligned on a 32-bit boundary, then ASSERT().
1086 @param Address The address that encodes the PCI Bus, Device, Function and
1088 @param AndData The value to AND with the PCI configuration register.
1089 @param OrData The value to OR with the result of the AND operation.
1091 @retval 0xFFFFFFFF Invalid PCI address.
1092 @retval other The value written back to the PCI configuration register.
1097 PciExpressAndThenOr32 (
1103 ASSERT_INVALID_PCI_ADDRESS (Address
);
1104 if (Address
>= PcdPciExpressBaseSize()) {
1107 return MmioAndThenOr32 (
1108 (UINTN
) GetPciExpressBaseAddress () + Address
,
1115 Reads a bit field of a PCI configuration register.
1117 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1118 specified by the StartBit and the EndBit. The value of the bit field is
1121 If Address > 0x0FFFFFFF, then ASSERT().
1122 If Address is not aligned on a 32-bit boundary, then ASSERT().
1123 If StartBit is greater than 31, then ASSERT().
1124 If EndBit is greater than 31, then ASSERT().
1125 If EndBit is less than StartBit, then ASSERT().
1127 @param Address The PCI configuration register to read.
1128 @param StartBit The ordinal of the least significant bit in the bit field.
1130 @param EndBit The ordinal of the most significant bit in the bit field.
1133 @retval 0xFFFFFFFF Invalid PCI address.
1134 @retval other The value of the bit field read from the PCI
1135 configuration register.
1140 PciExpressBitFieldRead32 (
1146 ASSERT_INVALID_PCI_ADDRESS (Address
);
1147 if (Address
>= PcdPciExpressBaseSize()) {
1150 return MmioBitFieldRead32 (
1151 (UINTN
) GetPciExpressBaseAddress () + Address
,
1158 Writes a bit field to a PCI configuration register.
1160 Writes Value to the bit field of the PCI configuration register. The bit
1161 field is specified by the StartBit and the EndBit. All other bits in the
1162 destination PCI configuration register are preserved. The new value of the
1163 32-bit register is returned.
1165 If Address > 0x0FFFFFFF, then ASSERT().
1166 If Address is not aligned on a 32-bit boundary, then ASSERT().
1167 If StartBit is greater than 31, then ASSERT().
1168 If EndBit is greater than 31, then ASSERT().
1169 If EndBit is less than StartBit, then ASSERT().
1170 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1172 @param Address The PCI configuration register to write.
1173 @param StartBit The ordinal of the least significant bit in the bit field.
1175 @param EndBit The ordinal of the most significant bit in the bit field.
1177 @param Value The new value of the bit field.
1179 @retval 0xFFFFFFFF Invalid PCI address.
1180 @retval other The value written back to the PCI configuration register.
1185 PciExpressBitFieldWrite32 (
1192 ASSERT_INVALID_PCI_ADDRESS (Address
);
1193 if (Address
>= PcdPciExpressBaseSize()) {
1196 return MmioBitFieldWrite32 (
1197 (UINTN
) GetPciExpressBaseAddress () + Address
,
1205 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1206 writes the result back to the bit field in the 32-bit port.
1208 Reads the 32-bit PCI configuration register specified by Address, performs a
1209 bitwise OR between the read result and the value specified by
1210 OrData, and writes the result to the 32-bit PCI configuration register
1211 specified by Address. The value written to the PCI configuration register is
1212 returned. This function must guarantee that all PCI read and write operations
1213 are serialized. Extra left bits in OrData are stripped.
1215 If Address > 0x0FFFFFFF, then ASSERT().
1216 If Address is not aligned on a 32-bit boundary, then ASSERT().
1217 If StartBit is greater than 31, then ASSERT().
1218 If EndBit is greater than 31, then ASSERT().
1219 If EndBit is less than StartBit, then ASSERT().
1220 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1222 @param Address The PCI configuration register to write.
1223 @param StartBit The ordinal of the least significant bit in the bit field.
1225 @param EndBit The ordinal of the most significant bit in the bit field.
1227 @param OrData The value to OR with the PCI configuration register.
1229 @retval 0xFFFFFFFF Invalid PCI address.
1230 @retval other The value written back to the PCI configuration register.
1235 PciExpressBitFieldOr32 (
1242 ASSERT_INVALID_PCI_ADDRESS (Address
);
1243 if (Address
>= PcdPciExpressBaseSize()) {
1246 return MmioBitFieldOr32 (
1247 (UINTN
) GetPciExpressBaseAddress () + Address
,
1255 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1256 AND, and writes the result back to the bit field in the 32-bit register.
1258 Reads the 32-bit PCI configuration register specified by Address, performs a
1259 bitwise AND between the read result and the value specified by AndData, and
1260 writes the result to the 32-bit PCI configuration register specified by
1261 Address. The value written to the PCI configuration register is returned.
1262 This function must guarantee that all PCI read and write operations are
1263 serialized. Extra left bits in AndData are stripped.
1265 If Address > 0x0FFFFFFF, then ASSERT().
1266 If Address is not aligned on a 32-bit boundary, then ASSERT().
1267 If StartBit is greater than 31, then ASSERT().
1268 If EndBit is greater than 31, then ASSERT().
1269 If EndBit is less than StartBit, then ASSERT().
1270 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1272 @param Address The PCI configuration register to write.
1273 @param StartBit The ordinal of the least significant bit in the bit field.
1275 @param EndBit The ordinal of the most significant bit in the bit field.
1277 @param AndData The value to AND with the PCI configuration register.
1279 @retval 0xFFFFFFFF Invalid PCI address.
1280 @retval other The value written back to the PCI configuration register.
1285 PciExpressBitFieldAnd32 (
1292 ASSERT_INVALID_PCI_ADDRESS (Address
);
1293 if (Address
>= PcdPciExpressBaseSize()) {
1296 return MmioBitFieldAnd32 (
1297 (UINTN
) GetPciExpressBaseAddress () + Address
,
1305 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1306 bitwise OR, and writes the result back to the bit field in the
1309 Reads the 32-bit PCI configuration register specified by Address, performs a
1310 bitwise AND followed by a bitwise OR between the read result and
1311 the value specified by AndData, and writes the result to the 32-bit PCI
1312 configuration register specified by Address. The value written to the PCI
1313 configuration register is returned. This function must guarantee that all PCI
1314 read and write operations are serialized. Extra left bits in both AndData and
1315 OrData are stripped.
1317 If Address > 0x0FFFFFFF, then ASSERT().
1318 If Address is not aligned on a 32-bit boundary, then ASSERT().
1319 If StartBit is greater than 31, then ASSERT().
1320 If EndBit is greater than 31, then ASSERT().
1321 If EndBit is less than StartBit, then ASSERT().
1322 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1323 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1325 @param Address The PCI configuration register to write.
1326 @param StartBit The ordinal of the least significant bit in the bit field.
1328 @param EndBit The ordinal of the most significant bit in the bit field.
1330 @param AndData The value to AND with the PCI configuration register.
1331 @param OrData The value to OR with the result of the AND operation.
1333 @retval 0xFFFFFFFF Invalid PCI address.
1334 @retval other The value written back to the PCI configuration register.
1339 PciExpressBitFieldAndThenOr32 (
1347 ASSERT_INVALID_PCI_ADDRESS (Address
);
1348 if (Address
>= PcdPciExpressBaseSize()) {
1351 return MmioBitFieldAndThenOr32 (
1352 (UINTN
) GetPciExpressBaseAddress () + Address
,
1361 Reads a range of PCI configuration registers into a caller supplied buffer.
1363 Reads the range of PCI configuration registers specified by StartAddress and
1364 Size into the buffer specified by Buffer. This function only allows the PCI
1365 configuration registers from a single PCI function to be read. Size is
1366 returned. When possible 32-bit PCI configuration read cycles are used to read
1367 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1368 and 16-bit PCI configuration read cycles may be used at the beginning and the
1371 If StartAddress > 0x0FFFFFFF, then ASSERT().
1372 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1373 If Size > 0 and Buffer is NULL, then ASSERT().
1375 @param StartAddress The starting address that encodes the PCI Bus, Device,
1376 Function and Register.
1377 @param Size The size in bytes of the transfer.
1378 @param Buffer The pointer to a buffer receiving the data read.
1380 @retval (UINTN)-1 Invalid PCI address.
1381 @retval other Size read data from StartAddress.
1386 PciExpressReadBuffer (
1387 IN UINTN StartAddress
,
1394 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1395 if (StartAddress
>= PcdPciExpressBaseSize()) {
1398 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1404 ASSERT (Buffer
!= NULL
);
1407 // Save Size for return
1411 if ((StartAddress
& 1) != 0) {
1413 // Read a byte if StartAddress is byte aligned
1415 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1416 StartAddress
+= sizeof (UINT8
);
1417 Size
-= sizeof (UINT8
);
1418 Buffer
= (UINT8
*)Buffer
+ 1;
1421 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1423 // Read a word if StartAddress is word aligned
1425 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1427 StartAddress
+= sizeof (UINT16
);
1428 Size
-= sizeof (UINT16
);
1429 Buffer
= (UINT16
*)Buffer
+ 1;
1432 while (Size
>= sizeof (UINT32
)) {
1434 // Read as many double words as possible
1436 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1438 StartAddress
+= sizeof (UINT32
);
1439 Size
-= sizeof (UINT32
);
1440 Buffer
= (UINT32
*)Buffer
+ 1;
1443 if (Size
>= sizeof (UINT16
)) {
1445 // Read the last remaining word if exist
1447 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1448 StartAddress
+= sizeof (UINT16
);
1449 Size
-= sizeof (UINT16
);
1450 Buffer
= (UINT16
*)Buffer
+ 1;
1453 if (Size
>= sizeof (UINT8
)) {
1455 // Read the last remaining byte if exist
1457 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1464 Copies the data in a caller supplied buffer to a specified range of PCI
1465 configuration space.
1467 Writes the range of PCI configuration registers specified by StartAddress and
1468 Size from the buffer specified by Buffer. This function only allows the PCI
1469 configuration registers from a single PCI function to be written. Size is
1470 returned. When possible 32-bit PCI configuration write cycles are used to
1471 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1472 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1473 and the end of the range.
1475 If StartAddress > 0x0FFFFFFF, then ASSERT().
1476 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1477 If Size > 0 and Buffer is NULL, then ASSERT().
1479 @param StartAddress The starting address that encodes the PCI Bus, Device,
1480 Function and Register.
1481 @param Size The size in bytes of the transfer.
1482 @param Buffer The pointer to a buffer containing the data to write.
1484 @retval (UINTN)-1 Invalid PCI address.
1485 @retval other Size written to StartAddress.
1490 PciExpressWriteBuffer (
1491 IN UINTN StartAddress
,
1498 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1499 if (StartAddress
>= PcdPciExpressBaseSize()) {
1502 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1508 ASSERT (Buffer
!= NULL
);
1511 // Save Size for return
1515 if ((StartAddress
& 1) != 0) {
1517 // Write a byte if StartAddress is byte aligned
1519 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1520 StartAddress
+= sizeof (UINT8
);
1521 Size
-= sizeof (UINT8
);
1522 Buffer
= (UINT8
*)Buffer
+ 1;
1525 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1527 // Write a word if StartAddress is word aligned
1529 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1530 StartAddress
+= sizeof (UINT16
);
1531 Size
-= sizeof (UINT16
);
1532 Buffer
= (UINT16
*)Buffer
+ 1;
1535 while (Size
>= sizeof (UINT32
)) {
1537 // Write as many double words as possible
1539 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1540 StartAddress
+= sizeof (UINT32
);
1541 Size
-= sizeof (UINT32
);
1542 Buffer
= (UINT32
*)Buffer
+ 1;
1545 if (Size
>= sizeof (UINT16
)) {
1547 // Write the last remaining word if exist
1549 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1550 StartAddress
+= sizeof (UINT16
);
1551 Size
-= sizeof (UINT16
);
1552 Buffer
= (UINT16
*)Buffer
+ 1;
1555 if (Size
>= sizeof (UINT8
)) {
1557 // Write the last remaining byte if exist
1559 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);