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
;
89 ASSERT (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
);
92 FreePool(HandleBuffer
);
98 The destructor function frees memory allocated by constructor.
100 The destructor function frees memory for data of protocol instances allocated by constructor.
101 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
103 @param ImageHandle The firmware allocated handle for the EFI image.
104 @param SystemTable A pointer to the EFI System Table.
106 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
111 PciSegmentLibDestructor (
112 IN EFI_HANDLE ImageHandle
,
113 IN EFI_SYSTEM_TABLE
*SystemTable
116 FreePool (mPciRootBridgeData
);
122 According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.
124 This internal function extracts segment number and bus number data from address, and
125 retrieves the corresponding PCI Root Bridge I/O Protocol instance.
127 @param Address The address that encodes the Segment, PCI Bus, Device, Function and
130 @return The address for PCI Root Bridge I/O Protocol.
133 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*
134 PciSegmentLibSearchForRootBridge (
139 UINT64 SegmentNumber
;
142 for (Index
= 0; Index
< mNumberOfPciRootBridges
; Index
++) {
144 // Matches segment number of address with the segment number of protocol instance.
146 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
147 if (SegmentNumber
== mPciRootBridgeData
[Index
].SegmentNumber
) {
149 // Matches the bus number of address with bus number range of protocol instance.
151 BusNumber
= BitFieldRead64 (Address
, 20, 27);
152 if (BusNumber
>= mPciRootBridgeData
[Index
].MinBusNumber
&& BusNumber
<= mPciRootBridgeData
[Index
].MaxBusNumber
) {
153 return mPciRootBridgeData
[Index
].PciRootBridgeIo
;
161 Internal worker function to read a PCI configuration register.
163 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
164 It reads and returns the PCI configuration register specified by Address,
165 the width of data is specified by Width.
167 @param Address The address that encodes the PCI Bus, Device, Function and
169 @param Width Width of data to read
171 @return The value read from the PCI configuration register.
175 DxePciSegmentLibPciRootBridgeIoReadWorker (
177 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
181 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
183 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
184 ASSERT (PciRootBridgeIo
!= NULL
);
186 PciRootBridgeIo
->Pci
.Read (
189 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
198 Internal worker function to writes a PCI configuration register.
200 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
201 It writes the PCI configuration register specified by Address with the
202 value specified by Data. The width of data is specifed by Width.
205 @param Address The address that encodes the PCI Bus, Device, Function and
207 @param Width Width of data to write
208 @param Data The value to write.
210 @return The value written to the PCI configuration register.
214 DxePciSegmentLibPciRootBridgeIoWriteWorker (
216 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
220 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
222 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
223 ASSERT (PciRootBridgeIo
!= NULL
);
225 PciRootBridgeIo
->Pci
.Write (
228 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
237 Register a PCI device so PCI configuration registers may be accessed after
238 SetVirtualAddressMap().
240 If any reserved bits in Address are set, then ASSERT().
242 @param Address Address that encodes the PCI Bus, Device, Function and
245 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
246 @retval RETURN_UNSUPPORTED An attempt was made to call this function
247 after ExitBootServices().
248 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
249 at runtime could not be mapped.
250 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
251 complete the registration.
256 PciSegmentRegisterForRuntimeAccess (
260 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
261 return RETURN_UNSUPPORTED
;
265 Reads an 8-bit PCI configuration register.
267 Reads and returns the 8-bit PCI configuration register specified by Address.
268 This function must guarantee that all PCI read and write operations are serialized.
270 If any reserved bits in Address are set, then ASSERT().
272 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
274 @return The 8-bit PCI configuration register specified by Address.
283 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
285 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
289 Writes an 8-bit PCI configuration register.
291 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
292 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
294 If any reserved bits in Address are set, then ASSERT().
296 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
297 @param Value The value to write.
299 @return The value written to the PCI configuration register.
309 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
311 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
315 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
317 Reads the 8-bit PCI configuration register specified by Address,
318 performs a bitwise OR between the read result and the value specified by OrData,
319 and writes the result to the 8-bit PCI configuration register specified by Address.
320 The value written to the PCI configuration register is returned.
321 This function must guarantee that all PCI read and write operations are serialized.
323 If any reserved bits in Address are set, then ASSERT().
325 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
326 @param OrData The value to OR with the PCI configuration register.
328 @return The value written to the PCI configuration register.
338 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
342 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
344 Reads the 8-bit PCI configuration register specified by Address,
345 performs a bitwise AND between the read result and the value specified by AndData,
346 and writes the result to the 8-bit PCI configuration register specified by Address.
347 The value written to the PCI configuration register is returned.
348 This function must guarantee that all PCI read and write operations are serialized.
349 If any reserved bits in Address are set, then ASSERT().
351 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
352 @param AndData The value to AND with the PCI configuration register.
354 @return The value written to the PCI configuration register.
364 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
368 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
369 followed a bitwise OR with another 8-bit value.
371 Reads the 8-bit PCI configuration register specified by Address,
372 performs a bitwise AND between the read result and the value specified by AndData,
373 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
374 and writes the result to the 8-bit PCI configuration register specified by Address.
375 The value written to the PCI configuration register is returned.
376 This function must guarantee that all PCI read and write operations are serialized.
378 If any reserved bits in Address are set, then ASSERT().
380 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
381 @param AndData The value to AND with the PCI configuration register.
382 @param OrData The value to OR with the PCI configuration register.
384 @return The value written to the PCI configuration register.
389 PciSegmentAndThenOr8 (
395 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
399 Reads a bit field of a PCI configuration register.
401 Reads the bit field in an 8-bit PCI configuration register. The bit field is
402 specified by the StartBit and the EndBit. The value of the bit field is
405 If any reserved bits in Address are set, then ASSERT().
406 If StartBit is greater than 7, then ASSERT().
407 If EndBit is greater than 7, then ASSERT().
408 If EndBit is less than StartBit, then ASSERT().
410 @param Address PCI configuration register to read.
411 @param StartBit The ordinal of the least significant bit in the bit field.
413 @param EndBit The ordinal of the most significant bit in the bit field.
416 @return The value of the bit field read from the PCI configuration register.
421 PciSegmentBitFieldRead8 (
427 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
431 Writes a bit field to a PCI configuration register.
433 Writes Value to the bit field of the PCI configuration register. The bit
434 field is specified by the StartBit and the EndBit. All other bits in the
435 destination PCI configuration register are preserved. The new value of the
436 8-bit register is returned.
438 If any reserved bits in Address are set, then ASSERT().
439 If StartBit is greater than 7, then ASSERT().
440 If EndBit is greater than 7, then ASSERT().
441 If EndBit is less than StartBit, then ASSERT().
442 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
444 @param Address PCI configuration register to write.
445 @param StartBit The ordinal of the least significant bit in the bit field.
447 @param EndBit The ordinal of the most significant bit in the bit field.
449 @param Value New value of the bit field.
451 @return The value written back to the PCI configuration register.
456 PciSegmentBitFieldWrite8 (
463 return PciSegmentWrite8 (
465 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
470 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
471 writes the result back to the bit field in the 8-bit port.
473 Reads the 8-bit PCI configuration register specified by Address, performs a
474 bitwise OR between the read result and the value specified by
475 OrData, and writes the result to the 8-bit PCI configuration register
476 specified by Address. The value written to the PCI configuration register is
477 returned. This function must guarantee that all PCI read and write operations
478 are serialized. Extra left bits in OrData are stripped.
480 If any reserved bits in Address are set, then ASSERT().
481 If StartBit is greater than 7, then ASSERT().
482 If EndBit is greater than 7, then ASSERT().
483 If EndBit is less than StartBit, then ASSERT().
484 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
486 @param Address PCI configuration register to write.
487 @param StartBit The ordinal of the least significant bit in the bit field.
489 @param EndBit The ordinal of the most significant bit in the bit field.
491 @param OrData The value to OR with the PCI configuration register.
493 @return The value written back to the PCI configuration register.
498 PciSegmentBitFieldOr8 (
505 return PciSegmentWrite8 (
507 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
512 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
513 AND, and writes the result back to the bit field in the 8-bit register.
515 Reads the 8-bit PCI configuration register specified by Address, performs a
516 bitwise AND between the read result and the value specified by AndData, and
517 writes the result to the 8-bit PCI configuration register specified by
518 Address. The value written to the PCI configuration register is returned.
519 This function must guarantee that all PCI read and write operations are
520 serialized. Extra left bits in AndData are stripped.
522 If any reserved bits in Address are set, then ASSERT().
523 If StartBit is greater than 7, then ASSERT().
524 If EndBit is greater than 7, then ASSERT().
525 If EndBit is less than StartBit, then ASSERT().
526 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
528 @param Address PCI configuration register to write.
529 @param StartBit The ordinal of the least significant bit in the bit field.
531 @param EndBit The ordinal of the most significant bit in the bit field.
533 @param AndData The value to AND with the PCI configuration register.
535 @return The value written back to the PCI configuration register.
540 PciSegmentBitFieldAnd8 (
547 return PciSegmentWrite8 (
549 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
554 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
555 bitwise OR, and writes the result back to the bit field in the 8-bit port.
557 Reads the 8-bit PCI configuration register specified by Address, performs a
558 bitwise AND followed by a bitwise OR between the read result and
559 the value specified by AndData, and writes the result to the 8-bit PCI
560 configuration register specified by Address. The value written to the PCI
561 configuration register is returned. This function must guarantee that all PCI
562 read and write operations are serialized. Extra left bits in both AndData and
565 If any reserved bits in Address are set, then ASSERT().
566 If StartBit is greater than 7, then ASSERT().
567 If EndBit is greater than 7, then ASSERT().
568 If EndBit is less than StartBit, then ASSERT().
569 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
570 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
572 @param Address PCI configuration register to write.
573 @param StartBit The ordinal of the least significant bit in the bit field.
575 @param EndBit The ordinal of the most significant bit in the bit field.
577 @param AndData The value to AND with the PCI configuration register.
578 @param OrData The value to OR with the result of the AND operation.
580 @return The value written back to the PCI configuration register.
585 PciSegmentBitFieldAndThenOr8 (
593 return PciSegmentWrite8 (
595 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
600 Reads a 16-bit PCI configuration register.
602 Reads and returns the 16-bit PCI configuration register specified by Address.
603 This function must guarantee that all PCI read and write operations are serialized.
605 If any reserved bits in Address are set, then ASSERT().
606 If Address is not aligned on a 16-bit boundary, then ASSERT().
608 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
610 @return The 16-bit PCI configuration register specified by Address.
619 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
621 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
625 Writes a 16-bit PCI configuration register.
627 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
628 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
630 If any reserved bits in Address are set, then ASSERT().
631 If Address is not aligned on a 16-bit boundary, then ASSERT().
633 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
634 @param Value The value to write.
636 @return The parameter of Value.
646 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
648 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
652 Performs a bitwise OR of a 16-bit PCI configuration register with
655 Reads the 16-bit PCI configuration register specified by Address, performs a
656 bitwise OR between the read result and the value specified by OrData, and
657 writes the result to the 16-bit PCI configuration register specified by Address.
658 The value written to the PCI configuration register is returned. This function
659 must guarantee that all PCI read and write operations are serialized.
661 If any reserved bits in Address are set, then ASSERT().
662 If Address is not aligned on a 16-bit boundary, then ASSERT().
664 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
666 @param OrData The value to OR with the PCI configuration register.
668 @return The value written back to the PCI configuration register.
678 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
682 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
684 Reads the 16-bit PCI configuration register specified by Address,
685 performs a bitwise AND between the read result and the value specified by AndData,
686 and writes the result to the 16-bit PCI configuration register specified by Address.
687 The value written to the PCI configuration register is returned.
688 This function must guarantee that all PCI read and write operations are serialized.
690 If any reserved bits in Address are set, then ASSERT().
691 If Address is not aligned on a 16-bit boundary, then ASSERT().
693 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
694 @param AndData The value to AND with the PCI configuration register.
696 @return The value written to the PCI configuration register.
706 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
710 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
711 followed a bitwise OR with another 16-bit value.
713 Reads the 16-bit PCI configuration register specified by Address,
714 performs a bitwise AND between the read result and the value specified by AndData,
715 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
716 and writes the result to the 16-bit PCI configuration register specified by Address.
717 The value written to the PCI configuration register is returned.
718 This function must guarantee that all PCI read and write operations are serialized.
720 If any reserved bits in Address are set, then ASSERT().
721 If Address is not aligned on a 16-bit boundary, then ASSERT().
723 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
724 @param AndData The value to AND with the PCI configuration register.
725 @param OrData The value to OR with the PCI configuration register.
727 @return The value written to the PCI configuration register.
732 PciSegmentAndThenOr16 (
738 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
742 Reads a bit field of a PCI configuration register.
744 Reads the bit field in a 16-bit PCI configuration register. The bit field is
745 specified by the StartBit and the EndBit. The value of the bit field is
748 If any reserved bits in Address are set, then ASSERT().
749 If Address is not aligned on a 16-bit boundary, then ASSERT().
750 If StartBit is greater than 15, then ASSERT().
751 If EndBit is greater than 15, then ASSERT().
752 If EndBit is less than StartBit, then ASSERT().
754 @param Address PCI configuration register to read.
755 @param StartBit The ordinal of the least significant bit in the bit field.
757 @param EndBit The ordinal of the most significant bit in the bit field.
760 @return The value of the bit field read from the PCI configuration register.
765 PciSegmentBitFieldRead16 (
771 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
775 Writes a bit field to a PCI configuration register.
777 Writes Value to the bit field of the PCI configuration register. The bit
778 field is specified by the StartBit and the EndBit. All other bits in the
779 destination PCI configuration register are preserved. The new value of the
780 16-bit register is returned.
782 If any reserved bits in Address are set, then ASSERT().
783 If Address is not aligned on a 16-bit boundary, then ASSERT().
784 If StartBit is greater than 15, then ASSERT().
785 If EndBit is greater than 15, then ASSERT().
786 If EndBit is less than StartBit, then ASSERT().
787 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
789 @param Address PCI configuration register to write.
790 @param StartBit The ordinal of the least significant bit in the bit field.
792 @param EndBit The ordinal of the most significant bit in the bit field.
794 @param Value New value of the bit field.
796 @return The value written back to the PCI configuration register.
801 PciSegmentBitFieldWrite16 (
808 return PciSegmentWrite16 (
810 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
815 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, writes
816 the result back to the bit field in the 16-bit port.
818 Reads the 16-bit PCI configuration register specified by Address, performs a
819 bitwise OR between the read result and the value specified by
820 OrData, and writes the result to the 16-bit PCI configuration register
821 specified by Address. The value written to the PCI configuration register is
822 returned. This function must guarantee that all PCI read and write operations
823 are serialized. Extra left bits in OrData are stripped.
825 If any reserved bits in Address are set, then ASSERT().
826 If Address is not aligned on a 16-bit boundary, then ASSERT().
827 If StartBit is greater than 15, then ASSERT().
828 If EndBit is greater than 15, then ASSERT().
829 If EndBit is less than StartBit, then ASSERT().
830 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
832 @param Address PCI configuration register to write.
833 @param StartBit The ordinal of the least significant bit in the bit field.
835 @param EndBit The ordinal of the most significant bit in the bit field.
837 @param OrData The value to OR with the PCI configuration register.
839 @return The value written back to the PCI configuration register.
844 PciSegmentBitFieldOr16 (
851 return PciSegmentWrite16 (
853 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
858 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
859 AND, writes the result back to the bit field in the 16-bit register.
861 Reads the 16-bit PCI configuration register specified by Address, performs a
862 bitwise AND between the read result and the value specified by AndData, and
863 writes the result to the 16-bit PCI configuration register specified by
864 Address. The value written to the PCI configuration register is returned.
865 This function must guarantee that all PCI read and write operations are
866 serialized. Extra left bits in AndData are stripped.
868 If any reserved bits in Address are set, then ASSERT().
869 If Address is not aligned on a 16-bit boundary, then ASSERT().
870 If StartBit is greater than 15, then ASSERT().
871 If EndBit is greater than 15, then ASSERT().
872 If EndBit is less than StartBit, then ASSERT().
873 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
875 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
876 @param StartBit The ordinal of the least significant bit in the bit field.
878 @param EndBit The ordinal of the most significant bit in the bit field.
880 @param AndData The value to AND with the PCI configuration register.
882 @return The value written back to the PCI configuration register.
887 PciSegmentBitFieldAnd16 (
894 return PciSegmentWrite16 (
896 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
901 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
902 bitwise OR, and writes the result back to the bit field in the
905 Reads the 16-bit PCI configuration register specified by Address, performs a
906 bitwise AND followed by a bitwise OR between the read result and
907 the value specified by AndData, and writes the result to the 16-bit PCI
908 configuration register specified by Address. The value written to the PCI
909 configuration register is returned. This function must guarantee that all PCI
910 read and write operations are serialized. Extra left bits in both AndData and
913 If any reserved bits in Address are set, then ASSERT().
914 If StartBit is greater than 15, then ASSERT().
915 If EndBit is greater than 15, then ASSERT().
916 If EndBit is less than StartBit, then ASSERT().
917 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
918 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
920 @param Address PCI configuration register to write.
921 @param StartBit The ordinal of the least significant bit in the bit field.
923 @param EndBit The ordinal of the most significant bit in the bit field.
925 @param AndData The value to AND with the PCI configuration register.
926 @param OrData The value to OR with the result of the AND operation.
928 @return The value written back to the PCI configuration register.
933 PciSegmentBitFieldAndThenOr16 (
941 return PciSegmentWrite16 (
943 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
948 Reads a 32-bit PCI configuration register.
950 Reads and returns the 32-bit PCI configuration register specified by Address.
951 This function must guarantee that all PCI read and write operations are serialized.
953 If any reserved bits in Address are set, then ASSERT().
954 If Address is not aligned on a 32-bit boundary, then ASSERT().
956 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
958 @return The 32-bit PCI configuration register specified by Address.
967 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
969 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
973 Writes a 32-bit PCI configuration register.
975 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
976 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
978 If any reserved bits in Address are set, then ASSERT().
979 If Address is not aligned on a 32-bit boundary, then ASSERT().
981 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
982 @param Value The value to write.
984 @return The parameter of Value.
994 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
996 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
1000 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
1002 Reads the 32-bit PCI configuration register specified by Address,
1003 performs a bitwise OR between the read result and the value specified by OrData,
1004 and writes the result to the 32-bit PCI configuration register specified by Address.
1005 The value written to the PCI configuration register is returned.
1006 This function must guarantee that all PCI read and write operations are serialized.
1008 If any reserved bits in Address are set, then ASSERT().
1009 If Address is not aligned on a 32-bit boundary, then ASSERT().
1011 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1012 @param OrData The value to OR with the PCI configuration register.
1014 @return The value written to the PCI configuration register.
1024 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1028 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
1030 Reads the 32-bit PCI configuration register specified by Address,
1031 performs a bitwise AND between the read result and the value specified by AndData,
1032 and writes the result to the 32-bit PCI configuration register specified by Address.
1033 The value written to the PCI configuration register is returned.
1034 This function must guarantee that all PCI read and write operations are serialized.
1036 If any reserved bits in Address are set, then ASSERT().
1037 If Address is not aligned on a 32-bit boundary, then ASSERT().
1039 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1040 @param AndData The value to AND with the PCI configuration register.
1042 @return The value written to the PCI configuration register.
1052 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1056 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
1057 followed a bitwise OR with another 32-bit value.
1059 Reads the 32-bit PCI configuration register specified by Address,
1060 performs a bitwise AND between the read result and the value specified by AndData,
1061 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
1062 and writes the result to the 32-bit PCI configuration register specified by Address.
1063 The value written to the PCI configuration register is returned.
1064 This function must guarantee that all PCI read and write operations are serialized.
1066 If any reserved bits in Address are set, then ASSERT().
1067 If Address is not aligned on a 32-bit boundary, then ASSERT().
1069 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1070 @param AndData The value to AND with the PCI configuration register.
1071 @param OrData The value to OR with the PCI configuration register.
1073 @return The value written to the PCI configuration register.
1078 PciSegmentAndThenOr32 (
1084 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1088 Reads a bit field of a PCI configuration register.
1090 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1091 specified by the StartBit and the EndBit. The value of the bit field is
1094 If any reserved bits in Address are set, then ASSERT().
1095 If Address is not aligned on a 32-bit boundary, then ASSERT().
1096 If StartBit is greater than 31, then ASSERT().
1097 If EndBit is greater than 31, then ASSERT().
1098 If EndBit is less than StartBit, then ASSERT().
1100 @param Address PCI configuration register to read.
1101 @param StartBit The ordinal of the least significant bit in the bit field.
1103 @param EndBit The ordinal of the most significant bit in the bit field.
1106 @return The value of the bit field read from the PCI configuration register.
1111 PciSegmentBitFieldRead32 (
1117 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1121 Writes a bit field to a PCI configuration register.
1123 Writes Value to the bit field of the PCI configuration register. The bit
1124 field is specified by the StartBit and the EndBit. All other bits in the
1125 destination PCI configuration register are preserved. The new value of the
1126 32-bit register is returned.
1128 If any reserved bits in Address are set, then ASSERT().
1129 If Address is not aligned on a 32-bit boundary, then ASSERT().
1130 If StartBit is greater than 31, then ASSERT().
1131 If EndBit is greater than 31, then ASSERT().
1132 If EndBit is less than StartBit, then ASSERT().
1133 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1135 @param Address PCI configuration register to write.
1136 @param StartBit The ordinal of the least significant bit in the bit field.
1138 @param EndBit The ordinal of the most significant bit in the bit field.
1140 @param Value New value of the bit field.
1142 @return The value written back to the PCI configuration register.
1147 PciSegmentBitFieldWrite32 (
1154 return PciSegmentWrite32 (
1156 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1161 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1162 writes the result back to the bit field in the 32-bit port.
1164 Reads the 32-bit PCI configuration register specified by Address, performs a
1165 bitwise OR between the read result and the value specified by
1166 OrData, and writes the result to the 32-bit PCI configuration register
1167 specified by Address. The value written to the PCI configuration register is
1168 returned. This function must guarantee that all PCI read and write operations
1169 are serialized. Extra left bits in OrData are stripped.
1171 If any reserved bits in Address are set, then ASSERT().
1172 If StartBit is greater than 31, then ASSERT().
1173 If EndBit is greater than 31, then ASSERT().
1174 If EndBit is less than StartBit, then ASSERT().
1175 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1177 @param Address PCI configuration register to write.
1178 @param StartBit The ordinal of the least significant bit in the bit field.
1180 @param EndBit The ordinal of the most significant bit in the bit field.
1182 @param OrData The value to OR with the PCI configuration register.
1184 @return The value written back to the PCI configuration register.
1189 PciSegmentBitFieldOr32 (
1196 return PciSegmentWrite32 (
1198 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1203 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1204 AND, and writes the result back to the bit field in the 32-bit register.
1207 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1208 AND between the read result and the value specified by AndData, and writes the result
1209 to the 32-bit PCI configuration register specified by Address. The value written to
1210 the PCI configuration register is returned. This function must guarantee that all PCI
1211 read and write operations are serialized. Extra left bits in AndData are stripped.
1212 If any reserved bits in Address are set, then ASSERT().
1213 If Address is not aligned on a 32-bit boundary, then ASSERT().
1214 If StartBit is greater than 31, then ASSERT().
1215 If EndBit is greater than 31, then ASSERT().
1216 If EndBit is less than StartBit, then ASSERT().
1217 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1219 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1220 @param StartBit The ordinal of the least significant bit in the bit field.
1222 @param EndBit The ordinal of the most significant bit in the bit field.
1224 @param AndData The value to AND with the PCI configuration register.
1226 @return The value written back to the PCI configuration register.
1231 PciSegmentBitFieldAnd32 (
1238 return PciSegmentWrite32 (
1240 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1245 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1246 bitwise OR, and writes the result back to the bit field in the
1249 Reads the 32-bit PCI configuration register specified by Address, performs a
1250 bitwise AND followed by a bitwise OR between the read result and
1251 the value specified by AndData, and writes the result to the 32-bit PCI
1252 configuration register specified by Address. The value written to the PCI
1253 configuration register is returned. This function must guarantee that all PCI
1254 read and write operations are serialized. Extra left bits in both AndData and
1255 OrData are stripped.
1257 If any reserved bits in Address are set, then ASSERT().
1258 If StartBit is greater than 31, then ASSERT().
1259 If EndBit is greater than 31, then ASSERT().
1260 If EndBit is less than StartBit, then ASSERT().
1261 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1262 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1264 @param Address PCI configuration register to write.
1265 @param StartBit The ordinal of the least significant bit in the bit field.
1267 @param EndBit The ordinal of the most significant bit in the bit field.
1269 @param AndData The value to AND with the PCI configuration register.
1270 @param OrData The value to OR with the result of the AND operation.
1272 @return The value written back to the PCI configuration register.
1277 PciSegmentBitFieldAndThenOr32 (
1285 return PciSegmentWrite32 (
1287 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1292 Reads a range of PCI configuration registers into a caller supplied buffer.
1294 Reads the range of PCI configuration registers specified by StartAddress and
1295 Size into the buffer specified by Buffer. This function only allows the PCI
1296 configuration registers from a single PCI function to be read. Size is
1297 returned. When possible 32-bit PCI configuration read cycles are used to read
1298 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1299 and 16-bit PCI configuration read cycles may be used at the beginning and the
1302 If any reserved bits in StartAddress are set, then ASSERT().
1303 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1304 If Size > 0 and Buffer is NULL, then ASSERT().
1306 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1307 Function and Register.
1308 @param Size Size in bytes of the transfer.
1309 @param Buffer Pointer to a buffer receiving the data read.
1316 PciSegmentReadBuffer (
1317 IN UINT64 StartAddress
,
1324 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1325 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1331 ASSERT (Buffer
!= NULL
);
1334 // Save Size for return
1338 if ((StartAddress
& BIT0
) != 0) {
1340 // Read a byte if StartAddress is byte aligned
1342 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1343 StartAddress
+= sizeof (UINT8
);
1344 Size
-= sizeof (UINT8
);
1345 Buffer
= (UINT8
*)Buffer
+ 1;
1348 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1350 // Read a word if StartAddress is word aligned
1352 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1353 StartAddress
+= sizeof (UINT16
);
1354 Size
-= sizeof (UINT16
);
1355 Buffer
= (UINT16
*)Buffer
+ 1;
1358 while (Size
>= sizeof (UINT32
)) {
1360 // Read as many double words as possible
1362 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1363 StartAddress
+= sizeof (UINT32
);
1364 Size
-= sizeof (UINT32
);
1365 Buffer
= (UINT32
*)Buffer
+ 1;
1368 if (Size
>= sizeof (UINT16
)) {
1370 // Read the last remaining word if exist
1372 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1373 StartAddress
+= sizeof (UINT16
);
1374 Size
-= sizeof (UINT16
);
1375 Buffer
= (UINT16
*)Buffer
+ 1;
1378 if (Size
>= sizeof (UINT8
)) {
1380 // Read the last remaining byte if exist
1382 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1389 Copies the data in a caller supplied buffer to a specified range of PCI
1390 configuration space.
1392 Writes the range of PCI configuration registers specified by StartAddress and
1393 Size from the buffer specified by Buffer. This function only allows the PCI
1394 configuration registers from a single PCI function to be written. Size is
1395 returned. When possible 32-bit PCI configuration write cycles are used to
1396 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1397 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1398 and the end of the range.
1400 If any reserved bits in StartAddress are set, then ASSERT().
1401 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1402 If Size > 0 and Buffer is NULL, then ASSERT().
1404 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1405 Function and Register.
1406 @param Size Size in bytes of the transfer.
1407 @param Buffer Pointer to a buffer containing the data to write.
1409 @return The parameter of Size.
1414 PciSegmentWriteBuffer (
1415 IN UINT64 StartAddress
,
1422 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1423 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1429 ASSERT (Buffer
!= NULL
);
1432 // Save Size for return
1436 if ((StartAddress
& BIT0
) != 0) {
1438 // Write a byte if StartAddress is byte aligned
1440 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1441 StartAddress
+= sizeof (UINT8
);
1442 Size
-= sizeof (UINT8
);
1443 Buffer
= (UINT8
*)Buffer
+ 1;
1446 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1448 // Write a word if StartAddress is word aligned
1450 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1451 StartAddress
+= sizeof (UINT16
);
1452 Size
-= sizeof (UINT16
);
1453 Buffer
= (UINT16
*)Buffer
+ 1;
1456 while (Size
>= sizeof (UINT32
)) {
1458 // Write as many double words as possible
1460 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1461 StartAddress
+= sizeof (UINT32
);
1462 Size
-= sizeof (UINT32
);
1463 Buffer
= (UINT32
*)Buffer
+ 1;
1466 if (Size
>= sizeof (UINT16
)) {
1468 // Write the last remaining word if exist
1470 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1471 StartAddress
+= sizeof (UINT16
);
1472 Size
-= sizeof (UINT16
);
1473 Buffer
= (UINT16
*)Buffer
+ 1;
1476 if (Size
>= sizeof (UINT8
)) {
1478 // Write the last remaining byte if exist
1480 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);