2 PCI Segment Library implementation using PCI CFG2 PPI.
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.
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 31:28
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) & (0xf0000000 | (M))) == 0)
38 Translate PCI Lib address into format of PCI CFG2 PPI.
40 @param A Address that encodes the PCI Bus, Device, Function and
44 #define PCI_TO_PCICFG2_ADDRESS(A) \
45 ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))
50 This internal function retrieves PCI CFG2 PPI from PPI database.
52 @param Address Address that encodes the PCI Segment, Bus, Device, Function and Register.
54 @return The pointer to PCI CFG2 PPI.
57 EFI_PEI_PCI_CFG2_PPI
*
58 InternalGetPciCfg2Ppi (
64 EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
69 SegmentNumber
= BitFieldRead64 (Address
, 32, 63);
72 // Loop through all instances of the PPI and match segment number
75 Status
= PeiServicesLocatePpi(
81 ASSERT_EFI_ERROR (Status
);
83 } while (PciCfg2Ppi
->Segment
!= SegmentNumber
);
89 Internal worker function to read a PCI configuration register.
91 This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service.
92 It reads and returns the PCI configuration register specified by Address,
93 the width of data is specified by Width.
95 @param Address Address that encodes the PCI Bus, Device, Function and
97 @param Width Width of data to read
99 @return The value read from the PCI configuration register.
103 PeiPciSegmentLibPciCfg2ReadWorker (
105 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
109 CONST EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
110 UINT64 PciCfg2Address
;
112 PciCfg2Ppi
= InternalGetPciCfg2Ppi (Address
);
113 PciCfg2Address
= PCI_TO_PCICFG2_ADDRESS (Address
);
115 GetPeiServicesTablePointer (),
126 Internal worker function to writes a PCI configuration register.
128 This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.
129 It writes the PCI configuration register specified by Address with the
130 value specified by Data. The width of data is specifed by Width.
133 @param Address Address that encodes the PCI Bus, Device, Function and
135 @param Width Width of data to write
136 @param Data The value to write.
138 @return The value written to the PCI configuration register.
142 PeiPciSegmentLibPciCfg2WriteWorker (
144 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
148 CONST EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
149 UINT64 PciCfg2Address
;
151 PciCfg2Ppi
= InternalGetPciCfg2Ppi (Address
);
152 PciCfg2Address
= PCI_TO_PCICFG2_ADDRESS (Address
);
154 GetPeiServicesTablePointer (),
165 Register a PCI device so PCI configuration registers may be accessed after
166 SetVirtualAddressMap().
168 If Address > 0x0FFFFFFF, then ASSERT().
170 @param Address Address that encodes the PCI Bus, Device, Function and
173 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
174 @retval RETURN_UNSUPPORTED An attempt was made to call this function
175 after ExitBootServices().
176 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
177 at runtime could not be mapped.
178 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
179 complete the registration.
184 PciSegmentRegisterForRuntimeAccess (
188 return RETURN_UNSUPPORTED
;
192 Reads an 8-bit PCI configuration register.
194 Reads and returns the 8-bit PCI configuration register specified by Address.
195 This function must guarantee that all PCI read and write operations are
198 If any reserved bits in Address are set, then ASSERT().
200 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
203 @return The value read from the PCI configuration register.
212 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
214 return (UINT8
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint8
);
218 Writes an 8-bit PCI configuration register.
220 Writes the 8-bit PCI configuration register specified by Address with the
221 value specified by Value. Value is returned. This function must guarantee
222 that all PCI read and write operations are serialized.
224 If any reserved bits in Address are set, then ASSERT().
226 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
228 @param Data The value to write.
230 @return The value written to the PCI configuration register.
240 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
242 return (UINT8
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint8
, Data
);
246 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
249 Reads the 8-bit PCI configuration register specified by Address, performs a
250 bitwise inclusive OR between the read result and the value specified by
251 OrData, and writes the result to the 8-bit PCI configuration register
252 specified by Address. The value written to the PCI configuration register is
253 returned. This function must guarantee that all PCI read and write operations
256 If any reserved bits in Address are set, then ASSERT().
258 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
260 @param OrData The value to OR with the PCI configuration register.
262 @return The value written back to the PCI configuration register.
272 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
276 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
278 Reads the 8-bit PCI configuration register specified by Address,
279 performs a bitwise AND between the read result and the value specified by AndData,
280 and writes the result to the 8-bit PCI configuration register specified by Address.
281 The value written to the PCI configuration register is returned.
282 This function must guarantee that all PCI read and write operations are serialized.
283 If any reserved bits in Address are set, then ASSERT().
285 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
286 @param AndData The value to AND with the PCI configuration register.
288 @return The value written to the PCI configuration register.
298 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
302 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
303 followed a bitwise inclusive OR with another 8-bit value.
305 Reads the 8-bit PCI configuration register specified by Address,
306 performs a bitwise AND between the read result and the value specified by AndData,
307 performs a bitwise inclusive OR between the result of the AND operation and the value specified by OrData,
308 and writes the result to the 8-bit PCI configuration register specified by Address.
309 The value written to the PCI configuration register is returned.
310 This function must guarantee that all PCI read and write operations are serialized.
312 If any reserved bits in Address are set, then ASSERT().
314 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
315 @param AndData The value to AND with the PCI configuration register.
316 @param OrData The value to OR with the PCI configuration register.
318 @return The value written to the PCI configuration register.
323 PciSegmentAndThenOr8 (
329 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
333 Reads a bit field of a PCI configuration register.
335 Reads the bit field in an 8-bit PCI configuration register. The bit field is
336 specified by the StartBit and the EndBit. The value of the bit field is
339 If any reserved bits in Address are set, then ASSERT().
340 If StartBit is greater than 7, then ASSERT().
341 If EndBit is greater than 7, then ASSERT().
342 If EndBit is less than StartBit, then ASSERT().
344 @param Address PCI configuration register to read.
345 @param StartBit The ordinal of the least significant bit in the bit field.
347 @param EndBit The ordinal of the most significant bit in the bit field.
350 @return The value of the bit field read from the PCI configuration register.
355 PciSegmentBitFieldRead8 (
361 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
365 Writes a bit field to a PCI configuration register.
367 Writes Value to the bit field of the PCI configuration register. The bit
368 field is specified by the StartBit and the EndBit. All other bits in the
369 destination PCI configuration register are preserved. The new value of the
370 8-bit register is returned.
372 If any reserved bits in Address are set, then ASSERT().
373 If StartBit is greater than 7, then ASSERT().
374 If EndBit is greater than 7, then ASSERT().
375 If EndBit is less than StartBit, then ASSERT().
377 @param Address PCI configuration register to write.
378 @param StartBit The ordinal of the least significant bit in the bit field.
380 @param EndBit The ordinal of the most significant bit in the bit field.
382 @param Value New value of the bit field.
384 @return The value written back to the PCI configuration register.
389 PciSegmentBitFieldWrite8 (
396 return PciSegmentWrite8 (
398 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
403 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
404 writes the result back to the bit field in the 8-bit port.
406 Reads the 8-bit PCI configuration register specified by Address, performs a
407 bitwise inclusive OR between the read result and the value specified by
408 OrData, and writes the result to the 8-bit PCI configuration register
409 specified by Address. The value written to the PCI configuration register is
410 returned. This function must guarantee that all PCI read and write operations
411 are serialized. Extra left bits in OrData are stripped.
413 If any reserved bits in Address are set, then ASSERT().
414 If StartBit is greater than 7, then ASSERT().
415 If EndBit is greater than 7, then ASSERT().
416 If EndBit is less than StartBit, then ASSERT().
418 @param Address PCI configuration register to write.
419 @param StartBit The ordinal of the least significant bit in the bit field.
421 @param EndBit The ordinal of the most significant bit in the bit field.
423 @param OrData The value to OR with the PCI configuration register.
425 @return The value written back to the PCI configuration register.
430 PciSegmentBitFieldOr8 (
437 return PciSegmentWrite8 (
439 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
444 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
445 AND, and writes the result back to the bit field in the 8-bit register.
447 Reads the 8-bit PCI configuration register specified by Address, performs a
448 bitwise AND between the read result and the value specified by AndData, and
449 writes the result to the 8-bit PCI configuration register specified by
450 Address. The value written to the PCI configuration register is returned.
451 This function must guarantee that all PCI read and write operations are
452 serialized. Extra left bits in AndData are stripped.
454 If any reserved bits in Address are set, then ASSERT().
455 If StartBit is greater than 7, then ASSERT().
456 If EndBit is greater than 7, then ASSERT().
457 If EndBit is less than StartBit, then ASSERT().
459 @param Address PCI configuration register to write.
460 @param StartBit The ordinal of the least significant bit in the bit field.
462 @param EndBit The ordinal of the most significant bit in the bit field.
464 @param AndData The value to AND with the PCI configuration register.
466 @return The value written back to the PCI configuration register.
471 PciSegmentBitFieldAnd8 (
478 return PciSegmentWrite8 (
480 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
485 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
486 bitwise inclusive OR, and writes the result back to the bit field in the
489 Reads the 8-bit PCI configuration register specified by Address, performs a
490 bitwise AND followed by a bitwise inclusive OR between the read result and
491 the value specified by AndData, and writes the result to the 8-bit PCI
492 configuration register specified by Address. The value written to the PCI
493 configuration register is returned. This function must guarantee that all PCI
494 read and write operations are serialized. Extra left bits in both AndData and
497 If any reserved bits in Address are set, then ASSERT().
498 If StartBit is greater than 7, then ASSERT().
499 If EndBit is greater than 7, then ASSERT().
500 If EndBit is less than StartBit, then ASSERT().
502 @param Address PCI configuration register to write.
503 @param StartBit The ordinal of the least significant bit in the bit field.
505 @param EndBit The ordinal of the most significant bit in the bit field.
507 @param AndData The value to AND with the PCI configuration register.
508 @param OrData The value to OR with the result of the AND operation.
510 @return The value written back to the PCI configuration register.
515 PciSegmentBitFieldAndThenOr8 (
523 return PciSegmentWrite8 (
525 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
530 Reads a 16-bit PCI configuration register.
532 Reads and returns the 16-bit PCI configuration register specified by Address.
533 This function must guarantee that all PCI read and write operations are
536 If any reserved bits in Address are set, then ASSERT().
538 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
541 @return The value read from the PCI configuration register.
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
559 value specified by Value. Value is returned. This function must guarantee
560 that all PCI read and write operations are serialized.
562 If any reserved bits in Address are set, then ASSERT().
564 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
566 @param Data The value to write.
568 @return The value written to the PCI configuration register.
578 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
580 return (UINT16
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint16
, Data
);
584 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
587 Reads the 16-bit PCI configuration register specified by Address, performs a
588 bitwise inclusive OR between the read result and the value specified by
589 OrData, and writes the result to the 16-bit PCI configuration register
590 specified by Address. The value written to the PCI configuration register is
591 returned. This function must guarantee that all PCI read and write operations
594 If any reserved bits in Address are set, then ASSERT().
596 @param Address 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 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
643 value, followed a bitwise inclusive OR with another 16-bit value.
645 Reads the 16-bit PCI configuration register specified by Address, performs a
646 bitwise AND between the read result and the value specified by AndData,
647 performs a bitwise inclusive OR between the result of the AND operation and
648 the value specified by OrData, and writes the result to the 16-bit PCI
649 configuration register specified by Address. The value written to the PCI
650 configuration register is returned. This function must guarantee that all PCI
651 read and write operations are serialized.
653 If any reserved bits in Address are set, then ASSERT().
655 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
657 @param AndData The value to AND with the PCI configuration register.
658 @param OrData The value to OR with the result of the AND operation.
660 @return The value written back to the PCI configuration register.
665 PciSegmentAndThenOr16 (
671 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
675 Reads a bit field of a PCI configuration register.
677 Reads the bit field in a 16-bit PCI configuration register. The bit field is
678 specified by the StartBit and the EndBit. The value of the bit field is
681 If any reserved bits in Address are set, 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 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 StartBit is greater than 15, then ASSERT().
716 If EndBit is greater than 15, then ASSERT().
717 If EndBit is less than StartBit, then ASSERT().
719 @param Address PCI configuration register to write.
720 @param StartBit The ordinal of the least significant bit in the bit field.
722 @param EndBit The ordinal of the most significant bit in the bit field.
724 @param Value New value of the bit field.
726 @return The value written back to the PCI configuration register.
731 PciSegmentBitFieldWrite16 (
738 return PciSegmentWrite16 (
740 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
745 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
746 writes the result back to the bit field in the 16-bit port.
748 Reads the 16-bit PCI configuration register specified by Address, performs a
749 bitwise inclusive OR between the read result and the value specified by
750 OrData, and writes the result to the 16-bit PCI configuration register
751 specified by Address. The value written to the PCI configuration register is
752 returned. This function must guarantee that all PCI read and write operations
753 are serialized. Extra left bits in OrData are stripped.
755 If any reserved bits in Address are set, then ASSERT().
756 If StartBit is greater than 15, then ASSERT().
757 If EndBit is greater than 15, then ASSERT().
758 If EndBit is less than StartBit, then ASSERT().
760 @param Address PCI configuration register to write.
761 @param StartBit The ordinal of the least significant bit in the bit field.
763 @param EndBit The ordinal of the most significant bit in the bit field.
765 @param OrData The value to OR with the PCI configuration register.
767 @return The value written back to the PCI configuration register.
772 PciSegmentBitFieldOr16 (
779 return PciSegmentWrite16 (
781 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
786 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
787 AND, and writes the result back to the bit field in the 16-bit register.
789 Reads the 16-bit PCI configuration register specified by Address, performs a
790 bitwise AND between the read result and the value specified by AndData, and
791 writes the result to the 16-bit PCI configuration register specified by
792 Address. The value written to the PCI configuration register is returned.
793 This function must guarantee that all PCI read and write operations are
794 serialized. Extra left bits in AndData are stripped.
796 If any reserved bits in Address are set, then ASSERT().
797 If StartBit is greater than 15, then ASSERT().
798 If EndBit is greater than 15, then ASSERT().
799 If EndBit is less than StartBit, then ASSERT().
801 @param Address PCI configuration register to write.
802 @param StartBit The ordinal of the least significant bit in the bit field.
804 @param EndBit The ordinal of the most significant bit in the bit field.
806 @param AndData The value to AND with the PCI configuration register.
808 @return The value written back 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 inclusive 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 inclusive 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().
844 @param Address PCI configuration register to write.
845 @param StartBit The ordinal of the least significant bit in the bit field.
847 @param EndBit The ordinal of the most significant bit in the bit field.
849 @param AndData The value to AND with the PCI configuration register.
850 @param OrData The value to OR with the result of the AND operation.
852 @return The value written back to the PCI configuration register.
857 PciSegmentBitFieldAndThenOr16 (
865 return PciSegmentWrite16 (
867 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
872 Reads a 32-bit PCI configuration register.
874 Reads and returns the 32-bit PCI configuration register specified by Address.
875 This function must guarantee that all PCI read and write operations are
878 If any reserved bits in Address are set, then ASSERT().
880 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
883 @return The value read from the PCI configuration register.
892 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
894 return PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint32
);
898 Writes a 32-bit PCI configuration register.
900 Writes the 32-bit PCI configuration register specified by Address with the
901 value specified by Value. Value is returned. This function must guarantee
902 that all PCI read and write operations are serialized.
904 If any reserved bits in Address are set, then ASSERT().
906 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
908 @param Data The value to write.
910 @return The value written to the PCI configuration register.
920 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
922 return PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint32
, Data
);
926 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
929 Reads the 32-bit PCI configuration register specified by Address, performs a
930 bitwise inclusive OR between the read result and the value specified by
931 OrData, and writes the result to the 32-bit PCI configuration register
932 specified by Address. The value written to the PCI configuration register is
933 returned. This function must guarantee that all PCI read and write operations
936 If any reserved bits in Address are set, then ASSERT().
938 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
940 @param OrData The value to OR with the PCI configuration register.
942 @return The value written back 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 Address that encodes the PCI Segment, Bus, Device, Function, and Register.
968 @param AndData The value to AND with the PCI configuration register.
970 @return The value written to the PCI configuration register.
980 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
984 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
985 followed a bitwise inclusive OR with another 32-bit value.
987 Reads the 32-bit PCI configuration register specified by Address,
988 performs a bitwise AND between the read result and the value specified by AndData,
989 performs a bitwise inclusive OR between the result of the AND operation and the value specified by OrData,
990 and writes the result to the 32-bit PCI configuration register specified by Address.
991 The value written to the PCI configuration register is returned.
992 This function must guarantee that all PCI read and write operations are serialized.
994 If any reserved bits in Address are set, then ASSERT().
995 If Address is not aligned on a 32-bit boundary, then ASSERT().
997 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
998 @param AndData The value to AND with the PCI configuration register.
999 @param OrData The value to OR with the PCI configuration register.
1001 @return The value written to the PCI configuration register.
1006 PciSegmentAndThenOr32 (
1012 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1016 Reads a bit field of a PCI configuration register.
1018 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1019 specified by the StartBit and the EndBit. The value of the bit field is
1022 If any reserved bits in Address are set, then ASSERT().
1023 If StartBit is greater than 31, then ASSERT().
1024 If EndBit is greater than 31, then ASSERT().
1025 If EndBit is less than StartBit, then ASSERT().
1027 @param Address PCI configuration register to read.
1028 @param StartBit The ordinal of the least significant bit in the bit field.
1030 @param EndBit The ordinal of the most significant bit in the bit field.
1033 @return The value of the bit field read from the PCI configuration register.
1038 PciSegmentBitFieldRead32 (
1044 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1048 Writes a bit field to a PCI configuration register.
1050 Writes Value to the bit field of the PCI configuration register. The bit
1051 field is specified by the StartBit and the EndBit. All other bits in the
1052 destination PCI configuration register are preserved. The new value of the
1053 32-bit register is returned.
1055 If any reserved bits in Address are set, then ASSERT().
1056 If StartBit is greater than 31, then ASSERT().
1057 If EndBit is greater than 31, then ASSERT().
1058 If EndBit is less than StartBit, then ASSERT().
1060 @param Address PCI configuration register to write.
1061 @param StartBit The ordinal of the least significant bit in the bit field.
1063 @param EndBit The ordinal of the most significant bit in the bit field.
1065 @param Value New value of the bit field.
1067 @return The value written back to the PCI configuration register.
1072 PciSegmentBitFieldWrite32 (
1079 return PciSegmentWrite32 (
1081 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1086 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1087 writes the result back to the bit field in the 32-bit port.
1089 Reads the 32-bit PCI configuration register specified by Address, performs a
1090 bitwise inclusive OR between the read result and the value specified by
1091 OrData, and writes the result to the 32-bit PCI configuration register
1092 specified by Address. The value written to the PCI configuration register is
1093 returned. This function must guarantee that all PCI read and write operations
1094 are serialized. Extra left bits in OrData are stripped.
1096 If any reserved bits in Address are set, then ASSERT().
1097 If StartBit is greater than 31, then ASSERT().
1098 If EndBit is greater than 31, then ASSERT().
1099 If EndBit is less than StartBit, then ASSERT().
1101 @param Address PCI configuration register to write.
1102 @param StartBit The ordinal of the least significant bit in the bit field.
1104 @param EndBit The ordinal of the most significant bit in the bit field.
1106 @param OrData The value to OR with the PCI configuration register.
1108 @return The value written back to the PCI configuration register.
1113 PciSegmentBitFieldOr32 (
1120 return PciSegmentWrite32 (
1122 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1127 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1128 AND, and writes the result back to the bit field in the 32-bit register.
1130 Reads the 32-bit PCI configuration register specified by Address, performs a
1131 bitwise AND between the read result and the value specified by AndData, and
1132 writes the result to the 32-bit PCI configuration register specified by
1133 Address. The value written to the PCI configuration register is returned.
1134 This function must guarantee that all PCI read and write operations are
1135 serialized. Extra left bits in AndData are stripped.
1137 If any reserved bits in Address are set, then ASSERT().
1138 If StartBit is greater than 31, then ASSERT().
1139 If EndBit is greater than 31, then ASSERT().
1140 If EndBit is less than StartBit, then ASSERT().
1142 @param Address PCI configuration register to write.
1143 @param StartBit The ordinal of the least significant bit in the bit field.
1145 @param EndBit The ordinal of the most significant bit in the bit field.
1147 @param AndData The value to AND with the PCI configuration register.
1149 @return The value written back to the PCI configuration register.
1154 PciSegmentBitFieldAnd32 (
1161 return PciSegmentWrite32 (
1163 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1168 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1169 bitwise inclusive OR, and writes the result back to the bit field in the
1172 Reads the 32-bit PCI configuration register specified by Address, performs a
1173 bitwise AND followed by a bitwise inclusive OR between the read result and
1174 the value specified by AndData, and writes the result to the 32-bit PCI
1175 configuration register specified by Address. The value written to the PCI
1176 configuration register is returned. This function must guarantee that all PCI
1177 read and write operations are serialized. Extra left bits in both AndData and
1178 OrData are stripped.
1180 If any reserved bits in Address are set, then ASSERT().
1181 If StartBit is greater than 31, then ASSERT().
1182 If EndBit is greater than 31, then ASSERT().
1183 If EndBit is less than StartBit, then ASSERT().
1185 @param Address PCI configuration register to write.
1186 @param StartBit The ordinal of the least significant bit in the bit field.
1188 @param EndBit The ordinal of the most significant bit in the bit field.
1190 @param AndData The value to AND with the PCI configuration register.
1191 @param OrData The value to OR with the result of the AND operation.
1193 @return The value written back to the PCI configuration register.
1198 PciSegmentBitFieldAndThenOr32 (
1206 return PciSegmentWrite32 (
1208 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1213 Reads a range of PCI configuration registers into a caller supplied buffer.
1215 Reads the range of PCI configuration registers specified by StartAddress and
1216 Size into the buffer specified by Buffer. This function only allows the PCI
1217 configuration registers from a single PCI function to be read. Size is
1218 returned. When possible 32-bit PCI configuration read cycles are used to read
1219 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1220 and 16-bit PCI configuration read cycles may be used at the beginning and the
1223 If StartAddress > 0x0FFFFFFF, then ASSERT().
1224 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1225 If Size > 0 and Buffer is NULL, then ASSERT().
1227 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1228 Function and Register.
1229 @param Size Size in bytes of the transfer.
1230 @param Buffer Pointer to a buffer receiving the data read.
1237 PciSegmentReadBuffer (
1238 IN UINT64 StartAddress
,
1245 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1246 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1252 ASSERT (Buffer
!= NULL
);
1255 // Save Size for return
1259 if ((StartAddress
& BIT0
) != 0) {
1261 // Read a byte if StartAddress is byte aligned
1263 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1264 StartAddress
+= sizeof (UINT8
);
1265 Size
-= sizeof (UINT8
);
1266 Buffer
= (UINT8
*)Buffer
+ 1;
1269 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1271 // Read a word if StartAddress is word aligned
1273 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1274 StartAddress
+= sizeof (UINT16
);
1275 Size
-= sizeof (UINT16
);
1276 Buffer
= (UINT16
*)Buffer
+ 1;
1279 while (Size
>= sizeof (UINT32
)) {
1281 // Read as many double words as possible
1283 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1284 StartAddress
+= sizeof (UINT32
);
1285 Size
-= sizeof (UINT32
);
1286 Buffer
= (UINT32
*)Buffer
+ 1;
1289 if (Size
>= sizeof (UINT16
)) {
1291 // Read the last remaining word if exist
1293 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1294 StartAddress
+= sizeof (UINT16
);
1295 Size
-= sizeof (UINT16
);
1296 Buffer
= (UINT16
*)Buffer
+ 1;
1299 if (Size
>= sizeof (UINT8
)) {
1301 // Read the last remaining byte if exist
1303 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1310 Copies the data in a caller supplied buffer to a specified range of PCI
1311 configuration space.
1313 Writes the range of PCI configuration registers specified by StartAddress and
1314 Size from the buffer specified by Buffer. This function only allows the PCI
1315 configuration registers from a single PCI function to be written. Size is
1316 returned. When possible 32-bit PCI configuration write cycles are used to
1317 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1318 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1319 and the end of the range.
1321 If StartAddress > 0x0FFFFFFF, then ASSERT().
1322 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1323 If Size > 0 and Buffer is NULL, then ASSERT().
1325 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1326 Function and Register.
1327 @param Size Size in bytes of the transfer.
1328 @param Buffer Pointer to a buffer containing the data to write.
1335 PciSegmentWriteBuffer (
1336 IN UINT64 StartAddress
,
1343 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1344 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1350 ASSERT (Buffer
!= NULL
);
1353 // Save Size for return
1357 if ((StartAddress
& BIT0
) != 0) {
1359 // Write a byte if StartAddress is byte aligned
1361 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1362 StartAddress
+= sizeof (UINT8
);
1363 Size
-= sizeof (UINT8
);
1364 Buffer
= (UINT8
*)Buffer
+ 1;
1367 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1369 // Write a word if StartAddress is word aligned
1371 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1372 StartAddress
+= sizeof (UINT16
);
1373 Size
-= sizeof (UINT16
);
1374 Buffer
= (UINT16
*)Buffer
+ 1;
1377 while (Size
>= sizeof (UINT32
)) {
1379 // Write as many double words as possible
1381 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1382 StartAddress
+= sizeof (UINT32
);
1383 Size
-= sizeof (UINT32
);
1384 Buffer
= (UINT32
*)Buffer
+ 1;
1387 if (Size
>= sizeof (UINT16
)) {
1389 // Write the last remaining word if exist
1391 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1392 StartAddress
+= sizeof (UINT16
);
1393 Size
-= sizeof (UINT16
);
1394 Buffer
= (UINT16
*)Buffer
+ 1;
1397 if (Size
>= sizeof (UINT8
)) {
1399 // Write the last remaining byte if exist
1401 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);