2 PCI Segment Library implementation using PCI CFG2 PPI.
4 Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are
6 licensed and made available under the terms and conditions of
7 the BSD License which accompanies this distribution. The full
8 text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Ppi/PciCfg2.h>
20 #include <Library/PciSegmentLib.h>
21 #include <Library/BaseLib.h>
22 #include <Library/PeiServicesTablePointerLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/PeiServicesLib.h>
27 Assert the validity of a PCI Segment address.
28 A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
30 @param A The address to validate.
31 @param M Additional bits to assert to be zero.
34 #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
35 ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
38 Translate PCI Lib address into format of PCI CFG2 PPI.
40 @param A Address that encodes the PCI Bus, Device, Function and
44 #define PCI_TO_PCICFG2_ADDRESS(A) \
45 ((((UINT32)(A) << 4) & 0xff000000) | (((UINT32)(A) >> 4) & 0x00000700) | (((UINT32)(A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))
50 This internal function retrieves PCI CFG2 PPI from PPI database.
52 @param Address 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 any reserved bits in Address are set, 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 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
189 return RETURN_UNSUPPORTED
;
193 Reads an 8-bit PCI configuration register.
195 Reads and returns the 8-bit PCI configuration register specified by Address.
196 This function must guarantee that all PCI read and write operations are serialized.
198 If any reserved bits in Address are set, then ASSERT().
200 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
202 @return The 8-bit PCI configuration register specified by Address.
211 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
213 return (UINT8
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint8
);
217 Writes an 8-bit PCI configuration register.
219 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
220 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
222 If any reserved bits in Address are set, then ASSERT().
224 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
225 @param Value The value to write.
227 @return The value written to the PCI configuration register.
237 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
239 return (UINT8
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint8
, Value
);
243 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
245 Reads the 8-bit PCI configuration register specified by Address,
246 performs a bitwise OR between the read result and the value specified by OrData,
247 and writes the result to the 8-bit PCI configuration register specified by Address.
248 The value written to the PCI configuration register is returned.
249 This function must guarantee that all PCI read and write operations are serialized.
251 If any reserved bits in Address are set, then ASSERT().
253 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
254 @param OrData The value to OR with the PCI configuration register.
256 @return The value written to the PCI configuration register.
266 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
270 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
272 Reads the 8-bit PCI configuration register specified by Address,
273 performs a bitwise AND between the read result and the value specified by AndData,
274 and writes the result to the 8-bit PCI configuration register specified by Address.
275 The value written to the PCI configuration register is returned.
276 This function must guarantee that all PCI read and write operations are serialized.
277 If any reserved bits in Address are set, then ASSERT().
279 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
280 @param AndData The value to AND with the PCI configuration register.
282 @return The value written to the PCI configuration register.
292 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
296 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
297 followed a bitwise OR with another 8-bit value.
299 Reads the 8-bit PCI configuration register specified by Address,
300 performs a bitwise AND between the read result and the value specified by AndData,
301 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
302 and writes the result to the 8-bit PCI configuration register specified by Address.
303 The value written to the PCI configuration register is returned.
304 This function must guarantee that all PCI read and write operations are serialized.
306 If any reserved bits in Address are set, then ASSERT().
308 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
309 @param AndData The value to AND with the PCI configuration register.
310 @param OrData The value to OR with the PCI configuration register.
312 @return The value written to the PCI configuration register.
317 PciSegmentAndThenOr8 (
323 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
327 Reads a bit field of a PCI configuration register.
329 Reads the bit field in an 8-bit PCI configuration register. The bit field is
330 specified by the StartBit and the EndBit. The value of the bit field is
333 If any reserved bits in Address are set, then ASSERT().
334 If StartBit is greater than 7, then ASSERT().
335 If EndBit is greater than 7, then ASSERT().
336 If EndBit is less than StartBit, then ASSERT().
338 @param Address PCI configuration register to read.
339 @param StartBit The ordinal of the least significant bit in the bit field.
341 @param EndBit The ordinal of the most significant bit in the bit field.
344 @return The value of the bit field read from the PCI configuration register.
349 PciSegmentBitFieldRead8 (
355 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
359 Writes a bit field to a PCI configuration register.
361 Writes Value to the bit field of the PCI configuration register. The bit
362 field is specified by the StartBit and the EndBit. All other bits in the
363 destination PCI configuration register are preserved. The new value of the
364 8-bit register is returned.
366 If any reserved bits in Address are set, then ASSERT().
367 If StartBit is greater than 7, then ASSERT().
368 If EndBit is greater than 7, then ASSERT().
369 If EndBit is less than StartBit, then ASSERT().
371 @param Address PCI configuration register to write.
372 @param StartBit The ordinal of the least significant bit in the bit field.
374 @param EndBit The ordinal of the most significant bit in the bit field.
376 @param Value New value of the bit field.
378 @return The value written back to the PCI configuration register.
383 PciSegmentBitFieldWrite8 (
390 return PciSegmentWrite8 (
392 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
397 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
398 writes the result back to the bit field in the 8-bit port.
400 Reads the 8-bit PCI configuration register specified by Address, performs a
401 bitwise OR between the read result and the value specified by
402 OrData, and writes the result to the 8-bit PCI configuration register
403 specified by Address. The value written to the PCI configuration register is
404 returned. This function must guarantee that all PCI read and write operations
405 are serialized. Extra left bits in OrData are stripped.
407 If any reserved bits in Address are set, then ASSERT().
408 If StartBit is greater than 7, then ASSERT().
409 If EndBit is greater than 7, then ASSERT().
410 If EndBit is less than StartBit, then ASSERT().
412 @param Address PCI configuration register to write.
413 @param StartBit The ordinal of the least significant bit in the bit field.
415 @param EndBit The ordinal of the most significant bit in the bit field.
417 @param OrData The value to OR with the PCI configuration register.
419 @return The value written back to the PCI configuration register.
424 PciSegmentBitFieldOr8 (
431 return PciSegmentWrite8 (
433 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
438 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
439 AND, and writes the result back to the bit field in the 8-bit register.
441 Reads the 8-bit PCI configuration register specified by Address, performs a
442 bitwise AND between the read result and the value specified by AndData, and
443 writes the result to the 8-bit PCI configuration register specified by
444 Address. The value written to the PCI configuration register is returned.
445 This function must guarantee that all PCI read and write operations are
446 serialized. Extra left bits in AndData are stripped.
448 If any reserved bits in Address are set, then ASSERT().
449 If StartBit is greater than 7, then ASSERT().
450 If EndBit is greater than 7, then ASSERT().
451 If EndBit is less than StartBit, then ASSERT().
453 @param Address PCI configuration register to write.
454 @param StartBit The ordinal of the least significant bit in the bit field.
456 @param EndBit The ordinal of the most significant bit in the bit field.
458 @param AndData The value to AND with the PCI configuration register.
460 @return The value written back to the PCI configuration register.
465 PciSegmentBitFieldAnd8 (
472 return PciSegmentWrite8 (
474 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
479 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
480 bitwise OR, and writes the result back to the bit field in the
483 Reads the 8-bit PCI configuration register specified by Address, performs a
484 bitwise AND followed by a bitwise OR between the read result and
485 the value specified by AndData, and writes the result to the 8-bit PCI
486 configuration register specified by Address. The value written to the PCI
487 configuration register is returned. This function must guarantee that all PCI
488 read and write operations are serialized. Extra left bits in both AndData and
491 If any reserved bits in Address are set, then ASSERT().
492 If StartBit is greater than 7, then ASSERT().
493 If EndBit is greater than 7, then ASSERT().
494 If EndBit is less than StartBit, then ASSERT().
496 @param Address PCI configuration register to write.
497 @param StartBit The ordinal of the least significant bit in the bit field.
499 @param EndBit The ordinal of the most significant bit in the bit field.
501 @param AndData The value to AND with the PCI configuration register.
502 @param OrData The value to OR with the result of the AND operation.
504 @return The value written back to the PCI configuration register.
509 PciSegmentBitFieldAndThenOr8 (
517 return PciSegmentWrite8 (
519 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
524 Reads a 16-bit PCI configuration register.
526 Reads and returns the 16-bit PCI configuration register specified by Address.
527 This function must guarantee that all PCI read and write operations are serialized.
529 If any reserved bits in Address are set, then ASSERT().
530 If Address is not aligned on a 16-bit boundary, then ASSERT().
532 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
534 @return The 16-bit PCI configuration register specified by Address.
543 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
545 return (UINT16
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint16
);
549 Writes a 16-bit PCI configuration register.
551 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
552 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
554 If any reserved bits in Address are set, then ASSERT().
555 If Address is not aligned on a 16-bit boundary, then ASSERT().
557 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
558 @param Value The value to write.
560 @return The parameter of Value.
570 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
572 return (UINT16
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint16
, Value
);
576 Performs a bitwise OR of a 16-bit PCI configuration register with
579 Reads the 16-bit PCI configuration register specified by Address, performs a
580 bitwise OR between the read result and the value specified by
581 OrData, and writes the result to the 16-bit PCI configuration register
582 specified by Address. The value written to the PCI configuration register is
583 returned. This function must guarantee that all PCI read and write operations
586 If any reserved bits in Address are set, then ASSERT().
587 If Address is not aligned on a 16-bit boundary, then ASSERT().
589 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
591 @param OrData The value to OR with the PCI configuration register.
593 @return The value written back to the PCI configuration register.
603 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
607 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
609 Reads the 16-bit PCI configuration register specified by Address,
610 performs a bitwise AND between the read result and the value specified by AndData,
611 and writes the result to the 16-bit PCI configuration register specified by Address.
612 The value written to the PCI configuration register is returned.
613 This function must guarantee that all PCI read and write operations are serialized.
615 If any reserved bits in Address are set, then ASSERT().
616 If Address is not aligned on a 16-bit boundary, then ASSERT().
618 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
619 @param AndData The value to AND with the PCI configuration register.
621 @return The value written to the PCI configuration register.
631 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
635 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
636 followed a bitwise OR with another 16-bit value.
638 Reads the 16-bit PCI configuration register specified by Address,
639 performs a bitwise AND between the read result and the value specified by AndData,
640 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
641 and writes the result to the 16-bit PCI configuration register specified by Address.
642 The value written to the PCI configuration register is returned.
643 This function must guarantee that all PCI read and write operations are serialized.
645 If any reserved bits in Address are set, then ASSERT().
646 If Address is not aligned on a 16-bit boundary, then ASSERT().
648 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
649 @param AndData The value to AND with the PCI configuration register.
650 @param OrData The value to OR with the PCI configuration register.
652 @return The value written to the PCI configuration register.
657 PciSegmentAndThenOr16 (
663 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
667 Reads a bit field of a PCI configuration register.
669 Reads the bit field in a 16-bit PCI configuration register. The bit field is
670 specified by the StartBit and the EndBit. The value of the bit field is
673 If any reserved bits in Address are set, then ASSERT().
674 If Address is not aligned on a 16-bit boundary, then ASSERT().
675 If StartBit is greater than 15, then ASSERT().
676 If EndBit is greater than 15, then ASSERT().
677 If EndBit is less than StartBit, then ASSERT().
679 @param Address PCI configuration register to read.
680 @param StartBit The ordinal of the least significant bit in the bit field.
682 @param EndBit The ordinal of the most significant bit in the bit field.
685 @return The value of the bit field read from the PCI configuration register.
690 PciSegmentBitFieldRead16 (
696 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
700 Writes a bit field to a PCI configuration register.
702 Writes Value to the bit field of the PCI configuration register. The bit
703 field is specified by the StartBit and the EndBit. All other bits in the
704 destination PCI configuration register are preserved. The new value of the
705 16-bit register is returned.
707 If any reserved bits in Address are set, then ASSERT().
708 If Address is not aligned on a 16-bit boundary, then ASSERT().
709 If StartBit is greater than 15, then ASSERT().
710 If EndBit is greater than 15, then ASSERT().
711 If EndBit is less than StartBit, then ASSERT().
713 @param Address PCI configuration register to write.
714 @param StartBit The ordinal of the least significant bit in the bit field.
716 @param EndBit The ordinal of the most significant bit in the bit field.
718 @param Value New value of the bit field.
720 @return The value written back to the PCI configuration register.
725 PciSegmentBitFieldWrite16 (
732 return PciSegmentWrite16 (
734 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
739 Reads the 16-bit PCI configuration register specified by Address,
740 performs a bitwise OR between the read result and the value specified by OrData,
741 and writes the result to the 16-bit PCI configuration register specified by Address.
743 If any reserved bits in Address are set, then ASSERT().
744 If Address is not aligned on a 16-bit boundary, then ASSERT().
745 If StartBit is greater than 15, then ASSERT().
746 If EndBit is greater than 15, then ASSERT().
747 If EndBit is less than StartBit, then ASSERT().
749 @param Address PCI configuration register to write.
750 @param StartBit The ordinal of the least significant bit in the bit field.
752 @param EndBit The ordinal of the most significant bit in the bit field.
754 @param OrData The value to OR with the PCI configuration register.
756 @return The value written back to the PCI configuration register.
761 PciSegmentBitFieldOr16 (
768 return PciSegmentWrite16 (
770 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
775 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
776 and writes the result back to the bit field in the 16-bit port.
778 Reads the 16-bit PCI configuration register specified by Address,
779 performs a bitwise OR between the read result and the value specified by OrData,
780 and writes the result to the 16-bit PCI configuration register specified by Address.
781 The value written to the PCI configuration register is returned.
782 This function must guarantee that all PCI read and write operations are serialized.
783 Extra left bits in OrData are stripped.
785 If any reserved bits in Address are set, then ASSERT().
786 If Address is not aligned on a 16-bit boundary, then ASSERT().
787 If StartBit is greater than 7, then ASSERT().
788 If EndBit is greater than 7, then ASSERT().
789 If EndBit is less than StartBit, then ASSERT().
791 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
792 @param StartBit The ordinal of the least significant bit in the bit field.
793 The ordinal of the least significant bit in a byte is bit 0.
794 @param EndBit The ordinal of the most significant bit in the bit field.
795 The ordinal of the most significant bit in a byte is bit 7.
796 @param AndData The value to AND with the read value from the PCI configuration register.
798 @return The value written to the PCI configuration register.
803 PciSegmentBitFieldAnd16 (
810 return PciSegmentWrite16 (
812 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
817 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
818 bitwise OR, and writes the result back to the bit field in the
821 Reads the 16-bit PCI configuration register specified by Address, performs a
822 bitwise AND followed by a bitwise OR between the read result and
823 the value specified by AndData, and writes the result to the 16-bit PCI
824 configuration register specified by Address. The value written to the PCI
825 configuration register is returned. This function must guarantee that all PCI
826 read and write operations are serialized. Extra left bits in both AndData and
829 If any reserved bits in Address are set, then ASSERT().
830 If StartBit is greater than 15, then ASSERT().
831 If EndBit is greater than 15, then ASSERT().
832 If EndBit is less than StartBit, then ASSERT().
834 @param Address PCI configuration register to write.
835 @param StartBit The ordinal of the least significant bit in the bit field.
837 @param EndBit The ordinal of the most significant bit in the bit field.
839 @param AndData The value to AND with the PCI configuration register.
840 @param OrData The value to OR with the result of the AND operation.
842 @return The value written back to the PCI configuration register.
847 PciSegmentBitFieldAndThenOr16 (
855 return PciSegmentWrite16 (
857 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
862 Reads a 32-bit PCI configuration register.
864 Reads and returns the 32-bit PCI configuration register specified by Address.
865 This function must guarantee that all PCI read and write operations are serialized.
867 If any reserved bits in Address are set, then ASSERT().
868 If Address is not aligned on a 32-bit boundary, then ASSERT().
870 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
872 @return The 32-bit PCI configuration register specified by Address.
881 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
883 return PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint32
);
887 Writes a 32-bit PCI configuration register.
889 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
890 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
892 If any reserved bits in Address are set, then ASSERT().
893 If Address is not aligned on a 32-bit boundary, then ASSERT().
895 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
896 @param Value The value to write.
898 @return The parameter of Value.
908 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
910 return PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint32
, Value
);
914 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
916 Reads the 32-bit PCI configuration register specified by Address,
917 performs a bitwise OR between the read result and the value specified by OrData,
918 and writes the result to the 32-bit PCI configuration register specified by Address.
919 The value written to the PCI configuration register is returned.
920 This function must guarantee that all PCI read and write operations are serialized.
922 If any reserved bits in Address are set, then ASSERT().
923 If Address is not aligned on a 32-bit boundary, then ASSERT().
925 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
926 @param OrData The value to OR with the PCI configuration register.
928 @return The value written to the PCI configuration register.
938 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
942 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
944 Reads the 32-bit PCI configuration register specified by Address,
945 performs a bitwise AND between the read result and the value specified by AndData,
946 and writes the result to the 32-bit PCI configuration register specified by Address.
947 The value written to the PCI configuration register is returned.
948 This function must guarantee that all PCI read and write operations are serialized.
950 If any reserved bits in Address are set, then ASSERT().
951 If Address is not aligned on a 32-bit boundary, then ASSERT().
953 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
954 @param AndData The value to AND with the PCI configuration register.
956 @return The value written to the PCI configuration register.
966 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
970 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
971 followed a bitwise OR with another 32-bit value.
973 Reads the 32-bit PCI configuration register specified by Address,
974 performs a bitwise AND between the read result and the value specified by AndData,
975 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
976 and writes the result to the 32-bit PCI configuration register specified by Address.
977 The value written to the PCI configuration register is returned.
978 This function must guarantee that all PCI read and write operations are serialized.
980 If any reserved bits in Address are set, then ASSERT().
981 If Address is not aligned on a 32-bit boundary, then ASSERT().
983 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
984 @param AndData The value to AND with the PCI configuration register.
985 @param OrData The value to OR with the PCI configuration register.
987 @return The value written to the PCI configuration register.
992 PciSegmentAndThenOr32 (
998 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1002 Reads a bit field of a PCI configuration register.
1004 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1005 specified by the StartBit and the EndBit. The value of the bit field is
1008 If any reserved bits in Address are set, then ASSERT().
1009 If Address is not aligned on a 32-bit boundary, then ASSERT().
1010 If StartBit is greater than 31, then ASSERT().
1011 If EndBit is greater than 31, then ASSERT().
1012 If EndBit is less than StartBit, then ASSERT().
1014 @param Address PCI configuration register to read.
1015 @param StartBit The ordinal of the least significant bit in the bit field.
1017 @param EndBit The ordinal of the most significant bit in the bit field.
1020 @return The value of the bit field read from the PCI configuration register.
1025 PciSegmentBitFieldRead32 (
1031 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1035 Writes a bit field to a PCI configuration register.
1037 Writes Value to the bit field of the PCI configuration register. The bit
1038 field is specified by the StartBit and the EndBit. All other bits in the
1039 destination PCI configuration register are preserved. The new value of the
1040 32-bit register is returned.
1042 If any reserved bits in Address are set, then ASSERT().
1043 If Address is not aligned on a 32-bit boundary, then ASSERT().
1044 If StartBit is greater than 31, then ASSERT().
1045 If EndBit is greater than 31, then ASSERT().
1046 If EndBit is less than StartBit, then ASSERT().
1048 @param Address PCI configuration register to write.
1049 @param StartBit The ordinal of the least significant bit in the bit field.
1051 @param EndBit The ordinal of the most significant bit in the bit field.
1053 @param Value New value of the bit field.
1055 @return The value written back to the PCI configuration register.
1060 PciSegmentBitFieldWrite32 (
1067 return PciSegmentWrite32 (
1069 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1074 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1075 writes the result back to the bit field in the 32-bit port.
1077 Reads the 32-bit PCI configuration register specified by Address, performs a
1078 bitwise OR between the read result and the value specified by
1079 OrData, and writes the result to the 32-bit PCI configuration register
1080 specified by Address. The value written to the PCI configuration register is
1081 returned. This function must guarantee that all PCI read and write operations
1082 are serialized. Extra left bits in OrData are stripped.
1084 If any reserved bits in Address are set, then ASSERT().
1085 If StartBit is greater than 31, then ASSERT().
1086 If EndBit is greater than 31, then ASSERT().
1087 If EndBit is less than StartBit, then ASSERT().
1089 @param Address PCI configuration register to write.
1090 @param StartBit The ordinal of the least significant bit in the bit field.
1092 @param EndBit The ordinal of the most significant bit in the bit field.
1094 @param OrData The value to OR with the PCI configuration register.
1096 @return The value written back to the PCI configuration register.
1101 PciSegmentBitFieldOr32 (
1108 return PciSegmentWrite32 (
1110 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1115 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1116 AND, and writes the result back to the bit field in the 32-bit register.
1119 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1120 AND between the read result and the value specified by AndData, and writes the result
1121 to the 32-bit PCI configuration register specified by Address. The value written to
1122 the PCI configuration register is returned. This function must guarantee that all PCI
1123 read and write operations are serialized. Extra left bits in AndData are stripped.
1124 If any reserved bits in Address are set, then ASSERT().
1125 If Address is not aligned on a 32-bit boundary, then ASSERT().
1126 If StartBit is greater than 31, then ASSERT().
1127 If EndBit is greater than 31, then ASSERT().
1128 If EndBit is less than StartBit, then ASSERT().
1131 @param Address PCI configuration register to write.
1132 @param StartBit The ordinal of the least significant bit in the bit field.
1134 @param EndBit The ordinal of the most significant bit in the bit field.
1136 @param AndData The value to AND with the PCI configuration register.
1138 @return The value written back to the PCI configuration register.
1143 PciSegmentBitFieldAnd32 (
1150 return PciSegmentWrite32 (
1152 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1157 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1158 bitwise OR, and writes the result back to the bit field in the
1161 Reads the 32-bit PCI configuration register specified by Address, performs a
1162 bitwise AND followed by a bitwise OR between the read result and
1163 the value specified by AndData, and writes the result to the 32-bit PCI
1164 configuration register specified by Address. The value written to the PCI
1165 configuration register is returned. This function must guarantee that all PCI
1166 read and write operations are serialized. Extra left bits in both AndData and
1167 OrData are stripped.
1169 If any reserved bits in Address are set, then ASSERT().
1170 If StartBit is greater than 31, then ASSERT().
1171 If EndBit is greater than 31, then ASSERT().
1172 If EndBit is less than StartBit, then ASSERT().
1174 @param Address PCI configuration register to write.
1175 @param StartBit The ordinal of the least significant bit in the bit field.
1177 @param EndBit The ordinal of the most significant bit in the bit field.
1179 @param AndData The value to AND with the PCI configuration register.
1180 @param OrData The value to OR with the result of the AND operation.
1182 @return The value written back to the PCI configuration register.
1187 PciSegmentBitFieldAndThenOr32 (
1195 return PciSegmentWrite32 (
1197 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1202 Reads a range of PCI configuration registers into a caller supplied buffer.
1204 Reads the range of PCI configuration registers specified by StartAddress and
1205 Size into the buffer specified by Buffer. This function only allows the PCI
1206 configuration registers from a single PCI function to be read. Size is
1207 returned. When possible 32-bit PCI configuration read cycles are used to read
1208 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1209 and 16-bit PCI configuration read cycles may be used at the beginning and the
1212 If any reserved bits in StartAddress are set, then ASSERT().
1213 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1214 If Size > 0 and Buffer is NULL, then ASSERT().
1216 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1217 Function and Register.
1218 @param Size Size in bytes of the transfer.
1219 @param Buffer Pointer to a buffer receiving the data read.
1226 PciSegmentReadBuffer (
1227 IN UINT64 StartAddress
,
1234 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1235 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1241 ASSERT (Buffer
!= NULL
);
1244 // Save Size for return
1248 if ((StartAddress
& BIT0
) != 0) {
1250 // Read a byte if StartAddress is byte aligned
1252 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1253 StartAddress
+= sizeof (UINT8
);
1254 Size
-= sizeof (UINT8
);
1255 Buffer
= (UINT8
*)Buffer
+ 1;
1258 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1260 // Read a word if StartAddress is word aligned
1262 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1263 StartAddress
+= sizeof (UINT16
);
1264 Size
-= sizeof (UINT16
);
1265 Buffer
= (UINT16
*)Buffer
+ 1;
1268 while (Size
>= sizeof (UINT32
)) {
1270 // Read as many double words as possible
1272 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1273 StartAddress
+= sizeof (UINT32
);
1274 Size
-= sizeof (UINT32
);
1275 Buffer
= (UINT32
*)Buffer
+ 1;
1278 if (Size
>= sizeof (UINT16
)) {
1280 // Read the last remaining word if exist
1282 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1283 StartAddress
+= sizeof (UINT16
);
1284 Size
-= sizeof (UINT16
);
1285 Buffer
= (UINT16
*)Buffer
+ 1;
1288 if (Size
>= sizeof (UINT8
)) {
1290 // Read the last remaining byte if exist
1292 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1300 Copies the data in a caller supplied buffer to a specified range of PCI
1301 configuration space.
1303 Writes the range of PCI configuration registers specified by StartAddress and
1304 Size from the buffer specified by Buffer. This function only allows the PCI
1305 configuration registers from a single PCI function to be written. Size is
1306 returned. When possible 32-bit PCI configuration write cycles are used to
1307 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1308 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1309 and the end of the range.
1311 If any reserved bits in StartAddress are set, then ASSERT().
1312 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1313 If Size > 0 and Buffer is NULL, then ASSERT().
1315 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1316 Function and Register.
1317 @param Size Size in bytes of the transfer.
1318 @param Buffer Pointer to a buffer containing the data to write.
1320 @return The parameter of Size.
1325 PciSegmentWriteBuffer (
1326 IN UINT64 StartAddress
,
1333 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1334 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1340 ASSERT (Buffer
!= NULL
);
1343 // Save Size for return
1347 if ((StartAddress
& BIT0
) != 0) {
1349 // Write a byte if StartAddress is byte aligned
1351 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1352 StartAddress
+= sizeof (UINT8
);
1353 Size
-= sizeof (UINT8
);
1354 Buffer
= (UINT8
*)Buffer
+ 1;
1357 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1359 // Write a word if StartAddress is word aligned
1361 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1362 StartAddress
+= sizeof (UINT16
);
1363 Size
-= sizeof (UINT16
);
1364 Buffer
= (UINT16
*)Buffer
+ 1;
1367 while (Size
>= sizeof (UINT32
)) {
1369 // Write as many double words as possible
1371 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1372 StartAddress
+= sizeof (UINT32
);
1373 Size
-= sizeof (UINT32
);
1374 Buffer
= (UINT32
*)Buffer
+ 1;
1377 if (Size
>= sizeof (UINT16
)) {
1379 // Write the last remaining word if exist
1381 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1382 StartAddress
+= sizeof (UINT16
);
1383 Size
-= sizeof (UINT16
);
1384 Buffer
= (UINT16
*)Buffer
+ 1;
1387 if (Size
>= sizeof (UINT8
)) {
1389 // Write the last remaining byte if exist
1391 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);