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
279 Reads the 8-bit PCI configuration register specified by Address, performs a
280 bitwise AND between the read result and the value specified by AndData, and
281 writes the result to the 8-bit PCI configuration register specified by
282 Address. The value written to the PCI configuration register is returned.
283 This function must guarantee that all PCI read and write operations are
286 If any reserved bits in Address are set, then ASSERT().
288 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
290 @param AndData The value to AND with the PCI configuration register.
292 @return The value written back to the PCI configuration register.
302 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
306 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
307 value, followed a bitwise inclusive OR with another 8-bit value.
309 Reads the 8-bit PCI configuration register specified by Address, performs a
310 bitwise AND between the read result and the value specified by AndData,
311 performs a bitwise inclusive OR between the result of the AND operation and
312 the value specified by OrData, and writes the result to the 8-bit PCI
313 configuration register specified by Address. The value written to the PCI
314 configuration register is returned. This function must guarantee that all PCI
315 read and write operations are serialized.
317 If any reserved bits in Address are set, then ASSERT().
319 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
321 @param AndData The value to AND with the PCI configuration register.
322 @param OrData The value to OR with the result of the AND operation.
324 @return The value written back to the PCI configuration register.
329 PciSegmentAndThenOr8 (
335 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
339 Reads a bit field of a PCI configuration register.
341 Reads the bit field in an 8-bit PCI configuration register. The bit field is
342 specified by the StartBit and the EndBit. The value of the bit field is
345 If any reserved bits in Address are set, then ASSERT().
346 If StartBit is greater than 7, then ASSERT().
347 If EndBit is greater than 7, then ASSERT().
348 If EndBit is less than StartBit, then ASSERT().
350 @param Address PCI configuration register to read.
351 @param StartBit The ordinal of the least significant bit in the bit field.
353 @param EndBit The ordinal of the most significant bit in the bit field.
356 @return The value of the bit field read from the PCI configuration register.
361 PciSegmentBitFieldRead8 (
367 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
371 Writes a bit field to a PCI configuration register.
373 Writes Value to the bit field of the PCI configuration register. The bit
374 field is specified by the StartBit and the EndBit. All other bits in the
375 destination PCI configuration register are preserved. The new value of the
376 8-bit register is returned.
378 If any reserved bits in Address are set, then ASSERT().
379 If StartBit is greater than 7, then ASSERT().
380 If EndBit is greater than 7, then ASSERT().
381 If EndBit is less than StartBit, then ASSERT().
383 @param Address PCI configuration register to write.
384 @param StartBit The ordinal of the least significant bit in the bit field.
386 @param EndBit The ordinal of the most significant bit in the bit field.
388 @param Value New value of the bit field.
390 @return The value written back to the PCI configuration register.
395 PciSegmentBitFieldWrite8 (
402 return PciSegmentWrite8 (
404 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
409 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
410 writes the result back to the bit field in the 8-bit port.
412 Reads the 8-bit PCI configuration register specified by Address, performs a
413 bitwise inclusive OR between the read result and the value specified by
414 OrData, and writes the result to the 8-bit PCI configuration register
415 specified by Address. The value written to the PCI configuration register is
416 returned. This function must guarantee that all PCI read and write operations
417 are serialized. Extra left bits in OrData are stripped.
419 If any reserved bits in Address are set, then ASSERT().
420 If StartBit is greater than 7, then ASSERT().
421 If EndBit is greater than 7, then ASSERT().
422 If EndBit is less than StartBit, then ASSERT().
424 @param Address PCI configuration register to write.
425 @param StartBit The ordinal of the least significant bit in the bit field.
427 @param EndBit The ordinal of the most significant bit in the bit field.
429 @param OrData The value to OR with the PCI configuration register.
431 @return The value written back to the PCI configuration register.
436 PciSegmentBitFieldOr8 (
443 return PciSegmentWrite8 (
445 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
450 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
451 AND, and writes the result back to the bit field in the 8-bit register.
453 Reads the 8-bit PCI configuration register specified by Address, performs a
454 bitwise AND between the read result and the value specified by AndData, and
455 writes the result to the 8-bit PCI configuration register specified by
456 Address. The value written to the PCI configuration register is returned.
457 This function must guarantee that all PCI read and write operations are
458 serialized. Extra left bits in AndData are stripped.
460 If any reserved bits in Address are set, then ASSERT().
461 If StartBit is greater than 7, then ASSERT().
462 If EndBit is greater than 7, then ASSERT().
463 If EndBit is less than StartBit, then ASSERT().
465 @param Address PCI configuration register to write.
466 @param StartBit The ordinal of the least significant bit in the bit field.
468 @param EndBit The ordinal of the most significant bit in the bit field.
470 @param AndData The value to AND with the PCI configuration register.
472 @return The value written back to the PCI configuration register.
477 PciSegmentBitFieldAnd8 (
484 return PciSegmentWrite8 (
486 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
491 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
492 bitwise inclusive OR, and writes the result back to the bit field in the
495 Reads the 8-bit PCI configuration register specified by Address, performs a
496 bitwise AND followed by a bitwise inclusive OR between the read result and
497 the value specified by AndData, and writes the result to the 8-bit PCI
498 configuration register specified by Address. The value written to the PCI
499 configuration register is returned. This function must guarantee that all PCI
500 read and write operations are serialized. Extra left bits in both AndData and
503 If any reserved bits in Address are set, then ASSERT().
504 If StartBit is greater than 7, then ASSERT().
505 If EndBit is greater than 7, then ASSERT().
506 If EndBit is less than StartBit, then ASSERT().
508 @param Address PCI configuration register to write.
509 @param StartBit The ordinal of the least significant bit in the bit field.
511 @param EndBit The ordinal of the most significant bit in the bit field.
513 @param AndData The value to AND with the PCI configuration register.
514 @param OrData The value to OR with the result of the AND operation.
516 @return The value written back to the PCI configuration register.
521 PciSegmentBitFieldAndThenOr8 (
529 return PciSegmentWrite8 (
531 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
536 Reads a 16-bit PCI configuration register.
538 Reads and returns the 16-bit PCI configuration register specified by Address.
539 This function must guarantee that all PCI read and write operations are
542 If any reserved bits in Address are set, then ASSERT().
544 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
547 @return The value read from the PCI configuration register.
556 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
558 return (UINT16
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint16
);
562 Writes a 16-bit PCI configuration register.
564 Writes the 16-bit PCI configuration register specified by Address with the
565 value specified by Value. Value is returned. This function must guarantee
566 that all PCI read and write operations are serialized.
568 If any reserved bits in Address are set, then ASSERT().
570 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
572 @param Data The value to write.
574 @return The value written to the PCI configuration register.
584 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
586 return (UINT16
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint16
, Data
);
590 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
593 Reads the 16-bit PCI configuration register specified by Address, performs a
594 bitwise inclusive OR between the read result and the value specified by
595 OrData, and writes the result to the 16-bit PCI configuration register
596 specified by Address. The value written to the PCI configuration register is
597 returned. This function must guarantee that all PCI read and write operations
600 If any reserved bits in Address are set, then ASSERT().
602 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
604 @param OrData The value to OR with the PCI configuration register.
606 @return The value written back to the PCI configuration register.
616 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
620 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
623 Reads the 16-bit PCI configuration register specified by Address, performs a
624 bitwise AND between the read result and the value specified by AndData, and
625 writes the result to the 16-bit PCI configuration register specified by
626 Address. The value written to the PCI configuration register is returned.
627 This function must guarantee that all PCI read and write operations are
630 If any reserved bits in Address are set, then ASSERT().
632 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
634 @param AndData The value to AND with the PCI configuration register.
636 @return The value written back to the PCI configuration register.
646 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
650 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
651 value, followed a bitwise inclusive OR with another 16-bit value.
653 Reads the 16-bit PCI configuration register specified by Address, performs a
654 bitwise AND between the read result and the value specified by AndData,
655 performs a bitwise inclusive OR between the result of the AND operation and
656 the value specified by OrData, and writes the result to the 16-bit PCI
657 configuration register specified by Address. The value written to the PCI
658 configuration register is returned. This function must guarantee that all PCI
659 read and write operations are serialized.
661 If any reserved bits in Address are set, then ASSERT().
663 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
665 @param AndData The value to AND with the PCI configuration register.
666 @param OrData The value to OR with the result of the AND operation.
668 @return The value written back to the PCI configuration register.
673 PciSegmentAndThenOr16 (
679 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
683 Reads a bit field of a PCI configuration register.
685 Reads the bit field in a 16-bit PCI configuration register. The bit field is
686 specified by the StartBit and the EndBit. The value of the bit field is
689 If any reserved bits in Address are set, then ASSERT().
690 If StartBit is greater than 15, then ASSERT().
691 If EndBit is greater than 15, then ASSERT().
692 If EndBit is less than StartBit, then ASSERT().
694 @param Address PCI configuration register to read.
695 @param StartBit The ordinal of the least significant bit in the bit field.
697 @param EndBit The ordinal of the most significant bit in the bit field.
700 @return The value of the bit field read from the PCI configuration register.
705 PciSegmentBitFieldRead16 (
711 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
715 Writes a bit field to a PCI configuration register.
717 Writes Value to the bit field of the PCI configuration register. The bit
718 field is specified by the StartBit and the EndBit. All other bits in the
719 destination PCI configuration register are preserved. The new value of the
720 16-bit register is returned.
722 If any reserved bits in Address are set, then ASSERT().
723 If StartBit is greater than 15, then ASSERT().
724 If EndBit is greater than 15, then ASSERT().
725 If EndBit is less than StartBit, then ASSERT().
727 @param Address PCI configuration register to write.
728 @param StartBit The ordinal of the least significant bit in the bit field.
730 @param EndBit The ordinal of the most significant bit in the bit field.
732 @param Value New value of the bit field.
734 @return The value written back to the PCI configuration register.
739 PciSegmentBitFieldWrite16 (
746 return PciSegmentWrite16 (
748 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
753 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
754 writes the result back to the bit field in the 16-bit port.
756 Reads the 16-bit PCI configuration register specified by Address, performs a
757 bitwise inclusive OR between the read result and the value specified by
758 OrData, and writes the result to the 16-bit PCI configuration register
759 specified by Address. The value written to the PCI configuration register is
760 returned. This function must guarantee that all PCI read and write operations
761 are serialized. Extra left bits in OrData are stripped.
763 If any reserved bits in Address are set, then ASSERT().
764 If StartBit is greater than 15, then ASSERT().
765 If EndBit is greater than 15, then ASSERT().
766 If EndBit is less than StartBit, then ASSERT().
768 @param Address PCI configuration register to write.
769 @param StartBit The ordinal of the least significant bit in the bit field.
771 @param EndBit The ordinal of the most significant bit in the bit field.
773 @param OrData The value to OR with the PCI configuration register.
775 @return The value written back to the PCI configuration register.
780 PciSegmentBitFieldOr16 (
787 return PciSegmentWrite16 (
789 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
794 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
795 AND, and writes the result back to the bit field in the 16-bit register.
797 Reads the 16-bit PCI configuration register specified by Address, performs a
798 bitwise AND between the read result and the value specified by AndData, and
799 writes the result to the 16-bit PCI configuration register specified by
800 Address. The value written to the PCI configuration register is returned.
801 This function must guarantee that all PCI read and write operations are
802 serialized. Extra left bits in AndData are stripped.
804 If any reserved bits in Address are set, then ASSERT().
805 If StartBit is greater than 15, then ASSERT().
806 If EndBit is greater than 15, then ASSERT().
807 If EndBit is less than StartBit, then ASSERT().
809 @param Address PCI configuration register to write.
810 @param StartBit The ordinal of the least significant bit in the bit field.
812 @param EndBit The ordinal of the most significant bit in the bit field.
814 @param AndData The value to AND with the PCI configuration register.
816 @return The value written back to the PCI configuration register.
821 PciSegmentBitFieldAnd16 (
828 return PciSegmentWrite16 (
830 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
835 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
836 bitwise inclusive OR, and writes the result back to the bit field in the
839 Reads the 16-bit PCI configuration register specified by Address, performs a
840 bitwise AND followed by a bitwise inclusive OR between the read result and
841 the value specified by AndData, and writes the result to the 16-bit PCI
842 configuration register specified by Address. The value written to the PCI
843 configuration register is returned. This function must guarantee that all PCI
844 read and write operations are serialized. Extra left bits in both AndData and
847 If any reserved bits in Address are set, then ASSERT().
848 If StartBit is greater than 15, then ASSERT().
849 If EndBit is greater than 15, then ASSERT().
850 If EndBit is less than StartBit, then ASSERT().
852 @param Address PCI configuration register to write.
853 @param StartBit The ordinal of the least significant bit in the bit field.
855 @param EndBit The ordinal of the most significant bit in the bit field.
857 @param AndData The value to AND with the PCI configuration register.
858 @param OrData The value to OR with the result of the AND operation.
860 @return The value written back to the PCI configuration register.
865 PciSegmentBitFieldAndThenOr16 (
873 return PciSegmentWrite16 (
875 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
880 Reads a 32-bit PCI configuration register.
882 Reads and returns the 32-bit PCI configuration register specified by Address.
883 This function must guarantee that all PCI read and write operations are
886 If any reserved bits in Address are set, then ASSERT().
888 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
891 @return The value read from the PCI configuration register.
900 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
902 return PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint32
);
906 Writes a 32-bit PCI configuration register.
908 Writes the 32-bit PCI configuration register specified by Address with the
909 value specified by Value. Value is returned. This function must guarantee
910 that all PCI read and write operations are serialized.
912 If any reserved bits in Address are set, then ASSERT().
914 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
916 @param Data The value to write.
918 @return The value written to the PCI configuration register.
928 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
930 return PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint32
, Data
);
934 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
937 Reads the 32-bit PCI configuration register specified by Address, performs a
938 bitwise inclusive OR between the read result and the value specified by
939 OrData, and writes the result to the 32-bit PCI configuration register
940 specified by Address. The value written to the PCI configuration register is
941 returned. This function must guarantee that all PCI read and write operations
944 If any reserved bits in Address are set, then ASSERT().
946 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
948 @param OrData The value to OR with the PCI configuration register.
950 @return The value written back to the PCI configuration register.
960 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
964 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
967 Reads the 32-bit PCI configuration register specified by Address, performs a
968 bitwise AND between the read result and the value specified by AndData, and
969 writes the result to the 32-bit PCI configuration register specified by
970 Address. The value written to the PCI configuration register is returned.
971 This function must guarantee that all PCI read and write operations are
974 If any reserved bits in Address are set, then ASSERT().
976 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
978 @param AndData The value to AND with the PCI configuration register.
980 @return The value written back to the PCI configuration register.
990 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
994 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
995 value, followed a bitwise inclusive OR with another 32-bit value.
997 Reads the 32-bit PCI configuration register specified by Address, performs a
998 bitwise AND between the read result and the value specified by AndData,
999 performs a bitwise inclusive OR between the result of the AND operation and
1000 the value specified by OrData, and writes the result to the 32-bit PCI
1001 configuration register specified by Address. The value written to the PCI
1002 configuration register is returned. This function must guarantee that all PCI
1003 read and write operations are serialized.
1005 If any reserved bits in Address are set, then ASSERT().
1007 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1009 @param AndData The value to AND with the PCI configuration register.
1010 @param OrData The value to OR with the result of the AND operation.
1012 @return The value written back to the PCI configuration register.
1017 PciSegmentAndThenOr32 (
1023 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1027 Reads a bit field of a PCI configuration register.
1029 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1030 specified by the StartBit and the EndBit. The value of the bit field is
1033 If any reserved bits in Address are set, then ASSERT().
1034 If StartBit is greater than 31, then ASSERT().
1035 If EndBit is greater than 31, then ASSERT().
1036 If EndBit is less than StartBit, then ASSERT().
1038 @param Address PCI configuration register to read.
1039 @param StartBit The ordinal of the least significant bit in the bit field.
1041 @param EndBit The ordinal of the most significant bit in the bit field.
1044 @return The value of the bit field read from the PCI configuration register.
1049 PciSegmentBitFieldRead32 (
1055 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1059 Writes a bit field to a PCI configuration register.
1061 Writes Value to the bit field of the PCI configuration register. The bit
1062 field is specified by the StartBit and the EndBit. All other bits in the
1063 destination PCI configuration register are preserved. The new value of the
1064 32-bit register is returned.
1066 If any reserved bits in Address are set, then ASSERT().
1067 If StartBit is greater than 31, then ASSERT().
1068 If EndBit is greater than 31, then ASSERT().
1069 If EndBit is less than StartBit, then ASSERT().
1071 @param Address PCI configuration register to write.
1072 @param StartBit The ordinal of the least significant bit in the bit field.
1074 @param EndBit The ordinal of the most significant bit in the bit field.
1076 @param Value New value of the bit field.
1078 @return The value written back to the PCI configuration register.
1083 PciSegmentBitFieldWrite32 (
1090 return PciSegmentWrite32 (
1092 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1097 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1098 writes the result back to the bit field in the 32-bit port.
1100 Reads the 32-bit PCI configuration register specified by Address, performs a
1101 bitwise inclusive OR between the read result and the value specified by
1102 OrData, and writes the result to the 32-bit PCI configuration register
1103 specified by Address. The value written to the PCI configuration register is
1104 returned. This function must guarantee that all PCI read and write operations
1105 are serialized. Extra left bits in OrData are stripped.
1107 If any reserved bits in Address are set, then ASSERT().
1108 If StartBit is greater than 31, then ASSERT().
1109 If EndBit is greater than 31, then ASSERT().
1110 If EndBit is less than StartBit, then ASSERT().
1112 @param Address PCI configuration register to write.
1113 @param StartBit The ordinal of the least significant bit in the bit field.
1115 @param EndBit The ordinal of the most significant bit in the bit field.
1117 @param OrData The value to OR with the PCI configuration register.
1119 @return The value written back to the PCI configuration register.
1124 PciSegmentBitFieldOr32 (
1131 return PciSegmentWrite32 (
1133 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1138 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1139 AND, and writes the result back to the bit field in the 32-bit register.
1141 Reads the 32-bit PCI configuration register specified by Address, performs a
1142 bitwise AND between the read result and the value specified by AndData, and
1143 writes the result to the 32-bit PCI configuration register specified by
1144 Address. The value written to the PCI configuration register is returned.
1145 This function must guarantee that all PCI read and write operations are
1146 serialized. Extra left bits in AndData are stripped.
1148 If any reserved bits in Address are set, then ASSERT().
1149 If StartBit is greater than 31, then ASSERT().
1150 If EndBit is greater than 31, then ASSERT().
1151 If EndBit is less than StartBit, then ASSERT().
1153 @param Address PCI configuration register to write.
1154 @param StartBit The ordinal of the least significant bit in the bit field.
1156 @param EndBit The ordinal of the most significant bit in the bit field.
1158 @param AndData The value to AND with the PCI configuration register.
1160 @return The value written back to the PCI configuration register.
1165 PciSegmentBitFieldAnd32 (
1172 return PciSegmentWrite32 (
1174 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1179 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1180 bitwise inclusive OR, and writes the result back to the bit field in the
1183 Reads the 32-bit PCI configuration register specified by Address, performs a
1184 bitwise AND followed by a bitwise inclusive OR between the read result and
1185 the value specified by AndData, and writes the result to the 32-bit PCI
1186 configuration register specified by Address. The value written to the PCI
1187 configuration register is returned. This function must guarantee that all PCI
1188 read and write operations are serialized. Extra left bits in both AndData and
1189 OrData are stripped.
1191 If any reserved bits in Address are set, then ASSERT().
1192 If StartBit is greater than 31, then ASSERT().
1193 If EndBit is greater than 31, then ASSERT().
1194 If EndBit is less than StartBit, then ASSERT().
1196 @param Address PCI configuration register to write.
1197 @param StartBit The ordinal of the least significant bit in the bit field.
1199 @param EndBit The ordinal of the most significant bit in the bit field.
1201 @param AndData The value to AND with the PCI configuration register.
1202 @param OrData The value to OR with the result of the AND operation.
1204 @return The value written back to the PCI configuration register.
1209 PciSegmentBitFieldAndThenOr32 (
1217 return PciSegmentWrite32 (
1219 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1224 Reads a range of PCI configuration registers into a caller supplied buffer.
1226 Reads the range of PCI configuration registers specified by StartAddress and
1227 Size into the buffer specified by Buffer. This function only allows the PCI
1228 configuration registers from a single PCI function to be read. Size is
1229 returned. When possible 32-bit PCI configuration read cycles are used to read
1230 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1231 and 16-bit PCI configuration read cycles may be used at the beginning and the
1234 If StartAddress > 0x0FFFFFFF, then ASSERT().
1235 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1236 If Size > 0 and Buffer is NULL, then ASSERT().
1238 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1239 Function and Register.
1240 @param Size Size in bytes of the transfer.
1241 @param Buffer Pointer to a buffer receiving the data read.
1248 PciSegmentReadBuffer (
1249 IN UINT64 StartAddress
,
1256 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1257 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1263 ASSERT (Buffer
!= NULL
);
1266 // Save Size for return
1270 if ((StartAddress
& BIT0
) != 0) {
1272 // Read a byte if StartAddress is byte aligned
1274 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1275 StartAddress
+= sizeof (UINT8
);
1276 Size
-= sizeof (UINT8
);
1277 Buffer
= (UINT8
*)Buffer
+ 1;
1280 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1282 // Read a word if StartAddress is word aligned
1284 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1285 StartAddress
+= sizeof (UINT16
);
1286 Size
-= sizeof (UINT16
);
1287 Buffer
= (UINT16
*)Buffer
+ 1;
1290 while (Size
>= sizeof (UINT32
)) {
1292 // Read as many double words as possible
1294 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1295 StartAddress
+= sizeof (UINT32
);
1296 Size
-= sizeof (UINT32
);
1297 Buffer
= (UINT32
*)Buffer
+ 1;
1300 if (Size
>= sizeof (UINT16
)) {
1302 // Read the last remaining word if exist
1304 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1305 StartAddress
+= sizeof (UINT16
);
1306 Size
-= sizeof (UINT16
);
1307 Buffer
= (UINT16
*)Buffer
+ 1;
1310 if (Size
>= sizeof (UINT8
)) {
1312 // Read the last remaining byte if exist
1314 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1321 Copies the data in a caller supplied buffer to a specified range of PCI
1322 configuration space.
1324 Writes the range of PCI configuration registers specified by StartAddress and
1325 Size from the buffer specified by Buffer. This function only allows the PCI
1326 configuration registers from a single PCI function to be written. Size is
1327 returned. When possible 32-bit PCI configuration write cycles are used to
1328 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1329 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1330 and the end of the range.
1332 If StartAddress > 0x0FFFFFFF, then ASSERT().
1333 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1334 If Size > 0 and Buffer is NULL, then ASSERT().
1336 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1337 Function and Register.
1338 @param Size Size in bytes of the transfer.
1339 @param Buffer Pointer to a buffer containing the data to write.
1346 PciSegmentWriteBuffer (
1347 IN UINT64 StartAddress
,
1354 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1355 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1361 ASSERT (Buffer
!= NULL
);
1364 // Save Size for return
1368 if ((StartAddress
& BIT0
) != 0) {
1370 // Write a byte if StartAddress is byte aligned
1372 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1373 StartAddress
+= sizeof (UINT8
);
1374 Size
-= sizeof (UINT8
);
1375 Buffer
= (UINT8
*)Buffer
+ 1;
1378 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1380 // Write a word if StartAddress is word aligned
1382 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1383 StartAddress
+= sizeof (UINT16
);
1384 Size
-= sizeof (UINT16
);
1385 Buffer
= (UINT16
*)Buffer
+ 1;
1388 while (Size
>= sizeof (UINT32
)) {
1390 // Write as many double words as possible
1392 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1393 StartAddress
+= sizeof (UINT32
);
1394 Size
-= sizeof (UINT32
);
1395 Buffer
= (UINT32
*)Buffer
+ 1;
1398 if (Size
>= sizeof (UINT16
)) {
1400 // Write the last remaining word if exist
1402 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1403 StartAddress
+= sizeof (UINT16
);
1404 Size
-= sizeof (UINT16
);
1405 Buffer
= (UINT16
*)Buffer
+ 1;
1408 if (Size
>= sizeof (UINT8
)) {
1410 // Write the last remaining byte if exist
1412 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);