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 (
117 IN EFI_HANDLE ImageHandle
,
118 IN EFI_SYSTEM_TABLE
*SystemTable
124 // Cache the physical address of the PCI Express MMIO range into a module global variable
126 mDxeRuntimePciExpressLibPciExpressBaseAddress
= (UINTN
) PcdGet64 (PcdPciExpressBaseAddress
);
129 // Register SetVirtualAddressMap () notify function
131 Status
= gBS
->CreateEvent (
132 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
134 DxeRuntimePciExpressLibVirtualNotify
,
136 &mDxeRuntimePciExpressLibVirtualNotifyEvent
138 ASSERT_EFI_ERROR (Status
);
144 The destructor function frees any allocated buffers and closes the Set Virtual
147 @param ImageHandle The firmware allocated handle for the EFI image.
148 @param SystemTable A pointer to the EFI System Table.
150 @retval EFI_SUCCESS The destructor completed successfully.
151 @retval Other value The destructor did not complete successfully.
156 DxeRuntimePciExpressLibDestructor (
157 IN EFI_HANDLE ImageHandle
,
158 IN EFI_SYSTEM_TABLE
*SystemTable
164 // If one or more PCI devices have been registered for runtime access, then
165 // free the registration table.
167 if (mDxeRuntimePciExpressLibRegistrationTable
!= NULL
) {
168 FreePool (mDxeRuntimePciExpressLibRegistrationTable
);
172 // Close the Set Virtual Address Map event
174 Status
= gBS
->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent
);
175 ASSERT_EFI_ERROR (Status
);
181 Gets the base address of PCI Express.
183 This internal functions retrieves PCI Express Base Address via a PCD entry
184 PcdPciExpressBaseAddress.
186 @return The base address of PCI Express.
190 GetPciExpressAddress (
197 // Make sure Address is valid
199 ASSERT (((Address
) & ~0xfffffff) == 0);
202 // Convert Address to a physical address in the MMIO PCI Express range
204 Address
+= mDxeRuntimePciExpressLibPciExpressBaseAddress
;
207 // If SetVirtualAddressMap() has not been called, then just return the physical address
209 if (!EfiGoneVirtual ()) {
214 // See if there is a physical address match at the exact same index as the last address match
216 if (mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].PhysicalAddress
== (Address
& 0x0ffff000)) {
218 // Convert the physical address to a virtual address and return the virtual address
220 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibLastRuntimeRange
].VirtualAddress
;
224 // Search the entire table for a phyical address match
226 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
227 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== (Address
& 0x0ffff000)) {
229 // Cache the matching index value
231 mDxeRuntimePciExpressLibLastRuntimeRange
= Index
;
233 // Convert the physical address to a virtual address and return the virtual address
235 return (Address
& 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable
[Index
].VirtualAddress
;
240 // No match was found. This is a critical error at OS runtime, so ASSERT() and force a breakpoint.
246 // Return the physical address
252 Registers a PCI device so PCI configuration registers may be accessed after
253 SetVirtualAddressMap().
255 Registers the PCI device specified by Address so all the PCI configuration
256 registers associated with that PCI device may be accessed after SetVirtualAddressMap()
259 If Address > 0x0FFFFFFF, then ASSERT().
261 @param Address Address that encodes the PCI Bus, Device, Function and
264 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
265 @retval RETURN_UNSUPPORTED An attempt was made to call this function
266 after ExitBootServices().
267 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
268 at runtime could not be mapped.
269 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
270 complete the registration.
275 PciExpressRegisterForRuntimeAccess (
280 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
285 // Return an error if this function is called after ExitBootServices().
287 if (EfiAtRuntime ()) {
288 return RETURN_UNSUPPORTED
;
292 // Make sure Address is valid
294 ASSERT (((Address
) & ~0xfffffff) == 0);
297 // Convert Address to a physical address in the MMIO PCI Express range
298 // at the beginning of the PCI Configuration header for the specified
301 Address
= GetPciExpressAddress (Address
& 0x0ffff000);
304 // See if Address has already been registerd for runtime access
306 for (Index
= 0; Index
< mDxeRuntimePciExpressLibNumberOfRuntimeRanges
; Index
++) {
307 if (mDxeRuntimePciExpressLibRegistrationTable
[Index
].PhysicalAddress
== Address
) {
308 return RETURN_SUCCESS
;
313 // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address
315 Status
= gDS
->GetMemorySpaceDescriptor (Address
, &Descriptor
);
316 if (EFI_ERROR (Status
)) {
317 return RETURN_UNSUPPORTED
;
321 // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS
322 // will allocate a virtual address range for the 4KB PCI Configuration Header.
324 Status
= gDS
->SetMemorySpaceAttributes (Address
, 0x1000, Descriptor
.Attributes
| EFI_MEMORY_RUNTIME
);
325 if (EFI_ERROR (Status
)) {
326 return RETURN_UNSUPPORTED
;
330 // Grow the size of the registration table
332 NewTable
= ReallocateRuntimePool (
333 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
334 (mDxeRuntimePciExpressLibNumberOfRuntimeRanges
+ 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE
),
335 mDxeRuntimePciExpressLibRegistrationTable
337 if (NewTable
== NULL
) {
338 return RETURN_OUT_OF_RESOURCES
;
340 mDxeRuntimePciExpressLibRegistrationTable
= NewTable
;
341 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].PhysicalAddress
= Address
;
342 mDxeRuntimePciExpressLibRegistrationTable
[mDxeRuntimePciExpressLibNumberOfRuntimeRanges
].VirtualAddress
= Address
;
343 mDxeRuntimePciExpressLibNumberOfRuntimeRanges
++;
345 return RETURN_SUCCESS
;
350 Reads an 8-bit PCI configuration register.
352 Reads and returns the 8-bit PCI configuration register specified by Address.
353 This function must guarantee that all PCI read and write operations are
356 If Address > 0x0FFFFFFF, then ASSERT().
358 @param Address Address that encodes the PCI Bus, Device, Function and
361 @return The read value from the PCI configuration register.
370 return MmioRead8 (GetPciExpressAddress (Address
));
374 Writes an 8-bit PCI configuration register.
376 Writes the 8-bit PCI configuration register specified by Address with the
377 value specified by Value. Value is returned. This function must guarantee
378 that all PCI read and write operations are serialized.
380 If Address > 0x0FFFFFFF, then ASSERT().
382 @param Address Address that encodes the PCI Bus, Device, Function and
384 @param Value The value to write.
386 @return The value written to the PCI configuration register.
396 return MmioWrite8 (GetPciExpressAddress (Address
), Value
);
400 Performs a bitwise OR of an 8-bit PCI configuration register with
403 Reads the 8-bit PCI configuration register specified by Address, performs a
404 bitwise OR between the read result and the value specified by
405 OrData, and writes the result to the 8-bit PCI configuration register
406 specified by Address. The value written to the PCI configuration register is
407 returned. This function must guarantee that all PCI read and write operations
410 If Address > 0x0FFFFFFF, then ASSERT().
412 @param Address Address that encodes the PCI Bus, Device, Function and
414 @param OrData The value to OR with the PCI configuration register.
416 @return The value written back to the PCI configuration register.
426 return MmioOr8 (GetPciExpressAddress (Address
), OrData
);
430 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
433 Reads the 8-bit PCI configuration register specified by Address, performs a
434 bitwise AND between the read result and the value specified by AndData, and
435 writes the result to the 8-bit PCI configuration register specified by
436 Address. The value written to the PCI configuration register is returned.
437 This function must guarantee that all PCI read and write operations are
440 If Address > 0x0FFFFFFF, then ASSERT().
442 @param Address Address that encodes the PCI Bus, Device, Function and
444 @param AndData The value to AND with the PCI configuration register.
446 @return The value written back to the PCI configuration register.
456 return MmioAnd8 (GetPciExpressAddress (Address
), AndData
);
460 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
461 value, followed a bitwise OR with another 8-bit value.
463 Reads the 8-bit PCI configuration register specified by Address, performs a
464 bitwise AND between the read result and the value specified by AndData,
465 performs a bitwise OR between the result of the AND operation and
466 the value specified by OrData, and writes the result to the 8-bit PCI
467 configuration register specified by Address. The value written to the PCI
468 configuration register is returned. This function must guarantee that all PCI
469 read and write operations are serialized.
471 If Address > 0x0FFFFFFF, then ASSERT().
473 @param Address Address that encodes the PCI Bus, Device, Function and
475 @param AndData The value to AND with the PCI configuration register.
476 @param OrData The value to OR with the result of the AND operation.
478 @return The value written back to the PCI configuration register.
483 PciExpressAndThenOr8 (
489 return MmioAndThenOr8 (
490 GetPciExpressAddress (Address
),
497 Reads a bit field of a PCI configuration register.
499 Reads the bit field in an 8-bit PCI configuration register. The bit field is
500 specified by the StartBit and the EndBit. The value of the bit field is
503 If Address > 0x0FFFFFFF, then ASSERT().
504 If StartBit is greater than 7, then ASSERT().
505 If EndBit is greater than 7, then ASSERT().
506 If EndBit is less than StartBit, then ASSERT().
508 @param Address PCI configuration register to read.
509 @param StartBit The ordinal of the least significant bit in the bit field.
511 @param EndBit The ordinal of the most significant bit in the bit field.
514 @return The value of the bit field read from the PCI configuration register.
519 PciExpressBitFieldRead8 (
525 return MmioBitFieldRead8 (
526 GetPciExpressAddress (Address
),
533 Writes a bit field to a PCI configuration register.
535 Writes Value to the bit field of the PCI configuration register. The bit
536 field is specified by the StartBit and the EndBit. All other bits in the
537 destination PCI configuration register are preserved. The new value of the
538 8-bit register is returned.
540 If Address > 0x0FFFFFFF, then ASSERT().
541 If StartBit is greater than 7, then ASSERT().
542 If EndBit is greater than 7, then ASSERT().
543 If EndBit is less than StartBit, then ASSERT().
545 @param Address PCI configuration register to write.
546 @param StartBit The ordinal of the least significant bit in the bit field.
548 @param EndBit The ordinal of the most significant bit in the bit field.
550 @param Value New value of the bit field.
552 @return The value written back to the PCI configuration register.
557 PciExpressBitFieldWrite8 (
564 return MmioBitFieldWrite8 (
565 GetPciExpressAddress (Address
),
573 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
574 writes the result back to the bit field in the 8-bit port.
576 Reads the 8-bit PCI configuration register specified by Address, performs a
577 bitwise OR between the read result and the value specified by
578 OrData, and writes the result to the 8-bit PCI configuration register
579 specified by Address. The value written to the PCI configuration register is
580 returned. This function must guarantee that all PCI read and write operations
581 are serialized. Extra left bits in OrData are stripped.
583 If Address > 0x0FFFFFFF, then ASSERT().
584 If StartBit is greater than 7, then ASSERT().
585 If EndBit is greater than 7, then ASSERT().
586 If EndBit is less than StartBit, then ASSERT().
588 @param Address PCI configuration register to write.
589 @param StartBit The ordinal of the least significant bit in the bit field.
591 @param EndBit The ordinal of the most significant bit in the bit field.
593 @param OrData The value to OR with the PCI configuration register.
595 @return The value written back to the PCI configuration register.
600 PciExpressBitFieldOr8 (
607 return MmioBitFieldOr8 (
608 GetPciExpressAddress (Address
),
616 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
617 AND, and writes the result back to the bit field in the 8-bit register.
619 Reads the 8-bit PCI configuration register specified by Address, performs a
620 bitwise AND between the read result and the value specified by AndData, and
621 writes the result to the 8-bit PCI configuration register specified by
622 Address. The value written to the PCI configuration register is returned.
623 This function must guarantee that all PCI read and write operations are
624 serialized. Extra left bits in AndData are stripped.
626 If Address > 0x0FFFFFFF, then ASSERT().
627 If StartBit is greater than 7, then ASSERT().
628 If EndBit is greater than 7, then ASSERT().
629 If EndBit is less than StartBit, then ASSERT().
631 @param Address 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().
676 @param Address PCI configuration register to write.
677 @param StartBit The ordinal of the least significant bit in the bit field.
679 @param EndBit The ordinal of the most significant bit in the bit field.
681 @param AndData The value to AND with the PCI configuration register.
682 @param OrData The value to OR with the result of the AND operation.
684 @return The value written back to the PCI configuration register.
689 PciExpressBitFieldAndThenOr8 (
697 return MmioBitFieldAndThenOr8 (
698 GetPciExpressAddress (Address
),
707 Reads a 16-bit PCI configuration register.
709 Reads and returns the 16-bit PCI configuration register specified by Address.
710 This function must guarantee that all PCI read and write operations are
713 If Address > 0x0FFFFFFF, then ASSERT().
714 If Address is not aligned on a 16-bit boundary, then ASSERT().
716 @param Address Address that encodes the PCI Bus, Device, Function and
719 @return The read value from the PCI configuration register.
728 return MmioRead16 (GetPciExpressAddress (Address
));
732 Writes a 16-bit PCI configuration register.
734 Writes the 16-bit PCI configuration register specified by Address with the
735 value specified by Value. Value is returned. This function must guarantee
736 that all PCI read and write operations are serialized.
738 If Address > 0x0FFFFFFF, then ASSERT().
739 If Address is not aligned on a 16-bit boundary, then ASSERT().
741 @param Address Address that encodes the PCI Bus, Device, Function and
743 @param Value The value to write.
745 @return The value written to the PCI configuration register.
755 return MmioWrite16 (GetPciExpressAddress (Address
), Value
);
759 Performs a bitwise OR of a 16-bit PCI configuration register with
762 Reads the 16-bit PCI configuration register specified by Address, performs a
763 bitwise OR between the read result and the value specified by
764 OrData, and writes the result to the 16-bit PCI configuration register
765 specified by Address. The value written to the PCI configuration register is
766 returned. This function must guarantee that all PCI read and write operations
769 If Address > 0x0FFFFFFF, then ASSERT().
770 If Address is not aligned on a 16-bit boundary, then ASSERT().
772 @param Address Address that encodes the PCI Bus, Device, Function and
774 @param OrData The value to OR with the PCI configuration register.
776 @return The value written back to the PCI configuration register.
786 return MmioOr16 (GetPciExpressAddress (Address
), OrData
);
790 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
793 Reads the 16-bit PCI configuration register specified by Address, performs a
794 bitwise AND between the read result and the value specified by AndData, and
795 writes the result to the 16-bit PCI configuration register specified by
796 Address. The value written to the PCI configuration register is returned.
797 This function must guarantee that all PCI read and write operations are
800 If Address > 0x0FFFFFFF, then ASSERT().
801 If Address is not aligned on a 16-bit boundary, then ASSERT().
803 @param Address Address that encodes the PCI Bus, Device, Function and
805 @param AndData The value to AND with the PCI configuration register.
807 @return The value written back to the PCI configuration register.
817 return MmioAnd16 (GetPciExpressAddress (Address
), AndData
);
821 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
822 value, followed a bitwise OR with another 16-bit value.
824 Reads the 16-bit PCI configuration register specified by Address, performs a
825 bitwise AND between the read result and the value specified by AndData,
826 performs a bitwise OR between the result of the AND operation and
827 the value specified by OrData, and writes the result to the 16-bit PCI
828 configuration register specified by Address. The value written to the PCI
829 configuration register is returned. This function must guarantee that all PCI
830 read and write operations are serialized.
832 If Address > 0x0FFFFFFF, then ASSERT().
833 If Address is not aligned on a 16-bit boundary, then ASSERT().
835 @param Address Address that encodes the PCI Bus, Device, Function and
837 @param AndData The value to AND with the PCI configuration register.
838 @param OrData The value to OR with the result of the AND operation.
840 @return The value written back to the PCI configuration register.
845 PciExpressAndThenOr16 (
851 return MmioAndThenOr16 (
852 GetPciExpressAddress (Address
),
859 Reads a bit field of a PCI configuration register.
861 Reads the bit field in a 16-bit PCI configuration register. The bit field is
862 specified by the StartBit and the EndBit. The value of the bit field is
865 If Address > 0x0FFFFFFF, then ASSERT().
866 If Address is not aligned on a 16-bit boundary, then ASSERT().
867 If StartBit is greater than 15, then ASSERT().
868 If EndBit is greater than 15, then ASSERT().
869 If EndBit is less than StartBit, then ASSERT().
871 @param Address PCI configuration register to read.
872 @param StartBit The ordinal of the least significant bit in the bit field.
874 @param EndBit The ordinal of the most significant bit in the bit field.
877 @return The value of the bit field read from the PCI configuration register.
882 PciExpressBitFieldRead16 (
888 return MmioBitFieldRead16 (
889 GetPciExpressAddress (Address
),
896 Writes a bit field to a PCI configuration register.
898 Writes Value to the bit field of the PCI configuration register. The bit
899 field is specified by the StartBit and the EndBit. All other bits in the
900 destination PCI configuration register are preserved. The new value of the
901 16-bit register is returned.
903 If Address > 0x0FFFFFFF, then ASSERT().
904 If Address is not aligned on a 16-bit boundary, then ASSERT().
905 If StartBit is greater than 15, then ASSERT().
906 If EndBit is greater than 15, then ASSERT().
907 If EndBit is less than StartBit, then ASSERT().
909 @param Address PCI configuration register to write.
910 @param StartBit The ordinal of the least significant bit in the bit field.
912 @param EndBit The ordinal of the most significant bit in the bit field.
914 @param Value New value of the bit field.
916 @return The value written back to the PCI configuration register.
921 PciExpressBitFieldWrite16 (
928 return MmioBitFieldWrite16 (
929 GetPciExpressAddress (Address
),
937 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
938 writes the result back to the bit field in the 16-bit port.
940 Reads the 16-bit PCI configuration register specified by Address, performs a
941 bitwise OR between the read result and the value specified by
942 OrData, and writes the result to the 16-bit PCI configuration register
943 specified by Address. The value written to the PCI configuration register is
944 returned. This function must guarantee that all PCI read and write operations
945 are serialized. Extra left bits in OrData are stripped.
947 If Address > 0x0FFFFFFF, then ASSERT().
948 If Address is not aligned on a 16-bit boundary, then ASSERT().
949 If StartBit is greater than 15, then ASSERT().
950 If EndBit is greater than 15, then ASSERT().
951 If EndBit is less than StartBit, then ASSERT().
953 @param Address PCI configuration register to write.
954 @param StartBit The ordinal of the least significant bit in the bit field.
956 @param EndBit The ordinal of the most significant bit in the bit field.
958 @param OrData The value to OR with the PCI configuration register.
960 @return The value written back to the PCI configuration register.
965 PciExpressBitFieldOr16 (
972 return MmioBitFieldOr16 (
973 GetPciExpressAddress (Address
),
981 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
982 AND, and writes the result back to the bit field in the 16-bit register.
984 Reads the 16-bit PCI configuration register specified by Address, performs a
985 bitwise AND between the read result and the value specified by AndData, and
986 writes the result to the 16-bit PCI configuration register specified by
987 Address. The value written to the PCI configuration register is returned.
988 This function must guarantee that all PCI read and write operations are
989 serialized. Extra left bits in AndData are stripped.
991 If Address > 0x0FFFFFFF, then ASSERT().
992 If Address is not aligned on a 16-bit boundary, then ASSERT().
993 If StartBit is greater than 15, then ASSERT().
994 If EndBit is greater than 15, then ASSERT().
995 If EndBit is less than StartBit, then ASSERT().
997 @param Address PCI configuration register to write.
998 @param StartBit The ordinal of the least significant bit in the bit field.
1000 @param EndBit The ordinal of the most significant bit in the bit field.
1002 @param AndData The value to AND with the PCI configuration register.
1004 @return The value written back to the PCI configuration register.
1009 PciExpressBitFieldAnd16 (
1016 return MmioBitFieldAnd16 (
1017 GetPciExpressAddress (Address
),
1025 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1026 bitwise OR, and writes the result back to the bit field in the
1029 Reads the 16-bit PCI configuration register specified by Address, performs a
1030 bitwise AND followed by a bitwise OR between the read result and
1031 the value specified by AndData, and writes the result to the 16-bit PCI
1032 configuration register specified by Address. The value written to the PCI
1033 configuration register is returned. This function must guarantee that all PCI
1034 read and write operations are serialized. Extra left bits in both AndData and
1035 OrData are stripped.
1037 If Address > 0x0FFFFFFF, then ASSERT().
1038 If Address is not aligned on a 16-bit boundary, then ASSERT().
1039 If StartBit is greater than 15, then ASSERT().
1040 If EndBit is greater than 15, then ASSERT().
1041 If EndBit is less than StartBit, then ASSERT().
1043 @param Address PCI configuration register to write.
1044 @param StartBit The ordinal of the least significant bit in the bit field.
1046 @param EndBit The ordinal of the most significant bit in the bit field.
1048 @param AndData The value to AND with the PCI configuration register.
1049 @param OrData The value to OR with the result of the AND operation.
1051 @return The value written back to the PCI configuration register.
1056 PciExpressBitFieldAndThenOr16 (
1064 return MmioBitFieldAndThenOr16 (
1065 GetPciExpressAddress (Address
),
1074 Reads a 32-bit PCI configuration register.
1076 Reads and returns the 32-bit PCI configuration register specified by Address.
1077 This function must guarantee that all PCI read and write operations are
1080 If Address > 0x0FFFFFFF, then ASSERT().
1081 If Address is not aligned on a 32-bit boundary, then ASSERT().
1083 @param Address Address that encodes the PCI Bus, Device, Function and
1086 @return The read value from the PCI configuration register.
1095 return MmioRead32 (GetPciExpressAddress (Address
));
1099 Writes a 32-bit PCI configuration register.
1101 Writes the 32-bit PCI configuration register specified by Address with the
1102 value specified by Value. Value is returned. This function must guarantee
1103 that all PCI read and write operations are serialized.
1105 If Address > 0x0FFFFFFF, then ASSERT().
1106 If Address is not aligned on a 32-bit boundary, then ASSERT().
1108 @param Address Address that encodes the PCI Bus, Device, Function and
1110 @param Value The value to write.
1112 @return The value written to the PCI configuration register.
1122 return MmioWrite32 (GetPciExpressAddress (Address
), Value
);
1126 Performs a bitwise OR of a 32-bit PCI configuration register with
1129 Reads the 32-bit PCI configuration register specified by Address, performs a
1130 bitwise OR between the read result and the value specified by
1131 OrData, and writes the result to the 32-bit PCI configuration register
1132 specified by Address. The value written to the PCI configuration register is
1133 returned. This function must guarantee that all PCI read and write operations
1136 If Address > 0x0FFFFFFF, then ASSERT().
1137 If Address is not aligned on a 32-bit boundary, then ASSERT().
1139 @param Address Address that encodes the PCI Bus, Device, Function and
1141 @param OrData The value to OR with the PCI configuration register.
1143 @return The value written back to the PCI configuration register.
1153 return MmioOr32 (GetPciExpressAddress (Address
), OrData
);
1157 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1160 Reads the 32-bit PCI configuration register specified by Address, performs a
1161 bitwise AND between the read result and the value specified by AndData, and
1162 writes the result to the 32-bit PCI configuration register specified by
1163 Address. The value written to the PCI configuration register is returned.
1164 This function must guarantee that all PCI read and write operations are
1167 If Address > 0x0FFFFFFF, then ASSERT().
1168 If Address is not aligned on a 32-bit boundary, then ASSERT().
1170 @param Address Address that encodes the PCI Bus, Device, Function and
1172 @param AndData The value to AND with the PCI configuration register.
1174 @return The value written back to the PCI configuration register.
1184 return MmioAnd32 (GetPciExpressAddress (Address
), AndData
);
1188 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1189 value, followed a bitwise OR with another 32-bit value.
1191 Reads the 32-bit PCI configuration register specified by Address, performs a
1192 bitwise AND between the read result and the value specified by AndData,
1193 performs a bitwise OR between the result of the AND operation and
1194 the value specified by OrData, and writes the result to the 32-bit PCI
1195 configuration register specified by Address. The value written to the PCI
1196 configuration register is returned. This function must guarantee that all PCI
1197 read and write operations are serialized.
1199 If Address > 0x0FFFFFFF, then ASSERT().
1200 If Address is not aligned on a 32-bit boundary, then ASSERT().
1202 @param Address Address that encodes the PCI Bus, Device, Function and
1204 @param AndData The value to AND with the PCI configuration register.
1205 @param OrData The value to OR with the result of the AND operation.
1207 @return The value written back to the PCI configuration register.
1212 PciExpressAndThenOr32 (
1218 return MmioAndThenOr32 (
1219 GetPciExpressAddress (Address
),
1226 Reads a bit field of a PCI configuration register.
1228 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1229 specified by the StartBit and the EndBit. The value of the bit field is
1232 If Address > 0x0FFFFFFF, then ASSERT().
1233 If Address is not aligned on a 32-bit boundary, then ASSERT().
1234 If StartBit is greater than 31, then ASSERT().
1235 If EndBit is greater than 31, then ASSERT().
1236 If EndBit is less than StartBit, then ASSERT().
1238 @param Address PCI configuration register to read.
1239 @param StartBit The ordinal of the least significant bit in the bit field.
1241 @param EndBit The ordinal of the most significant bit in the bit field.
1244 @return The value of the bit field read from the PCI configuration register.
1249 PciExpressBitFieldRead32 (
1255 return MmioBitFieldRead32 (
1256 GetPciExpressAddress (Address
),
1263 Writes a bit field to a PCI configuration register.
1265 Writes Value to the bit field of the PCI configuration register. The bit
1266 field is specified by the StartBit and the EndBit. All other bits in the
1267 destination PCI configuration register are preserved. The new value of the
1268 32-bit register is returned.
1270 If Address > 0x0FFFFFFF, then ASSERT().
1271 If Address is not aligned on a 32-bit boundary, then ASSERT().
1272 If StartBit is greater than 31, then ASSERT().
1273 If EndBit is greater than 31, then ASSERT().
1274 If EndBit is less than StartBit, then ASSERT().
1276 @param Address PCI configuration register to write.
1277 @param StartBit The ordinal of the least significant bit in the bit field.
1279 @param EndBit The ordinal of the most significant bit in the bit field.
1281 @param Value New value of the bit field.
1283 @return The value written back to the PCI configuration register.
1288 PciExpressBitFieldWrite32 (
1295 return MmioBitFieldWrite32 (
1296 GetPciExpressAddress (Address
),
1304 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1305 writes the result back to the bit field in the 32-bit port.
1307 Reads the 32-bit PCI configuration register specified by Address, performs a
1308 bitwise OR between the read result and the value specified by
1309 OrData, and writes the result to the 32-bit PCI configuration register
1310 specified by Address. The value written to the PCI configuration register is
1311 returned. This function must guarantee that all PCI read and write operations
1312 are serialized. Extra left bits in OrData are stripped.
1314 If Address > 0x0FFFFFFF, then ASSERT().
1315 If Address is not aligned on a 32-bit boundary, then ASSERT().
1316 If StartBit is greater than 31, then ASSERT().
1317 If EndBit is greater than 31, then ASSERT().
1318 If EndBit is less than StartBit, then ASSERT().
1320 @param Address PCI configuration register to write.
1321 @param StartBit The ordinal of the least significant bit in the bit field.
1323 @param EndBit The ordinal of the most significant bit in the bit field.
1325 @param OrData The value to OR with the PCI configuration register.
1327 @return The value written back to the PCI configuration register.
1332 PciExpressBitFieldOr32 (
1339 return MmioBitFieldOr32 (
1340 GetPciExpressAddress (Address
),
1348 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1349 AND, and writes the result back to the bit field in the 32-bit register.
1351 Reads the 32-bit PCI configuration register specified by Address, performs a
1352 bitwise AND between the read result and the value specified by AndData, and
1353 writes the result to the 32-bit PCI configuration register specified by
1354 Address. The value written to the PCI configuration register is returned.
1355 This function must guarantee that all PCI read and write operations are
1356 serialized. Extra left bits in AndData are stripped.
1358 If Address > 0x0FFFFFFF, then ASSERT().
1359 If Address is not aligned on a 32-bit boundary, then ASSERT().
1360 If StartBit is greater than 31, then ASSERT().
1361 If EndBit is greater than 31, then ASSERT().
1362 If EndBit is less than StartBit, then ASSERT().
1364 @param Address PCI configuration register to write.
1365 @param StartBit The ordinal of the least significant bit in the bit field.
1367 @param EndBit The ordinal of the most significant bit in the bit field.
1369 @param AndData The value to AND with the PCI configuration register.
1371 @return The value written back to the PCI configuration register.
1376 PciExpressBitFieldAnd32 (
1383 return MmioBitFieldAnd32 (
1384 GetPciExpressAddress (Address
),
1392 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1393 bitwise OR, and writes the result back to the bit field in the
1396 Reads the 32-bit PCI configuration register specified by Address, performs a
1397 bitwise AND followed by a bitwise OR between the read result and
1398 the value specified by AndData, and writes the result to the 32-bit PCI
1399 configuration register specified by Address. The value written to the PCI
1400 configuration register is returned. This function must guarantee that all PCI
1401 read and write operations are serialized. Extra left bits in both AndData and
1402 OrData are stripped.
1404 If Address > 0x0FFFFFFF, then ASSERT().
1405 If Address is not aligned on a 32-bit boundary, then ASSERT().
1406 If StartBit is greater than 31, then ASSERT().
1407 If EndBit is greater than 31, then ASSERT().
1408 If EndBit is less than StartBit, then ASSERT().
1410 @param Address PCI configuration register to write.
1411 @param StartBit The ordinal of the least significant bit in the bit field.
1413 @param EndBit The ordinal of the most significant bit in the bit field.
1415 @param AndData The value to AND with the PCI configuration register.
1416 @param OrData The value to OR with the result of the AND operation.
1418 @return The value written back to the PCI configuration register.
1423 PciExpressBitFieldAndThenOr32 (
1431 return MmioBitFieldAndThenOr32 (
1432 GetPciExpressAddress (Address
),
1441 Reads a range of PCI configuration registers into a caller supplied buffer.
1443 Reads the range of PCI configuration registers specified by StartAddress and
1444 Size into the buffer specified by Buffer. This function only allows the PCI
1445 configuration registers from a single PCI function to be read. Size is
1446 returned. When possible 32-bit PCI configuration read cycles are used to read
1447 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1448 and 16-bit PCI configuration read cycles may be used at the beginning and the
1451 If StartAddress > 0x0FFFFFFF, then ASSERT().
1452 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1453 If Size > 0 and Buffer is NULL, then ASSERT().
1455 @param StartAddress Starting address that encodes the PCI Bus, Device,
1456 Function and Register.
1457 @param Size Size in bytes of the transfer.
1458 @param Buffer Pointer to a buffer receiving the data read.
1460 @return Size read data from StartAddress.
1465 PciExpressReadBuffer (
1466 IN UINTN StartAddress
,
1473 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1479 ASSERT (Buffer
!= NULL
);
1482 // Save Size for return
1486 if ((StartAddress
& 1) != 0) {
1488 // Read a byte if StartAddress is byte aligned
1490 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1491 StartAddress
+= sizeof (UINT8
);
1492 Size
-= sizeof (UINT8
);
1493 Buffer
= (UINT8
*)Buffer
+ 1;
1496 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1498 // Read a word if StartAddress is word aligned
1500 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1502 StartAddress
+= sizeof (UINT16
);
1503 Size
-= sizeof (UINT16
);
1504 Buffer
= (UINT16
*)Buffer
+ 1;
1507 while (Size
>= sizeof (UINT32
)) {
1509 // Read as many double words as possible
1511 WriteUnaligned32 ((UINT32
*) Buffer
, (UINT32
) PciExpressRead32 (StartAddress
));
1513 StartAddress
+= sizeof (UINT32
);
1514 Size
-= sizeof (UINT32
);
1515 Buffer
= (UINT32
*)Buffer
+ 1;
1518 if (Size
>= sizeof (UINT16
)) {
1520 // Read the last remaining word if exist
1522 WriteUnaligned16 ((UINT16
*) Buffer
, (UINT16
) PciExpressRead16 (StartAddress
));
1523 StartAddress
+= sizeof (UINT16
);
1524 Size
-= sizeof (UINT16
);
1525 Buffer
= (UINT16
*)Buffer
+ 1;
1528 if (Size
>= sizeof (UINT8
)) {
1530 // Read the last remaining byte if exist
1532 *(volatile UINT8
*)Buffer
= PciExpressRead8 (StartAddress
);
1539 Copies the data in a caller supplied buffer to a specified range of PCI
1540 configuration space.
1542 Writes the range of PCI configuration registers specified by StartAddress and
1543 Size from the buffer specified by Buffer. This function only allows the PCI
1544 configuration registers from a single PCI function to be written. Size is
1545 returned. When possible 32-bit PCI configuration write cycles are used to
1546 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1547 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1548 and the end of the range.
1550 If StartAddress > 0x0FFFFFFF, then ASSERT().
1551 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1552 If Size > 0 and Buffer is NULL, then ASSERT().
1554 @param StartAddress Starting address that encodes the PCI Bus, Device,
1555 Function and Register.
1556 @param Size Size in bytes of the transfer.
1557 @param Buffer Pointer to a buffer containing the data to write.
1559 @return Size written to StartAddress.
1564 PciExpressWriteBuffer (
1565 IN UINTN StartAddress
,
1572 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1578 ASSERT (Buffer
!= NULL
);
1581 // Save Size for return
1585 if ((StartAddress
& 1) != 0) {
1587 // Write a byte if StartAddress is byte aligned
1589 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1590 StartAddress
+= sizeof (UINT8
);
1591 Size
-= sizeof (UINT8
);
1592 Buffer
= (UINT8
*)Buffer
+ 1;
1595 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1597 // Write a word if StartAddress is word aligned
1599 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1600 StartAddress
+= sizeof (UINT16
);
1601 Size
-= sizeof (UINT16
);
1602 Buffer
= (UINT16
*)Buffer
+ 1;
1605 while (Size
>= sizeof (UINT32
)) {
1607 // Write as many double words as possible
1609 PciExpressWrite32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1610 StartAddress
+= sizeof (UINT32
);
1611 Size
-= sizeof (UINT32
);
1612 Buffer
= (UINT32
*)Buffer
+ 1;
1615 if (Size
>= sizeof (UINT16
)) {
1617 // Write the last remaining word if exist
1619 PciExpressWrite16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1620 StartAddress
+= sizeof (UINT16
);
1621 Size
-= sizeof (UINT16
);
1622 Buffer
= (UINT16
*)Buffer
+ 1;
1625 if (Size
>= sizeof (UINT8
)) {
1627 // Write the last remaining byte if exist
1629 PciExpressWrite8 (StartAddress
, *(UINT8
*)Buffer
);