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 ((((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 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 serialized.
197 If any reserved bits in Address are set, then ASSERT().
199 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
201 @return The 8-bit PCI configuration register specified by Address.
210 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
212 return (UINT8
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint8
);
216 Writes an 8-bit PCI configuration register.
218 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
219 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
221 If Address > 0x0FFFFFFF, then ASSERT().
223 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
224 @param Value The value to write.
226 @return The value written to the PCI configuration register.
236 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
238 return (UINT8
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint8
, Value
);
242 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
244 Reads the 8-bit PCI configuration register specified by Address,
245 performs a bitwise OR between the read result and the value specified by OrData,
246 and writes the result to the 8-bit PCI configuration register specified by Address.
247 The value written to the PCI configuration register is returned.
248 This function must guarantee that all PCI read and write operations are serialized.
250 If any reserved bits in Address are set, then ASSERT().
252 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
253 @param OrData The value to OR with the PCI configuration register.
255 @return The value written to the PCI configuration register.
265 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
269 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
271 Reads the 8-bit PCI configuration register specified by Address,
272 performs a bitwise AND between the read result and the value specified by AndData,
273 and writes the result to the 8-bit PCI configuration register specified by Address.
274 The value written to the PCI configuration register is returned.
275 This function must guarantee that all PCI read and write operations are serialized.
276 If any reserved bits in Address are set, then ASSERT().
278 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
279 @param AndData The value to AND with the PCI configuration register.
281 @return The value written to the PCI configuration register.
291 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
295 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
296 followed a bitwise OR with another 8-bit value.
298 Reads the 8-bit PCI configuration register specified by Address,
299 performs a bitwise AND between the read result and the value specified by AndData,
300 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
301 and writes the result to the 8-bit PCI configuration register specified by Address.
302 The value written to the PCI configuration register is returned.
303 This function must guarantee that all PCI read and write operations are serialized.
305 If any reserved bits in Address are set, then ASSERT().
307 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
308 @param AndData The value to AND with the PCI configuration register.
309 @param OrData The value to OR with the PCI configuration register.
311 @return The value written to the PCI configuration register.
316 PciSegmentAndThenOr8 (
322 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
326 Reads a bit field of a PCI configuration register.
328 Reads the bit field in an 8-bit PCI configuration register. The bit field is
329 specified by the StartBit and the EndBit. The value of the bit field is
332 If any reserved bits in Address are set, then ASSERT().
333 If StartBit is greater than 7, then ASSERT().
334 If EndBit is greater than 7, then ASSERT().
335 If EndBit is less than StartBit, then ASSERT().
337 @param Address PCI configuration register to read.
338 @param StartBit The ordinal of the least significant bit in the bit field.
340 @param EndBit The ordinal of the most significant bit in the bit field.
343 @return The value of the bit field read from the PCI configuration register.
348 PciSegmentBitFieldRead8 (
354 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
358 Writes a bit field to a PCI configuration register.
360 Writes Value to the bit field of the PCI configuration register. The bit
361 field is specified by the StartBit and the EndBit. All other bits in the
362 destination PCI configuration register are preserved. The new value of the
363 8-bit register is returned.
365 If any reserved bits in Address are set, then ASSERT().
366 If StartBit is greater than 7, then ASSERT().
367 If EndBit is greater than 7, then ASSERT().
368 If EndBit is less than StartBit, then ASSERT().
370 @param Address PCI configuration register to write.
371 @param StartBit The ordinal of the least significant bit in the bit field.
373 @param EndBit The ordinal of the most significant bit in the bit field.
375 @param Value New value of the bit field.
377 @return The value written back to the PCI configuration register.
382 PciSegmentBitFieldWrite8 (
389 return PciSegmentWrite8 (
391 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
396 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
397 writes the result back to the bit field in the 8-bit port.
399 Reads the 8-bit PCI configuration register specified by Address, performs a
400 bitwise OR between the read result and the value specified by
401 OrData, and writes the result to the 8-bit PCI configuration register
402 specified by Address. The value written to the PCI configuration register is
403 returned. This function must guarantee that all PCI read and write operations
404 are serialized. Extra left bits in OrData are stripped.
406 If any reserved bits in Address are set, then ASSERT().
407 If StartBit is greater than 7, then ASSERT().
408 If EndBit is greater than 7, then ASSERT().
409 If EndBit is less than StartBit, then ASSERT().
411 @param Address PCI configuration register to write.
412 @param StartBit The ordinal of the least significant bit in the bit field.
414 @param EndBit The ordinal of the most significant bit in the bit field.
416 @param OrData The value to OR with the PCI configuration register.
418 @return The value written back to the PCI configuration register.
423 PciSegmentBitFieldOr8 (
430 return PciSegmentWrite8 (
432 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
437 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
438 AND, and writes the result back to the bit field in the 8-bit register.
440 Reads the 8-bit PCI configuration register specified by Address, performs a
441 bitwise AND between the read result and the value specified by AndData, and
442 writes the result to the 8-bit PCI configuration register specified by
443 Address. The value written to the PCI configuration register is returned.
444 This function must guarantee that all PCI read and write operations are
445 serialized. Extra left bits in AndData are stripped.
447 If any reserved bits in Address are set, then ASSERT().
448 If StartBit is greater than 7, then ASSERT().
449 If EndBit is greater than 7, then ASSERT().
450 If EndBit is less than StartBit, then ASSERT().
452 @param Address PCI configuration register to write.
453 @param StartBit The ordinal of the least significant bit in the bit field.
455 @param EndBit The ordinal of the most significant bit in the bit field.
457 @param AndData The value to AND with the PCI configuration register.
459 @return The value written back to the PCI configuration register.
464 PciSegmentBitFieldAnd8 (
471 return PciSegmentWrite8 (
473 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
478 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
479 bitwise OR, and writes the result back to the bit field in the
482 Reads the 8-bit PCI configuration register specified by Address, performs a
483 bitwise AND followed by a bitwise OR between the read result and
484 the value specified by AndData, and writes the result to the 8-bit PCI
485 configuration register specified by Address. The value written to the PCI
486 configuration register is returned. This function must guarantee that all PCI
487 read and write operations are serialized. Extra left bits in both AndData and
490 If any reserved bits in Address are set, then ASSERT().
491 If StartBit is greater than 7, then ASSERT().
492 If EndBit is greater than 7, then ASSERT().
493 If EndBit is less than StartBit, then ASSERT().
495 @param Address PCI configuration register to write.
496 @param StartBit The ordinal of the least significant bit in the bit field.
498 @param EndBit The ordinal of the most significant bit in the bit field.
500 @param AndData The value to AND with the PCI configuration register.
501 @param OrData The value to OR with the result of the AND operation.
503 @return The value written back to the PCI configuration register.
508 PciSegmentBitFieldAndThenOr8 (
516 return PciSegmentWrite8 (
518 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
523 Reads a 16-bit PCI configuration register.
525 Reads and returns the 16-bit PCI configuration register specified by Address.
526 This function must guarantee that all PCI read and write operations are serialized.
528 If any reserved bits in Address are set, then ASSERT().
529 If Address is not aligned on a 16-bit boundary, then ASSERT().
531 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
533 @return The 16-bit PCI configuration register specified by Address.
542 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
544 return (UINT16
) PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint16
);
548 Writes a 16-bit PCI configuration register.
550 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
551 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
553 If any reserved bits in Address are set, then ASSERT().
554 If Address is not aligned on a 16-bit boundary, then ASSERT().
556 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
557 @param Value The value to write.
559 @return The parameter of Value.
569 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
571 return (UINT16
) PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint16
, Value
);
575 Performs a bitwise OR of a 16-bit PCI configuration register with
578 Reads the 16-bit PCI configuration register specified by Address, performs a
579 bitwise OR between the read result and the value specified by
580 OrData, and writes the result to the 16-bit PCI configuration register
581 specified by Address. The value written to the PCI configuration register is
582 returned. This function must guarantee that all PCI read and write operations
585 If any reserved bits in Address are set, then ASSERT().
586 If Address is not aligned on a 16-bit boundary, then ASSERT().
588 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
590 @param OrData The value to OR with the PCI configuration register.
592 @return The value written back to the PCI configuration register.
602 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
606 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
608 Reads the 16-bit PCI configuration register specified by Address,
609 performs a bitwise AND between the read result and the value specified by AndData,
610 and writes the result to the 16-bit PCI configuration register specified by Address.
611 The value written to the PCI configuration register is returned.
612 This function must guarantee that all PCI read and write operations are serialized.
614 If any reserved bits in Address are set, then ASSERT().
615 If Address is not aligned on a 16-bit boundary, then ASSERT().
617 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
618 @param AndData The value to AND with the PCI configuration register.
620 @return The value written to the PCI configuration register.
630 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
634 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
635 followed a bitwise OR with another 16-bit value.
637 Reads the 16-bit PCI configuration register specified by Address,
638 performs a bitwise AND between the read result and the value specified by AndData,
639 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
640 and writes the result to the 16-bit PCI configuration register specified by Address.
641 The value written to the PCI configuration register is returned.
642 This function must guarantee that all PCI read and write operations are serialized.
644 If any reserved bits in Address are set, then ASSERT().
645 If Address is not aligned on a 16-bit boundary, then ASSERT().
647 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
648 @param AndData The value to AND with the PCI configuration register.
649 @param OrData The value to OR with the PCI configuration register.
651 @return The value written to the PCI configuration register.
656 PciSegmentAndThenOr16 (
662 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
666 Reads a bit field of a PCI configuration register.
668 Reads the bit field in a 16-bit PCI configuration register. The bit field is
669 specified by the StartBit and the EndBit. The value of the bit field is
672 If any reserved bits in Address are set, then ASSERT().
673 If Address is not aligned on a 16-bit boundary, then ASSERT().
674 If StartBit is greater than 15, then ASSERT().
675 If EndBit is greater than 15, then ASSERT().
676 If EndBit is less than StartBit, then ASSERT().
678 @param Address PCI configuration register to read.
679 @param StartBit The ordinal of the least significant bit in the bit field.
681 @param EndBit The ordinal of the most significant bit in the bit field.
684 @return The value of the bit field read from the PCI configuration register.
689 PciSegmentBitFieldRead16 (
695 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
699 Writes a bit field to a PCI configuration register.
701 Writes Value to the bit field of the PCI configuration register. The bit
702 field is specified by the StartBit and the EndBit. All other bits in the
703 destination PCI configuration register are preserved. The new value of the
704 16-bit register is returned.
706 If any reserved bits in Address are set, then ASSERT().
707 If Address is not aligned on a 16-bit boundary, then ASSERT().
708 If StartBit is greater than 15, then ASSERT().
709 If EndBit is greater than 15, then ASSERT().
710 If EndBit is less than StartBit, then ASSERT().
712 @param Address PCI configuration register to write.
713 @param StartBit The ordinal of the least significant bit in the bit field.
715 @param EndBit The ordinal of the most significant bit in the bit field.
717 @param Value New value of the bit field.
719 @return The value written back to the PCI configuration register.
724 PciSegmentBitFieldWrite16 (
731 return PciSegmentWrite16 (
733 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
738 Reads the 16-bit PCI configuration register specified by Address,
739 performs a bitwise OR between the read result and the value specified by OrData,
740 and writes the result to the 16-bit PCI configuration register specified by Address.
742 If any reserved bits in Address are set, then ASSERT().
743 If Address is not aligned on a 16-bit boundary, then ASSERT().
744 If StartBit is greater than 15, then ASSERT().
745 If EndBit is greater than 15, then ASSERT().
746 If EndBit is less than StartBit, then ASSERT().
748 @param Address PCI configuration register to write.
749 @param StartBit The ordinal of the least significant bit in the bit field.
751 @param EndBit The ordinal of the most significant bit in the bit field.
753 @param OrData The value to OR with the PCI configuration register.
755 @return The value written back to the PCI configuration register.
760 PciSegmentBitFieldOr16 (
767 return PciSegmentWrite16 (
769 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
774 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
775 and writes the result back to the bit field in the 16-bit port.
777 Reads the 16-bit PCI configuration register specified by Address,
778 performs a bitwise OR between the read result and the value specified by OrData,
779 and writes the result to the 16-bit PCI configuration register specified by Address.
780 The value written to the PCI configuration register is returned.
781 This function must guarantee that all PCI read and write operations are serialized.
782 Extra left bits in OrData are stripped.
784 If any reserved bits in Address are set, then ASSERT().
785 If Address is not aligned on a 16-bit boundary, then ASSERT().
786 If StartBit is greater than 7, then ASSERT().
787 If EndBit is greater than 7, then ASSERT().
788 If EndBit is less than StartBit, then ASSERT().
790 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
791 @param StartBit The ordinal of the least significant bit in the bit field.
792 The ordinal of the least significant bit in a byte is bit 0.
793 @param EndBit The ordinal of the most significant bit in the bit field.
794 The ordinal of the most significant bit in a byte is bit 7.
795 @param AndData The value to AND with the read value from the PCI configuration register.
797 @return The value written to the PCI configuration register.
802 PciSegmentBitFieldAnd16 (
809 return PciSegmentWrite16 (
811 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
816 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
817 bitwise OR, and writes the result back to the bit field in the
820 Reads the 16-bit PCI configuration register specified by Address, performs a
821 bitwise AND followed by a bitwise OR between the read result and
822 the value specified by AndData, and writes the result to the 16-bit PCI
823 configuration register specified by Address. The value written to the PCI
824 configuration register is returned. This function must guarantee that all PCI
825 read and write operations are serialized. Extra left bits in both AndData and
828 If any reserved bits in Address are set, then ASSERT().
829 If StartBit is greater than 15, then ASSERT().
830 If EndBit is greater than 15, then ASSERT().
831 If EndBit is less than StartBit, then ASSERT().
833 @param Address PCI configuration register to write.
834 @param StartBit The ordinal of the least significant bit in the bit field.
836 @param EndBit The ordinal of the most significant bit in the bit field.
838 @param AndData The value to AND with the PCI configuration register.
839 @param OrData The value to OR with the result of the AND operation.
841 @return The value written back to the PCI configuration register.
846 PciSegmentBitFieldAndThenOr16 (
854 return PciSegmentWrite16 (
856 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
861 Reads a 32-bit PCI configuration register.
863 Reads and returns the 32-bit PCI configuration register specified by Address.
864 This function must guarantee that all PCI read and write operations are serialized.
866 If any reserved bits in Address are set, then ASSERT().
867 If Address is not aligned on a 32-bit boundary, then ASSERT().
869 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
871 @return The 32-bit PCI configuration register specified by Address.
880 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
882 return PeiPciSegmentLibPciCfg2ReadWorker (Address
, EfiPeiPciCfgWidthUint32
);
886 Writes a 32-bit PCI configuration register.
888 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
889 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
891 If any reserved bits in Address are set, then ASSERT().
892 If Address is not aligned on a 32-bit boundary, then ASSERT().
894 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
895 @param Value The value to write.
897 @return The parameter of Value.
907 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
909 return PeiPciSegmentLibPciCfg2WriteWorker (Address
, EfiPeiPciCfgWidthUint32
, Value
);
913 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
915 Reads the 32-bit PCI configuration register specified by Address,
916 performs a bitwise OR between the read result and the value specified by OrData,
917 and writes the result to the 32-bit PCI configuration register specified by Address.
918 The value written to the PCI configuration register is returned.
919 This function must guarantee that all PCI read and write operations are serialized.
921 If any reserved bits in Address are set, then ASSERT().
922 If Address is not aligned on a 32-bit boundary, then ASSERT().
924 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
925 @param OrData The value to OR with the PCI configuration register.
927 @return The value written to the PCI configuration register.
937 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
941 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
943 Reads the 32-bit PCI configuration register specified by Address,
944 performs a bitwise AND between the read result and the value specified by AndData,
945 and writes the result to the 32-bit PCI configuration register specified by Address.
946 The value written to the PCI configuration register is returned.
947 This function must guarantee that all PCI read and write operations are serialized.
949 If any reserved bits in Address are set, then ASSERT().
950 If Address is not aligned on a 32-bit boundary, then ASSERT().
952 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
953 @param AndData The value to AND with the PCI configuration register.
955 @return The value written to the PCI configuration register.
965 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
969 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
970 followed a bitwise OR with another 32-bit value.
972 Reads the 32-bit PCI configuration register specified by Address,
973 performs a bitwise AND between the read result and the value specified by AndData,
974 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
975 and writes the result to the 32-bit PCI configuration register specified by Address.
976 The value written to the PCI configuration register is returned.
977 This function must guarantee that all PCI read and write operations are serialized.
979 If any reserved bits in Address are set, then ASSERT().
980 If Address is not aligned on a 32-bit boundary, then ASSERT().
982 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
983 @param AndData The value to AND with the PCI configuration register.
984 @param OrData The value to OR with the PCI configuration register.
986 @return The value written to the PCI configuration register.
991 PciSegmentAndThenOr32 (
997 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1001 Reads a bit field of a PCI configuration register.
1003 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1004 specified by the StartBit and the EndBit. The value of the bit field is
1007 If any reserved bits in Address are set, then ASSERT().
1008 If Address is not aligned on a 32-bit boundary, then ASSERT().
1009 If StartBit is greater than 31, then ASSERT().
1010 If EndBit is greater than 31, then ASSERT().
1011 If EndBit is less than StartBit, then ASSERT().
1013 @param Address PCI configuration register to read.
1014 @param StartBit The ordinal of the least significant bit in the bit field.
1016 @param EndBit The ordinal of the most significant bit in the bit field.
1019 @return The value of the bit field read from the PCI configuration register.
1024 PciSegmentBitFieldRead32 (
1030 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1034 Writes a bit field to a PCI configuration register.
1036 Writes Value to the bit field of the PCI configuration register. The bit
1037 field is specified by the StartBit and the EndBit. All other bits in the
1038 destination PCI configuration register are preserved. The new value of the
1039 32-bit register is returned.
1041 If any reserved bits in Address are set, then ASSERT().
1042 If Address is not aligned on a 32-bit boundary, then ASSERT().
1043 If StartBit is greater than 31, then ASSERT().
1044 If EndBit is greater than 31, then ASSERT().
1045 If EndBit is less than StartBit, then ASSERT().
1047 @param Address PCI configuration register to write.
1048 @param StartBit The ordinal of the least significant bit in the bit field.
1050 @param EndBit The ordinal of the most significant bit in the bit field.
1052 @param Value New value of the bit field.
1054 @return The value written back to the PCI configuration register.
1059 PciSegmentBitFieldWrite32 (
1066 return PciSegmentWrite32 (
1068 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1073 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1074 writes the result back to the bit field in the 32-bit port.
1076 Reads the 32-bit PCI configuration register specified by Address, performs a
1077 bitwise OR between the read result and the value specified by
1078 OrData, and writes the result to the 32-bit PCI configuration register
1079 specified by Address. The value written to the PCI configuration register is
1080 returned. This function must guarantee that all PCI read and write operations
1081 are serialized. Extra left bits in OrData are stripped.
1083 If any reserved bits in Address are set, then ASSERT().
1084 If StartBit is greater than 31, then ASSERT().
1085 If EndBit is greater than 31, then ASSERT().
1086 If EndBit is less than StartBit, then ASSERT().
1088 @param Address PCI configuration register to write.
1089 @param StartBit The ordinal of the least significant bit in the bit field.
1091 @param EndBit The ordinal of the most significant bit in the bit field.
1093 @param OrData The value to OR with the PCI configuration register.
1095 @return The value written back to the PCI configuration register.
1100 PciSegmentBitFieldOr32 (
1107 return PciSegmentWrite32 (
1109 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1114 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1115 AND, and writes the result back to the bit field in the 32-bit register.
1118 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1119 AND between the read result and the value specified by AndData, and writes the result
1120 to the 32-bit PCI configuration register specified by Address. The value written to
1121 the PCI configuration register is returned. This function must guarantee that all PCI
1122 read and write operations are serialized. Extra left bits in AndData are stripped.
1123 If any reserved bits in Address are set, then ASSERT().
1124 If Address is not aligned on a 32-bit boundary, then ASSERT().
1125 If StartBit is greater than 31, then ASSERT().
1126 If EndBit is greater than 31, then ASSERT().
1127 If EndBit is less than StartBit, then ASSERT().
1130 @param Address PCI configuration register to write.
1131 @param StartBit The ordinal of the least significant bit in the bit field.
1133 @param EndBit The ordinal of the most significant bit in the bit field.
1135 @param AndData The value to AND with the PCI configuration register.
1137 @return The value written back to the PCI configuration register.
1142 PciSegmentBitFieldAnd32 (
1149 return PciSegmentWrite32 (
1151 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1156 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1157 bitwise OR, and writes the result back to the bit field in the
1160 Reads the 32-bit PCI configuration register specified by Address, performs a
1161 bitwise AND followed by a bitwise OR between the read result and
1162 the value specified by AndData, and writes the result to the 32-bit PCI
1163 configuration register specified by Address. The value written to the PCI
1164 configuration register is returned. This function must guarantee that all PCI
1165 read and write operations are serialized. Extra left bits in both AndData and
1166 OrData are stripped.
1168 If any reserved bits in Address are set, then ASSERT().
1169 If StartBit is greater than 31, then ASSERT().
1170 If EndBit is greater than 31, then ASSERT().
1171 If EndBit is less than StartBit, then ASSERT().
1173 @param Address PCI configuration register to write.
1174 @param StartBit The ordinal of the least significant bit in the bit field.
1176 @param EndBit The ordinal of the most significant bit in the bit field.
1178 @param AndData The value to AND with the PCI configuration register.
1179 @param OrData The value to OR with the result of the AND operation.
1181 @return The value written back to the PCI configuration register.
1186 PciSegmentBitFieldAndThenOr32 (
1194 return PciSegmentWrite32 (
1196 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1201 Reads a range of PCI configuration registers into a caller supplied buffer.
1203 Reads the range of PCI configuration registers specified by StartAddress and
1204 Size into the buffer specified by Buffer. This function only allows the PCI
1205 configuration registers from a single PCI function to be read. Size is
1206 returned. When possible 32-bit PCI configuration read cycles are used to read
1207 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1208 and 16-bit PCI configuration read cycles may be used at the beginning and the
1211 If StartAddress > 0x0FFFFFFF, then ASSERT().
1212 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1213 If Size > 0 and Buffer is NULL, then ASSERT().
1215 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1216 Function and Register.
1217 @param Size Size in bytes of the transfer.
1218 @param Buffer Pointer to a buffer receiving the data read.
1225 PciSegmentReadBuffer (
1226 IN UINT64 StartAddress
,
1233 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1234 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1240 ASSERT (Buffer
!= NULL
);
1243 // Save Size for return
1247 if ((StartAddress
& BIT0
) != 0) {
1249 // Read a byte if StartAddress is byte aligned
1251 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1252 StartAddress
+= sizeof (UINT8
);
1253 Size
-= sizeof (UINT8
);
1254 Buffer
= (UINT8
*)Buffer
+ 1;
1257 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1259 // Read a word if StartAddress is word aligned
1261 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1262 StartAddress
+= sizeof (UINT16
);
1263 Size
-= sizeof (UINT16
);
1264 Buffer
= (UINT16
*)Buffer
+ 1;
1267 while (Size
>= sizeof (UINT32
)) {
1269 // Read as many double words as possible
1271 *(volatile UINT32
*)Buffer
= PciSegmentRead32 (StartAddress
);
1272 StartAddress
+= sizeof (UINT32
);
1273 Size
-= sizeof (UINT32
);
1274 Buffer
= (UINT32
*)Buffer
+ 1;
1277 if (Size
>= sizeof (UINT16
)) {
1279 // Read the last remaining word if exist
1281 *(volatile UINT16
*)Buffer
= PciSegmentRead16 (StartAddress
);
1282 StartAddress
+= sizeof (UINT16
);
1283 Size
-= sizeof (UINT16
);
1284 Buffer
= (UINT16
*)Buffer
+ 1;
1287 if (Size
>= sizeof (UINT8
)) {
1289 // Read the last remaining byte if exist
1291 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1299 Copies the data in a caller supplied buffer to a specified range of PCI
1300 configuration space.
1302 Writes the range of PCI configuration registers specified by StartAddress and
1303 Size from the buffer specified by Buffer. This function only allows the PCI
1304 configuration registers from a single PCI function to be written. Size is
1305 returned. When possible 32-bit PCI configuration write cycles are used to
1306 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1307 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1308 and the end of the range.
1310 If StartAddress > 0x0FFFFFFF, then ASSERT().
1311 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1312 If Size > 0 and Buffer is NULL, then ASSERT().
1314 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1315 Function and Register.
1316 @param Size Size in bytes of the transfer.
1317 @param Buffer Pointer to a buffer containing the data to write.
1319 @return The parameter of Size.
1324 PciSegmentWriteBuffer (
1325 IN UINT64 StartAddress
,
1332 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1333 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1339 ASSERT (Buffer
!= NULL
);
1342 // Save Size for return
1346 if ((StartAddress
& BIT0
) != 0) {
1348 // Write a byte if StartAddress is byte aligned
1350 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1351 StartAddress
+= sizeof (UINT8
);
1352 Size
-= sizeof (UINT8
);
1353 Buffer
= (UINT8
*)Buffer
+ 1;
1356 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1358 // Write a word if StartAddress is word aligned
1360 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1361 StartAddress
+= sizeof (UINT16
);
1362 Size
-= sizeof (UINT16
);
1363 Buffer
= (UINT16
*)Buffer
+ 1;
1366 while (Size
>= sizeof (UINT32
)) {
1368 // Write as many double words as possible
1370 PciSegmentWrite32 (StartAddress
, *(UINT32
*)Buffer
);
1371 StartAddress
+= sizeof (UINT32
);
1372 Size
-= sizeof (UINT32
);
1373 Buffer
= (UINT32
*)Buffer
+ 1;
1376 if (Size
>= sizeof (UINT16
)) {
1378 // Write the last remaining word if exist
1380 PciSegmentWrite16 (StartAddress
, *(UINT16
*)Buffer
);
1381 StartAddress
+= sizeof (UINT16
);
1382 Size
-= sizeof (UINT16
);
1383 Buffer
= (UINT16
*)Buffer
+ 1;
1386 if (Size
>= sizeof (UINT8
)) {
1388 // Write the last remaining byte if exist
1390 PciSegmentWrite8 (StartAddress
, *(UINT8
*)Buffer
);