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 Register a PCI device so PCI configuration registers may be accessed after
245 SetVirtualAddressMap().
247 If Address > 0x0FFFFFFF, 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 return RETURN_UNSUPPORTED
;
271 Reads an 8-bit PCI configuration register.
273 Reads and returns the 8-bit PCI configuration register specified by Address.
274 This function must guarantee that all PCI read and write operations are
277 If any reserved bits in Address are set, then ASSERT().
279 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
282 @return The value read from the PCI configuration register.
291 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
293 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
297 Writes an 8-bit PCI configuration register.
299 Writes the 8-bit PCI configuration register specified by Address with the
300 value specified by Value. Value is returned. This function must guarantee
301 that all PCI read and write operations are serialized.
303 If any reserved bits in Address are set, then ASSERT().
305 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
307 @param Data The value to write.
309 @return The value written to the PCI configuration register.
319 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
321 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Data
);
325 Performs a bitwise OR of an 8-bit PCI configuration register with
328 Reads the 8-bit PCI configuration register specified by Address, performs a
329 bitwise OR between the read result and the value specified by
330 OrData, and writes the result to the 8-bit PCI configuration register
331 specified by Address. The value written to the PCI configuration register is
332 returned. This function must guarantee that all PCI read and write operations
335 If any reserved bits in Address are set, then ASSERT().
337 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
339 @param OrData The value to OR with the PCI configuration register.
341 @return The value written back to the PCI configuration register.
351 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
355 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
358 Reads the 8-bit PCI configuration register specified by Address, performs a
359 bitwise AND between the read result and the value specified by AndData, and
360 writes the result to the 8-bit PCI configuration register specified by
361 Address. The value written to the PCI configuration register is returned.
362 This function must guarantee that all PCI read and write operations are
365 If any reserved bits in Address are set, then ASSERT().
367 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
369 @param AndData The value to AND with the PCI configuration register.
371 @return The value written back to the PCI configuration register.
381 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
385 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
386 value, followed a bitwise OR with another 8-bit value.
388 Reads the 8-bit PCI configuration register specified by Address, performs a
389 bitwise AND between the read result and the value specified by AndData,
390 performs a bitwise OR between the result of the AND operation and
391 the value specified by OrData, and writes the result to the 8-bit PCI
392 configuration register specified by Address. The value written to the PCI
393 configuration register is returned. This function must guarantee that all PCI
394 read and write operations are serialized.
396 If any reserved bits in Address are set, then ASSERT().
398 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
400 @param AndData The value to AND with the PCI configuration register.
401 @param OrData The value to OR with the result of the AND operation.
403 @return The value written back to the PCI configuration register.
408 PciSegmentAndThenOr8 (
414 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
418 Reads a bit field of a PCI configuration register.
420 Reads the bit field in an 8-bit PCI configuration register. The bit field is
421 specified by the StartBit and the EndBit. The value of the bit field is
424 If any reserved bits in Address are set, then ASSERT().
425 If StartBit is greater than 7, then ASSERT().
426 If EndBit is greater than 7, then ASSERT().
427 If EndBit is less than StartBit, then ASSERT().
429 @param Address PCI configuration register to read.
430 @param StartBit The ordinal of the least significant bit in the bit field.
432 @param EndBit The ordinal of the most significant bit in the bit field.
435 @return The value of the bit field read from the PCI configuration register.
440 PciSegmentBitFieldRead8 (
446 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
450 Writes a bit field to a PCI configuration register.
452 Writes Value to the bit field of the PCI configuration register. The bit
453 field is specified by the StartBit and the EndBit. All other bits in the
454 destination PCI configuration register are preserved. The new value of the
455 8-bit register is returned.
457 If any reserved bits in Address are set, then ASSERT().
458 If StartBit is greater than 7, then ASSERT().
459 If EndBit is greater than 7, then ASSERT().
460 If EndBit is less than StartBit, then ASSERT().
462 @param Address PCI configuration register to write.
463 @param StartBit The ordinal of the least significant bit in the bit field.
465 @param EndBit The ordinal of the most significant bit in the bit field.
467 @param Value New value of the bit field.
469 @return The value written back to the PCI configuration register.
474 PciSegmentBitFieldWrite8 (
481 return PciSegmentWrite8 (
483 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
488 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
489 writes the result back to the bit field in the 8-bit port.
491 Reads the 8-bit PCI configuration register specified by Address, performs a
492 bitwise OR between the read result and the value specified by
493 OrData, and writes the result to the 8-bit PCI configuration register
494 specified by Address. The value written to the PCI configuration register is
495 returned. This function must guarantee that all PCI read and write operations
496 are serialized. Extra left bits in OrData are stripped.
498 If any reserved bits in Address are set, then ASSERT().
499 If StartBit is greater than 7, then ASSERT().
500 If EndBit is greater than 7, then ASSERT().
501 If EndBit is less than StartBit, then ASSERT().
503 @param Address PCI configuration register to write.
504 @param StartBit The ordinal of the least significant bit in the bit field.
506 @param EndBit The ordinal of the most significant bit in the bit field.
508 @param OrData The value to OR with the PCI configuration register.
510 @return The value written back to the PCI configuration register.
515 PciSegmentBitFieldOr8 (
522 return PciSegmentWrite8 (
524 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
529 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
530 AND, and writes the result back to the bit field in the 8-bit register.
532 Reads the 8-bit PCI configuration register specified by Address, performs a
533 bitwise AND between the read result and the value specified by AndData, and
534 writes the result to the 8-bit PCI configuration register specified by
535 Address. The value written to the PCI configuration register is returned.
536 This function must guarantee that all PCI read and write operations are
537 serialized. Extra left bits in AndData are stripped.
539 If any reserved bits in Address are set, then ASSERT().
540 If StartBit is greater than 7, then ASSERT().
541 If EndBit is greater than 7, then ASSERT().
542 If EndBit is less than StartBit, then ASSERT().
544 @param Address PCI configuration register to write.
545 @param StartBit The ordinal of the least significant bit in the bit field.
547 @param EndBit The ordinal of the most significant bit in the bit field.
549 @param AndData The value to AND with the PCI configuration register.
551 @return The value written back to the PCI configuration register.
556 PciSegmentBitFieldAnd8 (
563 return PciSegmentWrite8 (
565 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
570 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
571 bitwise OR, and writes the result back to the bit field in the
574 Reads the 8-bit PCI configuration register specified by Address, performs a
575 bitwise AND followed by a bitwise OR between the read result and
576 the value specified by AndData, and writes the result to the 8-bit PCI
577 configuration register specified by Address. The value written to the PCI
578 configuration register is returned. This function must guarantee that all PCI
579 read and write operations are serialized. Extra left bits in both AndData and
582 If any reserved bits in Address are set, then ASSERT().
583 If StartBit is greater than 7, then ASSERT().
584 If EndBit is greater than 7, then ASSERT().
585 If EndBit is less than StartBit, then ASSERT().
587 @param Address PCI configuration register to write.
588 @param StartBit The ordinal of the least significant bit in the bit field.
590 @param EndBit The ordinal of the most significant bit in the bit field.
592 @param AndData The value to AND with the PCI configuration register.
593 @param OrData The value to OR with the result of the AND operation.
595 @return The value written back to the PCI configuration register.
600 PciSegmentBitFieldAndThenOr8 (
608 return PciSegmentWrite8 (
610 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
615 Reads a 16-bit PCI configuration register.
617 Reads and returns the 16-bit PCI configuration register specified by Address.
618 This function must guarantee that all PCI read and write operations are
621 If any reserved bits in Address are set, then ASSERT().
623 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
626 @return The value read from the PCI configuration register.
635 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
637 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
641 Writes a 16-bit PCI configuration register.
643 Writes the 16-bit PCI configuration register specified by Address with the
644 value specified by Value. Value is returned. This function must guarantee
645 that all PCI read and write operations are serialized.
647 If any reserved bits in Address are set, then ASSERT().
649 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
651 @param Data The value to write.
653 @return The value written to the PCI configuration register.
663 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
665 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Data
);
669 Performs a bitwise OR of a 16-bit PCI configuration register with
672 Reads the 16-bit PCI configuration register specified by Address, performs a
673 bitwise OR between the read result and the value specified by
674 OrData, and writes the result to the 16-bit PCI configuration register
675 specified by Address. The value written to the PCI configuration register is
676 returned. This function must guarantee that all PCI read and write operations
679 If any reserved bits in Address are set, then ASSERT().
681 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
683 @param OrData The value to OR with the PCI configuration register.
685 @return The value written back to the PCI configuration register.
695 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
699 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
702 Reads the 16-bit PCI configuration register specified by Address, performs a
703 bitwise AND between the read result and the value specified by AndData, and
704 writes the result to the 16-bit PCI configuration register specified by
705 Address. The value written to the PCI configuration register is returned.
706 This function must guarantee that all PCI read and write operations are
709 If any reserved bits in Address are set, then ASSERT().
711 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
713 @param AndData The value to AND with the PCI configuration register.
715 @return The value written back to the PCI configuration register.
725 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
729 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
730 value, followed a bitwise OR with another 16-bit value.
732 Reads the 16-bit PCI configuration register specified by Address, performs a
733 bitwise AND between the read result and the value specified by AndData,
734 performs a bitwise OR between the result of the AND operation and
735 the value specified by OrData, and writes the result to the 16-bit PCI
736 configuration register specified by Address. The value written to the PCI
737 configuration register is returned. This function must guarantee that all PCI
738 read and write operations are serialized.
740 If any reserved bits in Address are set, then ASSERT().
742 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
744 @param AndData The value to AND with the PCI configuration register.
745 @param OrData The value to OR with the result of the AND operation.
747 @return The value written back to the PCI configuration register.
752 PciSegmentAndThenOr16 (
758 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
762 Reads a bit field of a PCI configuration register.
764 Reads the bit field in a 16-bit PCI configuration register. The bit field is
765 specified by the StartBit and the EndBit. The value of the bit field is
768 If any reserved bits in Address are set, then ASSERT().
769 If StartBit is greater than 15, then ASSERT().
770 If EndBit is greater than 15, then ASSERT().
771 If EndBit is less than StartBit, then ASSERT().
773 @param Address PCI configuration register to read.
774 @param StartBit The ordinal of the least significant bit in the bit field.
776 @param EndBit The ordinal of the most significant bit in the bit field.
779 @return The value of the bit field read from the PCI configuration register.
784 PciSegmentBitFieldRead16 (
790 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
794 Writes a bit field to a PCI configuration register.
796 Writes Value to the bit field of the PCI configuration register. The bit
797 field is specified by the StartBit and the EndBit. All other bits in the
798 destination PCI configuration register are preserved. The new value of the
799 16-bit register is returned.
801 If any reserved bits in Address are set, then ASSERT().
802 If StartBit is greater than 15, then ASSERT().
803 If EndBit is greater than 15, then ASSERT().
804 If EndBit is less than StartBit, then ASSERT().
806 @param Address PCI configuration register to write.
807 @param StartBit The ordinal of the least significant bit in the bit field.
809 @param EndBit The ordinal of the most significant bit in the bit field.
811 @param Value New value of the bit field.
813 @return The value written back to the PCI configuration register.
818 PciSegmentBitFieldWrite16 (
825 return PciSegmentWrite16 (
827 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
832 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
833 writes the result back to the bit field in the 16-bit port.
835 Reads the 16-bit PCI configuration register specified by Address, performs a
836 bitwise OR between the read result and the value specified by
837 OrData, and writes the result to the 16-bit PCI configuration register
838 specified by Address. The value written to the PCI configuration register is
839 returned. This function must guarantee that all PCI read and write operations
840 are serialized. Extra left bits in OrData are stripped.
842 If any reserved bits in Address are set, then ASSERT().
843 If StartBit is greater than 15, then ASSERT().
844 If EndBit is greater than 15, then ASSERT().
845 If EndBit is less than StartBit, then ASSERT().
847 @param Address PCI configuration register to write.
848 @param StartBit The ordinal of the least significant bit in the bit field.
850 @param EndBit The ordinal of the most significant bit in the bit field.
852 @param OrData The value to OR with the PCI configuration register.
854 @return The value written back to the PCI configuration register.
859 PciSegmentBitFieldOr16 (
866 return PciSegmentWrite16 (
868 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
873 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
874 AND, and writes the result back to the bit field in the 16-bit register.
876 Reads the 16-bit PCI configuration register specified by Address, performs a
877 bitwise AND between the read result and the value specified by AndData, and
878 writes the result to the 16-bit PCI configuration register specified by
879 Address. The value written to the PCI configuration register is returned.
880 This function must guarantee that all PCI read and write operations are
881 serialized. Extra left bits in AndData are stripped.
883 If any reserved bits in Address are set, then ASSERT().
884 If StartBit is greater than 15, then ASSERT().
885 If EndBit is greater than 15, then ASSERT().
886 If EndBit is less than StartBit, then ASSERT().
888 @param Address PCI configuration register to write.
889 @param StartBit The ordinal of the least significant bit in the bit field.
891 @param EndBit The ordinal of the most significant bit in the bit field.
893 @param AndData The value to AND with the PCI configuration register.
895 @return The value written back to the PCI configuration register.
900 PciSegmentBitFieldAnd16 (
907 return PciSegmentWrite16 (
909 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
914 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
915 bitwise OR, and writes the result back to the bit field in the
918 Reads the 16-bit PCI configuration register specified by Address, performs a
919 bitwise AND followed by a bitwise OR between the read result and
920 the value specified by AndData, and writes the result to the 16-bit PCI
921 configuration register specified by Address. The value written to the PCI
922 configuration register is returned. This function must guarantee that all PCI
923 read and write operations are serialized. Extra left bits in both AndData and
926 If any reserved bits in Address are set, then ASSERT().
927 If StartBit is greater than 15, then ASSERT().
928 If EndBit is greater than 15, then ASSERT().
929 If EndBit is less than StartBit, then ASSERT().
931 @param Address PCI configuration register to write.
932 @param StartBit The ordinal of the least significant bit in the bit field.
934 @param EndBit The ordinal of the most significant bit in the bit field.
936 @param AndData The value to AND with the PCI configuration register.
937 @param OrData The value to OR with the result of the AND operation.
939 @return The value written back to the PCI configuration register.
944 PciSegmentBitFieldAndThenOr16 (
952 return PciSegmentWrite16 (
954 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
959 Reads a 32-bit PCI configuration register.
961 Reads and returns the 32-bit PCI configuration register specified by Address.
962 This function must guarantee that all PCI read and write operations are
965 If any reserved bits in Address are set, then ASSERT().
967 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
970 @return The value read from the PCI configuration register.
979 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
981 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
985 Writes a 32-bit PCI configuration register.
987 Writes the 32-bit PCI configuration register specified by Address with the
988 value specified by Value. Value is returned. This function must guarantee
989 that all PCI read and write operations are serialized.
991 If any reserved bits in Address are set, then ASSERT().
993 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
995 @param Data The value to write.
997 @return The value written to the PCI configuration register.
1007 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
1009 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Data
);
1013 Performs a bitwise OR of a 32-bit PCI configuration register with
1016 Reads the 32-bit PCI configuration register specified by Address, performs a
1017 bitwise OR between the read result and the value specified by
1018 OrData, and writes the result to the 32-bit PCI configuration register
1019 specified by Address. The value written to the PCI configuration register is
1020 returned. This function must guarantee that all PCI read and write operations
1023 If any reserved bits in Address are set, then ASSERT().
1025 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1027 @param OrData The value to OR with the PCI configuration register.
1029 @return The value written back to the PCI configuration register.
1039 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1043 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1046 Reads the 32-bit PCI configuration register specified by Address, performs a
1047 bitwise AND between the read result and the value specified by AndData, and
1048 writes the result to the 32-bit PCI configuration register specified by
1049 Address. The value written to the PCI configuration register is returned.
1050 This function must guarantee that all PCI read and write operations are
1053 If any reserved bits in Address are set, then ASSERT().
1055 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1057 @param AndData The value to AND with the PCI configuration register.
1059 @return The value written back to the PCI configuration register.
1069 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1073 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1074 value, followed a bitwise OR with another 32-bit value.
1076 Reads the 32-bit PCI configuration register specified by Address, performs a
1077 bitwise AND between the read result and the value specified by AndData,
1078 performs a bitwise OR between the result of the AND operation and
1079 the value specified by OrData, and writes the result to the 32-bit PCI
1080 configuration register specified by Address. The value written to the PCI
1081 configuration register is returned. This function must guarantee that all PCI
1082 read and write operations are serialized.
1084 If any reserved bits in Address are set, then ASSERT().
1086 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1088 @param AndData The value to AND with the PCI configuration register.
1089 @param OrData The value to OR with the result of the AND operation.
1091 @return The value written back to the PCI configuration register.
1096 PciSegmentAndThenOr32 (
1102 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1106 Reads a bit field of a PCI configuration register.
1108 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1109 specified by the StartBit and the EndBit. The value of the bit field is
1112 If any reserved bits in Address are set, then ASSERT().
1113 If StartBit is greater than 31, then ASSERT().
1114 If EndBit is greater than 31, then ASSERT().
1115 If EndBit is less than StartBit, then ASSERT().
1117 @param Address PCI configuration register to read.
1118 @param StartBit The ordinal of the least significant bit in the bit field.
1120 @param EndBit The ordinal of the most significant bit in the bit field.
1123 @return The value of the bit field read from the PCI configuration register.
1128 PciSegmentBitFieldRead32 (
1134 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1138 Writes a bit field to a PCI configuration register.
1140 Writes Value to the bit field of the PCI configuration register. The bit
1141 field is specified by the StartBit and the EndBit. All other bits in the
1142 destination PCI configuration register are preserved. The new value of the
1143 32-bit register is returned.
1145 If any reserved bits in Address are set, then ASSERT().
1146 If StartBit is greater than 31, then ASSERT().
1147 If EndBit is greater than 31, then ASSERT().
1148 If EndBit is less than StartBit, then ASSERT().
1150 @param Address PCI configuration register to write.
1151 @param StartBit The ordinal of the least significant bit in the bit field.
1153 @param EndBit The ordinal of the most significant bit in the bit field.
1155 @param Value New value of the bit field.
1157 @return The value written back to the PCI configuration register.
1162 PciSegmentBitFieldWrite32 (
1169 return PciSegmentWrite32 (
1171 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1176 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1177 writes the result back to the bit field in the 32-bit port.
1179 Reads the 32-bit PCI configuration register specified by Address, performs a
1180 bitwise OR between the read result and the value specified by
1181 OrData, and writes the result to the 32-bit PCI configuration register
1182 specified by Address. The value written to the PCI configuration register is
1183 returned. This function must guarantee that all PCI read and write operations
1184 are serialized. Extra left bits in OrData are stripped.
1186 If any reserved bits in Address are set, then ASSERT().
1187 If StartBit is greater than 31, then ASSERT().
1188 If EndBit is greater than 31, then ASSERT().
1189 If EndBit is less than StartBit, then ASSERT().
1191 @param Address PCI configuration register to write.
1192 @param StartBit The ordinal of the least significant bit in the bit field.
1194 @param EndBit The ordinal of the most significant bit in the bit field.
1196 @param OrData The value to OR with the PCI configuration register.
1198 @return The value written back to the PCI configuration register.
1203 PciSegmentBitFieldOr32 (
1210 return PciSegmentWrite32 (
1212 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1217 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1218 AND, and writes the result back to the bit field in the 32-bit register.
1220 Reads the 32-bit PCI configuration register specified by Address, performs a
1221 bitwise AND between the read result and the value specified by AndData, and
1222 writes the result to the 32-bit PCI configuration register specified by
1223 Address. The value written to the PCI configuration register is returned.
1224 This function must guarantee that all PCI read and write operations are
1225 serialized. Extra left bits in AndData are stripped.
1227 If any reserved bits in Address are set, then ASSERT().
1228 If StartBit is greater than 31, then ASSERT().
1229 If EndBit is greater than 31, then ASSERT().
1230 If EndBit is less than StartBit, then ASSERT().
1232 @param Address PCI configuration register to write.
1233 @param StartBit The ordinal of the least significant bit in the bit field.
1235 @param EndBit The ordinal of the most significant bit in the bit field.
1237 @param AndData The value to AND with the PCI configuration register.
1239 @return The value written back to the PCI configuration register.
1244 PciSegmentBitFieldAnd32 (
1251 return PciSegmentWrite32 (
1253 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1258 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1259 bitwise OR, and writes the result back to the bit field in the
1262 Reads the 32-bit PCI configuration register specified by Address, performs a
1263 bitwise AND followed by a bitwise OR between the read result and
1264 the value specified by AndData, and writes the result to the 32-bit PCI
1265 configuration register specified by Address. The value written to the PCI
1266 configuration register is returned. This function must guarantee that all PCI
1267 read and write operations are serialized. Extra left bits in both AndData and
1268 OrData are stripped.
1270 If any reserved bits in Address are set, then ASSERT().
1271 If StartBit is greater than 31, then ASSERT().
1272 If EndBit is greater than 31, then ASSERT().
1273 If EndBit is less than StartBit, then ASSERT().
1275 @param Address PCI configuration register to write.
1276 @param StartBit The ordinal of the least significant bit in the bit field.
1278 @param EndBit The ordinal of the most significant bit in the bit field.
1280 @param AndData The value to AND with the PCI configuration register.
1281 @param OrData The value to OR with the result of the AND operation.
1283 @return The value written back to the PCI configuration register.
1288 PciSegmentBitFieldAndThenOr32 (
1296 return PciSegmentWrite32 (
1298 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1303 Reads a range of PCI configuration registers into a caller supplied buffer.
1305 Reads the range of PCI configuration registers specified by StartAddress
1306 and Size into the buffer specified by Buffer.
1307 This function only allows the PCI configuration registers from a single PCI function to be read.
1310 If any reserved bits in StartAddress are set, then ASSERT().
1311 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1312 If Size > 0 and Buffer is NULL, then ASSERT().
1314 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device, Function, and Register.
1315 @param Size Size in bytes of the transfer.
1316 @param Buffer Pointer to a buffer receiving the data read.
1318 @return The parameter of Size.
1323 PciSegmentReadBuffer (
1324 IN UINT64 StartAddress
,
1331 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1332 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1338 ASSERT (Buffer
!= NULL
);
1341 // Save Size for return
1345 if ((StartAddress
& BIT0
) != 0) {
1347 // Read a byte if StartAddress is byte aligned
1349 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1350 StartAddress
+= sizeof (UINT8
);
1351 Size
-= sizeof (UINT8
);
1352 Buffer
= (UINT8
*)Buffer
+ 1;
1355 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1357 // Read a word if StartAddress is word aligned
1359 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1360 StartAddress
+= sizeof (UINT16
);
1361 Size
-= sizeof (UINT16
);
1362 Buffer
= (UINT16
*)Buffer
+ 1;
1365 while (Size
>= sizeof (UINT32
)) {
1367 // Read as many double words as possible
1369 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1370 StartAddress
+= sizeof (UINT32
);
1371 Size
-= sizeof (UINT32
);
1372 Buffer
= (UINT32
*)Buffer
+ 1;
1375 if (Size
>= sizeof (UINT16
)) {
1377 // Read the last remaining word if exist
1379 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1380 StartAddress
+= sizeof (UINT16
);
1381 Size
-= sizeof (UINT16
);
1382 Buffer
= (UINT16
*)Buffer
+ 1;
1385 if (Size
>= sizeof (UINT8
)) {
1387 // Read the last remaining byte if exist
1389 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1396 Copies the data in a caller supplied buffer to a specified range of PCI configuration space.
1398 Writes the range of PCI configuration registers specified by StartAddress
1399 and Size from the buffer specified by Buffer.
1400 This function only allows the PCI configuration registers from a single PCI function to be written.
1403 If any reserved bits in StartAddress are set, then ASSERT().
1404 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1405 If Size > 0 and Buffer is NULL, then ASSERT().
1407 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device, Function, and Register.
1408 @param Size Size in bytes of the transfer.
1409 @param Buffer Pointer to a buffer containing the data to write.
1411 @return The parameter of Size.
1416 PciSegmentWriteBuffer (
1417 IN UINT64 StartAddress
,
1424 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1425 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1431 ASSERT (Buffer
!= NULL
);
1434 // Save Size for return
1438 if ((StartAddress
& BIT0
) != 0) {
1440 // Write a byte if StartAddress is byte aligned
1442 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1443 StartAddress
+= sizeof (UINT8
);
1444 Size
-= sizeof (UINT8
);
1445 Buffer
= (UINT8
*)Buffer
+ 1;
1448 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1450 // Write a word if StartAddress is word aligned
1452 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1453 StartAddress
+= sizeof (UINT16
);
1454 Size
-= sizeof (UINT16
);
1455 Buffer
= (UINT16
*)Buffer
+ 1;
1458 while (Size
>= sizeof (UINT32
)) {
1460 // Write as many double words as possible
1462 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1463 StartAddress
+= sizeof (UINT32
);
1464 Size
-= sizeof (UINT32
);
1465 Buffer
= (UINT32
*)Buffer
+ 1;
1468 if (Size
>= sizeof (UINT16
)) {
1470 // Write the last remaining word if exist
1472 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1473 StartAddress
+= sizeof (UINT16
);
1474 Size
-= sizeof (UINT16
);
1475 Buffer
= (UINT16
*)Buffer
+ 1;
1478 if (Size
>= sizeof (UINT8
)) {
1480 // Write the last remaining byte if exist
1482 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);