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) | ((UINT64)((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
;
111 PciCfg2Ppi
= InternalGetPciCfg2Ppi (Address
);
114 GetPeiServicesTablePointer (),
117 PCI_TO_PCICFG2_ADDRESS (Address
),
125 Internal worker function to writes a PCI configuration register.
127 This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.
128 It writes the PCI configuration register specified by Address with the
129 value specified by Data. The width of data is specifed by Width.
132 @param Address Address that encodes the PCI Bus, Device, Function and
134 @param Width Width of data to write
135 @param Data The value to write.
137 @return The value written to the PCI configuration register.
141 PeiPciSegmentLibPciCfg2WriteWorker (
143 IN EFI_PEI_PCI_CFG_PPI_WIDTH Width
,
147 CONST EFI_PEI_PCI_CFG2_PPI
*PciCfg2Ppi
;
149 PciCfg2Ppi
= InternalGetPciCfg2Ppi (Address
);
152 GetPeiServicesTablePointer (),
155 PCI_TO_PCICFG2_ADDRESS (Address
),
163 Reads an 8-bit PCI configuration register.
165 Reads and returns the 8-bit PCI configuration register specified by Address.
166 This function must guarantee that all PCI read and write operations are
169 If any reserved bits in Address are set, then ASSERT().
171 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
174 @return The value read from the PCI configuration register.
183 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
185 return (UINT8
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint8
);
189 Writes an 8-bit PCI configuration register.
191 Writes the 8-bit PCI configuration register specified by Address with the
192 value specified by Value. Value is returned. This function must guarantee
193 that all PCI read and write operations are serialized.
195 If any reserved bits in Address are set, then ASSERT().
197 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
199 @param Data The value to write.
201 @return The value written to the PCI configuration register.
211 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
213 return (UINT8
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint8
, Data
);
217 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
220 Reads the 8-bit PCI configuration register specified by Address, performs a
221 bitwise inclusive OR between the read result and the value specified by
222 OrData, and writes the result to the 8-bit PCI configuration register
223 specified by Address. The value written to the PCI configuration register is
224 returned. This function must guarantee that all PCI read and write operations
227 If any reserved bits in Address are set, then ASSERT().
229 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
231 @param OrData The value to OR with the PCI configuration register.
233 @return The value written back to the PCI configuration register.
243 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
247 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
250 Reads the 8-bit PCI configuration register specified by Address, performs a
251 bitwise AND between the read result and the value specified by AndData, and
252 writes the result to the 8-bit PCI configuration register specified by
253 Address. The value written to the PCI configuration register is returned.
254 This function must guarantee that all PCI read and write operations are
257 If any reserved bits in Address are set, then ASSERT().
259 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
261 @param AndData The value to AND with the PCI configuration register.
263 @return The value written back to the PCI configuration register.
273 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
277 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
278 value, followed a bitwise inclusive OR with another 8-bit value.
280 Reads the 8-bit PCI configuration register specified by Address, performs a
281 bitwise AND between the read result and the value specified by AndData,
282 performs a bitwise inclusive OR between the result of the AND operation and
283 the value specified by OrData, and writes the result to the 8-bit PCI
284 configuration register specified by Address. The value written to the PCI
285 configuration register is returned. This function must guarantee that all PCI
286 read and write operations are serialized.
288 If any reserved bits in Address are set, then ASSERT().
290 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
292 @param AndData The value to AND with the PCI configuration register.
293 @param OrData The value to OR with the result of the AND operation.
295 @return The value written back to the PCI configuration register.
300 PciSegmentAndThenOr8 (
306 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
310 Reads a bit field of a PCI configuration register.
312 Reads the bit field in an 8-bit PCI configuration register. The bit field is
313 specified by the StartBit and the EndBit. The value of the bit field is
316 If any reserved bits in Address are set, then ASSERT().
317 If StartBit is greater than 7, then ASSERT().
318 If EndBit is greater than 7, then ASSERT().
319 If EndBit is less than StartBit, then ASSERT().
321 @param Address PCI configuration register to read.
322 @param StartBit The ordinal of the least significant bit in the bit field.
324 @param EndBit The ordinal of the most significant bit in the bit field.
327 @return The value of the bit field read from the PCI configuration register.
332 PciSegmentBitFieldRead8 (
338 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
342 Writes a bit field to a PCI configuration register.
344 Writes Value to the bit field of the PCI configuration register. The bit
345 field is specified by the StartBit and the EndBit. All other bits in the
346 destination PCI configuration register are preserved. The new value of the
347 8-bit register is returned.
349 If any reserved bits in Address are set, then ASSERT().
350 If StartBit is greater than 7, then ASSERT().
351 If EndBit is greater than 7, then ASSERT().
352 If EndBit is less than StartBit, then ASSERT().
354 @param Address PCI configuration register to write.
355 @param StartBit The ordinal of the least significant bit in the bit field.
357 @param EndBit The ordinal of the most significant bit in the bit field.
359 @param Value New value of the bit field.
361 @return The value written back to the PCI configuration register.
366 PciSegmentBitFieldWrite8 (
373 return PciSegmentWrite8 (
375 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
380 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
381 writes the result back to the bit field in the 8-bit port.
383 Reads the 8-bit PCI configuration register specified by Address, performs a
384 bitwise inclusive OR between the read result and the value specified by
385 OrData, and writes the result to the 8-bit PCI configuration register
386 specified by Address. The value written to the PCI configuration register is
387 returned. This function must guarantee that all PCI read and write operations
388 are serialized. Extra left bits in OrData are stripped.
390 If any reserved bits in Address are set, then ASSERT().
391 If StartBit is greater than 7, then ASSERT().
392 If EndBit is greater than 7, then ASSERT().
393 If EndBit is less than StartBit, then ASSERT().
395 @param Address PCI configuration register to write.
396 @param StartBit The ordinal of the least significant bit in the bit field.
398 @param EndBit The ordinal of the most significant bit in the bit field.
400 @param OrData The value to OR with the PCI configuration register.
402 @return The value written back to the PCI configuration register.
407 PciSegmentBitFieldOr8 (
414 return PciSegmentWrite8 (
416 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
421 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
422 AND, and writes the result back to the bit field in the 8-bit register.
424 Reads the 8-bit PCI configuration register specified by Address, performs a
425 bitwise AND between the read result and the value specified by AndData, and
426 writes the result to the 8-bit PCI configuration register specified by
427 Address. The value written to the PCI configuration register is returned.
428 This function must guarantee that all PCI read and write operations are
429 serialized. Extra left bits in AndData are stripped.
431 If any reserved bits in Address are set, then ASSERT().
432 If StartBit is greater than 7, then ASSERT().
433 If EndBit is greater than 7, then ASSERT().
434 If EndBit is less than StartBit, then ASSERT().
436 @param Address PCI configuration register to write.
437 @param StartBit The ordinal of the least significant bit in the bit field.
439 @param EndBit The ordinal of the most significant bit in the bit field.
441 @param AndData The value to AND with the PCI configuration register.
443 @return The value written back to the PCI configuration register.
448 PciSegmentBitFieldAnd8 (
455 return PciSegmentWrite8 (
457 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
462 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
463 bitwise inclusive OR, and writes the result back to the bit field in the
466 Reads the 8-bit PCI configuration register specified by Address, performs a
467 bitwise AND followed by a bitwise inclusive OR between the read result and
468 the value specified by AndData, and writes the result to the 8-bit PCI
469 configuration register specified by Address. The value written to the PCI
470 configuration register is returned. This function must guarantee that all PCI
471 read and write operations are serialized. Extra left bits in both AndData and
474 If any reserved bits in Address are set, then ASSERT().
475 If StartBit is greater than 7, then ASSERT().
476 If EndBit is greater than 7, then ASSERT().
477 If EndBit is less than StartBit, then ASSERT().
479 @param Address PCI configuration register to write.
480 @param StartBit The ordinal of the least significant bit in the bit field.
482 @param EndBit The ordinal of the most significant bit in the bit field.
484 @param AndData The value to AND with the PCI configuration register.
485 @param OrData The value to OR with the result of the AND operation.
487 @return The value written back to the PCI configuration register.
492 PciSegmentBitFieldAndThenOr8 (
500 return PciSegmentWrite8 (
502 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
507 Reads a 16-bit PCI configuration register.
509 Reads and returns the 16-bit PCI configuration register specified by Address.
510 This function must guarantee that all PCI read and write operations are
513 If any reserved bits in Address are set, then ASSERT().
515 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
518 @return The value read from the PCI configuration register.
527 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
529 return (UINT16
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint16
);
533 Writes a 16-bit PCI configuration register.
535 Writes the 16-bit PCI configuration register specified by Address with the
536 value specified by Value. Value is returned. This function must guarantee
537 that all PCI read and write operations are serialized.
539 If any reserved bits in Address are set, then ASSERT().
541 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
543 @param Data The value to write.
545 @return The value written to the PCI configuration register.
555 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
557 return (UINT16
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint16
, Data
);
561 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
564 Reads the 16-bit PCI configuration register specified by Address, performs a
565 bitwise inclusive OR between the read result and the value specified by
566 OrData, and writes the result to the 16-bit PCI configuration register
567 specified by Address. The value written to the PCI configuration register is
568 returned. This function must guarantee that all PCI read and write operations
571 If any reserved bits in Address are set, then ASSERT().
573 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
575 @param OrData The value to OR with the PCI configuration register.
577 @return The value written back to the PCI configuration register.
587 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
591 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
594 Reads the 16-bit PCI configuration register specified by Address, performs a
595 bitwise AND between the read result and the value specified by AndData, and
596 writes the result to the 16-bit PCI configuration register specified by
597 Address. The value written to the PCI configuration register is returned.
598 This function must guarantee that all PCI read and write operations are
601 If any reserved bits in Address are set, then ASSERT().
603 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
605 @param AndData The value to AND with the PCI configuration register.
607 @return The value written back to the PCI configuration register.
617 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
621 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
622 value, followed a bitwise inclusive OR with another 16-bit value.
624 Reads the 16-bit PCI configuration register specified by Address, performs a
625 bitwise AND between the read result and the value specified by AndData,
626 performs a bitwise inclusive OR between the result of the AND operation and
627 the value specified by OrData, and writes the result to the 16-bit PCI
628 configuration register specified by Address. The value written to the PCI
629 configuration register is returned. This function must guarantee that all PCI
630 read and write operations are serialized.
632 If any reserved bits in Address are set, then ASSERT().
634 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
636 @param AndData The value to AND with the PCI configuration register.
637 @param OrData The value to OR with the result of the AND operation.
639 @return The value written back to the PCI configuration register.
644 PciSegmentAndThenOr16 (
650 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
654 Reads a bit field of a PCI configuration register.
656 Reads the bit field in a 16-bit PCI configuration register. The bit field is
657 specified by the StartBit and the EndBit. The value of the bit field is
660 If any reserved bits in Address are set, then ASSERT().
661 If StartBit is greater than 15, then ASSERT().
662 If EndBit is greater than 15, then ASSERT().
663 If EndBit is less than StartBit, then ASSERT().
665 @param Address PCI configuration register to read.
666 @param StartBit The ordinal of the least significant bit in the bit field.
668 @param EndBit The ordinal of the most significant bit in the bit field.
671 @return The value of the bit field read from the PCI configuration register.
676 PciSegmentBitFieldRead16 (
682 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
686 Writes a bit field to a PCI configuration register.
688 Writes Value to the bit field of the PCI configuration register. The bit
689 field is specified by the StartBit and the EndBit. All other bits in the
690 destination PCI configuration register are preserved. The new value of the
691 16-bit register is returned.
693 If any reserved bits in Address are set, then ASSERT().
694 If StartBit is greater than 15, then ASSERT().
695 If EndBit is greater than 15, then ASSERT().
696 If EndBit is less than StartBit, then ASSERT().
698 @param Address PCI configuration register to write.
699 @param StartBit The ordinal of the least significant bit in the bit field.
701 @param EndBit The ordinal of the most significant bit in the bit field.
703 @param Value New value of the bit field.
705 @return The value written back to the PCI configuration register.
710 PciSegmentBitFieldWrite16 (
717 return PciSegmentWrite16 (
719 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
724 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
725 writes the result back to the bit field in the 16-bit port.
727 Reads the 16-bit PCI configuration register specified by Address, performs a
728 bitwise inclusive OR between the read result and the value specified by
729 OrData, and writes the result to the 16-bit PCI configuration register
730 specified by Address. The value written to the PCI configuration register is
731 returned. This function must guarantee that all PCI read and write operations
732 are serialized. Extra left bits in OrData are stripped.
734 If any reserved bits in Address are set, then ASSERT().
735 If StartBit is greater than 15, then ASSERT().
736 If EndBit is greater than 15, then ASSERT().
737 If EndBit is less than StartBit, then ASSERT().
739 @param Address PCI configuration register to write.
740 @param StartBit The ordinal of the least significant bit in the bit field.
742 @param EndBit The ordinal of the most significant bit in the bit field.
744 @param OrData The value to OR with the PCI configuration register.
746 @return The value written back to the PCI configuration register.
751 PciSegmentBitFieldOr16 (
758 return PciSegmentWrite16 (
760 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
765 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
766 AND, and writes the result back to the bit field in the 16-bit register.
768 Reads the 16-bit PCI configuration register specified by Address, performs a
769 bitwise AND between the read result and the value specified by AndData, and
770 writes the result to the 16-bit PCI configuration register specified by
771 Address. The value written to the PCI configuration register is returned.
772 This function must guarantee that all PCI read and write operations are
773 serialized. Extra left bits in AndData are stripped.
775 If any reserved bits in Address are set, then ASSERT().
776 If StartBit is greater than 15, then ASSERT().
777 If EndBit is greater than 15, then ASSERT().
778 If EndBit is less than StartBit, then ASSERT().
780 @param Address PCI configuration register to write.
781 @param StartBit The ordinal of the least significant bit in the bit field.
783 @param EndBit The ordinal of the most significant bit in the bit field.
785 @param AndData The value to AND with the PCI configuration register.
787 @return The value written back to the PCI configuration register.
792 PciSegmentBitFieldAnd16 (
799 return PciSegmentWrite16 (
801 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
806 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
807 bitwise inclusive OR, and writes the result back to the bit field in the
810 Reads the 16-bit PCI configuration register specified by Address, performs a
811 bitwise AND followed by a bitwise inclusive OR between the read result and
812 the value specified by AndData, and writes the result to the 16-bit PCI
813 configuration register specified by Address. The value written to the PCI
814 configuration register is returned. This function must guarantee that all PCI
815 read and write operations are serialized. Extra left bits in both AndData and
818 If any reserved bits in Address are set, then ASSERT().
819 If StartBit is greater than 15, then ASSERT().
820 If EndBit is greater than 15, then ASSERT().
821 If EndBit is less than StartBit, then ASSERT().
823 @param Address PCI configuration register to write.
824 @param StartBit The ordinal of the least significant bit in the bit field.
826 @param EndBit The ordinal of the most significant bit in the bit field.
828 @param AndData The value to AND with the PCI configuration register.
829 @param OrData The value to OR with the result of the AND operation.
831 @return The value written back to the PCI configuration register.
836 PciSegmentBitFieldAndThenOr16 (
844 return PciSegmentWrite16 (
846 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
851 Reads a 32-bit PCI configuration register.
853 Reads and returns the 32-bit PCI configuration register specified by Address.
854 This function must guarantee that all PCI read and write operations are
857 If any reserved bits in Address are set, then ASSERT().
859 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
862 @return The value read from the PCI configuration register.
871 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
873 return PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint32
);
877 Writes a 32-bit PCI configuration register.
879 Writes the 32-bit PCI configuration register specified by Address with the
880 value specified by Value. Value is returned. This function must guarantee
881 that all PCI read and write operations are serialized.
883 If any reserved bits in Address are set, then ASSERT().
885 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
887 @param Data The value to write.
889 @return The value written to the PCI configuration register.
899 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
901 return PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint32
, Data
);
905 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
908 Reads the 32-bit PCI configuration register specified by Address, performs a
909 bitwise inclusive OR between the read result and the value specified by
910 OrData, and writes the result to the 32-bit PCI configuration register
911 specified by Address. The value written to the PCI configuration register is
912 returned. This function must guarantee that all PCI read and write operations
915 If any reserved bits in Address are set, then ASSERT().
917 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
919 @param OrData The value to OR with the PCI configuration register.
921 @return The value written back to the PCI configuration register.
931 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
935 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
938 Reads the 32-bit PCI configuration register specified by Address, performs a
939 bitwise AND between the read result and the value specified by AndData, and
940 writes the result to the 32-bit PCI configuration register specified by
941 Address. The value written to the PCI configuration register is returned.
942 This function must guarantee that all PCI read and write operations are
945 If any reserved bits in Address are set, then ASSERT().
947 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
949 @param AndData The value to AND with the PCI configuration register.
951 @return The value written back to the PCI configuration register.
961 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
965 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
966 value, followed a bitwise inclusive OR with another 32-bit value.
968 Reads the 32-bit PCI configuration register specified by Address, performs a
969 bitwise AND between the read result and the value specified by AndData,
970 performs a bitwise inclusive OR between the result of the AND operation and
971 the value specified by OrData, and writes the result to the 32-bit PCI
972 configuration register specified by Address. The value written to the PCI
973 configuration register is returned. This function must guarantee that all PCI
974 read and write operations are serialized.
976 If any reserved bits in Address are set, then ASSERT().
978 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
980 @param AndData The value to AND with the PCI configuration register.
981 @param OrData The value to OR with the result of the AND operation.
983 @return The value written back to the PCI configuration register.
988 PciSegmentAndThenOr32 (
994 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
998 Reads a bit field of a PCI configuration register.
1000 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1001 specified by the StartBit and the EndBit. The value of the bit field is
1004 If any reserved bits in Address are set, then ASSERT().
1005 If StartBit is greater than 31, then ASSERT().
1006 If EndBit is greater than 31, then ASSERT().
1007 If EndBit is less than StartBit, then ASSERT().
1009 @param Address PCI configuration register to read.
1010 @param StartBit The ordinal of the least significant bit in the bit field.
1012 @param EndBit The ordinal of the most significant bit in the bit field.
1015 @return The value of the bit field read from the PCI configuration register.
1020 PciSegmentBitFieldRead32 (
1026 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1030 Writes a bit field to a PCI configuration register.
1032 Writes Value to the bit field of the PCI configuration register. The bit
1033 field is specified by the StartBit and the EndBit. All other bits in the
1034 destination PCI configuration register are preserved. The new value of the
1035 32-bit register is returned.
1037 If any reserved bits in Address are set, then ASSERT().
1038 If StartBit is greater than 31, then ASSERT().
1039 If EndBit is greater than 31, then ASSERT().
1040 If EndBit is less than StartBit, then ASSERT().
1042 @param Address PCI configuration register to write.
1043 @param StartBit The ordinal of the least significant bit in the bit field.
1045 @param EndBit The ordinal of the most significant bit in the bit field.
1047 @param Value New value of the bit field.
1049 @return The value written back to the PCI configuration register.
1054 PciSegmentBitFieldWrite32 (
1061 return PciSegmentWrite32 (
1063 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1068 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1069 writes the result back to the bit field in the 32-bit port.
1071 Reads the 32-bit PCI configuration register specified by Address, performs a
1072 bitwise inclusive OR between the read result and the value specified by
1073 OrData, and writes the result to the 32-bit PCI configuration register
1074 specified by Address. The value written to the PCI configuration register is
1075 returned. This function must guarantee that all PCI read and write operations
1076 are serialized. Extra left bits in OrData are stripped.
1078 If any reserved bits in Address are set, then ASSERT().
1079 If StartBit is greater than 31, then ASSERT().
1080 If EndBit is greater than 31, then ASSERT().
1081 If EndBit is less than StartBit, then ASSERT().
1083 @param Address PCI configuration register to write.
1084 @param StartBit The ordinal of the least significant bit in the bit field.
1086 @param EndBit The ordinal of the most significant bit in the bit field.
1088 @param OrData The value to OR with the PCI configuration register.
1090 @return The value written back to the PCI configuration register.
1095 PciSegmentBitFieldOr32 (
1102 return PciSegmentWrite32 (
1104 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1109 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1110 AND, and writes the result back to the bit field in the 32-bit register.
1112 Reads the 32-bit PCI configuration register specified by Address, performs a
1113 bitwise AND between the read result and the value specified by AndData, and
1114 writes the result to the 32-bit PCI configuration register specified by
1115 Address. The value written to the PCI configuration register is returned.
1116 This function must guarantee that all PCI read and write operations are
1117 serialized. Extra left bits in AndData are stripped.
1119 If any reserved bits in Address are set, then ASSERT().
1120 If StartBit is greater than 31, then ASSERT().
1121 If EndBit is greater than 31, then ASSERT().
1122 If EndBit is less than StartBit, then ASSERT().
1124 @param Address PCI configuration register to write.
1125 @param StartBit The ordinal of the least significant bit in the bit field.
1127 @param EndBit The ordinal of the most significant bit in the bit field.
1129 @param AndData The value to AND with the PCI configuration register.
1131 @return The value written back to the PCI configuration register.
1136 PciSegmentBitFieldAnd32 (
1143 return PciSegmentWrite32 (
1145 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1150 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1151 bitwise inclusive OR, and writes the result back to the bit field in the
1154 Reads the 32-bit PCI configuration register specified by Address, performs a
1155 bitwise AND followed by a bitwise inclusive OR between the read result and
1156 the value specified by AndData, and writes the result to the 32-bit PCI
1157 configuration register specified by Address. The value written to the PCI
1158 configuration register is returned. This function must guarantee that all PCI
1159 read and write operations are serialized. Extra left bits in both AndData and
1160 OrData are stripped.
1162 If any reserved bits in Address are set, then ASSERT().
1163 If StartBit is greater than 31, then ASSERT().
1164 If EndBit is greater than 31, then ASSERT().
1165 If EndBit is less than StartBit, then ASSERT().
1167 @param Address PCI configuration register to write.
1168 @param StartBit The ordinal of the least significant bit in the bit field.
1170 @param EndBit The ordinal of the most significant bit in the bit field.
1172 @param AndData The value to AND with the PCI configuration register.
1173 @param OrData The value to OR with the result of the AND operation.
1175 @return The value written back to the PCI configuration register.
1180 PciSegmentBitFieldAndThenOr32 (
1188 return PciSegmentWrite32 (
1190 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1195 Reads a range of PCI configuration registers into a caller supplied buffer.
1197 Reads the range of PCI configuration registers specified by StartAddress and
1198 Size into the buffer specified by Buffer. This function only allows the PCI
1199 configuration registers from a single PCI function to be read. Size is
1200 returned. When possible 32-bit PCI configuration read cycles are used to read
1201 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1202 and 16-bit PCI configuration read cycles may be used at the beginning and the
1205 If StartAddress > 0x0FFFFFFF, then ASSERT().
1206 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1207 If Size > 0 and Buffer is NULL, then ASSERT().
1209 @param StartAddress Starting Address that encodes the PCI Segment, Bus, Device,
1210 Function and Register.
1211 @param Size Size in bytes of the transfer.
1212 @param Buffer Pointer to a buffer receiving the data read.
1219 PciSegmentReadBuffer (
1220 IN UINT64 StartAddress
,
1227 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1228 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1234 ASSERT (Buffer
!= NULL
);
1237 // Save Size for return
1241 if ((StartAddress
& 1) != 0) {
1243 // Read a byte if StartAddress is byte aligned
1245 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1246 StartAddress
+= sizeof (UINT8
);
1247 Size
-= sizeof (UINT8
);
1248 Buffer
= (UINT8
*)Buffer
+ 1;
1251 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1253 // Read a word if StartAddress is word aligned
1255 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1256 StartAddress
+= sizeof (UINT16
);
1257 Size
-= sizeof (UINT16
);
1258 Buffer
= (UINT16
*)Buffer
+ 1;
1261 while (Size
>= sizeof (UINT32
)) {
1263 // Read as many double words as possible
1265 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1266 StartAddress
+= sizeof (UINT32
);
1267 Size
-= sizeof (UINT32
);
1268 Buffer
= (UINT32
*)Buffer
+ 1;
1271 if (Size
>= sizeof (UINT16
)) {
1273 // Read the last remaining word if exist
1275 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1276 StartAddress
+= sizeof (UINT16
);
1277 Size
-= sizeof (UINT16
);
1278 Buffer
= (UINT16
*)Buffer
+ 1;
1281 if (Size
>= sizeof (UINT8
)) {
1283 // Read the last remaining byte if exist
1285 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1292 Copies the data in a caller supplied buffer to a specified range of PCI
1293 configuration space.
1295 Writes the range of PCI configuration registers specified by StartAddress and
1296 Size from the buffer specified by Buffer. This function only allows the PCI
1297 configuration registers from a single PCI function to be written. Size is
1298 returned. When possible 32-bit PCI configuration write cycles are used to
1299 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1300 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1301 and the end of the range.
1303 If StartAddress > 0x0FFFFFFF, then ASSERT().
1304 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1305 If Size > 0 and Buffer is NULL, then ASSERT().
1307 @param StartAddress Starting Address that encodes the PCI Segment, Bus, Device,
1308 Function and Register.
1309 @param Size Size in bytes of the transfer.
1310 @param Buffer Pointer to a buffer containing the data to write.
1317 PciSegmentWriteBuffer (
1318 IN UINT64 StartAddress
,
1325 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1326 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1332 ASSERT (Buffer
!= NULL
);
1335 // Save Size for return
1339 if ((StartAddress
& 1) != 0) {
1341 // Write a byte if StartAddress is byte aligned
1343 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1344 StartAddress
+= sizeof (UINT8
);
1345 Size
-= sizeof (UINT8
);
1346 Buffer
= (UINT8
*)Buffer
+ 1;
1349 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1351 // Write a word if StartAddress is word aligned
1353 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1354 StartAddress
+= sizeof (UINT16
);
1355 Size
-= sizeof (UINT16
);
1356 Buffer
= (UINT16
*)Buffer
+ 1;
1359 while (Size
>= sizeof (UINT32
)) {
1361 // Write as many double words as possible
1363 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1364 StartAddress
+= sizeof (UINT32
);
1365 Size
-= sizeof (UINT32
);
1366 Buffer
= (UINT32
*)Buffer
+ 1;
1369 if (Size
>= sizeof (UINT16
)) {
1371 // Write the last remaining word if exist
1373 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1374 StartAddress
+= sizeof (UINT16
);
1375 Size
-= sizeof (UINT16
);
1376 Buffer
= (UINT16
*)Buffer
+ 1;
1379 if (Size
>= sizeof (UINT8
)) {
1381 // Write the last remaining byte if exist
1383 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);