]>
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 - 2017, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/PciLib.h>
14 #include <Library/PciSegmentLib.h>
17 Assert the validity of a PCI Segment address.
18 A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
19 and the segment should be 0.
21 @param A The address to validate.
22 @param M Additional bits to assert to be zero.
25 #define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
26 ASSERT (((A) & (0xfffffffff0000000ULL | (M))) == 0)
29 Convert the PCI Segment library address to PCI library address.
31 @param A The address to convert.
33 #define PCI_SEGMENT_TO_PCI_ADDRESS(A) ((UINTN) (UINT32) A)
36 Register a PCI device so PCI configuration registers may be accessed after
37 SetVirtualAddressMap().
39 If any reserved bits in Address are set, then ASSERT().
41 @param Address The address that encodes the PCI Bus, Device, Function and
44 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
45 @retval RETURN_UNSUPPORTED An attempt was made to call this function
46 after ExitBootServices().
47 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
48 at runtime could not be mapped.
49 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
50 complete the registration.
55 PciSegmentRegisterForRuntimeAccess (
59 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
60 return PciRegisterForRuntimeAccess (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
64 Reads an 8-bit PCI configuration register.
66 Reads and returns the 8-bit PCI configuration register specified by Address.
67 This function must guarantee that all PCI read and write operations are serialized.
69 If any reserved bits in Address are set, then ASSERT().
71 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
73 @return The 8-bit PCI configuration register specified by Address.
82 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
84 return PciRead8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
88 Writes an 8-bit PCI configuration register.
90 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
91 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
93 If any reserved bits in Address are set, then ASSERT().
95 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
96 @param Value The value to write.
98 @return The value written to the PCI configuration register.
108 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 0);
110 return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), Value
);
114 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
116 Reads the 8-bit PCI configuration register specified by Address,
117 performs a bitwise OR between the read result and the value specified by OrData,
118 and writes the result to the 8-bit PCI configuration register specified by Address.
119 The value written to the PCI configuration register is returned.
120 This function must guarantee that all PCI read and write operations are serialized.
122 If any reserved bits in Address are set, then ASSERT().
124 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
125 @param OrData The value to OR with the PCI configuration register.
127 @return The value written to the PCI configuration register.
137 return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), (UINT8
) (PciSegmentRead8 (Address
) | OrData
));
141 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
143 Reads the 8-bit PCI configuration register specified by Address,
144 performs a bitwise AND between the read result and the value specified by AndData,
145 and writes the result to the 8-bit PCI configuration register specified by Address.
146 The value written to the PCI configuration register is returned.
147 This function must guarantee that all PCI read and write operations are serialized.
148 If any reserved bits in Address are set, then ASSERT().
150 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
151 @param AndData The value to AND with the PCI configuration register.
153 @return The value written to the PCI configuration register.
163 return PciSegmentWrite8 (Address
, (UINT8
) (PciSegmentRead8 (Address
) & AndData
));
167 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
168 followed a bitwise OR with another 8-bit value.
170 Reads the 8-bit PCI configuration register specified by Address,
171 performs a bitwise AND between the read result and the value specified by AndData,
172 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
173 and writes the result to the 8-bit PCI configuration register specified by Address.
174 The value written to the PCI configuration register is returned.
175 This function must guarantee that all PCI read and write operations are serialized.
177 If any reserved bits in Address are set, then ASSERT().
179 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
180 @param AndData The value to AND with the PCI configuration register.
181 @param OrData The value to OR with the PCI configuration register.
183 @return The value written to the PCI configuration register.
188 PciSegmentAndThenOr8 (
194 return PciSegmentWrite8 (Address
, (UINT8
) ((PciSegmentRead8 (Address
) & AndData
) | OrData
));
198 Reads a bit field of a PCI configuration register.
200 Reads the bit field in an 8-bit PCI configuration register. The bit field is
201 specified by the StartBit and the EndBit. The value of the bit field is
204 If any reserved bits in Address are set, then ASSERT().
205 If StartBit is greater than 7, then ASSERT().
206 If EndBit is greater than 7, then ASSERT().
207 If EndBit is less than StartBit, then ASSERT().
209 @param Address PCI configuration register to read.
210 @param StartBit The ordinal of the least significant bit in the bit field.
212 @param EndBit The ordinal of the most significant bit in the bit field.
215 @return The value of the bit field read from the PCI configuration register.
220 PciSegmentBitFieldRead8 (
226 return BitFieldRead8 (PciSegmentRead8 (Address
), StartBit
, EndBit
);
230 Writes a bit field to a PCI configuration register.
232 Writes Value to the bit field of the PCI configuration register. The bit
233 field is specified by the StartBit and the EndBit. All other bits in the
234 destination PCI configuration register are preserved. The new value of the
235 8-bit register is returned.
237 If any reserved bits in Address are set, then ASSERT().
238 If StartBit is greater than 7, then ASSERT().
239 If EndBit is greater than 7, then ASSERT().
240 If EndBit is less than StartBit, then ASSERT().
241 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
243 @param Address PCI configuration register to write.
244 @param StartBit The ordinal of the least significant bit in the bit field.
246 @param EndBit The ordinal of the most significant bit in the bit field.
248 @param Value New value of the bit field.
250 @return The value written back to the PCI configuration register.
255 PciSegmentBitFieldWrite8 (
262 return PciSegmentWrite8 (
264 BitFieldWrite8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, Value
)
269 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
270 writes the result back to the bit field in the 8-bit port.
272 Reads the 8-bit PCI configuration register specified by Address, performs a
273 bitwise OR between the read result and the value specified by
274 OrData, and writes the result to the 8-bit PCI configuration register
275 specified by Address. The value written to the PCI configuration register is
276 returned. This function must guarantee that all PCI read and write operations
277 are serialized. Extra left bits in OrData are stripped.
279 If any reserved bits in Address are set, then ASSERT().
280 If StartBit is greater than 7, then ASSERT().
281 If EndBit is greater than 7, then ASSERT().
282 If EndBit is less than StartBit, then ASSERT().
283 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
285 @param Address PCI configuration register to write.
286 @param StartBit The ordinal of the least significant bit in the bit field.
288 @param EndBit The ordinal of the most significant bit in the bit field.
290 @param OrData The value to OR with the PCI configuration register.
292 @return The value written back to the PCI configuration register.
297 PciSegmentBitFieldOr8 (
304 return PciSegmentWrite8 (
306 BitFieldOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, OrData
)
311 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
312 AND, and writes the result back to the bit field in the 8-bit register.
314 Reads the 8-bit PCI configuration register specified by Address, performs a
315 bitwise AND between the read result and the value specified by AndData, and
316 writes the result to the 8-bit PCI configuration register specified by
317 Address. The value written to the PCI configuration register is returned.
318 This function must guarantee that all PCI read and write operations are
319 serialized. Extra left bits in AndData are stripped.
321 If any reserved bits in Address are set, then ASSERT().
322 If StartBit is greater than 7, then ASSERT().
323 If EndBit is greater than 7, then ASSERT().
324 If EndBit is less than StartBit, then ASSERT().
325 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
327 @param Address PCI configuration register to write.
328 @param StartBit The ordinal of the least significant bit in the bit field.
330 @param EndBit The ordinal of the most significant bit in the bit field.
332 @param AndData The value to AND with the PCI configuration register.
334 @return The value written back to the PCI configuration register.
339 PciSegmentBitFieldAnd8 (
346 return PciSegmentWrite8 (
348 BitFieldAnd8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
)
353 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
354 bitwise OR, and writes the result back to the bit field in the 8-bit port.
356 Reads the 8-bit PCI configuration register specified by Address, performs a
357 bitwise AND followed by a bitwise OR between the read result and
358 the value specified by AndData, and writes the result to the 8-bit PCI
359 configuration register specified by Address. The value written to the PCI
360 configuration register is returned. This function must guarantee that all PCI
361 read and write operations are serialized. Extra left bits in both AndData and
364 If any reserved bits in Address are set, then ASSERT().
365 If StartBit is greater than 7, then ASSERT().
366 If EndBit is greater than 7, then ASSERT().
367 If EndBit is less than StartBit, then ASSERT().
368 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
369 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
371 @param Address PCI configuration register to write.
372 @param StartBit The ordinal of the least significant bit in the bit field.
374 @param EndBit The ordinal of the most significant bit in the bit field.
376 @param AndData The value to AND with the PCI configuration register.
377 @param OrData The value to OR with the result of the AND operation.
379 @return The value written back to the PCI configuration register.
384 PciSegmentBitFieldAndThenOr8 (
392 return PciSegmentWrite8 (
394 BitFieldAndThenOr8 (PciSegmentRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
399 Reads a 16-bit PCI configuration register.
401 Reads and returns the 16-bit PCI configuration register specified by Address.
402 This function must guarantee that all PCI read and write operations are serialized.
404 If any reserved bits in Address are set, then ASSERT().
405 If Address is not aligned on a 16-bit boundary, then ASSERT().
407 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
409 @return The 16-bit PCI configuration register specified by Address.
418 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
420 return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
424 Writes a 16-bit PCI configuration register.
426 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
427 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
429 If any reserved bits in Address are set, then ASSERT().
430 If Address is not aligned on a 16-bit boundary, then ASSERT().
432 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
433 @param Value The value to write.
435 @return The parameter of Value.
445 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 1);
447 return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), Value
);
451 Performs a bitwise OR of a 16-bit PCI configuration register with
454 Reads the 16-bit PCI configuration register specified by Address, performs a
455 bitwise OR between the read result and the value specified by OrData, and
456 writes the result to the 16-bit PCI configuration register specified by Address.
457 The value written to the PCI configuration register is returned. This function
458 must guarantee that all PCI read and write operations are serialized.
460 If any reserved bits in Address are set, then ASSERT().
461 If Address is not aligned on a 16-bit boundary, then ASSERT().
463 @param Address Address that encodes the PCI Segment, Bus, Device, Function and
465 @param OrData The value to OR with the PCI configuration register.
467 @return The value written back to the PCI configuration register.
477 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) | OrData
));
481 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
483 Reads the 16-bit PCI configuration register specified by Address,
484 performs a bitwise AND between the read result and the value specified by AndData,
485 and writes the result to the 16-bit PCI configuration register specified by Address.
486 The value written to the PCI configuration register is returned.
487 This function must guarantee that all PCI read and write operations are serialized.
489 If any reserved bits in Address are set, then ASSERT().
490 If Address is not aligned on a 16-bit boundary, then ASSERT().
492 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
493 @param AndData The value to AND with the PCI configuration register.
495 @return The value written to the PCI configuration register.
505 return PciSegmentWrite16 (Address
, (UINT16
) (PciSegmentRead16 (Address
) & AndData
));
509 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
510 followed a bitwise OR with another 16-bit value.
512 Reads the 16-bit PCI configuration register specified by Address,
513 performs a bitwise AND between the read result and the value specified by AndData,
514 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
515 and writes the result to the 16-bit PCI configuration register specified by Address.
516 The value written to the PCI configuration register is returned.
517 This function must guarantee that all PCI read and write operations are serialized.
519 If any reserved bits in Address are set, then ASSERT().
520 If Address is not aligned on a 16-bit boundary, then ASSERT().
522 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
523 @param AndData The value to AND with the PCI configuration register.
524 @param OrData The value to OR with the PCI configuration register.
526 @return The value written to the PCI configuration register.
531 PciSegmentAndThenOr16 (
537 return PciSegmentWrite16 (Address
, (UINT16
) ((PciSegmentRead16 (Address
) & AndData
) | OrData
));
541 Reads a bit field of a PCI configuration register.
543 Reads the bit field in a 16-bit PCI configuration register. The bit field is
544 specified by the StartBit and the EndBit. The value of the bit field is
547 If any reserved bits in Address are set, then ASSERT().
548 If Address is not aligned on a 16-bit boundary, then ASSERT().
549 If StartBit is greater than 15, then ASSERT().
550 If EndBit is greater than 15, then ASSERT().
551 If EndBit is less than StartBit, then ASSERT().
553 @param Address PCI configuration register to read.
554 @param StartBit The ordinal of the least significant bit in the bit field.
556 @param EndBit The ordinal of the most significant bit in the bit field.
559 @return The value of the bit field read from the PCI configuration register.
564 PciSegmentBitFieldRead16 (
570 return BitFieldRead16 (PciSegmentRead16 (Address
), StartBit
, EndBit
);
574 Writes a bit field to a PCI configuration register.
576 Writes Value to the bit field of the PCI configuration register. The bit
577 field is specified by the StartBit and the EndBit. All other bits in the
578 destination PCI configuration register are preserved. The new value of the
579 16-bit register is returned.
581 If any reserved bits in Address are set, then ASSERT().
582 If Address is not aligned on a 16-bit boundary, then ASSERT().
583 If StartBit is greater than 15, then ASSERT().
584 If EndBit is greater than 15, then ASSERT().
585 If EndBit is less than StartBit, then ASSERT().
586 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
588 @param Address PCI configuration register to write.
589 @param StartBit The ordinal of the least significant bit in the bit field.
591 @param EndBit The ordinal of the most significant bit in the bit field.
593 @param Value New value of the bit field.
595 @return The value written back to the PCI configuration register.
600 PciSegmentBitFieldWrite16 (
607 return PciSegmentWrite16 (
609 BitFieldWrite16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, Value
)
614 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, writes
615 the result back to the bit field in the 16-bit port.
617 Reads the 16-bit PCI configuration register specified by Address, performs a
618 bitwise OR between the read result and the value specified by
619 OrData, and writes the result to the 16-bit PCI configuration register
620 specified by Address. The value written to the PCI configuration register is
621 returned. This function must guarantee that all PCI read and write operations
622 are serialized. Extra left bits in OrData are stripped.
624 If any reserved bits in Address are set, then ASSERT().
625 If Address is not aligned on a 16-bit boundary, then ASSERT().
626 If StartBit is greater than 15, then ASSERT().
627 If EndBit is greater than 15, then ASSERT().
628 If EndBit is less than StartBit, then ASSERT().
629 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
631 @param Address PCI configuration register to write.
632 @param StartBit The ordinal of the least significant bit in the bit field.
634 @param EndBit The ordinal of the most significant bit in the bit field.
636 @param OrData The value to OR with the PCI configuration register.
638 @return The value written back to the PCI configuration register.
643 PciSegmentBitFieldOr16 (
650 return PciSegmentWrite16 (
652 BitFieldOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, OrData
)
657 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
658 AND, writes the result back to the bit field in the 16-bit register.
660 Reads the 16-bit PCI configuration register specified by Address, performs a
661 bitwise AND between the read result and the value specified by AndData, and
662 writes the result to the 16-bit PCI configuration register specified by
663 Address. The value written to the PCI configuration register is returned.
664 This function must guarantee that all PCI read and write operations are
665 serialized. Extra left bits in AndData are stripped.
667 If any reserved bits in Address are set, then ASSERT().
668 If Address is not aligned on a 16-bit boundary, then ASSERT().
669 If StartBit is greater than 15, then ASSERT().
670 If EndBit is greater than 15, then ASSERT().
671 If EndBit is less than StartBit, then ASSERT().
672 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
674 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
675 @param StartBit The ordinal of the least significant bit in the bit field.
677 @param EndBit The ordinal of the most significant bit in the bit field.
679 @param AndData The value to AND with the PCI configuration register.
681 @return The value written back to the PCI configuration register.
686 PciSegmentBitFieldAnd16 (
693 return PciSegmentWrite16 (
695 BitFieldAnd16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
)
700 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
701 bitwise OR, and writes the result back to the bit field in the
704 Reads the 16-bit PCI configuration register specified by Address, performs a
705 bitwise AND followed by a bitwise OR between the read result and
706 the value specified by AndData, and writes the result to the 16-bit PCI
707 configuration register specified by Address. The value written to the PCI
708 configuration register is returned. This function must guarantee that all PCI
709 read and write operations are serialized. Extra left bits in both AndData and
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 AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
717 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
719 @param Address PCI configuration register to write.
720 @param StartBit The ordinal of the least significant bit in the bit field.
722 @param EndBit The ordinal of the most significant bit in the bit field.
724 @param AndData The value to AND with the PCI configuration register.
725 @param OrData The value to OR with the result of the AND operation.
727 @return The value written back to the PCI configuration register.
732 PciSegmentBitFieldAndThenOr16 (
740 return PciSegmentWrite16 (
742 BitFieldAndThenOr16 (PciSegmentRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
747 Reads a 32-bit PCI configuration register.
749 Reads and returns the 32-bit PCI configuration register specified by Address.
750 This function must guarantee that all PCI read and write operations are serialized.
752 If any reserved bits in Address are set, then ASSERT().
753 If Address is not aligned on a 32-bit boundary, then ASSERT().
755 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
757 @return The 32-bit PCI configuration register specified by Address.
766 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
768 return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
));
772 Writes a 32-bit PCI configuration register.
774 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
775 Value is returned. This function must guarantee that all PCI read and write operations are serialized.
777 If any reserved bits in Address are set, then ASSERT().
778 If Address is not aligned on a 32-bit boundary, then ASSERT().
780 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
781 @param Value The value to write.
783 @return The parameter of Value.
793 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address
, 3);
795 return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address
), Value
);
799 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
801 Reads the 32-bit PCI configuration register specified by Address,
802 performs a bitwise OR between the read result and the value specified by OrData,
803 and writes the result to the 32-bit PCI configuration register specified by Address.
804 The value written to the PCI configuration register is returned.
805 This function must guarantee that all PCI read and write operations are serialized.
807 If any reserved bits in Address are set, then ASSERT().
808 If Address is not aligned on a 32-bit boundary, then ASSERT().
810 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
811 @param OrData The value to OR with the PCI configuration register.
813 @return The value written to the PCI configuration register.
823 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) | OrData
);
827 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
829 Reads the 32-bit PCI configuration register specified by Address,
830 performs a bitwise AND between the read result and the value specified by AndData,
831 and writes the result to the 32-bit PCI configuration register specified by Address.
832 The value written to the PCI configuration register is returned.
833 This function must guarantee that all PCI read and write operations are serialized.
835 If any reserved bits in Address are set, then ASSERT().
836 If Address is not aligned on a 32-bit boundary, then ASSERT().
838 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
839 @param AndData The value to AND with the PCI configuration register.
841 @return The value written to the PCI configuration register.
851 return PciSegmentWrite32 (Address
, PciSegmentRead32 (Address
) & AndData
);
855 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
856 followed a bitwise OR with another 32-bit value.
858 Reads the 32-bit PCI configuration register specified by Address,
859 performs a bitwise AND between the read result and the value specified by AndData,
860 performs a bitwise OR between the result of the AND operation and the value specified by OrData,
861 and writes the result to the 32-bit PCI configuration register specified by Address.
862 The value written to the PCI configuration register is returned.
863 This function must guarantee that all PCI read and write operations are serialized.
865 If any reserved bits in Address are set, then ASSERT().
866 If Address is not aligned on a 32-bit boundary, then ASSERT().
868 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
869 @param AndData The value to AND with the PCI configuration register.
870 @param OrData The value to OR with the PCI configuration register.
872 @return The value written to the PCI configuration register.
877 PciSegmentAndThenOr32 (
883 return PciSegmentWrite32 (Address
, (PciSegmentRead32 (Address
) & AndData
) | OrData
);
887 Reads a bit field of a PCI configuration register.
889 Reads the bit field in a 32-bit PCI configuration register. The bit field is
890 specified by the StartBit and the EndBit. The value of the bit field is
893 If any reserved bits in Address are set, then ASSERT().
894 If Address is not aligned on a 32-bit boundary, then ASSERT().
895 If StartBit is greater than 31, then ASSERT().
896 If EndBit is greater than 31, then ASSERT().
897 If EndBit is less than StartBit, then ASSERT().
899 @param Address PCI configuration register to read.
900 @param StartBit The ordinal of the least significant bit in the bit field.
902 @param EndBit The ordinal of the most significant bit in the bit field.
905 @return The value of the bit field read from the PCI configuration register.
910 PciSegmentBitFieldRead32 (
916 return BitFieldRead32 (PciSegmentRead32 (Address
), StartBit
, EndBit
);
920 Writes a bit field to a PCI configuration register.
922 Writes Value to the bit field of the PCI configuration register. The bit
923 field is specified by the StartBit and the EndBit. All other bits in the
924 destination PCI configuration register are preserved. The new value of the
925 32-bit register is returned.
927 If any reserved bits in Address are set, then ASSERT().
928 If Address is not aligned on a 32-bit boundary, then ASSERT().
929 If StartBit is greater than 31, then ASSERT().
930 If EndBit is greater than 31, then ASSERT().
931 If EndBit is less than StartBit, then ASSERT().
932 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
934 @param Address PCI configuration register to write.
935 @param StartBit The ordinal of the least significant bit in the bit field.
937 @param EndBit The ordinal of the most significant bit in the bit field.
939 @param Value New value of the bit field.
941 @return The value written back to the PCI configuration register.
946 PciSegmentBitFieldWrite32 (
953 return PciSegmentWrite32 (
955 BitFieldWrite32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, Value
)
960 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
961 writes the result back to the bit field in the 32-bit port.
963 Reads the 32-bit PCI configuration register specified by Address, performs a
964 bitwise OR between the read result and the value specified by
965 OrData, and writes the result to the 32-bit PCI configuration register
966 specified by Address. The value written to the PCI configuration register is
967 returned. This function must guarantee that all PCI read and write operations
968 are serialized. Extra left bits in OrData are stripped.
970 If any reserved bits in Address are set, then ASSERT().
971 If StartBit is greater than 31, then ASSERT().
972 If EndBit is greater than 31, then ASSERT().
973 If EndBit is less than StartBit, then ASSERT().
974 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
976 @param Address PCI configuration register to write.
977 @param StartBit The ordinal of the least significant bit in the bit field.
979 @param EndBit The ordinal of the most significant bit in the bit field.
981 @param OrData The value to OR with the PCI configuration register.
983 @return The value written back to the PCI configuration register.
988 PciSegmentBitFieldOr32 (
995 return PciSegmentWrite32 (
997 BitFieldOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, OrData
)
1002 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1003 AND, and writes the result back to the bit field in the 32-bit register.
1006 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
1007 AND between the read result and the value specified by AndData, and writes the result
1008 to the 32-bit PCI configuration register specified by Address. The value written to
1009 the PCI configuration register is returned. This function must guarantee that all PCI
1010 read and write operations are serialized. Extra left bits in AndData are stripped.
1011 If any reserved bits in Address are set, then ASSERT().
1012 If Address is not aligned on a 32-bit boundary, then ASSERT().
1013 If StartBit is greater than 31, then ASSERT().
1014 If EndBit is greater than 31, then ASSERT().
1015 If EndBit is less than StartBit, then ASSERT().
1016 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1018 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
1019 @param StartBit The ordinal of the least significant bit in the bit field.
1021 @param EndBit The ordinal of the most significant bit in the bit field.
1023 @param AndData The value to AND with the PCI configuration register.
1025 @return The value written back to the PCI configuration register.
1030 PciSegmentBitFieldAnd32 (
1037 return PciSegmentWrite32 (
1039 BitFieldAnd32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
)
1044 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1045 bitwise OR, and writes the result back to the bit field in the
1048 Reads the 32-bit PCI configuration register specified by Address, performs a
1049 bitwise AND followed by a bitwise OR between the read result and
1050 the value specified by AndData, and writes the result to the 32-bit PCI
1051 configuration register specified by Address. The value written to the PCI
1052 configuration register is returned. This function must guarantee that all PCI
1053 read and write operations are serialized. Extra left bits in both AndData and
1054 OrData are stripped.
1056 If any reserved bits in Address are set, then ASSERT().
1057 If StartBit is greater than 31, then ASSERT().
1058 If EndBit is greater than 31, then ASSERT().
1059 If EndBit is less than StartBit, then ASSERT().
1060 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1061 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1063 @param Address PCI configuration register to write.
1064 @param StartBit The ordinal of the least significant bit in the bit field.
1066 @param EndBit The ordinal of the most significant bit in the bit field.
1068 @param AndData The value to AND with the PCI configuration register.
1069 @param OrData The value to OR with the result of the AND operation.
1071 @return The value written back to the PCI configuration register.
1076 PciSegmentBitFieldAndThenOr32 (
1084 return PciSegmentWrite32 (
1086 BitFieldAndThenOr32 (PciSegmentRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1091 Reads a range of PCI configuration registers into a caller supplied buffer.
1093 Reads the range of PCI configuration registers specified by StartAddress and
1094 Size into the buffer specified by Buffer. This function only allows the PCI
1095 configuration registers from a single PCI function to be read. Size is
1096 returned. When possible 32-bit PCI configuration read cycles are used to read
1097 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1098 and 16-bit PCI configuration read cycles may be used at the beginning and the
1101 If any reserved bits in StartAddress are set, then ASSERT().
1102 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1103 If Size > 0 and Buffer is NULL, then ASSERT().
1105 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1106 Function and Register.
1107 @param Size Size in bytes of the transfer.
1108 @param Buffer Pointer to a buffer receiving the data read.
1115 PciSegmentReadBuffer (
1116 IN UINT64 StartAddress
,
1123 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1124 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1130 ASSERT (Buffer
!= NULL
);
1133 // Save Size for return
1137 if ((StartAddress
& BIT0
) != 0) {
1139 // Read a byte if StartAddress is byte aligned
1141 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1142 StartAddress
+= sizeof (UINT8
);
1143 Size
-= sizeof (UINT8
);
1144 Buffer
= (UINT8
*)Buffer
+ 1;
1147 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1149 // Read a word if StartAddress is word aligned
1151 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1152 StartAddress
+= sizeof (UINT16
);
1153 Size
-= sizeof (UINT16
);
1154 Buffer
= (UINT16
*)Buffer
+ 1;
1157 while (Size
>= sizeof (UINT32
)) {
1159 // Read as many double words as possible
1161 WriteUnaligned32 (Buffer
, PciSegmentRead32 (StartAddress
));
1162 StartAddress
+= sizeof (UINT32
);
1163 Size
-= sizeof (UINT32
);
1164 Buffer
= (UINT32
*)Buffer
+ 1;
1167 if (Size
>= sizeof (UINT16
)) {
1169 // Read the last remaining word if exist
1171 WriteUnaligned16 (Buffer
, PciSegmentRead16 (StartAddress
));
1172 StartAddress
+= sizeof (UINT16
);
1173 Size
-= sizeof (UINT16
);
1174 Buffer
= (UINT16
*)Buffer
+ 1;
1177 if (Size
>= sizeof (UINT8
)) {
1179 // Read the last remaining byte if exist
1181 *(volatile UINT8
*)Buffer
= PciSegmentRead8 (StartAddress
);
1188 Copies the data in a caller supplied buffer to a specified range of PCI
1189 configuration space.
1191 Writes the range of PCI configuration registers specified by StartAddress and
1192 Size from the buffer specified by Buffer. This function only allows the PCI
1193 configuration registers from a single PCI function to be written. Size is
1194 returned. When possible 32-bit PCI configuration write cycles are used to
1195 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1196 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1197 and the end of the range.
1199 If any reserved bits in StartAddress are set, then ASSERT().
1200 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1201 If Size > 0 and Buffer is NULL, then ASSERT().
1203 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,
1204 Function and Register.
1205 @param Size Size in bytes of the transfer.
1206 @param Buffer Pointer to a buffer containing the data to write.
1208 @return The parameter of Size.
1213 PciSegmentWriteBuffer (
1214 IN UINT64 StartAddress
,
1221 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress
, 0);
1222 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1228 ASSERT (Buffer
!= NULL
);
1231 // Save Size for return
1235 if ((StartAddress
& BIT0
) != 0) {
1237 // Write a byte if StartAddress is byte aligned
1239 PciSegmentWrite8 (StartAddress
, *(UINT8
*) Buffer
);
1240 StartAddress
+= sizeof (UINT8
);
1241 Size
-= sizeof (UINT8
);
1242 Buffer
= (UINT8
*) Buffer
+ 1;
1245 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1247 // Write a word if StartAddress is word aligned
1249 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1250 StartAddress
+= sizeof (UINT16
);
1251 Size
-= sizeof (UINT16
);
1252 Buffer
= (UINT16
*) Buffer
+ 1;
1255 while (Size
>= sizeof (UINT32
)) {
1257 // Write as many double words as possible
1259 PciSegmentWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1260 StartAddress
+= sizeof (UINT32
);
1261 Size
-= sizeof (UINT32
);
1262 Buffer
= (UINT32
*) Buffer
+ 1;
1265 if (Size
>= sizeof (UINT16
)) {
1267 // Write the last remaining word if exist
1269 PciSegmentWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1270 StartAddress
+= sizeof (UINT16
);
1271 Size
-= sizeof (UINT16
);
1272 Buffer
= (UINT16
*) Buffer
+ 1;
1275 if (Size
>= sizeof (UINT8
)) {
1277 // Write the last remaining byte if exist
1279 PciSegmentWrite8 (StartAddress
, *(UINT8
*) Buffer
);