2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.
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 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 Reads an 8-bit PCI configuration register.
246 Reads and returns the 8-bit PCI configuration register specified by Address.
247 This function must guarantee that all PCI read and write operations are
250 If any reserved bits in Address are set, then ASSERT().
252 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
255 @return The value read from the PCI configuration register.
264 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
266 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
270 Writes an 8-bit PCI configuration register.
272 Writes the 8-bit PCI configuration register specified by Address with the
273 value specified by Value. Value is returned. This function must guarantee
274 that all PCI read and write operations are serialized.
276 If any reserved bits in Address are set, then ASSERT().
278 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
280 @param Data The value to write.
282 @return The value written to the PCI configuration register.
292 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
294 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Data
);
298 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
301 Reads the 8-bit PCI configuration register specified by Address, performs a
302 bitwise inclusive OR between the read result and the value specified by
303 OrData, and writes the result to the 8-bit PCI configuration register
304 specified by Address. The value written to the PCI configuration register is
305 returned. This function must guarantee that all PCI read and write operations
308 If any reserved bits in Address are set, then ASSERT().
310 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
312 @param OrData The value to OR with the PCI configuration register.
314 @return The value written back to the PCI configuration register.
324 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
328 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
331 Reads the 8-bit PCI configuration register specified by Address, performs a
332 bitwise AND between the read result and the value specified by AndData, and
333 writes the result to the 8-bit PCI configuration register specified by
334 Address. The value written to the PCI configuration register is returned.
335 This function must guarantee that all PCI read and write operations are
338 If any reserved bits in Address are set, then ASSERT().
340 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
342 @param AndData The value to AND with the PCI configuration register.
344 @return The value written back to the PCI configuration register.
354 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
358 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
359 value, followed a bitwise inclusive OR with another 8-bit value.
361 Reads the 8-bit PCI configuration register specified by Address, performs a
362 bitwise AND between the read result and the value specified by AndData,
363 performs a bitwise inclusive OR between the result of the AND operation and
364 the value specified by OrData, and writes the result to the 8-bit PCI
365 configuration register specified by Address. The value written to the PCI
366 configuration register is returned. This function must guarantee that all PCI
367 read and write operations are serialized.
369 If any reserved bits in Address are set, then ASSERT().
371 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
373 @param AndData The value to AND with the PCI configuration register.
374 @param OrData The value to OR with the result of the AND operation.
376 @return The value written back to the PCI configuration register.
381 PciSegmentAndThenOr8 (
387 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
391 Reads a bit field of a PCI configuration register.
393 Reads the bit field in an 8-bit PCI configuration register. The bit field is
394 specified by the StartBit and the EndBit. The value of the bit field is
397 If any reserved bits in Address are set, then ASSERT().
398 If StartBit is greater than 7, then ASSERT().
399 If EndBit is greater than 7, then ASSERT().
400 If EndBit is less than StartBit, then ASSERT().
402 @param Address PCI configuration register to read.
403 @param StartBit The ordinal of the least significant bit in the bit field.
405 @param EndBit The ordinal of the most significant bit in the bit field.
408 @return The value of the bit field read from the PCI configuration register.
413 PciSegmentBitFieldRead8 (
419 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
423 Writes a bit field to a PCI configuration register.
425 Writes Value to the bit field of the PCI configuration register. The bit
426 field is specified by the StartBit and the EndBit. All other bits in the
427 destination PCI configuration register are preserved. The new value of the
428 8-bit register is returned.
430 If any reserved bits in Address are set, then ASSERT().
431 If StartBit is greater than 7, then ASSERT().
432 If EndBit is greater than 7, then ASSERT().
433 If EndBit is less than StartBit, then ASSERT().
435 @param Address PCI configuration register to write.
436 @param StartBit The ordinal of the least significant bit in the bit field.
438 @param EndBit The ordinal of the most significant bit in the bit field.
440 @param Value New value of the bit field.
442 @return The value written back to the PCI configuration register.
447 PciSegmentBitFieldWrite8 (
454 return PciSegmentWrite8 (
456 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
461 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
462 writes the result back to the bit field in the 8-bit port.
464 Reads the 8-bit PCI configuration register specified by Address, performs a
465 bitwise inclusive OR between the read result and the value specified by
466 OrData, and writes the result to the 8-bit PCI configuration register
467 specified by Address. The value written to the PCI configuration register is
468 returned. This function must guarantee that all PCI read and write operations
469 are serialized. Extra left bits in OrData are stripped.
471 If any reserved bits in Address are set, then ASSERT().
472 If StartBit is greater than 7, then ASSERT().
473 If EndBit is greater than 7, then ASSERT().
474 If EndBit is less than StartBit, then ASSERT().
476 @param Address PCI configuration register to write.
477 @param StartBit The ordinal of the least significant bit in the bit field.
479 @param EndBit The ordinal of the most significant bit in the bit field.
481 @param OrData The value to OR with the PCI configuration register.
483 @return The value written back to the PCI configuration register.
488 PciSegmentBitFieldOr8 (
495 return PciSegmentWrite8 (
497 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
502 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
503 AND, and writes the result back to the bit field in the 8-bit register.
505 Reads the 8-bit PCI configuration register specified by Address, performs a
506 bitwise AND between the read result and the value specified by AndData, and
507 writes the result to the 8-bit PCI configuration register specified by
508 Address. The value written to the PCI configuration register is returned.
509 This function must guarantee that all PCI read and write operations are
510 serialized. Extra left bits in AndData are stripped.
512 If any reserved bits in Address are set, then ASSERT().
513 If StartBit is greater than 7, then ASSERT().
514 If EndBit is greater than 7, then ASSERT().
515 If EndBit is less than StartBit, then ASSERT().
517 @param Address PCI configuration register to write.
518 @param StartBit The ordinal of the least significant bit in the bit field.
520 @param EndBit The ordinal of the most significant bit in the bit field.
522 @param AndData The value to AND with the PCI configuration register.
524 @return The value written back to the PCI configuration register.
529 PciSegmentBitFieldAnd8 (
536 return PciSegmentWrite8 (
538 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
543 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
544 bitwise inclusive OR, and writes the result back to the bit field in the
547 Reads the 8-bit PCI configuration register specified by Address, performs a
548 bitwise AND followed by a bitwise inclusive OR between the read result and
549 the value specified by AndData, and writes the result to the 8-bit PCI
550 configuration register specified by Address. The value written to the PCI
551 configuration register is returned. This function must guarantee that all PCI
552 read and write operations are serialized. Extra left bits in both AndData and
555 If any reserved bits in Address are set, then ASSERT().
556 If StartBit is greater than 7, then ASSERT().
557 If EndBit is greater than 7, then ASSERT().
558 If EndBit is less than StartBit, then ASSERT().
560 @param Address PCI configuration register to write.
561 @param StartBit The ordinal of the least significant bit in the bit field.
563 @param EndBit The ordinal of the most significant bit in the bit field.
565 @param AndData The value to AND with the PCI configuration register.
566 @param OrData The value to OR with the result of the AND operation.
568 @return The value written back to the PCI configuration register.
573 PciSegmentBitFieldAndThenOr8 (
581 return PciSegmentWrite8 (
583 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
588 Reads a 16-bit PCI configuration register.
590 Reads and returns the 16-bit PCI configuration register specified by Address.
591 This function must guarantee that all PCI read and write operations are
594 If any reserved bits in Address are set, then ASSERT().
596 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
599 @return The value read from the PCI configuration register.
608 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
610 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
614 Writes a 16-bit PCI configuration register.
616 Writes the 16-bit PCI configuration register specified by Address with the
617 value specified by Value. Value is returned. This function must guarantee
618 that all PCI read and write operations are serialized.
620 If any reserved bits in Address are set, then ASSERT().
622 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
624 @param Data The value to write.
626 @return The value written to the PCI configuration register.
636 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
638 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Data
);
642 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
645 Reads the 16-bit PCI configuration register specified by Address, performs a
646 bitwise inclusive OR between the read result and the value specified by
647 OrData, and writes the result to the 16-bit PCI configuration register
648 specified by Address. The value written to the PCI configuration register is
649 returned. This function must guarantee that all PCI read and write operations
652 If any reserved bits in Address are set, then ASSERT().
654 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
656 @param OrData The value to OR with the PCI configuration register.
658 @return The value written back to the PCI configuration register.
668 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
672 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
675 Reads the 16-bit PCI configuration register specified by Address, performs a
676 bitwise AND between the read result and the value specified by AndData, and
677 writes the result to the 16-bit PCI configuration register specified by
678 Address. The value written to the PCI configuration register is returned.
679 This function must guarantee that all PCI read and write operations are
682 If any reserved bits in Address are set, then ASSERT().
684 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
686 @param AndData The value to AND with the PCI configuration register.
688 @return The value written back to the PCI configuration register.
698 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
702 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
703 value, followed a bitwise inclusive OR with another 16-bit value.
705 Reads the 16-bit PCI configuration register specified by Address, performs a
706 bitwise AND between the read result and the value specified by AndData,
707 performs a bitwise inclusive OR between the result of the AND operation and
708 the value specified by OrData, and writes the result to the 16-bit PCI
709 configuration register specified by Address. The value written to the PCI
710 configuration register is returned. This function must guarantee that all PCI
711 read and write operations are serialized.
713 If any reserved bits in Address are set, then ASSERT().
715 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
717 @param AndData The value to AND with the PCI configuration register.
718 @param OrData The value to OR with the result of the AND operation.
720 @return The value written back to the PCI configuration register.
725 PciSegmentAndThenOr16 (
731 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
735 Reads a bit field of a PCI configuration register.
737 Reads the bit field in a 16-bit PCI configuration register. The bit field is
738 specified by the StartBit and the EndBit. The value of the bit field is
741 If any reserved bits in Address are set, then ASSERT().
742 If StartBit is greater than 15, then ASSERT().
743 If EndBit is greater than 15, then ASSERT().
744 If EndBit is less than StartBit, then ASSERT().
746 @param Address PCI configuration register to read.
747 @param StartBit The ordinal of the least significant bit in the bit field.
749 @param EndBit The ordinal of the most significant bit in the bit field.
752 @return The value of the bit field read from the PCI configuration register.
757 PciSegmentBitFieldRead16 (
763 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
767 Writes a bit field to a PCI configuration register.
769 Writes Value to the bit field of the PCI configuration register. The bit
770 field is specified by the StartBit and the EndBit. All other bits in the
771 destination PCI configuration register are preserved. The new value of the
772 16-bit register is returned.
774 If any reserved bits in Address are set, then ASSERT().
775 If StartBit is greater than 15, then ASSERT().
776 If EndBit is greater than 15, then ASSERT().
777 If EndBit is less than StartBit, then ASSERT().
779 @param Address PCI configuration register to write.
780 @param StartBit The ordinal of the least significant bit in the bit field.
782 @param EndBit The ordinal of the most significant bit in the bit field.
784 @param Value New value of the bit field.
786 @return The value written back to the PCI configuration register.
791 PciSegmentBitFieldWrite16 (
798 return PciSegmentWrite16 (
800 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
805 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
806 writes the result back to the bit field in the 16-bit port.
808 Reads the 16-bit PCI configuration register specified by Address, performs a
809 bitwise inclusive OR between the read result and the value specified by
810 OrData, and writes the result to the 16-bit PCI configuration register
811 specified by Address. The value written to the PCI configuration register is
812 returned. This function must guarantee that all PCI read and write operations
813 are serialized. Extra left bits in OrData are stripped.
815 If any reserved bits in Address are set, then ASSERT().
816 If StartBit is greater than 15, then ASSERT().
817 If EndBit is greater than 15, then ASSERT().
818 If EndBit is less than StartBit, then ASSERT().
820 @param Address PCI configuration register to write.
821 @param StartBit The ordinal of the least significant bit in the bit field.
823 @param EndBit The ordinal of the most significant bit in the bit field.
825 @param OrData The value to OR with the PCI configuration register.
827 @return The value written back to the PCI configuration register.
832 PciSegmentBitFieldOr16 (
839 return PciSegmentWrite16 (
841 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
846 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
847 AND, and writes the result back to the bit field in the 16-bit register.
849 Reads the 16-bit PCI configuration register specified by Address, performs a
850 bitwise AND between the read result and the value specified by AndData, and
851 writes the result to the 16-bit PCI configuration register specified by
852 Address. The value written to the PCI configuration register is returned.
853 This function must guarantee that all PCI read and write operations are
854 serialized. Extra left bits in AndData are stripped.
856 If any reserved bits in Address are set, then ASSERT().
857 If StartBit is greater than 15, then ASSERT().
858 If EndBit is greater than 15, then ASSERT().
859 If EndBit is less than StartBit, then ASSERT().
861 @param Address PCI configuration register to write.
862 @param StartBit The ordinal of the least significant bit in the bit field.
864 @param EndBit The ordinal of the most significant bit in the bit field.
866 @param AndData The value to AND with the PCI configuration register.
868 @return The value written back to the PCI configuration register.
873 PciSegmentBitFieldAnd16 (
880 return PciSegmentWrite16 (
882 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
887 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
888 bitwise inclusive OR, and writes the result back to the bit field in the
891 Reads the 16-bit PCI configuration register specified by Address, performs a
892 bitwise AND followed by a bitwise inclusive OR between the read result and
893 the value specified by AndData, and writes the result to the 16-bit PCI
894 configuration register specified by Address. The value written to the PCI
895 configuration register is returned. This function must guarantee that all PCI
896 read and write operations are serialized. Extra left bits in both AndData and
899 If any reserved bits in Address are set, then ASSERT().
900 If StartBit is greater than 15, then ASSERT().
901 If EndBit is greater than 15, then ASSERT().
902 If EndBit is less than StartBit, then ASSERT().
904 @param Address PCI configuration register to write.
905 @param StartBit The ordinal of the least significant bit in the bit field.
907 @param EndBit The ordinal of the most significant bit in the bit field.
909 @param AndData The value to AND with the PCI configuration register.
910 @param OrData The value to OR with the result of the AND operation.
912 @return The value written back to the PCI configuration register.
917 PciSegmentBitFieldAndThenOr16 (
925 return PciSegmentWrite16 (
927 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
932 Reads a 32-bit PCI configuration register.
934 Reads and returns the 32-bit PCI configuration register specified by Address.
935 This function must guarantee that all PCI read and write operations are
938 If any reserved bits in Address are set, then ASSERT().
940 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
943 @return The value read from the PCI configuration register.
952 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
954 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
958 Writes a 32-bit PCI configuration register.
960 Writes the 32-bit PCI configuration register specified by Address with the
961 value specified by Value. Value is returned. This function must guarantee
962 that all PCI read and write operations are serialized.
964 If any reserved bits in Address are set, then ASSERT().
966 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
968 @param Data The value to write.
970 @return The value written to the PCI configuration register.
980 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
982 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Data
);
986 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
989 Reads the 32-bit PCI configuration register specified by Address, performs a
990 bitwise inclusive OR between the read result and the value specified by
991 OrData, and writes the result to the 32-bit PCI configuration register
992 specified by Address. The value written to the PCI configuration register is
993 returned. This function must guarantee that all PCI read and write operations
996 If any reserved bits in Address are set, then ASSERT().
998 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1000 @param OrData The value to OR with the PCI configuration register.
1002 @return The value written back to the PCI configuration register.
1012 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1016 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1019 Reads the 32-bit PCI configuration register specified by Address, performs a
1020 bitwise AND between the read result and the value specified by AndData, and
1021 writes the result to the 32-bit PCI configuration register specified by
1022 Address. The value written to the PCI configuration register is returned.
1023 This function must guarantee that all PCI read and write operations are
1026 If any reserved bits in Address are set, then ASSERT().
1028 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1030 @param AndData The value to AND with the PCI configuration register.
1032 @return The value written back to the PCI configuration register.
1042 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1046 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1047 value, followed a bitwise inclusive OR with another 32-bit value.
1049 Reads the 32-bit PCI configuration register specified by Address, performs a
1050 bitwise AND between the read result and the value specified by AndData,
1051 performs a bitwise inclusive OR between the result of the AND operation and
1052 the value specified by OrData, and writes the result to the 32-bit PCI
1053 configuration register specified by Address. The value written to the PCI
1054 configuration register is returned. This function must guarantee that all PCI
1055 read and write operations are serialized.
1057 If any reserved bits in Address are set, then ASSERT().
1059 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1061 @param AndData The value to AND with the PCI configuration register.
1062 @param OrData The value to OR with the result of the AND operation.
1064 @return The value written back to the PCI configuration register.
1069 PciSegmentAndThenOr32 (
1075 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1079 Reads a bit field of a PCI configuration register.
1081 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1082 specified by the StartBit and the EndBit. The value of the bit field is
1085 If any reserved bits in Address are set, then ASSERT().
1086 If StartBit is greater than 31, then ASSERT().
1087 If EndBit is greater than 31, then ASSERT().
1088 If EndBit is less than StartBit, then ASSERT().
1090 @param Address PCI configuration register to read.
1091 @param StartBit The ordinal of the least significant bit in the bit field.
1093 @param EndBit The ordinal of the most significant bit in the bit field.
1096 @return The value of the bit field read from the PCI configuration register.
1101 PciSegmentBitFieldRead32 (
1107 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1111 Writes a bit field to a PCI configuration register.
1113 Writes Value to the bit field of the PCI configuration register. The bit
1114 field is specified by the StartBit and the EndBit. All other bits in the
1115 destination PCI configuration register are preserved. The new value of the
1116 32-bit register is returned.
1118 If any reserved bits in Address are set, then ASSERT().
1119 If StartBit is greater than 31, then ASSERT().
1120 If EndBit is greater than 31, then ASSERT().
1121 If EndBit is less than StartBit, then ASSERT().
1123 @param Address PCI configuration register to write.
1124 @param StartBit The ordinal of the least significant bit in the bit field.
1126 @param EndBit The ordinal of the most significant bit in the bit field.
1128 @param Value New value of the bit field.
1130 @return The value written back to the PCI configuration register.
1135 PciSegmentBitFieldWrite32 (
1142 return PciSegmentWrite32 (
1144 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1149 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1150 writes the result back to the bit field in the 32-bit port.
1152 Reads the 32-bit PCI configuration register specified by Address, performs a
1153 bitwise inclusive OR between the read result and the value specified by
1154 OrData, and writes the result to the 32-bit PCI configuration register
1155 specified by Address. The value written to the PCI configuration register is
1156 returned. This function must guarantee that all PCI read and write operations
1157 are serialized. Extra left bits in OrData are stripped.
1159 If any reserved bits in Address are set, then ASSERT().
1160 If StartBit is greater than 31, then ASSERT().
1161 If EndBit is greater than 31, then ASSERT().
1162 If EndBit is less than StartBit, then ASSERT().
1164 @param Address PCI configuration register to write.
1165 @param StartBit The ordinal of the least significant bit in the bit field.
1167 @param EndBit The ordinal of the most significant bit in the bit field.
1169 @param OrData The value to OR with the PCI configuration register.
1171 @return The value written back to the PCI configuration register.
1176 PciSegmentBitFieldOr32 (
1183 return PciSegmentWrite32 (
1185 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1190 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1191 AND, and writes the result back to the bit field in the 32-bit register.
1193 Reads the 32-bit PCI configuration register specified by Address, performs a
1194 bitwise AND between the read result and the value specified by AndData, and
1195 writes the result to the 32-bit PCI configuration register specified by
1196 Address. The value written to the PCI configuration register is returned.
1197 This function must guarantee that all PCI read and write operations are
1198 serialized. Extra left bits in AndData are stripped.
1200 If any reserved bits in Address are set, then ASSERT().
1201 If StartBit is greater than 31, then ASSERT().
1202 If EndBit is greater than 31, then ASSERT().
1203 If EndBit is less than StartBit, then ASSERT().
1205 @param Address PCI configuration register to write.
1206 @param StartBit The ordinal of the least significant bit in the bit field.
1208 @param EndBit The ordinal of the most significant bit in the bit field.
1210 @param AndData The value to AND with the PCI configuration register.
1212 @return The value written back to the PCI configuration register.
1217 PciSegmentBitFieldAnd32 (
1224 return PciSegmentWrite32 (
1226 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1231 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1232 bitwise inclusive OR, and writes the result back to the bit field in the
1235 Reads the 32-bit PCI configuration register specified by Address, performs a
1236 bitwise AND followed by a bitwise inclusive OR between the read result and
1237 the value specified by AndData, and writes the result to the 32-bit PCI
1238 configuration register specified by Address. The value written to the PCI
1239 configuration register is returned. This function must guarantee that all PCI
1240 read and write operations are serialized. Extra left bits in both AndData and
1241 OrData are stripped.
1243 If any reserved bits in Address are set, then ASSERT().
1244 If StartBit is greater than 31, then ASSERT().
1245 If EndBit is greater than 31, then ASSERT().
1246 If EndBit is less than StartBit, then ASSERT().
1248 @param Address PCI configuration register to write.
1249 @param StartBit The ordinal of the least significant bit in the bit field.
1251 @param EndBit The ordinal of the most significant bit in the bit field.
1253 @param AndData The value to AND with the PCI configuration register.
1254 @param OrData The value to OR with the result of the AND operation.
1256 @return The value written back to the PCI configuration register.
1261 PciSegmentBitFieldAndThenOr32 (
1269 return PciSegmentWrite32 (
1271 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1276 Reads a range of PCI configuration registers into a caller supplied buffer.
1278 Reads the range of PCI configuration registers specified by StartAddress and
1279 Size into the buffer specified by Buffer. This function only allows the PCI
1280 configuration registers from a single PCI function to be read. Size is
1281 returned. When possible 32-bit PCI configuration read cycles are used to read
1282 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1283 and 16-bit PCI configuration read cycles may be used at the beginning and the
1286 If StartAddress > 0x0FFFFFFF, then ASSERT().
1287 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1288 If Size > 0 and Buffer is NULL, then ASSERT().
1290 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1291 Function and Register.
1292 @param Size Size in bytes of the transfer.
1293 @param Buffer Pointer to a buffer receiving the data read.
1300 PciSegmentReadBuffer (
1301 IN UINT64 StartAddress
,
1308 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1309 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1315 ASSERT (Buffer
!= NULL
);
1318 // Save Size for return
1322 if ((StartAddress
& BIT0
) != 0) {
1324 // Read a byte if StartAddress is byte aligned
1326 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1327 StartAddress
+= sizeof (UINT8
);
1328 Size
-= sizeof (UINT8
);
1329 Buffer
= (UINT8
*)Buffer
+ 1;
1332 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1334 // Read a word if StartAddress is word aligned
1336 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1337 StartAddress
+= sizeof (UINT16
);
1338 Size
-= sizeof (UINT16
);
1339 Buffer
= (UINT16
*)Buffer
+ 1;
1342 while (Size
>= sizeof (UINT32
)) {
1344 // Read as many double words as possible
1346 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1347 StartAddress
+= sizeof (UINT32
);
1348 Size
-= sizeof (UINT32
);
1349 Buffer
= (UINT32
*)Buffer
+ 1;
1352 if (Size
>= sizeof (UINT16
)) {
1354 // Read the last remaining word if exist
1356 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1357 StartAddress
+= sizeof (UINT16
);
1358 Size
-= sizeof (UINT16
);
1359 Buffer
= (UINT16
*)Buffer
+ 1;
1362 if (Size
>= sizeof (UINT8
)) {
1364 // Read the last remaining byte if exist
1366 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1373 Copies the data in a caller supplied buffer to a specified range of PCI
1374 configuration space.
1376 Writes the range of PCI configuration registers specified by StartAddress and
1377 Size from the buffer specified by Buffer. This function only allows the PCI
1378 configuration registers from a single PCI function to be written. Size is
1379 returned. When possible 32-bit PCI configuration write cycles are used to
1380 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1381 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1382 and the end of the range.
1384 If StartAddress > 0x0FFFFFFF, then ASSERT().
1385 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1386 If Size > 0 and Buffer is NULL, then ASSERT().
1388 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1389 Function and Register.
1390 @param Size Size in bytes of the transfer.
1391 @param Buffer Pointer to a buffer containing the data to write.
1398 PciSegmentWriteBuffer (
1399 IN UINT64 StartAddress
,
1406 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1407 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1413 ASSERT (Buffer
!= NULL
);
1416 // Save Size for return
1420 if ((StartAddress
& BIT0
) != 0) {
1422 // Write a byte if StartAddress is byte aligned
1424 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1425 StartAddress
+= sizeof (UINT8
);
1426 Size
-= sizeof (UINT8
);
1427 Buffer
= (UINT8
*)Buffer
+ 1;
1430 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1432 // Write a word if StartAddress is word aligned
1434 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1435 StartAddress
+= sizeof (UINT16
);
1436 Size
-= sizeof (UINT16
);
1437 Buffer
= (UINT16
*)Buffer
+ 1;
1440 while (Size
>= sizeof (UINT32
)) {
1442 // Write as many double words as possible
1444 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1445 StartAddress
+= sizeof (UINT32
);
1446 Size
-= sizeof (UINT32
);
1447 Buffer
= (UINT32
*)Buffer
+ 1;
1450 if (Size
>= sizeof (UINT16
)) {
1452 // Write the last remaining word if exist
1454 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1455 StartAddress
+= sizeof (UINT16
);
1456 Size
-= sizeof (UINT16
);
1457 Buffer
= (UINT16
*)Buffer
+ 1;
1460 if (Size
>= sizeof (UINT8
)) {
1462 // Write the last remaining byte if exist
1464 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);