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 <Guid/EventGroup.h>
18 #include <Library/BaseLib.h>
19 #include <Library/PciExpressLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PcdLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/DxeServicesTableLib.h>
26 #include <Library/UefiRuntimeLib.h>
29 /// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime
32 UINTN PhysicalAddress
;
34 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
;
37 /// Set Virtual Address Map Event
39 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent
= NULL
;
42 /// Module global that contains the base physical address of the PCI Express MMIO range.
44 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress
= 0;
47 /// The number of PCI devices that have been registered for runtime access.
49 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges
= 0;
52 /// The table of PCI devices that have been registered for runtime access.
54 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
*mDxeRuntimePciExpressLibRegistrationTable
= NULL
;
57 /// The table index of the most recent virtual address lookup.
59 UINTN mDxeRuntimePciExpressLibLastRuntimeRange
= 0;
63 Convert the physical PCI Express MMIO addresses for all registered PCI devices
66 @param[in] Event The event that is being processed.
67 @param[in] Context The Event Context.
71 DxeRuntimePciExpressLibVirtualNotify (
79 // If there have been no runtime registrations, then just return
81 if (mDxeRuntimePciExpressLibRegistrationTable
== NULL
) {
86 // Convert physical addresses associated with the set of registered PCI devices to
89 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
90 EfiConvertPointer (0, (VOID
**) &(mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
));
94 // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.
96 EfiConvertPointer (0, (VOID
**) &mDxeRuntimePciExpressLibRegistrationTable
);
100 The constructor function caches the PCI Express Base Address and creates a
101 Set Virtual Address Map event to convert physical address to virtual addresses.
103 @param ImageHandle The firmware allocated handle for the EFI image.
104 @param SystemTable A pointer to the EFI System Table.
106 @retval EFI_SUCCESS The constructor completed successfully.
107 @retval Other value The constructor did not complete successfully.
112 DxeRuntimePciExpressLibConstructor (
113 IN EFI_HANDLE ImageHandle
,
114 IN EFI_SYSTEM_TABLE
*SystemTable
120 // Cache the physical address of the PCI Express MMIO range into a module global variable
122 mDxeRuntimePciExpressLibPciExpressBaseAddress
= (UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
125 // Register SetVirtualAddressMap () notify function
127 Status
= gBS
->CreateEventEx (
130 DxeRuntimePciExpressLibVirtualNotify
,
132 &gEfiEventVirtualAddressChangeGuid
,
133 &mDxeRuntimePciExpressLibVirtualNotifyEvent
135 ASSERT_EFI_ERROR (Status
);
141 The destructor function frees any allocated buffers and closes the Set Virtual
144 @param ImageHandle The firmware allocated handle for the EFI image.
145 @param SystemTable A pointer to the EFI System Table.
147 @retval EFI_SUCCESS The destructor completed successfully.
148 @retval Other value The destructor did not complete successfully.
153 DxeRuntimePciExpressLibDestructor (
154 IN EFI_HANDLE ImageHandle
,
155 IN EFI_SYSTEM_TABLE
*SystemTable
161 // If one or more PCI devices have been registered for runtime access, then
162 // free the registration table.
164 if (mDxeRuntimePciExpressLibRegistrationTable
!= NULL
) {
165 FreePool (mDxeRuntimePciExpressLibRegistrationTable
);
169 // Close the Set Virtual Address Map event
171 Status
= gBS
->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent
);
172 ASSERT_EFI_ERROR (Status
);
178 Gets the base address of PCI Express.
180 This internal functions retrieves PCI Express Base Address via a PCD entry
181 PcdPciExpressBaseAddress.
183 @param Address The address that encodes the PCI Bus, Device, Function and Register.
184 @return The base address of PCI Express.
188 GetPciExpressAddress (
195 // Make sure Address is valid
197 ASSERT (((Address
) & ~0xfffffff) == 0);
200 // Convert Address to a physical address in the MMIO PCI Express range
202 Address
+= mDxeRuntimePciExpressLibPciExpressBaseAddress
;
205 // If SetVirtualAddressMap() has not been called, then just return the physical address
207 if (!EfiGoneVirtual ()) {
212 // See if there is a physical address match at the exact same index as the last address match
214 if (mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].PhysicalAddress
== (Address
& (~0x00000fff))) {
216 // Convert the physical address to a virtual address and return the virtual address
218 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].VirtualAddress
;
222 // Search the entire table for a physical address match
224 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
225 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== (Address
& (~0x00000fff))) {
227 // Cache the matching index value
229 mDxeRuntimePciExpressLibLastRuntimeRange
= Index
;
231 // Convert the physical address to a virtual address and return the virtual address
233 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
;
238 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
244 // Return the physical address
250 Registers a PCI device so PCI configuration registers may be accessed after
251 SetVirtualAddressMap().
253 Registers the PCI device specified by Address so all the PCI configuration
254 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
257 If Address > 0x0FFFFFFF, then ASSERT().
259 @param Address The address that encodes the PCI Bus, Device, Function and
262 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
263 @retval RETURN_UNSUPPORTED An attempt was made to call this function
264 after ExitBootServices().
265 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
266 at runtime could not be mapped.
267 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
268 complete the registration.
273 PciExpressRegisterForRuntimeAccess (
278 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
283 // Return an error if this function is called after ExitBootServices().
285 if (EfiAtRuntime ()) {
286 return RETURN_UNSUPPORTED
;
290 // Make sure Address is valid
292 ASSERT (((Address
) & ~0xfffffff) == 0);
295 // Convert Address to a physical address in the MMIO PCI Express range
296 // at the beginning of the PCI Configuration header for the specified
299 Address
= GetPciExpressAddress (Address
& 0x0ffff000);
302 // See if Address has already been registerd for runtime access
304 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
305 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== Address
) {
306 return RETURN_SUCCESS
;
311 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
313 Status
= gDS
->GetMemorySpaceDescriptor (Address
, &Descriptor
);
314 if (EFI_ERROR (Status
)) {
315 return RETURN_UNSUPPORTED
;
319 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
320 // will allocate a virtual address range for the 4KB PCI Configuration Header.
322 Status
= gDS
->SetMemorySpaceAttributes (Address
, 0x1000, Descriptor
.Attributes
| EFI_MEMORY_RUNTIME
);
323 if (EFI_ERROR (Status
)) {
324 return RETURN_UNSUPPORTED
;
328 // Grow the size of the registration table
330 NewTable
= ReallocateRuntimePool (
331 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
332 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
333 mDxeRuntimePciExpressLibRegistrationTable
335 if (NewTable
== NULL
) {
336 return RETURN_OUT_OF_RESOURCES
;
338 mDxeRuntimePciExpressLibRegistrationTable
= NewTable
;
339 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].PhysicalAddress
= Address
;
340 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].VirtualAddress
= Address
;
341 mDxeRuntimePciExpressLibNumberOfRuntimeRanges
++;
343 return RETURN_SUCCESS
;
348 Reads an 8-bit PCI configuration register.
350 Reads and returns the 8-bit PCI configuration register specified by Address.
351 This function must guarantee that all PCI read and write operations are
354 If Address > 0x0FFFFFFF, then ASSERT().
356 @param Address The address that encodes the PCI Bus, Device, Function and
359 @return The read value from the PCI configuration register.
368 return MmioRead8 (GetPciExpressAddress (Address
));
372 Writes an 8-bit PCI configuration register.
374 Writes the 8-bit PCI configuration register specified by Address with the
375 value specified by Value. Value is returned. This function must guarantee
376 that all PCI read and write operations are serialized.
378 If Address > 0x0FFFFFFF, then ASSERT().
380 @param Address The address that encodes the PCI Bus, Device, Function and
382 @param Value The value to write.
384 @return The value written to the PCI configuration register.
394 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
398 Performs a bitwise OR of an 8-bit PCI configuration register with
401 Reads the 8-bit PCI configuration register specified by Address, performs a
402 bitwise OR between the read result and the value specified by
403 OrData, and writes the result to the 8-bit PCI configuration register
404 specified by Address. The value written to the PCI configuration register is
405 returned. This function must guarantee that all PCI read and write operations
408 If Address > 0x0FFFFFFF, then ASSERT().
410 @param Address The address that encodes the PCI Bus, Device, Function and
412 @param OrData The value to OR with the PCI configuration register.
414 @return The value written back to the PCI configuration register.
424 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
428 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
431 Reads the 8-bit PCI configuration register specified by Address, performs a
432 bitwise AND between the read result and the value specified by AndData, and
433 writes the result to the 8-bit PCI configuration register specified by
434 Address. The value written to the PCI configuration register is returned.
435 This function must guarantee that all PCI read and write operations are
438 If Address > 0x0FFFFFFF, then ASSERT().
440 @param Address The address that encodes the PCI Bus, Device, Function and
442 @param AndData The value to AND with the PCI configuration register.
444 @return The value written back to the PCI configuration register.
454 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
458 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
459 value, followed a bitwise OR with another 8-bit value.
461 Reads the 8-bit PCI configuration register specified by Address, performs a
462 bitwise AND between the read result and the value specified by AndData,
463 performs a bitwise OR between the result of the AND operation and
464 the value specified by OrData, and writes the result to the 8-bit PCI
465 configuration register specified by Address. The value written to the PCI
466 configuration register is returned. This function must guarantee that all PCI
467 read and write operations are serialized.
469 If Address > 0x0FFFFFFF, then ASSERT().
471 @param Address The address that encodes the PCI Bus, Device, Function and
473 @param AndData The value to AND with the PCI configuration register.
474 @param OrData The value to OR with the result of the AND operation.
476 @return The value written back to the PCI configuration register.
481 PciExpressAndThenOr8 (
487 return MmioAndThenOr8 (
488 GetPciExpressAddress (Address
),
495 Reads a bit field of a PCI configuration register.
497 Reads the bit field in an 8-bit PCI configuration register. The bit field is
498 specified by the StartBit and the EndBit. The value of the bit field is
501 If Address > 0x0FFFFFFF, then ASSERT().
502 If StartBit is greater than 7, then ASSERT().
503 If EndBit is greater than 7, then ASSERT().
504 If EndBit is less than StartBit, then ASSERT().
506 @param Address The PCI configuration register to read.
507 @param StartBit The ordinal of the least significant bit in the bit field.
509 @param EndBit The ordinal of the most significant bit in the bit field.
512 @return The value of the bit field read from the PCI configuration register.
517 PciExpressBitFieldRead8 (
523 return MmioBitFieldRead8 (
524 GetPciExpressAddress (Address
),
531 Writes a bit field to a PCI configuration register.
533 Writes Value to the bit field of the PCI configuration register. The bit
534 field is specified by the StartBit and the EndBit. All other bits in the
535 destination PCI configuration register are preserved. The new value of the
536 8-bit register is returned.
538 If Address > 0x0FFFFFFF, then ASSERT().
539 If StartBit is greater than 7, then ASSERT().
540 If EndBit is greater than 7, then ASSERT().
541 If EndBit is less than StartBit, then ASSERT().
542 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
544 @param Address The PCI configuration register to write.
545 @param StartBit The ordinal of the least significant bit in the bit field.
547 @param EndBit The ordinal of the most significant bit in the bit field.
549 @param Value The new value of the bit field.
551 @return The value written back to the PCI configuration register.
556 PciExpressBitFieldWrite8 (
563 return MmioBitFieldWrite8 (
564 GetPciExpressAddress (Address
),
572 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
573 writes the result back to the bit field in the 8-bit port.
575 Reads the 8-bit PCI configuration register specified by Address, performs a
576 bitwise OR between the read result and the value specified by
577 OrData, and writes the result to the 8-bit PCI configuration register
578 specified by Address. The value written to the PCI configuration register is
579 returned. This function must guarantee that all PCI read and write operations
580 are serialized. Extra left bits in OrData are stripped.
582 If Address > 0x0FFFFFFF, then ASSERT().
583 If StartBit is greater than 7, then ASSERT().
584 If EndBit is greater than 7, then ASSERT().
585 If EndBit is less than StartBit, then ASSERT().
586 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
588 @param Address The PCI configuration register to write.
589 @param StartBit The ordinal of the least significant bit in the bit field.
591 @param EndBit The ordinal of the most significant bit in the bit field.
593 @param OrData The value to OR with the PCI configuration register.
595 @return The value written back to the PCI configuration register.
600 PciExpressBitFieldOr8 (
607 return MmioBitFieldOr8 (
608 GetPciExpressAddress (Address
),
616 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
617 AND, and writes the result back to the bit field in the 8-bit register.
619 Reads the 8-bit PCI configuration register specified by Address, performs a
620 bitwise AND between the read result and the value specified by AndData, and
621 writes the result to the 8-bit PCI configuration register specified by
622 Address. The value written to the PCI configuration register is returned.
623 This function must guarantee that all PCI read and write operations are
624 serialized. Extra left bits in AndData are stripped.
626 If Address > 0x0FFFFFFF, then ASSERT().
627 If StartBit is greater than 7, then ASSERT().
628 If EndBit is greater than 7, then ASSERT().
629 If EndBit is less than StartBit, then ASSERT().
630 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
632 @param Address The PCI configuration register to write.
633 @param StartBit The ordinal of the least significant bit in the bit field.
635 @param EndBit The ordinal of the most significant bit in the bit field.
637 @param AndData The value to AND with the PCI configuration register.
639 @return The value written back to the PCI configuration register.
644 PciExpressBitFieldAnd8 (
651 return MmioBitFieldAnd8 (
652 GetPciExpressAddress (Address
),
660 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
661 bitwise OR, and writes the result back to the bit field in the
664 Reads the 8-bit PCI configuration register specified by Address, performs a
665 bitwise AND followed by a bitwise OR between the read result and
666 the value specified by AndData, and writes the result to the 8-bit PCI
667 configuration register specified by Address. The value written to the PCI
668 configuration register is returned. This function must guarantee that all PCI
669 read and write operations are serialized. Extra left bits in both AndData and
672 If Address > 0x0FFFFFFF, then ASSERT().
673 If StartBit is greater than 7, then ASSERT().
674 If EndBit is greater than 7, then ASSERT().
675 If EndBit is less than StartBit, then ASSERT().
676 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
677 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
679 @param Address The PCI configuration register to write.
680 @param StartBit The ordinal of the least significant bit in the bit field.
682 @param EndBit The ordinal of the most significant bit in the bit field.
684 @param AndData The value to AND with the PCI configuration register.
685 @param OrData The value to OR with the result of the AND operation.
687 @return The value written back to the PCI configuration register.
692 PciExpressBitFieldAndThenOr8 (
700 return MmioBitFieldAndThenOr8 (
701 GetPciExpressAddress (Address
),
710 Reads a 16-bit PCI configuration register.
712 Reads and returns the 16-bit PCI configuration register specified by Address.
713 This function must guarantee that all PCI read and write operations are
716 If Address > 0x0FFFFFFF, then ASSERT().
717 If Address is not aligned on a 16-bit boundary, then ASSERT().
719 @param Address The address that encodes the PCI Bus, Device, Function and
722 @return The read value from the PCI configuration register.
731 return MmioRead16 (GetPciExpressAddress (Address
));
735 Writes a 16-bit PCI configuration register.
737 Writes the 16-bit PCI configuration register specified by Address with the
738 value specified by Value. Value is returned. This function must guarantee
739 that all PCI read and write operations are serialized.
741 If Address > 0x0FFFFFFF, then ASSERT().
742 If Address is not aligned on a 16-bit boundary, then ASSERT().
744 @param Address The address that encodes the PCI Bus, Device, Function and
746 @param Value The value to write.
748 @return The value written to the PCI configuration register.
758 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
762 Performs a bitwise OR of a 16-bit PCI configuration register with
765 Reads the 16-bit PCI configuration register specified by Address, performs a
766 bitwise OR between the read result and the value specified by
767 OrData, and writes the result to the 16-bit PCI configuration register
768 specified by Address. The value written to the PCI configuration register is
769 returned. This function must guarantee that all PCI read and write operations
772 If Address > 0x0FFFFFFF, then ASSERT().
773 If Address is not aligned on a 16-bit boundary, then ASSERT().
775 @param Address The address that encodes the PCI Bus, Device, Function and
777 @param OrData The value to OR with the PCI configuration register.
779 @return The value written back to the PCI configuration register.
789 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
793 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
796 Reads the 16-bit PCI configuration register specified by Address, performs a
797 bitwise AND between the read result and the value specified by AndData, and
798 writes the result to the 16-bit PCI configuration register specified by
799 Address. The value written to the PCI configuration register is returned.
800 This function must guarantee that all PCI read and write operations are
803 If Address > 0x0FFFFFFF, then ASSERT().
804 If Address is not aligned on a 16-bit boundary, then ASSERT().
806 @param Address The address that encodes the PCI Bus, Device, Function and
808 @param AndData The value to AND with the PCI configuration register.
810 @return The value written back to the PCI configuration register.
820 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
824 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
825 value, followed a bitwise OR with another 16-bit value.
827 Reads the 16-bit PCI configuration register specified by Address, performs a
828 bitwise AND between the read result and the value specified by AndData,
829 performs a bitwise OR between the result of the AND operation and
830 the value specified by OrData, and writes the result to the 16-bit PCI
831 configuration register specified by Address. The value written to the PCI
832 configuration register is returned. This function must guarantee that all PCI
833 read and write operations are serialized.
835 If Address > 0x0FFFFFFF, then ASSERT().
836 If Address is not aligned on a 16-bit boundary, then ASSERT().
838 @param Address The address that encodes the PCI Bus, Device, Function and
840 @param AndData The value to AND with the PCI configuration register.
841 @param OrData The value to OR with the result of the AND operation.
843 @return The value written back to the PCI configuration register.
848 PciExpressAndThenOr16 (
854 return MmioAndThenOr16 (
855 GetPciExpressAddress (Address
),
862 Reads a bit field of a PCI configuration register.
864 Reads the bit field in a 16-bit PCI configuration register. The bit field is
865 specified by the StartBit and the EndBit. The value of the bit field is
868 If Address > 0x0FFFFFFF, then ASSERT().
869 If Address is not aligned on a 16-bit boundary, then ASSERT().
870 If StartBit is greater than 15, then ASSERT().
871 If EndBit is greater than 15, then ASSERT().
872 If EndBit is less than StartBit, then ASSERT().
874 @param Address The PCI configuration register to read.
875 @param StartBit The ordinal of the least significant bit in the bit field.
877 @param EndBit The ordinal of the most significant bit in the bit field.
880 @return The value of the bit field read from the PCI configuration register.
885 PciExpressBitFieldRead16 (
891 return MmioBitFieldRead16 (
892 GetPciExpressAddress (Address
),
899 Writes a bit field to a PCI configuration register.
901 Writes Value to the bit field of the PCI configuration register. The bit
902 field is specified by the StartBit and the EndBit. All other bits in the
903 destination PCI configuration register are preserved. The new value of the
904 16-bit register is returned.
906 If Address > 0x0FFFFFFF, then ASSERT().
907 If Address is not aligned on a 16-bit boundary, then ASSERT().
908 If StartBit is greater than 15, then ASSERT().
909 If EndBit is greater than 15, then ASSERT().
910 If EndBit is less than StartBit, then ASSERT().
911 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
913 @param Address The PCI configuration register to write.
914 @param StartBit The ordinal of the least significant bit in the bit field.
916 @param EndBit The ordinal of the most significant bit in the bit field.
918 @param Value The new value of the bit field.
920 @return The value written back to the PCI configuration register.
925 PciExpressBitFieldWrite16 (
932 return MmioBitFieldWrite16 (
933 GetPciExpressAddress (Address
),
941 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
942 writes the result back to the bit field in the 16-bit port.
944 Reads the 16-bit PCI configuration register specified by Address, performs a
945 bitwise OR between the read result and the value specified by
946 OrData, and writes the result to the 16-bit PCI configuration register
947 specified by Address. The value written to the PCI configuration register is
948 returned. This function must guarantee that all PCI read and write operations
949 are serialized. Extra left bits in OrData are stripped.
951 If Address > 0x0FFFFFFF, then ASSERT().
952 If Address is not aligned on a 16-bit boundary, then ASSERT().
953 If StartBit is greater than 15, then ASSERT().
954 If EndBit is greater than 15, then ASSERT().
955 If EndBit is less than StartBit, then ASSERT().
956 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
958 @param Address The PCI configuration register to write.
959 @param StartBit The ordinal of the least significant bit in the bit field.
961 @param EndBit The ordinal of the most significant bit in the bit field.
963 @param OrData The value to OR with the PCI configuration register.
965 @return The value written back to the PCI configuration register.
970 PciExpressBitFieldOr16 (
977 return MmioBitFieldOr16 (
978 GetPciExpressAddress (Address
),
986 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
987 AND, and writes the result back to the bit field in the 16-bit register.
989 Reads the 16-bit PCI configuration register specified by Address, performs a
990 bitwise AND between the read result and the value specified by AndData, and
991 writes the result to the 16-bit PCI configuration register specified by
992 Address. The value written to the PCI configuration register is returned.
993 This function must guarantee that all PCI read and write operations are
994 serialized. Extra left bits in AndData are stripped.
996 If Address > 0x0FFFFFFF, then ASSERT().
997 If Address is not aligned on a 16-bit boundary, then ASSERT().
998 If StartBit is greater than 15, then ASSERT().
999 If EndBit is greater than 15, then ASSERT().
1000 If EndBit is less than StartBit, then ASSERT().
1001 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1003 @param Address The PCI configuration register to write.
1004 @param StartBit The ordinal of the least significant bit in the bit field.
1006 @param EndBit The ordinal of the most significant bit in the bit field.
1008 @param AndData The value to AND with the PCI configuration register.
1010 @return The value written back to the PCI configuration register.
1015 PciExpressBitFieldAnd16 (
1022 return MmioBitFieldAnd16 (
1023 GetPciExpressAddress (Address
),
1031 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1032 bitwise OR, and writes the result back to the bit field in the
1035 Reads the 16-bit PCI configuration register specified by Address, performs a
1036 bitwise AND followed by a bitwise OR between the read result and
1037 the value specified by AndData, and writes the result to the 16-bit PCI
1038 configuration register specified by Address. The value written to the PCI
1039 configuration register is returned. This function must guarantee that all PCI
1040 read and write operations are serialized. Extra left bits in both AndData and
1041 OrData are stripped.
1043 If Address > 0x0FFFFFFF, then ASSERT().
1044 If Address is not aligned on a 16-bit boundary, then ASSERT().
1045 If StartBit is greater than 15, then ASSERT().
1046 If EndBit is greater than 15, then ASSERT().
1047 If EndBit is less than StartBit, then ASSERT().
1048 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1049 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1051 @param Address The PCI configuration register to write.
1052 @param StartBit The ordinal of the least significant bit in the bit field.
1054 @param EndBit The ordinal of the most significant bit in the bit field.
1056 @param AndData The value to AND with the PCI configuration register.
1057 @param OrData The value to OR with the result of the AND operation.
1059 @return The value written back to the PCI configuration register.
1064 PciExpressBitFieldAndThenOr16 (
1072 return MmioBitFieldAndThenOr16 (
1073 GetPciExpressAddress (Address
),
1082 Reads a 32-bit PCI configuration register.
1084 Reads and returns the 32-bit PCI configuration register specified by Address.
1085 This function must guarantee that all PCI read and write operations are
1088 If Address > 0x0FFFFFFF, then ASSERT().
1089 If Address is not aligned on a 32-bit boundary, then ASSERT().
1091 @param Address The address that encodes the PCI Bus, Device, Function and
1094 @return The read value from the PCI configuration register.
1103 return MmioRead32 (GetPciExpressAddress (Address
));
1107 Writes a 32-bit PCI configuration register.
1109 Writes the 32-bit PCI configuration register specified by Address with the
1110 value specified by Value. Value is returned. This function must guarantee
1111 that all PCI read and write operations are serialized.
1113 If Address > 0x0FFFFFFF, then ASSERT().
1114 If Address is not aligned on a 32-bit boundary, then ASSERT().
1116 @param Address The address that encodes the PCI Bus, Device, Function and
1118 @param Value The value to write.
1120 @return The value written to the PCI configuration register.
1130 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1134 Performs a bitwise OR of a 32-bit PCI configuration register with
1137 Reads the 32-bit PCI configuration register specified by Address, performs a
1138 bitwise OR between the read result and the value specified by
1139 OrData, and writes the result to the 32-bit PCI configuration register
1140 specified by Address. The value written to the PCI configuration register is
1141 returned. This function must guarantee that all PCI read and write operations
1144 If Address > 0x0FFFFFFF, then ASSERT().
1145 If Address is not aligned on a 32-bit boundary, then ASSERT().
1147 @param Address The address that encodes the PCI Bus, Device, Function and
1149 @param OrData The value to OR with the PCI configuration register.
1151 @return The value written back to the PCI configuration register.
1161 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1165 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1168 Reads the 32-bit PCI configuration register specified by Address, performs a
1169 bitwise AND between the read result and the value specified by AndData, and
1170 writes the result to the 32-bit PCI configuration register specified by
1171 Address. The value written to the PCI configuration register is returned.
1172 This function must guarantee that all PCI read and write operations are
1175 If Address > 0x0FFFFFFF, then ASSERT().
1176 If Address is not aligned on a 32-bit boundary, then ASSERT().
1178 @param Address The address that encodes the PCI Bus, Device, Function and
1180 @param AndData The value to AND with the PCI configuration register.
1182 @return The value written back to the PCI configuration register.
1192 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1196 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1197 value, followed a bitwise OR with another 32-bit value.
1199 Reads the 32-bit PCI configuration register specified by Address, performs a
1200 bitwise AND between the read result and the value specified by AndData,
1201 performs a bitwise OR between the result of the AND operation and
1202 the value specified by OrData, and writes the result to the 32-bit PCI
1203 configuration register specified by Address. The value written to the PCI
1204 configuration register is returned. This function must guarantee that all PCI
1205 read and write operations are serialized.
1207 If Address > 0x0FFFFFFF, then ASSERT().
1208 If Address is not aligned on a 32-bit boundary, then ASSERT().
1210 @param Address The address that encodes the PCI Bus, Device, Function and
1212 @param AndData The value to AND with the PCI configuration register.
1213 @param OrData The value to OR with the result of the AND operation.
1215 @return The value written back to the PCI configuration register.
1220 PciExpressAndThenOr32 (
1226 return MmioAndThenOr32 (
1227 GetPciExpressAddress (Address
),
1234 Reads a bit field of a PCI configuration register.
1236 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1237 specified by the StartBit and the EndBit. The value of the bit field is
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().
1246 @param Address The PCI configuration register to read.
1247 @param StartBit The ordinal of the least significant bit in the bit field.
1249 @param EndBit The ordinal of the most significant bit in the bit field.
1252 @return The value of the bit field read from the PCI configuration register.
1257 PciExpressBitFieldRead32 (
1263 return MmioBitFieldRead32 (
1264 GetPciExpressAddress (Address
),
1271 Writes a bit field to a PCI configuration register.
1273 Writes Value to the bit field of the PCI configuration register. The bit
1274 field is specified by the StartBit and the EndBit. All other bits in the
1275 destination PCI configuration register are preserved. The new value of the
1276 32-bit register is returned.
1278 If Address > 0x0FFFFFFF, then ASSERT().
1279 If Address is not aligned on a 32-bit boundary, then ASSERT().
1280 If StartBit is greater than 31, then ASSERT().
1281 If EndBit is greater than 31, then ASSERT().
1282 If EndBit is less than StartBit, then ASSERT().
1283 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1285 @param Address The PCI configuration register to write.
1286 @param StartBit The ordinal of the least significant bit in the bit field.
1288 @param EndBit The ordinal of the most significant bit in the bit field.
1290 @param Value The new value of the bit field.
1292 @return The value written back to the PCI configuration register.
1297 PciExpressBitFieldWrite32 (
1304 return MmioBitFieldWrite32 (
1305 GetPciExpressAddress (Address
),
1313 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1314 writes the result back to the bit field in the 32-bit port.
1316 Reads the 32-bit PCI configuration register specified by Address, performs a
1317 bitwise OR between the read result and the value specified by
1318 OrData, and writes the result to the 32-bit PCI configuration register
1319 specified by Address. The value written to the PCI configuration register is
1320 returned. This function must guarantee that all PCI read and write operations
1321 are serialized. Extra left bits in OrData are stripped.
1323 If Address > 0x0FFFFFFF, then ASSERT().
1324 If Address is not aligned on a 32-bit boundary, then ASSERT().
1325 If StartBit is greater than 31, then ASSERT().
1326 If EndBit is greater than 31, then ASSERT().
1327 If EndBit is less than StartBit, then ASSERT().
1328 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1330 @param Address The PCI configuration register to write.
1331 @param StartBit The ordinal of the least significant bit in the bit field.
1333 @param EndBit The ordinal of the most significant bit in the bit field.
1335 @param OrData The value to OR with the PCI configuration register.
1337 @return The value written back to the PCI configuration register.
1342 PciExpressBitFieldOr32 (
1349 return MmioBitFieldOr32 (
1350 GetPciExpressAddress (Address
),
1358 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1359 AND, and writes the result back to the bit field in the 32-bit register.
1361 Reads the 32-bit PCI configuration register specified by Address, performs a
1362 bitwise AND between the read result and the value specified by AndData, and
1363 writes the result to the 32-bit PCI configuration register specified by
1364 Address. The value written to the PCI configuration register is returned.
1365 This function must guarantee that all PCI read and write operations are
1366 serialized. Extra left bits in AndData are stripped.
1368 If Address > 0x0FFFFFFF, then ASSERT().
1369 If Address is not aligned on a 32-bit boundary, then ASSERT().
1370 If StartBit is greater than 31, then ASSERT().
1371 If EndBit is greater than 31, then ASSERT().
1372 If EndBit is less than StartBit, then ASSERT().
1373 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1375 @param Address The PCI configuration register to write.
1376 @param StartBit The ordinal of the least significant bit in the bit field.
1378 @param EndBit The ordinal of the most significant bit in the bit field.
1380 @param AndData The value to AND with the PCI configuration register.
1382 @return The value written back to the PCI configuration register.
1387 PciExpressBitFieldAnd32 (
1394 return MmioBitFieldAnd32 (
1395 GetPciExpressAddress (Address
),
1403 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1404 bitwise OR, and writes the result back to the bit field in the
1407 Reads the 32-bit PCI configuration register specified by Address, performs a
1408 bitwise AND followed by a bitwise OR between the read result and
1409 the value specified by AndData, and writes the result to the 32-bit PCI
1410 configuration register specified by Address. The value written to the PCI
1411 configuration register is returned. This function must guarantee that all PCI
1412 read and write operations are serialized. Extra left bits in both AndData and
1413 OrData are stripped.
1415 If Address > 0x0FFFFFFF, then ASSERT().
1416 If Address is not aligned on a 32-bit boundary, then ASSERT().
1417 If StartBit is greater than 31, then ASSERT().
1418 If EndBit is greater than 31, then ASSERT().
1419 If EndBit is less than StartBit, then ASSERT().
1420 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1421 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1423 @param Address The PCI configuration register to write.
1424 @param StartBit The ordinal of the least significant bit in the bit field.
1426 @param EndBit The ordinal of the most significant bit in the bit field.
1428 @param AndData The value to AND with the PCI configuration register.
1429 @param OrData The value to OR with the result of the AND operation.
1431 @return The value written back to the PCI configuration register.
1436 PciExpressBitFieldAndThenOr32 (
1444 return MmioBitFieldAndThenOr32 (
1445 GetPciExpressAddress (Address
),
1454 Reads a range of PCI configuration registers into a caller supplied buffer.
1456 Reads the range of PCI configuration registers specified by StartAddress and
1457 Size into the buffer specified by Buffer. This function only allows the PCI
1458 configuration registers from a single PCI function to be read. Size is
1459 returned. When possible 32-bit PCI configuration read cycles are used to read
1460 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1461 and 16-bit PCI configuration read cycles may be used at the beginning and the
1464 If StartAddress > 0x0FFFFFFF, then ASSERT().
1465 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1466 If Size > 0 and Buffer is NULL, then ASSERT().
1468 @param StartAddress The starting address that encodes the PCI Bus, Device,
1469 Function and Register.
1470 @param Size The size in bytes of the transfer.
1471 @param Buffer The pointer to a buffer receiving the data read.
1473 @return Size read data from StartAddress.
1478 PciExpressReadBuffer (
1479 IN UINTN StartAddress
,
1487 // Make sure Address is valid
1489 ASSERT (((StartAddress
) & ~0xfffffff) == 0);
1490 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1496 ASSERT (Buffer
!= NULL
);
1499 // Save Size for return
1503 if ((StartAddress
& 1) != 0) {
1505 // Read a byte if StartAddress is byte aligned
1507 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1508 StartAddress
+= sizeof (UINT8
);
1509 Size
-= sizeof (UINT8
);
1510 Buffer
= (UINT8
*)Buffer
+ 1;
1513 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1515 // Read a word if StartAddress is word aligned
1517 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1519 StartAddress
+= sizeof (UINT16
);
1520 Size
-= sizeof (UINT16
);
1521 Buffer
= (UINT16
*)Buffer
+ 1;
1524 while (Size
>= sizeof (UINT32
)) {
1526 // Read as many double words as possible
1528 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1530 StartAddress
+= sizeof (UINT32
);
1531 Size
-= sizeof (UINT32
);
1532 Buffer
= (UINT32
*)Buffer
+ 1;
1535 if (Size
>= sizeof (UINT16
)) {
1537 // Read the last remaining word if exist
1539 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1540 StartAddress
+= sizeof (UINT16
);
1541 Size
-= sizeof (UINT16
);
1542 Buffer
= (UINT16
*)Buffer
+ 1;
1545 if (Size
>= sizeof (UINT8
)) {
1547 // Read the last remaining byte if exist
1549 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1556 Copies the data in a caller supplied buffer to a specified range of PCI
1557 configuration space.
1559 Writes the range of PCI configuration registers specified by StartAddress and
1560 Size from the buffer specified by Buffer. This function only allows the PCI
1561 configuration registers from a single PCI function to be written. Size is
1562 returned. When possible 32-bit PCI configuration write cycles are used to
1563 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1564 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1565 and the end of the range.
1567 If StartAddress > 0x0FFFFFFF, then ASSERT().
1568 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1569 If Size > 0 and Buffer is NULL, then ASSERT().
1571 @param StartAddress The starting address that encodes the PCI Bus, Device,
1572 Function and Register.
1573 @param Size The size in bytes of the transfer.
1574 @param Buffer The pointer to a buffer containing the data to write.
1576 @return Size written to StartAddress.
1581 PciExpressWriteBuffer (
1582 IN UINTN StartAddress
,
1590 // Make sure Address is valid
1592 ASSERT (((StartAddress
) & ~0xfffffff) == 0);
1593 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1599 ASSERT (Buffer
!= NULL
);
1602 // Save Size for return
1606 if ((StartAddress
& 1) != 0) {
1608 // Write a byte if StartAddress is byte aligned
1610 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1611 StartAddress
+= sizeof (UINT8
);
1612 Size
-= sizeof (UINT8
);
1613 Buffer
= (UINT8
*)Buffer
+ 1;
1616 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1618 // Write a word if StartAddress is word aligned
1620 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1621 StartAddress
+= sizeof (UINT16
);
1622 Size
-= sizeof (UINT16
);
1623 Buffer
= (UINT16
*)Buffer
+ 1;
1626 while (Size
>= sizeof (UINT32
)) {
1628 // Write as many double words as possible
1630 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1631 StartAddress
+= sizeof (UINT32
);
1632 Size
-= sizeof (UINT32
);
1633 Buffer
= (UINT32
*)Buffer
+ 1;
1636 if (Size
>= sizeof (UINT16
)) {
1638 // Write the last remaining word if exist
1640 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1641 StartAddress
+= sizeof (UINT16
);
1642 Size
-= sizeof (UINT16
);
1643 Buffer
= (UINT16
*)Buffer
+ 1;
1646 if (Size
>= sizeof (UINT8
)) {
1648 // Write the last remaining byte if exist
1650 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);