2 PCI Library using SMM PCI Root Bridge I/O Protocol.
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Protocol/SmmPciRootBridgeIo.h>
10 #include <Library/PciLib.h>
11 #include <Library/DebugLib.h>
12 #include <Library/BaseLib.h>
13 #include <Library/SmmServicesTableLib.h>
16 Assert the validity of a PCI address. A valid PCI address should contain 1's
17 only in the low 28 bits.
19 @param A The address to validate.
20 @param M Additional bits to assert to be zero.
23 #define ASSERT_INVALID_PCI_ADDRESS(A, M) \
24 ASSERT (((A) & (~0xfffffff | (M))) == 0)
27 Translate PCI Lib address into format of PCI Root Bridge I/O Protocol.
29 @param A The address that encodes the PCI Bus, Device, Function and
33 #define PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS(A) \
34 ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))
37 // Global variable to cache pointer to PCI Root Bridge I/O protocol.
39 EFI_SMM_PCI_ROOT_BRIDGE_IO_PROTOCOL
*mSmmPciRootBridgeIo
= NULL
;
42 The constructor function caches the pointer to PCI Root Bridge I/O protocol.
44 The constructor function locates PCI Root Bridge I/O protocol from protocol database.
45 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
47 @param ImageHandle The firmware allocated handle for the EFI image.
48 @param SystemTable A pointer to the EFI System Table.
50 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
56 IN EFI_HANDLE ImageHandle
,
57 IN EFI_SYSTEM_TABLE
*SystemTable
62 Status
= gSmst
->SmmLocateProtocol (&gEfiSmmPciRootBridgeIoProtocolGuid
, NULL
, (VOID
**)&mSmmPciRootBridgeIo
);
63 ASSERT_EFI_ERROR (Status
);
64 ASSERT (mSmmPciRootBridgeIo
!= NULL
);
70 Internal worker function to read a PCI configuration register.
72 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
73 It reads and returns the PCI configuration register specified by Address,
74 the width of data is specified by Width.
76 @param Address The address that encodes the PCI Bus, Device, Function and
78 @param Width The width of data to read
80 @return The value read from the PCI configuration register.
84 SmmPciLibPciRootBridgeIoReadWorker (
86 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
91 mSmmPciRootBridgeIo
->Pci
.Read (
94 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
103 Internal worker function to writes a PCI configuration register.
105 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
106 It writes the PCI configuration register specified by Address with the
107 value specified by Data. The width of data is specified by Width.
110 @param Address The address that encodes the PCI Bus, Device, Function and
112 @param Width The width of data to write
113 @param Data The value to write.
115 @return The value written to the PCI configuration register.
119 SmmPciLibPciRootBridgeIoWriteWorker (
121 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
125 mSmmPciRootBridgeIo
->Pci
.Write (
128 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
136 Registers a PCI device so PCI configuration registers may be accessed after
137 SetVirtualAddressMap().
139 Registers the PCI device specified by Address so all the PCI configuration registers
140 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
142 If Address > 0x0FFFFFFF, then ASSERT().
144 @param Address The address that encodes the PCI Bus, Device, Function and
147 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
148 @retval RETURN_UNSUPPORTED An attempt was made to call this function
149 after ExitBootServices().
150 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
151 at runtime could not be mapped.
152 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
153 complete the registration.
158 PciRegisterForRuntimeAccess (
162 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
163 return RETURN_UNSUPPORTED
;
167 Reads an 8-bit PCI configuration register.
169 Reads and returns the 8-bit PCI configuration register specified by Address.
170 This function must guarantee that all PCI read and write operations are
173 If Address > 0x0FFFFFFF, then ASSERT().
175 @param Address The address that encodes the PCI Bus, Device, Function and
178 @return The read value from the PCI configuration register.
187 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
189 return (UINT8
)SmmPciLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
193 Writes an 8-bit PCI configuration register.
195 Writes the 8-bit PCI configuration register specified by Address with the
196 value specified by Value. Value is returned. This function must guarantee
197 that all PCI read and write operations are serialized.
199 If Address > 0x0FFFFFFF, then ASSERT().
201 @param Address The address that encodes the PCI Bus, Device, Function and
203 @param Value The value to write.
205 @return The value written to the PCI configuration register.
215 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
217 return (UINT8
)SmmPciLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
221 Performs a bitwise OR of an 8-bit PCI configuration register with
224 Reads the 8-bit PCI configuration register specified by Address, performs a
225 bitwise OR between the read result and the value specified by
226 OrData, and writes the result to the 8-bit PCI configuration register
227 specified by Address. The value written to the PCI configuration register is
228 returned. This function must guarantee that all PCI read and write operations
231 If Address > 0x0FFFFFFF, then ASSERT().
233 @param Address The address that encodes the PCI Bus, Device, Function and
235 @param OrData The value to OR with the PCI configuration register.
237 @return The value written back to the PCI configuration register.
247 return PciWrite8 (Address
, (UINT8
)(PciRead8 (Address
) | OrData
));
251 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
254 Reads the 8-bit PCI configuration register specified by Address, performs a
255 bitwise AND between the read result and the value specified by AndData, and
256 writes the result to the 8-bit PCI configuration register specified by
257 Address. The value written to the PCI configuration register is returned.
258 This function must guarantee that all PCI read and write operations are
261 If Address > 0x0FFFFFFF, then ASSERT().
263 @param Address The address that encodes the PCI Bus, Device, Function and
265 @param AndData The value to AND with the PCI configuration register.
267 @return The value written back to the PCI configuration register.
277 return PciWrite8 (Address
, (UINT8
)(PciRead8 (Address
) & AndData
));
281 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
282 value, followed a bitwise OR with another 8-bit value.
284 Reads the 8-bit PCI configuration register specified by Address, performs a
285 bitwise AND between the read result and the value specified by AndData,
286 performs a bitwise OR between the result of the AND operation and
287 the value specified by OrData, and writes the result to the 8-bit PCI
288 configuration register specified by Address. The value written to the PCI
289 configuration register is returned. This function must guarantee that all PCI
290 read and write operations are serialized.
292 If Address > 0x0FFFFFFF, then ASSERT().
294 @param Address The address that encodes the PCI Bus, Device, Function and
296 @param AndData The value to AND with the PCI configuration register.
297 @param OrData The value to OR with the result of the AND operation.
299 @return The value written back to the PCI configuration register.
310 return PciWrite8 (Address
, (UINT8
)((PciRead8 (Address
) & AndData
) | OrData
));
314 Reads a bit field of a PCI configuration register.
316 Reads the bit field in an 8-bit PCI configuration register. The bit field is
317 specified by the StartBit and the EndBit. The value of the bit field is
320 If Address > 0x0FFFFFFF, then ASSERT().
321 If StartBit is greater than 7, then ASSERT().
322 If EndBit is greater than 7, then ASSERT().
323 If EndBit is less than StartBit, then ASSERT().
325 @param Address The PCI configuration register to read.
326 @param StartBit The ordinal of the least significant bit in the bit field.
328 @param EndBit The ordinal of the most significant bit in the bit field.
331 @return The value of the bit field read from the PCI configuration register.
342 return BitFieldRead8 (PciRead8 (Address
), StartBit
, EndBit
);
346 Writes a bit field to a PCI configuration register.
348 Writes Value to the bit field of the PCI configuration register. The bit
349 field is specified by the StartBit and the EndBit. All other bits in the
350 destination PCI configuration register are preserved. The new value of the
351 8-bit register is returned.
353 If Address > 0x0FFFFFFF, then ASSERT().
354 If StartBit is greater than 7, then ASSERT().
355 If EndBit is greater than 7, then ASSERT().
356 If EndBit is less than StartBit, then ASSERT().
357 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
359 @param Address The PCI configuration register to write.
360 @param StartBit The ordinal of the least significant bit in the bit field.
362 @param EndBit The ordinal of the most significant bit in the bit field.
364 @param Value The new value of the bit field.
366 @return The value written back to the PCI configuration register.
380 BitFieldWrite8 (PciRead8 (Address
), StartBit
, EndBit
, Value
)
385 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
386 writes the result back to the bit field in the 8-bit port.
388 Reads the 8-bit PCI configuration register specified by Address, performs a
389 bitwise OR between the read result and the value specified by
390 OrData, and writes the result to the 8-bit PCI configuration register
391 specified by Address. The value written to the PCI configuration register is
392 returned. This function must guarantee that all PCI read and write operations
393 are serialized. Extra left bits in OrData are stripped.
395 If Address > 0x0FFFFFFF, then ASSERT().
396 If StartBit is greater than 7, then ASSERT().
397 If EndBit is greater than 7, then ASSERT().
398 If EndBit is less than StartBit, then ASSERT().
399 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
401 @param Address The PCI configuration register to write.
402 @param StartBit The ordinal of the least significant bit in the bit field.
404 @param EndBit The ordinal of the most significant bit in the bit field.
406 @param OrData The value to OR with the PCI configuration register.
408 @return The value written back to the PCI configuration register.
422 BitFieldOr8 (PciRead8 (Address
), StartBit
, EndBit
, OrData
)
427 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
428 AND, and writes the result back to the bit field in the 8-bit register.
430 Reads the 8-bit PCI configuration register specified by Address, performs a
431 bitwise AND between the read result and the value specified by AndData, and
432 writes the result to the 8-bit PCI configuration register specified by
433 Address. The value written to the PCI configuration register is returned.
434 This function must guarantee that all PCI read and write operations are
435 serialized. Extra left bits in AndData are stripped.
437 If Address > 0x0FFFFFFF, then ASSERT().
438 If StartBit is greater than 7, then ASSERT().
439 If EndBit is greater than 7, then ASSERT().
440 If EndBit is less than StartBit, then ASSERT().
441 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
443 @param Address The PCI configuration register to write.
444 @param StartBit The ordinal of the least significant bit in the bit field.
446 @param EndBit The ordinal of the most significant bit in the bit field.
448 @param AndData The value to AND with the PCI configuration register.
450 @return The value written back to the PCI configuration register.
464 BitFieldAnd8 (PciRead8 (Address
), StartBit
, EndBit
, AndData
)
469 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
470 bitwise OR, and writes the result back to the bit field in the
473 Reads the 8-bit PCI configuration register specified by Address, performs a
474 bitwise AND followed by a bitwise OR between the read result and
475 the value specified by AndData, and writes the result to the 8-bit PCI
476 configuration register specified by Address. The value written to the PCI
477 configuration register is returned. This function must guarantee that all PCI
478 read and write operations are serialized. Extra left bits in both AndData and
481 If Address > 0x0FFFFFFF, then ASSERT().
482 If StartBit is greater than 7, then ASSERT().
483 If EndBit is greater than 7, then ASSERT().
484 If EndBit is less than StartBit, then ASSERT().
485 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
486 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
488 @param Address The PCI configuration register to write.
489 @param StartBit The ordinal of the least significant bit in the bit field.
491 @param EndBit The ordinal of the most significant bit in the bit field.
493 @param AndData The value to AND with the PCI configuration register.
494 @param OrData The value to OR with the result of the AND operation.
496 @return The value written back to the PCI configuration register.
501 PciBitFieldAndThenOr8 (
511 BitFieldAndThenOr8 (PciRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
516 Reads a 16-bit PCI configuration register.
518 Reads and returns the 16-bit PCI configuration register specified by Address.
519 This function must guarantee that all PCI read and write operations are
522 If Address > 0x0FFFFFFF, then ASSERT().
523 If Address is not aligned on a 16-bit boundary, then ASSERT().
525 @param Address The address that encodes the PCI Bus, Device, Function and
528 @return The read value from the PCI configuration register.
537 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
539 return (UINT16
)SmmPciLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
543 Writes a 16-bit PCI configuration register.
545 Writes the 16-bit PCI configuration register specified by Address with the
546 value specified by Value. Value is returned. This function must guarantee
547 that all PCI read and write operations are serialized.
549 If Address > 0x0FFFFFFF, then ASSERT().
550 If Address is not aligned on a 16-bit boundary, then ASSERT().
552 @param Address The address that encodes the PCI Bus, Device, Function and
554 @param Value The value to write.
556 @return The value written to the PCI configuration register.
566 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
568 return (UINT16
)SmmPciLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
572 Performs a bitwise OR of a 16-bit PCI configuration register with
575 Reads the 16-bit PCI configuration register specified by Address, performs a
576 bitwise OR between the read result and the value specified by
577 OrData, and writes the result to the 16-bit PCI configuration register
578 specified by Address. The value written to the PCI configuration register is
579 returned. This function must guarantee that all PCI read and write operations
582 If Address > 0x0FFFFFFF, then ASSERT().
583 If Address is not aligned on a 16-bit boundary, then ASSERT().
585 @param Address The address that encodes the PCI Bus, Device, Function and
587 @param OrData The value to OR with the PCI configuration register.
589 @return The value written back to the PCI configuration register.
599 return PciWrite16 (Address
, (UINT16
)(PciRead16 (Address
) | OrData
));
603 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
606 Reads the 16-bit PCI configuration register specified by Address, performs a
607 bitwise AND between the read result and the value specified by AndData, and
608 writes the result to the 16-bit PCI configuration register specified by
609 Address. The value written to the PCI configuration register is returned.
610 This function must guarantee that all PCI read and write operations are
613 If Address > 0x0FFFFFFF, then ASSERT().
614 If Address is not aligned on a 16-bit boundary, then ASSERT().
616 @param Address The address that encodes the PCI Bus, Device, Function and
618 @param AndData The value to AND with the PCI configuration register.
620 @return The value written back to the PCI configuration register.
630 return PciWrite16 (Address
, (UINT16
)(PciRead16 (Address
) & AndData
));
634 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
635 value, followed a bitwise OR with another 16-bit value.
637 Reads the 16-bit PCI configuration register specified by Address, performs a
638 bitwise AND between the read result and the value specified by AndData,
639 performs a bitwise OR between the result of the AND operation and
640 the value specified by OrData, and writes the result to the 16-bit PCI
641 configuration register specified by Address. The value written to the PCI
642 configuration register is returned. This function must guarantee that all PCI
643 read and write operations are serialized.
645 If Address > 0x0FFFFFFF, then ASSERT().
646 If Address is not aligned on a 16-bit boundary, then ASSERT().
648 @param Address The address that encodes the PCI Bus, Device, Function and
650 @param AndData The value to AND with the PCI configuration register.
651 @param OrData The value to OR with the result of the AND operation.
653 @return The value written back to the PCI configuration register.
664 return PciWrite16 (Address
, (UINT16
)((PciRead16 (Address
) & AndData
) | OrData
));
668 Reads a bit field of a PCI configuration register.
670 Reads the bit field in a 16-bit PCI configuration register. The bit field is
671 specified by the StartBit and the EndBit. The value of the bit field is
674 If Address > 0x0FFFFFFF, then ASSERT().
675 If Address is not aligned on a 16-bit boundary, then ASSERT().
676 If StartBit is greater than 15, then ASSERT().
677 If EndBit is greater than 15, then ASSERT().
678 If EndBit is less than StartBit, then ASSERT().
680 @param Address The PCI configuration register to read.
681 @param StartBit The ordinal of the least significant bit in the bit field.
683 @param EndBit The ordinal of the most significant bit in the bit field.
686 @return The value of the bit field read from the PCI configuration register.
697 return BitFieldRead16 (PciRead16 (Address
), StartBit
, EndBit
);
701 Writes a bit field to a PCI configuration register.
703 Writes Value to the bit field of the PCI configuration register. The bit
704 field is specified by the StartBit and the EndBit. All other bits in the
705 destination PCI configuration register are preserved. The new value of the
706 16-bit register is returned.
708 If Address > 0x0FFFFFFF, then ASSERT().
709 If Address is not aligned on a 16-bit boundary, then ASSERT().
710 If StartBit is greater than 15, then ASSERT().
711 If EndBit is greater than 15, then ASSERT().
712 If EndBit is less than StartBit, then ASSERT().
713 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
715 @param Address The PCI configuration register to write.
716 @param StartBit The ordinal of the least significant bit in the bit field.
718 @param EndBit The ordinal of the most significant bit in the bit field.
720 @param Value The new value of the bit field.
722 @return The value written back to the PCI configuration register.
736 BitFieldWrite16 (PciRead16 (Address
), StartBit
, EndBit
, Value
)
741 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
742 writes the result back to the bit field in the 16-bit port.
744 Reads the 16-bit PCI configuration register specified by Address, performs a
745 bitwise OR between the read result and the value specified by
746 OrData, and writes the result to the 16-bit PCI configuration register
747 specified by Address. The value written to the PCI configuration register is
748 returned. This function must guarantee that all PCI read and write operations
749 are serialized. Extra left bits in OrData are stripped.
751 If Address > 0x0FFFFFFF, then ASSERT().
752 If Address is not aligned on a 16-bit boundary, then ASSERT().
753 If StartBit is greater than 15, then ASSERT().
754 If EndBit is greater than 15, then ASSERT().
755 If EndBit is less than StartBit, then ASSERT().
756 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
758 @param Address The PCI configuration register to write.
759 @param StartBit The ordinal of the least significant bit in the bit field.
761 @param EndBit The ordinal of the most significant bit in the bit field.
763 @param OrData The value to OR with the PCI configuration register.
765 @return The value written back to the PCI configuration register.
779 BitFieldOr16 (PciRead16 (Address
), StartBit
, EndBit
, OrData
)
784 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
785 AND, and writes the result back to the bit field in the 16-bit register.
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
792 serialized. Extra left bits in AndData are stripped.
794 If Address > 0x0FFFFFFF, then ASSERT().
795 If Address is not aligned on a 16-bit boundary, then ASSERT().
796 If StartBit is greater than 15, then ASSERT().
797 If EndBit is greater than 15, then ASSERT().
798 If EndBit is less than StartBit, then ASSERT().
799 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
801 @param Address The PCI configuration register to write.
802 @param StartBit The ordinal of the least significant bit in the bit field.
804 @param EndBit The ordinal of the most significant bit in the bit field.
806 @param AndData The value to AND with the PCI configuration register.
808 @return The value written back to the PCI configuration register.
822 BitFieldAnd16 (PciRead16 (Address
), StartBit
, EndBit
, AndData
)
827 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
828 bitwise OR, and writes the result back to the bit field in the
831 Reads the 16-bit PCI configuration register specified by Address, performs a
832 bitwise AND followed by a bitwise OR between the read result and
833 the value specified by AndData, and writes the result to the 16-bit PCI
834 configuration register specified by Address. The value written to the PCI
835 configuration register is returned. This function must guarantee that all PCI
836 read and write operations are serialized. Extra left bits in both AndData and
839 If Address > 0x0FFFFFFF, then ASSERT().
840 If Address is not aligned on a 16-bit boundary, then ASSERT().
841 If StartBit is greater than 15, then ASSERT().
842 If EndBit is greater than 15, then ASSERT().
843 If EndBit is less than StartBit, then ASSERT().
844 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
845 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
847 @param Address The PCI configuration register to write.
848 @param StartBit The ordinal of the least significant bit in the bit field.
850 @param EndBit The ordinal of the most significant bit in the bit field.
852 @param AndData The value to AND with the PCI configuration register.
853 @param OrData The value to OR with the result of the AND operation.
855 @return The value written back to the PCI configuration register.
860 PciBitFieldAndThenOr16 (
870 BitFieldAndThenOr16 (PciRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
875 Reads a 32-bit PCI configuration register.
877 Reads and returns the 32-bit PCI configuration register specified by Address.
878 This function must guarantee that all PCI read and write operations are
881 If Address > 0x0FFFFFFF, then ASSERT().
882 If Address is not aligned on a 32-bit boundary, then ASSERT().
884 @param Address The address that encodes the PCI Bus, Device, Function and
887 @return The read value from the PCI configuration register.
896 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
898 return SmmPciLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
902 Writes a 32-bit PCI configuration register.
904 Writes the 32-bit PCI configuration register specified by Address with the
905 value specified by Value. Value is returned. This function must guarantee
906 that all PCI read and write operations are serialized.
908 If Address > 0x0FFFFFFF, then ASSERT().
909 If Address is not aligned on a 32-bit boundary, then ASSERT().
911 @param Address The address that encodes the PCI Bus, Device, Function and
913 @param Value The value to write.
915 @return The value written to the PCI configuration register.
925 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
927 return SmmPciLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
931 Performs a bitwise OR of a 32-bit PCI configuration register with
934 Reads the 32-bit PCI configuration register specified by Address, performs a
935 bitwise OR between the read result and the value specified by
936 OrData, and writes the result to the 32-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
941 If Address > 0x0FFFFFFF, then ASSERT().
942 If Address is not aligned on a 32-bit boundary, then ASSERT().
944 @param Address The address that encodes the PCI Bus, Device, Function and
946 @param OrData The value to OR with the PCI configuration register.
948 @return The value written back to the PCI configuration register.
958 return PciWrite32 (Address
, PciRead32 (Address
) | OrData
);
962 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
965 Reads the 32-bit PCI configuration register specified by Address, performs a
966 bitwise AND between the read result and the value specified by AndData, and
967 writes the result to the 32-bit PCI configuration register specified by
968 Address. The value written to the PCI configuration register is returned.
969 This function must guarantee that all PCI read and write operations are
972 If Address > 0x0FFFFFFF, then ASSERT().
973 If Address is not aligned on a 32-bit boundary, then ASSERT().
975 @param Address The address that encodes the PCI Bus, Device, Function and
977 @param AndData The value to AND with the PCI configuration register.
979 @return The value written back to the PCI configuration register.
989 return PciWrite32 (Address
, PciRead32 (Address
) & AndData
);
993 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
994 value, followed a bitwise OR with another 32-bit value.
996 Reads the 32-bit PCI configuration register specified by Address, performs a
997 bitwise AND between the read result and the value specified by AndData,
998 performs a bitwise OR between the result of the AND operation and
999 the value specified by OrData, and writes the result to the 32-bit PCI
1000 configuration register specified by Address. The value written to the PCI
1001 configuration register is returned. This function must guarantee that all PCI
1002 read and write operations are serialized.
1004 If Address > 0x0FFFFFFF, then ASSERT().
1005 If Address is not aligned on a 32-bit boundary, then ASSERT().
1007 @param Address The address that encodes the PCI Bus, Device, Function and
1009 @param AndData The value to AND with the PCI configuration register.
1010 @param OrData The value to OR with the result of the AND operation.
1012 @return The value written back to the PCI configuration register.
1023 return PciWrite32 (Address
, (PciRead32 (Address
) & AndData
) | OrData
);
1027 Reads a bit field of a PCI configuration register.
1029 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1030 specified by the StartBit and the EndBit. The value of the bit field is
1033 If Address > 0x0FFFFFFF, then ASSERT().
1034 If Address is not aligned on a 32-bit boundary, then ASSERT().
1035 If StartBit is greater than 31, then ASSERT().
1036 If EndBit is greater than 31, then ASSERT().
1037 If EndBit is less than StartBit, then ASSERT().
1039 @param Address The PCI configuration register to read.
1040 @param StartBit The ordinal of the least significant bit in the bit field.
1042 @param EndBit The ordinal of the most significant bit in the bit field.
1045 @return The value of the bit field read from the PCI configuration register.
1056 return BitFieldRead32 (PciRead32 (Address
), StartBit
, EndBit
);
1060 Writes a bit field to a PCI configuration register.
1062 Writes Value to the bit field of the PCI configuration register. The bit
1063 field is specified by the StartBit and the EndBit. All other bits in the
1064 destination PCI configuration register are preserved. The new value of the
1065 32-bit register is returned.
1067 If Address > 0x0FFFFFFF, then ASSERT().
1068 If Address is not aligned on a 32-bit boundary, then ASSERT().
1069 If StartBit is greater than 31, then ASSERT().
1070 If EndBit is greater than 31, then ASSERT().
1071 If EndBit is less than StartBit, then ASSERT().
1072 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1074 @param Address The PCI configuration register to write.
1075 @param StartBit The ordinal of the least significant bit in the bit field.
1077 @param EndBit The ordinal of the most significant bit in the bit field.
1079 @param Value The new value of the bit field.
1081 @return The value written back to the PCI configuration register.
1086 PciBitFieldWrite32 (
1095 BitFieldWrite32 (PciRead32 (Address
), StartBit
, EndBit
, Value
)
1100 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1101 writes the result back to the bit field in the 32-bit port.
1103 Reads the 32-bit PCI configuration register specified by Address, performs a
1104 bitwise OR between the read result and the value specified by
1105 OrData, and writes the result to the 32-bit PCI configuration register
1106 specified by Address. The value written to the PCI configuration register is
1107 returned. This function must guarantee that all PCI read and write operations
1108 are serialized. Extra left bits in OrData are stripped.
1110 If Address > 0x0FFFFFFF, then ASSERT().
1111 If Address is not aligned on a 32-bit boundary, then ASSERT().
1112 If StartBit is greater than 31, then ASSERT().
1113 If EndBit is greater than 31, then ASSERT().
1114 If EndBit is less than StartBit, then ASSERT().
1115 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1117 @param Address The PCI configuration register to write.
1118 @param StartBit The ordinal of the least significant bit in the bit field.
1120 @param EndBit The ordinal of the most significant bit in the bit field.
1122 @param OrData The value to OR with the PCI configuration register.
1124 @return The value written back to the PCI configuration register.
1138 BitFieldOr32 (PciRead32 (Address
), StartBit
, EndBit
, OrData
)
1143 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1144 AND, and writes the result back to the bit field in the 32-bit register.
1146 Reads the 32-bit PCI configuration register specified by Address, performs a
1147 bitwise AND between the read result and the value specified by AndData, and
1148 writes the result to the 32-bit PCI configuration register specified by
1149 Address. The value written to the PCI configuration register is returned.
1150 This function must guarantee that all PCI read and write operations are
1151 serialized. Extra left bits in AndData are stripped.
1153 If Address > 0x0FFFFFFF, then ASSERT().
1154 If Address is not aligned on a 32-bit boundary, then ASSERT().
1155 If StartBit is greater than 31, then ASSERT().
1156 If EndBit is greater than 31, then ASSERT().
1157 If EndBit is less than StartBit, then ASSERT().
1158 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1160 @param Address The PCI configuration register to write.
1161 @param StartBit The ordinal of the least significant bit in the bit field.
1163 @param EndBit The ordinal of the most significant bit in the bit field.
1165 @param AndData The value to AND with the PCI configuration register.
1167 @return The value written back to the PCI configuration register.
1181 BitFieldAnd32 (PciRead32 (Address
), StartBit
, EndBit
, AndData
)
1186 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1187 bitwise OR, and writes the result back to the bit field in the
1190 Reads the 32-bit PCI configuration register specified by Address, performs a
1191 bitwise AND followed by a bitwise OR between the read result and
1192 the value specified by AndData, and writes the result to the 32-bit PCI
1193 configuration register specified by Address. The value written to the PCI
1194 configuration register is returned. This function must guarantee that all PCI
1195 read and write operations are serialized. Extra left bits in both AndData and
1196 OrData are stripped.
1198 If Address > 0x0FFFFFFF, then ASSERT().
1199 If Address is not aligned on a 32-bit boundary, then ASSERT().
1200 If StartBit is greater than 31, then ASSERT().
1201 If EndBit is greater than 31, then ASSERT().
1202 If EndBit is less than StartBit, then ASSERT().
1203 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1204 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1206 @param Address The PCI configuration register to write.
1207 @param StartBit The ordinal of the least significant bit in the bit field.
1209 @param EndBit The ordinal of the most significant bit in the bit field.
1211 @param AndData The value to AND with the PCI configuration register.
1212 @param OrData The value to OR with the result of the AND operation.
1214 @return The value written back to the PCI configuration register.
1219 PciBitFieldAndThenOr32 (
1229 BitFieldAndThenOr32 (PciRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1234 Reads a range of PCI configuration registers into a caller supplied buffer.
1236 Reads the range of PCI configuration registers specified by StartAddress and
1237 Size into the buffer specified by Buffer. This function only allows the PCI
1238 configuration registers from a single PCI function to be read. Size is
1239 returned. When possible 32-bit PCI configuration read cycles are used to read
1240 from StartAddress to StartAddress + Size. Due to alignment restrictions, 8-bit
1241 and 16-bit PCI configuration read cycles may be used at the beginning and the
1244 If StartAddress > 0x0FFFFFFF, then ASSERT().
1245 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1246 If Size > 0 and Buffer is NULL, then ASSERT().
1248 @param StartAddress The starting address that encodes the PCI Bus, Device,
1249 Function and Register.
1250 @param Size The size in bytes of the transfer.
1251 @param Buffer The pointer to a buffer receiving the data read.
1259 IN UINTN StartAddress
,
1266 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1267 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1273 ASSERT (Buffer
!= NULL
);
1276 // Save Size for return
1280 if ((StartAddress
& BIT0
) != 0) {
1282 // Read a byte if StartAddress is byte aligned
1284 *(volatile UINT8
*)Buffer
= PciRead8 (StartAddress
);
1285 StartAddress
+= sizeof (UINT8
);
1286 Size
-= sizeof (UINT8
);
1287 Buffer
= (UINT8
*)Buffer
+ 1;
1290 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& BIT1
) != 0)) {
1292 // Read a word if StartAddress is word aligned
1294 WriteUnaligned16 (Buffer
, PciRead16 (StartAddress
));
1295 StartAddress
+= sizeof (UINT16
);
1296 Size
-= sizeof (UINT16
);
1297 Buffer
= (UINT16
*)Buffer
+ 1;
1300 while (Size
>= sizeof (UINT32
)) {
1302 // Read as many double words as possible
1304 WriteUnaligned32 (Buffer
, PciRead32 (StartAddress
));
1305 StartAddress
+= sizeof (UINT32
);
1306 Size
-= sizeof (UINT32
);
1307 Buffer
= (UINT32
*)Buffer
+ 1;
1310 if (Size
>= sizeof (UINT16
)) {
1312 // Read the last remaining word if exist
1314 WriteUnaligned16 (Buffer
, PciRead16 (StartAddress
));
1315 StartAddress
+= sizeof (UINT16
);
1316 Size
-= sizeof (UINT16
);
1317 Buffer
= (UINT16
*)Buffer
+ 1;
1320 if (Size
>= sizeof (UINT8
)) {
1322 // Read the last remaining byte if exist
1324 *(volatile UINT8
*)Buffer
= PciRead8 (StartAddress
);
1331 Copies the data in a caller supplied buffer to a specified range of PCI
1332 configuration space.
1334 Writes the range of PCI configuration registers specified by StartAddress and
1335 Size from the buffer specified by Buffer. This function only allows the PCI
1336 configuration registers from a single PCI function to be written. Size is
1337 returned. When possible 32-bit PCI configuration write cycles are used to
1338 write from StartAddress to StartAddress + Size. Due to alignment restrictions,
1339 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1340 and the end of the range.
1342 If StartAddress > 0x0FFFFFFF, then ASSERT().
1343 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1344 If Size > 0 and Buffer is NULL, then ASSERT().
1346 @param StartAddress The starting address that encodes the PCI Bus, Device,
1347 Function and Register.
1348 @param Size The size in bytes of the transfer.
1349 @param Buffer The pointer to a buffer containing the data to write.
1351 @return Size written to StartAddress.
1357 IN UINTN StartAddress
,
1364 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1365 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1371 ASSERT (Buffer
!= NULL
);
1374 // Save Size for return
1378 if ((StartAddress
& BIT0
) != 0) {
1380 // Write a byte if StartAddress is byte aligned
1382 PciWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1383 StartAddress
+= sizeof (UINT8
);
1384 Size
-= sizeof (UINT8
);
1385 Buffer
= (UINT8
*)Buffer
+ 1;
1388 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& BIT1
) != 0)) {
1390 // Write a word if StartAddress is word aligned
1392 PciWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1393 StartAddress
+= sizeof (UINT16
);
1394 Size
-= sizeof (UINT16
);
1395 Buffer
= (UINT16
*)Buffer
+ 1;
1398 while (Size
>= sizeof (UINT32
)) {
1400 // Write as many double words as possible
1402 PciWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1403 StartAddress
+= sizeof (UINT32
);
1404 Size
-= sizeof (UINT32
);
1405 Buffer
= (UINT32
*)Buffer
+ 1;
1408 if (Size
>= sizeof (UINT16
)) {
1410 // Write the last remaining word if exist
1412 PciWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1413 StartAddress
+= sizeof (UINT16
);
1414 Size
-= sizeof (UINT16
);
1415 Buffer
= (UINT16
*)Buffer
+ 1;
1418 if (Size
>= sizeof (UINT8
)) {
1420 // Write the last remaining byte if exist
1422 PciWrite8 (StartAddress
, *(UINT8
*)Buffer
);