2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.
4 Copyright (c) 2007 - 2010, Intel Corporation All rights
5 reserved. 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 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 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 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().
450 @param Address PCI configuration register to write.
451 @param StartBit The ordinal of the least significant bit in the bit field.
453 @param EndBit The ordinal of the most significant bit in the bit field.
455 @param Value New value of the bit field.
457 @return The value written back to the PCI configuration register.
462 PciSegmentBitFieldWrite8 (
469 return PciSegmentWrite8 (
471 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
476 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
477 writes the result back to the bit field in the 8-bit port.
479 Reads the 8-bit PCI configuration register specified by Address, performs a
480 bitwise OR between the read result and the value specified by
481 OrData, and writes the result to the 8-bit PCI configuration register
482 specified by Address. The value written to the PCI configuration register is
483 returned. This function must guarantee that all PCI read and write operations
484 are serialized. Extra left bits in OrData are stripped.
486 If any reserved bits in Address are set, then ASSERT().
487 If StartBit is greater than 7, then ASSERT().
488 If EndBit is greater than 7, then ASSERT().
489 If EndBit is less than StartBit, then ASSERT().
491 @param Address PCI configuration register to write.
492 @param StartBit The ordinal of the least significant bit in the bit field.
494 @param EndBit The ordinal of the most significant bit in the bit field.
496 @param OrData The value to OR with the PCI configuration register.
498 @return The value written back to the PCI configuration register.
503 PciSegmentBitFieldOr8 (
510 return PciSegmentWrite8 (
512 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
517 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
518 AND, and writes the result back to the bit field in the 8-bit register.
520 Reads the 8-bit PCI configuration register specified by Address, performs a
521 bitwise AND between the read result and the value specified by AndData, and
522 writes the result to the 8-bit PCI configuration register specified by
523 Address. The value written to the PCI configuration register is returned.
524 This function must guarantee that all PCI read and write operations are
525 serialized. Extra left bits in AndData are stripped.
527 If any reserved bits in Address are set, then ASSERT().
528 If StartBit is greater than 7, then ASSERT().
529 If EndBit is greater than 7, then ASSERT().
530 If EndBit is less than StartBit, then ASSERT().
532 @param Address PCI configuration register to write.
533 @param StartBit The ordinal of the least significant bit in the bit field.
535 @param EndBit The ordinal of the most significant bit in the bit field.
537 @param AndData The value to AND with the PCI configuration register.
539 @return The value written back to the PCI configuration register.
544 PciSegmentBitFieldAnd8 (
551 return PciSegmentWrite8 (
553 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
558 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
559 bitwise OR, and writes the result back to the bit field in the
562 Reads the 8-bit PCI configuration register specified by Address, performs a
563 bitwise AND followed by a bitwise OR between the read result and
564 the value specified by AndData, and writes the result to the 8-bit PCI
565 configuration register specified by Address. The value written to the PCI
566 configuration register is returned. This function must guarantee that all PCI
567 read and write operations are serialized. Extra left bits in both AndData and
570 If any reserved bits in Address are set, then ASSERT().
571 If StartBit is greater than 7, then ASSERT().
572 If EndBit is greater than 7, then ASSERT().
573 If EndBit is less than StartBit, 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
660 OrData, and writes the result to the 16-bit PCI configuration register
661 specified by Address. The value written to the PCI configuration register is
662 returned. This function must guarantee that all PCI read and write operations
665 If any reserved bits in Address are set, then ASSERT().
666 If Address is not aligned on a 16-bit boundary, then ASSERT().
668 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
670 @param OrData The value to OR with the PCI configuration register.
672 @return The value written back to the PCI configuration register.
682 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
686 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
688 Reads the 16-bit PCI configuration register specified by Address,
689 performs a bitwise AND between the read result and the value specified by AndData,
690 and writes the result to the 16-bit PCI configuration register specified by Address.
691 The value written to the PCI configuration register is returned.
692 This function must guarantee that all PCI read and write operations are serialized.
694 If any reserved bits in Address are set, then ASSERT().
695 If Address is not aligned on a 16-bit boundary, then ASSERT().
697 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
698 @param AndData The value to AND with the PCI configuration register.
700 @return The value written to the PCI configuration register.
710 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
714 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
715 followed a bitwise OR with another 16-bit value.
717 Reads the 16-bit PCI configuration register specified by Address,
718 performs a bitwise AND between the read result and the value specified by AndData,
719 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
720 and writes the result to the 16-bit PCI configuration register specified by Address.
721 The value written to the PCI configuration register is returned.
722 This function must guarantee that all PCI read and write operations are serialized.
724 If any reserved bits in Address are set, then ASSERT().
725 If Address is not aligned on a 16-bit boundary, then ASSERT().
727 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
728 @param AndData The value to AND with the PCI configuration register.
729 @param OrData The value to OR with the PCI configuration register.
731 @return The value written to the PCI configuration register.
736 PciSegmentAndThenOr16 (
742 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
746 Reads a bit field of a PCI configuration register.
748 Reads the bit field in a 16-bit PCI configuration register. The bit field is
749 specified by the StartBit and the EndBit. The value of the bit field is
752 If any reserved bits in Address are set, then ASSERT().
753 If Address is not aligned on a 16-bit boundary, then ASSERT().
754 If StartBit is greater than 15, then ASSERT().
755 If EndBit is greater than 15, then ASSERT().
756 If EndBit is less than StartBit, then ASSERT().
758 @param Address PCI configuration register to read.
759 @param StartBit The ordinal of the least significant bit in the bit field.
761 @param EndBit The ordinal of the most significant bit in the bit field.
764 @return The value of the bit field read from the PCI configuration register.
769 PciSegmentBitFieldRead16 (
775 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
779 Writes a bit field to a PCI configuration register.
781 Writes Value to the bit field of the PCI configuration register. The bit
782 field is specified by the StartBit and the EndBit. All other bits in the
783 destination PCI configuration register are preserved. The new value of the
784 16-bit register is returned.
786 If any reserved bits in Address are set, then ASSERT().
787 If Address is not aligned on a 16-bit boundary, then ASSERT().
788 If StartBit is greater than 15, then ASSERT().
789 If EndBit is greater than 15, then ASSERT().
790 If EndBit is less than StartBit, 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 the 16-bit PCI configuration register specified by Address,
819 performs a bitwise OR between the read result and the value specified by OrData,
820 and writes the result to the 16-bit PCI configuration register specified by Address.
822 If any reserved bits in Address are set, then ASSERT().
823 If Address is not aligned on a 16-bit boundary, then ASSERT().
824 If StartBit is greater than 15, then ASSERT().
825 If EndBit is greater than 15, then ASSERT().
826 If EndBit is less than StartBit, then ASSERT().
828 @param Address PCI configuration register to write.
829 @param StartBit The ordinal of the least significant bit in the bit field.
831 @param EndBit The ordinal of the most significant bit in the bit field.
833 @param OrData The value to OR with the PCI configuration register.
835 @return The value written back to the PCI configuration register.
840 PciSegmentBitFieldOr16 (
847 return PciSegmentWrite16 (
849 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
854 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
855 and writes the result back to the bit field in the 16-bit port.
857 Reads the 16-bit PCI configuration register specified by Address,
858 performs a bitwise OR between the read result and the value specified by OrData,
859 and writes the result to the 16-bit PCI configuration register specified by Address.
860 The value written to the PCI configuration register is returned.
861 This function must guarantee that all PCI read and write operations are serialized.
862 Extra left bits in OrData are stripped.
864 If any reserved bits in Address are set, then ASSERT().
865 If Address is not aligned on a 16-bit boundary, then ASSERT().
866 If StartBit is greater than 7, then ASSERT().
867 If EndBit is greater than 7, then ASSERT().
868 If EndBit is less than StartBit, then ASSERT().
870 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
871 @param StartBit The ordinal of the least significant bit in the bit field.
872 The ordinal of the least significant bit in a byte is bit 0.
873 @param EndBit The ordinal of the most significant bit in the bit field.
874 The ordinal of the most significant bit in a byte is bit 7.
875 @param AndData The value to AND with the read value from the PCI configuration register.
877 @return The value written to the PCI configuration register.
882 PciSegmentBitFieldAnd16 (
889 return PciSegmentWrite16 (
891 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
896 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
897 bitwise OR, and writes the result back to the bit field in the
900 Reads the 16-bit PCI configuration register specified by Address, performs a
901 bitwise AND followed by a bitwise OR between the read result and
902 the value specified by AndData, and writes the result to the 16-bit PCI
903 configuration register specified by Address. The value written to the PCI
904 configuration register is returned. This function must guarantee that all PCI
905 read and write operations are serialized. Extra left bits in both AndData and
908 If any reserved bits in Address are set, then ASSERT().
909 If StartBit is greater than 15, then ASSERT().
910 If EndBit is greater than 15, then ASSERT().
911 If EndBit is less than StartBit, then ASSERT().
913 @param Address PCI configuration register to write.
914 @param StartBit The ordinal of the least significant bit in the bit field.
916 @param EndBit The ordinal of the most significant bit in the bit field.
918 @param AndData The value to AND with the PCI configuration register.
919 @param OrData The value to OR with the result of the AND operation.
921 @return The value written back to the PCI configuration register.
926 PciSegmentBitFieldAndThenOr16 (
934 return PciSegmentWrite16 (
936 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
941 Reads a 32-bit PCI configuration register.
943 Reads and returns the 32-bit PCI configuration register specified by Address.
944 This function must guarantee that all PCI read and write operations are serialized.
946 If any reserved bits in Address are set, then ASSERT().
947 If Address is not aligned on a 32-bit boundary, then ASSERT().
949 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
951 @return The 32-bit PCI configuration register specified by Address.
960 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
962 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
966 Writes a 32-bit PCI configuration register.
968 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
969 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
971 If any reserved bits in Address are set, then ASSERT().
972 If Address is not aligned on a 32-bit boundary, then ASSERT().
974 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
975 @param Value The value to write.
977 @return The parameter of Value.
987 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
989 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
993 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
995 Reads the 32-bit PCI configuration register specified by Address,
996 performs a bitwise OR between the read result and the value specified by OrData,
997 and writes the result to the 32-bit PCI configuration register specified by Address.
998 The value written to the PCI configuration register is returned.
999 This function must guarantee that all PCI read and write operations are serialized.
1001 If any reserved bits in Address are set, then ASSERT().
1002 If Address is not aligned on a 32-bit boundary, then ASSERT().
1004 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1005 @param OrData The value to OR with the PCI configuration register.
1007 @return The value written to the PCI configuration register.
1017 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1021 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
1023 Reads the 32-bit PCI configuration register specified by Address,
1024 performs a bitwise AND between the read result and the value specified by AndData,
1025 and writes the result to the 32-bit PCI configuration register specified by Address.
1026 The value written to the PCI configuration register is returned.
1027 This function must guarantee that all PCI read and write operations are serialized.
1029 If any reserved bits in Address are set, then ASSERT().
1030 If Address is not aligned on a 32-bit boundary, then ASSERT().
1032 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1033 @param AndData The value to AND with the PCI configuration register.
1035 @return The value written to the PCI configuration register.
1045 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1049 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
1050 followed a bitwise OR with another 32-bit value.
1052 Reads the 32-bit PCI configuration register specified by Address,
1053 performs a bitwise AND between the read result and the value specified by AndData,
1054 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
1055 and writes the result to the 32-bit PCI configuration register specified by Address.
1056 The value written to the PCI configuration register is returned.
1057 This function must guarantee that all PCI read and write operations are serialized.
1059 If any reserved bits in Address are set, then ASSERT().
1060 If Address is not aligned on a 32-bit boundary, then ASSERT().
1062 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1063 @param AndData The value to AND with the PCI configuration register.
1064 @param OrData The value to OR with the PCI configuration register.
1066 @return The value written to the PCI configuration register.
1071 PciSegmentAndThenOr32 (
1077 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1081 Reads a bit field of a PCI configuration register.
1083 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1084 specified by the StartBit and the EndBit. The value of the bit field is
1087 If any reserved bits in Address are set, then ASSERT().
1088 If Address is not aligned on a 32-bit boundary, then ASSERT().
1089 If StartBit is greater than 31, then ASSERT().
1090 If EndBit is greater than 31, then ASSERT().
1091 If EndBit is less than StartBit, then ASSERT().
1093 @param Address PCI configuration register to read.
1094 @param StartBit The ordinal of the least significant bit in the bit field.
1096 @param EndBit The ordinal of the most significant bit in the bit field.
1099 @return The value of the bit field read from the PCI configuration register.
1104 PciSegmentBitFieldRead32 (
1110 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1114 Writes a bit field to a PCI configuration register.
1116 Writes Value to the bit field of the PCI configuration register. The bit
1117 field is specified by the StartBit and the EndBit. All other bits in the
1118 destination PCI configuration register are preserved. The new value of the
1119 32-bit register is returned.
1121 If any reserved bits in Address are set, then ASSERT().
1122 If Address is not aligned on a 32-bit boundary, then ASSERT().
1123 If StartBit is greater than 31, then ASSERT().
1124 If EndBit is greater than 31, then ASSERT().
1125 If EndBit is less than StartBit, then ASSERT().
1127 @param Address PCI configuration register to write.
1128 @param StartBit The ordinal of the least significant bit in the bit field.
1130 @param EndBit The ordinal of the most significant bit in the bit field.
1132 @param Value New value of the bit field.
1134 @return The value written back to the PCI configuration register.
1139 PciSegmentBitFieldWrite32 (
1146 return PciSegmentWrite32 (
1148 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1153 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1154 writes the result back to the bit field in the 32-bit port.
1156 Reads the 32-bit PCI configuration register specified by Address, performs a
1157 bitwise OR between the read result and the value specified by
1158 OrData, and writes the result to the 32-bit PCI configuration register
1159 specified by Address. The value written to the PCI configuration register is
1160 returned. This function must guarantee that all PCI read and write operations
1161 are serialized. Extra left bits in OrData are stripped.
1163 If any reserved bits in Address are set, then ASSERT().
1164 If StartBit is greater than 31, then ASSERT().
1165 If EndBit is greater than 31, then ASSERT().
1166 If EndBit is less than StartBit, then ASSERT().
1168 @param Address PCI configuration register to write.
1169 @param StartBit The ordinal of the least significant bit in the bit field.
1171 @param EndBit The ordinal of the most significant bit in the bit field.
1173 @param OrData The value to OR with the PCI configuration register.
1175 @return The value written back to the PCI configuration register.
1180 PciSegmentBitFieldOr32 (
1187 return PciSegmentWrite32 (
1189 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1194 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1195 AND, and writes the result back to the bit field in the 32-bit register.
1198 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1199 AND between the read result and the value specified by AndData, and writes the result
1200 to the 32-bit PCI configuration register specified by Address. The value written to
1201 the PCI configuration register is returned. This function must guarantee that all PCI
1202 read and write operations are serialized. Extra left bits in AndData are stripped.
1203 If any reserved bits in Address are set, then ASSERT().
1204 If Address is not aligned on a 32-bit boundary, then ASSERT().
1205 If StartBit is greater than 31, then ASSERT().
1206 If EndBit is greater than 31, then ASSERT().
1207 If EndBit is less than StartBit, then ASSERT().
1210 @param Address PCI configuration register to write.
1211 @param StartBit The ordinal of the least significant bit in the bit field.
1213 @param EndBit The ordinal of the most significant bit in the bit field.
1215 @param AndData The value to AND with the PCI configuration register.
1217 @return The value written back to the PCI configuration register.
1222 PciSegmentBitFieldAnd32 (
1229 return PciSegmentWrite32 (
1231 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1236 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1237 bitwise OR, and writes the result back to the bit field in the
1240 Reads the 32-bit PCI configuration register specified by Address, performs a
1241 bitwise AND followed by a bitwise OR between the read result and
1242 the value specified by AndData, and writes the result to the 32-bit PCI
1243 configuration register specified by Address. The value written to the PCI
1244 configuration register is returned. This function must guarantee that all PCI
1245 read and write operations are serialized. Extra left bits in both AndData and
1246 OrData are stripped.
1248 If any reserved bits in Address are set, then ASSERT().
1249 If StartBit is greater than 31, then ASSERT().
1250 If EndBit is greater than 31, then ASSERT().
1251 If EndBit is less than StartBit, then ASSERT().
1253 @param Address PCI configuration register to write.
1254 @param StartBit The ordinal of the least significant bit in the bit field.
1256 @param EndBit The ordinal of the most significant bit in the bit field.
1258 @param AndData The value to AND with the PCI configuration register.
1259 @param OrData The value to OR with the result of the AND operation.
1261 @return The value written back to the PCI configuration register.
1266 PciSegmentBitFieldAndThenOr32 (
1274 return PciSegmentWrite32 (
1276 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1281 Reads a range of PCI configuration registers into a caller supplied buffer.
1283 Reads the range of PCI configuration registers specified by StartAddress and
1284 Size into the buffer specified by Buffer. This function only allows the PCI
1285 configuration registers from a single PCI function to be read. Size is
1286 returned. When possible 32-bit PCI configuration read cycles are used to read
1287 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1288 and 16-bit PCI configuration read cycles may be used at the beginning and the
1291 If any reserved bits in StartAddress are set, then ASSERT().
1292 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1293 If Size > 0 and Buffer is NULL, then ASSERT().
1295 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1296 Function and Register.
1297 @param Size Size in bytes of the transfer.
1298 @param Buffer Pointer to a buffer receiving the data read.
1305 PciSegmentReadBuffer (
1306 IN UINT64 StartAddress
,
1313 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1314 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1320 ASSERT (Buffer
!= NULL
);
1323 // Save Size for return
1327 if ((StartAddress
& BIT0
) != 0) {
1329 // Read a byte if StartAddress is byte aligned
1331 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1332 StartAddress
+= sizeof (UINT8
);
1333 Size
-= sizeof (UINT8
);
1334 Buffer
= (UINT8
*)Buffer
+ 1;
1337 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1339 // Read a word if StartAddress is word aligned
1341 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1342 StartAddress
+= sizeof (UINT16
);
1343 Size
-= sizeof (UINT16
);
1344 Buffer
= (UINT16
*)Buffer
+ 1;
1347 while (Size
>= sizeof (UINT32
)) {
1349 // Read as many double words as possible
1351 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1352 StartAddress
+= sizeof (UINT32
);
1353 Size
-= sizeof (UINT32
);
1354 Buffer
= (UINT32
*)Buffer
+ 1;
1357 if (Size
>= sizeof (UINT16
)) {
1359 // Read the last remaining word if exist
1361 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1362 StartAddress
+= sizeof (UINT16
);
1363 Size
-= sizeof (UINT16
);
1364 Buffer
= (UINT16
*)Buffer
+ 1;
1367 if (Size
>= sizeof (UINT8
)) {
1369 // Read the last remaining byte if exist
1371 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1378 Copies the data in a caller supplied buffer to a specified range of PCI
1379 configuration space.
1381 Writes the range of PCI configuration registers specified by StartAddress and
1382 Size from the buffer specified by Buffer. This function only allows the PCI
1383 configuration registers from a single PCI function to be written. Size is
1384 returned. When possible 32-bit PCI configuration write cycles are used to
1385 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1386 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1387 and the end of the range.
1389 If any reserved bits in StartAddress are set, then ASSERT().
1390 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1391 If Size > 0 and Buffer is NULL, then ASSERT().
1393 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1394 Function and Register.
1395 @param Size Size in bytes of the transfer.
1396 @param Buffer Pointer to a buffer containing the data to write.
1398 @return The parameter of Size.
1403 PciSegmentWriteBuffer (
1404 IN UINT64 StartAddress
,
1411 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1412 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1418 ASSERT (Buffer
!= NULL
);
1421 // Save Size for return
1425 if ((StartAddress
& BIT0
) != 0) {
1427 // Write a byte if StartAddress is byte aligned
1429 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1430 StartAddress
+= sizeof (UINT8
);
1431 Size
-= sizeof (UINT8
);
1432 Buffer
= (UINT8
*)Buffer
+ 1;
1435 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1437 // Write a word if StartAddress is word aligned
1439 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1440 StartAddress
+= sizeof (UINT16
);
1441 Size
-= sizeof (UINT16
);
1442 Buffer
= (UINT16
*)Buffer
+ 1;
1445 while (Size
>= sizeof (UINT32
)) {
1447 // Write as many double words as possible
1449 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1450 StartAddress
+= sizeof (UINT32
);
1451 Size
-= sizeof (UINT32
);
1452 Buffer
= (UINT32
*)Buffer
+ 1;
1455 if (Size
>= sizeof (UINT16
)) {
1457 // Write the last remaining word if exist
1459 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1460 StartAddress
+= sizeof (UINT16
);
1461 Size
-= sizeof (UINT16
);
1462 Buffer
= (UINT16
*)Buffer
+ 1;
1465 if (Size
>= sizeof (UINT8
)) {
1467 // Write the last remaining byte if exist
1469 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);