]>
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
15 #include <Library/BaseLib.h>
16 #include <Library/PciExpressLib.h>
17 #include <Library/IoLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/PcdLib.h>
22 Assert the validity of a PCI address. A valid PCI address should contain 1's
23 only in the low 28 bits. PcdPciExpressBaseSize limits the size to the real
24 number of PCI busses in this segment.
26 @param A The address to validate.
29 #define ASSERT_INVALID_PCI_ADDRESS(A) \
30 ASSERT (((A) & ~0xfffffff) == 0)
33 Registers a PCI device so PCI configuration registers may be accessed after
34 SetVirtualAddressMap().
36 Registers the PCI device specified by Address so all the PCI configuration
37 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
40 If Address > 0x0FFFFFFF, then ASSERT().
42 @param Address The address that encodes the PCI Bus, Device, Function and
45 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
46 @retval RETURN_UNSUPPORTED An attempt was made to call this function
47 after ExitBootServices().
48 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
49 at runtime could not be mapped.
50 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
51 complete the registration.
56 PciExpressRegisterForRuntimeAccess (
60 ASSERT_INVALID_PCI_ADDRESS (Address
);
61 return RETURN_UNSUPPORTED
;
65 Gets the base address of PCI Express.
67 This internal functions retrieves PCI Express Base Address via a PCD entry
68 PcdPciExpressBaseAddress.
70 @return The base address of PCI Express.
74 GetPciExpressBaseAddress (
78 return (VOID
*)(UINTN
)PcdGet64 (PcdPciExpressBaseAddress
);
82 Gets the size of PCI Express.
84 This internal functions retrieves PCI Express Base Size via a PCD entry
85 PcdPciExpressBaseSize.
87 @return The base size of PCI Express.
92 PcdPciExpressBaseSize (
96 return (UINTN
)PcdGet64 (PcdPciExpressBaseSize
);
100 Reads an 8-bit PCI configuration register.
102 Reads and returns the 8-bit PCI configuration register specified by Address.
103 This function must guarantee that all PCI read and write operations are
106 If Address > 0x0FFFFFFF, then ASSERT().
108 @param Address The address that encodes the PCI Bus, Device, Function and
111 @retval 0xFF Invalid PCI address.
112 @retval other The read value from the PCI configuration register.
121 ASSERT_INVALID_PCI_ADDRESS (Address
);
122 if (Address
>= PcdPciExpressBaseSize ()) {
126 return MmioRead8 ((UINTN
)GetPciExpressBaseAddress () + Address
);
130 Writes an 8-bit PCI configuration register.
132 Writes the 8-bit PCI configuration register specified by Address with the
133 value specified by Value. Value is returned. This function must guarantee
134 that all PCI read and write operations are serialized.
136 If Address > 0x0FFFFFFF, then ASSERT().
138 @param Address The address that encodes the PCI Bus, Device, Function and
140 @param Value The value to write.
142 @retval 0xFF Invalid PCI address.
143 @retval other The value written to the PCI configuration register.
153 ASSERT_INVALID_PCI_ADDRESS (Address
);
154 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 ()) {
194 return MmioOr8 ((UINTN
)GetPciExpressBaseAddress () + Address
, OrData
);
198 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
201 Reads the 8-bit PCI configuration register specified by Address, performs a
202 bitwise AND between the read result and the value specified by AndData, and
203 writes the result to the 8-bit PCI configuration register specified by
204 Address. The value written to the PCI configuration register is returned.
205 This function must guarantee that all PCI read and write operations are
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.
214 @retval 0xFF Invalid PCI address.
215 @retval other The value written back to the PCI configuration register.
225 ASSERT_INVALID_PCI_ADDRESS (Address
);
226 if (Address
>= PcdPciExpressBaseSize ()) {
230 return MmioAnd8 ((UINTN
)GetPciExpressBaseAddress () + Address
, AndData
);
234 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
235 value, followed a bitwise OR with another 8-bit value.
237 Reads the 8-bit PCI configuration register specified by Address, performs a
238 bitwise AND between the read result and the value specified by AndData,
239 performs a bitwise OR between the result of the AND operation and
240 the value specified by OrData, and writes the result to the 8-bit PCI
241 configuration register specified by Address. The value written to the PCI
242 configuration register is returned. This function must guarantee that all PCI
243 read and write operations are serialized.
245 If Address > 0x0FFFFFFF, then ASSERT().
247 @param Address The address that encodes the PCI Bus, Device, Function and
249 @param AndData The value to AND with the PCI configuration register.
250 @param OrData The value to OR with the result of the AND operation.
252 @retval 0xFF Invalid PCI address.
253 @retval other The value written back to the PCI configuration register.
258 PciExpressAndThenOr8 (
264 ASSERT_INVALID_PCI_ADDRESS (Address
);
265 if (Address
>= PcdPciExpressBaseSize ()) {
269 return MmioAndThenOr8 (
270 (UINTN
)GetPciExpressBaseAddress () + Address
,
277 Reads a bit field of a PCI configuration register.
279 Reads the bit field in an 8-bit PCI configuration register. The bit field is
280 specified by the StartBit and the EndBit. The value of the bit field is
283 If Address > 0x0FFFFFFF, then ASSERT().
284 If StartBit is greater than 7, then ASSERT().
285 If EndBit is greater than 7, then ASSERT().
286 If EndBit is less than StartBit, then ASSERT().
288 @param Address The PCI configuration register to read.
289 @param StartBit The ordinal of the least significant bit in the bit field.
291 @param EndBit The ordinal of the most significant bit in the bit field.
294 @retval 0xFF Invalid PCI address.
295 @retval other The value of the bit field read from the PCI configuration
301 PciExpressBitFieldRead8 (
307 ASSERT_INVALID_PCI_ADDRESS (Address
);
308 if (Address
>= PcdPciExpressBaseSize ()) {
312 return MmioBitFieldRead8 (
313 (UINTN
)GetPciExpressBaseAddress () + Address
,
320 Writes a bit field to a PCI configuration register.
322 Writes Value to the bit field of the PCI configuration register. The bit
323 field is specified by the StartBit and the EndBit. All other bits in the
324 destination PCI configuration register are preserved. The new value of the
325 8-bit register is returned.
327 If Address > 0x0FFFFFFF, then ASSERT().
328 If StartBit is greater than 7, then ASSERT().
329 If EndBit is greater than 7, then ASSERT().
330 If EndBit is less than StartBit, then ASSERT().
331 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
333 @param Address The PCI configuration register to write.
334 @param StartBit The ordinal of the least significant bit in the bit field.
336 @param EndBit The ordinal of the most significant bit in the bit field.
338 @param Value The new value of the bit field.
340 @retval 0xFF Invalid PCI address.
341 @retval other The value written back to the PCI configuration register.
346 PciExpressBitFieldWrite8 (
353 ASSERT_INVALID_PCI_ADDRESS (Address
);
354 if (Address
>= PcdPciExpressBaseSize ()) {
358 return MmioBitFieldWrite8 (
359 (UINTN
)GetPciExpressBaseAddress () + Address
,
367 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
368 writes the result back to the bit field in the 8-bit port.
370 Reads the 8-bit PCI configuration register specified by Address, performs a
371 bitwise OR between the read result and the value specified by
372 OrData, and writes the result to the 8-bit PCI configuration register
373 specified by Address. The value written to the PCI configuration register is
374 returned. This function must guarantee that all PCI read and write operations
375 are serialized. Extra left bits in OrData are stripped.
377 If Address > 0x0FFFFFFF, then ASSERT().
378 If StartBit is greater than 7, then ASSERT().
379 If EndBit is greater than 7, then ASSERT().
380 If EndBit is less than StartBit, then ASSERT().
381 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
383 @param Address The PCI configuration register to write.
384 @param StartBit The ordinal of the least significant bit in the bit field.
386 @param EndBit The ordinal of the most significant bit in the bit field.
388 @param OrData The value to OR with the PCI configuration register.
390 @retval 0xFF Invalid PCI address.
391 @retval other The value written back to the PCI configuration register.
396 PciExpressBitFieldOr8 (
403 ASSERT_INVALID_PCI_ADDRESS (Address
);
404 if (Address
>= PcdPciExpressBaseSize ()) {
408 return MmioBitFieldOr8 (
409 (UINTN
)GetPciExpressBaseAddress () + Address
,
417 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
418 AND, and writes the result back to the bit field in the 8-bit register.
420 Reads the 8-bit PCI configuration register specified by Address, performs a
421 bitwise AND between the read result and the value specified by AndData, and
422 writes the result to the 8-bit PCI configuration register specified by
423 Address. The value written to the PCI configuration register is returned.
424 This function must guarantee that all PCI read and write operations are
425 serialized. Extra left bits in AndData are stripped.
427 If Address > 0x0FFFFFFF, then ASSERT().
428 If StartBit is greater than 7, then ASSERT().
429 If EndBit is greater than 7, then ASSERT().
430 If EndBit is less than StartBit, then ASSERT().
431 If AndData 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.
440 @retval 0xFF Invalid PCI address.
441 @retval other The value written back to the PCI configuration register.
446 PciExpressBitFieldAnd8 (
453 ASSERT_INVALID_PCI_ADDRESS (Address
);
454 if (Address
>= PcdPciExpressBaseSize ()) {
458 return MmioBitFieldAnd8 (
459 (UINTN
)GetPciExpressBaseAddress () + Address
,
467 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
468 bitwise OR, and writes the result back to the bit field in the
471 Reads the 8-bit PCI configuration register specified by Address, performs a
472 bitwise AND followed by a bitwise OR between the read result and
473 the value specified by AndData, and writes the result to the 8-bit PCI
474 configuration register specified by Address. The value written to the PCI
475 configuration register is returned. This function must guarantee that all PCI
476 read and write operations are serialized. Extra left bits in both AndData and
479 If Address > 0x0FFFFFFF, then ASSERT().
480 If StartBit is greater than 7, then ASSERT().
481 If EndBit is greater than 7, then ASSERT().
482 If EndBit is less than StartBit, then ASSERT().
483 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
484 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
486 @param Address The PCI configuration register to write.
487 @param StartBit The ordinal of the least significant bit in the bit field.
489 @param EndBit The ordinal of the most significant bit in the bit field.
491 @param AndData The value to AND with the PCI configuration register.
492 @param OrData The value to OR with the result of the AND operation.
494 @retval 0xFF Invalid PCI address.
495 @retval other The value written back to the PCI configuration register.
500 PciExpressBitFieldAndThenOr8 (
508 ASSERT_INVALID_PCI_ADDRESS (Address
);
509 if (Address
>= PcdPciExpressBaseSize ()) {
513 return MmioBitFieldAndThenOr8 (
514 (UINTN
)GetPciExpressBaseAddress () + Address
,
523 Reads a 16-bit PCI configuration register.
525 Reads and returns the 16-bit PCI configuration register specified by Address.
526 This function must guarantee that all PCI read and write operations are
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
535 @retval 0xFF Invalid PCI address.
536 @retval other The read value from the PCI configuration register.
545 ASSERT_INVALID_PCI_ADDRESS (Address
);
546 if (Address
>= PcdPciExpressBaseSize ()) {
550 return MmioRead16 ((UINTN
)GetPciExpressBaseAddress () + Address
);
554 Writes a 16-bit PCI configuration register.
556 Writes the 16-bit PCI configuration register specified by Address with the
557 value specified by Value. Value is returned. This function must guarantee
558 that all PCI read and write operations are serialized.
560 If Address > 0x0FFFFFFF, then ASSERT().
561 If Address is not aligned on a 16-bit boundary, then ASSERT().
563 @param Address The address that encodes the PCI Bus, Device, Function and
565 @param Value The value to write.
567 @retval 0xFFFF Invalid PCI address.
568 @retval other The value written to the PCI configuration register.
578 ASSERT_INVALID_PCI_ADDRESS (Address
);
579 if (Address
>= PcdPciExpressBaseSize ()) {
583 return MmioWrite16 ((UINTN
)GetPciExpressBaseAddress () + Address
, Value
);
587 Performs a bitwise OR of a 16-bit PCI configuration register with
590 Reads the 16-bit PCI configuration register specified by Address, performs a
591 bitwise OR between the read result and the value specified by
592 OrData, and writes the result to the 16-bit PCI configuration register
593 specified by Address. The value written to the PCI configuration register is
594 returned. This function must guarantee that all PCI read and write operations
597 If Address > 0x0FFFFFFF, then ASSERT().
598 If Address is not aligned on a 16-bit boundary, then ASSERT().
600 @param Address The address that encodes the PCI Bus, Device, Function and
602 @param OrData The value to OR with the PCI configuration register.
604 @retval 0xFFFF Invalid PCI address.
605 @retval other The value written back to the PCI configuration register.
615 ASSERT_INVALID_PCI_ADDRESS (Address
);
616 if (Address
>= PcdPciExpressBaseSize ()) {
620 return MmioOr16 ((UINTN
)GetPciExpressBaseAddress () + Address
, OrData
);
624 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
627 Reads the 16-bit PCI configuration register specified by Address, performs a
628 bitwise AND between the read result and the value specified by AndData, and
629 writes the result to the 16-bit PCI configuration register specified by
630 Address. The value written to the PCI configuration register is returned.
631 This function must guarantee that all PCI read and write operations are
634 If Address > 0x0FFFFFFF, then ASSERT().
635 If Address is not aligned on a 16-bit boundary, then ASSERT().
637 @param Address The address that encodes the PCI Bus, Device, Function and
639 @param AndData The value to AND with the PCI configuration register.
641 @retval 0xFFFF Invalid PCI address.
642 @retval other The value written back to the PCI configuration register.
652 ASSERT_INVALID_PCI_ADDRESS (Address
);
653 if (Address
>= PcdPciExpressBaseSize ()) {
657 return MmioAnd16 ((UINTN
)GetPciExpressBaseAddress () + Address
, AndData
);
661 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
662 value, followed a bitwise OR with another 16-bit value.
664 Reads the 16-bit PCI configuration register specified by Address, performs a
665 bitwise AND between the read result and the value specified by AndData,
666 performs a bitwise OR between the result of the AND operation and
667 the value specified by OrData, and writes the result to the 16-bit PCI
668 configuration register specified by Address. The value written to the PCI
669 configuration register is returned. This function must guarantee that all PCI
670 read and write operations are serialized.
672 If Address > 0x0FFFFFFF, then ASSERT().
673 If Address is not aligned on a 16-bit boundary, then ASSERT().
675 @param Address The address that encodes the PCI Bus, Device, Function and
677 @param AndData The value to AND with the PCI configuration register.
678 @param OrData The value to OR with the result of the AND operation.
680 @retval 0xFFFF Invalid PCI address.
681 @retval other The value written back to the PCI configuration register.
686 PciExpressAndThenOr16 (
692 ASSERT_INVALID_PCI_ADDRESS (Address
);
693 if (Address
>= PcdPciExpressBaseSize ()) {
697 return MmioAndThenOr16 (
698 (UINTN
)GetPciExpressBaseAddress () + Address
,
705 Reads a bit field of a PCI configuration register.
707 Reads the bit field in a 16-bit PCI configuration register. The bit field is
708 specified by the StartBit and the EndBit. The value of the bit field is
711 If Address > 0x0FFFFFFF, then ASSERT().
712 If Address is not aligned on a 16-bit boundary, then ASSERT().
713 If StartBit is greater than 15, then ASSERT().
714 If EndBit is greater than 15, then ASSERT().
715 If EndBit is less than StartBit, then ASSERT().
717 @param Address The PCI configuration register to read.
718 @param StartBit The ordinal of the least significant bit in the bit field.
720 @param EndBit The ordinal of the most significant bit in the bit field.
723 @retval 0xFFFF Invalid PCI address.
724 @retval other The value of the bit field read from the PCI configuration
730 PciExpressBitFieldRead16 (
736 ASSERT_INVALID_PCI_ADDRESS (Address
);
737 if (Address
>= PcdPciExpressBaseSize ()) {
741 return MmioBitFieldRead16 (
742 (UINTN
)GetPciExpressBaseAddress () + Address
,
749 Writes a bit field to a PCI configuration register.
751 Writes Value to the bit field of the PCI configuration register. The bit
752 field is specified by the StartBit and the EndBit. All other bits in the
753 destination PCI configuration register are preserved. The new value of the
754 16-bit register is returned.
756 If Address > 0x0FFFFFFF, then ASSERT().
757 If Address is not aligned on a 16-bit boundary, then ASSERT().
758 If StartBit is greater than 15, then ASSERT().
759 If EndBit is greater than 15, then ASSERT().
760 If EndBit is less than StartBit, then ASSERT().
761 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
763 @param Address The PCI configuration register to write.
764 @param StartBit The ordinal of the least significant bit in the bit field.
766 @param EndBit The ordinal of the most significant bit in the bit field.
768 @param Value The new value of the bit field.
770 @retval 0xFFFF Invalid PCI address.
771 @retval other The value written back to the PCI configuration register.
776 PciExpressBitFieldWrite16 (
783 ASSERT_INVALID_PCI_ADDRESS (Address
);
784 if (Address
>= PcdPciExpressBaseSize ()) {
788 return MmioBitFieldWrite16 (
789 (UINTN
)GetPciExpressBaseAddress () + Address
,
797 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
798 writes the result back to the bit field in the 16-bit port.
800 Reads the 16-bit PCI configuration register specified by Address, performs a
801 bitwise OR between the read result and the value specified by
802 OrData, and writes the result to the 16-bit PCI configuration register
803 specified by Address. The value written to the PCI configuration register is
804 returned. This function must guarantee that all PCI read and write operations
805 are serialized. Extra left bits in OrData are stripped.
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 OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
814 @param Address The PCI configuration register to write.
815 @param StartBit The ordinal of the least significant bit in the bit field.
817 @param EndBit The ordinal of the most significant bit in the bit field.
819 @param OrData The value to OR with the PCI configuration register.
821 @retval 0xFFFF Invalid PCI address.
822 @retval other The value written back to the PCI configuration register.
827 PciExpressBitFieldOr16 (
834 ASSERT_INVALID_PCI_ADDRESS (Address
);
835 if (Address
>= PcdPciExpressBaseSize ()) {
839 return MmioBitFieldOr16 (
840 (UINTN
)GetPciExpressBaseAddress () + Address
,
848 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
849 AND, and writes the result back to the bit field in the 16-bit register.
851 Reads the 16-bit PCI configuration register specified by Address, performs a
852 bitwise AND between the read result and the value specified by AndData, and
853 writes the result to the 16-bit PCI configuration register specified by
854 Address. The value written to the PCI configuration register is returned.
855 This function must guarantee that all PCI read and write operations are
856 serialized. Extra left bits in AndData are stripped.
858 If Address > 0x0FFFFFFF, then ASSERT().
859 If Address is not aligned on a 16-bit boundary, then ASSERT().
860 If StartBit is greater than 15, then ASSERT().
861 If EndBit is greater than 15, then ASSERT().
862 If EndBit is less than StartBit, then ASSERT().
863 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
865 @param Address The PCI configuration register to write.
866 @param StartBit The ordinal of the least significant bit in the bit field.
868 @param EndBit The ordinal of the most significant bit in the bit field.
870 @param AndData The value to AND with the PCI configuration register.
872 @retval 0xFFFF Invalid PCI address.
873 @retval other The value written back to the PCI configuration register.
878 PciExpressBitFieldAnd16 (
885 ASSERT_INVALID_PCI_ADDRESS (Address
);
886 if (Address
>= PcdPciExpressBaseSize ()) {
890 return MmioBitFieldAnd16 (
891 (UINTN
)GetPciExpressBaseAddress () + Address
,
899 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
900 bitwise OR, and writes the result back to the bit field in the
903 Reads the 16-bit PCI configuration register specified by Address, performs a
904 bitwise AND followed by a bitwise OR between the read result and
905 the value specified by AndData, and writes the result to the 16-bit PCI
906 configuration register specified by Address. The value written to the PCI
907 configuration register is returned. This function must guarantee that all PCI
908 read and write operations are serialized. Extra left bits in both AndData and
911 If Address > 0x0FFFFFFF, then ASSERT().
912 If Address is not aligned on a 16-bit boundary, then ASSERT().
913 If StartBit is greater than 15, then ASSERT().
914 If EndBit is greater than 15, then ASSERT().
915 If EndBit is less than StartBit, then ASSERT().
916 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
917 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
919 @param Address The PCI configuration register to write.
920 @param StartBit The ordinal of the least significant bit in the bit field.
922 @param EndBit The ordinal of the most significant bit in the bit field.
924 @param AndData The value to AND with the PCI configuration register.
925 @param OrData The value to OR with the result of the AND operation.
927 @retval 0xFFFF Invalid PCI address.
928 @retval other The value written back to the PCI configuration register.
933 PciExpressBitFieldAndThenOr16 (
941 ASSERT_INVALID_PCI_ADDRESS (Address
);
942 if (Address
>= PcdPciExpressBaseSize ()) {
946 return MmioBitFieldAndThenOr16 (
947 (UINTN
)GetPciExpressBaseAddress () + Address
,
956 Reads a 32-bit PCI configuration register.
958 Reads and returns the 32-bit PCI configuration register specified by Address.
959 This function must guarantee that all PCI read and write operations are
962 If Address > 0x0FFFFFFF, then ASSERT().
963 If Address is not aligned on a 32-bit boundary, then ASSERT().
965 @param Address The address that encodes the PCI Bus, Device, Function and
968 @retval 0xFFFF Invalid PCI address.
969 @retval other The read value from the PCI configuration register.
978 ASSERT_INVALID_PCI_ADDRESS (Address
);
979 if (Address
>= PcdPciExpressBaseSize ()) {
983 return MmioRead32 ((UINTN
)GetPciExpressBaseAddress () + Address
);
987 Writes a 32-bit PCI configuration register.
989 Writes the 32-bit PCI configuration register specified by Address with the
990 value specified by Value. Value is returned. This function must guarantee
991 that all PCI read and write operations are serialized.
993 If Address > 0x0FFFFFFF, then ASSERT().
994 If Address is not aligned on a 32-bit boundary, then ASSERT().
996 @param Address The address that encodes the PCI Bus, Device, Function and
998 @param Value The value to write.
1000 @retval 0xFFFFFFFF Invalid PCI address.
1001 @retval other The value written to the PCI configuration register.
1011 ASSERT_INVALID_PCI_ADDRESS (Address
);
1012 if (Address
>= PcdPciExpressBaseSize ()) {
1016 return MmioWrite32 ((UINTN
)GetPciExpressBaseAddress () + Address
, Value
);
1020 Performs a bitwise OR of a 32-bit PCI configuration register with
1023 Reads the 32-bit PCI configuration register specified by Address, performs a
1024 bitwise OR between the read result and the value specified by
1025 OrData, and writes the result to the 32-bit PCI configuration register
1026 specified by Address. The value written to the PCI configuration register is
1027 returned. This function must guarantee that all PCI read and write operations
1030 If Address > 0x0FFFFFFF, then ASSERT().
1031 If Address is not aligned on a 32-bit boundary, then ASSERT().
1033 @param Address The address that encodes the PCI Bus, Device, Function and
1035 @param OrData The value to OR with the PCI configuration register.
1037 @retval 0xFFFFFFFF Invalid PCI address.
1038 @retval other The value written back to the PCI configuration register.
1048 ASSERT_INVALID_PCI_ADDRESS (Address
);
1049 if (Address
>= PcdPciExpressBaseSize ()) {
1053 return MmioOr32 ((UINTN
)GetPciExpressBaseAddress () + Address
, OrData
);
1057 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1060 Reads the 32-bit PCI configuration register specified by Address, performs a
1061 bitwise AND between the read result and the value specified by AndData, and
1062 writes the result to the 32-bit PCI configuration register specified by
1063 Address. The value written to the PCI configuration register is returned.
1064 This function must guarantee that all PCI read and write operations are
1067 If Address > 0x0FFFFFFF, then ASSERT().
1068 If Address is not aligned on a 32-bit boundary, then ASSERT().
1070 @param Address The address that encodes the PCI Bus, Device, Function and
1072 @param AndData The value to AND with the PCI configuration register.
1074 @retval 0xFFFFFFFF Invalid PCI address.
1075 @retval other The value written back to the PCI configuration register.
1085 ASSERT_INVALID_PCI_ADDRESS (Address
);
1086 if (Address
>= PcdPciExpressBaseSize ()) {
1090 return MmioAnd32 ((UINTN
)GetPciExpressBaseAddress () + Address
, AndData
);
1094 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1095 value, followed a bitwise OR with another 32-bit value.
1097 Reads the 32-bit PCI configuration register specified by Address, performs a
1098 bitwise AND between the read result and the value specified by AndData,
1099 performs a bitwise OR between the result of the AND operation and
1100 the value specified by OrData, and writes the result to the 32-bit PCI
1101 configuration register specified by Address. The value written to the PCI
1102 configuration register is returned. This function must guarantee that all PCI
1103 read and write operations are serialized.
1105 If Address > 0x0FFFFFFF, then ASSERT().
1106 If Address is not aligned on a 32-bit boundary, then ASSERT().
1108 @param Address The address that encodes the PCI Bus, Device, Function and
1110 @param AndData The value to AND with the PCI configuration register.
1111 @param OrData The value to OR with the result of the AND operation.
1113 @retval 0xFFFFFFFF Invalid PCI address.
1114 @retval other The value written back to the PCI configuration register.
1119 PciExpressAndThenOr32 (
1125 ASSERT_INVALID_PCI_ADDRESS (Address
);
1126 if (Address
>= PcdPciExpressBaseSize ()) {
1130 return MmioAndThenOr32 (
1131 (UINTN
)GetPciExpressBaseAddress () + Address
,
1138 Reads a bit field of a PCI configuration register.
1140 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1141 specified by the StartBit and the EndBit. The value of the bit field is
1144 If Address > 0x0FFFFFFF, then ASSERT().
1145 If Address is not aligned on a 32-bit boundary, then ASSERT().
1146 If StartBit is greater than 31, then ASSERT().
1147 If EndBit is greater than 31, then ASSERT().
1148 If EndBit is less than StartBit, then ASSERT().
1150 @param Address The PCI configuration register to read.
1151 @param StartBit The ordinal of the least significant bit in the bit field.
1153 @param EndBit The ordinal of the most significant bit in the bit field.
1156 @retval 0xFFFFFFFF Invalid PCI address.
1157 @retval other The value of the bit field read from the PCI
1158 configuration register.
1163 PciExpressBitFieldRead32 (
1169 ASSERT_INVALID_PCI_ADDRESS (Address
);
1170 if (Address
>= PcdPciExpressBaseSize ()) {
1174 return MmioBitFieldRead32 (
1175 (UINTN
)GetPciExpressBaseAddress () + Address
,
1182 Writes a bit field to a PCI configuration register.
1184 Writes Value to the bit field of the PCI configuration register. The bit
1185 field is specified by the StartBit and the EndBit. All other bits in the
1186 destination PCI configuration register are preserved. The new value of the
1187 32-bit register is returned.
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 Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1196 @param Address The PCI configuration register to write.
1197 @param StartBit The ordinal of the least significant bit in the bit field.
1199 @param EndBit The ordinal of the most significant bit in the bit field.
1201 @param Value The new value of the bit field.
1203 @retval 0xFFFFFFFF Invalid PCI address.
1204 @retval other The value written back to the PCI configuration register.
1209 PciExpressBitFieldWrite32 (
1216 ASSERT_INVALID_PCI_ADDRESS (Address
);
1217 if (Address
>= PcdPciExpressBaseSize ()) {
1221 return MmioBitFieldWrite32 (
1222 (UINTN
)GetPciExpressBaseAddress () + Address
,
1230 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1231 writes the result back to the bit field in the 32-bit port.
1233 Reads the 32-bit PCI configuration register specified by Address, performs a
1234 bitwise OR between the read result and the value specified by
1235 OrData, and writes the result to the 32-bit PCI configuration register
1236 specified by Address. The value written to the PCI configuration register is
1237 returned. This function must guarantee that all PCI read and write operations
1238 are serialized. Extra left bits in OrData are stripped.
1240 If Address > 0x0FFFFFFF, then ASSERT().
1241 If Address is not aligned on a 32-bit boundary, then ASSERT().
1242 If StartBit is greater than 31, then ASSERT().
1243 If EndBit is greater than 31, then ASSERT().
1244 If EndBit is less than StartBit, then ASSERT().
1245 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1247 @param Address The PCI configuration register to write.
1248 @param StartBit The ordinal of the least significant bit in the bit field.
1250 @param EndBit The ordinal of the most significant bit in the bit field.
1252 @param OrData The value to OR with the PCI configuration register.
1254 @retval 0xFFFFFFFF Invalid PCI address.
1255 @retval other The value written back to the PCI configuration register.
1260 PciExpressBitFieldOr32 (
1267 ASSERT_INVALID_PCI_ADDRESS (Address
);
1268 if (Address
>= PcdPciExpressBaseSize ()) {
1272 return MmioBitFieldOr32 (
1273 (UINTN
)GetPciExpressBaseAddress () + Address
,
1281 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1282 AND, and writes the result back to the bit field in the 32-bit register.
1284 Reads the 32-bit PCI configuration register specified by Address, performs a
1285 bitwise AND between the read result and the value specified by AndData, and
1286 writes the result to the 32-bit PCI configuration register specified by
1287 Address. The value written to the PCI configuration register is returned.
1288 This function must guarantee that all PCI read and write operations are
1289 serialized. Extra left bits in AndData are stripped.
1291 If Address > 0x0FFFFFFF, then ASSERT().
1292 If Address is not aligned on a 32-bit boundary, then ASSERT().
1293 If StartBit is greater than 31, then ASSERT().
1294 If EndBit is greater than 31, then ASSERT().
1295 If EndBit is less than StartBit, then ASSERT().
1296 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1298 @param Address The PCI configuration register to write.
1299 @param StartBit The ordinal of the least significant bit in the bit field.
1301 @param EndBit The ordinal of the most significant bit in the bit field.
1303 @param AndData The value to AND with the PCI configuration register.
1305 @retval 0xFFFFFFFF Invalid PCI address.
1306 @retval other The value written back to the PCI configuration register.
1311 PciExpressBitFieldAnd32 (
1318 ASSERT_INVALID_PCI_ADDRESS (Address
);
1319 if (Address
>= PcdPciExpressBaseSize ()) {
1323 return MmioBitFieldAnd32 (
1324 (UINTN
)GetPciExpressBaseAddress () + Address
,
1332 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1333 bitwise OR, and writes the result back to the bit field in the
1336 Reads the 32-bit PCI configuration register specified by Address, performs a
1337 bitwise AND followed by a bitwise OR between the read result and
1338 the value specified by AndData, and writes the result to the 32-bit PCI
1339 configuration register specified by Address. The value written to the PCI
1340 configuration register is returned. This function must guarantee that all PCI
1341 read and write operations are serialized. Extra left bits in both AndData and
1342 OrData are stripped.
1344 If Address > 0x0FFFFFFF, then ASSERT().
1345 If Address is not aligned on a 32-bit boundary, then ASSERT().
1346 If StartBit is greater than 31, then ASSERT().
1347 If EndBit is greater than 31, then ASSERT().
1348 If EndBit is less than StartBit, then ASSERT().
1349 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1350 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1352 @param Address The PCI configuration register to write.
1353 @param StartBit The ordinal of the least significant bit in the bit field.
1355 @param EndBit The ordinal of the most significant bit in the bit field.
1357 @param AndData The value to AND with the PCI configuration register.
1358 @param OrData The value to OR with the result of the AND operation.
1360 @retval 0xFFFFFFFF Invalid PCI address.
1361 @retval other The value written back to the PCI configuration register.
1366 PciExpressBitFieldAndThenOr32 (
1374 ASSERT_INVALID_PCI_ADDRESS (Address
);
1375 if (Address
>= PcdPciExpressBaseSize ()) {
1379 return MmioBitFieldAndThenOr32 (
1380 (UINTN
)GetPciExpressBaseAddress () + Address
,
1389 Reads a range of PCI configuration registers into a caller supplied buffer.
1391 Reads the range of PCI configuration registers specified by StartAddress and
1392 Size into the buffer specified by Buffer. This function only allows the PCI
1393 configuration registers from a single PCI function to be read. Size is
1394 returned. When possible 32-bit PCI configuration read cycles are used to read
1395 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1396 and 16-bit PCI configuration read cycles may be used at the beginning and the
1399 If StartAddress > 0x0FFFFFFF, then ASSERT().
1400 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1401 If Size > 0 and Buffer is NULL, then ASSERT().
1403 @param StartAddress The starting address that encodes the PCI Bus, Device,
1404 Function and Register.
1405 @param Size The size in bytes of the transfer.
1406 @param Buffer The pointer to a buffer receiving the data read.
1408 @retval (UINTN)-1 Invalid PCI address.
1409 @retval other Size read data from StartAddress.
1414 PciExpressReadBuffer (
1415 IN UINTN StartAddress
,
1422 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1423 if (StartAddress
>= PcdPciExpressBaseSize ()) {
1427 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1433 ASSERT (Buffer
!= NULL
);
1436 // Save Size for return
1440 if ((StartAddress
& 1) != 0) {
1442 // Read a byte if StartAddress is byte aligned
1444 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1445 StartAddress
+= sizeof (UINT8
);
1446 Size
-= sizeof (UINT8
);
1447 Buffer
= (UINT8
*)Buffer
+ 1;
1450 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& 2) != 0)) {
1452 // Read a word if StartAddress is word aligned
1454 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
)PciExpressRead16 (StartAddress
));
1456 StartAddress
+= sizeof (UINT16
);
1457 Size
-= sizeof (UINT16
);
1458 Buffer
= (UINT16
*)Buffer
+ 1;
1461 while (Size
>= sizeof (UINT32
)) {
1463 // Read as many double words as possible
1465 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
)PciExpressRead32 (StartAddress
));
1467 StartAddress
+= sizeof (UINT32
);
1468 Size
-= sizeof (UINT32
);
1469 Buffer
= (UINT32
*)Buffer
+ 1;
1472 if (Size
>= sizeof (UINT16
)) {
1474 // Read the last remaining word if exist
1476 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
)PciExpressRead16 (StartAddress
));
1477 StartAddress
+= sizeof (UINT16
);
1478 Size
-= sizeof (UINT16
);
1479 Buffer
= (UINT16
*)Buffer
+ 1;
1482 if (Size
>= sizeof (UINT8
)) {
1484 // Read the last remaining byte if exist
1486 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1493 Copies the data in a caller supplied buffer to a specified range of PCI
1494 configuration space.
1496 Writes the range of PCI configuration registers specified by StartAddress and
1497 Size from the buffer specified by Buffer. This function only allows the PCI
1498 configuration registers from a single PCI function to be written. Size is
1499 returned. When possible 32-bit PCI configuration write cycles are used to
1500 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1501 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1502 and the end of the range.
1504 If StartAddress > 0x0FFFFFFF, then ASSERT().
1505 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1506 If Size > 0 and Buffer is NULL, then ASSERT().
1508 @param StartAddress The starting address that encodes the PCI Bus, Device,
1509 Function and Register.
1510 @param Size The size in bytes of the transfer.
1511 @param Buffer The pointer to a buffer containing the data to write.
1513 @retval (UINTN)-1 Invalid PCI address.
1514 @retval other Size written to StartAddress.
1519 PciExpressWriteBuffer (
1520 IN UINTN StartAddress
,
1527 ASSERT_INVALID_PCI_ADDRESS (StartAddress
);
1528 if (StartAddress
>= PcdPciExpressBaseSize ()) {
1532 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1538 ASSERT (Buffer
!= NULL
);
1541 // Save Size for return
1545 if ((StartAddress
& 1) != 0) {
1547 // Write a byte if StartAddress is byte aligned
1549 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1550 StartAddress
+= sizeof (UINT8
);
1551 Size
-= sizeof (UINT8
);
1552 Buffer
= (UINT8
*)Buffer
+ 1;
1555 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& 2) != 0)) {
1557 // Write a word if StartAddress is word aligned
1559 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1560 StartAddress
+= sizeof (UINT16
);
1561 Size
-= sizeof (UINT16
);
1562 Buffer
= (UINT16
*)Buffer
+ 1;
1565 while (Size
>= sizeof (UINT32
)) {
1567 // Write as many double words as possible
1569 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1570 StartAddress
+= sizeof (UINT32
);
1571 Size
-= sizeof (UINT32
);
1572 Buffer
= (UINT32
*)Buffer
+ 1;
1575 if (Size
>= sizeof (UINT16
)) {
1577 // Write the last remaining word if exist
1579 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1580 StartAddress
+= sizeof (UINT16
);
1581 Size
-= sizeof (UINT16
);
1582 Buffer
= (UINT16
*)Buffer
+ 1;
1585 if (Size
>= sizeof (UINT8
)) {
1587 // Write the last remaining byte if exist
1589 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);