2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.
4 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are
6 licensed and made available under the terms and conditions of
7 the BSD License which accompanies this distribution. The full
8 text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PciSegmentLib.h"
19 // Global variable to record data of PCI Root Bridge I/O Protocol instances
21 PCI_ROOT_BRIDGE_DATA
*mPciRootBridgeData
= NULL
;
22 UINTN mNumberOfPciRootBridges
= 0;
25 The constructor function caches data of PCI Root Bridge I/O Protocol instances.
27 The constructor function locates PCI Root Bridge I/O protocol instances,
28 and caches the protocol instances, together with their segment numbers and bus ranges.
29 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
31 @param ImageHandle The firmware allocated handle for the EFI image.
32 @param SystemTable A pointer to the EFI System Table.
34 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
39 PciSegmentLibConstructor (
40 IN EFI_HANDLE ImageHandle
,
41 IN EFI_SYSTEM_TABLE
*SystemTable
47 EFI_HANDLE
*HandleBuffer
;
48 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
49 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
53 PciRootBridgeIo
= NULL
;
56 Status
= gBS
->LocateHandleBuffer (
58 &gEfiPciRootBridgeIoProtocolGuid
,
63 ASSERT_EFI_ERROR (Status
);
65 mNumberOfPciRootBridges
= HandleCount
;
67 mPciRootBridgeData
= AllocatePool (HandleCount
* sizeof (PCI_ROOT_BRIDGE_DATA
));
68 ASSERT (mPciRootBridgeData
!= NULL
);
71 // Traverse all PCI Root Bridge I/O Protocol instances, and record the protocol
72 // instances, together with their segment numbers and bus ranges.
74 for (Index
= 0; Index
< HandleCount
; Index
++) {
75 Status
= gBS
->HandleProtocol (
77 &gEfiPciRootBridgeIoProtocolGuid
,
78 (VOID
**) &PciRootBridgeIo
80 ASSERT_EFI_ERROR (Status
);
82 mPciRootBridgeData
[Index
].PciRootBridgeIo
= PciRootBridgeIo
;
83 mPciRootBridgeData
[Index
].SegmentNumber
= PciRootBridgeIo
->SegmentNumber
;
85 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
86 ASSERT_EFI_ERROR (Status
);
88 while (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
89 if (Descriptors
->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
90 mPciRootBridgeData
[Index
].MinBusNumber
= Descriptors
->AddrRangeMin
;
91 mPciRootBridgeData
[Index
].MaxBusNumber
= Descriptors
->AddrRangeMax
;
96 ASSERT (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
);
99 FreePool(HandleBuffer
);
105 The destructor function frees memory allocated by constructor.
107 The destructor function frees memory for data of protocol instances allocated by constructor.
108 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
110 @param ImageHandle The firmware allocated handle for the EFI image.
111 @param SystemTable A pointer to the EFI System Table.
113 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
118 PciSegmentLibDestructor (
119 IN EFI_HANDLE ImageHandle
,
120 IN EFI_SYSTEM_TABLE
*SystemTable
123 FreePool (mPciRootBridgeData
);
129 According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.
131 This internal function extracts segment number and bus number data from address, and
132 retrieves the corresponding PCI Root Bridge I/O Protocol instance.
134 @param Address The address that encodes the Segment, PCI Bus, Device, Function and
137 @return The address for PCI Root Bridge I/O Protocol.
140 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*
141 PciSegmentLibSearchForRootBridge (
146 UINT64 SegmentNumber
;
149 for (Index
= 0; Index
< mNumberOfPciRootBridges
; Index
++) {
151 // Matches segment number of address with the segment number of protocol instance.
153 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
154 if (SegmentNumber
== mPciRootBridgeData
[Index
].SegmentNumber
) {
156 // Matches the bus number of address with bus number range of protocol instance.
158 BusNumber
= BitFieldRead64 (Address
, 20, 27);
159 if (BusNumber
>= mPciRootBridgeData
[Index
].MinBusNumber
&& BusNumber
<= mPciRootBridgeData
[Index
].MaxBusNumber
) {
160 return mPciRootBridgeData
[Index
].PciRootBridgeIo
;
168 Internal worker function to read a PCI configuration register.
170 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
171 It reads and returns the PCI configuration register specified by Address,
172 the width of data is specified by Width.
174 @param Address The address that encodes the PCI Bus, Device, Function and
176 @param Width Width of data to read
178 @return The value read from the PCI configuration register.
182 DxePciSegmentLibPciRootBridgeIoReadWorker (
184 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
188 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
190 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
191 ASSERT (PciRootBridgeIo
!= NULL
);
193 PciRootBridgeIo
->Pci
.Read (
196 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
205 Internal worker function to writes a PCI configuration register.
207 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
208 It writes the PCI configuration register specified by Address with the
209 value specified by Data. The width of data is specifed by Width.
212 @param Address The address that encodes the PCI Bus, Device, Function and
214 @param Width Width of data to write
215 @param Data The value to write.
217 @return The value written to the PCI configuration register.
221 DxePciSegmentLibPciRootBridgeIoWriteWorker (
223 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
227 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
229 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
230 ASSERT (PciRootBridgeIo
!= NULL
);
232 PciRootBridgeIo
->Pci
.Write (
235 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
244 Register a PCI device so PCI configuration registers may be accessed after
245 SetVirtualAddressMap().
247 If any reserved bits in Address are set, then ASSERT().
249 @param Address Address that encodes the PCI Bus, Device, Function and
252 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
253 @retval RETURN_UNSUPPORTED An attempt was made to call this function
254 after ExitBootServices().
255 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
256 at runtime could not be mapped.
257 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
258 complete the registration.
263 PciSegmentRegisterForRuntimeAccess (
267 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
268 return RETURN_UNSUPPORTED
;
272 Reads an 8-bit PCI configuration register.
274 Reads and returns the 8-bit PCI configuration register specified by Address.
275 This function must guarantee that all PCI read and write operations are serialized.
277 If any reserved bits in Address are set, then ASSERT().
279 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
281 @return The 8-bit PCI configuration register specified by Address.
290 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
292 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
296 Writes an 8-bit PCI configuration register.
298 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
299 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
301 If any reserved bits in Address are set, then ASSERT().
303 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
304 @param Value The value to write.
306 @return The value written to the PCI configuration register.
316 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
318 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
322 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
324 Reads the 8-bit PCI configuration register specified by Address,
325 performs a bitwise OR between the read result and the value specified by OrData,
326 and writes the result to the 8-bit PCI configuration register specified by Address.
327 The value written to the PCI configuration register is returned.
328 This function must guarantee that all PCI read and write operations are serialized.
330 If any reserved bits in Address are set, then ASSERT().
332 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
333 @param OrData The value to OR with the PCI configuration register.
335 @return The value written to the PCI configuration register.
345 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
349 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
351 Reads the 8-bit PCI configuration register specified by Address,
352 performs a bitwise AND between the read result and the value specified by AndData,
353 and writes the result to the 8-bit PCI configuration register specified by Address.
354 The value written to the PCI configuration register is returned.
355 This function must guarantee that all PCI read and write operations are serialized.
356 If any reserved bits in Address are set, then ASSERT().
358 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
359 @param AndData The value to AND with the PCI configuration register.
361 @return The value written to the PCI configuration register.
371 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
375 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
376 followed a bitwise OR with another 8-bit value.
378 Reads the 8-bit PCI configuration register specified by Address,
379 performs a bitwise AND between the read result and the value specified by AndData,
380 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
381 and writes the result to the 8-bit PCI configuration register specified by Address.
382 The value written to the PCI configuration register is returned.
383 This function must guarantee that all PCI read and write operations are serialized.
385 If any reserved bits in Address are set, then ASSERT().
387 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
388 @param AndData The value to AND with the PCI configuration register.
389 @param OrData The value to OR with the PCI configuration register.
391 @return The value written to the PCI configuration register.
396 PciSegmentAndThenOr8 (
402 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
406 Reads a bit field of a PCI configuration register.
408 Reads the bit field in an 8-bit PCI configuration register. The bit field is
409 specified by the StartBit and the EndBit. The value of the bit field is
412 If any reserved bits in Address are set, then ASSERT().
413 If StartBit is greater than 7, then ASSERT().
414 If EndBit is greater than 7, then ASSERT().
415 If EndBit is less than StartBit, then ASSERT().
417 @param Address PCI configuration register to read.
418 @param StartBit The ordinal of the least significant bit in the bit field.
420 @param EndBit The ordinal of the most significant bit in the bit field.
423 @return The value of the bit field read from the PCI configuration register.
428 PciSegmentBitFieldRead8 (
434 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
438 Writes a bit field to a PCI configuration register.
440 Writes Value to the bit field of the PCI configuration register. The bit
441 field is specified by the StartBit and the EndBit. All other bits in the
442 destination PCI configuration register are preserved. The new value of the
443 8-bit register is returned.
445 If any reserved bits in Address are set, then ASSERT().
446 If StartBit is greater than 7, then ASSERT().
447 If EndBit is greater than 7, then ASSERT().
448 If EndBit is less than StartBit, then ASSERT().
449 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
451 @param Address PCI configuration register to write.
452 @param StartBit The ordinal of the least significant bit in the bit field.
454 @param EndBit The ordinal of the most significant bit in the bit field.
456 @param Value New value of the bit field.
458 @return The value written back to the PCI configuration register.
463 PciSegmentBitFieldWrite8 (
470 return PciSegmentWrite8 (
472 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
477 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
478 writes the result back to the bit field in the 8-bit port.
480 Reads the 8-bit PCI configuration register specified by Address, performs a
481 bitwise OR between the read result and the value specified by
482 OrData, and writes the result to the 8-bit PCI configuration register
483 specified by Address. The value written to the PCI configuration register is
484 returned. This function must guarantee that all PCI read and write operations
485 are serialized. Extra left bits in OrData are stripped.
487 If any reserved bits in Address are set, then ASSERT().
488 If StartBit is greater than 7, then ASSERT().
489 If EndBit is greater than 7, then ASSERT().
490 If EndBit is less than StartBit, then ASSERT().
491 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
493 @param Address PCI configuration register to write.
494 @param StartBit The ordinal of the least significant bit in the bit field.
496 @param EndBit The ordinal of the most significant bit in the bit field.
498 @param OrData The value to OR with the PCI configuration register.
500 @return The value written back to the PCI configuration register.
505 PciSegmentBitFieldOr8 (
512 return PciSegmentWrite8 (
514 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
519 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
520 AND, and writes the result back to the bit field in the 8-bit register.
522 Reads the 8-bit PCI configuration register specified by Address, performs a
523 bitwise AND between the read result and the value specified by AndData, and
524 writes the result to the 8-bit PCI configuration register specified by
525 Address. The value written to the PCI configuration register is returned.
526 This function must guarantee that all PCI read and write operations are
527 serialized. Extra left bits in AndData are stripped.
529 If any reserved bits in Address are set, then ASSERT().
530 If StartBit is greater than 7, then ASSERT().
531 If EndBit is greater than 7, then ASSERT().
532 If EndBit is less than StartBit, then ASSERT().
533 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
535 @param Address PCI configuration register to write.
536 @param StartBit The ordinal of the least significant bit in the bit field.
538 @param EndBit The ordinal of the most significant bit in the bit field.
540 @param AndData The value to AND with the PCI configuration register.
542 @return The value written back to the PCI configuration register.
547 PciSegmentBitFieldAnd8 (
554 return PciSegmentWrite8 (
556 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
561 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
562 bitwise OR, and writes the result back to the bit field in the 8-bit port.
564 Reads the 8-bit PCI configuration register specified by Address, performs a
565 bitwise AND followed by a bitwise OR between the read result and
566 the value specified by AndData, and writes the result to the 8-bit PCI
567 configuration register specified by Address. The value written to the PCI
568 configuration register is returned. This function must guarantee that all PCI
569 read and write operations are serialized. Extra left bits in both AndData and
572 If any reserved bits in Address are set, then ASSERT().
573 If StartBit is greater than 7, then ASSERT().
574 If EndBit is greater than 7, then ASSERT().
575 If EndBit is less than StartBit, then ASSERT().
576 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
577 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
579 @param Address PCI configuration register to write.
580 @param StartBit The ordinal of the least significant bit in the bit field.
582 @param EndBit The ordinal of the most significant bit in the bit field.
584 @param AndData The value to AND with the PCI configuration register.
585 @param OrData The value to OR with the result of the AND operation.
587 @return The value written back to the PCI configuration register.
592 PciSegmentBitFieldAndThenOr8 (
600 return PciSegmentWrite8 (
602 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
607 Reads a 16-bit PCI configuration register.
609 Reads and returns the 16-bit PCI configuration register specified by Address.
610 This function must guarantee that all PCI read and write operations are serialized.
612 If any reserved bits in Address are set, then ASSERT().
613 If Address is not aligned on a 16-bit boundary, then ASSERT().
615 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
617 @return The 16-bit PCI configuration register specified by Address.
626 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
628 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
632 Writes a 16-bit PCI configuration register.
634 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
635 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
637 If any reserved bits in Address are set, then ASSERT().
638 If Address is not aligned on a 16-bit boundary, then ASSERT().
640 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
641 @param Value The value to write.
643 @return The parameter of Value.
653 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
655 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
659 Performs a bitwise OR of a 16-bit PCI configuration register with
662 Reads the 16-bit PCI configuration register specified by Address, performs a
663 bitwise OR between the read result and the value specified by OrData, and
664 writes the result to the 16-bit PCI configuration register specified by Address.
665 The value written to the PCI configuration register is returned. This function
666 must guarantee that all PCI read and write operations are serialized.
668 If any reserved bits in Address are set, then ASSERT().
669 If Address is not aligned on a 16-bit boundary, then ASSERT().
671 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
673 @param OrData The value to OR with the PCI configuration register.
675 @return The value written back to the PCI configuration register.
685 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
689 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
691 Reads the 16-bit PCI configuration register specified by Address,
692 performs a bitwise AND between the read result and the value specified by AndData,
693 and writes the result to the 16-bit PCI configuration register specified by Address.
694 The value written to the PCI configuration register is returned.
695 This function must guarantee that all PCI read and write operations are serialized.
697 If any reserved bits in Address are set, then ASSERT().
698 If Address is not aligned on a 16-bit boundary, then ASSERT().
700 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
701 @param AndData The value to AND with the PCI configuration register.
703 @return The value written to the PCI configuration register.
713 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
717 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
718 followed a bitwise OR with another 16-bit value.
720 Reads the 16-bit PCI configuration register specified by Address,
721 performs a bitwise AND between the read result and the value specified by AndData,
722 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
723 and writes the result to the 16-bit PCI configuration register specified by Address.
724 The value written to the PCI configuration register is returned.
725 This function must guarantee that all PCI read and write operations are serialized.
727 If any reserved bits in Address are set, then ASSERT().
728 If Address is not aligned on a 16-bit boundary, then ASSERT().
730 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
731 @param AndData The value to AND with the PCI configuration register.
732 @param OrData The value to OR with the PCI configuration register.
734 @return The value written to the PCI configuration register.
739 PciSegmentAndThenOr16 (
745 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
749 Reads a bit field of a PCI configuration register.
751 Reads the bit field in a 16-bit PCI configuration register. The bit field is
752 specified by the StartBit and the EndBit. The value of the bit field is
755 If any reserved bits in Address are set, then ASSERT().
756 If Address is not aligned on a 16-bit boundary, then ASSERT().
757 If StartBit is greater than 15, then ASSERT().
758 If EndBit is greater than 15, then ASSERT().
759 If EndBit is less than StartBit, then ASSERT().
761 @param Address PCI configuration register to read.
762 @param StartBit The ordinal of the least significant bit in the bit field.
764 @param EndBit The ordinal of the most significant bit in the bit field.
767 @return The value of the bit field read from the PCI configuration register.
772 PciSegmentBitFieldRead16 (
778 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
782 Writes a bit field to a PCI configuration register.
784 Writes Value to the bit field of the PCI configuration register. The bit
785 field is specified by the StartBit and the EndBit. All other bits in the
786 destination PCI configuration register are preserved. The new value of the
787 16-bit register is returned.
789 If any reserved bits in Address are set, then ASSERT().
790 If Address is not aligned on a 16-bit boundary, then ASSERT().
791 If StartBit is greater than 15, then ASSERT().
792 If EndBit is greater than 15, then ASSERT().
793 If EndBit is less than StartBit, then ASSERT().
794 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
796 @param Address PCI configuration register to write.
797 @param StartBit The ordinal of the least significant bit in the bit field.
799 @param EndBit The ordinal of the most significant bit in the bit field.
801 @param Value New value of the bit field.
803 @return The value written back to the PCI configuration register.
808 PciSegmentBitFieldWrite16 (
815 return PciSegmentWrite16 (
817 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
822 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, writes
823 the result back to the bit field in the 16-bit port.
825 Reads the 16-bit PCI configuration register specified by Address, performs a
826 bitwise OR between the read result and the value specified by
827 OrData, and writes the result to the 16-bit PCI configuration register
828 specified by Address. The value written to the PCI configuration register is
829 returned. This function must guarantee that all PCI read and write operations
830 are serialized. Extra left bits in OrData are stripped.
832 If any reserved bits in Address are set, then ASSERT().
833 If Address is not aligned on a 16-bit boundary, then ASSERT().
834 If StartBit is greater than 15, then ASSERT().
835 If EndBit is greater than 15, then ASSERT().
836 If EndBit is less than StartBit, then ASSERT().
837 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
839 @param Address PCI configuration register to write.
840 @param StartBit The ordinal of the least significant bit in the bit field.
842 @param EndBit The ordinal of the most significant bit in the bit field.
844 @param OrData The value to OR with the PCI configuration register.
846 @return The value written back to the PCI configuration register.
851 PciSegmentBitFieldOr16 (
858 return PciSegmentWrite16 (
860 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
865 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
866 AND, writes the result back to the bit field in the 16-bit register.
868 Reads the 16-bit PCI configuration register specified by Address, performs a
869 bitwise AND between the read result and the value specified by AndData, and
870 writes the result to the 16-bit PCI configuration register specified by
871 Address. The value written to the PCI configuration register is returned.
872 This function must guarantee that all PCI read and write operations are
873 serialized. Extra left bits in AndData are stripped.
875 If any reserved bits in Address are set, then ASSERT().
876 If Address is not aligned on a 16-bit boundary, then ASSERT().
877 If StartBit is greater than 15, then ASSERT().
878 If EndBit is greater than 15, then ASSERT().
879 If EndBit is less than StartBit, then ASSERT().
880 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
882 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
883 @param StartBit The ordinal of the least significant bit in the bit field.
885 @param EndBit The ordinal of the most significant bit in the bit field.
887 @param AndData The value to AND with the PCI configuration register.
889 @return The value written back to the PCI configuration register.
894 PciSegmentBitFieldAnd16 (
901 return PciSegmentWrite16 (
903 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
908 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
909 bitwise OR, and writes the result back to the bit field in the
912 Reads the 16-bit PCI configuration register specified by Address, performs a
913 bitwise AND followed by a bitwise OR between the read result and
914 the value specified by AndData, and writes the result to the 16-bit PCI
915 configuration register specified by Address. The value written to the PCI
916 configuration register is returned. This function must guarantee that all PCI
917 read and write operations are serialized. Extra left bits in both AndData and
920 If any reserved bits in Address are set, then ASSERT().
921 If StartBit is greater than 15, then ASSERT().
922 If EndBit is greater than 15, then ASSERT().
923 If EndBit is less than StartBit, then ASSERT().
924 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
925 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
927 @param Address PCI configuration register to write.
928 @param StartBit The ordinal of the least significant bit in the bit field.
930 @param EndBit The ordinal of the most significant bit in the bit field.
932 @param AndData The value to AND with the PCI configuration register.
933 @param OrData The value to OR with the result of the AND operation.
935 @return The value written back to the PCI configuration register.
940 PciSegmentBitFieldAndThenOr16 (
948 return PciSegmentWrite16 (
950 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
955 Reads a 32-bit PCI configuration register.
957 Reads and returns the 32-bit PCI configuration register specified by Address.
958 This function must guarantee that all PCI read and write operations are serialized.
960 If any reserved bits in Address are set, then ASSERT().
961 If Address is not aligned on a 32-bit boundary, then ASSERT().
963 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
965 @return The 32-bit PCI configuration register specified by Address.
974 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
976 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
980 Writes a 32-bit PCI configuration register.
982 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
983 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
985 If any reserved bits in Address are set, then ASSERT().
986 If Address is not aligned on a 32-bit boundary, then ASSERT().
988 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
989 @param Value The value to write.
991 @return The parameter of Value.
1001 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
1003 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
1007 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
1009 Reads the 32-bit PCI configuration register specified by Address,
1010 performs a bitwise OR between the read result and the value specified by OrData,
1011 and writes the result to the 32-bit PCI configuration register specified by Address.
1012 The value written to the PCI configuration register is returned.
1013 This function must guarantee that all PCI read and write operations are serialized.
1015 If any reserved bits in Address are set, then ASSERT().
1016 If Address is not aligned on a 32-bit boundary, then ASSERT().
1018 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1019 @param OrData The value to OR with the PCI configuration register.
1021 @return The value written to the PCI configuration register.
1031 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1035 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
1037 Reads the 32-bit PCI configuration register specified by Address,
1038 performs a bitwise AND between the read result and the value specified by AndData,
1039 and writes the result to the 32-bit PCI configuration register specified by Address.
1040 The value written to the PCI configuration register is returned.
1041 This function must guarantee that all PCI read and write operations are serialized.
1043 If any reserved bits in Address are set, then ASSERT().
1044 If Address is not aligned on a 32-bit boundary, then ASSERT().
1046 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1047 @param AndData The value to AND with the PCI configuration register.
1049 @return The value written to the PCI configuration register.
1059 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1063 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
1064 followed a bitwise OR with another 32-bit value.
1066 Reads the 32-bit PCI configuration register specified by Address,
1067 performs a bitwise AND between the read result and the value specified by AndData,
1068 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
1069 and writes the result to the 32-bit PCI configuration register specified by Address.
1070 The value written to the PCI configuration register is returned.
1071 This function must guarantee that all PCI read and write operations are serialized.
1073 If any reserved bits in Address are set, then ASSERT().
1074 If Address is not aligned on a 32-bit boundary, then ASSERT().
1076 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1077 @param AndData The value to AND with the PCI configuration register.
1078 @param OrData The value to OR with the PCI configuration register.
1080 @return The value written to the PCI configuration register.
1085 PciSegmentAndThenOr32 (
1091 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1095 Reads a bit field of a PCI configuration register.
1097 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1098 specified by the StartBit and the EndBit. The value of the bit field is
1101 If any reserved bits in Address are set, then ASSERT().
1102 If Address is not aligned on a 32-bit boundary, then ASSERT().
1103 If StartBit is greater than 31, then ASSERT().
1104 If EndBit is greater than 31, then ASSERT().
1105 If EndBit is less than StartBit, then ASSERT().
1107 @param Address PCI configuration register to read.
1108 @param StartBit The ordinal of the least significant bit in the bit field.
1110 @param EndBit The ordinal of the most significant bit in the bit field.
1113 @return The value of the bit field read from the PCI configuration register.
1118 PciSegmentBitFieldRead32 (
1124 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1128 Writes a bit field to a PCI configuration register.
1130 Writes Value to the bit field of the PCI configuration register. The bit
1131 field is specified by the StartBit and the EndBit. All other bits in the
1132 destination PCI configuration register are preserved. The new value of the
1133 32-bit register is returned.
1135 If any reserved bits in Address are set, then ASSERT().
1136 If Address is not aligned on a 32-bit boundary, then ASSERT().
1137 If StartBit is greater than 31, then ASSERT().
1138 If EndBit is greater than 31, then ASSERT().
1139 If EndBit is less than StartBit, then ASSERT().
1140 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1142 @param Address PCI configuration register to write.
1143 @param StartBit The ordinal of the least significant bit in the bit field.
1145 @param EndBit The ordinal of the most significant bit in the bit field.
1147 @param Value New value of the bit field.
1149 @return The value written back to the PCI configuration register.
1154 PciSegmentBitFieldWrite32 (
1161 return PciSegmentWrite32 (
1163 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1168 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1169 writes the result back to the bit field in the 32-bit port.
1171 Reads the 32-bit PCI configuration register specified by Address, performs a
1172 bitwise OR between the read result and the value specified by
1173 OrData, and writes the result to the 32-bit PCI configuration register
1174 specified by Address. The value written to the PCI configuration register is
1175 returned. This function must guarantee that all PCI read and write operations
1176 are serialized. Extra left bits in OrData are stripped.
1178 If any reserved bits in Address are set, then ASSERT().
1179 If StartBit is greater than 31, then ASSERT().
1180 If EndBit is greater than 31, then ASSERT().
1181 If EndBit is less than StartBit, then ASSERT().
1182 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1184 @param Address PCI configuration register to write.
1185 @param StartBit The ordinal of the least significant bit in the bit field.
1187 @param EndBit The ordinal of the most significant bit in the bit field.
1189 @param OrData The value to OR with the PCI configuration register.
1191 @return The value written back to the PCI configuration register.
1196 PciSegmentBitFieldOr32 (
1203 return PciSegmentWrite32 (
1205 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1210 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1211 AND, and writes the result back to the bit field in the 32-bit register.
1214 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1215 AND between the read result and the value specified by AndData, and writes the result
1216 to the 32-bit PCI configuration register specified by Address. The value written to
1217 the PCI configuration register is returned. This function must guarantee that all PCI
1218 read and write operations are serialized. Extra left bits in AndData are stripped.
1219 If any reserved bits in Address are set, then ASSERT().
1220 If Address is not aligned on a 32-bit boundary, then ASSERT().
1221 If StartBit is greater than 31, then ASSERT().
1222 If EndBit is greater than 31, then ASSERT().
1223 If EndBit is less than StartBit, then ASSERT().
1224 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1226 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1227 @param StartBit The ordinal of the least significant bit in the bit field.
1229 @param EndBit The ordinal of the most significant bit in the bit field.
1231 @param AndData The value to AND with the PCI configuration register.
1233 @return The value written back to the PCI configuration register.
1238 PciSegmentBitFieldAnd32 (
1245 return PciSegmentWrite32 (
1247 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1252 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1253 bitwise OR, and writes the result back to the bit field in the
1256 Reads the 32-bit PCI configuration register specified by Address, performs a
1257 bitwise AND followed by a bitwise OR between the read result and
1258 the value specified by AndData, and writes the result to the 32-bit PCI
1259 configuration register specified by Address. The value written to the PCI
1260 configuration register is returned. This function must guarantee that all PCI
1261 read and write operations are serialized. Extra left bits in both AndData and
1262 OrData are stripped.
1264 If any reserved bits in Address are set, then ASSERT().
1265 If StartBit is greater than 31, then ASSERT().
1266 If EndBit is greater than 31, then ASSERT().
1267 If EndBit is less than StartBit, then ASSERT().
1268 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1269 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1271 @param Address PCI configuration register to write.
1272 @param StartBit The ordinal of the least significant bit in the bit field.
1274 @param EndBit The ordinal of the most significant bit in the bit field.
1276 @param AndData The value to AND with the PCI configuration register.
1277 @param OrData The value to OR with the result of the AND operation.
1279 @return The value written back to the PCI configuration register.
1284 PciSegmentBitFieldAndThenOr32 (
1292 return PciSegmentWrite32 (
1294 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1299 Reads a range of PCI configuration registers into a caller supplied buffer.
1301 Reads the range of PCI configuration registers specified by StartAddress and
1302 Size into the buffer specified by Buffer. This function only allows the PCI
1303 configuration registers from a single PCI function to be read. Size is
1304 returned. When possible 32-bit PCI configuration read cycles are used to read
1305 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1306 and 16-bit PCI configuration read cycles may be used at the beginning and the
1309 If any reserved bits in StartAddress are set, then ASSERT().
1310 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1311 If Size > 0 and Buffer is NULL, then ASSERT().
1313 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1314 Function and Register.
1315 @param Size Size in bytes of the transfer.
1316 @param Buffer Pointer to a buffer receiving the data read.
1323 PciSegmentReadBuffer (
1324 IN UINT64 StartAddress
,
1331 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1332 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1338 ASSERT (Buffer
!= NULL
);
1341 // Save Size for return
1345 if ((StartAddress
& BIT0
) != 0) {
1347 // Read a byte if StartAddress is byte aligned
1349 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1350 StartAddress
+= sizeof (UINT8
);
1351 Size
-= sizeof (UINT8
);
1352 Buffer
= (UINT8
*)Buffer
+ 1;
1355 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1357 // Read a word if StartAddress is word aligned
1359 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1360 StartAddress
+= sizeof (UINT16
);
1361 Size
-= sizeof (UINT16
);
1362 Buffer
= (UINT16
*)Buffer
+ 1;
1365 while (Size
>= sizeof (UINT32
)) {
1367 // Read as many double words as possible
1369 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1370 StartAddress
+= sizeof (UINT32
);
1371 Size
-= sizeof (UINT32
);
1372 Buffer
= (UINT32
*)Buffer
+ 1;
1375 if (Size
>= sizeof (UINT16
)) {
1377 // Read the last remaining word if exist
1379 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1380 StartAddress
+= sizeof (UINT16
);
1381 Size
-= sizeof (UINT16
);
1382 Buffer
= (UINT16
*)Buffer
+ 1;
1385 if (Size
>= sizeof (UINT8
)) {
1387 // Read the last remaining byte if exist
1389 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1396 Copies the data in a caller supplied buffer to a specified range of PCI
1397 configuration space.
1399 Writes the range of PCI configuration registers specified by StartAddress and
1400 Size from the buffer specified by Buffer. This function only allows the PCI
1401 configuration registers from a single PCI function to be written. Size is
1402 returned. When possible 32-bit PCI configuration write cycles are used to
1403 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1404 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1405 and the end of the range.
1407 If any reserved bits in StartAddress are set, then ASSERT().
1408 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1409 If Size > 0 and Buffer is NULL, then ASSERT().
1411 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1412 Function and Register.
1413 @param Size Size in bytes of the transfer.
1414 @param Buffer Pointer to a buffer containing the data to write.
1416 @return The parameter of Size.
1421 PciSegmentWriteBuffer (
1422 IN UINT64 StartAddress
,
1429 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1430 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1436 ASSERT (Buffer
!= NULL
);
1439 // Save Size for return
1443 if ((StartAddress
& BIT0
) != 0) {
1445 // Write a byte if StartAddress is byte aligned
1447 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1448 StartAddress
+= sizeof (UINT8
);
1449 Size
-= sizeof (UINT8
);
1450 Buffer
= (UINT8
*)Buffer
+ 1;
1453 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1455 // Write a word if StartAddress is word aligned
1457 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1458 StartAddress
+= sizeof (UINT16
);
1459 Size
-= sizeof (UINT16
);
1460 Buffer
= (UINT16
*)Buffer
+ 1;
1463 while (Size
>= sizeof (UINT32
)) {
1465 // Write as many double words as possible
1467 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1468 StartAddress
+= sizeof (UINT32
);
1469 Size
-= sizeof (UINT32
);
1470 Buffer
= (UINT32
*)Buffer
+ 1;
1473 if (Size
>= sizeof (UINT16
)) {
1475 // Write the last remaining word if exist
1477 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1478 StartAddress
+= sizeof (UINT16
);
1479 Size
-= sizeof (UINT16
);
1480 Buffer
= (UINT16
*)Buffer
+ 1;
1483 if (Size
>= sizeof (UINT8
)) {
1485 // Write the last remaining byte if exist
1487 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);