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
->CreateEvent (
128 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
130 DxeRuntimePciExpressLibVirtualNotify
,
132 &mDxeRuntimePciExpressLibVirtualNotifyEvent
134 ASSERT_EFI_ERROR (Status
);
140 The destructor function frees any allocated buffers and closes the Set Virtual
143 @param ImageHandle The firmware allocated handle for the EFI image.
144 @param SystemTable A pointer to the EFI System Table.
146 @retval EFI_SUCCESS The destructor completed successfully.
147 @retval Other value The destructor did not complete successfully.
152 DxeRuntimePciExpressLibDestructor (
153 IN EFI_HANDLE ImageHandle
,
154 IN EFI_SYSTEM_TABLE
*SystemTable
160 // If one or more PCI devices have been registered for runtime access, then
161 // free the registration table.
163 if (mDxeRuntimePciExpressLibRegistrationTable
!= NULL
) {
164 FreePool (mDxeRuntimePciExpressLibRegistrationTable
);
168 // Close the Set Virtual Address Map event
170 Status
= gBS
->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent
);
171 ASSERT_EFI_ERROR (Status
);
177 Gets the base address of PCI Express.
179 This internal functions retrieves PCI Express Base Address via a PCD entry
180 PcdPciExpressBaseAddress.
182 @param Address The address that encodes the PCI Bus, Device, Function and Register.
183 @return The base address of PCI Express.
187 GetPciExpressAddress (
194 // Make sure Address is valid
196 ASSERT (((Address
) & ~0xfffffff) == 0);
199 // Convert Address to a physical address in the MMIO PCI Express range
201 Address
+= mDxeRuntimePciExpressLibPciExpressBaseAddress
;
204 // If SetVirtualAddressMap() has not been called, then just return the physical address
206 if (!EfiGoneVirtual ()) {
211 // See if there is a physical address match at the exact same index as the last address match
213 if (mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].PhysicalAddress
== (Address
& (~0x00000fff))) {
215 // Convert the physical address to a virtual address and return the virtual address
217 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].VirtualAddress
;
221 // Search the entire table for a physical address match
223 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
224 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== (Address
& (~0x00000fff))) {
226 // Cache the matching index value
228 mDxeRuntimePciExpressLibLastRuntimeRange
= Index
;
230 // Convert the physical address to a virtual address and return the virtual address
232 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
;
237 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
243 // Return the physical address
249 Registers a PCI device so PCI configuration registers may be accessed after
250 SetVirtualAddressMap().
252 Registers the PCI device specified by Address so all the PCI configuration
253 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
256 If Address > 0x0FFFFFFF, then ASSERT().
258 @param Address The address that encodes the PCI Bus, Device, Function and
261 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
262 @retval RETURN_UNSUPPORTED An attempt was made to call this function
263 after ExitBootServices().
264 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
265 at runtime could not be mapped.
266 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
267 complete the registration.
272 PciExpressRegisterForRuntimeAccess (
277 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
282 // Return an error if this function is called after ExitBootServices().
284 if (EfiAtRuntime ()) {
285 return RETURN_UNSUPPORTED
;
289 // Make sure Address is valid
291 ASSERT (((Address
) & ~0xfffffff) == 0);
294 // Convert Address to a physical address in the MMIO PCI Express range
295 // at the beginning of the PCI Configuration header for the specified
298 Address
= GetPciExpressAddress (Address
& 0x0ffff000);
301 // See if Address has already been registered for runtime access
303 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
304 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== Address
) {
305 return RETURN_SUCCESS
;
310 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
312 Status
= gDS
->GetMemorySpaceDescriptor (Address
, &Descriptor
);
313 if (EFI_ERROR (Status
)) {
314 return RETURN_UNSUPPORTED
;
318 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
319 // will allocate a virtual address range for the 4KB PCI Configuration Header.
321 Status
= gDS
->SetMemorySpaceAttributes (Address
, 0x1000, Descriptor
.Attributes
| EFI_MEMORY_RUNTIME
);
322 if (EFI_ERROR (Status
)) {
323 return RETURN_UNSUPPORTED
;
327 // Grow the size of the registration table
329 NewTable
= ReallocateRuntimePool (
330 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
331 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
332 mDxeRuntimePciExpressLibRegistrationTable
334 if (NewTable
== NULL
) {
335 return RETURN_OUT_OF_RESOURCES
;
337 mDxeRuntimePciExpressLibRegistrationTable
= NewTable
;
338 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].PhysicalAddress
= Address
;
339 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].VirtualAddress
= Address
;
340 mDxeRuntimePciExpressLibNumberOfRuntimeRanges
++;
342 return RETURN_SUCCESS
;
347 Reads an 8-bit PCI configuration register.
349 Reads and returns the 8-bit PCI configuration register specified by Address.
350 This function must guarantee that all PCI read and write operations are
353 If Address > 0x0FFFFFFF, then ASSERT().
355 @param Address The address that encodes the PCI Bus, Device, Function and
358 @return The read value from the PCI configuration register.
367 return MmioRead8 (GetPciExpressAddress (Address
));
371 Writes an 8-bit PCI configuration register.
373 Writes the 8-bit PCI configuration register specified by Address with the
374 value specified by Value. Value is returned. This function must guarantee
375 that all PCI read and write operations are serialized.
377 If Address > 0x0FFFFFFF, then ASSERT().
379 @param Address The address that encodes the PCI Bus, Device, Function and
381 @param Value The value to write.
383 @return The value written to the PCI configuration register.
393 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
397 Performs a bitwise OR of an 8-bit PCI configuration register with
400 Reads the 8-bit PCI configuration register specified by Address, performs a
401 bitwise OR between the read result and the value specified by
402 OrData, and writes the result to the 8-bit PCI configuration register
403 specified by Address. The value written to the PCI configuration register is
404 returned. This function must guarantee that all PCI read and write operations
407 If Address > 0x0FFFFFFF, then ASSERT().
409 @param Address The address that encodes the PCI Bus, Device, Function and
411 @param OrData The value to OR with the PCI configuration register.
413 @return The value written back to the PCI configuration register.
423 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
427 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
430 Reads the 8-bit PCI configuration register specified by Address, performs a
431 bitwise AND between the read result and the value specified by AndData, and
432 writes the result to the 8-bit PCI configuration register specified by
433 Address. The value written to the PCI configuration register is returned.
434 This function must guarantee that all PCI read and write operations are
437 If Address > 0x0FFFFFFF, then ASSERT().
439 @param Address The address that encodes the PCI Bus, Device, Function and
441 @param AndData The value to AND with the PCI configuration register.
443 @return The value written back to the PCI configuration register.
453 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
457 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
458 value, followed a bitwise OR with another 8-bit value.
460 Reads the 8-bit PCI configuration register specified by Address, performs a
461 bitwise AND between the read result and the value specified by AndData,
462 performs a bitwise OR between the result of the AND operation and
463 the value specified by OrData, and writes the result to the 8-bit PCI
464 configuration register specified by Address. The value written to the PCI
465 configuration register is returned. This function must guarantee that all PCI
466 read and write operations are serialized.
468 If Address > 0x0FFFFFFF, then ASSERT().
470 @param Address The address that encodes the PCI Bus, Device, Function and
472 @param AndData The value to AND with the PCI configuration register.
473 @param OrData The value to OR with the result of the AND operation.
475 @return The value written back to the PCI configuration register.
480 PciExpressAndThenOr8 (
486 return MmioAndThenOr8 (
487 GetPciExpressAddress (Address
),
494 Reads a bit field of a PCI configuration register.
496 Reads the bit field in an 8-bit PCI configuration register. The bit field is
497 specified by the StartBit and the EndBit. The value of the bit field is
500 If Address > 0x0FFFFFFF, then ASSERT().
501 If StartBit is greater than 7, then ASSERT().
502 If EndBit is greater than 7, then ASSERT().
503 If EndBit is less than StartBit, then ASSERT().
505 @param Address The PCI configuration register to read.
506 @param StartBit The ordinal of the least significant bit in the bit field.
508 @param EndBit The ordinal of the most significant bit in the bit field.
511 @return The value of the bit field read from the PCI configuration register.
516 PciExpressBitFieldRead8 (
522 return MmioBitFieldRead8 (
523 GetPciExpressAddress (Address
),
530 Writes a bit field to a PCI configuration register.
532 Writes Value to the bit field of the PCI configuration register. The bit
533 field is specified by the StartBit and the EndBit. All other bits in the
534 destination PCI configuration register are preserved. The new value of the
535 8-bit register is returned.
537 If Address > 0x0FFFFFFF, then ASSERT().
538 If StartBit is greater than 7, then ASSERT().
539 If EndBit is greater than 7, then ASSERT().
540 If EndBit is less than StartBit, then ASSERT().
541 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
543 @param Address The PCI configuration register to write.
544 @param StartBit The ordinal of the least significant bit in the bit field.
546 @param EndBit The ordinal of the most significant bit in the bit field.
548 @param Value The new value of the bit field.
550 @return The value written back to the PCI configuration register.
555 PciExpressBitFieldWrite8 (
562 return MmioBitFieldWrite8 (
563 GetPciExpressAddress (Address
),
571 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
572 writes the result back to the bit field in the 8-bit port.
574 Reads the 8-bit PCI configuration register specified by Address, performs a
575 bitwise OR between the read result and the value specified by
576 OrData, and writes the result to the 8-bit PCI configuration register
577 specified by Address. The value written to the PCI configuration register is
578 returned. This function must guarantee that all PCI read and write operations
579 are serialized. Extra left bits in OrData are stripped.
581 If Address > 0x0FFFFFFF, then ASSERT().
582 If StartBit is greater than 7, then ASSERT().
583 If EndBit is greater than 7, then ASSERT().
584 If EndBit is less than StartBit, then ASSERT().
585 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
587 @param Address The PCI configuration register to write.
588 @param StartBit The ordinal of the least significant bit in the bit field.
590 @param EndBit The ordinal of the most significant bit in the bit field.
592 @param OrData The value to OR with the PCI configuration register.
594 @return The value written back to the PCI configuration register.
599 PciExpressBitFieldOr8 (
606 return MmioBitFieldOr8 (
607 GetPciExpressAddress (Address
),
615 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
616 AND, and writes the result back to the bit field in the 8-bit register.
618 Reads the 8-bit PCI configuration register specified by Address, performs a
619 bitwise AND between the read result and the value specified by AndData, and
620 writes the result to the 8-bit PCI configuration register specified by
621 Address. The value written to the PCI configuration register is returned.
622 This function must guarantee that all PCI read and write operations are
623 serialized. Extra left bits in AndData are stripped.
625 If Address > 0x0FFFFFFF, then ASSERT().
626 If StartBit is greater than 7, then ASSERT().
627 If EndBit is greater than 7, then ASSERT().
628 If EndBit is less than StartBit, then ASSERT().
629 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
631 @param Address The PCI configuration register to write.
632 @param StartBit The ordinal of the least significant bit in the bit field.
634 @param EndBit The ordinal of the most significant bit in the bit field.
636 @param AndData The value to AND with the PCI configuration register.
638 @return The value written back to the PCI configuration register.
643 PciExpressBitFieldAnd8 (
650 return MmioBitFieldAnd8 (
651 GetPciExpressAddress (Address
),
659 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
660 bitwise OR, and writes the result back to the bit field in the
663 Reads the 8-bit PCI configuration register specified by Address, performs a
664 bitwise AND followed by a bitwise OR between the read result and
665 the value specified by AndData, and writes the result to the 8-bit PCI
666 configuration register specified by Address. The value written to the PCI
667 configuration register is returned. This function must guarantee that all PCI
668 read and write operations are serialized. Extra left bits in both AndData and
671 If Address > 0x0FFFFFFF, then ASSERT().
672 If StartBit is greater than 7, then ASSERT().
673 If EndBit is greater than 7, then ASSERT().
674 If EndBit is less than StartBit, then ASSERT().
675 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
676 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
678 @param Address The PCI configuration register to write.
679 @param StartBit The ordinal of the least significant bit in the bit field.
681 @param EndBit The ordinal of the most significant bit in the bit field.
683 @param AndData The value to AND with the PCI configuration register.
684 @param OrData The value to OR with the result of the AND operation.
686 @return The value written back to the PCI configuration register.
691 PciExpressBitFieldAndThenOr8 (
699 return MmioBitFieldAndThenOr8 (
700 GetPciExpressAddress (Address
),
709 Reads a 16-bit PCI configuration register.
711 Reads and returns the 16-bit PCI configuration register specified by Address.
712 This function must guarantee that all PCI read and write operations are
715 If Address > 0x0FFFFFFF, then ASSERT().
716 If Address is not aligned on a 16-bit boundary, then ASSERT().
718 @param Address The address that encodes the PCI Bus, Device, Function and
721 @return The read value from the PCI configuration register.
730 return MmioRead16 (GetPciExpressAddress (Address
));
734 Writes a 16-bit PCI configuration register.
736 Writes the 16-bit PCI configuration register specified by Address with the
737 value specified by Value. Value is returned. This function must guarantee
738 that all PCI read and write operations are serialized.
740 If Address > 0x0FFFFFFF, then ASSERT().
741 If Address is not aligned on a 16-bit boundary, then ASSERT().
743 @param Address The address that encodes the PCI Bus, Device, Function and
745 @param Value The value to write.
747 @return The value written to the PCI configuration register.
757 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
761 Performs a bitwise OR of a 16-bit PCI configuration register with
764 Reads the 16-bit PCI configuration register specified by Address, performs a
765 bitwise OR between the read result and the value specified by
766 OrData, and writes the result to the 16-bit PCI configuration register
767 specified by Address. The value written to the PCI configuration register is
768 returned. This function must guarantee that all PCI read and write operations
771 If Address > 0x0FFFFFFF, then ASSERT().
772 If Address is not aligned on a 16-bit boundary, then ASSERT().
774 @param Address The address that encodes the PCI Bus, Device, Function and
776 @param OrData The value to OR with the PCI configuration register.
778 @return The value written back to the PCI configuration register.
788 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
792 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
795 Reads the 16-bit PCI configuration register specified by Address, performs a
796 bitwise AND between the read result and the value specified by AndData, and
797 writes the result to the 16-bit PCI configuration register specified by
798 Address. The value written to the PCI configuration register is returned.
799 This function must guarantee that all PCI read and write operations are
802 If Address > 0x0FFFFFFF, then ASSERT().
803 If Address is not aligned on a 16-bit boundary, then ASSERT().
805 @param Address The address that encodes the PCI Bus, Device, Function and
807 @param AndData The value to AND with the PCI configuration register.
809 @return The value written back to the PCI configuration register.
819 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
823 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
824 value, followed a bitwise OR with another 16-bit value.
826 Reads the 16-bit PCI configuration register specified by Address, performs a
827 bitwise AND between the read result and the value specified by AndData,
828 performs a bitwise OR between the result of the AND operation and
829 the value specified by OrData, and writes the result to the 16-bit PCI
830 configuration register specified by Address. The value written to the PCI
831 configuration register is returned. This function must guarantee that all PCI
832 read and write operations are serialized.
834 If Address > 0x0FFFFFFF, then ASSERT().
835 If Address is not aligned on a 16-bit boundary, then ASSERT().
837 @param Address The address that encodes the PCI Bus, Device, Function and
839 @param AndData The value to AND with the PCI configuration register.
840 @param OrData The value to OR with the result of the AND operation.
842 @return The value written back to the PCI configuration register.
847 PciExpressAndThenOr16 (
853 return MmioAndThenOr16 (
854 GetPciExpressAddress (Address
),
861 Reads a bit field of a PCI configuration register.
863 Reads the bit field in a 16-bit PCI configuration register. The bit field is
864 specified by the StartBit and the EndBit. The value of the bit field is
867 If Address > 0x0FFFFFFF, then ASSERT().
868 If Address is not aligned on a 16-bit boundary, then ASSERT().
869 If StartBit is greater than 15, then ASSERT().
870 If EndBit is greater than 15, then ASSERT().
871 If EndBit is less than StartBit, then ASSERT().
873 @param Address The PCI configuration register to read.
874 @param StartBit The ordinal of the least significant bit in the bit field.
876 @param EndBit The ordinal of the most significant bit in the bit field.
879 @return The value of the bit field read from the PCI configuration register.
884 PciExpressBitFieldRead16 (
890 return MmioBitFieldRead16 (
891 GetPciExpressAddress (Address
),
898 Writes a bit field to a PCI configuration register.
900 Writes Value to the bit field of the PCI configuration register. The bit
901 field is specified by the StartBit and the EndBit. All other bits in the
902 destination PCI configuration register are preserved. The new value of the
903 16-bit register is returned.
905 If Address > 0x0FFFFFFF, then ASSERT().
906 If Address is not aligned on a 16-bit boundary, then ASSERT().
907 If StartBit is greater than 15, then ASSERT().
908 If EndBit is greater than 15, then ASSERT().
909 If EndBit is less than StartBit, then ASSERT().
910 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
912 @param Address The PCI configuration register to write.
913 @param StartBit The ordinal of the least significant bit in the bit field.
915 @param EndBit The ordinal of the most significant bit in the bit field.
917 @param Value The new value of the bit field.
919 @return The value written back to the PCI configuration register.
924 PciExpressBitFieldWrite16 (
931 return MmioBitFieldWrite16 (
932 GetPciExpressAddress (Address
),
940 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
941 writes the result back to the bit field in the 16-bit port.
943 Reads the 16-bit PCI configuration register specified by Address, performs a
944 bitwise OR between the read result and the value specified by
945 OrData, and writes the result to the 16-bit PCI configuration register
946 specified by Address. The value written to the PCI configuration register is
947 returned. This function must guarantee that all PCI read and write operations
948 are serialized. Extra left bits in OrData are stripped.
950 If Address > 0x0FFFFFFF, then ASSERT().
951 If Address is not aligned on a 16-bit boundary, then ASSERT().
952 If StartBit is greater than 15, then ASSERT().
953 If EndBit is greater than 15, then ASSERT().
954 If EndBit is less than StartBit, then ASSERT().
955 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
957 @param Address The PCI configuration register to write.
958 @param StartBit The ordinal of the least significant bit in the bit field.
960 @param EndBit The ordinal of the most significant bit in the bit field.
962 @param OrData The value to OR with the PCI configuration register.
964 @return The value written back to the PCI configuration register.
969 PciExpressBitFieldOr16 (
976 return MmioBitFieldOr16 (
977 GetPciExpressAddress (Address
),
985 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
986 AND, and writes the result back to the bit field in the 16-bit register.
988 Reads the 16-bit PCI configuration register specified by Address, performs a
989 bitwise AND between the read result and the value specified by AndData, and
990 writes the result to the 16-bit PCI configuration register specified by
991 Address. The value written to the PCI configuration register is returned.
992 This function must guarantee that all PCI read and write operations are
993 serialized. Extra left bits in AndData are stripped.
995 If Address > 0x0FFFFFFF, then ASSERT().
996 If Address is not aligned on a 16-bit boundary, then ASSERT().
997 If StartBit is greater than 15, then ASSERT().
998 If EndBit is greater than 15, then ASSERT().
999 If EndBit is less than StartBit, then ASSERT().
1000 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1002 @param Address The PCI configuration register to write.
1003 @param StartBit The ordinal of the least significant bit in the bit field.
1005 @param EndBit The ordinal of the most significant bit in the bit field.
1007 @param AndData The value to AND with the PCI configuration register.
1009 @return The value written back to the PCI configuration register.
1014 PciExpressBitFieldAnd16 (
1021 return MmioBitFieldAnd16 (
1022 GetPciExpressAddress (Address
),
1030 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1031 bitwise OR, and writes the result back to the bit field in the
1034 Reads the 16-bit PCI configuration register specified by Address, performs a
1035 bitwise AND followed by a bitwise OR between the read result and
1036 the value specified by AndData, and writes the result to the 16-bit PCI
1037 configuration register specified by Address. The value written to the PCI
1038 configuration register is returned. This function must guarantee that all PCI
1039 read and write operations are serialized. Extra left bits in both AndData and
1040 OrData are stripped.
1042 If Address > 0x0FFFFFFF, then ASSERT().
1043 If Address is not aligned on a 16-bit boundary, then ASSERT().
1044 If StartBit is greater than 15, then ASSERT().
1045 If EndBit is greater than 15, then ASSERT().
1046 If EndBit is less than StartBit, then ASSERT().
1047 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1048 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1050 @param Address The PCI configuration register to write.
1051 @param StartBit The ordinal of the least significant bit in the bit field.
1053 @param EndBit The ordinal of the most significant bit in the bit field.
1055 @param AndData The value to AND with the PCI configuration register.
1056 @param OrData The value to OR with the result of the AND operation.
1058 @return The value written back to the PCI configuration register.
1063 PciExpressBitFieldAndThenOr16 (
1071 return MmioBitFieldAndThenOr16 (
1072 GetPciExpressAddress (Address
),
1081 Reads a 32-bit PCI configuration register.
1083 Reads and returns the 32-bit PCI configuration register specified by Address.
1084 This function must guarantee that all PCI read and write operations are
1087 If Address > 0x0FFFFFFF, then ASSERT().
1088 If Address is not aligned on a 32-bit boundary, then ASSERT().
1090 @param Address The address that encodes the PCI Bus, Device, Function and
1093 @return The read value from the PCI configuration register.
1102 return MmioRead32 (GetPciExpressAddress (Address
));
1106 Writes a 32-bit PCI configuration register.
1108 Writes the 32-bit PCI configuration register specified by Address with the
1109 value specified by Value. Value is returned. This function must guarantee
1110 that all PCI read and write operations are serialized.
1112 If Address > 0x0FFFFFFF, then ASSERT().
1113 If Address is not aligned on a 32-bit boundary, then ASSERT().
1115 @param Address The address that encodes the PCI Bus, Device, Function and
1117 @param Value The value to write.
1119 @return The value written to the PCI configuration register.
1129 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1133 Performs a bitwise OR of a 32-bit PCI configuration register with
1136 Reads the 32-bit PCI configuration register specified by Address, performs a
1137 bitwise OR between the read result and the value specified by
1138 OrData, and writes the result to the 32-bit PCI configuration register
1139 specified by Address. The value written to the PCI configuration register is
1140 returned. This function must guarantee that all PCI read and write operations
1143 If Address > 0x0FFFFFFF, then ASSERT().
1144 If Address is not aligned on a 32-bit boundary, then ASSERT().
1146 @param Address The address that encodes the PCI Bus, Device, Function and
1148 @param OrData The value to OR with the PCI configuration register.
1150 @return The value written back to the PCI configuration register.
1160 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1164 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1167 Reads the 32-bit PCI configuration register specified by Address, performs a
1168 bitwise AND between the read result and the value specified by AndData, and
1169 writes the result to the 32-bit PCI configuration register specified by
1170 Address. The value written to the PCI configuration register is returned.
1171 This function must guarantee that all PCI read and write operations are
1174 If Address > 0x0FFFFFFF, then ASSERT().
1175 If Address is not aligned on a 32-bit boundary, then ASSERT().
1177 @param Address The address that encodes the PCI Bus, Device, Function and
1179 @param AndData The value to AND with the PCI configuration register.
1181 @return The value written back to the PCI configuration register.
1191 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1195 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1196 value, followed a bitwise OR with another 32-bit value.
1198 Reads the 32-bit PCI configuration register specified by Address, performs a
1199 bitwise AND between the read result and the value specified by AndData,
1200 performs a bitwise OR between the result of the AND operation and
1201 the value specified by OrData, and writes the result to the 32-bit PCI
1202 configuration register specified by Address. The value written to the PCI
1203 configuration register is returned. This function must guarantee that all PCI
1204 read and write operations are serialized.
1206 If Address > 0x0FFFFFFF, then ASSERT().
1207 If Address is not aligned on a 32-bit boundary, then ASSERT().
1209 @param Address The address that encodes the PCI Bus, Device, Function and
1211 @param AndData The value to AND with the PCI configuration register.
1212 @param OrData The value to OR with the result of the AND operation.
1214 @return The value written back to the PCI configuration register.
1219 PciExpressAndThenOr32 (
1225 return MmioAndThenOr32 (
1226 GetPciExpressAddress (Address
),
1233 Reads a bit field of a PCI configuration register.
1235 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1236 specified by the StartBit and the EndBit. The value of the bit field is
1239 If Address > 0x0FFFFFFF, then ASSERT().
1240 If Address is not aligned on a 32-bit boundary, then ASSERT().
1241 If StartBit is greater than 31, then ASSERT().
1242 If EndBit is greater than 31, then ASSERT().
1243 If EndBit is less than StartBit, then ASSERT().
1245 @param Address The PCI configuration register to read.
1246 @param StartBit The ordinal of the least significant bit in the bit field.
1248 @param EndBit The ordinal of the most significant bit in the bit field.
1251 @return The value of the bit field read from the PCI configuration register.
1256 PciExpressBitFieldRead32 (
1262 return MmioBitFieldRead32 (
1263 GetPciExpressAddress (Address
),
1270 Writes a bit field to a PCI configuration register.
1272 Writes Value to the bit field of the PCI configuration register. The bit
1273 field is specified by the StartBit and the EndBit. All other bits in the
1274 destination PCI configuration register are preserved. The new value of the
1275 32-bit register is returned.
1277 If Address > 0x0FFFFFFF, then ASSERT().
1278 If Address is not aligned on a 32-bit boundary, then ASSERT().
1279 If StartBit is greater than 31, then ASSERT().
1280 If EndBit is greater than 31, then ASSERT().
1281 If EndBit is less than StartBit, then ASSERT().
1282 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1284 @param Address The PCI configuration register to write.
1285 @param StartBit The ordinal of the least significant bit in the bit field.
1287 @param EndBit The ordinal of the most significant bit in the bit field.
1289 @param Value The new value of the bit field.
1291 @return The value written back to the PCI configuration register.
1296 PciExpressBitFieldWrite32 (
1303 return MmioBitFieldWrite32 (
1304 GetPciExpressAddress (Address
),
1312 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1313 writes the result back to the bit field in the 32-bit port.
1315 Reads the 32-bit PCI configuration register specified by Address, performs a
1316 bitwise OR between the read result and the value specified by
1317 OrData, and writes the result to the 32-bit PCI configuration register
1318 specified by Address. The value written to the PCI configuration register is
1319 returned. This function must guarantee that all PCI read and write operations
1320 are serialized. Extra left bits in OrData are stripped.
1322 If Address > 0x0FFFFFFF, then ASSERT().
1323 If Address is not aligned on a 32-bit boundary, then ASSERT().
1324 If StartBit is greater than 31, then ASSERT().
1325 If EndBit is greater than 31, then ASSERT().
1326 If EndBit is less than StartBit, then ASSERT().
1327 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1329 @param Address The PCI configuration register to write.
1330 @param StartBit The ordinal of the least significant bit in the bit field.
1332 @param EndBit The ordinal of the most significant bit in the bit field.
1334 @param OrData The value to OR with the PCI configuration register.
1336 @return The value written back to the PCI configuration register.
1341 PciExpressBitFieldOr32 (
1348 return MmioBitFieldOr32 (
1349 GetPciExpressAddress (Address
),
1357 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1358 AND, and writes the result back to the bit field in the 32-bit register.
1360 Reads the 32-bit PCI configuration register specified by Address, performs a
1361 bitwise AND between the read result and the value specified by AndData, and
1362 writes the result to the 32-bit PCI configuration register specified by
1363 Address. The value written to the PCI configuration register is returned.
1364 This function must guarantee that all PCI read and write operations are
1365 serialized. Extra left bits in AndData are stripped.
1367 If Address > 0x0FFFFFFF, then ASSERT().
1368 If Address is not aligned on a 32-bit boundary, then ASSERT().
1369 If StartBit is greater than 31, then ASSERT().
1370 If EndBit is greater than 31, then ASSERT().
1371 If EndBit is less than StartBit, then ASSERT().
1372 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1374 @param Address The PCI configuration register to write.
1375 @param StartBit The ordinal of the least significant bit in the bit field.
1377 @param EndBit The ordinal of the most significant bit in the bit field.
1379 @param AndData The value to AND with the PCI configuration register.
1381 @return The value written back to the PCI configuration register.
1386 PciExpressBitFieldAnd32 (
1393 return MmioBitFieldAnd32 (
1394 GetPciExpressAddress (Address
),
1402 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1403 bitwise OR, and writes the result back to the bit field in the
1406 Reads the 32-bit PCI configuration register specified by Address, performs a
1407 bitwise AND followed by a bitwise OR between the read result and
1408 the value specified by AndData, and writes the result to the 32-bit PCI
1409 configuration register specified by Address. The value written to the PCI
1410 configuration register is returned. This function must guarantee that all PCI
1411 read and write operations are serialized. Extra left bits in both AndData and
1412 OrData are stripped.
1414 If Address > 0x0FFFFFFF, then ASSERT().
1415 If Address is not aligned on a 32-bit boundary, then ASSERT().
1416 If StartBit is greater than 31, then ASSERT().
1417 If EndBit is greater than 31, then ASSERT().
1418 If EndBit is less than StartBit, then ASSERT().
1419 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1420 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1422 @param Address The PCI configuration register to write.
1423 @param StartBit The ordinal of the least significant bit in the bit field.
1425 @param EndBit The ordinal of the most significant bit in the bit field.
1427 @param AndData The value to AND with the PCI configuration register.
1428 @param OrData The value to OR with the result of the AND operation.
1430 @return The value written back to the PCI configuration register.
1435 PciExpressBitFieldAndThenOr32 (
1443 return MmioBitFieldAndThenOr32 (
1444 GetPciExpressAddress (Address
),
1453 Reads a range of PCI configuration registers into a caller supplied buffer.
1455 Reads the range of PCI configuration registers specified by StartAddress and
1456 Size into the buffer specified by Buffer. This function only allows the PCI
1457 configuration registers from a single PCI function to be read. Size is
1458 returned. When possible 32-bit PCI configuration read cycles are used to read
1459 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit
1460 and 16-bit PCI configuration read cycles may be used at the beginning and the
1463 If StartAddress > 0x0FFFFFFF, then ASSERT().
1464 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1465 If Size > 0 and Buffer is NULL, then ASSERT().
1467 @param StartAddress The starting address that encodes the PCI Bus, Device,
1468 Function and Register.
1469 @param Size The size in bytes of the transfer.
1470 @param Buffer The pointer to a buffer receiving the data read.
1472 @return Size read data from StartAddress.
1477 PciExpressReadBuffer (
1478 IN UINTN StartAddress
,
1486 // Make sure Address is valid
1488 ASSERT (((StartAddress
) & ~0xfffffff) == 0);
1489 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1495 ASSERT (Buffer
!= NULL
);
1498 // Save Size for return
1502 if ((StartAddress
& 1) != 0) {
1504 // Read a byte if StartAddress is byte aligned
1506 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1507 StartAddress
+= sizeof (UINT8
);
1508 Size
-= sizeof (UINT8
);
1509 Buffer
= (UINT8
*)Buffer
+ 1;
1512 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1514 // Read a word if StartAddress is word aligned
1516 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1518 StartAddress
+= sizeof (UINT16
);
1519 Size
-= sizeof (UINT16
);
1520 Buffer
= (UINT16
*)Buffer
+ 1;
1523 while (Size
>= sizeof (UINT32
)) {
1525 // Read as many double words as possible
1527 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1529 StartAddress
+= sizeof (UINT32
);
1530 Size
-= sizeof (UINT32
);
1531 Buffer
= (UINT32
*)Buffer
+ 1;
1534 if (Size
>= sizeof (UINT16
)) {
1536 // Read the last remaining word if exist
1538 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1539 StartAddress
+= sizeof (UINT16
);
1540 Size
-= sizeof (UINT16
);
1541 Buffer
= (UINT16
*)Buffer
+ 1;
1544 if (Size
>= sizeof (UINT8
)) {
1546 // Read the last remaining byte if exist
1548 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1555 Copies the data in a caller supplied buffer to a specified range of PCI
1556 configuration space.
1558 Writes the range of PCI configuration registers specified by StartAddress and
1559 Size from the buffer specified by Buffer. This function only allows the PCI
1560 configuration registers from a single PCI function to be written. Size is
1561 returned. When possible 32-bit PCI configuration write cycles are used to
1562 write from StartAddress to StartAddress + Size. Due to alignment restrictions,
1563 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1564 and the end of the range.
1566 If StartAddress > 0x0FFFFFFF, then ASSERT().
1567 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1568 If Size > 0 and Buffer is NULL, then ASSERT().
1570 @param StartAddress The starting address that encodes the PCI Bus, Device,
1571 Function and Register.
1572 @param Size The size in bytes of the transfer.
1573 @param Buffer The pointer to a buffer containing the data to write.
1575 @return Size written to StartAddress.
1580 PciExpressWriteBuffer (
1581 IN UINTN StartAddress
,
1589 // Make sure Address is valid
1591 ASSERT (((StartAddress
) & ~0xfffffff) == 0);
1592 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1598 ASSERT (Buffer
!= NULL
);
1601 // Save Size for return
1605 if ((StartAddress
& 1) != 0) {
1607 // Write a byte if StartAddress is byte aligned
1609 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1610 StartAddress
+= sizeof (UINT8
);
1611 Size
-= sizeof (UINT8
);
1612 Buffer
= (UINT8
*)Buffer
+ 1;
1615 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1617 // Write a word if StartAddress is word aligned
1619 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1620 StartAddress
+= sizeof (UINT16
);
1621 Size
-= sizeof (UINT16
);
1622 Buffer
= (UINT16
*)Buffer
+ 1;
1625 while (Size
>= sizeof (UINT32
)) {
1627 // Write as many double words as possible
1629 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1630 StartAddress
+= sizeof (UINT32
);
1631 Size
-= sizeof (UINT32
);
1632 Buffer
= (UINT32
*)Buffer
+ 1;
1635 if (Size
>= sizeof (UINT16
)) {
1637 // Write the last remaining word if exist
1639 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1640 StartAddress
+= sizeof (UINT16
);
1641 Size
-= sizeof (UINT16
);
1642 Buffer
= (UINT16
*)Buffer
+ 1;
1645 if (Size
>= sizeof (UINT8
)) {
1647 // Write the last remaining byte if exist
1649 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);