2 PCI Segment Library implementation using PCI CFG2 PPI.
4 Copyright (c) 2007 - 2012, 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.
18 #include <Ppi/PciCfg2.h>
20 #include <Library/PciSegmentLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/PeiServicesTablePointerLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/PeiServicesLib.h>
27 Assert the validity of a PCI Segment address.
28 A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
30 @param A The address to validate.
31 @param M Additional bits to assert to be zero.
34 #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
35 ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
38 Translate PCI Lib address into format of PCI CFG2 PPI.
40 @param A The address that encodes the PCI Bus, Device, Function and
44 #define PCI_TO_PCICFG2_ADDRESS(A) \
45 ((((UINT32)(A) << 4) & 0xff000000) | (((UINT32)(A) >> 4) & 0x00000700) | (((UINT32)(A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))
50 This internal function retrieves PCI CFG2 PPI from PPI database.
52 @param Address The address that encodes the PCI Segment, Bus, Device,
53 Function and Register.
55 @return The pointer to PCI CFG2 PPI.
58 EFI_PEI_PCI_CFG2_PPI
*
59 InternalGetPciCfg2Ppi (
65 EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
70 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
73 // Loop through all instances of the PPI and match segment number
76 Status
= PeiServicesLocatePpi(
82 ASSERT_EFI_ERROR (Status
);
84 } while (PciCfg2Ppi
->Segment
!= SegmentNumber
);
90 Internal worker function to read a PCI configuration register.
92 This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service.
93 It reads and returns the PCI configuration register specified by Address,
94 the width of data is specified by Width.
96 @param Address The address that encodes the PCI Bus, Device, Function and
98 @param Width The width of data to read
100 @return The value read from the PCI configuration register.
104 PeiPciSegmentLibPciCfg2ReadWorker (
106 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
110 CONST EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
111 UINT64 PciCfg2Address
;
113 PciCfg2Ppi
= InternalGetPciCfg2Ppi (Address
);
114 PciCfg2Address
= PCI_TO_PCICFG2_ADDRESS (Address
);
116 GetPeiServicesTablePointer (),
127 Internal worker function to writes a PCI configuration register.
129 This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.
130 It writes the PCI configuration register specified by Address with the
131 value specified by Data. The width of data is specifed by Width.
134 @param Address The address that encodes the PCI Bus, Device, Function and
136 @param Width The width of data to write
137 @param Data The value to write.
139 @return The value written to the PCI configuration register.
143 PeiPciSegmentLibPciCfg2WriteWorker (
145 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
149 CONST EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
150 UINT64 PciCfg2Address
;
152 PciCfg2Ppi
= InternalGetPciCfg2Ppi (Address
);
153 PciCfg2Address
= PCI_TO_PCICFG2_ADDRESS (Address
);
155 GetPeiServicesTablePointer (),
166 Register a PCI device so PCI configuration registers may be accessed after
167 SetVirtualAddressMap().
169 If any reserved bits in Address are set, then ASSERT().
171 @param Address The address that encodes the PCI Bus, Device, Function and
174 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
175 @retval RETURN_UNSUPPORTED An attempt was made to call this function
176 after ExitBootServices().
177 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
178 at runtime could not be mapped.
179 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
180 complete the registration.
185 PciSegmentRegisterForRuntimeAccess (
189 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
190 return RETURN_UNSUPPORTED
;
194 Reads an 8-bit PCI configuration register.
196 Reads and returns the 8-bit PCI configuration register specified by Address.
197 This function must guarantee that all PCI read and write operations are serialized.
199 If any reserved bits in Address are set, then ASSERT().
201 @param Address The address that encodes the PCI Segment, Bus, Device, Function,
204 @return The 8-bit PCI configuration register specified by Address.
213 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
215 return (UINT8
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint8
);
219 Writes an 8-bit PCI configuration register.
221 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
222 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
224 If any reserved bits in Address are set, then ASSERT().
226 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
227 @param Value The value to write.
229 @return The value written to the PCI configuration register.
239 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
241 return (UINT8
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint8
, Value
);
245 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
247 Reads the 8-bit PCI configuration register specified by Address,
248 performs a bitwise OR between the read result and the value specified by OrData,
249 and writes the result to the 8-bit PCI configuration register specified by Address.
250 The value written to the PCI configuration register is returned.
251 This function must guarantee that all PCI read and write operations are serialized.
253 If any reserved bits in Address are set, then ASSERT().
255 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
256 @param OrData The value to OR with the PCI configuration register.
258 @return The value written to the PCI configuration register.
268 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
272 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
274 Reads the 8-bit PCI configuration register specified by Address,
275 performs a bitwise AND between the read result and the value specified by AndData,
276 and writes the result to the 8-bit PCI configuration register specified by Address.
277 The value written to the PCI configuration register is returned.
278 This function must guarantee that all PCI read and write operations are serialized.
279 If any reserved bits in Address are set, then ASSERT().
281 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
282 @param AndData The value to AND with the PCI configuration register.
284 @return The value written to the PCI configuration register.
294 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
298 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
299 followed a bitwise OR with another 8-bit value.
301 Reads the 8-bit PCI configuration register specified by Address,
302 performs a bitwise AND between the read result and the value specified by AndData,
303 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
304 and writes the result to the 8-bit PCI configuration register specified by Address.
305 The value written to the PCI configuration register is returned.
306 This function must guarantee that all PCI read and write operations are serialized.
308 If any reserved bits in Address are set, then ASSERT().
310 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
311 @param AndData The value to AND with the PCI configuration register.
312 @param OrData The value to OR with the PCI configuration register.
314 @return The value written to the PCI configuration register.
319 PciSegmentAndThenOr8 (
325 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
329 Reads a bit field of a PCI configuration register.
331 Reads the bit field in an 8-bit PCI configuration register. The bit field is
332 specified by the StartBit and the EndBit. The value of the bit field is
335 If any reserved bits in Address are set, then ASSERT().
336 If StartBit is greater than 7, then ASSERT().
337 If EndBit is greater than 7, then ASSERT().
338 If EndBit is less than StartBit, then ASSERT().
340 @param Address The PCI configuration register to read.
341 @param StartBit The ordinal of the least significant bit in the bit field.
343 @param EndBit The ordinal of the most significant bit in the bit field.
346 @return The value of the bit field read from the PCI configuration register.
351 PciSegmentBitFieldRead8 (
357 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
361 Writes a bit field to a PCI configuration register.
363 Writes Value to the bit field of the PCI configuration register. The bit
364 field is specified by the StartBit and the EndBit. All other bits in the
365 destination PCI configuration register are preserved. The new value of the
366 8-bit register is returned.
368 If any reserved bits in Address are set, then ASSERT().
369 If StartBit is greater than 7, then ASSERT().
370 If EndBit is greater than 7, then ASSERT().
371 If EndBit is less than StartBit, then ASSERT().
372 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
374 @param Address The PCI configuration register to write.
375 @param StartBit The ordinal of the least significant bit in the bit field.
377 @param EndBit The ordinal of the most significant bit in the bit field.
379 @param Value The new value of the bit field.
381 @return The value written back to the PCI configuration register.
386 PciSegmentBitFieldWrite8 (
393 return PciSegmentWrite8 (
395 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
400 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
401 writes the result back to the bit field in the 8-bit port.
403 Reads the 8-bit PCI configuration register specified by Address, performs a
404 bitwise OR between the read result and the value specified by
405 OrData, and writes the result to the 8-bit PCI configuration register
406 specified by Address. The value written to the PCI configuration register is
407 returned. This function must guarantee that all PCI read and write operations
408 are serialized. Extra left bits in OrData are stripped.
410 If any reserved bits in Address are set, then ASSERT().
411 If StartBit is greater than 7, then ASSERT().
412 If EndBit is greater than 7, then ASSERT().
413 If EndBit is less than StartBit, then ASSERT().
414 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
416 @param Address The PCI configuration register to write.
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.
421 @param OrData The value to OR with the PCI configuration register.
423 @return The value written back to the PCI configuration register.
428 PciSegmentBitFieldOr8 (
435 return PciSegmentWrite8 (
437 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
442 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
443 AND, and writes the result back to the bit field in the 8-bit register.
445 Reads the 8-bit PCI configuration register specified by Address, performs a
446 bitwise AND between the read result and the value specified by AndData, and
447 writes the result to the 8-bit PCI configuration register specified by
448 Address. The value written to the PCI configuration register is returned.
449 This function must guarantee that all PCI read and write operations are
450 serialized. Extra left bits in AndData are stripped.
452 If any reserved bits in Address are set, then ASSERT().
453 If StartBit is greater than 7, then ASSERT().
454 If EndBit is greater than 7, then ASSERT().
455 If EndBit is less than StartBit, then ASSERT().
456 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
458 @param Address The PCI configuration register to write.
459 @param StartBit The ordinal of the least significant bit in the bit field.
461 @param EndBit The ordinal of the most significant bit in the bit field.
463 @param AndData The value to AND with the PCI configuration register.
465 @return The value written back to the PCI configuration register.
470 PciSegmentBitFieldAnd8 (
477 return PciSegmentWrite8 (
479 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
484 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
485 bitwise OR, and writes the result back to the bit field in the
488 Reads the 8-bit PCI configuration register specified by Address, performs a
489 bitwise AND followed by a bitwise OR between the read result and
490 the value specified by AndData, and writes the result to the 8-bit PCI
491 configuration register specified by Address. The value written to the PCI
492 configuration register is returned. This function must guarantee that all PCI
493 read and write operations are serialized. Extra left bits in both AndData and
496 If any reserved bits in Address are set, then ASSERT().
497 If StartBit is greater than 7, then ASSERT().
498 If EndBit is greater than 7, then ASSERT().
499 If EndBit is less than StartBit, then ASSERT().
500 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
501 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
503 @param Address The 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 AndData The value to AND with the PCI configuration register.
509 @param OrData The value to OR with the result of the AND operation.
511 @return The value written back to the PCI configuration register.
516 PciSegmentBitFieldAndThenOr8 (
524 return PciSegmentWrite8 (
526 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
531 Reads a 16-bit PCI configuration register.
533 Reads and returns the 16-bit PCI configuration register specified by Address.
534 This function must guarantee that all PCI read and write operations are serialized.
536 If any reserved bits in Address are set, then ASSERT().
537 If Address is not aligned on a 16-bit boundary, then ASSERT().
539 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
541 @return The 16-bit PCI configuration register specified by Address.
550 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
552 return (UINT16
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint16
);
556 Writes a 16-bit PCI configuration register.
558 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
559 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
561 If any reserved bits in Address are set, then ASSERT().
562 If Address is not aligned on a 16-bit boundary, then ASSERT().
564 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
565 @param Value The value to write.
567 @return The parameter of Value.
577 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
579 return (UINT16
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint16
, Value
);
583 Performs a bitwise OR of a 16-bit PCI configuration register with
586 Reads the 16-bit PCI configuration register specified by Address, performs a
587 bitwise OR between the read result and the value specified by
588 OrData, and writes the result to the 16-bit PCI configuration register
589 specified by Address. The value written to the PCI configuration register is
590 returned. This function must guarantee that all PCI read and write operations
593 If any reserved bits in Address are set, then ASSERT().
594 If Address is not aligned on a 16-bit boundary, then ASSERT().
596 @param Address The address that encodes the PCI Segment, Bus, Device, Function and
598 @param OrData The value to OR with the PCI configuration register.
600 @return The value written back to the PCI configuration register.
610 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
614 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
616 Reads the 16-bit PCI configuration register specified by Address,
617 performs a bitwise AND between the read result and the value specified by AndData,
618 and writes the result to the 16-bit PCI configuration register specified by Address.
619 The value written to the PCI configuration register is returned.
620 This function must guarantee that all PCI read and write operations are serialized.
622 If any reserved bits in Address are set, then ASSERT().
623 If Address is not aligned on a 16-bit boundary, then ASSERT().
625 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
626 @param AndData The value to AND with the PCI configuration register.
628 @return The value written to the PCI configuration register.
638 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
642 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
643 followed a bitwise OR with another 16-bit value.
645 Reads the 16-bit PCI configuration register specified by Address,
646 performs a bitwise AND between the read result and the value specified by AndData,
647 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
648 and writes the result to the 16-bit PCI configuration register specified by Address.
649 The value written to the PCI configuration register is returned.
650 This function must guarantee that all PCI read and write operations are serialized.
652 If any reserved bits in Address are set, then ASSERT().
653 If Address is not aligned on a 16-bit boundary, then ASSERT().
655 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
656 @param AndData The value to AND with the PCI configuration register.
657 @param OrData The value to OR with the PCI configuration register.
659 @return The value written to the PCI configuration register.
664 PciSegmentAndThenOr16 (
670 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
674 Reads a bit field of a PCI configuration register.
676 Reads the bit field in a 16-bit PCI configuration register. The bit field is
677 specified by the StartBit and the EndBit. The value of the bit field is
680 If any reserved bits in Address are set, then ASSERT().
681 If Address is not aligned on a 16-bit boundary, then ASSERT().
682 If StartBit is greater than 15, then ASSERT().
683 If EndBit is greater than 15, then ASSERT().
684 If EndBit is less than StartBit, then ASSERT().
686 @param Address The PCI configuration register to read.
687 @param StartBit The ordinal of the least significant bit in the bit field.
689 @param EndBit The ordinal of the most significant bit in the bit field.
692 @return The value of the bit field read from the PCI configuration register.
697 PciSegmentBitFieldRead16 (
703 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
707 Writes a bit field to a PCI configuration register.
709 Writes Value to the bit field of the PCI configuration register. The bit
710 field is specified by the StartBit and the EndBit. All other bits in the
711 destination PCI configuration register are preserved. The new value of the
712 16-bit register is returned.
714 If any reserved bits in Address are set, then ASSERT().
715 If Address is not aligned on a 16-bit boundary, then ASSERT().
716 If StartBit is greater than 15, then ASSERT().
717 If EndBit is greater than 15, then ASSERT().
718 If EndBit is less than StartBit, then ASSERT().
719 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
721 @param Address The PCI configuration register to write.
722 @param StartBit The ordinal of the least significant bit in the bit field.
724 @param EndBit The ordinal of the most significant bit in the bit field.
726 @param Value The new value of the bit field.
728 @return The value written back to the PCI configuration register.
733 PciSegmentBitFieldWrite16 (
740 return PciSegmentWrite16 (
742 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
747 Reads the 16-bit PCI configuration register specified by Address,
748 performs a bitwise OR between the read result and the value specified by OrData,
749 and writes the result to the 16-bit PCI configuration register specified by Address.
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().
756 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
758 @param Address The PCI configuration register to write.
759 @param StartBit The ordinal of the least significant bit in the bit field.
761 @param EndBit The ordinal of the most significant bit in the bit field.
763 @param OrData The value to OR with the PCI configuration register.
765 @return The value written back to the PCI configuration register.
770 PciSegmentBitFieldOr16 (
777 return PciSegmentWrite16 (
779 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
784 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
785 and writes the result back to the bit field in the 16-bit port.
787 Reads the 16-bit PCI configuration register specified by Address,
788 performs a bitwise OR between the read result and the value specified by OrData,
789 and writes the result to the 16-bit PCI configuration register specified by Address.
790 The value written to the PCI configuration register is returned.
791 This function must guarantee that all PCI read and write operations are serialized.
792 Extra left bits in OrData are stripped.
794 If any reserved bits in Address are set, then ASSERT().
795 If Address is not aligned on a 16-bit boundary, then ASSERT().
796 If StartBit is greater than 7, then ASSERT().
797 If EndBit is greater than 7, then ASSERT().
798 If EndBit is less than StartBit, then ASSERT().
799 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
801 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
802 @param StartBit The ordinal of the least significant bit in the bit field.
803 The ordinal of the least significant bit in a byte is bit 0.
804 @param EndBit The ordinal of the most significant bit in the bit field.
805 The ordinal of the most significant bit in a byte is bit 7.
806 @param AndData The value to AND with the read value from the PCI configuration register.
808 @return The value written to the PCI configuration register.
813 PciSegmentBitFieldAnd16 (
820 return PciSegmentWrite16 (
822 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
827 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
828 bitwise OR, and writes the result back to the bit field in the
831 Reads the 16-bit PCI configuration register specified by Address, performs a
832 bitwise AND followed by a bitwise OR between the read result and
833 the value specified by AndData, and writes the result to the 16-bit PCI
834 configuration register specified by Address. The value written to the PCI
835 configuration register is returned. This function must guarantee that all PCI
836 read and write operations are serialized. Extra left bits in both AndData and
839 If any reserved bits in Address are set, then ASSERT().
840 If StartBit is greater than 15, then ASSERT().
841 If EndBit is greater than 15, then ASSERT().
842 If EndBit is less than StartBit, then ASSERT().
843 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
844 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
846 @param Address The PCI configuration register to write.
847 @param StartBit The ordinal of the least significant bit in the bit field.
849 @param EndBit The ordinal of the most significant bit in the bit field.
851 @param AndData The value to AND with the PCI configuration register.
852 @param OrData The value to OR with the result of the AND operation.
854 @return The value written back to the PCI configuration register.
859 PciSegmentBitFieldAndThenOr16 (
867 return PciSegmentWrite16 (
869 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
874 Reads a 32-bit PCI configuration register.
876 Reads and returns the 32-bit PCI configuration register specified by Address.
877 This function must guarantee that all PCI read and write operations are serialized.
879 If any reserved bits in Address are set, then ASSERT().
880 If Address is not aligned on a 32-bit boundary, then ASSERT().
882 @param Address The address that encodes the PCI Segment, Bus, Device, Function,
885 @return The 32-bit PCI configuration register specified by Address.
894 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
896 return PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint32
);
900 Writes a 32-bit PCI configuration register.
902 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
903 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
905 If any reserved bits in Address are set, then ASSERT().
906 If Address is not aligned on a 32-bit boundary, then ASSERT().
908 @param Address The address that encodes the PCI Segment, Bus, Device,
909 Function, and Register.
910 @param Value The value to write.
912 @return The parameter of Value.
922 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
924 return PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint32
, Value
);
928 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
930 Reads the 32-bit PCI configuration register specified by Address,
931 performs a bitwise OR between the read result and the value specified by OrData,
932 and writes the result to the 32-bit PCI configuration register specified by Address.
933 The value written to the PCI configuration register is returned.
934 This function must guarantee that all PCI read and write operations are serialized.
936 If any reserved bits in Address are set, then ASSERT().
937 If Address is not aligned on a 32-bit boundary, then ASSERT().
939 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
940 @param OrData The value to OR with the PCI configuration register.
942 @return The value written to the PCI configuration register.
952 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
956 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
958 Reads the 32-bit PCI configuration register specified by Address,
959 performs a bitwise AND between the read result and the value specified by AndData,
960 and writes the result to the 32-bit PCI configuration register specified by Address.
961 The value written to the PCI configuration register is returned.
962 This function must guarantee that all PCI read and write operations are serialized.
964 If any reserved bits in Address are set, then ASSERT().
965 If Address is not aligned on a 32-bit boundary, then ASSERT().
967 @param Address The address that encodes the PCI Segment, Bus, Device, Function,
969 @param AndData The value to AND with the PCI configuration register.
971 @return The value written to the PCI configuration register.
981 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
985 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
986 followed a bitwise OR with another 32-bit value.
988 Reads the 32-bit PCI configuration register specified by Address,
989 performs a bitwise AND between the read result and the value specified by AndData,
990 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
991 and writes the result to the 32-bit PCI configuration register specified by Address.
992 The value written to the PCI configuration register is returned.
993 This function must guarantee that all PCI read and write operations are serialized.
995 If any reserved bits in Address are set, then ASSERT().
996 If Address is not aligned on a 32-bit boundary, then ASSERT().
998 @param Address The address that encodes the PCI Segment, Bus, Device, Function,
1000 @param AndData The value to AND with the PCI configuration register.
1001 @param OrData The value to OR with the PCI configuration register.
1003 @return The value written to the PCI configuration register.
1008 PciSegmentAndThenOr32 (
1014 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1018 Reads a bit field of a PCI configuration register.
1020 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1021 specified by the StartBit and the EndBit. The value of the bit field is
1024 If any reserved bits in Address are set, then ASSERT().
1025 If Address is not aligned on a 32-bit boundary, then ASSERT().
1026 If StartBit is greater than 31, then ASSERT().
1027 If EndBit is greater than 31, then ASSERT().
1028 If EndBit is less than StartBit, then ASSERT().
1030 @param Address The PCI configuration register to read.
1031 @param StartBit The ordinal of the least significant bit in the bit field.
1033 @param EndBit The ordinal of the most significant bit in the bit field.
1036 @return The value of the bit field read from the PCI configuration register.
1041 PciSegmentBitFieldRead32 (
1047 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1051 Writes a bit field to a PCI configuration register.
1053 Writes Value to the bit field of the PCI configuration register. The bit
1054 field is specified by the StartBit and the EndBit. All other bits in the
1055 destination PCI configuration register are preserved. The new value of the
1056 32-bit register is returned.
1058 If any reserved bits in Address are set, then ASSERT().
1059 If Address is not aligned on a 32-bit boundary, then ASSERT().
1060 If StartBit is greater than 31, then ASSERT().
1061 If EndBit is greater than 31, then ASSERT().
1062 If EndBit is less than StartBit, then ASSERT().
1063 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1065 @param Address The PCI configuration register to write.
1066 @param StartBit The ordinal of the least significant bit in the bit field.
1068 @param EndBit The ordinal of the most significant bit in the bit field.
1070 @param Value The new value of the bit field.
1072 @return The value written back to the PCI configuration register.
1077 PciSegmentBitFieldWrite32 (
1084 return PciSegmentWrite32 (
1086 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1091 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1092 writes the result back to the bit field in the 32-bit port.
1094 Reads the 32-bit PCI configuration register specified by Address, performs a
1095 bitwise OR between the read result and the value specified by
1096 OrData, and writes the result to the 32-bit PCI configuration register
1097 specified by Address. The value written to the PCI configuration register is
1098 returned. This function must guarantee that all PCI read and write operations
1099 are serialized. Extra left bits in OrData are stripped.
1101 If any reserved bits in Address are set, then ASSERT().
1102 If StartBit is greater than 31, then ASSERT().
1103 If EndBit is greater than 31, then ASSERT().
1104 If EndBit is less than StartBit, then ASSERT().
1105 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1107 @param Address The PCI configuration register to write.
1108 @param StartBit The ordinal of the least significant bit in the bit field.
1110 @param EndBit The ordinal of the most significant bit in the bit field.
1112 @param OrData The value to OR with the PCI configuration register.
1114 @return The value written back to the PCI configuration register.
1119 PciSegmentBitFieldOr32 (
1126 return PciSegmentWrite32 (
1128 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1133 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1134 AND, and writes the result back to the bit field in the 32-bit register.
1137 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1138 AND between the read result and the value specified by AndData, and writes the result
1139 to the 32-bit PCI configuration register specified by Address. The value written to
1140 the PCI configuration register is returned. This function must guarantee that all PCI
1141 read and write operations are serialized. Extra left bits in AndData are stripped.
1142 If any reserved bits in Address are set, then ASSERT().
1143 If Address is not aligned on a 32-bit boundary, then ASSERT().
1144 If StartBit is greater than 31, then ASSERT().
1145 If EndBit is greater than 31, then ASSERT().
1146 If EndBit is less than StartBit, then ASSERT().
1147 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1149 @param Address The PCI configuration register to write.
1150 @param StartBit The ordinal of the least significant bit in the bit field.
1152 @param EndBit The ordinal of the most significant bit in the bit field.
1154 @param AndData The value to AND with the PCI configuration register.
1156 @return The value written back to the PCI configuration register.
1161 PciSegmentBitFieldAnd32 (
1168 return PciSegmentWrite32 (
1170 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1175 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1176 bitwise OR, and writes the result back to the bit field in the
1179 Reads the 32-bit PCI configuration register specified by Address, performs a
1180 bitwise AND followed by a bitwise OR between the read result and
1181 the value specified by AndData, and writes the result to the 32-bit PCI
1182 configuration register specified by Address. The value written to the PCI
1183 configuration register is returned. This function must guarantee that all PCI
1184 read and write operations are serialized. Extra left bits in both AndData and
1185 OrData are stripped.
1187 If any reserved bits in Address are set, then ASSERT().
1188 If StartBit is greater than 31, then ASSERT().
1189 If EndBit is greater than 31, then ASSERT().
1190 If EndBit is less than StartBit, then ASSERT().
1191 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1192 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1194 @param Address The PCI configuration register to write.
1195 @param StartBit The ordinal of the least significant bit in the bit field.
1197 @param EndBit The ordinal of the most significant bit in the bit field.
1199 @param AndData The value to AND with the PCI configuration register.
1200 @param OrData The value to OR with the result of the AND operation.
1202 @return The value written back to the PCI configuration register.
1207 PciSegmentBitFieldAndThenOr32 (
1215 return PciSegmentWrite32 (
1217 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1222 Reads a range of PCI configuration registers into a caller supplied buffer.
1224 Reads the range of PCI configuration registers specified by StartAddress and
1225 Size into the buffer specified by Buffer. This function only allows the PCI
1226 configuration registers from a single PCI function to be read. Size is
1227 returned. When possible 32-bit PCI configuration read cycles are used to read
1228 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1229 and 16-bit PCI configuration read cycles may be used at the beginning and the
1232 If any reserved bits in StartAddress are set, then ASSERT().
1233 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1234 If Size > 0 and Buffer is NULL, then ASSERT().
1236 @param StartAddress The starting address that encodes the PCI Segment, Bus,
1237 Device, Function and Register.
1238 @param Size The size in bytes of the transfer.
1239 @param Buffer The pointer to a buffer receiving the data read.
1246 PciSegmentReadBuffer (
1247 IN UINT64 StartAddress
,
1254 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1255 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1261 ASSERT (Buffer
!= NULL
);
1264 // Save Size for return
1268 if ((StartAddress
& BIT0
) != 0) {
1270 // Read a byte if StartAddress is byte aligned
1272 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1273 StartAddress
+= sizeof (UINT8
);
1274 Size
-= sizeof (UINT8
);
1275 Buffer
= (UINT8
*)Buffer
+ 1;
1278 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1280 // Read a word if StartAddress is word aligned
1282 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1283 StartAddress
+= sizeof (UINT16
);
1284 Size
-= sizeof (UINT16
);
1285 Buffer
= (UINT16
*)Buffer
+ 1;
1288 while (Size
>= sizeof (UINT32
)) {
1290 // Read as many double words as possible
1292 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1293 StartAddress
+= sizeof (UINT32
);
1294 Size
-= sizeof (UINT32
);
1295 Buffer
= (UINT32
*)Buffer
+ 1;
1298 if (Size
>= sizeof (UINT16
)) {
1300 // Read the last remaining word if exist
1302 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1303 StartAddress
+= sizeof (UINT16
);
1304 Size
-= sizeof (UINT16
);
1305 Buffer
= (UINT16
*)Buffer
+ 1;
1308 if (Size
>= sizeof (UINT8
)) {
1310 // Read the last remaining byte if exist
1312 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1320 Copies the data in a caller supplied buffer to a specified range of PCI
1321 configuration space.
1323 Writes the range of PCI configuration registers specified by StartAddress and
1324 Size from the buffer specified by Buffer. This function only allows the PCI
1325 configuration registers from a single PCI function to be written. Size is
1326 returned. When possible 32-bit PCI configuration write cycles are used to
1327 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1328 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1329 and the end of the range.
1331 If any reserved bits in StartAddress are set, then ASSERT().
1332 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1333 If Size > 0 and Buffer is NULL, then ASSERT().
1335 @param StartAddress The starting address that encodes the PCI Segment, Bus,
1336 Device, Function and Register.
1337 @param Size The size in bytes of the transfer.
1338 @param Buffer The pointer to a buffer containing the data to write.
1340 @return The parameter of Size.
1345 PciSegmentWriteBuffer (
1346 IN UINT64 StartAddress
,
1353 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1354 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1360 ASSERT (Buffer
!= NULL
);
1363 // Save Size for return
1367 if ((StartAddress
& BIT0
) != 0) {
1369 // Write a byte if StartAddress is byte aligned
1371 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1372 StartAddress
+= sizeof (UINT8
);
1373 Size
-= sizeof (UINT8
);
1374 Buffer
= (UINT8
*)Buffer
+ 1;
1377 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1379 // Write a word if StartAddress is word aligned
1381 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1382 StartAddress
+= sizeof (UINT16
);
1383 Size
-= sizeof (UINT16
);
1384 Buffer
= (UINT16
*)Buffer
+ 1;
1387 while (Size
>= sizeof (UINT32
)) {
1389 // Write as many double words as possible
1391 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1392 StartAddress
+= sizeof (UINT32
);
1393 Size
-= sizeof (UINT32
);
1394 Buffer
= (UINT32
*)Buffer
+ 1;
1397 if (Size
>= sizeof (UINT16
)) {
1399 // Write the last remaining word if exist
1401 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1402 StartAddress
+= sizeof (UINT16
);
1403 Size
-= sizeof (UINT16
);
1404 Buffer
= (UINT16
*)Buffer
+ 1;
1407 if (Size
>= sizeof (UINT8
)) {
1409 // Write the last remaining byte if exist
1411 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);