2 DXE PCI Segment Library instance layered on top of ESAL services.
4 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Protocol/ExtendedSalServiceClasses.h>
19 #include <Library/PciSegmentLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/ExtendedSalLib.h>
25 Assert the validity of a PCI Segment address.
26 A valid PCI Segment address should not contain 1's in bits 31:28
28 @param A The address to validate.
29 @param M Additional bits to assert to be zero.
32 #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
33 ASSERT (((A) & (0xf0000000 | (M))) == 0)
36 Converts a PCI Library Address to a ESAL PCI Service Address.
37 Based on SAL Spec 3.2, there are two SAL PCI Address:
40 Bits 0..7 - Register address
41 Bits 8..10 - Function number
42 Bits 11..15 - Device number
43 Bits 16..23 - Bus number
44 Bits 24..31 - PCI segment group
45 Bits 32..63 - Reserved (0)
48 Bits 0..7 - Register address
49 Bits 8..11 - Extended Register address
50 Bits 12..14 - Function number
51 Bits 15..19 - Device number
52 Bits 20..27 - Bus number
53 Bits 28..43 - PCI segment group
54 Bits 44..63 - Reserved (0)
56 @param A The PCI Library Address to convert.
59 #define CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0(Address) (((Address >> 8) & 0xff000000) | (((Address) >> 4) & 0x00ffff00) | ((Address) & 0xff))
60 #define CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1(Address) (((Address >> 4) & 0xffff0000000) | ((Address) & 0xfffffff))
63 Check a PCI Library Address is a PCI Compatible Address or not.
65 #define IS_PCI_COMPATIBLE_ADDRESS(Address) (((Address) & 0xf00) == 0)
68 Internal worker function to read a PCI configuration register.
70 This function wraps EsalPciConfigRead function of Extended SAL PCI
72 It reads and returns the PCI configuration register specified by Address,
73 the width of data is specified by Width.
75 @param Address Address that encodes the PCI Bus, Device, Function and
77 @param Width Width of data to read
79 @return The value read from the PCI configuration register.
83 DxePciSegmentLibEsalReadWorker (
88 SAL_RETURN_REGS Return
;
90 if (IS_PCI_COMPATIBLE_ADDRESS(Address
)) {
92 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO
,
93 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI
,
94 SalPciConfigReadFunctionId
,
95 CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address
),
97 EFI_SAL_PCI_COMPATIBLE_ADDRESS
,
105 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO
,
106 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI
,
107 SalPciConfigReadFunctionId
,
108 CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address
),
110 EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS
,
118 return (UINT32
) Return
.r9
;
122 Internal worker function to writes a PCI configuration register.
124 This function wraps EsalPciConfigWrite function of Extended SAL PCI
126 It writes the PCI configuration register specified by Address with the
127 value specified by Data. The width of data is specifed by Width.
130 @param Address Address that encodes the PCI Bus, Device, Function and
132 @param Width Width of data to write
133 @param Data The value to write.
135 @return The value written to the PCI configuration register.
139 DxePciSegmentLibEsalWriteWorker (
145 if (IS_PCI_COMPATIBLE_ADDRESS(Address
)) {
147 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO
,
148 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI
,
149 SalPciConfigWriteFunctionId
,
150 CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address
),
153 EFI_SAL_PCI_COMPATIBLE_ADDRESS
,
160 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO
,
161 EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI
,
162 SalPciConfigWriteFunctionId
,
163 CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address
),
166 EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS
,
177 Reads an 8-bit PCI configuration register.
179 Reads and returns the 8-bit PCI configuration register specified by Address.
180 This function must guarantee that all PCI read and write operations are
183 If any reserved bits in Address are set, then ASSERT().
185 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
188 @return The value read from the PCI configuration register.
197 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
199 return (UINT8
) DxePciSegmentLibEsalReadWorker (Address
, 1);
203 Writes an 8-bit PCI configuration register.
205 Writes the 8-bit PCI configuration register specified by Address with the
206 value specified by Value. Value is returned. This function must guarantee
207 that all PCI read and write operations are serialized.
209 If any reserved bits in Address are set, then ASSERT().
211 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
213 @param Data The value to write.
215 @return The value written to the PCI configuration register.
225 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
227 return (UINT8
) DxePciSegmentLibEsalWriteWorker (Address
, 1, Data
);
231 Performs a bitwise OR of an 8-bit PCI configuration register with
234 Reads the 8-bit PCI configuration register specified by Address, performs a
235 bitwise OR between the read result and the value specified by
236 OrData, and writes the result to the 8-bit PCI configuration register
237 specified by Address. The value written to the PCI configuration register is
238 returned. This function must guarantee that all PCI read and write operations
241 If any reserved bits in Address are set, then ASSERT().
243 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
245 @param OrData The value to OR with the PCI configuration register.
247 @return The value written back to the PCI configuration register.
257 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
261 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
264 Reads the 8-bit PCI configuration register specified by Address, performs a
265 bitwise AND between the read result and the value specified by AndData, and
266 writes the result to the 8-bit PCI configuration register specified by
267 Address. The value written to the PCI configuration register is returned.
268 This function must guarantee that all PCI read and write operations are
271 If any reserved bits in Address are set, then ASSERT().
273 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
275 @param AndData The value to AND with the PCI configuration register.
277 @return The value written back to the PCI configuration register.
287 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
291 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
292 value, followed a bitwise OR with another 8-bit value.
294 Reads the 8-bit PCI configuration register specified by Address, performs a
295 bitwise AND between the read result and the value specified by AndData,
296 performs a bitwise OR between the result of the AND operation and
297 the value specified by OrData, and writes the result to the 8-bit PCI
298 configuration register specified by Address. The value written to the PCI
299 configuration register is returned. This function must guarantee that all PCI
300 read and write operations are serialized.
302 If any reserved bits in Address are set, then ASSERT().
304 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
306 @param AndData The value to AND with the PCI configuration register.
307 @param OrData The value to OR with the result of the AND operation.
309 @return The value written back to the PCI configuration register.
314 PciSegmentAndThenOr8 (
320 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
324 Reads a bit field of a PCI configuration register.
326 Reads the bit field in an 8-bit PCI configuration register. The bit field is
327 specified by the StartBit and the EndBit. The value of the bit field is
330 If any reserved bits in Address are set, then ASSERT().
331 If StartBit is greater than 7, then ASSERT().
332 If EndBit is greater than 7, then ASSERT().
333 If EndBit is less than StartBit, then ASSERT().
335 @param Address PCI configuration register to read.
336 @param StartBit The ordinal of the least significant bit in the bit field.
338 @param EndBit The ordinal of the most significant bit in the bit field.
341 @return The value of the bit field read from the PCI configuration register.
346 PciSegmentBitFieldRead8 (
352 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
356 Writes a bit field to a PCI configuration register.
358 Writes Value to the bit field of the PCI configuration register. The bit
359 field is specified by the StartBit and the EndBit. All other bits in the
360 destination PCI configuration register are preserved. The new value of the
361 8-bit register is returned.
363 If any reserved bits in Address are set, then ASSERT().
364 If StartBit is greater than 7, then ASSERT().
365 If EndBit is greater than 7, then ASSERT().
366 If EndBit is less than StartBit, then ASSERT().
367 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
369 @param Address PCI configuration register to write.
370 @param StartBit The ordinal of the least significant bit in the bit field.
372 @param EndBit The ordinal of the most significant bit in the bit field.
374 @param Value New value of the bit field.
376 @return The value written back to the PCI configuration register.
381 PciSegmentBitFieldWrite8 (
388 return PciSegmentWrite8 (
390 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
395 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
396 writes the result back to the bit field in the 8-bit port.
398 Reads the 8-bit PCI configuration register specified by Address, performs a
399 bitwise OR between the read result and the value specified by
400 OrData, and writes the result to the 8-bit PCI configuration register
401 specified by Address. The value written to the PCI configuration register is
402 returned. This function must guarantee that all PCI read and write operations
403 are serialized. Extra left bits in OrData are stripped.
405 If any reserved bits in Address are set, then ASSERT().
406 If StartBit is greater than 7, then ASSERT().
407 If EndBit is greater than 7, then ASSERT().
408 If EndBit is less than StartBit, then ASSERT().
409 If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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().
451 If AndData is larger than the bitmask value range specified by StartBit and EndBit, 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().
495 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
496 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
498 @param Address PCI configuration register to write.
499 @param StartBit The ordinal of the least significant bit in the bit field.
501 @param EndBit The ordinal of the most significant bit in the bit field.
503 @param AndData The value to AND with the PCI configuration register.
504 @param OrData The value to OR with the result of the AND operation.
506 @return The value written back to the PCI configuration register.
511 PciSegmentBitFieldAndThenOr8 (
519 return PciSegmentWrite8 (
521 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
526 Reads a 16-bit PCI configuration register.
528 Reads and returns the 16-bit PCI configuration register specified by Address.
529 This function must guarantee that all PCI read and write operations are
532 If any reserved bits in Address are set, then ASSERT().
534 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
537 @return The value read from the PCI configuration register.
546 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
548 return (UINT16
) DxePciSegmentLibEsalReadWorker (Address
, 2);
552 Writes a 16-bit PCI configuration register.
554 Writes the 16-bit PCI configuration register specified by Address with the
555 value specified by Value. Value is returned. This function must guarantee
556 that all PCI read and write operations are serialized.
558 If any reserved bits in Address are set, then ASSERT().
560 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
562 @param Data The value to write.
564 @return The value written to the PCI configuration register.
574 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
576 return (UINT16
) DxePciSegmentLibEsalWriteWorker (Address
, 2, Data
);
580 Performs a bitwise OR of a 16-bit PCI configuration register with
583 Reads the 16-bit PCI configuration register specified by Address, performs a
584 bitwise OR between the read result and the value specified by
585 OrData, and writes the result to the 16-bit PCI configuration register
586 specified by Address. The value written to the PCI configuration register is
587 returned. This function must guarantee that all PCI read and write operations
590 If any reserved bits in Address are set, then ASSERT().
592 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
594 @param OrData The value to OR with the PCI configuration register.
596 @return The value written back to the PCI configuration register.
606 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
610 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
613 Reads the 16-bit PCI configuration register specified by Address, performs a
614 bitwise AND between the read result and the value specified by AndData, and
615 writes the result to the 16-bit PCI configuration register specified by
616 Address. The value written to the PCI configuration register is returned.
617 This function must guarantee that all PCI read and write operations are
620 If any reserved bits in Address are set, then ASSERT().
622 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
624 @param AndData The value to AND with the PCI configuration register.
626 @return The value written back to the PCI configuration register.
636 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
640 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
641 value, followed a bitwise OR with another 16-bit value.
643 Reads the 16-bit PCI configuration register specified by Address, performs a
644 bitwise AND between the read result and the value specified by AndData,
645 performs a bitwise OR between the result of the AND operation and
646 the value specified by OrData, and writes the result to the 16-bit PCI
647 configuration register specified by Address. The value written to the PCI
648 configuration register is returned. This function must guarantee that all PCI
649 read and write operations are serialized.
651 If any reserved bits in Address are set, then ASSERT().
653 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
655 @param AndData The value to AND with the PCI configuration register.
656 @param OrData The value to OR with the result of the AND operation.
658 @return The value written back to the PCI configuration register.
663 PciSegmentAndThenOr16 (
669 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
673 Reads a bit field of a PCI configuration register.
675 Reads the bit field in a 16-bit PCI configuration register. The bit field is
676 specified by the StartBit and the EndBit. The value of the bit field is
679 If any reserved bits in Address are set, then ASSERT().
680 If StartBit is greater than 15, then ASSERT().
681 If EndBit is greater than 15, then ASSERT().
682 If EndBit is less than StartBit, then ASSERT().
684 @param Address PCI configuration register to read.
685 @param StartBit The ordinal of the least significant bit in the bit field.
687 @param EndBit The ordinal of the most significant bit in the bit field.
690 @return The value of the bit field read from the PCI configuration register.
695 PciSegmentBitFieldRead16 (
701 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
705 Writes a bit field to a PCI configuration register.
707 Writes Value to the bit field of the PCI configuration register. The bit
708 field is specified by the StartBit and the EndBit. All other bits in the
709 destination PCI configuration register are preserved. The new value of the
710 16-bit register is returned.
712 If any reserved bits in Address are set, then ASSERT().
713 If StartBit is greater than 15, then ASSERT().
714 If EndBit is greater than 15, then ASSERT().
715 If EndBit is less than StartBit, then ASSERT().
716 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
718 @param Address PCI configuration register to write.
719 @param StartBit The ordinal of the least significant bit in the bit field.
721 @param EndBit The ordinal of the most significant bit in the bit field.
723 @param Value New value of the bit field.
725 @return The value written back to the PCI configuration register.
730 PciSegmentBitFieldWrite16 (
737 return PciSegmentWrite16 (
739 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
744 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
745 writes the result back to the bit field in the 16-bit port.
747 Reads the 16-bit PCI configuration register specified by Address, performs a
748 bitwise OR between the read result and the value specified by
749 OrData, and writes the result to the 16-bit PCI configuration register
750 specified by Address. The value written to the PCI configuration register is
751 returned. This function must guarantee that all PCI read and write operations
752 are serialized. Extra left bits in OrData are stripped.
754 If any reserved bits in Address are set, then ASSERT().
755 If StartBit is greater than 15, then ASSERT().
756 If EndBit is greater than 15, then ASSERT().
757 If EndBit is less than StartBit, then ASSERT().
758 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
760 @param Address PCI configuration register to write.
761 @param StartBit The ordinal of the least significant bit in the bit field.
763 @param EndBit The ordinal of the most significant bit in the bit field.
765 @param OrData The value to OR with the PCI configuration register.
767 @return The value written back to the PCI configuration register.
772 PciSegmentBitFieldOr16 (
779 return PciSegmentWrite16 (
781 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
786 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
787 AND, and writes the result back to the bit field in the 16-bit register.
789 Reads the 16-bit PCI configuration register specified by Address, performs a
790 bitwise AND between the read result and the value specified by AndData, and
791 writes the result to the 16-bit PCI configuration register specified by
792 Address. The value written to the PCI configuration register is returned.
793 This function must guarantee that all PCI read and write operations are
794 serialized. Extra left bits in AndData are stripped.
796 If any reserved bits in Address are set, then ASSERT().
797 If StartBit is greater than 15, then ASSERT().
798 If EndBit is greater than 15, then ASSERT().
799 If EndBit is less than StartBit, then ASSERT().
800 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
802 @param Address PCI configuration register to write.
803 @param StartBit The ordinal of the least significant bit in the bit field.
805 @param EndBit The ordinal of the most significant bit in the bit field.
807 @param AndData The value to AND with the PCI configuration register.
809 @return The value written back to the PCI configuration register.
814 PciSegmentBitFieldAnd16 (
821 return PciSegmentWrite16 (
823 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
828 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
829 bitwise OR, and writes the result back to the bit field in the
832 Reads the 16-bit PCI configuration register specified by Address, performs a
833 bitwise AND followed by a bitwise OR between the read result and
834 the value specified by AndData, and writes the result to the 16-bit PCI
835 configuration register specified by Address. The value written to the PCI
836 configuration register is returned. This function must guarantee that all PCI
837 read and write operations are serialized. Extra left bits in both AndData and
840 If any reserved bits in Address are set, then ASSERT().
841 If StartBit is greater than 15, then ASSERT().
842 If EndBit is greater than 15, then ASSERT().
843 If EndBit is less than StartBit, then ASSERT().
844 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
845 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
847 @param Address PCI configuration register to write.
848 @param StartBit The ordinal of the least significant bit in the bit field.
850 @param EndBit The ordinal of the most significant bit in the bit field.
852 @param AndData The value to AND with the PCI configuration register.
853 @param OrData The value to OR with the result of the AND operation.
855 @return The value written back to the PCI configuration register.
860 PciSegmentBitFieldAndThenOr16 (
868 return PciSegmentWrite16 (
870 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
875 Reads a 32-bit PCI configuration register.
877 Reads and returns the 32-bit PCI configuration register specified by Address.
878 This function must guarantee that all PCI read and write operations are
881 If any reserved bits in Address are set, then ASSERT().
883 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
886 @return The value read from the PCI configuration register.
895 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
897 return DxePciSegmentLibEsalReadWorker (Address
, 4);
901 Writes a 32-bit PCI configuration register.
903 Writes the 32-bit PCI configuration register specified by Address with the
904 value specified by Value. Value is returned. This function must guarantee
905 that all PCI read and write operations are serialized.
907 If any reserved bits in Address are set, then ASSERT().
909 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
911 @param Data The value to write.
913 @return The value written to the PCI configuration register.
923 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
925 return DxePciSegmentLibEsalWriteWorker (Address
, 4, Data
);
929 Performs a bitwise OR of a 32-bit PCI configuration register with
932 Reads the 32-bit PCI configuration register specified by Address, performs a
933 bitwise OR between the read result and the value specified by
934 OrData, and writes the result to the 32-bit PCI configuration register
935 specified by Address. The value written to the PCI configuration register is
936 returned. This function must guarantee that all PCI read and write operations
939 If any reserved bits in Address are set, then ASSERT().
941 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
943 @param OrData The value to OR with the PCI configuration register.
945 @return The value written back to the PCI configuration register.
955 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
959 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
962 Reads the 32-bit PCI configuration register specified by Address, performs a
963 bitwise AND between the read result and the value specified by AndData, and
964 writes the result to the 32-bit PCI configuration register specified by
965 Address. The value written to the PCI configuration register is returned.
966 This function must guarantee that all PCI read and write operations are
969 If any reserved bits in Address are set, then ASSERT().
971 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
973 @param AndData The value to AND with the PCI configuration register.
975 @return The value written back to the PCI configuration register.
985 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
989 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
990 value, followed a bitwise OR with another 32-bit value.
992 Reads the 32-bit PCI configuration register specified by Address, performs a
993 bitwise AND between the read result and the value specified by AndData,
994 performs a bitwise OR between the result of the AND operation and
995 the value specified by OrData, and writes the result to the 32-bit PCI
996 configuration register specified by Address. The value written to the PCI
997 configuration register is returned. This function must guarantee that all PCI
998 read and write operations are serialized.
1000 If any reserved bits in Address are set, then ASSERT().
1002 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
1004 @param AndData The value to AND with the PCI configuration register.
1005 @param OrData The value to OR with the result of the AND operation.
1007 @return The value written back to the PCI configuration register.
1012 PciSegmentAndThenOr32 (
1018 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
1022 Reads a bit field of a PCI configuration register.
1024 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1025 specified by the StartBit and the EndBit. The value of the bit field is
1028 If any reserved bits in Address are set, then ASSERT().
1029 If StartBit is greater than 31, then ASSERT().
1030 If EndBit is greater than 31, then ASSERT().
1031 If EndBit is less than StartBit, then ASSERT().
1033 @param Address PCI configuration register to read.
1034 @param StartBit The ordinal of the least significant bit in the bit field.
1036 @param EndBit The ordinal of the most significant bit in the bit field.
1039 @return The value of the bit field read from the PCI configuration register.
1044 PciSegmentBitFieldRead32 (
1050 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
1054 Writes a bit field to a PCI configuration register.
1056 Writes Value to the bit field of the PCI configuration register. The bit
1057 field is specified by the StartBit and the EndBit. All other bits in the
1058 destination PCI configuration register are preserved. The new value of the
1059 32-bit register is returned.
1061 If any reserved bits in Address are set, then ASSERT().
1062 If StartBit is greater than 31, then ASSERT().
1063 If EndBit is greater than 31, then ASSERT().
1064 If EndBit is less than StartBit, then ASSERT().
1065 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1067 @param Address PCI configuration register to write.
1068 @param StartBit The ordinal of the least significant bit in the bit field.
1070 @param EndBit The ordinal of the most significant bit in the bit field.
1072 @param Value New value of the bit field.
1074 @return The value written back to the PCI configuration register.
1079 PciSegmentBitFieldWrite32 (
1086 return PciSegmentWrite32 (
1088 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
1093 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1094 writes the result back to the bit field in the 32-bit port.
1096 Reads the 32-bit PCI configuration register specified by Address, performs a
1097 bitwise OR between the read result and the value specified by
1098 OrData, and writes the result to the 32-bit PCI configuration register
1099 specified by Address. The value written to the PCI configuration register is
1100 returned. This function must guarantee that all PCI read and write operations
1101 are serialized. Extra left bits in OrData are stripped.
1103 If any reserved bits in Address are set, then ASSERT().
1104 If StartBit is greater than 31, then ASSERT().
1105 If EndBit is greater than 31, then ASSERT().
1106 If EndBit is less than StartBit, then ASSERT().
1107 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1109 @param Address PCI configuration register to write.
1110 @param StartBit The ordinal of the least significant bit in the bit field.
1112 @param EndBit The ordinal of the most significant bit in the bit field.
1114 @param OrData The value to OR with the PCI configuration register.
1116 @return The value written back to the PCI configuration register.
1121 PciSegmentBitFieldOr32 (
1128 return PciSegmentWrite32 (
1130 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1135 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1136 AND, and writes the result back to the bit field in the 32-bit register.
1138 Reads the 32-bit PCI configuration register specified by Address, performs a
1139 bitwise AND between the read result and the value specified by AndData, and
1140 writes the result to the 32-bit PCI configuration register specified by
1141 Address. The value written to the PCI configuration register is returned.
1142 This function must guarantee that all PCI read and write operations are
1143 serialized. Extra left bits in AndData are stripped.
1145 If any reserved bits in Address are set, then ASSERT().
1146 If StartBit is greater than 31, then ASSERT().
1147 If EndBit is greater than 31, then ASSERT().
1148 If EndBit is less than StartBit, then ASSERT().
1149 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1151 @param Address PCI configuration register to write.
1152 @param StartBit The ordinal of the least significant bit in the bit field.
1154 @param EndBit The ordinal of the most significant bit in the bit field.
1156 @param AndData The value to AND with the PCI configuration register.
1158 @return The value written back to the PCI configuration register.
1163 PciSegmentBitFieldAnd32 (
1170 return PciSegmentWrite32 (
1172 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1177 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1178 bitwise OR, and writes the result back to the bit field in the
1181 Reads the 32-bit PCI configuration register specified by Address, performs a
1182 bitwise AND followed by a bitwise OR between the read result and
1183 the value specified by AndData, and writes the result to the 32-bit PCI
1184 configuration register specified by Address. The value written to the PCI
1185 configuration register is returned. This function must guarantee that all PCI
1186 read and write operations are serialized. Extra left bits in both AndData and
1187 OrData are stripped.
1189 If any reserved bits in Address are set, then ASSERT().
1190 If StartBit is greater than 31, then ASSERT().
1191 If EndBit is greater than 31, then ASSERT().
1192 If EndBit is less than StartBit, then ASSERT().
1193 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1194 If OrData is larger than the bitmask value range specified by StartBit and EndBit, 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
& 1) != 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
& 2) != 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
& 1) != 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
& 2) != 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
);