2 Functions accessing PCI configuration registers on any supported PCI segment
4 Copyright (c) 2007 - 2008, 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 varible to record data of PCI Root Bridge I/O Protcol instances
21 PCI_ROOT_BRIDGE_DATA
*mPciRootBridgeData
= NULL
;
22 UINTN mNumberOfPciRootBridges
= 0;
25 The constructor function caches data of PCI Root Bridge I/O Protcol 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 Status
= gBS
->FreePool(HandleBuffer
);
100 ASSERT_EFI_ERROR (Status
);
106 The destructor function frees memory allocated by constructor.
108 The destructor function frees memory for data of protocol instances allocated by constructor.
109 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
111 @param ImageHandle The firmware allocated handle for the EFI image.
112 @param SystemTable A pointer to the EFI System Table.
114 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
119 PciSegmentLibDestructor (
120 IN EFI_HANDLE ImageHandle
,
121 IN EFI_SYSTEM_TABLE
*SystemTable
124 FreePool (mPciRootBridgeData
);
130 According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.
132 This internal function extracts segment number and bus number data from address, and
133 retrieves the corresponding PCI Root Bridge I/O Protocol instance.
135 @param Address Address that encodes the Segment, PCI Bus, Device, Function and
138 @return The address for PCI Root Bridge I/O Protocol.
141 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*
142 PciSegmentLibSearchForRootBridge (
147 UINT64 SegmentNumber
;
150 for (Index
= 0; Index
< mNumberOfPciRootBridges
; Index
++) {
152 // Matches segment number of address with the segment number of protocol instance.
154 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
155 if (SegmentNumber
== mPciRootBridgeData
[Index
].SegmentNumber
) {
157 // Matches the bus number of address with bus number range of protocol instance.
159 BusNumber
= BitFieldRead64 (Address
, 20, 27);
160 if (BusNumber
>= mPciRootBridgeData
[Index
].MinBusNumber
&& BusNumber
<= mPciRootBridgeData
[Index
].MaxBusNumber
) {
161 return mPciRootBridgeData
[Index
].PciRootBridgeIo
;
169 Internal worker function to read a PCI configuration register.
171 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
172 It reads and returns the PCI configuration register specified by Address,
173 the width of data is specified by Width.
175 @param Address Address that encodes the PCI Bus, Device, Function and
177 @param Width Width of data to read
179 @return The value read from the PCI configuration register.
183 DxePciSegmentLibPciRootBridgeIoReadWorker (
185 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
189 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
191 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
192 ASSERT (PciRootBridgeIo
!= NULL
);
194 PciRootBridgeIo
->Pci
.Read (
197 PCI_TO_PCICFG2_ADDRESS (Address
),
206 Internal worker function to writes a PCI configuration register.
208 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
209 It writes the PCI configuration register specified by Address with the
210 value specified by Data. The width of data is specifed by Width.
213 @param Address Address that encodes the PCI Bus, Device, Function and
215 @param Width Width of data to write
216 @param Data The value to write.
218 @return The value written to the PCI configuration register.
222 DxePciSegmentLibPciRootBridgeIoWriteWorker (
224 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
228 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
230 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
231 ASSERT (PciRootBridgeIo
!= NULL
);
233 PciRootBridgeIo
->Pci
.Write (
236 PCI_TO_PCICFG2_ADDRESS (Address
),
245 Reads an 8-bit PCI configuration register.
247 Reads and returns the 8-bit PCI configuration register specified by Address.
248 This function must guarantee that all PCI read and write operations are
251 If any reserved bits in Address are set, then ASSERT().
253 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
256 @return The value read from the PCI configuration register.
265 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
267 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
271 Writes an 8-bit PCI configuration register.
273 Writes the 8-bit PCI configuration register specified by Address with the
274 value specified by Value. Value is returned. This function must guarantee
275 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
281 @param Data The value to write.
283 @return The value written to the PCI configuration register.
293 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
295 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Data
);
299 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
302 Reads the 8-bit PCI configuration register specified by Address, performs a
303 bitwise inclusive OR between the read result and the value specified by
304 OrData, and writes the result to the 8-bit PCI configuration register
305 specified by Address. The value written to the PCI configuration register is
306 returned. This function must guarantee that all PCI read and write operations
309 If any reserved bits in Address are set, then ASSERT().
311 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
313 @param OrData The value to OR with the PCI configuration register.
315 @return The value written back to the PCI configuration register.
325 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
329 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
332 Reads the 8-bit PCI configuration register specified by Address, performs a
333 bitwise AND between the read result and the value specified by AndData, and
334 writes the result to the 8-bit PCI configuration register specified by
335 Address. The value written to the PCI configuration register is returned.
336 This function must guarantee that all PCI read and write operations are
339 If any reserved bits in Address are set, then ASSERT().
341 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
343 @param AndData The value to AND with the PCI configuration register.
345 @return The value written back to the PCI configuration register.
355 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
359 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
360 value, followed a bitwise inclusive OR with another 8-bit value.
362 Reads the 8-bit PCI configuration register specified by Address, performs a
363 bitwise AND between the read result and the value specified by AndData,
364 performs a bitwise inclusive OR between the result of the AND operation and
365 the value specified by OrData, and writes the result to the 8-bit PCI
366 configuration register specified by Address. The value written to the PCI
367 configuration register is returned. This function must guarantee that all PCI
368 read and write operations are serialized.
370 If any reserved bits in Address are set, then ASSERT().
372 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
374 @param AndData The value to AND with the PCI configuration register.
375 @param OrData The value to OR with the result of the AND operation.
377 @return The value written back to the PCI configuration register.
382 PciSegmentAndThenOr8 (
388 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
392 Reads a bit field of a PCI configuration register.
394 Reads the bit field in an 8-bit PCI configuration register. The bit field is
395 specified by the StartBit and the EndBit. The value of the bit field is
398 If any reserved bits in Address are set, then ASSERT().
399 If StartBit is greater than 7, then ASSERT().
400 If EndBit is greater than 7, then ASSERT().
401 If EndBit is less than StartBit, then ASSERT().
403 @param Address PCI configuration register to read.
404 @param StartBit The ordinal of the least significant bit in the bit field.
406 @param EndBit The ordinal of the most significant bit in the bit field.
409 @return The value of the bit field read from the PCI configuration register.
414 PciSegmentBitFieldRead8 (
420 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
424 Writes a bit field to a PCI configuration register.
426 Writes Value to the bit field of the PCI configuration register. The bit
427 field is specified by the StartBit and the EndBit. All other bits in the
428 destination PCI configuration register are preserved. The new value of the
429 8-bit register is returned.
431 If any reserved bits in Address are set, then ASSERT().
432 If StartBit is greater than 7, then ASSERT().
433 If EndBit is greater than 7, then ASSERT().
434 If EndBit is less than StartBit, then ASSERT().
436 @param Address PCI configuration register to write.
437 @param StartBit The ordinal of the least significant bit in the bit field.
439 @param EndBit The ordinal of the most significant bit in the bit field.
441 @param Value New value of the bit field.
443 @return The value written back to the PCI configuration register.
448 PciSegmentBitFieldWrite8 (
455 return PciSegmentWrite8 (
457 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
462 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
463 writes the result back to the bit field in the 8-bit port.
465 Reads the 8-bit PCI configuration register specified by Address, performs a
466 bitwise inclusive OR between the read result and the value specified by
467 OrData, and writes the result to the 8-bit PCI configuration register
468 specified by Address. The value written to the PCI configuration register is
469 returned. This function must guarantee that all PCI read and write operations
470 are serialized. Extra left bits in OrData are stripped.
472 If any reserved bits in Address are set, then ASSERT().
473 If StartBit is greater than 7, then ASSERT().
474 If EndBit is greater than 7, then ASSERT().
475 If EndBit is less than StartBit, then ASSERT().
477 @param Address PCI configuration register to write.
478 @param StartBit The ordinal of the least significant bit in the bit field.
480 @param EndBit The ordinal of the most significant bit in the bit field.
482 @param OrData The value to OR with the PCI configuration register.
484 @return The value written back to the PCI configuration register.
489 PciSegmentBitFieldOr8 (
496 return PciSegmentWrite8 (
498 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
503 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
504 AND, and writes the result back to the bit field in the 8-bit register.
506 Reads the 8-bit PCI configuration register specified by Address, performs a
507 bitwise AND between the read result and the value specified by AndData, and
508 writes the result to the 8-bit PCI configuration register specified by
509 Address. The value written to the PCI configuration register is returned.
510 This function must guarantee that all PCI read and write operations are
511 serialized. Extra left bits in AndData are stripped.
513 If any reserved bits in Address are set, then ASSERT().
514 If StartBit is greater than 7, then ASSERT().
515 If EndBit is greater than 7, then ASSERT().
516 If EndBit is less than StartBit, then ASSERT().
518 @param Address PCI configuration register to write.
519 @param StartBit The ordinal of the least significant bit in the bit field.
521 @param EndBit The ordinal of the most significant bit in the bit field.
523 @param AndData The value to AND with the PCI configuration register.
525 @return The value written back to the PCI configuration register.
530 PciSegmentBitFieldAnd8 (
537 return PciSegmentWrite8 (
539 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
544 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
545 bitwise inclusive OR, and writes the result back to the bit field in the
548 Reads the 8-bit PCI configuration register specified by Address, performs a
549 bitwise AND followed by a bitwise inclusive OR between the read result and
550 the value specified by AndData, and writes the result to the 8-bit PCI
551 configuration register specified by Address. The value written to the PCI
552 configuration register is returned. This function must guarantee that all PCI
553 read and write operations are serialized. Extra left bits in both AndData and
556 If any reserved bits in Address are set, then ASSERT().
557 If StartBit is greater than 7, then ASSERT().
558 If EndBit is greater than 7, then ASSERT().
559 If EndBit is less than StartBit, then ASSERT().
561 @param Address PCI configuration register to write.
562 @param StartBit The ordinal of the least significant bit in the bit field.
564 @param EndBit The ordinal of the most significant bit in the bit field.
566 @param AndData The value to AND with the PCI configuration register.
567 @param OrData The value to OR with the result of the AND operation.
569 @return The value written back to the PCI configuration register.
574 PciSegmentBitFieldAndThenOr8 (
582 return PciSegmentWrite8 (
584 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
589 Reads a 16-bit PCI configuration register.
591 Reads and returns the 16-bit PCI configuration register specified by Address.
592 This function must guarantee that all PCI read and write operations are
595 If any reserved bits in Address are set, then ASSERT().
597 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
600 @return The value read from the PCI configuration register.
609 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
611 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
615 Writes a 16-bit PCI configuration register.
617 Writes the 16-bit PCI configuration register specified by Address with the
618 value specified by Value. Value is returned. This function must guarantee
619 that all PCI read and write operations are serialized.
621 If any reserved bits in Address are set, then ASSERT().
623 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
625 @param Data The value to write.
627 @return The value written to the PCI configuration register.
637 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
639 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Data
);
643 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
646 Reads the 16-bit PCI configuration register specified by Address, performs a
647 bitwise inclusive OR between the read result and the value specified by
648 OrData, and writes the result to the 16-bit PCI configuration register
649 specified by Address. The value written to the PCI configuration register is
650 returned. This function must guarantee that all PCI read and write operations
653 If any reserved bits in Address are set, then ASSERT().
655 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
657 @param OrData The value to OR with the PCI configuration register.
659 @return The value written back to the PCI configuration register.
669 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
673 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
676 Reads the 16-bit PCI configuration register specified by Address, performs a
677 bitwise AND between the read result and the value specified by AndData, and
678 writes the result to the 16-bit PCI configuration register specified by
679 Address. The value written to the PCI configuration register is returned.
680 This function must guarantee that all PCI read and write operations are
683 If any reserved bits in Address are set, then ASSERT().
685 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
687 @param AndData The value to AND with the PCI configuration register.
689 @return The value written back to the PCI configuration register.
699 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
703 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
704 value, followed a bitwise inclusive OR with another 16-bit value.
706 Reads the 16-bit PCI configuration register specified by Address, performs a
707 bitwise AND between the read result and the value specified by AndData,
708 performs a bitwise inclusive OR between the result of the AND operation and
709 the value specified by OrData, and writes the result to the 16-bit PCI
710 configuration register specified by Address. The value written to the PCI
711 configuration register is returned. This function must guarantee that all PCI
712 read and write operations are serialized.
714 If any reserved bits in Address are set, then ASSERT().
716 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
718 @param AndData The value to AND with the PCI configuration register.
719 @param OrData The value to OR with the result of the AND operation.
721 @return The value written back to the PCI configuration register.
726 PciSegmentAndThenOr16 (
732 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
736 Reads a bit field of a PCI configuration register.
738 Reads the bit field in a 16-bit PCI configuration register. The bit field is
739 specified by the StartBit and the EndBit. The value of the bit field is
742 If any reserved bits in Address are set, then ASSERT().
743 If StartBit is greater than 15, then ASSERT().
744 If EndBit is greater than 15, then ASSERT().
745 If EndBit is less than StartBit, then ASSERT().
747 @param Address PCI configuration register to read.
748 @param StartBit The ordinal of the least significant bit in the bit field.
750 @param EndBit The ordinal of the most significant bit in the bit field.
753 @return The value of the bit field read from the PCI configuration register.
758 PciSegmentBitFieldRead16 (
764 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
768 Writes a bit field to a PCI configuration register.
770 Writes Value to the bit field of the PCI configuration register. The bit
771 field is specified by the StartBit and the EndBit. All other bits in the
772 destination PCI configuration register are preserved. The new value of the
773 16-bit register is returned.
775 If any reserved bits in Address are set, then ASSERT().
776 If StartBit is greater than 15, then ASSERT().
777 If EndBit is greater than 15, then ASSERT().
778 If EndBit is less than StartBit, then ASSERT().
780 @param Address PCI configuration register to write.
781 @param StartBit The ordinal of the least significant bit in the bit field.
783 @param EndBit The ordinal of the most significant bit in the bit field.
785 @param Value New value of the bit field.
787 @return The value written back to the PCI configuration register.
792 PciSegmentBitFieldWrite16 (
799 return PciSegmentWrite16 (
801 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
806 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
807 writes the result back to the bit field in the 16-bit port.
809 Reads the 16-bit PCI configuration register specified by Address, performs a
810 bitwise inclusive OR between the read result and the value specified by
811 OrData, and writes the result to the 16-bit PCI configuration register
812 specified by Address. The value written to the PCI configuration register is
813 returned. This function must guarantee that all PCI read and write operations
814 are serialized. Extra left bits in OrData are stripped.
816 If any reserved bits in Address are set, then ASSERT().
817 If StartBit is greater than 15, then ASSERT().
818 If EndBit is greater than 15, then ASSERT().
819 If EndBit is less than StartBit, then ASSERT().
821 @param Address PCI configuration register to write.
822 @param StartBit The ordinal of the least significant bit in the bit field.
824 @param EndBit The ordinal of the most significant bit in the bit field.
826 @param OrData The value to OR with the PCI configuration register.
828 @return The value written back to the PCI configuration register.
833 PciSegmentBitFieldOr16 (
840 return PciSegmentWrite16 (
842 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
847 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
848 AND, and writes the result back to the bit field in the 16-bit register.
850 Reads the 16-bit PCI configuration register specified by Address, performs a
851 bitwise AND between the read result and the value specified by AndData, and
852 writes the result to the 16-bit PCI configuration register specified by
853 Address. The value written to the PCI configuration register is returned.
854 This function must guarantee that all PCI read and write operations are
855 serialized. Extra left bits in AndData are stripped.
857 If any reserved bits in Address are set, then ASSERT().
858 If StartBit is greater than 15, then ASSERT().
859 If EndBit is greater than 15, then ASSERT().
860 If EndBit is less than StartBit, then ASSERT().
862 @param Address PCI configuration register to write.
863 @param StartBit The ordinal of the least significant bit in the bit field.
865 @param EndBit The ordinal of the most significant bit in the bit field.
867 @param AndData The value to AND with the PCI configuration register.
869 @return The value written back to the PCI configuration register.
874 PciSegmentBitFieldAnd16 (
881 return PciSegmentWrite16 (
883 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
888 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
889 bitwise inclusive OR, and writes the result back to the bit field in the
892 Reads the 16-bit PCI configuration register specified by Address, performs a
893 bitwise AND followed by a bitwise inclusive OR between the read result and
894 the value specified by AndData, and writes the result to the 16-bit PCI
895 configuration register specified by Address. The value written to the PCI
896 configuration register is returned. This function must guarantee that all PCI
897 read and write operations are serialized. Extra left bits in both AndData and
900 If any reserved bits in Address are set, then ASSERT().
901 If StartBit is greater than 15, then ASSERT().
902 If EndBit is greater than 15, then ASSERT().
903 If EndBit is less than StartBit, then ASSERT().
905 @param Address PCI configuration register to write.
906 @param StartBit The ordinal of the least significant bit in the bit field.
908 @param EndBit The ordinal of the most significant bit in the bit field.
910 @param AndData The value to AND with the PCI configuration register.
911 @param OrData The value to OR with the result of the AND operation.
913 @return The value written back to the PCI configuration register.
918 PciSegmentBitFieldAndThenOr16 (
926 return PciSegmentWrite16 (
928 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
933 Reads a 32-bit PCI configuration register.
935 Reads and returns the 32-bit PCI configuration register specified by Address.
936 This function must guarantee that all PCI read and write operations are
939 If any reserved bits in Address are set, then ASSERT().
941 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
944 @return The value read from the PCI configuration register.
953 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
955 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
959 Writes a 32-bit PCI configuration register.
961 Writes the 32-bit PCI configuration register specified by Address with the
962 value specified by Value. Value is returned. This function must guarantee
963 that all PCI read and write operations are serialized.
965 If any reserved bits in Address are set, then ASSERT().
967 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
969 @param Data The value to write.
971 @return The value written to the PCI configuration register.
981 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
983 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Data
);
987 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
990 Reads the 32-bit PCI configuration register specified by Address, performs a
991 bitwise inclusive OR between the read result and the value specified by
992 OrData, and writes the result to the 32-bit PCI configuration register
993 specified by Address. The value written to the PCI configuration register is
994 returned. This function must guarantee that all PCI read and write operations
997 If any reserved bits in Address are set, then ASSERT().
999 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1001 @param OrData The value to OR with the PCI configuration register.
1003 @return The value written back to the PCI configuration register.
1013 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1017 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1020 Reads the 32-bit PCI configuration register specified by Address, performs a
1021 bitwise AND between the read result and the value specified by AndData, and
1022 writes the result to the 32-bit PCI configuration register specified by
1023 Address. The value written to the PCI configuration register is returned.
1024 This function must guarantee that all PCI read and write operations are
1027 If any reserved bits in Address are set, then ASSERT().
1029 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1031 @param AndData The value to AND with the PCI configuration register.
1033 @return The value written back to the PCI configuration register.
1043 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1047 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1048 value, followed a bitwise inclusive OR with another 32-bit value.
1050 Reads the 32-bit PCI configuration register specified by Address, performs a
1051 bitwise AND between the read result and the value specified by AndData,
1052 performs a bitwise inclusive OR between the result of the AND operation and
1053 the value specified by OrData, and writes the result to the 32-bit PCI
1054 configuration register specified by Address. The value written to the PCI
1055 configuration register is returned. This function must guarantee that all PCI
1056 read and write operations are serialized.
1058 If any reserved bits in Address are set, then ASSERT().
1060 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1062 @param AndData The value to AND with the PCI configuration register.
1063 @param OrData The value to OR with the result of the AND operation.
1065 @return The value written back to the PCI configuration register.
1070 PciSegmentAndThenOr32 (
1076 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1080 Reads a bit field of a PCI configuration register.
1082 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1083 specified by the StartBit and the EndBit. The value of the bit field is
1086 If any reserved bits in Address are set, then ASSERT().
1087 If StartBit is greater than 31, then ASSERT().
1088 If EndBit is greater than 31, then ASSERT().
1089 If EndBit is less than StartBit, then ASSERT().
1091 @param Address PCI configuration register to read.
1092 @param StartBit The ordinal of the least significant bit in the bit field.
1094 @param EndBit The ordinal of the most significant bit in the bit field.
1097 @return The value of the bit field read from the PCI configuration register.
1102 PciSegmentBitFieldRead32 (
1108 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1112 Writes a bit field to a PCI configuration register.
1114 Writes Value to the bit field of the PCI configuration register. The bit
1115 field is specified by the StartBit and the EndBit. All other bits in the
1116 destination PCI configuration register are preserved. The new value of the
1117 32-bit register is returned.
1119 If any reserved bits in Address are set, then ASSERT().
1120 If StartBit is greater than 31, then ASSERT().
1121 If EndBit is greater than 31, then ASSERT().
1122 If EndBit is less than StartBit, then ASSERT().
1124 @param Address PCI configuration register to write.
1125 @param StartBit The ordinal of the least significant bit in the bit field.
1127 @param EndBit The ordinal of the most significant bit in the bit field.
1129 @param Value New value of the bit field.
1131 @return The value written back to the PCI configuration register.
1136 PciSegmentBitFieldWrite32 (
1143 return PciSegmentWrite32 (
1145 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1150 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1151 writes the result back to the bit field in the 32-bit port.
1153 Reads the 32-bit PCI configuration register specified by Address, performs a
1154 bitwise inclusive OR between the read result and the value specified by
1155 OrData, and writes the result to the 32-bit PCI configuration register
1156 specified by Address. The value written to the PCI configuration register is
1157 returned. This function must guarantee that all PCI read and write operations
1158 are serialized. Extra left bits in OrData are stripped.
1160 If any reserved bits in Address are set, then ASSERT().
1161 If StartBit is greater than 31, then ASSERT().
1162 If EndBit is greater than 31, then ASSERT().
1163 If EndBit is less than StartBit, then ASSERT().
1165 @param Address PCI configuration register to write.
1166 @param StartBit The ordinal of the least significant bit in the bit field.
1168 @param EndBit The ordinal of the most significant bit in the bit field.
1170 @param OrData The value to OR with the PCI configuration register.
1172 @return The value written back to the PCI configuration register.
1177 PciSegmentBitFieldOr32 (
1184 return PciSegmentWrite32 (
1186 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1191 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1192 AND, and writes the result back to the bit field in the 32-bit register.
1194 Reads the 32-bit PCI configuration register specified by Address, performs a
1195 bitwise AND between the read result and the value specified by AndData, and
1196 writes the result to the 32-bit PCI configuration register specified by
1197 Address. The value written to the PCI configuration register is returned.
1198 This function must guarantee that all PCI read and write operations are
1199 serialized. Extra left bits in AndData are stripped.
1201 If any reserved bits in Address are set, then ASSERT().
1202 If StartBit is greater than 31, then ASSERT().
1203 If EndBit is greater than 31, then ASSERT().
1204 If EndBit is less than StartBit, then ASSERT().
1206 @param Address PCI configuration register to write.
1207 @param StartBit The ordinal of the least significant bit in the bit field.
1209 @param EndBit The ordinal of the most significant bit in the bit field.
1211 @param AndData The value to AND with the PCI configuration register.
1213 @return The value written back to the PCI configuration register.
1218 PciSegmentBitFieldAnd32 (
1225 return PciSegmentWrite32 (
1227 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1232 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1233 bitwise inclusive OR, and writes the result back to the bit field in the
1236 Reads the 32-bit PCI configuration register specified by Address, performs a
1237 bitwise AND followed by a bitwise inclusive OR between the read result and
1238 the value specified by AndData, and writes the result to the 32-bit PCI
1239 configuration register specified by Address. The value written to the PCI
1240 configuration register is returned. This function must guarantee that all PCI
1241 read and write operations are serialized. Extra left bits in both AndData and
1242 OrData are stripped.
1244 If any reserved bits in Address are set, then ASSERT().
1245 If StartBit is greater than 31, then ASSERT().
1246 If EndBit is greater than 31, then ASSERT().
1247 If EndBit is less than StartBit, then ASSERT().
1249 @param Address PCI configuration register to write.
1250 @param StartBit The ordinal of the least significant bit in the bit field.
1252 @param EndBit The ordinal of the most significant bit in the bit field.
1254 @param AndData The value to AND with the PCI configuration register.
1255 @param OrData The value to OR with the result of the AND operation.
1257 @return The value written back to the PCI configuration register.
1262 PciSegmentBitFieldAndThenOr32 (
1270 return PciSegmentWrite32 (
1272 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1277 Reads a range of PCI configuration registers into a caller supplied buffer.
1279 Reads the range of PCI configuration registers specified by StartAddress and
1280 Size into the buffer specified by Buffer. This function only allows the PCI
1281 configuration registers from a single PCI function to be read. Size is
1282 returned. When possible 32-bit PCI configuration read cycles are used to read
1283 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1284 and 16-bit PCI configuration read cycles may be used at the beginning and the
1287 If StartAddress > 0x0FFFFFFF, then ASSERT().
1288 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1289 If Size > 0 and Buffer is NULL, then ASSERT().
1291 @param StartAddress Starting Address that encodes the PCI Segment, Bus, Device,
1292 Function and Register.
1293 @param Size Size in bytes of the transfer.
1294 @param Buffer Pointer to a buffer receiving the data read.
1301 PciSegmentReadBuffer (
1302 IN UINT64 StartAddress
,
1309 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1310 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1316 ASSERT (Buffer
!= NULL
);
1319 // Save Size for return
1323 if ((StartAddress
& 1) != 0) {
1325 // Read a byte if StartAddress is byte aligned
1327 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1328 StartAddress
+= sizeof (UINT8
);
1329 Size
-= sizeof (UINT8
);
1330 Buffer
= (UINT8
*)Buffer
+ 1;
1333 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1335 // Read a word if StartAddress is word aligned
1337 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1338 StartAddress
+= sizeof (UINT16
);
1339 Size
-= sizeof (UINT16
);
1340 Buffer
= (UINT16
*)Buffer
+ 1;
1343 while (Size
>= sizeof (UINT32
)) {
1345 // Read as many double words as possible
1347 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1348 StartAddress
+= sizeof (UINT32
);
1349 Size
-= sizeof (UINT32
);
1350 Buffer
= (UINT32
*)Buffer
+ 1;
1353 if (Size
>= sizeof (UINT16
)) {
1355 // Read the last remaining word if exist
1357 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1358 StartAddress
+= sizeof (UINT16
);
1359 Size
-= sizeof (UINT16
);
1360 Buffer
= (UINT16
*)Buffer
+ 1;
1363 if (Size
>= sizeof (UINT8
)) {
1365 // Read the last remaining byte if exist
1367 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1374 Copies the data in a caller supplied buffer to a specified range of PCI
1375 configuration space.
1377 Writes the range of PCI configuration registers specified by StartAddress and
1378 Size from the buffer specified by Buffer. This function only allows the PCI
1379 configuration registers from a single PCI function to be written. Size is
1380 returned. When possible 32-bit PCI configuration write cycles are used to
1381 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1382 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1383 and the end of the range.
1385 If StartAddress > 0x0FFFFFFF, then ASSERT().
1386 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1387 If Size > 0 and Buffer is NULL, then ASSERT().
1389 @param StartAddress Starting Address that encodes the PCI Segment, Bus, Device,
1390 Function and Register.
1391 @param Size Size in bytes of the transfer.
1392 @param Buffer Pointer to a buffer containing the data to write.
1399 PciSegmentWriteBuffer (
1400 IN UINT64 StartAddress
,
1407 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1408 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1414 ASSERT (Buffer
!= NULL
);
1417 // Save Size for return
1421 if ((StartAddress
& 1) != 0) {
1423 // Write a byte if StartAddress is byte aligned
1425 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1426 StartAddress
+= sizeof (UINT8
);
1427 Size
-= sizeof (UINT8
);
1428 Buffer
= (UINT8
*)Buffer
+ 1;
1431 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1433 // Write a word if StartAddress is word aligned
1435 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1436 StartAddress
+= sizeof (UINT16
);
1437 Size
-= sizeof (UINT16
);
1438 Buffer
= (UINT16
*)Buffer
+ 1;
1441 while (Size
>= sizeof (UINT32
)) {
1443 // Write as many double words as possible
1445 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1446 StartAddress
+= sizeof (UINT32
);
1447 Size
-= sizeof (UINT32
);
1448 Buffer
= (UINT32
*)Buffer
+ 1;
1451 if (Size
>= sizeof (UINT16
)) {
1453 // Write the last remaining word if exist
1455 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1456 StartAddress
+= sizeof (UINT16
);
1457 Size
-= sizeof (UINT16
);
1458 Buffer
= (UINT16
*)Buffer
+ 1;
1461 if (Size
>= sizeof (UINT8
)) {
1463 // Write the last remaining byte if exist
1465 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);