2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.
4 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "PciSegmentLib.h"
12 // Global variable to record data of PCI Root Bridge I/O Protocol instances
14 PCI_ROOT_BRIDGE_DATA
*mPciRootBridgeData
= NULL
;
15 UINTN mNumberOfPciRootBridges
= 0;
18 The constructor function caches data of PCI Root Bridge I/O Protocol instances.
20 The constructor function locates PCI Root Bridge I/O protocol instances,
21 and caches the protocol instances, together with their segment numbers and bus ranges.
22 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
24 @param ImageHandle The firmware allocated handle for the EFI image.
25 @param SystemTable A pointer to the EFI System Table.
27 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
32 PciSegmentLibConstructor (
33 IN EFI_HANDLE ImageHandle
,
34 IN EFI_SYSTEM_TABLE
*SystemTable
40 EFI_HANDLE
*HandleBuffer
;
41 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
42 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
46 PciRootBridgeIo
= NULL
;
49 Status
= gBS
->LocateHandleBuffer (
51 &gEfiPciRootBridgeIoProtocolGuid
,
56 ASSERT_EFI_ERROR (Status
);
58 mNumberOfPciRootBridges
= HandleCount
;
60 mPciRootBridgeData
= AllocatePool (HandleCount
* sizeof (PCI_ROOT_BRIDGE_DATA
));
61 ASSERT (mPciRootBridgeData
!= NULL
);
64 // Traverse all PCI Root Bridge I/O Protocol instances, and record the protocol
65 // instances, together with their segment numbers and bus ranges.
67 for (Index
= 0; Index
< HandleCount
; Index
++) {
68 Status
= gBS
->HandleProtocol (
70 &gEfiPciRootBridgeIoProtocolGuid
,
71 (VOID
**)&PciRootBridgeIo
73 ASSERT_EFI_ERROR (Status
);
75 mPciRootBridgeData
[Index
].PciRootBridgeIo
= PciRootBridgeIo
;
76 mPciRootBridgeData
[Index
].SegmentNumber
= PciRootBridgeIo
->SegmentNumber
;
78 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**)&Descriptors
);
79 ASSERT_EFI_ERROR (Status
);
81 while (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
82 if (Descriptors
->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
83 mPciRootBridgeData
[Index
].MinBusNumber
= Descriptors
->AddrRangeMin
;
84 mPciRootBridgeData
[Index
].MaxBusNumber
= Descriptors
->AddrRangeMax
;
91 ASSERT (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
);
94 FreePool (HandleBuffer
);
100 The destructor function frees memory allocated by constructor.
102 The destructor function frees memory for data of protocol instances allocated by constructor.
103 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
105 @param ImageHandle The firmware allocated handle for the EFI image.
106 @param SystemTable A pointer to the EFI System Table.
108 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
113 PciSegmentLibDestructor (
114 IN EFI_HANDLE ImageHandle
,
115 IN EFI_SYSTEM_TABLE
*SystemTable
118 FreePool (mPciRootBridgeData
);
124 According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.
126 This internal function extracts segment number and bus number data from address, and
127 retrieves the corresponding PCI Root Bridge I/O Protocol instance.
129 @param Address The address that encodes the Segment, PCI Bus, Device, Function and
132 @return The address for PCI Root Bridge I/O Protocol.
135 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*
136 PciSegmentLibSearchForRootBridge (
141 UINT64 SegmentNumber
;
144 for (Index
= 0; Index
< mNumberOfPciRootBridges
; Index
++) {
146 // Matches segment number of address with the segment number of protocol instance.
148 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
149 if (SegmentNumber
== mPciRootBridgeData
[Index
].SegmentNumber
) {
151 // Matches the bus number of address with bus number range of protocol instance.
153 BusNumber
= BitFieldRead64 (Address
, 20, 27);
154 if ((BusNumber
>= mPciRootBridgeData
[Index
].MinBusNumber
) && (BusNumber
<= mPciRootBridgeData
[Index
].MaxBusNumber
)) {
155 return mPciRootBridgeData
[Index
].PciRootBridgeIo
;
164 Internal worker function to read a PCI configuration register.
166 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
167 It reads and returns the PCI configuration register specified by Address,
168 the width of data is specified by Width.
170 @param Address The address that encodes the PCI Bus, Device, Function and
172 @param Width Width of data to read
174 @return The value read from the PCI configuration register.
178 DxePciSegmentLibPciRootBridgeIoReadWorker (
180 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
184 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
186 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
187 ASSERT (PciRootBridgeIo
!= NULL
);
189 PciRootBridgeIo
->Pci
.Read (
192 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
201 Internal worker function to writes a PCI configuration register.
203 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
204 It writes the PCI configuration register specified by Address with the
205 value specified by Data. The width of data is specifed by Width.
208 @param Address The address that encodes the PCI Bus, Device, Function and
210 @param Width Width of data to write
211 @param Data The value to write.
213 @return The value written to the PCI configuration register.
217 DxePciSegmentLibPciRootBridgeIoWriteWorker (
219 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
223 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
225 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
226 ASSERT (PciRootBridgeIo
!= NULL
);
228 PciRootBridgeIo
->Pci
.Write (
231 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
240 Register a PCI device so PCI configuration registers may be accessed after
241 SetVirtualAddressMap().
243 If any reserved bits in Address are set, then ASSERT().
245 @param Address Address that encodes the PCI Bus, Device, Function and
248 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
249 @retval RETURN_UNSUPPORTED An attempt was made to call this function
250 after ExitBootServices().
251 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
252 at runtime could not be mapped.
253 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
254 complete the registration.
259 PciSegmentRegisterForRuntimeAccess (
263 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
264 return RETURN_UNSUPPORTED
;
268 Reads an 8-bit PCI configuration register.
270 Reads and returns the 8-bit PCI configuration register specified by Address.
271 This function must guarantee that all PCI read and write operations are serialized.
273 If any reserved bits in Address are set, then ASSERT().
275 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
277 @return The 8-bit PCI configuration register specified by Address.
286 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
288 return (UINT8
)DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
292 Writes an 8-bit PCI configuration register.
294 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
295 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
297 If any reserved bits in Address are set, then ASSERT().
299 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
300 @param Value The value to write.
302 @return The value written to the PCI configuration register.
312 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
314 return (UINT8
)DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
318 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
320 Reads the 8-bit PCI configuration register specified by Address,
321 performs a bitwise OR between the read result and the value specified by OrData,
322 and writes the result to the 8-bit PCI configuration register specified by Address.
323 The value written to the PCI configuration register is returned.
324 This function must guarantee that all PCI read and write operations are serialized.
326 If any reserved bits in Address are set, then ASSERT().
328 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
329 @param OrData The value to OR with the PCI configuration register.
331 @return The value written to the PCI configuration register.
341 return PciSegmentWrite8 (Address
, (UINT8
)(PciSegmentRead8 (Address
) | OrData
));
345 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
347 Reads the 8-bit PCI configuration register specified by Address,
348 performs a bitwise AND between the read result and the value specified by AndData,
349 and writes the result to the 8-bit PCI configuration register specified by Address.
350 The value written to the PCI configuration register is returned.
351 This function must guarantee that all PCI read and write operations are serialized.
352 If any reserved bits in Address are set, then ASSERT().
354 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
355 @param AndData The value to AND with the PCI configuration register.
357 @return The value written to the PCI configuration register.
367 return PciSegmentWrite8 (Address
, (UINT8
)(PciSegmentRead8 (Address
) & AndData
));
371 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
372 followed a bitwise OR with another 8-bit value.
374 Reads the 8-bit PCI configuration register specified by Address,
375 performs a bitwise AND between the read result and the value specified by AndData,
376 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
377 and writes the result to the 8-bit PCI configuration register specified by Address.
378 The value written to the PCI configuration register is returned.
379 This function must guarantee that all PCI read and write operations are serialized.
381 If any reserved bits in Address are set, then ASSERT().
383 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
384 @param AndData The value to AND with the PCI configuration register.
385 @param OrData The value to OR with the PCI configuration register.
387 @return The value written to the PCI configuration register.
392 PciSegmentAndThenOr8 (
398 return PciSegmentWrite8 (Address
, (UINT8
)((PciSegmentRead8 (Address
) & AndData
) | OrData
));
402 Reads a bit field of a PCI configuration register.
404 Reads the bit field in an 8-bit PCI configuration register. The bit field is
405 specified by the StartBit and the EndBit. The value of the bit field is
408 If any reserved bits in Address are set, then ASSERT().
409 If StartBit is greater than 7, then ASSERT().
410 If EndBit is greater than 7, then ASSERT().
411 If EndBit is less than StartBit, then ASSERT().
413 @param Address PCI configuration register to read.
414 @param StartBit The ordinal of the least significant bit in the bit field.
416 @param EndBit The ordinal of the most significant bit in the bit field.
419 @return The value of the bit field read from the PCI configuration register.
424 PciSegmentBitFieldRead8 (
430 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
434 Writes a bit field to a PCI configuration register.
436 Writes Value to the bit field of the PCI configuration register. The bit
437 field is specified by the StartBit and the EndBit. All other bits in the
438 destination PCI configuration register are preserved. The new value of the
439 8-bit register is returned.
441 If any reserved bits in Address are set, then ASSERT().
442 If StartBit is greater than 7, then ASSERT().
443 If EndBit is greater than 7, then ASSERT().
444 If EndBit is less than StartBit, then ASSERT().
445 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
447 @param Address PCI configuration register to write.
448 @param StartBit The ordinal of the least significant bit in the bit field.
450 @param EndBit The ordinal of the most significant bit in the bit field.
452 @param Value New value of the bit field.
454 @return The value written back to the PCI configuration register.
459 PciSegmentBitFieldWrite8 (
466 return PciSegmentWrite8 (
468 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
473 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
474 writes the result back to the bit field in the 8-bit port.
476 Reads the 8-bit PCI configuration register specified by Address, performs a
477 bitwise OR between the read result and the value specified by
478 OrData, and writes the result to the 8-bit PCI configuration register
479 specified by Address. The value written to the PCI configuration register is
480 returned. This function must guarantee that all PCI read and write operations
481 are serialized. Extra left bits in OrData are stripped.
483 If any reserved bits in Address are set, then ASSERT().
484 If StartBit is greater than 7, then ASSERT().
485 If EndBit is greater than 7, then ASSERT().
486 If EndBit is less than StartBit, then ASSERT().
487 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
489 @param Address PCI configuration register to write.
490 @param StartBit The ordinal of the least significant bit in the bit field.
492 @param EndBit The ordinal of the most significant bit in the bit field.
494 @param OrData The value to OR with the PCI configuration register.
496 @return The value written back to the PCI configuration register.
501 PciSegmentBitFieldOr8 (
508 return PciSegmentWrite8 (
510 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
515 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
516 AND, and writes the result back to the bit field in the 8-bit register.
518 Reads the 8-bit PCI configuration register specified by Address, performs a
519 bitwise AND between the read result and the value specified by AndData, and
520 writes the result to the 8-bit PCI configuration register specified by
521 Address. The value written to the PCI configuration register is returned.
522 This function must guarantee that all PCI read and write operations are
523 serialized. Extra left bits in AndData are stripped.
525 If any reserved bits in Address are set, then ASSERT().
526 If StartBit is greater than 7, then ASSERT().
527 If EndBit is greater than 7, then ASSERT().
528 If EndBit is less than StartBit, then ASSERT().
529 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
531 @param Address PCI configuration register to write.
532 @param StartBit The ordinal of the least significant bit in the bit field.
534 @param EndBit The ordinal of the most significant bit in the bit field.
536 @param AndData The value to AND with the PCI configuration register.
538 @return The value written back to the PCI configuration register.
543 PciSegmentBitFieldAnd8 (
550 return PciSegmentWrite8 (
552 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
557 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
558 bitwise OR, and writes the result back to the bit field in the 8-bit port.
560 Reads the 8-bit PCI configuration register specified by Address, performs a
561 bitwise AND followed by a bitwise OR between the read result and
562 the value specified by AndData, and writes the result to the 8-bit PCI
563 configuration register specified by Address. The value written to the PCI
564 configuration register is returned. This function must guarantee that all PCI
565 read and write operations are serialized. Extra left bits in both AndData and
568 If any reserved bits in Address are set, then ASSERT().
569 If StartBit is greater than 7, then ASSERT().
570 If EndBit is greater than 7, then ASSERT().
571 If EndBit is less than StartBit, then ASSERT().
572 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
573 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
575 @param Address PCI configuration register to write.
576 @param StartBit The ordinal of the least significant bit in the bit field.
578 @param EndBit The ordinal of the most significant bit in the bit field.
580 @param AndData The value to AND with the PCI configuration register.
581 @param OrData The value to OR with the result of the AND operation.
583 @return The value written back to the PCI configuration register.
588 PciSegmentBitFieldAndThenOr8 (
596 return PciSegmentWrite8 (
598 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
603 Reads a 16-bit PCI configuration register.
605 Reads and returns the 16-bit PCI configuration register specified by Address.
606 This function must guarantee that all PCI read and write operations are serialized.
608 If any reserved bits in Address are set, then ASSERT().
609 If Address is not aligned on a 16-bit boundary, then ASSERT().
611 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
613 @return The 16-bit PCI configuration register specified by Address.
622 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
624 return (UINT16
)DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
628 Writes a 16-bit PCI configuration register.
630 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
631 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
633 If any reserved bits in Address are set, then ASSERT().
634 If Address is not aligned on a 16-bit boundary, then ASSERT().
636 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
637 @param Value The value to write.
639 @return The parameter of Value.
649 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
651 return (UINT16
)DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
655 Performs a bitwise OR of a 16-bit PCI configuration register with
658 Reads the 16-bit PCI configuration register specified by Address, performs a
659 bitwise OR between the read result and the value specified by OrData, and
660 writes the result to the 16-bit PCI configuration register specified by Address.
661 The value written to the PCI configuration register is returned. This function
662 must guarantee that all PCI read and write operations are serialized.
664 If any reserved bits in Address are set, then ASSERT().
665 If Address is not aligned on a 16-bit boundary, then ASSERT().
667 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
669 @param OrData The value to OR with the PCI configuration register.
671 @return The value written back to the PCI configuration register.
681 return PciSegmentWrite16 (Address
, (UINT16
)(PciSegmentRead16 (Address
) | OrData
));
685 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
687 Reads the 16-bit PCI configuration register specified by Address,
688 performs a bitwise AND between the read result and the value specified by AndData,
689 and writes the result to the 16-bit PCI configuration register specified by Address.
690 The value written to the PCI configuration register is returned.
691 This function must guarantee that all PCI read and write operations are serialized.
693 If any reserved bits in Address are set, then ASSERT().
694 If Address is not aligned on a 16-bit boundary, then ASSERT().
696 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
697 @param AndData The value to AND with the PCI configuration register.
699 @return The value written to the PCI configuration register.
709 return PciSegmentWrite16 (Address
, (UINT16
)(PciSegmentRead16 (Address
) & AndData
));
713 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
714 followed a bitwise OR with another 16-bit value.
716 Reads the 16-bit PCI configuration register specified by Address,
717 performs a bitwise AND between the read result and the value specified by AndData,
718 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
719 and writes the result to the 16-bit PCI configuration register specified by Address.
720 The value written to the PCI configuration register is returned.
721 This function must guarantee that all PCI read and write operations are serialized.
723 If any reserved bits in Address are set, then ASSERT().
724 If Address is not aligned on a 16-bit boundary, then ASSERT().
726 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
727 @param AndData The value to AND with the PCI configuration register.
728 @param OrData The value to OR with the PCI configuration register.
730 @return The value written to the PCI configuration register.
735 PciSegmentAndThenOr16 (
741 return PciSegmentWrite16 (Address
, (UINT16
)((PciSegmentRead16 (Address
) & AndData
) | OrData
));
745 Reads a bit field of a PCI configuration register.
747 Reads the bit field in a 16-bit PCI configuration register. The bit field is
748 specified by the StartBit and the EndBit. The value of the bit field is
751 If any reserved bits in Address are set, 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().
757 @param Address PCI configuration register to read.
758 @param StartBit The ordinal of the least significant bit in the bit field.
760 @param EndBit The ordinal of the most significant bit in the bit field.
763 @return The value of the bit field read from the PCI configuration register.
768 PciSegmentBitFieldRead16 (
774 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
778 Writes a bit field to a PCI configuration register.
780 Writes Value to the bit field of the PCI configuration register. The bit
781 field is specified by the StartBit and the EndBit. All other bits in the
782 destination PCI configuration register are preserved. The new value of the
783 16-bit register is returned.
785 If any reserved bits in Address are set, then ASSERT().
786 If Address is not aligned on a 16-bit boundary, then ASSERT().
787 If StartBit is greater than 15, then ASSERT().
788 If EndBit is greater than 15, then ASSERT().
789 If EndBit is less than StartBit, then ASSERT().
790 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
792 @param Address PCI configuration register to write.
793 @param StartBit The ordinal of the least significant bit in the bit field.
795 @param EndBit The ordinal of the most significant bit in the bit field.
797 @param Value New value of the bit field.
799 @return The value written back to the PCI configuration register.
804 PciSegmentBitFieldWrite16 (
811 return PciSegmentWrite16 (
813 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
818 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, writes
819 the result back to the bit field in the 16-bit port.
821 Reads the 16-bit PCI configuration register specified by Address, performs a
822 bitwise OR between the read result and the value specified by
823 OrData, and writes the result to the 16-bit PCI configuration register
824 specified by Address. The value written to the PCI configuration register is
825 returned. This function must guarantee that all PCI read and write operations
826 are serialized. Extra left bits in OrData are stripped.
828 If any reserved bits in Address are set, then ASSERT().
829 If Address is not aligned on a 16-bit boundary, then ASSERT().
830 If StartBit is greater than 15, then ASSERT().
831 If EndBit is greater than 15, then ASSERT().
832 If EndBit is less than StartBit, then ASSERT().
833 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
835 @param Address PCI configuration register to write.
836 @param StartBit The ordinal of the least significant bit in the bit field.
838 @param EndBit The ordinal of the most significant bit in the bit field.
840 @param OrData The value to OR with the PCI configuration register.
842 @return The value written back to the PCI configuration register.
847 PciSegmentBitFieldOr16 (
854 return PciSegmentWrite16 (
856 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
861 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
862 AND, writes the result back to the bit field in the 16-bit register.
864 Reads the 16-bit PCI configuration register specified by Address, performs a
865 bitwise AND between the read result and the value specified by AndData, and
866 writes the result to the 16-bit PCI configuration register specified by
867 Address. The value written to the PCI configuration register is returned.
868 This function must guarantee that all PCI read and write operations are
869 serialized. Extra left bits in AndData are stripped.
871 If any reserved bits in Address are set, then ASSERT().
872 If Address is not aligned on a 16-bit boundary, then ASSERT().
873 If StartBit is greater than 15, then ASSERT().
874 If EndBit is greater than 15, then ASSERT().
875 If EndBit is less than StartBit, then ASSERT().
876 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
878 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
879 @param StartBit The ordinal of the least significant bit in the bit field.
881 @param EndBit The ordinal of the most significant bit in the bit field.
883 @param AndData The value to AND with the PCI configuration register.
885 @return The value written back to the PCI configuration register.
890 PciSegmentBitFieldAnd16 (
897 return PciSegmentWrite16 (
899 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
904 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
905 bitwise OR, and writes the result back to the bit field in the
908 Reads the 16-bit PCI configuration register specified by Address, performs a
909 bitwise AND followed by a bitwise OR between the read result and
910 the value specified by AndData, and writes the result to the 16-bit PCI
911 configuration register specified by Address. The value written to the PCI
912 configuration register is returned. This function must guarantee that all PCI
913 read and write operations are serialized. Extra left bits in both AndData and
916 If any reserved bits in Address are set, then ASSERT().
917 If StartBit is greater than 15, then ASSERT().
918 If EndBit is greater than 15, then ASSERT().
919 If EndBit is less than StartBit, then ASSERT().
920 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
921 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
923 @param Address PCI configuration register to write.
924 @param StartBit The ordinal of the least significant bit in the bit field.
926 @param EndBit The ordinal of the most significant bit in the bit field.
928 @param AndData The value to AND with the PCI configuration register.
929 @param OrData The value to OR with the result of the AND operation.
931 @return The value written back to the PCI configuration register.
936 PciSegmentBitFieldAndThenOr16 (
944 return PciSegmentWrite16 (
946 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
951 Reads a 32-bit PCI configuration register.
953 Reads and returns the 32-bit PCI configuration register specified by Address.
954 This function must guarantee that all PCI read and write operations are serialized.
956 If any reserved bits in Address are set, then ASSERT().
957 If Address is not aligned on a 32-bit boundary, then ASSERT().
959 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
961 @return The 32-bit PCI configuration register specified by Address.
970 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
972 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
976 Writes a 32-bit PCI configuration register.
978 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
979 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
981 If any reserved bits in Address are set, then ASSERT().
982 If Address is not aligned on a 32-bit boundary, then ASSERT().
984 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
985 @param Value The value to write.
987 @return The parameter of Value.
997 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
999 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
1003 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
1005 Reads the 32-bit PCI configuration register specified by Address,
1006 performs a bitwise OR between the read result and the value specified by OrData,
1007 and writes the result to the 32-bit PCI configuration register specified by Address.
1008 The value written to the PCI configuration register is returned.
1009 This function must guarantee that all PCI read and write operations are serialized.
1011 If any reserved bits in Address are set, then ASSERT().
1012 If Address is not aligned on a 32-bit boundary, then ASSERT().
1014 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1015 @param OrData The value to OR with the PCI configuration register.
1017 @return The value written to the PCI configuration register.
1027 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1031 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
1033 Reads the 32-bit PCI configuration register specified by Address,
1034 performs a bitwise AND between the read result and the value specified by AndData,
1035 and writes the result to the 32-bit PCI configuration register specified by Address.
1036 The value written to the PCI configuration register is returned.
1037 This function must guarantee that all PCI read and write operations are serialized.
1039 If any reserved bits in Address are set, then ASSERT().
1040 If Address is not aligned on a 32-bit boundary, then ASSERT().
1042 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1043 @param AndData The value to AND with the PCI configuration register.
1045 @return The value written to the PCI configuration register.
1055 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1059 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
1060 followed a bitwise OR with another 32-bit value.
1062 Reads the 32-bit PCI configuration register specified by Address,
1063 performs a bitwise AND between the read result and the value specified by AndData,
1064 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
1065 and writes the result to the 32-bit PCI configuration register specified by Address.
1066 The value written to the PCI configuration register is returned.
1067 This function must guarantee that all PCI read and write operations are serialized.
1069 If any reserved bits in Address are set, then ASSERT().
1070 If Address is not aligned on a 32-bit boundary, then ASSERT().
1072 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1073 @param AndData The value to AND with the PCI configuration register.
1074 @param OrData The value to OR with the PCI configuration register.
1076 @return The value written to the PCI configuration register.
1081 PciSegmentAndThenOr32 (
1087 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1091 Reads a bit field of a PCI configuration register.
1093 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1094 specified by the StartBit and the EndBit. The value of the bit field is
1097 If any reserved bits in Address are set, then ASSERT().
1098 If Address is not aligned on a 32-bit boundary, then ASSERT().
1099 If StartBit is greater than 31, then ASSERT().
1100 If EndBit is greater than 31, then ASSERT().
1101 If EndBit is less than StartBit, then ASSERT().
1103 @param Address PCI configuration register to read.
1104 @param StartBit The ordinal of the least significant bit in the bit field.
1106 @param EndBit The ordinal of the most significant bit in the bit field.
1109 @return The value of the bit field read from the PCI configuration register.
1114 PciSegmentBitFieldRead32 (
1120 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1124 Writes a bit field to a PCI configuration register.
1126 Writes Value to the bit field of the PCI configuration register. The bit
1127 field is specified by the StartBit and the EndBit. All other bits in the
1128 destination PCI configuration register are preserved. The new value of the
1129 32-bit register is returned.
1131 If any reserved bits in Address are set, then ASSERT().
1132 If Address is not aligned on a 32-bit boundary, then ASSERT().
1133 If StartBit is greater than 31, then ASSERT().
1134 If EndBit is greater than 31, then ASSERT().
1135 If EndBit is less than StartBit, then ASSERT().
1136 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1138 @param Address PCI configuration register to write.
1139 @param StartBit The ordinal of the least significant bit in the bit field.
1141 @param EndBit The ordinal of the most significant bit in the bit field.
1143 @param Value New value of the bit field.
1145 @return The value written back to the PCI configuration register.
1150 PciSegmentBitFieldWrite32 (
1157 return PciSegmentWrite32 (
1159 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1164 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1165 writes the result back to the bit field in the 32-bit port.
1167 Reads the 32-bit PCI configuration register specified by Address, performs a
1168 bitwise OR between the read result and the value specified by
1169 OrData, and writes the result to the 32-bit PCI configuration register
1170 specified by Address. The value written to the PCI configuration register is
1171 returned. This function must guarantee that all PCI read and write operations
1172 are serialized. Extra left bits in OrData are stripped.
1174 If any reserved bits in Address are set, then ASSERT().
1175 If StartBit is greater than 31, then ASSERT().
1176 If EndBit is greater than 31, then ASSERT().
1177 If EndBit is less than StartBit, then ASSERT().
1178 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1180 @param Address PCI configuration register to write.
1181 @param StartBit The ordinal of the least significant bit in the bit field.
1183 @param EndBit The ordinal of the most significant bit in the bit field.
1185 @param OrData The value to OR with the PCI configuration register.
1187 @return The value written back to the PCI configuration register.
1192 PciSegmentBitFieldOr32 (
1199 return PciSegmentWrite32 (
1201 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1206 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1207 AND, and writes the result back to the bit field in the 32-bit register.
1210 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1211 AND between the read result and the value specified by AndData, and writes the result
1212 to the 32-bit PCI configuration register specified by Address. The value written to
1213 the PCI configuration register is returned. This function must guarantee that all PCI
1214 read and write operations are serialized. Extra left bits in AndData are stripped.
1215 If any reserved bits in Address are set, then ASSERT().
1216 If Address is not aligned on a 32-bit boundary, then ASSERT().
1217 If StartBit is greater than 31, then ASSERT().
1218 If EndBit is greater than 31, then ASSERT().
1219 If EndBit is less than StartBit, then ASSERT().
1220 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1222 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1223 @param StartBit The ordinal of the least significant bit in the bit field.
1225 @param EndBit The ordinal of the most significant bit in the bit field.
1227 @param AndData The value to AND with the PCI configuration register.
1229 @return The value written back to the PCI configuration register.
1234 PciSegmentBitFieldAnd32 (
1241 return PciSegmentWrite32 (
1243 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1248 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1249 bitwise OR, and writes the result back to the bit field in the
1252 Reads the 32-bit PCI configuration register specified by Address, performs a
1253 bitwise AND followed by a bitwise OR between the read result and
1254 the value specified by AndData, and writes the result to the 32-bit PCI
1255 configuration register specified by Address. The value written to the PCI
1256 configuration register is returned. This function must guarantee that all PCI
1257 read and write operations are serialized. Extra left bits in both AndData and
1258 OrData are stripped.
1260 If any reserved bits in Address are set, then ASSERT().
1261 If StartBit is greater than 31, then ASSERT().
1262 If EndBit is greater than 31, then ASSERT().
1263 If EndBit is less than StartBit, then ASSERT().
1264 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1265 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1267 @param Address PCI configuration register to write.
1268 @param StartBit The ordinal of the least significant bit in the bit field.
1270 @param EndBit The ordinal of the most significant bit in the bit field.
1272 @param AndData The value to AND with the PCI configuration register.
1273 @param OrData The value to OR with the result of the AND operation.
1275 @return The value written back to the PCI configuration register.
1280 PciSegmentBitFieldAndThenOr32 (
1288 return PciSegmentWrite32 (
1290 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1295 Reads a range of PCI configuration registers into a caller supplied buffer.
1297 Reads the range of PCI configuration registers specified by StartAddress and
1298 Size into the buffer specified by Buffer. This function only allows the PCI
1299 configuration registers from a single PCI function to be read. Size is
1300 returned. When possible 32-bit PCI configuration read cycles are used to read
1301 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1302 and 16-bit PCI configuration read cycles may be used at the beginning and the
1305 If any reserved bits in StartAddress are set, then ASSERT().
1306 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1307 If Size > 0 and Buffer is NULL, then ASSERT().
1309 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1310 Function and Register.
1311 @param Size Size in bytes of the transfer.
1312 @param Buffer Pointer to a buffer receiving the data read.
1319 PciSegmentReadBuffer (
1320 IN UINT64 StartAddress
,
1327 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1328 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1334 ASSERT (Buffer
!= NULL
);
1337 // Save Size for return
1341 if ((StartAddress
& BIT0
) != 0) {
1343 // Read a byte if StartAddress is byte aligned
1345 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1346 StartAddress
+= sizeof (UINT8
);
1347 Size
-= sizeof (UINT8
);
1348 Buffer
= (UINT8
*)Buffer
+ 1;
1351 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& BIT1
) != 0)) {
1353 // Read a word if StartAddress is word aligned
1355 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1356 StartAddress
+= sizeof (UINT16
);
1357 Size
-= sizeof (UINT16
);
1358 Buffer
= (UINT16
*)Buffer
+ 1;
1361 while (Size
>= sizeof (UINT32
)) {
1363 // Read as many double words as possible
1365 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1366 StartAddress
+= sizeof (UINT32
);
1367 Size
-= sizeof (UINT32
);
1368 Buffer
= (UINT32
*)Buffer
+ 1;
1371 if (Size
>= sizeof (UINT16
)) {
1373 // Read the last remaining word if exist
1375 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1376 StartAddress
+= sizeof (UINT16
);
1377 Size
-= sizeof (UINT16
);
1378 Buffer
= (UINT16
*)Buffer
+ 1;
1381 if (Size
>= sizeof (UINT8
)) {
1383 // Read the last remaining byte if exist
1385 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1392 Copies the data in a caller supplied buffer to a specified range of PCI
1393 configuration space.
1395 Writes the range of PCI configuration registers specified by StartAddress and
1396 Size from the buffer specified by Buffer. This function only allows the PCI
1397 configuration registers from a single PCI function to be written. Size is
1398 returned. When possible 32-bit PCI configuration write cycles are used to
1399 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1400 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1401 and the end of the range.
1403 If any reserved bits in StartAddress are set, then ASSERT().
1404 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1405 If Size > 0 and Buffer is NULL, then ASSERT().
1407 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1408 Function and Register.
1409 @param Size Size in bytes of the transfer.
1410 @param Buffer Pointer to a buffer containing the data to write.
1412 @return The parameter of Size.
1417 PciSegmentWriteBuffer (
1418 IN UINT64 StartAddress
,
1425 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1426 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1432 ASSERT (Buffer
!= NULL
);
1435 // Save Size for return
1439 if ((StartAddress
& BIT0
) != 0) {
1441 // Write a byte if StartAddress is byte aligned
1443 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1444 StartAddress
+= sizeof (UINT8
);
1445 Size
-= sizeof (UINT8
);
1446 Buffer
= (UINT8
*)Buffer
+ 1;
1449 if ((Size
>= sizeof (UINT16
)) && ((StartAddress
& BIT1
) != 0)) {
1451 // Write a word if StartAddress is word aligned
1453 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1454 StartAddress
+= sizeof (UINT16
);
1455 Size
-= sizeof (UINT16
);
1456 Buffer
= (UINT16
*)Buffer
+ 1;
1459 while (Size
>= sizeof (UINT32
)) {
1461 // Write as many double words as possible
1463 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1464 StartAddress
+= sizeof (UINT32
);
1465 Size
-= sizeof (UINT32
);
1466 Buffer
= (UINT32
*)Buffer
+ 1;
1469 if (Size
>= sizeof (UINT16
)) {
1471 // Write the last remaining word if exist
1473 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1474 StartAddress
+= sizeof (UINT16
);
1475 Size
-= sizeof (UINT16
);
1476 Buffer
= (UINT16
*)Buffer
+ 1;
1479 if (Size
>= sizeof (UINT8
)) {
1481 // Write the last remaining byte if exist
1483 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);