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 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 Register.
280 @return The 8-bit PCI configuration register specified by Address.
289 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
291 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
295 Writes an 8-bit PCI configuration register.
297 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
298 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
300 If Address > 0x0FFFFFFF, then ASSERT().
302 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
303 @param Value The value to write.
305 @return The value written to the PCI configuration register.
315 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
317 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
321 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
323 Reads the 8-bit PCI configuration register specified by Address,
324 performs a bitwise OR between the read result and the value specified by OrData,
325 and writes the result to the 8-bit PCI configuration register specified by Address.
326 The value written to the PCI configuration register is returned.
327 This function must guarantee that all PCI read and write operations are serialized.
329 If any reserved bits in Address are set, then ASSERT().
331 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
332 @param OrData The value to OR with the PCI configuration register.
334 @return The value written to the PCI configuration register.
344 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
348 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
350 Reads the 8-bit PCI configuration register specified by Address,
351 performs a bitwise AND between the read result and the value specified by AndData,
352 and writes the result to the 8-bit PCI configuration register specified by Address.
353 The value written to the PCI configuration register is returned.
354 This function must guarantee that all PCI read and write operations are serialized.
355 If any reserved bits in Address are set, then ASSERT().
357 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
358 @param AndData The value to AND with the PCI configuration register.
360 @return The value written to the PCI configuration register.
370 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
374 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
375 followed a bitwise OR with another 8-bit value.
377 Reads the 8-bit PCI configuration register specified by Address,
378 performs a bitwise AND between the read result and the value specified by AndData,
379 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
380 and writes the result to the 8-bit PCI configuration register specified by Address.
381 The value written to the PCI configuration register is returned.
382 This function must guarantee that all PCI read and write operations are serialized.
384 If any reserved bits in Address are set, then ASSERT().
386 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
387 @param AndData The value to AND with the PCI configuration register.
388 @param OrData The value to OR with the PCI configuration register.
390 @return The value written to the PCI configuration register.
395 PciSegmentAndThenOr8 (
401 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
405 Reads a bit field of a PCI configuration register.
407 Reads the bit field in an 8-bit PCI configuration register. The bit field is
408 specified by the StartBit and the EndBit. The value of the bit field is
411 If any reserved bits in Address are set, then ASSERT().
412 If StartBit is greater than 7, then ASSERT().
413 If EndBit is greater than 7, then ASSERT().
414 If EndBit is less than StartBit, then ASSERT().
416 @param Address PCI configuration register to read.
417 @param StartBit The ordinal of the least significant bit in the bit field.
419 @param EndBit The ordinal of the most significant bit in the bit field.
422 @return The value of the bit field read from the PCI configuration register.
427 PciSegmentBitFieldRead8 (
433 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
437 Writes a bit field to a PCI configuration register.
439 Writes Value to the bit field of the PCI configuration register. The bit
440 field is specified by the StartBit and the EndBit. All other bits in the
441 destination PCI configuration register are preserved. The new value of the
442 8-bit register is returned.
444 If any reserved bits in Address are set, then ASSERT().
445 If StartBit is greater than 7, then ASSERT().
446 If EndBit is greater than 7, then ASSERT().
447 If EndBit is less than StartBit, then ASSERT().
449 @param Address PCI configuration register to write.
450 @param StartBit The ordinal of the least significant bit in the bit field.
452 @param EndBit The ordinal of the most significant bit in the bit field.
454 @param Value New value of the bit field.
456 @return The value written back to the PCI configuration register.
461 PciSegmentBitFieldWrite8 (
468 return PciSegmentWrite8 (
470 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
475 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
476 writes the result back to the bit field in the 8-bit port.
478 Reads the 8-bit PCI configuration register specified by Address, performs a
479 bitwise OR between the read result and the value specified by
480 OrData, and writes the result to the 8-bit PCI configuration register
481 specified by Address. The value written to the PCI configuration register is
482 returned. This function must guarantee that all PCI read and write operations
483 are serialized. Extra left bits in OrData are stripped.
485 If any reserved bits in Address are set, then ASSERT().
486 If StartBit is greater than 7, then ASSERT().
487 If EndBit is greater than 7, then ASSERT().
488 If EndBit is less than StartBit, then ASSERT().
490 @param Address PCI configuration register to write.
491 @param StartBit The ordinal of the least significant bit in the bit field.
493 @param EndBit The ordinal of the most significant bit in the bit field.
495 @param OrData The value to OR with the PCI configuration register.
497 @return The value written back to the PCI configuration register.
502 PciSegmentBitFieldOr8 (
509 return PciSegmentWrite8 (
511 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
516 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
517 AND, and writes the result back to the bit field in the 8-bit register.
519 Reads the 8-bit PCI configuration register specified by Address, performs a
520 bitwise AND between the read result and the value specified by AndData, and
521 writes the result to the 8-bit PCI configuration register specified by
522 Address. The value written to the PCI configuration register is returned.
523 This function must guarantee that all PCI read and write operations are
524 serialized. Extra left bits in AndData are stripped.
526 If any reserved bits in Address are set, then ASSERT().
527 If StartBit is greater than 7, then ASSERT().
528 If EndBit is greater than 7, then ASSERT().
529 If EndBit is less than StartBit, then ASSERT().
531 @param Address PCI configuration register to write.
532 @param StartBit The ordinal of the least significant bit in the bit field.
534 @param EndBit The ordinal of the most significant bit in the bit field.
536 @param AndData The value to AND with the PCI configuration register.
538 @return The value written back to the PCI configuration register.
543 PciSegmentBitFieldAnd8 (
550 return PciSegmentWrite8 (
552 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
557 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
558 bitwise OR, and writes the result back to the bit field in the
561 Reads the 8-bit PCI configuration register specified by Address, performs a
562 bitwise AND followed by a bitwise OR between the read result and
563 the value specified by AndData, and writes the result to the 8-bit PCI
564 configuration register specified by Address. The value written to the PCI
565 configuration register is returned. This function must guarantee that all PCI
566 read and write operations are serialized. Extra left bits in both AndData and
569 If any reserved bits in Address are set, then ASSERT().
570 If StartBit is greater than 7, then ASSERT().
571 If EndBit is greater than 7, then ASSERT().
572 If EndBit is less than StartBit, then ASSERT().
574 @param Address PCI configuration register to write.
575 @param StartBit The ordinal of the least significant bit in the bit field.
577 @param EndBit The ordinal of the most significant bit in the bit field.
579 @param AndData The value to AND with the PCI configuration register.
580 @param OrData The value to OR with the result of the AND operation.
582 @return The value written back to the PCI configuration register.
587 PciSegmentBitFieldAndThenOr8 (
595 return PciSegmentWrite8 (
597 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
602 Reads a 16-bit PCI configuration register.
604 Reads and returns the 16-bit PCI configuration register specified by Address.
605 This function must guarantee that all PCI read and write operations are serialized.
607 If any reserved bits in Address are set, then ASSERT().
608 If Address is not aligned on a 16-bit boundary, then ASSERT().
610 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
612 @return The 16-bit PCI configuration register specified by Address.
621 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
623 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
627 Writes a 16-bit PCI configuration register.
629 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
630 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
632 If any reserved bits in Address are set, then ASSERT().
633 If Address is not aligned on a 16-bit boundary, then ASSERT().
635 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
636 @param Value The value to write.
638 @return The parameter of Value.
648 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
650 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
654 Performs a bitwise OR of a 16-bit PCI configuration register with
657 Reads the 16-bit PCI configuration register specified by Address, performs a
658 bitwise OR between the read result and the value specified by
659 OrData, and writes the result to the 16-bit PCI configuration register
660 specified by Address. The value written to the PCI configuration register is
661 returned. This function must guarantee that all PCI read and write operations
664 If any reserved bits in Address are set, then ASSERT().
665 If Address is not aligned on a 16-bit boundary, then ASSERT().
667 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
669 @param OrData The value to OR with the PCI configuration register.
671 @return The value written back to the PCI configuration register.
681 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
685 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
687 Reads the 16-bit PCI configuration register specified by Address,
688 performs a bitwise AND between the read result and the value specified by AndData,
689 and writes the result to the 16-bit PCI configuration register specified by Address.
690 The value written to the PCI configuration register is returned.
691 This function must guarantee that all PCI read and write operations are serialized.
693 If any reserved bits in Address are set, then ASSERT().
694 If Address is not aligned on a 16-bit boundary, then ASSERT().
696 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
697 @param AndData The value to AND with the PCI configuration register.
699 @return The value written to the PCI configuration register.
709 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
713 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
714 followed a bitwise OR with another 16-bit value.
716 Reads the 16-bit PCI configuration register specified by Address,
717 performs a bitwise AND between the read result and the value specified by AndData,
718 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
719 and writes the result to the 16-bit PCI configuration register specified by Address.
720 The value written to the PCI configuration register is returned.
721 This function must guarantee that all PCI read and write operations are serialized.
723 If any reserved bits in Address are set, then ASSERT().
724 If Address is not aligned on a 16-bit boundary, then ASSERT().
726 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
727 @param AndData The value to AND with the PCI configuration register.
728 @param OrData The value to OR with the PCI configuration register.
730 @return The value written to the PCI configuration register.
735 PciSegmentAndThenOr16 (
741 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
745 Reads a bit field of a PCI configuration register.
747 Reads the bit field in a 16-bit PCI configuration register. The bit field is
748 specified by the StartBit and the EndBit. The value of the bit field is
751 If any reserved bits in Address are set, then ASSERT().
752 If Address is not aligned on a 16-bit boundary, then ASSERT().
753 If StartBit is greater than 15, then ASSERT().
754 If EndBit is greater than 15, then ASSERT().
755 If EndBit is less than StartBit, then ASSERT().
757 @param Address PCI configuration register to read.
758 @param StartBit The ordinal of the least significant bit in the bit field.
760 @param EndBit The ordinal of the most significant bit in the bit field.
763 @return The value of the bit field read from the PCI configuration register.
768 PciSegmentBitFieldRead16 (
774 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
778 Writes a bit field to a PCI configuration register.
780 Writes Value to the bit field of the PCI configuration register. The bit
781 field is specified by the StartBit and the EndBit. All other bits in the
782 destination PCI configuration register are preserved. The new value of the
783 16-bit register is returned.
785 If any reserved bits in Address are set, then ASSERT().
786 If Address is not aligned on a 16-bit boundary, then ASSERT().
787 If StartBit is greater than 15, then ASSERT().
788 If EndBit is greater than 15, then ASSERT().
789 If EndBit is less than StartBit, then ASSERT().
791 @param Address PCI configuration register to write.
792 @param StartBit The ordinal of the least significant bit in the bit field.
794 @param EndBit The ordinal of the most significant bit in the bit field.
796 @param Value New value of the bit field.
798 @return The value written back to the PCI configuration register.
803 PciSegmentBitFieldWrite16 (
810 return PciSegmentWrite16 (
812 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
817 Reads the 16-bit PCI configuration register specified by Address,
818 performs a bitwise OR between the read result and the value specified by OrData,
819 and writes the result to the 16-bit PCI configuration register specified by Address.
821 If any reserved bits in Address are set, then ASSERT().
822 If Address is not aligned on a 16-bit boundary, then ASSERT().
823 If StartBit is greater than 15, then ASSERT().
824 If EndBit is greater than 15, then ASSERT().
825 If EndBit is less than StartBit, then ASSERT().
827 @param Address PCI configuration register to write.
828 @param StartBit The ordinal of the least significant bit in the bit field.
830 @param EndBit The ordinal of the most significant bit in the bit field.
832 @param OrData The value to OR with the PCI configuration register.
834 @return The value written back to the PCI configuration register.
839 PciSegmentBitFieldOr16 (
846 return PciSegmentWrite16 (
848 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
853 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
854 and writes the result back to the bit field in the 16-bit port.
856 Reads the 16-bit PCI configuration register specified by Address,
857 performs a bitwise OR between the read result and the value specified by OrData,
858 and writes the result to the 16-bit PCI configuration register specified by Address.
859 The value written to the PCI configuration register is returned.
860 This function must guarantee that all PCI read and write operations are serialized.
861 Extra left bits in OrData are stripped.
863 If any reserved bits in Address are set, then ASSERT().
864 If Address is not aligned on a 16-bit boundary, then ASSERT().
865 If StartBit is greater than 7, then ASSERT().
866 If EndBit is greater than 7, then ASSERT().
867 If EndBit is less than StartBit, then ASSERT().
869 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
870 @param StartBit The ordinal of the least significant bit in the bit field.
871 The ordinal of the least significant bit in a byte is bit 0.
872 @param EndBit The ordinal of the most significant bit in the bit field.
873 The ordinal of the most significant bit in a byte is bit 7.
874 @param AndData The value to AND with the read value from the PCI configuration register.
876 @return The value written to the PCI configuration register.
881 PciSegmentBitFieldAnd16 (
888 return PciSegmentWrite16 (
890 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
895 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
896 bitwise OR, and writes the result back to the bit field in the
899 Reads the 16-bit PCI configuration register specified by Address, performs a
900 bitwise AND followed by a bitwise OR between the read result and
901 the value specified by AndData, and writes the result to the 16-bit PCI
902 configuration register specified by Address. The value written to the PCI
903 configuration register is returned. This function must guarantee that all PCI
904 read and write operations are serialized. Extra left bits in both AndData and
907 If any reserved bits in Address are set, then ASSERT().
908 If StartBit is greater than 15, then ASSERT().
909 If EndBit is greater than 15, then ASSERT().
910 If EndBit is less than StartBit, then ASSERT().
912 @param Address PCI configuration register to write.
913 @param StartBit The ordinal of the least significant bit in the bit field.
915 @param EndBit The ordinal of the most significant bit in the bit field.
917 @param AndData The value to AND with the PCI configuration register.
918 @param OrData The value to OR with the result of the AND operation.
920 @return The value written back to the PCI configuration register.
925 PciSegmentBitFieldAndThenOr16 (
933 return PciSegmentWrite16 (
935 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
940 Reads a 32-bit PCI configuration register.
942 Reads and returns the 32-bit PCI configuration register specified by Address.
943 This function must guarantee that all PCI read and write operations are serialized.
945 If any reserved bits in Address are set, then ASSERT().
946 If Address is not aligned on a 32-bit boundary, then ASSERT().
948 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
950 @return The 32-bit PCI configuration register specified by Address.
959 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
961 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
965 Writes a 32-bit PCI configuration register.
967 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
968 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
970 If any reserved bits in Address are set, then ASSERT().
971 If Address is not aligned on a 32-bit boundary, then ASSERT().
973 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
974 @param Value The value to write.
976 @return The parameter of Value.
986 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
988 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
992 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
994 Reads the 32-bit PCI configuration register specified by Address,
995 performs a bitwise OR between the read result and the value specified by OrData,
996 and writes the result to the 32-bit PCI configuration register specified by Address.
997 The value written to the PCI configuration register is returned.
998 This function must guarantee that all PCI read and write operations are serialized.
1000 If any reserved bits in Address are set, then ASSERT().
1001 If Address is not aligned on a 32-bit boundary, then ASSERT().
1003 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1004 @param OrData The value to OR with the PCI configuration register.
1006 @return The value written to the PCI configuration register.
1016 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1020 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
1022 Reads the 32-bit PCI configuration register specified by Address,
1023 performs a bitwise AND between the read result and the value specified by AndData,
1024 and writes the result to the 32-bit PCI configuration register specified by Address.
1025 The value written to the PCI configuration register is returned.
1026 This function must guarantee that all PCI read and write operations are serialized.
1028 If any reserved bits in Address are set, then ASSERT().
1029 If Address is not aligned on a 32-bit boundary, then ASSERT().
1031 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1032 @param AndData The value to AND with the PCI configuration register.
1034 @return The value written to the PCI configuration register.
1044 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1048 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
1049 followed a bitwise OR with another 32-bit value.
1051 Reads the 32-bit PCI configuration register specified by Address,
1052 performs a bitwise AND between the read result and the value specified by AndData,
1053 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
1054 and writes the result to the 32-bit PCI configuration register specified by Address.
1055 The value written to the PCI configuration register is returned.
1056 This function must guarantee that all PCI read and write operations are serialized.
1058 If any reserved bits in Address are set, then ASSERT().
1059 If Address is not aligned on a 32-bit boundary, then ASSERT().
1061 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1062 @param AndData The value to AND with the PCI configuration register.
1063 @param OrData The value to OR with the PCI configuration register.
1065 @return The value written 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 Address is not aligned on a 32-bit boundary, then ASSERT().
1088 If StartBit is greater than 31, then ASSERT().
1089 If EndBit is greater than 31, then ASSERT().
1090 If EndBit is less than StartBit, then ASSERT().
1092 @param Address PCI configuration register to read.
1093 @param StartBit The ordinal of the least significant bit in the bit field.
1095 @param EndBit The ordinal of the most significant bit in the bit field.
1098 @return The value of the bit field read from the PCI configuration register.
1103 PciSegmentBitFieldRead32 (
1109 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1113 Writes a bit field to a PCI configuration register.
1115 Writes Value to the bit field of the PCI configuration register. The bit
1116 field is specified by the StartBit and the EndBit. All other bits in the
1117 destination PCI configuration register are preserved. The new value of the
1118 32-bit register is returned.
1120 If any reserved bits in Address are set, then ASSERT().
1121 If Address is not aligned on a 32-bit boundary, then ASSERT().
1122 If StartBit is greater than 31, then ASSERT().
1123 If EndBit is greater than 31, then ASSERT().
1124 If EndBit is less than StartBit, then ASSERT().
1126 @param Address PCI configuration register to write.
1127 @param StartBit The ordinal of the least significant bit in the bit field.
1129 @param EndBit The ordinal of the most significant bit in the bit field.
1131 @param Value New value of the bit field.
1133 @return The value written back to the PCI configuration register.
1138 PciSegmentBitFieldWrite32 (
1145 return PciSegmentWrite32 (
1147 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1152 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1153 writes the result back to the bit field in the 32-bit port.
1155 Reads the 32-bit PCI configuration register specified by Address, performs a
1156 bitwise OR between the read result and the value specified by
1157 OrData, and writes the result to the 32-bit PCI configuration register
1158 specified by Address. The value written to the PCI configuration register is
1159 returned. This function must guarantee that all PCI read and write operations
1160 are serialized. Extra left bits in OrData are stripped.
1162 If any reserved bits in Address are set, then ASSERT().
1163 If StartBit is greater than 31, then ASSERT().
1164 If EndBit is greater than 31, then ASSERT().
1165 If EndBit is less than StartBit, then ASSERT().
1167 @param Address PCI configuration register to write.
1168 @param StartBit The ordinal of the least significant bit in the bit field.
1170 @param EndBit The ordinal of the most significant bit in the bit field.
1172 @param OrData The value to OR with the PCI configuration register.
1174 @return The value written back to the PCI configuration register.
1179 PciSegmentBitFieldOr32 (
1186 return PciSegmentWrite32 (
1188 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1193 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1194 AND, and writes the result back to the bit field in the 32-bit register.
1197 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1198 AND between the read result and the value specified by AndData, and writes the result
1199 to the 32-bit PCI configuration register specified by Address. The value written to
1200 the PCI configuration register is returned. This function must guarantee that all PCI
1201 read and write operations are serialized. Extra left bits in AndData are stripped.
1202 If any reserved bits in Address are set, then ASSERT().
1203 If Address is not aligned on a 32-bit boundary, then ASSERT().
1204 If StartBit is greater than 31, then ASSERT().
1205 If EndBit is greater than 31, then ASSERT().
1206 If EndBit is less than StartBit, then ASSERT().
1209 @param Address PCI configuration register to write.
1210 @param StartBit The ordinal of the least significant bit in the bit field.
1212 @param EndBit The ordinal of the most significant bit in the bit field.
1214 @param AndData The value to AND with the PCI configuration register.
1216 @return The value written back to the PCI configuration register.
1221 PciSegmentBitFieldAnd32 (
1228 return PciSegmentWrite32 (
1230 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1235 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1236 bitwise OR, and writes the result back to the bit field in the
1239 Reads the 32-bit PCI configuration register specified by Address, performs a
1240 bitwise AND followed by a bitwise OR between the read result and
1241 the value specified by AndData, and writes the result to the 32-bit PCI
1242 configuration register specified by Address. The value written to the PCI
1243 configuration register is returned. This function must guarantee that all PCI
1244 read and write operations are serialized. Extra left bits in both AndData and
1245 OrData are stripped.
1247 If any reserved bits in Address are set, then ASSERT().
1248 If StartBit is greater than 31, then ASSERT().
1249 If EndBit is greater than 31, then ASSERT().
1250 If EndBit is less than StartBit, then ASSERT().
1252 @param Address PCI configuration register to write.
1253 @param StartBit The ordinal of the least significant bit in the bit field.
1255 @param EndBit The ordinal of the most significant bit in the bit field.
1257 @param AndData The value to AND with the PCI configuration register.
1258 @param OrData The value to OR with the result of the AND operation.
1260 @return The value written back to the PCI configuration register.
1265 PciSegmentBitFieldAndThenOr32 (
1273 return PciSegmentWrite32 (
1275 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1280 Reads a range of PCI configuration registers into a caller supplied buffer.
1282 Reads the range of PCI configuration registers specified by StartAddress and
1283 Size into the buffer specified by Buffer. This function only allows the PCI
1284 configuration registers from a single PCI function to be read. Size is
1285 returned. When possible 32-bit PCI configuration read cycles are used to read
1286 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1287 and 16-bit PCI configuration read cycles may be used at the beginning and the
1290 If StartAddress > 0x0FFFFFFF, then ASSERT().
1291 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1292 If Size > 0 and Buffer is NULL, then ASSERT().
1294 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1295 Function and Register.
1296 @param Size Size in bytes of the transfer.
1297 @param Buffer Pointer to a buffer receiving the data read.
1304 PciSegmentReadBuffer (
1305 IN UINT64 StartAddress
,
1312 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1313 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1319 ASSERT (Buffer
!= NULL
);
1322 // Save Size for return
1326 if ((StartAddress
& BIT0
) != 0) {
1328 // Read a byte if StartAddress is byte aligned
1330 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1331 StartAddress
+= sizeof (UINT8
);
1332 Size
-= sizeof (UINT8
);
1333 Buffer
= (UINT8
*)Buffer
+ 1;
1336 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1338 // Read a word if StartAddress is word aligned
1340 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1341 StartAddress
+= sizeof (UINT16
);
1342 Size
-= sizeof (UINT16
);
1343 Buffer
= (UINT16
*)Buffer
+ 1;
1346 while (Size
>= sizeof (UINT32
)) {
1348 // Read as many double words as possible
1350 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1351 StartAddress
+= sizeof (UINT32
);
1352 Size
-= sizeof (UINT32
);
1353 Buffer
= (UINT32
*)Buffer
+ 1;
1356 if (Size
>= sizeof (UINT16
)) {
1358 // Read the last remaining word if exist
1360 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1361 StartAddress
+= sizeof (UINT16
);
1362 Size
-= sizeof (UINT16
);
1363 Buffer
= (UINT16
*)Buffer
+ 1;
1366 if (Size
>= sizeof (UINT8
)) {
1368 // Read the last remaining byte if exist
1370 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1377 Copies the data in a caller supplied buffer to a specified range of PCI
1378 configuration space.
1380 Writes the range of PCI configuration registers specified by StartAddress and
1381 Size from the buffer specified by Buffer. This function only allows the PCI
1382 configuration registers from a single PCI function to be written. Size is
1383 returned. When possible 32-bit PCI configuration write cycles are used to
1384 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1385 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1386 and the end of the range.
1388 If StartAddress > 0x0FFFFFFF, then ASSERT().
1389 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1390 If Size > 0 and Buffer is NULL, then ASSERT().
1392 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1393 Function and Register.
1394 @param Size Size in bytes of the transfer.
1395 @param Buffer Pointer to a buffer containing the data to write.
1397 @return The parameter of Size.
1402 PciSegmentWriteBuffer (
1403 IN UINT64 StartAddress
,
1410 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1411 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1417 ASSERT (Buffer
!= NULL
);
1420 // Save Size for return
1424 if ((StartAddress
& BIT0
) != 0) {
1426 // Write a byte if StartAddress is byte aligned
1428 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1429 StartAddress
+= sizeof (UINT8
);
1430 Size
-= sizeof (UINT8
);
1431 Buffer
= (UINT8
*)Buffer
+ 1;
1434 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1436 // Write a word if StartAddress is word aligned
1438 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1439 StartAddress
+= sizeof (UINT16
);
1440 Size
-= sizeof (UINT16
);
1441 Buffer
= (UINT16
*)Buffer
+ 1;
1444 while (Size
>= sizeof (UINT32
)) {
1446 // Write as many double words as possible
1448 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1449 StartAddress
+= sizeof (UINT32
);
1450 Size
-= sizeof (UINT32
);
1451 Buffer
= (UINT32
*)Buffer
+ 1;
1454 if (Size
>= sizeof (UINT16
)) {
1456 // Write the last remaining word if exist
1458 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1459 StartAddress
+= sizeof (UINT16
);
1460 Size
-= sizeof (UINT16
);
1461 Buffer
= (UINT16
*)Buffer
+ 1;
1464 if (Size
>= sizeof (UINT8
)) {
1466 // Write the last remaining byte if exist
1468 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);