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 - 2008, Intel Corporation<BR>
9 All rights reserved. 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 <Library/BaseLib.h>
23 #include <Library/PciExpressLib.h>
24 #include <Library/IoLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/DxeServicesTableLib.h>
30 #include <Library/UefiRuntimeLib.h>
33 /// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime
36 UINTN PhysicalAddress
;
38 } PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
;
41 /// Set Virtual Address Map Event
43 EFI_EVENT mDxeRuntimePciExpressLibVirtualNotifyEvent
= NULL
;
46 /// Module global that contains the base physical address of the PCI Express MMIO range
48 UINTN mDxeRuntimePciExpressLibPciExpressBaseAddress
= 0;
51 /// The number of PCI devices that have been registered for runtime access
53 UINTN mDxeRuntimePciExpressLibNumberOfRuntimeRanges
= 0;
56 /// The table of PCI devices that have been registered for runtime access
58 PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
*mDxeRuntimePciExpressLibRegistrationTable
= NULL
;
61 /// The table index of the most recent virtual address lookup
63 UINTN mDxeRuntimePciExpressLibLastRuntimeRange
= 0;
67 Convert the physical PCI Express MMIO addresses for all registered PCI devices
70 @param[in] Event The Event that is being processed
71 @param[in] Context Event Context
75 DxeRuntimePciExpressLibVirtualNotify (
83 // If there have been no runtime registrations, then just return
85 if (mDxeRuntimePciExpressLibRegistrationTable
== NULL
) {
90 // Convert physical addresses associated with the set of registered PCI devices to
93 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
94 EfiConvertPointer (0, (VOID
**) &(mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
));
98 // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.
100 EfiConvertPointer (0, (VOID
**) &mDxeRuntimePciExpressLibRegistrationTable
);
104 The constructor function caches the PCI Express Base Address and creates a
105 Set Virtual Address Map event to convert physical address to virtual addresses.
107 @param ImageHandle The firmware allocated handle for the EFI image.
108 @param SystemTable A pointer to the EFI System Table.
110 @retval EFI_SUCCESS The constructor completed successfully.
111 @retval Other value The constructor did not complete successfully.
116 DxeRuntimePciExpressLibConstructor (
123 // Cache the physical address of the PCI Express MMIO range into a module global variable
125 mDxeRuntimePciExpressLibPciExpressBaseAddress
= (UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
128 // Register SetVirtualAddressMap () notify function
130 Status
= gBS
->CreateEvent (
131 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
133 DxeRuntimePciExpressLibVirtualNotify
,
135 &mDxeRuntimePciExpressLibVirtualNotifyEvent
137 ASSERT_EFI_ERROR (Status
);
143 The destructor function frees any allocated buffers and closes the Set Virtual
146 @param ImageHandle The firmware allocated handle for the EFI image.
147 @param SystemTable A pointer to the EFI System Table.
149 @retval EFI_SUCCESS The destructor completed successfully.
150 @retval Other value The destructor did not complete successfully.
155 DxeRuntimePciExpressLibDestructor (
162 // If one or more PCI devices have been registered for runtime access, then
163 // free the registration table.
165 if (mDxeRuntimePciExpressLibRegistrationTable
!= NULL
) {
166 FreePool (mDxeRuntimePciExpressLibRegistrationTable
);
170 // Close the Set Virtual Address Map event
172 Status
= gBS
->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent
);
173 ASSERT_EFI_ERROR (Status
);
179 Gets the base address of PCI Express.
181 This internal functions retrieves PCI Express Base Address via a PCD entry
182 PcdPciExpressBaseAddress.
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
& 0x0ffff000)) {
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 phyical address match
224 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
225 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== (Address
& 0x0ffff000)) {
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 Register a PCI device so PCI configuration registers may be accessed after
251 SetVirtualAddressMap().
253 If Address > 0x0FFFFFFF, then ASSERT().
255 @param Address Address that encodes the PCI Bus, Device, Function and
258 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
259 @retval RETURN_UNSUPPORTED An attempt was made to call this function
260 after ExitBootServices().
261 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
262 at runtime could not be mapped.
263 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
264 complete the registration.
269 PciExpressRegisterForRuntimeAccess (
274 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
279 // Return an error if this function is called after ExitBootServices().
281 if (EfiAtRuntime ()) {
282 return RETURN_UNSUPPORTED
;
286 // Make sure Address is valid
288 ASSERT (((Address
) & ~0xfffffff) == 0);
291 // Convert Address to a physical address in the MMIO PCI Express range
292 // at the beginning of the PCI Configuration header for the specified
295 Address
= GetPciExpressAddress (Address
& 0x0ffff000);
298 // See if Address has already been registerd for runtime access
300 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
301 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== Address
) {
302 return RETURN_SUCCESS
;
307 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
309 Status
= gDS
->GetMemorySpaceDescriptor (Address
, &Descriptor
);
310 if (EFI_ERROR (Status
)) {
311 return RETURN_UNSUPPORTED
;
315 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
316 // will allocate a virtual address range for the 4KB PCI Configuration Header.
318 Status
= gDS
->SetMemorySpaceAttributes (Address
, 0x1000, Descriptor
.Attributes
| EFI_MEMORY_RUNTIME
);
319 if (EFI_ERROR (Status
)) {
320 return RETURN_UNSUPPORTED
;
324 // Grow the size of the registration table
326 NewTable
= ReallocateRuntimePool (
327 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
328 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
329 mDxeRuntimePciExpressLibRegistrationTable
331 if (NewTable
== NULL
) {
332 return RETURN_OUT_OF_RESOURCES
;
334 mDxeRuntimePciExpressLibRegistrationTable
= NewTable
;
335 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].PhysicalAddress
= Address
;
336 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].VirtualAddress
= Address
;
337 mDxeRuntimePciExpressLibNumberOfRuntimeRanges
++;
339 return RETURN_SUCCESS
;
344 Reads an 8-bit PCI configuration register.
346 Reads and returns the 8-bit PCI configuration register specified by Address.
347 This function must guarantee that all PCI read and write operations are
350 If Address > 0x0FFFFFFF, then ASSERT().
352 @param Address Address that encodes the PCI Bus, Device, Function and
355 @return The read value from the PCI configuration register.
364 return MmioRead8 (GetPciExpressAddress (Address
));
368 Writes an 8-bit PCI configuration register.
370 Writes the 8-bit PCI configuration register specified by Address with the
371 value specified by Value. Value is returned. This function must guarantee
372 that all PCI read and write operations are serialized.
374 If Address > 0x0FFFFFFF, then ASSERT().
376 @param Address Address that encodes the PCI Bus, Device, Function and
378 @param Value The value to write.
380 @return The value written to the PCI configuration register.
390 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
394 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
397 Reads the 8-bit PCI configuration register specified by Address, performs a
398 bitwise inclusive OR between the read result and the value specified by
399 OrData, and writes the result to the 8-bit PCI configuration register
400 specified by Address. The value written to the PCI configuration register is
401 returned. This function must guarantee that all PCI read and write operations
404 If Address > 0x0FFFFFFF, then ASSERT().
406 @param Address Address that encodes the PCI Bus, Device, Function and
408 @param OrData The value to OR with the PCI configuration register.
410 @return The value written back to the PCI configuration register.
420 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
424 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
427 Reads the 8-bit PCI configuration register specified by Address, performs a
428 bitwise AND between the read result and the value specified by AndData, and
429 writes the result to the 8-bit PCI configuration register specified by
430 Address. The value written to the PCI configuration register is returned.
431 This function must guarantee that all PCI read and write operations are
434 If Address > 0x0FFFFFFF, then ASSERT().
436 @param Address Address that encodes the PCI Bus, Device, Function and
438 @param AndData The value to AND with the PCI configuration register.
440 @return The value written back to the PCI configuration register.
450 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
454 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
455 value, followed a bitwise inclusive OR with another 8-bit value.
457 Reads the 8-bit PCI configuration register specified by Address, performs a
458 bitwise AND between the read result and the value specified by AndData,
459 performs a bitwise inclusive OR between the result of the AND operation and
460 the value specified by OrData, and writes the result to the 8-bit PCI
461 configuration register specified by Address. The value written to the PCI
462 configuration register is returned. This function must guarantee that all PCI
463 read and write operations are serialized.
465 If Address > 0x0FFFFFFF, then ASSERT().
467 @param Address Address that encodes the PCI Bus, Device, Function and
469 @param AndData The value to AND with the PCI configuration register.
470 @param OrData The value to OR with the result of the AND operation.
472 @return The value written back to the PCI configuration register.
477 PciExpressAndThenOr8 (
483 return MmioAndThenOr8 (
484 GetPciExpressAddress (Address
),
491 Reads a bit field of a PCI configuration register.
493 Reads the bit field in an 8-bit PCI configuration register. The bit field is
494 specified by the StartBit and the EndBit. The value of the bit field is
497 If Address > 0x0FFFFFFF, then ASSERT().
498 If StartBit is greater than 7, then ASSERT().
499 If EndBit is greater than 7, then ASSERT().
500 If EndBit is less than StartBit, then ASSERT().
502 @param Address PCI configuration register to read.
503 @param StartBit The ordinal of the least significant bit in the bit field.
505 @param EndBit The ordinal of the most significant bit in the bit field.
508 @return The value of the bit field read from the PCI configuration register.
513 PciExpressBitFieldRead8 (
519 return MmioBitFieldRead8 (
520 GetPciExpressAddress (Address
),
527 Writes a bit field to a PCI configuration register.
529 Writes Value to the bit field of the PCI configuration register. The bit
530 field is specified by the StartBit and the EndBit. All other bits in the
531 destination PCI configuration register are preserved. The new value of the
532 8-bit register is returned.
534 If Address > 0x0FFFFFFF, then ASSERT().
535 If StartBit is greater than 7, then ASSERT().
536 If EndBit is greater than 7, then ASSERT().
537 If EndBit is less than StartBit, then ASSERT().
539 @param Address PCI configuration register to write.
540 @param StartBit The ordinal of the least significant bit in the bit field.
542 @param EndBit The ordinal of the most significant bit in the bit field.
544 @param Value New value of the bit field.
546 @return The value written back to the PCI configuration register.
551 PciExpressBitFieldWrite8 (
558 return MmioBitFieldWrite8 (
559 GetPciExpressAddress (Address
),
567 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
568 writes the result back to the bit field in the 8-bit port.
570 Reads the 8-bit PCI configuration register specified by Address, performs a
571 bitwise inclusive OR between the read result and the value specified by
572 OrData, and writes the result to the 8-bit PCI configuration register
573 specified by Address. The value written to the PCI configuration register is
574 returned. This function must guarantee that all PCI read and write operations
575 are serialized. Extra left bits in OrData are stripped.
577 If Address > 0x0FFFFFFF, then ASSERT().
578 If StartBit is greater than 7, then ASSERT().
579 If EndBit is greater than 7, then ASSERT().
580 If EndBit is less than StartBit, then ASSERT().
582 @param Address PCI configuration register to write.
583 @param StartBit The ordinal of the least significant bit in the bit field.
585 @param EndBit The ordinal of the most significant bit in the bit field.
587 @param OrData The value to OR with the PCI configuration register.
589 @return The value written back to the PCI configuration register.
594 PciExpressBitFieldOr8 (
601 return MmioBitFieldOr8 (
602 GetPciExpressAddress (Address
),
610 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
611 AND, and writes the result back to the bit field in the 8-bit register.
613 Reads the 8-bit PCI configuration register specified by Address, performs a
614 bitwise AND between the read result and the value specified by AndData, and
615 writes the result to the 8-bit PCI configuration register specified by
616 Address. The value written to the PCI configuration register is returned.
617 This function must guarantee that all PCI read and write operations are
618 serialized. Extra left bits in AndData are stripped.
620 If Address > 0x0FFFFFFF, then ASSERT().
621 If StartBit is greater than 7, then ASSERT().
622 If EndBit is greater than 7, then ASSERT().
623 If EndBit is less than StartBit, then ASSERT().
625 @param Address PCI configuration register to write.
626 @param StartBit The ordinal of the least significant bit in the bit field.
628 @param EndBit The ordinal of the most significant bit in the bit field.
630 @param AndData The value to AND with the PCI configuration register.
632 @return The value written back to the PCI configuration register.
637 PciExpressBitFieldAnd8 (
644 return MmioBitFieldAnd8 (
645 GetPciExpressAddress (Address
),
653 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
654 bitwise inclusive OR, and writes the result back to the bit field in the
657 Reads the 8-bit PCI configuration register specified by Address, performs a
658 bitwise AND followed by a bitwise inclusive OR between the read result and
659 the value specified by AndData, and writes the result to the 8-bit PCI
660 configuration register specified by Address. The value written to the PCI
661 configuration register is returned. This function must guarantee that all PCI
662 read and write operations are serialized. Extra left bits in both AndData and
665 If Address > 0x0FFFFFFF, then ASSERT().
666 If StartBit is greater than 7, then ASSERT().
667 If EndBit is greater than 7, then ASSERT().
668 If EndBit is less than StartBit, then ASSERT().
670 @param Address PCI configuration register to write.
671 @param StartBit The ordinal of the least significant bit in the bit field.
673 @param EndBit The ordinal of the most significant bit in the bit field.
675 @param AndData The value to AND with the PCI configuration register.
676 @param OrData The value to OR with the result of the AND operation.
678 @return The value written back to the PCI configuration register.
683 PciExpressBitFieldAndThenOr8 (
691 return MmioBitFieldAndThenOr8 (
692 GetPciExpressAddress (Address
),
701 Reads a 16-bit PCI configuration register.
703 Reads and returns the 16-bit PCI configuration register specified by Address.
704 This function must guarantee that all PCI read and write operations are
707 If Address > 0x0FFFFFFF, then ASSERT().
708 If Address is not aligned on a 16-bit boundary, then ASSERT().
710 @param Address Address that encodes the PCI Bus, Device, Function and
713 @return The read value from the PCI configuration register.
722 return MmioRead16 (GetPciExpressAddress (Address
));
726 Writes a 16-bit PCI configuration register.
728 Writes the 16-bit PCI configuration register specified by Address with the
729 value specified by Value. Value is returned. This function must guarantee
730 that all PCI read and write operations are serialized.
732 If Address > 0x0FFFFFFF, then ASSERT().
733 If Address is not aligned on a 16-bit boundary, then ASSERT().
735 @param Address Address that encodes the PCI Bus, Device, Function and
737 @param Value The value to write.
739 @return The value written to the PCI configuration register.
749 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
753 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
756 Reads the 16-bit PCI configuration register specified by Address, performs a
757 bitwise inclusive OR between the read result and the value specified by
758 OrData, and writes the result to the 16-bit PCI configuration register
759 specified by Address. The value written to the PCI configuration register is
760 returned. This function must guarantee that all PCI read and write operations
763 If Address > 0x0FFFFFFF, then ASSERT().
764 If Address is not aligned on a 16-bit boundary, then ASSERT().
766 @param Address Address that encodes the PCI Bus, Device, Function and
768 @param OrData The value to OR with the PCI configuration register.
770 @return The value written back to the PCI configuration register.
780 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
784 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
787 Reads the 16-bit PCI configuration register specified by Address, performs a
788 bitwise AND between the read result and the value specified by AndData, and
789 writes the result to the 16-bit PCI configuration register specified by
790 Address. The value written to the PCI configuration register is returned.
791 This function must guarantee that all PCI read and write operations are
794 If Address > 0x0FFFFFFF, then ASSERT().
795 If Address is not aligned on a 16-bit boundary, then ASSERT().
797 @param Address Address that encodes the PCI Bus, Device, Function and
799 @param AndData The value to AND with the PCI configuration register.
801 @return The value written back to the PCI configuration register.
811 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
815 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
816 value, followed a bitwise inclusive OR with another 16-bit value.
818 Reads the 16-bit PCI configuration register specified by Address, performs a
819 bitwise AND between the read result and the value specified by AndData,
820 performs a bitwise inclusive OR between the result of the AND operation and
821 the value specified by OrData, and writes the result to the 16-bit PCI
822 configuration register specified by Address. The value written to the PCI
823 configuration register is returned. This function must guarantee that all PCI
824 read and write operations are serialized.
826 If Address > 0x0FFFFFFF, then ASSERT().
827 If Address is not aligned on a 16-bit boundary, then ASSERT().
829 @param Address Address that encodes the PCI Bus, Device, Function and
831 @param AndData The value to AND with the PCI configuration register.
832 @param OrData The value to OR with the result of the AND operation.
834 @return The value written back to the PCI configuration register.
839 PciExpressAndThenOr16 (
845 return MmioAndThenOr16 (
846 GetPciExpressAddress (Address
),
853 Reads a bit field of a PCI configuration register.
855 Reads the bit field in a 16-bit PCI configuration register. The bit field is
856 specified by the StartBit and the EndBit. The value of the bit field is
859 If Address > 0x0FFFFFFF, then ASSERT().
860 If Address is not aligned on a 16-bit boundary, then ASSERT().
861 If StartBit is greater than 15, then ASSERT().
862 If EndBit is greater than 15, then ASSERT().
863 If EndBit is less than StartBit, then ASSERT().
865 @param Address PCI configuration register to read.
866 @param StartBit The ordinal of the least significant bit in the bit field.
868 @param EndBit The ordinal of the most significant bit in the bit field.
871 @return The value of the bit field read from the PCI configuration register.
876 PciExpressBitFieldRead16 (
882 return MmioBitFieldRead16 (
883 GetPciExpressAddress (Address
),
890 Writes a bit field to a PCI configuration register.
892 Writes Value to the bit field of the PCI configuration register. The bit
893 field is specified by the StartBit and the EndBit. All other bits in the
894 destination PCI configuration register are preserved. The new value of the
895 16-bit register is returned.
897 If Address > 0x0FFFFFFF, then ASSERT().
898 If Address is not aligned on a 16-bit boundary, then ASSERT().
899 If StartBit is greater than 15, then ASSERT().
900 If EndBit is greater than 15, then ASSERT().
901 If EndBit is less than StartBit, then ASSERT().
903 @param Address PCI configuration register to write.
904 @param StartBit The ordinal of the least significant bit in the bit field.
906 @param EndBit The ordinal of the most significant bit in the bit field.
908 @param Value New value of the bit field.
910 @return The value written back to the PCI configuration register.
915 PciExpressBitFieldWrite16 (
922 return MmioBitFieldWrite16 (
923 GetPciExpressAddress (Address
),
931 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
932 writes the result back to the bit field in the 16-bit port.
934 Reads the 16-bit PCI configuration register specified by Address, performs a
935 bitwise inclusive OR between the read result and the value specified by
936 OrData, and writes the result to the 16-bit PCI configuration register
937 specified by Address. The value written to the PCI configuration register is
938 returned. This function must guarantee that all PCI read and write operations
939 are serialized. Extra left bits in OrData are stripped.
941 If Address > 0x0FFFFFFF, then ASSERT().
942 If Address is not aligned on a 16-bit boundary, then ASSERT().
943 If StartBit is greater than 15, then ASSERT().
944 If EndBit is greater than 15, then ASSERT().
945 If EndBit is less than StartBit, then ASSERT().
947 @param Address PCI configuration register to write.
948 @param StartBit The ordinal of the least significant bit in the bit field.
950 @param EndBit The ordinal of the most significant bit in the bit field.
952 @param OrData The value to OR with the PCI configuration register.
954 @return The value written back to the PCI configuration register.
959 PciExpressBitFieldOr16 (
966 return MmioBitFieldOr16 (
967 GetPciExpressAddress (Address
),
975 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
976 AND, and writes the result back to the bit field in the 16-bit register.
978 Reads the 16-bit PCI configuration register specified by Address, performs a
979 bitwise AND between the read result and the value specified by AndData, and
980 writes the result to the 16-bit PCI configuration register specified by
981 Address. The value written to the PCI configuration register is returned.
982 This function must guarantee that all PCI read and write operations are
983 serialized. Extra left bits in AndData are stripped.
985 If Address > 0x0FFFFFFF, then ASSERT().
986 If Address is not aligned on a 16-bit boundary, then ASSERT().
987 If StartBit is greater than 15, then ASSERT().
988 If EndBit is greater than 15, then ASSERT().
989 If EndBit is less than StartBit, then ASSERT().
991 @param Address PCI configuration register to write.
992 @param StartBit The ordinal of the least significant bit in the bit field.
994 @param EndBit The ordinal of the most significant bit in the bit field.
996 @param AndData The value to AND with the PCI configuration register.
998 @return The value written back to the PCI configuration register.
1003 PciExpressBitFieldAnd16 (
1010 return MmioBitFieldAnd16 (
1011 GetPciExpressAddress (Address
),
1019 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1020 bitwise inclusive OR, and writes the result back to the bit field in the
1023 Reads the 16-bit PCI configuration register specified by Address, performs a
1024 bitwise AND followed by a bitwise inclusive OR between the read result and
1025 the value specified by AndData, and writes the result to the 16-bit PCI
1026 configuration register specified by Address. The value written to the PCI
1027 configuration register is returned. This function must guarantee that all PCI
1028 read and write operations are serialized. Extra left bits in both AndData and
1029 OrData are stripped.
1031 If Address > 0x0FFFFFFF, then ASSERT().
1032 If Address is not aligned on a 16-bit boundary, then ASSERT().
1033 If StartBit is greater than 15, then ASSERT().
1034 If EndBit is greater than 15, then ASSERT().
1035 If EndBit is less than StartBit, then ASSERT().
1037 @param Address PCI configuration register to write.
1038 @param StartBit The ordinal of the least significant bit in the bit field.
1040 @param EndBit The ordinal of the most significant bit in the bit field.
1042 @param AndData The value to AND with the PCI configuration register.
1043 @param OrData The value to OR with the result of the AND operation.
1045 @return The value written back to the PCI configuration register.
1050 PciExpressBitFieldAndThenOr16 (
1058 return MmioBitFieldAndThenOr16 (
1059 GetPciExpressAddress (Address
),
1068 Reads a 32-bit PCI configuration register.
1070 Reads and returns the 32-bit PCI configuration register specified by Address.
1071 This function must guarantee that all PCI read and write operations are
1074 If Address > 0x0FFFFFFF, then ASSERT().
1075 If Address is not aligned on a 32-bit boundary, then ASSERT().
1077 @param Address Address that encodes the PCI Bus, Device, Function and
1080 @return The read value from the PCI configuration register.
1089 return MmioRead32 (GetPciExpressAddress (Address
));
1093 Writes a 32-bit PCI configuration register.
1095 Writes the 32-bit PCI configuration register specified by Address with the
1096 value specified by Value. Value is returned. This function must guarantee
1097 that all PCI read and write operations are serialized.
1099 If Address > 0x0FFFFFFF, then ASSERT().
1100 If Address is not aligned on a 32-bit boundary, then ASSERT().
1102 @param Address Address that encodes the PCI Bus, Device, Function and
1104 @param Value The value to write.
1106 @return The value written to the PCI configuration register.
1116 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1120 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
1123 Reads the 32-bit PCI configuration register specified by Address, performs a
1124 bitwise inclusive OR between the read result and the value specified by
1125 OrData, and writes the result to the 32-bit PCI configuration register
1126 specified by Address. The value written to the PCI configuration register is
1127 returned. This function must guarantee that all PCI read and write operations
1130 If Address > 0x0FFFFFFF, then ASSERT().
1131 If Address is not aligned on a 32-bit boundary, then ASSERT().
1133 @param Address Address that encodes the PCI Bus, Device, Function and
1135 @param OrData The value to OR with the PCI configuration register.
1137 @return The value written back to the PCI configuration register.
1147 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1151 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1154 Reads the 32-bit PCI configuration register specified by Address, performs a
1155 bitwise AND between the read result and the value specified by AndData, and
1156 writes the result to the 32-bit PCI configuration register specified by
1157 Address. The value written to the PCI configuration register is returned.
1158 This function must guarantee that all PCI read and write operations are
1161 If Address > 0x0FFFFFFF, then ASSERT().
1162 If Address is not aligned on a 32-bit boundary, then ASSERT().
1164 @param Address Address that encodes the PCI Bus, Device, Function and
1166 @param AndData The value to AND with the PCI configuration register.
1168 @return The value written back to the PCI configuration register.
1178 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1182 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1183 value, followed a bitwise inclusive OR with another 32-bit value.
1185 Reads the 32-bit PCI configuration register specified by Address, performs a
1186 bitwise AND between the read result and the value specified by AndData,
1187 performs a bitwise inclusive OR between the result of the AND operation and
1188 the value specified by OrData, and writes the result to the 32-bit PCI
1189 configuration register specified by Address. The value written to the PCI
1190 configuration register is returned. This function must guarantee that all PCI
1191 read and write operations are serialized.
1193 If Address > 0x0FFFFFFF, then ASSERT().
1194 If Address is not aligned on a 32-bit boundary, then ASSERT().
1196 @param Address Address that encodes the PCI Bus, Device, Function and
1198 @param AndData The value to AND with the PCI configuration register.
1199 @param OrData The value to OR with the result of the AND operation.
1201 @return The value written back to the PCI configuration register.
1206 PciExpressAndThenOr32 (
1212 return MmioAndThenOr32 (
1213 GetPciExpressAddress (Address
),
1220 Reads a bit field of a PCI configuration register.
1222 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1223 specified by the StartBit and the EndBit. The value of the bit field is
1226 If Address > 0x0FFFFFFF, then ASSERT().
1227 If Address is not aligned on a 32-bit boundary, then ASSERT().
1228 If StartBit is greater than 31, then ASSERT().
1229 If EndBit is greater than 31, then ASSERT().
1230 If EndBit is less than StartBit, then ASSERT().
1232 @param Address PCI configuration register to read.
1233 @param StartBit The ordinal of the least significant bit in the bit field.
1235 @param EndBit The ordinal of the most significant bit in the bit field.
1238 @return The value of the bit field read from the PCI configuration register.
1243 PciExpressBitFieldRead32 (
1249 return MmioBitFieldRead32 (
1250 GetPciExpressAddress (Address
),
1257 Writes a bit field to a PCI configuration register.
1259 Writes Value to the bit field of the PCI configuration register. The bit
1260 field is specified by the StartBit and the EndBit. All other bits in the
1261 destination PCI configuration register are preserved. The new value of the
1262 32-bit register is returned.
1264 If Address > 0x0FFFFFFF, then ASSERT().
1265 If Address is not aligned on a 32-bit boundary, then ASSERT().
1266 If StartBit is greater than 31, then ASSERT().
1267 If EndBit is greater than 31, then ASSERT().
1268 If EndBit is less than StartBit, then ASSERT().
1270 @param Address PCI configuration register to write.
1271 @param StartBit The ordinal of the least significant bit in the bit field.
1273 @param EndBit The ordinal of the most significant bit in the bit field.
1275 @param Value New value of the bit field.
1277 @return The value written back to the PCI configuration register.
1282 PciExpressBitFieldWrite32 (
1289 return MmioBitFieldWrite32 (
1290 GetPciExpressAddress (Address
),
1298 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1299 writes the result back to the bit field in the 32-bit port.
1301 Reads the 32-bit PCI configuration register specified by Address, performs a
1302 bitwise inclusive OR between the read result and the value specified by
1303 OrData, and writes the result to the 32-bit PCI configuration register
1304 specified by Address. The value written to the PCI configuration register is
1305 returned. This function must guarantee that all PCI read and write operations
1306 are serialized. Extra left bits in OrData are stripped.
1308 If Address > 0x0FFFFFFF, then ASSERT().
1309 If Address is not aligned on a 32-bit boundary, then ASSERT().
1310 If StartBit is greater than 31, then ASSERT().
1311 If EndBit is greater than 31, then ASSERT().
1312 If EndBit is less than StartBit, then ASSERT().
1314 @param Address PCI configuration register to write.
1315 @param StartBit The ordinal of the least significant bit in the bit field.
1317 @param EndBit The ordinal of the most significant bit in the bit field.
1319 @param OrData The value to OR with the PCI configuration register.
1321 @return The value written back to the PCI configuration register.
1326 PciExpressBitFieldOr32 (
1333 return MmioBitFieldOr32 (
1334 GetPciExpressAddress (Address
),
1342 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1343 AND, and writes the result back to the bit field in the 32-bit register.
1345 Reads the 32-bit PCI configuration register specified by Address, performs a
1346 bitwise AND between the read result and the value specified by AndData, and
1347 writes the result to the 32-bit PCI configuration register specified by
1348 Address. The value written to the PCI configuration register is returned.
1349 This function must guarantee that all PCI read and write operations are
1350 serialized. Extra left bits in AndData are stripped.
1352 If Address > 0x0FFFFFFF, then ASSERT().
1353 If Address is not aligned on a 32-bit boundary, then ASSERT().
1354 If StartBit is greater than 31, then ASSERT().
1355 If EndBit is greater than 31, then ASSERT().
1356 If EndBit is less than StartBit, then ASSERT().
1358 @param Address PCI configuration register to write.
1359 @param StartBit The ordinal of the least significant bit in the bit field.
1361 @param EndBit The ordinal of the most significant bit in the bit field.
1363 @param AndData The value to AND with the PCI configuration register.
1365 @return The value written back to the PCI configuration register.
1370 PciExpressBitFieldAnd32 (
1377 return MmioBitFieldAnd32 (
1378 GetPciExpressAddress (Address
),
1386 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1387 bitwise inclusive OR, and writes the result back to the bit field in the
1390 Reads the 32-bit PCI configuration register specified by Address, performs a
1391 bitwise AND followed by a bitwise inclusive OR between the read result and
1392 the value specified by AndData, and writes the result to the 32-bit PCI
1393 configuration register specified by Address. The value written to the PCI
1394 configuration register is returned. This function must guarantee that all PCI
1395 read and write operations are serialized. Extra left bits in both AndData and
1396 OrData are stripped.
1398 If Address > 0x0FFFFFFF, then ASSERT().
1399 If Address is not aligned on a 32-bit boundary, then ASSERT().
1400 If StartBit is greater than 31, then ASSERT().
1401 If EndBit is greater than 31, then ASSERT().
1402 If EndBit is less than StartBit, then ASSERT().
1404 @param Address PCI configuration register to write.
1405 @param StartBit The ordinal of the least significant bit in the bit field.
1407 @param EndBit The ordinal of the most significant bit in the bit field.
1409 @param AndData The value to AND with the PCI configuration register.
1410 @param OrData The value to OR with the result of the AND operation.
1412 @return The value written back to the PCI configuration register.
1417 PciExpressBitFieldAndThenOr32 (
1425 return MmioBitFieldAndThenOr32 (
1426 GetPciExpressAddress (Address
),
1435 Reads a range of PCI configuration registers into a caller supplied buffer.
1437 Reads the range of PCI configuration registers specified by StartAddress and
1438 Size into the buffer specified by Buffer. This function only allows the PCI
1439 configuration registers from a single PCI function to be read. Size is
1440 returned. When possible 32-bit PCI configuration read cycles are used to read
1441 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1442 and 16-bit PCI configuration read cycles may be used at the beginning and the
1445 If StartAddress > 0x0FFFFFFF, then ASSERT().
1446 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1447 If Size > 0 and Buffer is NULL, then ASSERT().
1449 @param StartAddress Starting address that encodes the PCI Bus, Device,
1450 Function and Register.
1451 @param Size Size in bytes of the transfer.
1452 @param Buffer Pointer to a buffer receiving the data read.
1459 PciExpressReadBuffer (
1460 IN UINTN StartAddress
,
1467 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1473 ASSERT (Buffer
!= NULL
);
1476 // Save Size for return
1480 if ((StartAddress
& 1) != 0) {
1482 // Read a byte if StartAddress is byte aligned
1484 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1485 StartAddress
+= sizeof (UINT8
);
1486 Size
-= sizeof (UINT8
);
1487 Buffer
= (UINT8
*)Buffer
+ 1;
1490 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1492 // Read a word if StartAddress is word aligned
1494 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1496 StartAddress
+= sizeof (UINT16
);
1497 Size
-= sizeof (UINT16
);
1498 Buffer
= (UINT16
*)Buffer
+ 1;
1501 while (Size
>= sizeof (UINT32
)) {
1503 // Read as many double words as possible
1505 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1507 StartAddress
+= sizeof (UINT32
);
1508 Size
-= sizeof (UINT32
);
1509 Buffer
= (UINT32
*)Buffer
+ 1;
1512 if (Size
>= sizeof (UINT16
)) {
1514 // Read the last remaining word if exist
1516 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1517 StartAddress
+= sizeof (UINT16
);
1518 Size
-= sizeof (UINT16
);
1519 Buffer
= (UINT16
*)Buffer
+ 1;
1522 if (Size
>= sizeof (UINT8
)) {
1524 // Read the last remaining byte if exist
1526 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1533 Copies the data in a caller supplied buffer to a specified range of PCI
1534 configuration space.
1536 Writes the range of PCI configuration registers specified by StartAddress and
1537 Size from the buffer specified by Buffer. This function only allows the PCI
1538 configuration registers from a single PCI function to be written. Size is
1539 returned. When possible 32-bit PCI configuration write cycles are used to
1540 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1541 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1542 and the end of the range.
1544 If StartAddress > 0x0FFFFFFF, then ASSERT().
1545 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1546 If Size > 0 and Buffer is NULL, then ASSERT().
1548 @param StartAddress Starting address that encodes the PCI Bus, Device,
1549 Function and Register.
1550 @param Size Size in bytes of the transfer.
1551 @param Buffer Pointer to a buffer containing the data to write.
1558 PciExpressWriteBuffer (
1559 IN UINTN StartAddress
,
1566 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1572 ASSERT (Buffer
!= NULL
);
1575 // Save Size for return
1579 if ((StartAddress
& 1) != 0) {
1581 // Write a byte if StartAddress is byte aligned
1583 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1584 StartAddress
+= sizeof (UINT8
);
1585 Size
-= sizeof (UINT8
);
1586 Buffer
= (UINT8
*)Buffer
+ 1;
1589 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1591 // Write a word if StartAddress is word aligned
1593 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1594 StartAddress
+= sizeof (UINT16
);
1595 Size
-= sizeof (UINT16
);
1596 Buffer
= (UINT16
*)Buffer
+ 1;
1599 while (Size
>= sizeof (UINT32
)) {
1601 // Write as many double words as possible
1603 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1604 StartAddress
+= sizeof (UINT32
);
1605 Size
-= sizeof (UINT32
);
1606 Buffer
= (UINT32
*)Buffer
+ 1;
1609 if (Size
>= sizeof (UINT16
)) {
1611 // Write the last remaining word if exist
1613 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1614 StartAddress
+= sizeof (UINT16
);
1615 Size
-= sizeof (UINT16
);
1616 Buffer
= (UINT16
*)Buffer
+ 1;
1619 if (Size
>= sizeof (UINT8
)) {
1621 // Write the last remaining byte if exist
1623 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);