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 - 2012, Intel Corporation. All rights reserved.<BR>
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php.
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include <Guid/EventGroup.h>
24 #include <Library/BaseLib.h>
25 #include <Library/PciExpressLib.h>
26 #include <Library/IoLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/PcdLib.h>
29 #include <Library/MemoryAllocationLib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/DxeServicesTableLib.h>
32 #include <Library/UefiRuntimeLib.h>
35 /// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime
38 UINTN PhysicalAddress
;
40 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
;
43 /// Set Virtual Address Map Event
45 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent
= NULL
;
48 /// Module global that contains the base physical address of the PCI Express MMIO range.
50 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress
= 0;
53 /// The number of PCI devices that have been registered for runtime access.
55 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges
= 0;
58 /// The table of PCI devices that have been registered for runtime access.
60 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
*mDxeRuntimePciExpressLibRegistrationTable
= NULL
;
63 /// The table index of the most recent virtual address lookup.
65 UINTN mDxeRuntimePciExpressLibLastRuntimeRange
= 0;
69 Convert the physical PCI Express MMIO addresses for all registered PCI devices
72 @param[in] Event The event that is being processed.
73 @param[in] Context The Event Context.
77 DxeRuntimePciExpressLibVirtualNotify (
85 // If there have been no runtime registrations, then just return
87 if (mDxeRuntimePciExpressLibRegistrationTable
== NULL
) {
92 // Convert physical addresses associated with the set of registered PCI devices to
95 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
96 EfiConvertPointer (0, (VOID
**) &(mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
));
100 // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.
102 EfiConvertPointer (0, (VOID
**) &mDxeRuntimePciExpressLibRegistrationTable
);
106 The constructor function caches the PCI Express Base Address and creates a
107 Set Virtual Address Map event to convert physical address to virtual addresses.
109 @param ImageHandle The firmware allocated handle for the EFI image.
110 @param SystemTable A pointer to the EFI System Table.
112 @retval EFI_SUCCESS The constructor completed successfully.
113 @retval Other value The constructor did not complete successfully.
118 DxeRuntimePciExpressLibConstructor (
119 IN EFI_HANDLE ImageHandle
,
120 IN EFI_SYSTEM_TABLE
*SystemTable
126 // Cache the physical address of the PCI Express MMIO range into a module global variable
128 mDxeRuntimePciExpressLibPciExpressBaseAddress
= (UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
131 // Register SetVirtualAddressMap () notify function
133 Status
= gBS
->CreateEventEx (
136 DxeRuntimePciExpressLibVirtualNotify
,
138 &gEfiEventVirtualAddressChangeGuid
,
139 &mDxeRuntimePciExpressLibVirtualNotifyEvent
141 ASSERT_EFI_ERROR (Status
);
147 The destructor function frees any allocated buffers and closes the Set Virtual
150 @param ImageHandle The firmware allocated handle for the EFI image.
151 @param SystemTable A pointer to the EFI System Table.
153 @retval EFI_SUCCESS The destructor completed successfully.
154 @retval Other value The destructor did not complete successfully.
159 DxeRuntimePciExpressLibDestructor (
160 IN EFI_HANDLE ImageHandle
,
161 IN EFI_SYSTEM_TABLE
*SystemTable
167 // If one or more PCI devices have been registered for runtime access, then
168 // free the registration table.
170 if (mDxeRuntimePciExpressLibRegistrationTable
!= NULL
) {
171 FreePool (mDxeRuntimePciExpressLibRegistrationTable
);
175 // Close the Set Virtual Address Map event
177 Status
= gBS
->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent
);
178 ASSERT_EFI_ERROR (Status
);
184 Gets the base address of PCI Express.
186 This internal functions retrieves PCI Express Base Address via a PCD entry
187 PcdPciExpressBaseAddress.
189 @param Address The address that encodes the PCI Bus, Device, Function and Register.
190 @return The base address of PCI Express.
194 GetPciExpressAddress (
201 // Make sure Address is valid
203 ASSERT (((Address
) & ~0xfffffff) == 0);
206 // Convert Address to a physical address in the MMIO PCI Express range
208 Address
+= mDxeRuntimePciExpressLibPciExpressBaseAddress
;
211 // If SetVirtualAddressMap() has not been called, then just return the physical address
213 if (!EfiGoneVirtual ()) {
218 // See if there is a physical address match at the exact same index as the last address match
220 if (mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].PhysicalAddress
== (Address
& (~0x00000fff))) {
222 // Convert the physical address to a virtual address and return the virtual address
224 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].VirtualAddress
;
228 // Search the entire table for a physical address match
230 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
231 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== (Address
& (~0x00000fff))) {
233 // Cache the matching index value
235 mDxeRuntimePciExpressLibLastRuntimeRange
= Index
;
237 // Convert the physical address to a virtual address and return the virtual address
239 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
;
244 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
250 // Return the physical address
256 Registers a PCI device so PCI configuration registers may be accessed after
257 SetVirtualAddressMap().
259 Registers the PCI device specified by Address so all the PCI configuration
260 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
263 If Address > 0x0FFFFFFF, then ASSERT().
265 @param Address The address that encodes the PCI Bus, Device, Function and
268 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
269 @retval RETURN_UNSUPPORTED An attempt was made to call this function
270 after ExitBootServices().
271 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
272 at runtime could not be mapped.
273 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
274 complete the registration.
279 PciExpressRegisterForRuntimeAccess (
284 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
289 // Return an error if this function is called after ExitBootServices().
291 if (EfiAtRuntime ()) {
292 return RETURN_UNSUPPORTED
;
296 // Make sure Address is valid
298 ASSERT (((Address
) & ~0xfffffff) == 0);
301 // Convert Address to a physical address in the MMIO PCI Express range
302 // at the beginning of the PCI Configuration header for the specified
305 Address
= GetPciExpressAddress (Address
& 0x0ffff000);
308 // See if Address has already been registerd for runtime access
310 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
311 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== Address
) {
312 return RETURN_SUCCESS
;
317 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
319 Status
= gDS
->GetMemorySpaceDescriptor (Address
, &Descriptor
);
320 if (EFI_ERROR (Status
)) {
321 return RETURN_UNSUPPORTED
;
325 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
326 // will allocate a virtual address range for the 4KB PCI Configuration Header.
328 Status
= gDS
->SetMemorySpaceAttributes (Address
, 0x1000, Descriptor
.Attributes
| EFI_MEMORY_RUNTIME
);
329 if (EFI_ERROR (Status
)) {
330 return RETURN_UNSUPPORTED
;
334 // Grow the size of the registration table
336 NewTable
= ReallocateRuntimePool (
337 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
338 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
339 mDxeRuntimePciExpressLibRegistrationTable
341 if (NewTable
== NULL
) {
342 return RETURN_OUT_OF_RESOURCES
;
344 mDxeRuntimePciExpressLibRegistrationTable
= NewTable
;
345 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].PhysicalAddress
= Address
;
346 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].VirtualAddress
= Address
;
347 mDxeRuntimePciExpressLibNumberOfRuntimeRanges
++;
349 return RETURN_SUCCESS
;
354 Reads an 8-bit PCI configuration register.
356 Reads and returns the 8-bit PCI configuration register specified by Address.
357 This function must guarantee that all PCI read and write operations are
360 If Address > 0x0FFFFFFF, then ASSERT().
362 @param Address The address that encodes the PCI Bus, Device, Function and
365 @return The read value from the PCI configuration register.
374 return MmioRead8 (GetPciExpressAddress (Address
));
378 Writes an 8-bit PCI configuration register.
380 Writes the 8-bit PCI configuration register specified by Address with the
381 value specified by Value. Value is returned. This function must guarantee
382 that all PCI read and write operations are serialized.
384 If Address > 0x0FFFFFFF, then ASSERT().
386 @param Address The address that encodes the PCI Bus, Device, Function and
388 @param Value The value to write.
390 @return The value written to the PCI configuration register.
400 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
404 Performs a bitwise OR of an 8-bit PCI configuration register with
407 Reads the 8-bit PCI configuration register specified by Address, performs a
408 bitwise OR between the read result and the value specified by
409 OrData, and writes the result to the 8-bit PCI configuration register
410 specified by Address. The value written to the PCI configuration register is
411 returned. This function must guarantee that all PCI read and write operations
414 If Address > 0x0FFFFFFF, then ASSERT().
416 @param Address The address that encodes the PCI Bus, Device, Function and
418 @param OrData The value to OR with the PCI configuration register.
420 @return The value written back to the PCI configuration register.
430 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
434 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
437 Reads the 8-bit PCI configuration register specified by Address, performs a
438 bitwise AND between the read result and the value specified by AndData, and
439 writes the result to the 8-bit PCI configuration register specified by
440 Address. The value written to the PCI configuration register is returned.
441 This function must guarantee that all PCI read and write operations are
444 If Address > 0x0FFFFFFF, then ASSERT().
446 @param Address The address that encodes the PCI Bus, Device, Function and
448 @param AndData The value to AND with the PCI configuration register.
450 @return The value written back to the PCI configuration register.
460 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
464 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
465 value, followed a bitwise OR with another 8-bit value.
467 Reads the 8-bit PCI configuration register specified by Address, performs a
468 bitwise AND between the read result and the value specified by AndData,
469 performs a bitwise OR between the result of the AND operation and
470 the value specified by OrData, and writes the result to the 8-bit PCI
471 configuration register specified by Address. The value written to the PCI
472 configuration register is returned. This function must guarantee that all PCI
473 read and write operations are serialized.
475 If Address > 0x0FFFFFFF, then ASSERT().
477 @param Address The address that encodes the PCI Bus, Device, Function and
479 @param AndData The value to AND with the PCI configuration register.
480 @param OrData The value to OR with the result of the AND operation.
482 @return The value written back to the PCI configuration register.
487 PciExpressAndThenOr8 (
493 return MmioAndThenOr8 (
494 GetPciExpressAddress (Address
),
501 Reads a bit field of a PCI configuration register.
503 Reads the bit field in an 8-bit PCI configuration register. The bit field is
504 specified by the StartBit and the EndBit. The value of the bit field is
507 If Address > 0x0FFFFFFF, then ASSERT().
508 If StartBit is greater than 7, then ASSERT().
509 If EndBit is greater than 7, then ASSERT().
510 If EndBit is less than StartBit, then ASSERT().
512 @param Address The PCI configuration register to read.
513 @param StartBit The ordinal of the least significant bit in the bit field.
515 @param EndBit The ordinal of the most significant bit in the bit field.
518 @return The value of the bit field read from the PCI configuration register.
523 PciExpressBitFieldRead8 (
529 return MmioBitFieldRead8 (
530 GetPciExpressAddress (Address
),
537 Writes a bit field to a PCI configuration register.
539 Writes Value to the bit field of the PCI configuration register. The bit
540 field is specified by the StartBit and the EndBit. All other bits in the
541 destination PCI configuration register are preserved. The new value of the
542 8-bit register is returned.
544 If Address > 0x0FFFFFFF, then ASSERT().
545 If StartBit is greater than 7, then ASSERT().
546 If EndBit is greater than 7, then ASSERT().
547 If EndBit is less than StartBit, then ASSERT().
548 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
550 @param Address The PCI configuration register to write.
551 @param StartBit The ordinal of the least significant bit in the bit field.
553 @param EndBit The ordinal of the most significant bit in the bit field.
555 @param Value The new value of the bit field.
557 @return The value written back to the PCI configuration register.
562 PciExpressBitFieldWrite8 (
569 return MmioBitFieldWrite8 (
570 GetPciExpressAddress (Address
),
578 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
579 writes the result back to the bit field in the 8-bit port.
581 Reads the 8-bit PCI configuration register specified by Address, performs a
582 bitwise OR between the read result and the value specified by
583 OrData, and writes the result to the 8-bit PCI configuration register
584 specified by Address. The value written to the PCI configuration register is
585 returned. This function must guarantee that all PCI read and write operations
586 are serialized. Extra left bits in OrData are stripped.
588 If Address > 0x0FFFFFFF, then ASSERT().
589 If StartBit is greater than 7, then ASSERT().
590 If EndBit is greater than 7, then ASSERT().
591 If EndBit is less than StartBit, then ASSERT().
592 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
594 @param Address The PCI configuration register to write.
595 @param StartBit The ordinal of the least significant bit in the bit field.
597 @param EndBit The ordinal of the most significant bit in the bit field.
599 @param OrData The value to OR with the PCI configuration register.
601 @return The value written back to the PCI configuration register.
606 PciExpressBitFieldOr8 (
613 return MmioBitFieldOr8 (
614 GetPciExpressAddress (Address
),
622 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
623 AND, and writes the result back to the bit field in the 8-bit register.
625 Reads the 8-bit PCI configuration register specified by Address, performs a
626 bitwise AND between the read result and the value specified by AndData, and
627 writes the result to the 8-bit PCI configuration register specified by
628 Address. The value written to the PCI configuration register is returned.
629 This function must guarantee that all PCI read and write operations are
630 serialized. Extra left bits in AndData are stripped.
632 If Address > 0x0FFFFFFF, then ASSERT().
633 If StartBit is greater than 7, then ASSERT().
634 If EndBit is greater than 7, then ASSERT().
635 If EndBit is less than StartBit, then ASSERT().
636 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
638 @param Address The PCI configuration register to write.
639 @param StartBit The ordinal of the least significant bit in the bit field.
641 @param EndBit The ordinal of the most significant bit in the bit field.
643 @param AndData The value to AND with the PCI configuration register.
645 @return The value written back to the PCI configuration register.
650 PciExpressBitFieldAnd8 (
657 return MmioBitFieldAnd8 (
658 GetPciExpressAddress (Address
),
666 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
667 bitwise OR, and writes the result back to the bit field in the
670 Reads the 8-bit PCI configuration register specified by Address, performs a
671 bitwise AND followed by a bitwise OR between the read result and
672 the value specified by AndData, and writes the result to the 8-bit PCI
673 configuration register specified by Address. The value written to the PCI
674 configuration register is returned. This function must guarantee that all PCI
675 read and write operations are serialized. Extra left bits in both AndData and
678 If Address > 0x0FFFFFFF, then ASSERT().
679 If StartBit is greater than 7, then ASSERT().
680 If EndBit is greater than 7, then ASSERT().
681 If EndBit is less than StartBit, then ASSERT().
682 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
683 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
685 @param Address The PCI configuration register to write.
686 @param StartBit The ordinal of the least significant bit in the bit field.
688 @param EndBit The ordinal of the most significant bit in the bit field.
690 @param AndData The value to AND with the PCI configuration register.
691 @param OrData The value to OR with the result of the AND operation.
693 @return The value written back to the PCI configuration register.
698 PciExpressBitFieldAndThenOr8 (
706 return MmioBitFieldAndThenOr8 (
707 GetPciExpressAddress (Address
),
716 Reads a 16-bit PCI configuration register.
718 Reads and returns the 16-bit PCI configuration register specified by Address.
719 This function must guarantee that all PCI read and write operations are
722 If Address > 0x0FFFFFFF, then ASSERT().
723 If Address is not aligned on a 16-bit boundary, then ASSERT().
725 @param Address The address that encodes the PCI Bus, Device, Function and
728 @return The read value from the PCI configuration register.
737 return MmioRead16 (GetPciExpressAddress (Address
));
741 Writes a 16-bit PCI configuration register.
743 Writes the 16-bit PCI configuration register specified by Address with the
744 value specified by Value. Value is returned. This function must guarantee
745 that all PCI read and write operations are serialized.
747 If Address > 0x0FFFFFFF, then ASSERT().
748 If Address is not aligned on a 16-bit boundary, then ASSERT().
750 @param Address The address that encodes the PCI Bus, Device, Function and
752 @param Value The value to write.
754 @return The value written to the PCI configuration register.
764 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
768 Performs a bitwise OR of a 16-bit PCI configuration register with
771 Reads the 16-bit PCI configuration register specified by Address, performs a
772 bitwise OR between the read result and the value specified by
773 OrData, and writes the result to the 16-bit PCI configuration register
774 specified by Address. The value written to the PCI configuration register is
775 returned. This function must guarantee that all PCI read and write operations
778 If Address > 0x0FFFFFFF, then ASSERT().
779 If Address is not aligned on a 16-bit boundary, then ASSERT().
781 @param Address The address that encodes the PCI Bus, Device, Function and
783 @param OrData The value to OR with the PCI configuration register.
785 @return The value written back to the PCI configuration register.
795 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
799 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
802 Reads the 16-bit PCI configuration register specified by Address, performs a
803 bitwise AND between the read result and the value specified by AndData, and
804 writes the result to the 16-bit PCI configuration register specified by
805 Address. The value written to the PCI configuration register is returned.
806 This function must guarantee that all PCI read and write operations are
809 If Address > 0x0FFFFFFF, then ASSERT().
810 If Address is not aligned on a 16-bit boundary, then ASSERT().
812 @param Address The address that encodes the PCI Bus, Device, Function and
814 @param AndData The value to AND with the PCI configuration register.
816 @return The value written back to the PCI configuration register.
826 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
830 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
831 value, followed a bitwise OR with another 16-bit value.
833 Reads the 16-bit PCI configuration register specified by Address, performs a
834 bitwise AND between the read result and the value specified by AndData,
835 performs a bitwise OR between the result of the AND operation and
836 the value specified by OrData, and writes the result to the 16-bit PCI
837 configuration register specified by Address. The value written to the PCI
838 configuration register is returned. This function must guarantee that all PCI
839 read and write operations are serialized.
841 If Address > 0x0FFFFFFF, then ASSERT().
842 If Address is not aligned on a 16-bit boundary, then ASSERT().
844 @param Address The address that encodes the PCI Bus, Device, Function and
846 @param AndData The value to AND with the PCI configuration register.
847 @param OrData The value to OR with the result of the AND operation.
849 @return The value written back to the PCI configuration register.
854 PciExpressAndThenOr16 (
860 return MmioAndThenOr16 (
861 GetPciExpressAddress (Address
),
868 Reads a bit field of a PCI configuration register.
870 Reads the bit field in a 16-bit PCI configuration register. The bit field is
871 specified by the StartBit and the EndBit. The value of the bit field is
874 If Address > 0x0FFFFFFF, then ASSERT().
875 If Address is not aligned on a 16-bit boundary, then ASSERT().
876 If StartBit is greater than 15, then ASSERT().
877 If EndBit is greater than 15, then ASSERT().
878 If EndBit is less than StartBit, then ASSERT().
880 @param Address The PCI configuration register to read.
881 @param StartBit The ordinal of the least significant bit in the bit field.
883 @param EndBit The ordinal of the most significant bit in the bit field.
886 @return The value of the bit field read from the PCI configuration register.
891 PciExpressBitFieldRead16 (
897 return MmioBitFieldRead16 (
898 GetPciExpressAddress (Address
),
905 Writes a bit field to a PCI configuration register.
907 Writes Value to the bit field of the PCI configuration register. The bit
908 field is specified by the StartBit and the EndBit. All other bits in the
909 destination PCI configuration register are preserved. The new value of the
910 16-bit register is returned.
912 If Address > 0x0FFFFFFF, then ASSERT().
913 If Address is not aligned on a 16-bit boundary, then ASSERT().
914 If StartBit is greater than 15, then ASSERT().
915 If EndBit is greater than 15, then ASSERT().
916 If EndBit is less than StartBit, then ASSERT().
917 If Value 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 Value The new value of the bit field.
926 @return The value written back to the PCI configuration register.
931 PciExpressBitFieldWrite16 (
938 return MmioBitFieldWrite16 (
939 GetPciExpressAddress (Address
),
947 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
948 writes the result back to the bit field in the 16-bit port.
950 Reads the 16-bit PCI configuration register specified by Address, performs a
951 bitwise OR between the read result and the value specified by
952 OrData, and writes the result to the 16-bit PCI configuration register
953 specified by Address. The value written to the PCI configuration register is
954 returned. This function must guarantee that all PCI read and write operations
955 are serialized. Extra left bits in OrData are stripped.
957 If Address > 0x0FFFFFFF, then ASSERT().
958 If Address is not aligned on a 16-bit boundary, then ASSERT().
959 If StartBit is greater than 15, then ASSERT().
960 If EndBit is greater than 15, then ASSERT().
961 If EndBit is less than StartBit, then ASSERT().
962 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
964 @param Address The PCI configuration register to write.
965 @param StartBit The ordinal of the least significant bit in the bit field.
967 @param EndBit The ordinal of the most significant bit in the bit field.
969 @param OrData The value to OR with the PCI configuration register.
971 @return The value written back to the PCI configuration register.
976 PciExpressBitFieldOr16 (
983 return MmioBitFieldOr16 (
984 GetPciExpressAddress (Address
),
992 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
993 AND, and writes the result back to the bit field in the 16-bit register.
995 Reads the 16-bit PCI configuration register specified by Address, performs a
996 bitwise AND between the read result and the value specified by AndData, and
997 writes the result to the 16-bit PCI configuration register specified by
998 Address. The value written to the PCI configuration register is returned.
999 This function must guarantee that all PCI read and write operations are
1000 serialized. Extra left bits in AndData are stripped.
1002 If Address > 0x0FFFFFFF, then ASSERT().
1003 If Address is not aligned on a 16-bit boundary, then ASSERT().
1004 If StartBit is greater than 15, then ASSERT().
1005 If EndBit is greater than 15, then ASSERT().
1006 If EndBit is less than StartBit, then ASSERT().
1007 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1009 @param Address The PCI configuration register to write.
1010 @param StartBit The ordinal of the least significant bit in the bit field.
1012 @param EndBit The ordinal of the most significant bit in the bit field.
1014 @param AndData The value to AND with the PCI configuration register.
1016 @return The value written back to the PCI configuration register.
1021 PciExpressBitFieldAnd16 (
1028 return MmioBitFieldAnd16 (
1029 GetPciExpressAddress (Address
),
1037 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1038 bitwise OR, and writes the result back to the bit field in the
1041 Reads the 16-bit PCI configuration register specified by Address, performs a
1042 bitwise AND followed by a bitwise OR between the read result and
1043 the value specified by AndData, and writes the result to the 16-bit PCI
1044 configuration register specified by Address. The value written to the PCI
1045 configuration register is returned. This function must guarantee that all PCI
1046 read and write operations are serialized. Extra left bits in both AndData and
1047 OrData are stripped.
1049 If Address > 0x0FFFFFFF, then ASSERT().
1050 If Address is not aligned on a 16-bit boundary, then ASSERT().
1051 If StartBit is greater than 15, then ASSERT().
1052 If EndBit is greater than 15, then ASSERT().
1053 If EndBit is less than StartBit, then ASSERT().
1054 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1055 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1057 @param Address The PCI configuration register to write.
1058 @param StartBit The ordinal of the least significant bit in the bit field.
1060 @param EndBit The ordinal of the most significant bit in the bit field.
1062 @param AndData The value to AND with the PCI configuration register.
1063 @param OrData The value to OR with the result of the AND operation.
1065 @return The value written back to the PCI configuration register.
1070 PciExpressBitFieldAndThenOr16 (
1078 return MmioBitFieldAndThenOr16 (
1079 GetPciExpressAddress (Address
),
1088 Reads a 32-bit PCI configuration register.
1090 Reads and returns the 32-bit PCI configuration register specified by Address.
1091 This function must guarantee that all PCI read and write operations are
1094 If Address > 0x0FFFFFFF, then ASSERT().
1095 If Address is not aligned on a 32-bit boundary, then ASSERT().
1097 @param Address The address that encodes the PCI Bus, Device, Function and
1100 @return The read value from the PCI configuration register.
1109 return MmioRead32 (GetPciExpressAddress (Address
));
1113 Writes a 32-bit PCI configuration register.
1115 Writes the 32-bit PCI configuration register specified by Address with the
1116 value specified by Value. Value is returned. This function must guarantee
1117 that all PCI read and write operations are serialized.
1119 If Address > 0x0FFFFFFF, then ASSERT().
1120 If Address is not aligned on a 32-bit boundary, then ASSERT().
1122 @param Address The address that encodes the PCI Bus, Device, Function and
1124 @param Value The value to write.
1126 @return The value written to the PCI configuration register.
1136 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1140 Performs a bitwise OR of a 32-bit PCI configuration register with
1143 Reads the 32-bit PCI configuration register specified by Address, performs a
1144 bitwise OR between the read result and the value specified by
1145 OrData, and writes the result to the 32-bit PCI configuration register
1146 specified by Address. The value written to the PCI configuration register is
1147 returned. This function must guarantee that all PCI read and write operations
1150 If Address > 0x0FFFFFFF, then ASSERT().
1151 If Address is not aligned on a 32-bit boundary, then ASSERT().
1153 @param Address The address that encodes the PCI Bus, Device, Function and
1155 @param OrData The value to OR with the PCI configuration register.
1157 @return The value written back to the PCI configuration register.
1167 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1171 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1174 Reads the 32-bit PCI configuration register specified by Address, performs a
1175 bitwise AND between the read result and the value specified by AndData, and
1176 writes the result to the 32-bit PCI configuration register specified by
1177 Address. The value written to the PCI configuration register is returned.
1178 This function must guarantee that all PCI read and write operations are
1181 If Address > 0x0FFFFFFF, then ASSERT().
1182 If Address is not aligned on a 32-bit boundary, then ASSERT().
1184 @param Address The address that encodes the PCI Bus, Device, Function and
1186 @param AndData The value to AND with the PCI configuration register.
1188 @return The value written back to the PCI configuration register.
1198 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1202 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1203 value, followed a bitwise OR with another 32-bit value.
1205 Reads the 32-bit PCI configuration register specified by Address, performs a
1206 bitwise AND between the read result and the value specified by AndData,
1207 performs a bitwise OR between the result of the AND operation and
1208 the value specified by OrData, and writes the result to the 32-bit PCI
1209 configuration register specified by Address. The value written to the PCI
1210 configuration register is returned. This function must guarantee that all PCI
1211 read and write operations are serialized.
1213 If Address > 0x0FFFFFFF, then ASSERT().
1214 If Address is not aligned on a 32-bit boundary, then ASSERT().
1216 @param Address The address that encodes the PCI Bus, Device, Function and
1218 @param AndData The value to AND with the PCI configuration register.
1219 @param OrData The value to OR with the result of the AND operation.
1221 @return The value written back to the PCI configuration register.
1226 PciExpressAndThenOr32 (
1232 return MmioAndThenOr32 (
1233 GetPciExpressAddress (Address
),
1240 Reads a bit field of a PCI configuration register.
1242 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1243 specified by the StartBit and the EndBit. The value of the bit field is
1246 If Address > 0x0FFFFFFF, then ASSERT().
1247 If Address is not aligned on a 32-bit boundary, then ASSERT().
1248 If StartBit is greater than 31, then ASSERT().
1249 If EndBit is greater than 31, then ASSERT().
1250 If EndBit is less than StartBit, then ASSERT().
1252 @param Address The PCI configuration register to read.
1253 @param StartBit The ordinal of the least significant bit in the bit field.
1255 @param EndBit The ordinal of the most significant bit in the bit field.
1258 @return The value of the bit field read from the PCI configuration register.
1263 PciExpressBitFieldRead32 (
1269 return MmioBitFieldRead32 (
1270 GetPciExpressAddress (Address
),
1277 Writes a bit field to a PCI configuration register.
1279 Writes Value to the bit field of the PCI configuration register. The bit
1280 field is specified by the StartBit and the EndBit. All other bits in the
1281 destination PCI configuration register are preserved. The new value of the
1282 32-bit register is returned.
1284 If Address > 0x0FFFFFFF, then ASSERT().
1285 If Address is not aligned on a 32-bit boundary, then ASSERT().
1286 If StartBit is greater than 31, then ASSERT().
1287 If EndBit is greater than 31, then ASSERT().
1288 If EndBit is less than StartBit, then ASSERT().
1289 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1291 @param Address The PCI configuration register to write.
1292 @param StartBit The ordinal of the least significant bit in the bit field.
1294 @param EndBit The ordinal of the most significant bit in the bit field.
1296 @param Value The new value of the bit field.
1298 @return The value written back to the PCI configuration register.
1303 PciExpressBitFieldWrite32 (
1310 return MmioBitFieldWrite32 (
1311 GetPciExpressAddress (Address
),
1319 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1320 writes the result back to the bit field in the 32-bit port.
1322 Reads the 32-bit PCI configuration register specified by Address, performs a
1323 bitwise OR between the read result and the value specified by
1324 OrData, and writes the result to the 32-bit PCI configuration register
1325 specified by Address. The value written to the PCI configuration register is
1326 returned. This function must guarantee that all PCI read and write operations
1327 are serialized. Extra left bits in OrData are stripped.
1329 If Address > 0x0FFFFFFF, then ASSERT().
1330 If Address is not aligned on a 32-bit boundary, then ASSERT().
1331 If StartBit is greater than 31, then ASSERT().
1332 If EndBit is greater than 31, then ASSERT().
1333 If EndBit is less than StartBit, then ASSERT().
1334 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1336 @param Address The PCI configuration register to write.
1337 @param StartBit The ordinal of the least significant bit in the bit field.
1339 @param EndBit The ordinal of the most significant bit in the bit field.
1341 @param OrData The value to OR with the PCI configuration register.
1343 @return The value written back to the PCI configuration register.
1348 PciExpressBitFieldOr32 (
1355 return MmioBitFieldOr32 (
1356 GetPciExpressAddress (Address
),
1364 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1365 AND, and writes the result back to the bit field in the 32-bit register.
1367 Reads the 32-bit PCI configuration register specified by Address, performs a
1368 bitwise AND between the read result and the value specified by AndData, and
1369 writes the result to the 32-bit PCI configuration register specified by
1370 Address. The value written to the PCI configuration register is returned.
1371 This function must guarantee that all PCI read and write operations are
1372 serialized. Extra left bits in AndData are stripped.
1374 If Address > 0x0FFFFFFF, then ASSERT().
1375 If Address is not aligned on a 32-bit boundary, then ASSERT().
1376 If StartBit is greater than 31, then ASSERT().
1377 If EndBit is greater than 31, then ASSERT().
1378 If EndBit is less than StartBit, then ASSERT().
1379 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1381 @param Address The PCI configuration register to write.
1382 @param StartBit The ordinal of the least significant bit in the bit field.
1384 @param EndBit The ordinal of the most significant bit in the bit field.
1386 @param AndData The value to AND with the PCI configuration register.
1388 @return The value written back to the PCI configuration register.
1393 PciExpressBitFieldAnd32 (
1400 return MmioBitFieldAnd32 (
1401 GetPciExpressAddress (Address
),
1409 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1410 bitwise OR, and writes the result back to the bit field in the
1413 Reads the 32-bit PCI configuration register specified by Address, performs a
1414 bitwise AND followed by a bitwise OR between the read result and
1415 the value specified by AndData, and writes the result to the 32-bit PCI
1416 configuration register specified by Address. The value written to the PCI
1417 configuration register is returned. This function must guarantee that all PCI
1418 read and write operations are serialized. Extra left bits in both AndData and
1419 OrData are stripped.
1421 If Address > 0x0FFFFFFF, then ASSERT().
1422 If Address is not aligned on a 32-bit boundary, then ASSERT().
1423 If StartBit is greater than 31, then ASSERT().
1424 If EndBit is greater than 31, then ASSERT().
1425 If EndBit is less than StartBit, then ASSERT().
1426 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1427 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1429 @param Address The PCI configuration register to write.
1430 @param StartBit The ordinal of the least significant bit in the bit field.
1432 @param EndBit The ordinal of the most significant bit in the bit field.
1434 @param AndData The value to AND with the PCI configuration register.
1435 @param OrData The value to OR with the result of the AND operation.
1437 @return The value written back to the PCI configuration register.
1442 PciExpressBitFieldAndThenOr32 (
1450 return MmioBitFieldAndThenOr32 (
1451 GetPciExpressAddress (Address
),
1460 Reads a range of PCI configuration registers into a caller supplied buffer.
1462 Reads the range of PCI configuration registers specified by StartAddress and
1463 Size into the buffer specified by Buffer. This function only allows the PCI
1464 configuration registers from a single PCI function to be read. Size is
1465 returned. When possible 32-bit PCI configuration read cycles are used to read
1466 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1467 and 16-bit PCI configuration read cycles may be used at the beginning and the
1470 If StartAddress > 0x0FFFFFFF, then ASSERT().
1471 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1472 If Size > 0 and Buffer is NULL, then ASSERT().
1474 @param StartAddress The starting address that encodes the PCI Bus, Device,
1475 Function and Register.
1476 @param Size The size in bytes of the transfer.
1477 @param Buffer The pointer to a buffer receiving the data read.
1479 @return Size read data from StartAddress.
1484 PciExpressReadBuffer (
1485 IN UINTN StartAddress
,
1493 // Make sure Address is valid
1495 ASSERT (((StartAddress
) & ~0xfffffff) == 0);
1496 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1502 ASSERT (Buffer
!= NULL
);
1505 // Save Size for return
1509 if ((StartAddress
& 1) != 0) {
1511 // Read a byte if StartAddress is byte aligned
1513 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1514 StartAddress
+= sizeof (UINT8
);
1515 Size
-= sizeof (UINT8
);
1516 Buffer
= (UINT8
*)Buffer
+ 1;
1519 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1521 // Read a word if StartAddress is word aligned
1523 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1525 StartAddress
+= sizeof (UINT16
);
1526 Size
-= sizeof (UINT16
);
1527 Buffer
= (UINT16
*)Buffer
+ 1;
1530 while (Size
>= sizeof (UINT32
)) {
1532 // Read as many double words as possible
1534 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1536 StartAddress
+= sizeof (UINT32
);
1537 Size
-= sizeof (UINT32
);
1538 Buffer
= (UINT32
*)Buffer
+ 1;
1541 if (Size
>= sizeof (UINT16
)) {
1543 // Read the last remaining word if exist
1545 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1546 StartAddress
+= sizeof (UINT16
);
1547 Size
-= sizeof (UINT16
);
1548 Buffer
= (UINT16
*)Buffer
+ 1;
1551 if (Size
>= sizeof (UINT8
)) {
1553 // Read the last remaining byte if exist
1555 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1562 Copies the data in a caller supplied buffer to a specified range of PCI
1563 configuration space.
1565 Writes the range of PCI configuration registers specified by StartAddress and
1566 Size from the buffer specified by Buffer. This function only allows the PCI
1567 configuration registers from a single PCI function to be written. Size is
1568 returned. When possible 32-bit PCI configuration write cycles are used to
1569 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1570 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1571 and the end of the range.
1573 If StartAddress > 0x0FFFFFFF, then ASSERT().
1574 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1575 If Size > 0 and Buffer is NULL, then ASSERT().
1577 @param StartAddress The starting address that encodes the PCI Bus, Device,
1578 Function and Register.
1579 @param Size The size in bytes of the transfer.
1580 @param Buffer The pointer to a buffer containing the data to write.
1582 @return Size written to StartAddress.
1587 PciExpressWriteBuffer (
1588 IN UINTN StartAddress
,
1596 // Make sure Address is valid
1598 ASSERT (((StartAddress
) & ~0xfffffff) == 0);
1599 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1605 ASSERT (Buffer
!= NULL
);
1608 // Save Size for return
1612 if ((StartAddress
& 1) != 0) {
1614 // Write a byte if StartAddress is byte aligned
1616 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1617 StartAddress
+= sizeof (UINT8
);
1618 Size
-= sizeof (UINT8
);
1619 Buffer
= (UINT8
*)Buffer
+ 1;
1622 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1624 // Write a word if StartAddress is word aligned
1626 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1627 StartAddress
+= sizeof (UINT16
);
1628 Size
-= sizeof (UINT16
);
1629 Buffer
= (UINT16
*)Buffer
+ 1;
1632 while (Size
>= sizeof (UINT32
)) {
1634 // Write as many double words as possible
1636 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1637 StartAddress
+= sizeof (UINT32
);
1638 Size
-= sizeof (UINT32
);
1639 Buffer
= (UINT32
*)Buffer
+ 1;
1642 if (Size
>= sizeof (UINT16
)) {
1644 // Write the last remaining word if exist
1646 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1647 StartAddress
+= sizeof (UINT16
);
1648 Size
-= sizeof (UINT16
);
1649 Buffer
= (UINT16
*)Buffer
+ 1;
1652 if (Size
>= sizeof (UINT8
)) {
1654 // Write the last remaining byte if exist
1656 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);