2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are
6 licensed and made available under the terms and conditions of
7 the BSD License which accompanies this distribution. The full
8 text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PciSegmentLib.h"
19 // Global variable to record data of PCI Root Bridge I/O Protocol instances
21 PCI_ROOT_BRIDGE_DATA
*mPciRootBridgeData
= NULL
;
22 UINTN mNumberOfPciRootBridges
= 0;
25 The constructor function caches data of PCI Root Bridge I/O Protocol instances.
27 The constructor function locates PCI Root Bridge I/O protocol instances,
28 and caches the protocol instances, together with their segment numbers and bus ranges.
29 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
31 @param ImageHandle The firmware allocated handle for the EFI image.
32 @param SystemTable A pointer to the EFI System Table.
34 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
39 PciSegmentLibConstructor (
40 IN EFI_HANDLE ImageHandle
,
41 IN EFI_SYSTEM_TABLE
*SystemTable
47 EFI_HANDLE
*HandleBuffer
;
48 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
49 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
53 PciRootBridgeIo
= NULL
;
56 Status
= gBS
->LocateHandleBuffer (
58 &gEfiPciRootBridgeIoProtocolGuid
,
63 ASSERT_EFI_ERROR (Status
);
65 mNumberOfPciRootBridges
= HandleCount
;
67 mPciRootBridgeData
= AllocatePool (HandleCount
* sizeof (PCI_ROOT_BRIDGE_DATA
));
68 ASSERT (mPciRootBridgeData
!= NULL
);
71 // Traverse all PCI Root Bridge I/O Protocol instances, and record the protocol
72 // instances, together with their segment numbers and bus ranges.
74 for (Index
= 0; Index
< HandleCount
; Index
++) {
75 Status
= gBS
->HandleProtocol (
77 &gEfiPciRootBridgeIoProtocolGuid
,
78 (VOID
**) &PciRootBridgeIo
80 ASSERT_EFI_ERROR (Status
);
82 mPciRootBridgeData
[Index
].PciRootBridgeIo
= PciRootBridgeIo
;
83 mPciRootBridgeData
[Index
].SegmentNumber
= PciRootBridgeIo
->SegmentNumber
;
85 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
86 ASSERT_EFI_ERROR (Status
);
88 while (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
89 if (Descriptors
->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
90 mPciRootBridgeData
[Index
].MinBusNumber
= Descriptors
->AddrRangeMin
;
91 mPciRootBridgeData
[Index
].MaxBusNumber
= Descriptors
->AddrRangeMax
;
96 ASSERT (Descriptors
->Desc
!= ACPI_END_TAG_DESCRIPTOR
);
100 // HandleBuffer is allocated by gBS AllocatePool() service.
101 // So, gBS FreePool() service is used to free HandleBuffer.
103 gBS
->FreePool (HandleBuffer
);
109 The destructor function frees memory allocated by constructor.
111 The destructor function frees memory for data of protocol instances allocated by constructor.
112 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
114 @param ImageHandle The firmware allocated handle for the EFI image.
115 @param SystemTable A pointer to the EFI System Table.
117 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
122 PciSegmentLibDestructor (
123 IN EFI_HANDLE ImageHandle
,
124 IN EFI_SYSTEM_TABLE
*SystemTable
127 FreePool (mPciRootBridgeData
);
133 According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.
135 This internal function extracts segment number and bus number data from address, and
136 retrieves the corresponding PCI Root Bridge I/O Protocol instance.
138 @param Address The address that encodes the Segment, PCI Bus, Device, Function and
141 @return The address for PCI Root Bridge I/O Protocol.
144 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*
145 PciSegmentLibSearchForRootBridge (
150 UINT64 SegmentNumber
;
153 for (Index
= 0; Index
< mNumberOfPciRootBridges
; Index
++) {
155 // Matches segment number of address with the segment number of protocol instance.
157 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
158 if (SegmentNumber
== mPciRootBridgeData
[Index
].SegmentNumber
) {
160 // Matches the bus number of address with bus number range of protocol instance.
162 BusNumber
= BitFieldRead64 (Address
, 20, 27);
163 if (BusNumber
>= mPciRootBridgeData
[Index
].MinBusNumber
&& BusNumber
<= mPciRootBridgeData
[Index
].MaxBusNumber
) {
164 return mPciRootBridgeData
[Index
].PciRootBridgeIo
;
172 Internal worker function to read a PCI configuration register.
174 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
175 It reads and returns the PCI configuration register specified by Address,
176 the width of data is specified by Width.
178 @param Address The address that encodes the PCI Bus, Device, Function and
180 @param Width Width of data to read
182 @return The value read from the PCI configuration register.
186 DxePciSegmentLibPciRootBridgeIoReadWorker (
188 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
192 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
194 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
195 ASSERT (PciRootBridgeIo
!= NULL
);
197 PciRootBridgeIo
->Pci
.Read (
200 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
209 Internal worker function to writes a PCI configuration register.
211 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
212 It writes the PCI configuration register specified by Address with the
213 value specified by Data. The width of data is specifed by Width.
216 @param Address The address that encodes the PCI Bus, Device, Function and
218 @param Width Width of data to write
219 @param Data The value to write.
221 @return The value written to the PCI configuration register.
225 DxePciSegmentLibPciRootBridgeIoWriteWorker (
227 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
231 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
233 PciRootBridgeIo
= PciSegmentLibSearchForRootBridge (Address
);
234 ASSERT (PciRootBridgeIo
!= NULL
);
236 PciRootBridgeIo
->Pci
.Write (
239 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
248 Register a PCI device so PCI configuration registers may be accessed after
249 SetVirtualAddressMap().
251 If any reserved bits in Address are set, then ASSERT().
253 @param Address The address that encodes the PCI Bus, Device, Function and
256 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
257 @retval RETURN_UNSUPPORTED An attempt was made to call this function
258 after ExitBootServices().
259 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
260 at runtime could not be mapped.
261 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
262 complete the registration.
267 PciSegmentRegisterForRuntimeAccess (
271 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
272 return RETURN_UNSUPPORTED
;
276 Reads an 8-bit PCI configuration register.
278 Reads and returns the 8-bit PCI configuration register specified by Address.
279 This function must guarantee that all PCI read and write operations are serialized.
281 If any reserved bits in Address are set, then ASSERT().
283 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
285 @return The 8-bit PCI configuration register specified by Address.
294 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
296 return (UINT8
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
300 Writes an 8-bit PCI configuration register.
302 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
303 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
305 If any reserved bits in Address are set, then ASSERT().
307 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
308 @param Value The value to write.
310 @return The value written to the PCI configuration register.
320 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
322 return (UINT8
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
326 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
328 Reads the 8-bit PCI configuration register specified by Address,
329 performs a bitwise OR between the read result and the value specified by OrData,
330 and writes the result to the 8-bit PCI configuration register specified by Address.
331 The value written to the PCI configuration register is returned.
332 This function must guarantee that all PCI read and write operations are serialized.
334 If any reserved bits in Address are set, then ASSERT().
336 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
337 @param OrData The value to OR with the PCI configuration register.
339 @return The value written to the PCI configuration register.
349 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
353 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
355 Reads the 8-bit PCI configuration register specified by Address,
356 performs a bitwise AND between the read result and the value specified by AndData,
357 and writes the result to the 8-bit PCI configuration register specified by Address.
358 The value written to the PCI configuration register is returned.
359 This function must guarantee that all PCI read and write operations are serialized.
360 If any reserved bits in Address are set, then ASSERT().
362 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
363 @param AndData The value to AND with the PCI configuration register.
365 @return The value written to the PCI configuration register.
375 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
379 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
380 followed a bitwise OR with another 8-bit value.
382 Reads the 8-bit PCI configuration register specified by Address,
383 performs a bitwise AND between the read result and the value specified by AndData,
384 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
385 and writes the result to the 8-bit PCI configuration register specified by Address.
386 The value written to the PCI configuration register is returned.
387 This function must guarantee that all PCI read and write operations are serialized.
389 If any reserved bits in Address are set, then ASSERT().
391 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
392 @param AndData The value to AND with the PCI configuration register.
393 @param OrData The value to OR with the PCI configuration register.
395 @return The value written to the PCI configuration register.
400 PciSegmentAndThenOr8 (
406 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
410 Reads a bit field of a PCI configuration register.
412 Reads the bit field in an 8-bit PCI configuration register. The bit field is
413 specified by the StartBit and the EndBit. The value of the bit field is
416 If any reserved bits in Address are set, then ASSERT().
417 If StartBit is greater than 7, then ASSERT().
418 If EndBit is greater than 7, then ASSERT().
419 If EndBit is less than StartBit, then ASSERT().
421 @param Address The PCI configuration register to read.
422 @param StartBit The ordinal of the least significant bit in the bit field.
424 @param EndBit The ordinal of the most significant bit in the bit field.
427 @return The value of the bit field read from the PCI configuration register.
432 PciSegmentBitFieldRead8 (
438 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
442 Writes a bit field to a PCI configuration register.
444 Writes Value to the bit field of the PCI configuration register. The bit
445 field is specified by the StartBit and the EndBit. All other bits in the
446 destination PCI configuration register are preserved. The new value of the
447 8-bit register is returned.
449 If any reserved bits in Address are set, then ASSERT().
450 If StartBit is greater than 7, then ASSERT().
451 If EndBit is greater than 7, then ASSERT().
452 If EndBit is less than StartBit, then ASSERT().
454 @param Address The PCI configuration register to write.
455 @param StartBit The ordinal of the least significant bit in the bit field.
457 @param EndBit The ordinal of the most significant bit in the bit field.
459 @param Value The new value of the bit field.
461 @return The value written back to the PCI configuration register.
466 PciSegmentBitFieldWrite8 (
473 return PciSegmentWrite8 (
475 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
480 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
481 writes the result back to the bit field in the 8-bit port.
483 Reads the 8-bit PCI configuration register specified by Address, performs a
484 bitwise OR between the read result and the value specified by
485 OrData, and writes the result to the 8-bit PCI configuration register
486 specified by Address. The value written to the PCI configuration register is
487 returned. This function must guarantee that all PCI read and write operations
488 are serialized. Extra left bits in OrData are stripped.
490 If any reserved bits in Address are set, then ASSERT().
491 If StartBit is greater than 7, then ASSERT().
492 If EndBit is greater than 7, then ASSERT().
493 If EndBit is less than StartBit, then ASSERT().
495 @param Address The PCI configuration register to write.
496 @param StartBit The ordinal of the least significant bit in the bit field.
498 @param EndBit The ordinal of the most significant bit in the bit field.
500 @param OrData The value to OR with the PCI configuration register.
502 @return The value written back to the PCI configuration register.
507 PciSegmentBitFieldOr8 (
514 return PciSegmentWrite8 (
516 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
521 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
522 AND, and writes the result back to the bit field in the 8-bit register.
524 Reads the 8-bit PCI configuration register specified by Address, performs a
525 bitwise AND between the read result and the value specified by AndData, and
526 writes the result to the 8-bit PCI configuration register specified by
527 Address. The value written to the PCI configuration register is returned.
528 This function must guarantee that all PCI read and write operations are
529 serialized. Extra left bits in AndData are stripped.
531 If any reserved bits in Address are set, then ASSERT().
532 If StartBit is greater than 7, then ASSERT().
533 If EndBit is greater than 7, then ASSERT().
534 If EndBit is less than StartBit, then ASSERT().
536 @param Address The PCI configuration register to write.
537 @param StartBit The ordinal of the least significant bit in the bit field.
539 @param EndBit The ordinal of the most significant bit in the bit field.
541 @param AndData The value to AND with the PCI configuration register.
543 @return The value written back to the PCI configuration register.
548 PciSegmentBitFieldAnd8 (
555 return PciSegmentWrite8 (
557 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
562 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
563 bitwise OR, and writes the result back to the bit field in the
566 Reads the 8-bit PCI configuration register specified by Address, performs a
567 bitwise AND followed by a bitwise OR between the read result and
568 the value specified by AndData, and writes the result to the 8-bit PCI
569 configuration register specified by Address. The value written to the PCI
570 configuration register is returned. This function must guarantee that all PCI
571 read and write operations are serialized. Extra left bits in both AndData and
574 If any reserved bits in Address are set, then ASSERT().
575 If StartBit is greater than 7, then ASSERT().
576 If EndBit is greater than 7, then ASSERT().
577 If EndBit is less than StartBit, then ASSERT().
579 @param Address The PCI configuration register to write.
580 @param StartBit The ordinal of the least significant bit in the bit field.
582 @param EndBit The ordinal of the most significant bit in the bit field.
584 @param AndData The value to AND with the PCI configuration register.
585 @param OrData The value to OR with the result of the AND operation.
587 @return The value written back to the PCI configuration register.
592 PciSegmentBitFieldAndThenOr8 (
600 return PciSegmentWrite8 (
602 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
607 Reads a 16-bit PCI configuration register.
609 Reads and returns the 16-bit PCI configuration register specified by Address.
610 This function must guarantee that all PCI read and write operations are serialized.
612 If any reserved bits in Address are set, then ASSERT().
613 If Address is not aligned on a 16-bit boundary, then ASSERT().
615 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
617 @return The 16-bit PCI configuration register specified by Address.
626 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
628 return (UINT16
) DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
632 Writes a 16-bit PCI configuration register.
634 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
635 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
637 If any reserved bits in Address are set, then ASSERT().
638 If Address is not aligned on a 16-bit boundary, then ASSERT().
640 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
641 @param Value The value to write.
643 @return The parameter of Value.
653 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
655 return (UINT16
) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
659 Performs a bitwise OR of a 16-bit PCI configuration register with
662 Reads the 16-bit PCI configuration register specified by Address, performs a
663 bitwise OR between the read result and the value specified by
664 OrData, and writes the result to the 16-bit PCI configuration register
665 specified by Address. The value written to the PCI configuration register is
666 returned. This function must guarantee that all PCI read and write operations
669 If any reserved bits in Address are set, then ASSERT().
670 If Address is not aligned on a 16-bit boundary, then ASSERT().
672 @param Address The address that encodes the PCI Segment, Bus, Device, Function and
674 @param OrData The value to OR with the PCI configuration register.
676 @return The value written back to the PCI configuration register.
686 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
690 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
692 Reads the 16-bit PCI configuration register specified by Address,
693 performs a bitwise AND between the read result and the value specified by AndData,
694 and writes the result to the 16-bit PCI configuration register specified by Address.
695 The value written to the PCI configuration register is returned.
696 This function must guarantee that all PCI read and write operations are serialized.
698 If any reserved bits in Address are set, then ASSERT().
699 If Address is not aligned on a 16-bit boundary, then ASSERT().
701 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
702 @param AndData The value to AND with the PCI configuration register.
704 @return The value written to the PCI configuration register.
714 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
718 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
719 followed a bitwise OR with another 16-bit value.
721 Reads the 16-bit PCI configuration register specified by Address,
722 performs a bitwise AND between the read result and the value specified by AndData,
723 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
724 and writes the result to the 16-bit PCI configuration register specified by Address.
725 The value written to the PCI configuration register is returned.
726 This function must guarantee that all PCI read and write operations are serialized.
728 If any reserved bits in Address are set, then ASSERT().
729 If Address is not aligned on a 16-bit boundary, then ASSERT().
731 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
732 @param AndData The value to AND with the PCI configuration register.
733 @param OrData The value to OR with the PCI configuration register.
735 @return The value written to the PCI configuration register.
740 PciSegmentAndThenOr16 (
746 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
750 Reads a bit field of a PCI configuration register.
752 Reads the bit field in a 16-bit PCI configuration register. The bit field is
753 specified by the StartBit and the EndBit. The value of the bit field is
756 If any reserved bits in Address are set, then ASSERT().
757 If Address is not aligned on a 16-bit boundary, then ASSERT().
758 If StartBit is greater than 15, then ASSERT().
759 If EndBit is greater than 15, then ASSERT().
760 If EndBit is less than StartBit, then ASSERT().
762 @param Address The PCI configuration register to read.
763 @param StartBit The ordinal of the least significant bit in the bit field.
765 @param EndBit The ordinal of the most significant bit in the bit field.
768 @return The value of the bit field read from the PCI configuration register.
773 PciSegmentBitFieldRead16 (
779 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
783 Writes a bit field to a PCI configuration register.
785 Writes Value to the bit field of the PCI configuration register. The bit
786 field is specified by the StartBit and the EndBit. All other bits in the
787 destination PCI configuration register are preserved. The new value of the
788 16-bit register is returned.
790 If any reserved bits in Address are set, then ASSERT().
791 If Address is not aligned on a 16-bit boundary, then ASSERT().
792 If StartBit is greater than 15, then ASSERT().
793 If EndBit is greater than 15, then ASSERT().
794 If EndBit is less than StartBit, then ASSERT().
796 @param Address The PCI configuration register to write.
797 @param StartBit The ordinal of the least significant bit in the bit field.
799 @param EndBit The ordinal of the most significant bit in the bit field.
801 @param Value The new value of the bit field.
803 @return The value written back to the PCI configuration register.
808 PciSegmentBitFieldWrite16 (
815 return PciSegmentWrite16 (
817 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
822 Reads the 16-bit PCI configuration register specified by Address,
823 performs a bitwise OR between the read result and the value specified by OrData,
824 and writes the result to the 16-bit PCI configuration register specified by Address.
826 If any reserved bits in Address are set, then ASSERT().
827 If Address is not aligned on a 16-bit boundary, then ASSERT().
828 If StartBit is greater than 15, then ASSERT().
829 If EndBit is greater than 15, then ASSERT().
830 If EndBit is less than StartBit, then ASSERT().
832 @param Address The PCI configuration register to write.
833 @param StartBit The ordinal of the least significant bit in the bit field.
835 @param EndBit The ordinal of the most significant bit in the bit field.
837 @param OrData The value to OR with the PCI configuration register.
839 @return The value written back to the PCI configuration register.
844 PciSegmentBitFieldOr16 (
851 return PciSegmentWrite16 (
853 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
858 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
859 and writes the result back to the bit field in the 16-bit port.
861 Reads the 16-bit PCI configuration register specified by Address,
862 performs a bitwise OR between the read result and the value specified by OrData,
863 and writes the result to the 16-bit PCI configuration register specified by Address.
864 The value written to the PCI configuration register is returned.
865 This function must guarantee that all PCI read and write operations are serialized.
866 Extra left bits in OrData are stripped.
868 If any reserved bits in Address are set, then ASSERT().
869 If Address is not aligned on a 16-bit boundary, then ASSERT().
870 If StartBit is greater than 7, then ASSERT().
871 If EndBit is greater than 7, then ASSERT().
872 If EndBit is less than StartBit, then ASSERT().
874 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
875 @param StartBit The ordinal of the least significant bit in the bit field.
876 The ordinal of the least significant bit in a byte is bit 0.
877 @param EndBit The ordinal of the most significant bit in the bit field.
878 The ordinal of the most significant bit in a byte is bit 7.
879 @param AndData The value to AND with the read value from the PCI configuration register.
881 @return The value written to the PCI configuration register.
886 PciSegmentBitFieldAnd16 (
893 return PciSegmentWrite16 (
895 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
900 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
901 bitwise OR, and writes the result back to the bit field in the
904 Reads the 16-bit PCI configuration register specified by Address, performs a
905 bitwise AND followed by a bitwise OR between the read result and
906 the value specified by AndData, and writes the result to the 16-bit PCI
907 configuration register specified by Address. The value written to the PCI
908 configuration register is returned. This function must guarantee that all PCI
909 read and write operations are serialized. Extra left bits in both AndData and
912 If any reserved bits in Address are set, then ASSERT().
913 If StartBit is greater than 15, then ASSERT().
914 If EndBit is greater than 15, then ASSERT().
915 If EndBit is less than StartBit, then ASSERT().
917 @param Address The PCI configuration register to write.
918 @param StartBit The ordinal of the least significant bit in the bit field.
920 @param EndBit The ordinal of the most significant bit in the bit field.
922 @param AndData The value to AND with the PCI configuration register.
923 @param OrData The value to OR with the result of the AND operation.
925 @return The value written back to the PCI configuration register.
930 PciSegmentBitFieldAndThenOr16 (
938 return PciSegmentWrite16 (
940 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
945 Reads a 32-bit PCI configuration register.
947 Reads and returns the 32-bit PCI configuration register specified by Address.
948 This function must guarantee that all PCI read and write operations are serialized.
950 If any reserved bits in Address are set, then ASSERT().
951 If Address is not aligned on a 32-bit boundary, then ASSERT().
953 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
955 @return The 32-bit PCI configuration register specified by Address.
964 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
966 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
970 Writes a 32-bit PCI configuration register.
972 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
973 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
975 If any reserved bits in Address are set, then ASSERT().
976 If Address is not aligned on a 32-bit boundary, then ASSERT().
978 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
979 @param Value The value to write.
981 @return The parameter of Value.
991 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
993 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
997 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
999 Reads the 32-bit PCI configuration register specified by Address,
1000 performs a bitwise OR between the read result and the value specified by OrData,
1001 and writes the result to the 32-bit PCI configuration register specified by Address.
1002 The value written to the PCI configuration register is returned.
1003 This function must guarantee that all PCI read and write operations are serialized.
1005 If any reserved bits in Address are set, then ASSERT().
1006 If Address is not aligned on a 32-bit boundary, then ASSERT().
1008 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
1009 @param OrData The value to OR with the PCI configuration register.
1011 @return The value written to the PCI configuration register.
1021 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
1025 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
1027 Reads the 32-bit PCI configuration register specified by Address,
1028 performs a bitwise AND between the read result and the value specified by AndData,
1029 and writes the result to the 32-bit PCI configuration register specified by Address.
1030 The value written to the PCI configuration register is returned.
1031 This function must guarantee that all PCI read and write operations are serialized.
1033 If any reserved bits in Address are set, then ASSERT().
1034 If Address is not aligned on a 32-bit boundary, then ASSERT().
1036 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
1037 @param AndData The value to AND with the PCI configuration register.
1039 @return The value written to the PCI configuration register.
1049 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
1053 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
1054 followed a bitwise OR with another 32-bit value.
1056 Reads the 32-bit PCI configuration register specified by Address,
1057 performs a bitwise AND between the read result and the value specified by AndData,
1058 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
1059 and writes the result to the 32-bit PCI configuration register specified by Address.
1060 The value written to the PCI configuration register is returned.
1061 This function must guarantee that all PCI read and write operations are serialized.
1063 If any reserved bits in Address are set, then ASSERT().
1064 If Address is not aligned on a 32-bit boundary, then ASSERT().
1066 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
1067 @param AndData The value to AND with the PCI configuration register.
1068 @param OrData The value to OR with the PCI configuration register.
1070 @return The value written to the PCI configuration register.
1075 PciSegmentAndThenOr32 (
1081 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1085 Reads a bit field of a PCI configuration register.
1087 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1088 specified by the StartBit and the EndBit. The value of the bit field is
1091 If any reserved bits in Address are set, then ASSERT().
1092 If Address is not aligned on a 32-bit boundary, then ASSERT().
1093 If StartBit is greater than 31, then ASSERT().
1094 If EndBit is greater than 31, then ASSERT().
1095 If EndBit is less than StartBit, then ASSERT().
1097 @param Address The PCI configuration register to read.
1098 @param StartBit The ordinal of the least significant bit in the bit field.
1100 @param EndBit The ordinal of the most significant bit in the bit field.
1103 @return The value of the bit field read from the PCI configuration register.
1108 PciSegmentBitFieldRead32 (
1114 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1118 Writes a bit field to a PCI configuration register.
1120 Writes Value to the bit field of the PCI configuration register. The bit
1121 field is specified by the StartBit and the EndBit. All other bits in the
1122 destination PCI configuration register are preserved. The new value of the
1123 32-bit register is returned.
1125 If any reserved bits in Address are set, then ASSERT().
1126 If Address is not aligned on a 32-bit boundary, then ASSERT().
1127 If StartBit is greater than 31, then ASSERT().
1128 If EndBit is greater than 31, then ASSERT().
1129 If EndBit is less than StartBit, then ASSERT().
1131 @param Address The PCI configuration register to write.
1132 @param StartBit The ordinal of the least significant bit in the bit field.
1134 @param EndBit The ordinal of the most significant bit in the bit field.
1136 @param Value The new value of the bit field.
1138 @return The value written back to the PCI configuration register.
1143 PciSegmentBitFieldWrite32 (
1150 return PciSegmentWrite32 (
1152 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1157 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1158 writes the result back to the bit field in the 32-bit port.
1160 Reads the 32-bit PCI configuration register specified by Address, performs a
1161 bitwise OR between the read result and the value specified by
1162 OrData, and writes the result to the 32-bit PCI configuration register
1163 specified by Address. The value written to the PCI configuration register is
1164 returned. This function must guarantee that all PCI read and write operations
1165 are serialized. Extra left bits in OrData are stripped.
1167 If any reserved bits in Address are set, then ASSERT().
1168 If StartBit is greater than 31, then ASSERT().
1169 If EndBit is greater than 31, then ASSERT().
1170 If EndBit is less than StartBit, then ASSERT().
1172 @param Address The PCI configuration register to write.
1173 @param StartBit The ordinal of the least significant bit in the bit field.
1175 @param EndBit The ordinal of the most significant bit in the bit field.
1177 @param OrData The value to OR with the PCI configuration register.
1179 @return The value written back to the PCI configuration register.
1184 PciSegmentBitFieldOr32 (
1191 return PciSegmentWrite32 (
1193 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1198 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1199 AND, and writes the result back to the bit field in the 32-bit register.
1202 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1203 AND between the read result and the value specified by AndData, and writes the result
1204 to the 32-bit PCI configuration register specified by Address. The value written to
1205 the PCI configuration register is returned. This function must guarantee that all PCI
1206 read and write operations are serialized. Extra left bits in AndData are stripped.
1207 If any reserved bits in Address are set, then ASSERT().
1208 If Address is not aligned on a 32-bit boundary, then ASSERT().
1209 If StartBit is greater than 31, then ASSERT().
1210 If EndBit is greater than 31, then ASSERT().
1211 If EndBit is less than StartBit, then ASSERT().
1214 @param Address The PCI configuration register to write.
1215 @param StartBit The ordinal of the least significant bit in the bit field.
1217 @param EndBit The ordinal of the most significant bit in the bit field.
1219 @param AndData The value to AND with the PCI configuration register.
1221 @return The value written back to the PCI configuration register.
1226 PciSegmentBitFieldAnd32 (
1233 return PciSegmentWrite32 (
1235 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1240 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1241 bitwise OR, and writes the result back to the bit field in the
1244 Reads the 32-bit PCI configuration register specified by Address, performs a
1245 bitwise AND followed by a bitwise OR between the read result and
1246 the value specified by AndData, and writes the result to the 32-bit PCI
1247 configuration register specified by Address. The value written to the PCI
1248 configuration register is returned. This function must guarantee that all PCI
1249 read and write operations are serialized. Extra left bits in both AndData and
1250 OrData are stripped.
1252 If any reserved bits in Address are set, then ASSERT().
1253 If StartBit is greater than 31, then ASSERT().
1254 If EndBit is greater than 31, then ASSERT().
1255 If EndBit is less than StartBit, then ASSERT().
1257 @param Address The PCI configuration register to write.
1258 @param StartBit The ordinal of the least significant bit in the bit field.
1260 @param EndBit The ordinal of the most significant bit in the bit field.
1262 @param AndData The value to AND with the PCI configuration register.
1263 @param OrData The value to OR with the result of the AND operation.
1265 @return The value written back to the PCI configuration register.
1270 PciSegmentBitFieldAndThenOr32 (
1278 return PciSegmentWrite32 (
1280 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1285 Reads a range of PCI configuration registers into a caller supplied buffer.
1287 Reads the range of PCI configuration registers specified by StartAddress and
1288 Size into the buffer specified by Buffer. This function only allows the PCI
1289 configuration registers from a single PCI function to be read. Size is
1290 returned. When possible 32-bit PCI configuration read cycles are used to read
1291 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1292 and 16-bit PCI configuration read cycles may be used at the beginning and the
1295 If any reserved bits in StartAddress are set, then ASSERT().
1296 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1297 If Size > 0 and Buffer is NULL, then ASSERT().
1299 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,
1300 Function and Register.
1301 @param Size The size in bytes of the transfer.
1302 @param Buffer The pointer to a buffer receiving the data read.
1309 PciSegmentReadBuffer (
1310 IN UINT64 StartAddress
,
1317 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1318 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1324 ASSERT (Buffer
!= NULL
);
1327 // Save Size for return
1331 if ((StartAddress
& BIT0
) != 0) {
1333 // Read a byte if StartAddress is byte aligned
1335 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1336 StartAddress
+= sizeof (UINT8
);
1337 Size
-= sizeof (UINT8
);
1338 Buffer
= (UINT8
*)Buffer
+ 1;
1341 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1343 // Read a word if StartAddress is word aligned
1345 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1346 StartAddress
+= sizeof (UINT16
);
1347 Size
-= sizeof (UINT16
);
1348 Buffer
= (UINT16
*)Buffer
+ 1;
1351 while (Size
>= sizeof (UINT32
)) {
1353 // Read as many double words as possible
1355 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1356 StartAddress
+= sizeof (UINT32
);
1357 Size
-= sizeof (UINT32
);
1358 Buffer
= (UINT32
*)Buffer
+ 1;
1361 if (Size
>= sizeof (UINT16
)) {
1363 // Read the last remaining word if exist
1365 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1366 StartAddress
+= sizeof (UINT16
);
1367 Size
-= sizeof (UINT16
);
1368 Buffer
= (UINT16
*)Buffer
+ 1;
1371 if (Size
>= sizeof (UINT8
)) {
1373 // Read the last remaining byte if exist
1375 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1382 Copies the data in a caller supplied buffer to a specified range of PCI
1383 configuration space.
1385 Writes the range of PCI configuration registers specified by StartAddress and
1386 Size from the buffer specified by Buffer. This function only allows the PCI
1387 configuration registers from a single PCI function to be written. Size is
1388 returned. When possible 32-bit PCI configuration write cycles are used to
1389 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1390 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1391 and the end of the range.
1393 If any reserved bits in StartAddress are set, then ASSERT().
1394 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1395 If Size > 0 and Buffer is NULL, then ASSERT().
1397 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,
1398 Function and Register.
1399 @param Size The size in bytes of the transfer.
1400 @param Buffer The pointer to a buffer containing the data to write.
1402 @return The parameter of Size.
1407 PciSegmentWriteBuffer (
1408 IN UINT64 StartAddress
,
1415 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1416 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1422 ASSERT (Buffer
!= NULL
);
1425 // Save Size for return
1429 if ((StartAddress
& BIT0
) != 0) {
1431 // Write a byte if StartAddress is byte aligned
1433 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1434 StartAddress
+= sizeof (UINT8
);
1435 Size
-= sizeof (UINT8
);
1436 Buffer
= (UINT8
*)Buffer
+ 1;
1439 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1441 // Write a word if StartAddress is word aligned
1443 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1444 StartAddress
+= sizeof (UINT16
);
1445 Size
-= sizeof (UINT16
);
1446 Buffer
= (UINT16
*)Buffer
+ 1;
1449 while (Size
>= sizeof (UINT32
)) {
1451 // Write as many double words as possible
1453 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1454 StartAddress
+= sizeof (UINT32
);
1455 Size
-= sizeof (UINT32
);
1456 Buffer
= (UINT32
*)Buffer
+ 1;
1459 if (Size
>= sizeof (UINT16
)) {
1461 // Write the last remaining word if exist
1463 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1464 StartAddress
+= sizeof (UINT16
);
1465 Size
-= sizeof (UINT16
);
1466 Buffer
= (UINT16
*)Buffer
+ 1;
1469 if (Size
>= sizeof (UINT8
)) {
1471 // Write the last remaining byte if exist
1473 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);