]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BasePciSegmentLibPci/PciSegmentLib.c
2 PCI Segment Library that layers on top of the PCI Library which only
3 supports segment 0 PCI configuration access.
5 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are
7 licensed and made available under the terms and conditions of
8 the BSD License which accompanies this distribution. The full
9 text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php.
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PciLib.h>
21 #include <Library/PciSegmentLib.h>
24 Assert the validity of a PCI Segment address.
25 A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
26 and the segment should be 0.
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) & (0xfffffffff0000000ULL | (M))) == 0)
36 Convert the PCI Segment library address to PCI library address.
38 @param A The address to convert.
40 #define PCI_SEGMENT_TO_PCI_ADDRESS(A) ((UINTN) (UINT32) A)
43 Register a PCI device so PCI configuration registers may be accessed after
44 SetVirtualAddressMap().
46 If any reserved bits in Address are set, then ASSERT().
48 @param Address The address that encodes the PCI Bus, Device, Function and
51 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
52 @retval RETURN_UNSUPPORTED An attempt was made to call this function
53 after ExitBootServices().
54 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
55 at runtime could not be mapped.
56 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
57 complete the registration.
62 PciSegmentRegisterForRuntimeAccess (
66 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
67 return PciRegisterForRuntimeAccess (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
71 Reads an 8-bit PCI configuration register.
73 Reads and returns the 8-bit PCI configuration register specified by Address.
74 This function must guarantee that all PCI read and write operations are serialized.
76 If any reserved bits in Address are set, then ASSERT().
78 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
80 @return The 8-bit PCI configuration register specified by Address.
89 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
91 return PciRead8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
95 Writes an 8-bit PCI configuration register.
97 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
98 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
100 If any reserved bits in Address are set, then ASSERT().
102 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
103 @param Value The value to write.
105 @return The value written to the PCI configuration register.
115 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
117 return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), Value
);
121 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
123 Reads the 8-bit PCI configuration register specified by Address,
124 performs a bitwise OR between the read result and the value specified by OrData,
125 and writes the result to the 8-bit PCI configuration register specified by Address.
126 The value written to the PCI configuration register is returned.
127 This function must guarantee that all PCI read and write operations are serialized.
129 If any reserved bits in Address are set, then ASSERT().
131 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
132 @param OrData The value to OR with the PCI configuration register.
134 @return The value written to the PCI configuration register.
144 return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
148 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
150 Reads the 8-bit PCI configuration register specified by Address,
151 performs a bitwise AND between the read result and the value specified by AndData,
152 and writes the result to the 8-bit PCI configuration register specified by Address.
153 The value written to the PCI configuration register is returned.
154 This function must guarantee that all PCI read and write operations are serialized.
155 If any reserved bits in Address are set, then ASSERT().
157 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
158 @param AndData The value to AND with the PCI configuration register.
160 @return The value written to the PCI configuration register.
170 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
174 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
175 followed a bitwise OR with another 8-bit value.
177 Reads the 8-bit PCI configuration register specified by Address,
178 performs a bitwise AND between the read result and the value specified by AndData,
179 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
180 and writes the result to the 8-bit PCI configuration register specified by Address.
181 The value written to the PCI configuration register is returned.
182 This function must guarantee that all PCI read and write operations are serialized.
184 If any reserved bits in Address are set, then ASSERT().
186 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
187 @param AndData The value to AND with the PCI configuration register.
188 @param OrData The value to OR with the PCI configuration register.
190 @return The value written to the PCI configuration register.
195 PciSegmentAndThenOr8 (
201 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
205 Reads a bit field of a PCI configuration register.
207 Reads the bit field in an 8-bit PCI configuration register. The bit field is
208 specified by the StartBit and the EndBit. The value of the bit field is
211 If any reserved bits in Address are set, then ASSERT().
212 If StartBit is greater than 7, then ASSERT().
213 If EndBit is greater than 7, then ASSERT().
214 If EndBit is less than StartBit, then ASSERT().
216 @param Address The PCI configuration register to read.
217 @param StartBit The ordinal of the least significant bit in the bit field.
219 @param EndBit The ordinal of the most significant bit in the bit field.
222 @return The value of the bit field read from the PCI configuration register.
227 PciSegmentBitFieldRead8 (
233 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
237 Writes a bit field to a PCI configuration register.
239 Writes Value to the bit field of the PCI configuration register. The bit
240 field is specified by the StartBit and the EndBit. All other bits in the
241 destination PCI configuration register are preserved. The new value of the
242 8-bit register is returned.
244 If any reserved bits in Address are set, then ASSERT().
245 If StartBit is greater than 7, then ASSERT().
246 If EndBit is greater than 7, then ASSERT().
247 If EndBit is less than StartBit, then ASSERT().
248 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
250 @param Address The PCI configuration register to write.
251 @param StartBit The ordinal of the least significant bit in the bit field.
253 @param EndBit The ordinal of the most significant bit in the bit field.
255 @param Value The new value of the bit field.
257 @return The value written back to the PCI configuration register.
262 PciSegmentBitFieldWrite8 (
269 return PciSegmentWrite8 (
271 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
276 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
277 writes the result back to the bit field in the 8-bit port.
279 Reads the 8-bit PCI configuration register specified by Address, performs a
280 bitwise OR between the read result and the value specified by
281 OrData, and writes the result to the 8-bit PCI configuration register
282 specified by Address. The value written to the PCI configuration register is
283 returned. This function must guarantee that all PCI read and write operations
284 are serialized. Extra left bits in OrData are stripped.
286 If any reserved bits in Address are set, then ASSERT().
287 If StartBit is greater than 7, then ASSERT().
288 If EndBit is greater than 7, then ASSERT().
289 If EndBit is less than StartBit, then ASSERT().
290 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
292 @param Address The PCI configuration register to write.
293 @param StartBit The ordinal of the least significant bit in the bit field.
295 @param EndBit The ordinal of the most significant bit in the bit field.
297 @param OrData The value to OR with the PCI configuration register.
299 @return The value written back to the PCI configuration register.
304 PciSegmentBitFieldOr8 (
311 return PciSegmentWrite8 (
313 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
318 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
319 AND, and writes the result back to the bit field in the 8-bit register.
321 Reads the 8-bit PCI configuration register specified by Address, performs a
322 bitwise AND between the read result and the value specified by AndData, and
323 writes the result to the 8-bit PCI configuration register specified by
324 Address. The value written to the PCI configuration register is returned.
325 This function must guarantee that all PCI read and write operations are
326 serialized. Extra left bits in AndData are stripped.
328 If any reserved bits in Address are set, then ASSERT().
329 If StartBit is greater than 7, then ASSERT().
330 If EndBit is greater than 7, then ASSERT().
331 If EndBit is less than StartBit, then ASSERT().
332 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
334 @param Address The PCI configuration register to write.
335 @param StartBit The ordinal of the least significant bit in the bit field.
337 @param EndBit The ordinal of the most significant bit in the bit field.
339 @param AndData The value to AND with the PCI configuration register.
341 @return The value written back to the PCI configuration register.
346 PciSegmentBitFieldAnd8 (
353 return PciSegmentWrite8 (
355 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
360 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
361 bitwise OR, and writes the result back to the bit field in the
364 Reads the 8-bit PCI configuration register specified by Address, performs a
365 bitwise AND followed by a bitwise OR between the read result and
366 the value specified by AndData, and writes the result to the 8-bit PCI
367 configuration register specified by Address. The value written to the PCI
368 configuration register is returned. This function must guarantee that all PCI
369 read and write operations are serialized. Extra left bits in both AndData and
372 If any reserved bits in Address are set, then ASSERT().
373 If StartBit is greater than 7, then ASSERT().
374 If EndBit is greater than 7, then ASSERT().
375 If EndBit is less than StartBit, then ASSERT().
376 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
377 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
379 @param Address The PCI configuration register to write.
380 @param StartBit The ordinal of the least significant bit in the bit field.
382 @param EndBit The ordinal of the most significant bit in the bit field.
384 @param AndData The value to AND with the PCI configuration register.
385 @param OrData The value to OR with the result of the AND operation.
387 @return The value written back to the PCI configuration register.
392 PciSegmentBitFieldAndThenOr8 (
400 return PciSegmentWrite8 (
402 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
407 Reads a 16-bit PCI configuration register.
409 Reads and returns the 16-bit PCI configuration register specified by Address.
410 This function must guarantee that all PCI read and write operations are serialized.
412 If any reserved bits in Address are set, then ASSERT().
413 If Address is not aligned on a 16-bit boundary, then ASSERT().
415 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
417 @return The 16-bit PCI configuration register specified by Address.
426 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
428 return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
432 Writes a 16-bit PCI configuration register.
434 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
435 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
437 If any reserved bits in Address are set, then ASSERT().
438 If Address is not aligned on a 16-bit boundary, then ASSERT().
440 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
441 @param Value The value to write.
443 @return The parameter of Value.
453 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
455 return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), Value
);
459 Performs a bitwise OR of a 16-bit PCI configuration register with
462 Reads the 16-bit PCI configuration register specified by Address, performs a
463 bitwise OR between the read result and the value specified by
464 OrData, and writes the result to the 16-bit PCI configuration register
465 specified by Address. The value written to the PCI configuration register is
466 returned. This function must guarantee that all PCI read and write operations
469 If any reserved bits in Address are set, then ASSERT().
470 If Address is not aligned on a 16-bit boundary, then ASSERT().
472 @param Address The address that encodes the PCI Segment, Bus, Device, Function and
474 @param OrData The value to OR with the PCI configuration register.
476 @return The value written back to the PCI configuration register.
486 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
490 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
492 Reads the 16-bit PCI configuration register specified by Address,
493 performs a bitwise AND between the read result and the value specified by AndData,
494 and writes the result to the 16-bit PCI configuration register specified by Address.
495 The value written to the PCI configuration register is returned.
496 This function must guarantee that all PCI read and write operations are serialized.
498 If any reserved bits in Address are set, then ASSERT().
499 If Address is not aligned on a 16-bit boundary, then ASSERT().
501 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
502 @param AndData The value to AND with the PCI configuration register.
504 @return The value written to the PCI configuration register.
514 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
518 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
519 followed a bitwise OR with another 16-bit value.
521 Reads the 16-bit PCI configuration register specified by Address,
522 performs a bitwise AND between the read result and the value specified by AndData,
523 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
524 and writes the result to the 16-bit PCI configuration register specified by Address.
525 The value written to the PCI configuration register is returned.
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 The address that encodes the PCI Segment, Bus, Device, Function, and Register.
532 @param AndData The value to AND with the PCI configuration register.
533 @param OrData The value to OR with the PCI configuration register.
535 @return The value written to the PCI configuration register.
540 PciSegmentAndThenOr16 (
546 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
550 Reads a bit field of a PCI configuration register.
552 Reads the bit field in a 16-bit PCI configuration register. The bit field is
553 specified by the StartBit and the EndBit. The value of the bit field is
556 If any reserved bits in Address are set, then ASSERT().
557 If Address is not aligned on a 16-bit boundary, then ASSERT().
558 If StartBit is greater than 15, then ASSERT().
559 If EndBit is greater than 15, then ASSERT().
560 If EndBit is less than StartBit, then ASSERT().
562 @param Address The PCI configuration register to read.
563 @param StartBit The ordinal of the least significant bit in the bit field.
565 @param EndBit The ordinal of the most significant bit in the bit field.
568 @return The value of the bit field read from the PCI configuration register.
573 PciSegmentBitFieldRead16 (
579 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
583 Writes a bit field to a PCI configuration register.
585 Writes Value to the bit field of the PCI configuration register. The bit
586 field is specified by the StartBit and the EndBit. All other bits in the
587 destination PCI configuration register are preserved. The new value of the
588 16-bit register is returned.
590 If any reserved bits in Address are set, then ASSERT().
591 If Address is not aligned on a 16-bit boundary, then ASSERT().
592 If StartBit is greater than 15, then ASSERT().
593 If EndBit is greater than 15, then ASSERT().
594 If EndBit is less than StartBit, then ASSERT().
595 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
597 @param Address The PCI configuration register to write.
598 @param StartBit The ordinal of the least significant bit in the bit field.
600 @param EndBit The ordinal of the most significant bit in the bit field.
602 @param Value The new value of the bit field.
604 @return The value written back to the PCI configuration register.
609 PciSegmentBitFieldWrite16 (
616 return PciSegmentWrite16 (
618 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
623 Reads the 16-bit PCI configuration register specified by Address,
624 performs a bitwise OR between the read result and the value specified by OrData,
625 and writes the result to the 16-bit PCI configuration register specified by Address.
627 If any reserved bits in Address are set, then ASSERT().
628 If Address is not aligned on a 16-bit boundary, then ASSERT().
629 If StartBit is greater than 15, then ASSERT().
630 If EndBit is greater than 15, then ASSERT().
631 If EndBit is less than StartBit, then ASSERT().
632 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
634 @param Address The PCI configuration register to write.
635 @param StartBit The ordinal of the least significant bit in the bit field.
637 @param EndBit The ordinal of the most significant bit in the bit field.
639 @param OrData The value to OR with the PCI configuration register.
641 @return The value written back to the PCI configuration register.
646 PciSegmentBitFieldOr16 (
653 return PciSegmentWrite16 (
655 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
660 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
661 and writes the result back to the bit field in the 16-bit port.
663 Reads the 16-bit PCI configuration register specified by Address,
664 performs a bitwise OR between the read result and the value specified by OrData,
665 and writes the result to the 16-bit PCI configuration register specified by Address.
666 The value written to the PCI configuration register is returned.
667 This function must guarantee that all PCI read and write operations are serialized.
668 Extra left bits in OrData are stripped.
670 If any reserved bits in Address are set, then ASSERT().
671 If Address is not aligned on a 16-bit boundary, then ASSERT().
672 If StartBit is greater than 7, then ASSERT().
673 If EndBit is greater than 7, then ASSERT().
674 If EndBit is less than StartBit, then ASSERT().
675 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
677 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
678 @param StartBit The ordinal of the least significant bit in the bit field.
679 The ordinal of the least significant bit in a byte is bit 0.
680 @param EndBit The ordinal of the most significant bit in the bit field.
681 The ordinal of the most significant bit in a byte is bit 7.
682 @param AndData The value to AND with the read value from the PCI configuration register.
684 @return The value written to the PCI configuration register.
689 PciSegmentBitFieldAnd16 (
696 return PciSegmentWrite16 (
698 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
703 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
704 bitwise OR, and writes the result back to the bit field in the
707 Reads the 16-bit PCI configuration register specified by Address, performs a
708 bitwise AND followed by a bitwise OR between the read result and
709 the value specified by AndData, and writes the result to the 16-bit PCI
710 configuration register specified by Address. The value written to the PCI
711 configuration register is returned. This function must guarantee that all PCI
712 read and write operations are serialized. Extra left bits in both AndData and
715 If any reserved bits in Address are set, then ASSERT().
716 If StartBit is greater than 15, then ASSERT().
717 If EndBit is greater than 15, then ASSERT().
718 If EndBit is less than StartBit, then ASSERT().
719 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
720 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
722 @param Address The PCI configuration register to write.
723 @param StartBit The ordinal of the least significant bit in the bit field.
725 @param EndBit The ordinal of the most significant bit in the bit field.
727 @param AndData The value to AND with the PCI configuration register.
728 @param OrData The value to OR with the result of the AND operation.
730 @return The value written back to the PCI configuration register.
735 PciSegmentBitFieldAndThenOr16 (
743 return PciSegmentWrite16 (
745 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
750 Reads a 32-bit PCI configuration register.
752 Reads and returns the 32-bit PCI configuration register specified by Address.
753 This function must guarantee that all PCI read and write operations are serialized.
755 If any reserved bits in Address are set, then ASSERT().
756 If Address is not aligned on a 32-bit boundary, then ASSERT().
758 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
760 @return The 32-bit PCI configuration register specified by Address.
769 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
771 return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
775 Writes a 32-bit PCI configuration register.
777 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
778 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
780 If any reserved bits in Address are set, then ASSERT().
781 If Address is not aligned on a 32-bit boundary, then ASSERT().
783 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
784 @param Value The value to write.
786 @return The parameter of Value.
796 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
798 return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), Value
);
802 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
804 Reads the 32-bit PCI configuration register specified by Address,
805 performs a bitwise OR between the read result and the value specified by OrData,
806 and writes the result to the 32-bit PCI configuration register specified by Address.
807 The value written to the PCI configuration register is returned.
808 This function must guarantee that all PCI read and write operations are serialized.
810 If any reserved bits in Address are set, then ASSERT().
811 If Address is not aligned on a 32-bit boundary, then ASSERT().
813 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
814 @param OrData The value to OR with the PCI configuration register.
816 @return The value written to the PCI configuration register.
826 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
830 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
832 Reads the 32-bit PCI configuration register specified by Address,
833 performs a bitwise AND between the read result and the value specified by AndData,
834 and writes the result to the 32-bit PCI configuration register specified by Address.
835 The value written to the PCI configuration register is returned.
836 This function must guarantee that all PCI read and write operations are serialized.
838 If any reserved bits in Address are set, then ASSERT().
839 If Address is not aligned on a 32-bit boundary, then ASSERT().
841 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
842 @param AndData The value to AND with the PCI configuration register.
844 @return The value written to the PCI configuration register.
854 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
858 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
859 followed a bitwise OR with another 32-bit value.
861 Reads the 32-bit PCI configuration register specified by Address,
862 performs a bitwise AND between the read result and the value specified by AndData,
863 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
864 and writes the result to the 32-bit PCI configuration register specified by Address.
865 The value written to the PCI configuration register is returned.
866 This function must guarantee that all PCI read and write operations are serialized.
868 If any reserved bits in Address are set, then ASSERT().
869 If Address is not aligned on a 32-bit boundary, then ASSERT().
871 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
872 @param AndData The value to AND with the PCI configuration register.
873 @param OrData The value to OR with the PCI configuration register.
875 @return The value written to the PCI configuration register.
880 PciSegmentAndThenOr32 (
886 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
890 Reads a bit field of a PCI configuration register.
892 Reads the bit field in a 32-bit PCI configuration register. The bit field is
893 specified by the StartBit and the EndBit. The value of the bit field is
896 If any reserved bits in Address are set, then ASSERT().
897 If Address is not aligned on a 32-bit boundary, then ASSERT().
898 If StartBit is greater than 31, then ASSERT().
899 If EndBit is greater than 31, then ASSERT().
900 If EndBit is less than StartBit, then ASSERT().
902 @param Address The PCI configuration register to read.
903 @param StartBit The ordinal of the least significant bit in the bit field.
905 @param EndBit The ordinal of the most significant bit in the bit field.
908 @return The value of the bit field read from the PCI configuration register.
913 PciSegmentBitFieldRead32 (
919 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
923 Writes a bit field to a PCI configuration register.
925 Writes Value to the bit field of the PCI configuration register. The bit
926 field is specified by the StartBit and the EndBit. All other bits in the
927 destination PCI configuration register are preserved. The new value of the
928 32-bit register is returned.
930 If any reserved bits in Address are set, then ASSERT().
931 If Address is not aligned on a 32-bit boundary, then ASSERT().
932 If StartBit is greater than 31, then ASSERT().
933 If EndBit is greater than 31, then ASSERT().
934 If EndBit is less than StartBit, then ASSERT().
935 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
937 @param Address The PCI configuration register to write.
938 @param StartBit The ordinal of the least significant bit in the bit field.
940 @param EndBit The ordinal of the most significant bit in the bit field.
942 @param Value The new value of the bit field.
944 @return The value written back to the PCI configuration register.
949 PciSegmentBitFieldWrite32 (
956 return PciSegmentWrite32 (
958 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
963 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
964 writes the result back to the bit field in the 32-bit port.
966 Reads the 32-bit PCI configuration register specified by Address, performs a
967 bitwise OR between the read result and the value specified by
968 OrData, and writes the result to the 32-bit PCI configuration register
969 specified by Address. The value written to the PCI configuration register is
970 returned. This function must guarantee that all PCI read and write operations
971 are serialized. Extra left bits in OrData are stripped.
973 If any reserved bits in Address are set, then ASSERT().
974 If StartBit is greater than 31, then ASSERT().
975 If EndBit is greater than 31, then ASSERT().
976 If EndBit is less than StartBit, then ASSERT().
977 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
979 @param Address The PCI configuration register to write.
980 @param StartBit The ordinal of the least significant bit in the bit field.
982 @param EndBit The ordinal of the most significant bit in the bit field.
984 @param OrData The value to OR with the PCI configuration register.
986 @return The value written back to the PCI configuration register.
991 PciSegmentBitFieldOr32 (
998 return PciSegmentWrite32 (
1000 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1005 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1006 AND, and writes the result back to the bit field in the 32-bit register.
1009 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1010 AND between the read result and the value specified by AndData, and writes the result
1011 to the 32-bit PCI configuration register specified by Address. The value written to
1012 the PCI configuration register is returned. This function must guarantee that all PCI
1013 read and write operations are serialized. Extra left bits in AndData are stripped.
1014 If any reserved bits in Address are set, then ASSERT().
1015 If Address is not aligned on a 32-bit boundary, then ASSERT().
1016 If StartBit is greater than 31, then ASSERT().
1017 If EndBit is greater than 31, then ASSERT().
1018 If EndBit is less than StartBit, then ASSERT().
1019 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1021 @param Address The PCI configuration register to write.
1022 @param StartBit The ordinal of the least significant bit in the bit field.
1024 @param EndBit The ordinal of the most significant bit in the bit field.
1026 @param AndData The value to AND with the PCI configuration register.
1028 @return The value written back to the PCI configuration register.
1033 PciSegmentBitFieldAnd32 (
1040 return PciSegmentWrite32 (
1042 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1047 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1048 bitwise OR, and writes the result back to the bit field in the
1051 Reads the 32-bit PCI configuration register specified by Address, performs a
1052 bitwise AND followed by a bitwise OR between the read result and
1053 the value specified by AndData, and writes the result to the 32-bit PCI
1054 configuration register specified by Address. The value written to the PCI
1055 configuration register is returned. This function must guarantee that all PCI
1056 read and write operations are serialized. Extra left bits in both AndData and
1057 OrData are stripped.
1059 If any reserved bits in Address are set, then ASSERT().
1060 If StartBit is greater than 31, then ASSERT().
1061 If EndBit is greater than 31, then ASSERT().
1062 If EndBit is less than StartBit, then ASSERT().
1063 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1064 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1066 @param Address The PCI configuration register to write.
1067 @param StartBit The ordinal of the least significant bit in the bit field.
1069 @param EndBit The ordinal of the most significant bit in the bit field.
1071 @param AndData The value to AND with the PCI configuration register.
1072 @param OrData The value to OR with the result of the AND operation.
1074 @return The value written back to the PCI configuration register.
1079 PciSegmentBitFieldAndThenOr32 (
1087 return PciSegmentWrite32 (
1089 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1094 Reads a range of PCI configuration registers into a caller supplied buffer.
1096 Reads the range of PCI configuration registers specified by StartAddress and
1097 Size into the buffer specified by Buffer. This function only allows the PCI
1098 configuration registers from a single PCI function to be read. Size is
1099 returned. When possible 32-bit PCI configuration read cycles are used to read
1100 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1101 and 16-bit PCI configuration read cycles may be used at the beginning and the
1104 If any reserved bits in StartAddress are set, then ASSERT().
1105 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1106 If Size > 0 and Buffer is NULL, then ASSERT().
1108 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,
1109 Function and Register.
1110 @param Size The size in bytes of the transfer.
1111 @param Buffer The pointer to a buffer receiving the data read.
1118 PciSegmentReadBuffer (
1119 IN UINT64 StartAddress
,
1126 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1127 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1133 ASSERT (Buffer
!= NULL
);
1136 // Save Size for return
1140 if ((StartAddress
& BIT0
) != 0) {
1142 // Read a byte if StartAddress is byte aligned
1144 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1145 StartAddress
+= sizeof (UINT8
);
1146 Size
-= sizeof (UINT8
);
1147 Buffer
= (UINT8
*)Buffer
+ 1;
1150 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1152 // Read a word if StartAddress is word aligned
1154 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1155 StartAddress
+= sizeof (UINT16
);
1156 Size
-= sizeof (UINT16
);
1157 Buffer
= (UINT16
*)Buffer
+ 1;
1160 while (Size
>= sizeof (UINT32
)) {
1162 // Read as many double words as possible
1164 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1165 StartAddress
+= sizeof (UINT32
);
1166 Size
-= sizeof (UINT32
);
1167 Buffer
= (UINT32
*)Buffer
+ 1;
1170 if (Size
>= sizeof (UINT16
)) {
1172 // Read the last remaining word if exist
1174 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1175 StartAddress
+= sizeof (UINT16
);
1176 Size
-= sizeof (UINT16
);
1177 Buffer
= (UINT16
*)Buffer
+ 1;
1180 if (Size
>= sizeof (UINT8
)) {
1182 // Read the last remaining byte if exist
1184 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1191 Copies the data in a caller supplied buffer to a specified range of PCI
1192 configuration space.
1194 Writes the range of PCI configuration registers specified by StartAddress and
1195 Size from the buffer specified by Buffer. This function only allows the PCI
1196 configuration registers from a single PCI function to be written. Size is
1197 returned. When possible 32-bit PCI configuration write cycles are used to
1198 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1199 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1200 and the end of the range.
1202 If any reserved bits in StartAddress are set, then ASSERT().
1203 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1204 If Size > 0 and Buffer is NULL, then ASSERT().
1206 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,
1207 Function and Register.
1208 @param Size The size in bytes of the transfer.
1209 @param Buffer The pointer to a buffer containing the data to write.
1211 @return The parameter of Size.
1216 PciSegmentWriteBuffer (
1217 IN UINT64 StartAddress
,
1224 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1225 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1231 ASSERT (Buffer
!= NULL
);
1234 // Save Size for return
1238 if ((StartAddress
& BIT0
) != 0) {
1240 // Write a byte if StartAddress is byte aligned
1242 PciSegmentWrite8 (StartAddress
, *(UINT8
*) Buffer
);
1243 StartAddress
+= sizeof (UINT8
);
1244 Size
-= sizeof (UINT8
);
1245 Buffer
= (UINT8
*) Buffer
+ 1;
1248 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1250 // Write a word if StartAddress is word aligned
1252 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1253 StartAddress
+= sizeof (UINT16
);
1254 Size
-= sizeof (UINT16
);
1255 Buffer
= (UINT16
*) Buffer
+ 1;
1258 while (Size
>= sizeof (UINT32
)) {
1260 // Write as many double words as possible
1262 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1263 StartAddress
+= sizeof (UINT32
);
1264 Size
-= sizeof (UINT32
);
1265 Buffer
= (UINT32
*) Buffer
+ 1;
1268 if (Size
>= sizeof (UINT16
)) {
1270 // Write the last remaining word if exist
1272 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1273 StartAddress
+= sizeof (UINT16
);
1274 Size
-= sizeof (UINT16
);
1275 Buffer
= (UINT16
*) Buffer
+ 1;
1278 if (Size
>= sizeof (UINT8
)) {
1280 // Write the last remaining byte if exist
1282 PciSegmentWrite8 (StartAddress
, *(UINT8
*) Buffer
);