2 PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
3 Layers on top of an I/O Library instance.
5 Copyright (c) 2006 - 2009, Intel Corporation<BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/BaseLib.h>
20 #include <Library/PciCf8Lib.h>
21 #include <Library/IoLib.h>
22 #include <Library/DebugLib.h>
25 // Declare I/O Ports used to perform PCI Confguration Cycles
27 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
28 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
31 Convert a PCI Library address to PCI CF8 formatted address.
33 Declare macro to convert PCI Library address to PCI CF8 formatted address.
34 Bit fields of PCI Library and CF8 formatted address is as follows:
35 PCI Library formatted address CF8 Formatted Address
36 ============================= ======================
37 Bits 00..11 Register Bits 00..07 Register
38 Bits 12..14 Function Bits 08..10 Function
39 Bits 15..19 Device Bits 11..15 Device
40 Bits 20..27 Bus Bits 16..23 Bus
41 Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
44 @param A The address to convert.
46 @retval The coverted address.
49 #define PCI_TO_CF8_ADDRESS(A) \
50 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
53 Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's
54 only in the low 28 bits, excluding bits 08..11.
56 @param A The address to validate.
57 @param M Additional bits to assert to be zero.
60 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
61 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
64 Registers a PCI device so PCI configuration registers may be accessed after
65 SetVirtualAddressMap().
67 Registers the PCI device specified by Address so all the PCI configuration registers
68 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
70 If Address > 0x0FFFFFFF, then ASSERT().
71 If the register specified by Address >= 0x100, then ASSERT().
73 @param Address Address that encodes the PCI Bus, Device, Function and
76 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
77 @retval RETURN_UNSUPPORTED An attempt was made to call this function
78 after ExitBootServices().
79 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
80 at runtime could not be mapped.
81 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
82 complete the registration.
87 PciCf8RegisterForRuntimeAccess (
91 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
92 return RETURN_SUCCESS
;
96 Reads an 8-bit PCI configuration register.
98 Reads and returns the 8-bit PCI configuration register specified by Address.
99 This function must guarantee that all PCI read and write operations are
102 If Address > 0x0FFFFFFF, then ASSERT().
103 If the register specified by Address >= 0x100, then ASSERT().
105 @param Address Address that encodes the PCI Bus, Device, Function and
108 @return The read value from the PCI configuration register.
117 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
118 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
119 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
123 Writes an 8-bit PCI configuration register.
125 Writes the 8-bit PCI configuration register specified by Address with the
126 value specified by Value. Value is returned. This function must guarantee
127 that all PCI read and write operations are serialized.
129 If Address > 0x0FFFFFFF, then ASSERT().
130 If the register specified by Address >= 0x100, then ASSERT().
132 @param Address Address that encodes the PCI Bus, Device, Function and
134 @param Value The value to write.
136 @return The value written to the PCI configuration register.
146 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
147 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
149 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
155 Performs a bitwise OR of an 8-bit PCI configuration register with
158 Reads the 8-bit PCI configuration register specified by Address, performs a
159 bitwise OR between the read result and the value specified by
160 OrData, and writes the result to the 8-bit PCI configuration register
161 specified by Address. The value written to the PCI configuration register is
162 returned. This function must guarantee that all PCI read and write operations
165 If Address > 0x0FFFFFFF, then ASSERT().
166 If the register specified by Address >= 0x100, then ASSERT().
168 @param Address Address that encodes the PCI Bus, Device, Function and
170 @param OrData The value to OR with the PCI configuration register.
172 @return The value written back to the PCI configuration register.
182 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
183 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
185 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
191 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
194 Reads the 8-bit PCI configuration register specified by Address, performs a
195 bitwise AND between the read result and the value specified by AndData, and
196 writes the result to the 8-bit PCI configuration register specified by
197 Address. The value written to the PCI configuration register is returned.
198 This function must guarantee that all PCI read and write operations are
201 If Address > 0x0FFFFFFF, then ASSERT().
202 If the register specified by Address >= 0x100, then ASSERT().
204 @param Address Address that encodes the PCI Bus, Device, Function and
206 @param AndData The value to AND with the PCI configuration register.
208 @return The value written back to the PCI configuration register.
218 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
219 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
221 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
227 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
228 value, followed a bitwise OR with another 8-bit value.
230 Reads the 8-bit PCI configuration register specified by Address, performs a
231 bitwise AND between the read result and the value specified by AndData,
232 performs a bitwise OR between the result of the AND operation and
233 the value specified by OrData, and writes the result to the 8-bit PCI
234 configuration register specified by Address. The value written to the PCI
235 configuration register is returned. This function must guarantee that all PCI
236 read and write operations are serialized.
238 If Address > 0x0FFFFFFF, then ASSERT().
239 If the register specified by Address >= 0x100, then ASSERT().
241 @param Address Address that encodes the PCI Bus, Device, Function and
243 @param AndData The value to AND with the PCI configuration register.
244 @param OrData The value to OR with the result of the AND operation.
246 @return The value written back to the PCI configuration register.
257 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
258 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
259 return IoAndThenOr8 (
260 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
267 Reads a bit field of a PCI configuration register.
269 Reads the bit field in an 8-bit PCI configuration register. The bit field is
270 specified by the StartBit and the EndBit. The value of the bit field is
273 If Address > 0x0FFFFFFF, then ASSERT().
274 If the register specified by Address >= 0x100, then ASSERT().
275 If StartBit is greater than 7, then ASSERT().
276 If EndBit is greater than 7, then ASSERT().
277 If EndBit is less than StartBit, then ASSERT().
279 @param Address PCI configuration register to read.
280 @param StartBit The ordinal of the least significant bit in the bit field.
282 @param EndBit The ordinal of the most significant bit in the bit field.
285 @return The value of the bit field read from the PCI configuration register.
290 PciCf8BitFieldRead8 (
296 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
297 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
298 return IoBitFieldRead8 (
299 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
306 Writes a bit field to a PCI configuration register.
308 Writes Value to the bit field of the PCI configuration register. The bit
309 field is specified by the StartBit and the EndBit. All other bits in the
310 destination PCI configuration register are preserved. The new value of the
311 8-bit register is returned.
313 If Address > 0x0FFFFFFF, then ASSERT().
314 If the register specified by Address >= 0x100, then ASSERT().
315 If StartBit is greater than 7, then ASSERT().
316 If EndBit is greater than 7, then ASSERT().
317 If EndBit is less than StartBit, then ASSERT().
319 @param Address PCI configuration register to write.
320 @param StartBit The ordinal of the least significant bit in the bit field.
322 @param EndBit The ordinal of the most significant bit in the bit field.
324 @param Value New value of the bit field.
326 @return The value written back to the PCI configuration register.
331 PciCf8BitFieldWrite8 (
338 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
339 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
340 return IoBitFieldWrite8 (
341 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
349 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
350 writes the result back to the bit field in the 8-bit port.
352 Reads the 8-bit PCI configuration register specified by Address, performs a
353 bitwise OR between the read result and the value specified by
354 OrData, and writes the result to the 8-bit PCI configuration register
355 specified by Address. The value written to the PCI configuration register is
356 returned. This function must guarantee that all PCI read and write operations
357 are serialized. Extra left bits in OrData are stripped.
359 If Address > 0x0FFFFFFF, then ASSERT().
360 If the register specified by Address >= 0x100, then ASSERT().
361 If StartBit is greater than 7, then ASSERT().
362 If EndBit is greater than 7, then ASSERT().
363 If EndBit is less than StartBit, then ASSERT().
365 @param Address PCI configuration register to write.
366 @param StartBit The ordinal of the least significant bit in the bit field.
368 @param EndBit The ordinal of the most significant bit in the bit field.
370 @param OrData The value to OR with the PCI configuration register.
372 @return The value written back to the PCI configuration register.
384 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
385 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
386 return IoBitFieldOr8 (
387 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
395 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
396 AND, and writes the result back to the bit field in the 8-bit register.
398 Reads the 8-bit PCI configuration register specified by Address, performs a
399 bitwise AND between the read result and the value specified by AndData, and
400 writes the result to the 8-bit PCI configuration register specified by
401 Address. The value written to the PCI configuration register is returned.
402 This function must guarantee that all PCI read and write operations are
403 serialized. Extra left bits in AndData are stripped.
405 If Address > 0x0FFFFFFF, then ASSERT().
406 If the register specified by Address >= 0x100, then ASSERT().
407 If StartBit is greater than 7, then ASSERT().
408 If EndBit is greater than 7, then ASSERT().
409 If EndBit is less than StartBit, then ASSERT().
411 @param Address PCI configuration register to write.
412 @param StartBit The ordinal of the least significant bit in the bit field.
414 @param EndBit The ordinal of the most significant bit in the bit field.
416 @param AndData The value to AND with the PCI configuration register.
418 @return The value written back to the PCI configuration register.
430 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
431 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
432 return IoBitFieldAnd8 (
433 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
441 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
442 bitwise OR, and writes the result back to the bit field in the
445 Reads the 8-bit PCI configuration register specified by Address, performs a
446 bitwise AND followed by a bitwise OR between the read result and
447 the value specified by AndData, and writes the result to the 8-bit PCI
448 configuration register specified by Address. The value written to the PCI
449 configuration register is returned. This function must guarantee that all PCI
450 read and write operations are serialized. Extra left bits in both AndData and
453 If Address > 0x0FFFFFFF, then ASSERT().
454 If the register specified by Address >= 0x100, then ASSERT().
455 If StartBit is greater than 7, then ASSERT().
456 If EndBit is greater than 7, then ASSERT().
457 If EndBit is less than StartBit, then ASSERT().
459 @param Address PCI configuration register to write.
460 @param StartBit The ordinal of the least significant bit in the bit field.
462 @param EndBit The ordinal of the most significant bit in the bit field.
464 @param AndData The value to AND with the PCI configuration register.
465 @param OrData The value to OR with the result of the AND operation.
467 @return The value written back to the PCI configuration register.
472 PciCf8BitFieldAndThenOr8(
480 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
481 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
482 return IoBitFieldAndThenOr8 (
483 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
492 Reads a 16-bit PCI configuration register.
494 Reads and returns the 16-bit PCI configuration register specified by Address.
495 This function must guarantee that all PCI read and write operations are
498 If Address > 0x0FFFFFFF, then ASSERT().
499 If Address is not aligned on a 16-bit boundary, then ASSERT().
500 If the register specified by Address >= 0x100, then ASSERT().
502 @param Address Address that encodes the PCI Bus, Device, Function and
505 @return The read value from the PCI configuration register.
514 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
515 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
516 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
520 Writes a 16-bit PCI configuration register.
522 Writes the 16-bit PCI configuration register specified by Address with the
523 value specified by Value. Value is returned. This function must guarantee
524 that all PCI read and write operations are serialized.
526 If Address > 0x0FFFFFFF, then ASSERT().
527 If Address is not aligned on a 16-bit boundary, then ASSERT().
528 If the register specified by Address >= 0x100, then ASSERT().
530 @param Address Address that encodes the PCI Bus, Device, Function and
532 @param Value The value to write.
534 @return The value written to the PCI configuration register.
544 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
545 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
547 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
553 Performs a bitwise OR of a 16-bit PCI configuration register with
556 Reads the 16-bit PCI configuration register specified by Address, performs a
557 bitwise OR between the read result and the value specified by
558 OrData, and writes the result to the 16-bit PCI configuration register
559 specified by Address. The value written to the PCI configuration register is
560 returned. This function must guarantee that all PCI read and write operations
563 If Address > 0x0FFFFFFF, then ASSERT().
564 If Address is not aligned on a 16-bit boundary, then ASSERT().
565 If the register specified by Address >= 0x100, then ASSERT().
567 @param Address Address that encodes the PCI Bus, Device, Function and
569 @param OrData The value to OR with the PCI configuration register.
571 @return The value written back to the PCI configuration register.
581 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
582 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
584 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
590 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
593 Reads the 16-bit PCI configuration register specified by Address, performs a
594 bitwise AND between the read result and the value specified by AndData, and
595 writes the result to the 16-bit PCI configuration register specified by
596 Address. The value written to the PCI configuration register is returned.
597 This function must guarantee that all PCI read and write operations are
600 If Address > 0x0FFFFFFF, then ASSERT().
601 If Address is not aligned on a 16-bit boundary, then ASSERT().
602 If the register specified by Address >= 0x100, then ASSERT().
604 @param Address Address that encodes the PCI Bus, Device, Function and
606 @param AndData The value to AND with the PCI configuration register.
608 @return The value written back to the PCI configuration register.
618 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
619 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
621 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
627 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
628 value, followed a bitwise OR with another 16-bit value.
630 Reads the 16-bit PCI configuration register specified by Address, performs a
631 bitwise AND between the read result and the value specified by AndData,
632 performs a bitwise OR between the result of the AND operation and
633 the value specified by OrData, and writes the result to the 16-bit PCI
634 configuration register specified by Address. The value written to the PCI
635 configuration register is returned. This function must guarantee that all PCI
636 read and write operations are serialized.
638 If Address > 0x0FFFFFFF, then ASSERT().
639 If Address is not aligned on a 16-bit boundary, then ASSERT().
640 If the register specified by Address >= 0x100, then ASSERT().
642 @param Address Address that encodes the PCI Bus, Device, Function and
644 @param AndData The value to AND with the PCI configuration register.
645 @param OrData The value to OR with the result of the AND operation.
647 @return The value written back to the PCI configuration register.
658 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
659 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
660 return IoAndThenOr16 (
661 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
668 Reads a bit field of a PCI configuration register.
670 Reads the bit field in a 16-bit PCI configuration register. The bit field is
671 specified by the StartBit and the EndBit. The value of the bit field is
674 If Address > 0x0FFFFFFF, then ASSERT().
675 If Address is not aligned on a 16-bit boundary, then ASSERT().
676 If the register specified by Address >= 0x100, then ASSERT().
677 If StartBit is greater than 15, then ASSERT().
678 If EndBit is greater than 15, then ASSERT().
679 If EndBit is less than StartBit, then ASSERT().
681 @param Address PCI configuration register to read.
682 @param StartBit The ordinal of the least significant bit in the bit field.
684 @param EndBit The ordinal of the most significant bit in the bit field.
687 @return The value of the bit field read from the PCI configuration register.
692 PciCf8BitFieldRead16 (
698 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
699 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
700 return IoBitFieldRead16 (
701 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
708 Writes a bit field to a PCI configuration register.
710 Writes Value to the bit field of the PCI configuration register. The bit
711 field is specified by the StartBit and the EndBit. All other bits in the
712 destination PCI configuration register are preserved. The new value of the
713 16-bit register is returned.
715 If Address > 0x0FFFFFFF, then ASSERT().
716 If Address is not aligned on a 16-bit boundary, then ASSERT().
717 If the register specified by Address >= 0x100, then ASSERT().
718 If StartBit is greater than 15, then ASSERT().
719 If EndBit is greater than 15, then ASSERT().
720 If EndBit is less than StartBit, then ASSERT().
722 @param Address 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 Value New value of the bit field.
729 @return The value written back to the PCI configuration register.
734 PciCf8BitFieldWrite16 (
741 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
742 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
743 return IoBitFieldWrite16 (
744 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
752 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
753 writes the result back to the bit field in the 16-bit port.
755 Reads the 16-bit PCI configuration register specified by Address, performs a
756 bitwise OR between the read result and the value specified by
757 OrData, and writes the result to the 16-bit PCI configuration register
758 specified by Address. The value written to the PCI configuration register is
759 returned. This function must guarantee that all PCI read and write operations
760 are serialized. Extra left bits in OrData are stripped.
762 If Address > 0x0FFFFFFF, then ASSERT().
763 If Address is not aligned on a 16-bit boundary, then ASSERT().
764 If the register specified by Address >= 0x100, then ASSERT().
765 If StartBit is greater than 15, then ASSERT().
766 If EndBit is greater than 15, then ASSERT().
767 If EndBit is less than StartBit, then ASSERT().
769 @param Address PCI configuration register to write.
770 @param StartBit The ordinal of the least significant bit in the bit field.
772 @param EndBit The ordinal of the most significant bit in the bit field.
774 @param OrData The value to OR with the PCI configuration register.
776 @return The value written back to the PCI configuration register.
788 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
789 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
790 return IoBitFieldOr16 (
791 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
799 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
800 AND, and writes the result back to the bit field in the 16-bit register.
802 Reads the 16-bit PCI configuration register specified by Address, performs a
803 bitwise AND between the read result and the value specified by AndData, and
804 writes the result to the 16-bit PCI configuration register specified by
805 Address. The value written to the PCI configuration register is returned.
806 This function must guarantee that all PCI read and write operations are
807 serialized. Extra left bits in AndData are stripped.
809 If Address > 0x0FFFFFFF, then ASSERT().
810 If Address is not aligned on a 16-bit boundary, then ASSERT().
811 If the register specified by Address >= 0x100, then ASSERT().
812 If StartBit is greater than 15, then ASSERT().
813 If EndBit is greater than 15, then ASSERT().
814 If EndBit is less than StartBit, then ASSERT().
816 @param Address PCI configuration register to write.
817 @param StartBit The ordinal of the least significant bit in the bit field.
819 @param EndBit The ordinal of the most significant bit in the bit field.
821 @param AndData The value to AND with the PCI configuration register.
823 @return The value written back to the PCI configuration register.
828 PciCf8BitFieldAnd16 (
835 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
836 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
837 return IoBitFieldAnd16 (
838 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
846 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
847 bitwise OR, and writes the result back to the bit field in the
850 Reads the 16-bit PCI configuration register specified by Address, performs a
851 bitwise AND followed by a bitwise OR between the read result and
852 the value specified by AndData, and writes the result to the 16-bit PCI
853 configuration register specified by Address. The value written to the PCI
854 configuration register is returned. This function must guarantee that all PCI
855 read and write operations are serialized. Extra left bits in both AndData and
858 If Address > 0x0FFFFFFF, then ASSERT().
859 If Address is not aligned on a 16-bit boundary, then ASSERT().
860 If the register specified by Address >= 0x100, then ASSERT().
861 If StartBit is greater than 15, then ASSERT().
862 If EndBit is greater than 15, then ASSERT().
863 If EndBit is less than StartBit, then ASSERT().
865 @param Address PCI configuration register to write.
866 @param StartBit The ordinal of the least significant bit in the bit field.
868 @param EndBit The ordinal of the most significant bit in the bit field.
870 @param AndData The value to AND with the PCI configuration register.
871 @param OrData The value to OR with the result of the AND operation.
873 @return The value written back to the PCI configuration register.
878 PciCf8BitFieldAndThenOr16(
886 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
887 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
888 return IoBitFieldAndThenOr16 (
889 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
898 Reads a 32-bit PCI configuration register.
900 Reads and returns the 32-bit PCI configuration register specified by Address.
901 This function must guarantee that all PCI read and write operations are
904 If Address > 0x0FFFFFFF, then ASSERT().
905 If Address is not aligned on a 32-bit boundary, then ASSERT().
906 If the register specified by Address >= 0x100, then ASSERT().
908 @param Address Address that encodes the PCI Bus, Device, Function and
911 @return The read value from the PCI configuration register.
920 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
921 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
922 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
926 Writes a 32-bit PCI configuration register.
928 Writes the 32-bit PCI configuration register specified by Address with the
929 value specified by Value. Value is returned. This function must guarantee
930 that all PCI read and write operations are serialized.
932 If Address > 0x0FFFFFFF, then ASSERT().
933 If Address is not aligned on a 32-bit boundary, then ASSERT().
934 If the register specified by Address >= 0x100, then ASSERT().
936 @param Address Address that encodes the PCI Bus, Device, Function and
938 @param Value The value to write.
940 @return The value written to the PCI configuration register.
950 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
951 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
953 PCI_CONFIGURATION_DATA_PORT
,
959 Performs a bitwise OR of a 32-bit PCI configuration register with
962 Reads the 32-bit PCI configuration register specified by Address, performs a
963 bitwise OR between the read result and the value specified by
964 OrData, and writes the result to the 32-bit PCI configuration register
965 specified by Address. The value written to the PCI configuration register is
966 returned. This function must guarantee that all PCI read and write operations
969 If Address > 0x0FFFFFFF, then ASSERT().
970 If Address is not aligned on a 32-bit boundary, then ASSERT().
971 If the register specified by Address >= 0x100, then ASSERT().
973 @param Address Address that encodes the PCI Bus, Device, Function and
975 @param OrData The value to OR with the PCI configuration register.
977 @return The value written back to the PCI configuration register.
987 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
988 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
990 PCI_CONFIGURATION_DATA_PORT
,
996 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
999 Reads the 32-bit PCI configuration register specified by Address, performs a
1000 bitwise AND between the read result and the value specified by AndData, and
1001 writes the result to the 32-bit PCI configuration register specified by
1002 Address. The value written to the PCI configuration register is returned.
1003 This function must guarantee that all PCI read and write operations are
1006 If Address > 0x0FFFFFFF, then ASSERT().
1007 If Address is not aligned on a 32-bit boundary, then ASSERT().
1008 If the register specified by Address >= 0x100, then ASSERT().
1010 @param Address Address that encodes the PCI Bus, Device, Function and
1012 @param AndData The value to AND with the PCI configuration register.
1014 @return The value written back to the PCI configuration register.
1024 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1025 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1027 PCI_CONFIGURATION_DATA_PORT
,
1033 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1034 value, followed a bitwise OR with another 32-bit value.
1036 Reads the 32-bit PCI configuration register specified by Address, performs a
1037 bitwise AND between the read result and the value specified by AndData,
1038 performs a bitwise OR between the result of the AND operation and
1039 the value specified by OrData, and writes the result to the 32-bit PCI
1040 configuration register specified by Address. The value written to the PCI
1041 configuration register is returned. This function must guarantee that all PCI
1042 read and write operations are serialized.
1044 If Address > 0x0FFFFFFF, then ASSERT().
1045 If Address is not aligned on a 32-bit boundary, then ASSERT().
1046 If the register specified by Address >= 0x100, then ASSERT().
1048 @param Address Address that encodes the PCI Bus, Device, Function and
1050 @param AndData The value to AND with the PCI configuration register.
1051 @param OrData The value to OR with the result of the AND operation.
1053 @return The value written back to the PCI configuration register.
1064 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1065 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1066 return IoAndThenOr32 (
1067 PCI_CONFIGURATION_DATA_PORT
,
1074 Reads a bit field of a PCI configuration register.
1076 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1077 specified by the StartBit and the EndBit. The value of the bit field is
1080 If Address > 0x0FFFFFFF, then ASSERT().
1081 If Address is not aligned on a 32-bit boundary, then ASSERT().
1082 If the register specified by Address >= 0x100, then ASSERT().
1083 If StartBit is greater than 31, then ASSERT().
1084 If EndBit is greater than 31, then ASSERT().
1085 If EndBit is less than StartBit, then ASSERT().
1087 @param Address PCI configuration register to read.
1088 @param StartBit The ordinal of the least significant bit in the bit field.
1090 @param EndBit The ordinal of the most significant bit in the bit field.
1093 @return The value of the bit field read from the PCI configuration register.
1098 PciCf8BitFieldRead32 (
1104 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1105 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1106 return IoBitFieldRead32 (
1107 PCI_CONFIGURATION_DATA_PORT
,
1114 Writes a bit field to a PCI configuration register.
1116 Writes Value to the bit field of the PCI configuration register. The bit
1117 field is specified by the StartBit and the EndBit. All other bits in the
1118 destination PCI configuration register are preserved. The new value of the
1119 32-bit register is returned.
1121 If Address > 0x0FFFFFFF, then ASSERT().
1122 If Address is not aligned on a 32-bit boundary, then ASSERT().
1123 If the register specified by Address >= 0x100, then ASSERT().
1124 If StartBit is greater than 31, then ASSERT().
1125 If EndBit is greater than 31, then ASSERT().
1126 If EndBit is less than StartBit, then ASSERT().
1128 @param Address PCI configuration register to write.
1129 @param StartBit The ordinal of the least significant bit in the bit field.
1131 @param EndBit The ordinal of the most significant bit in the bit field.
1133 @param Value New value of the bit field.
1135 @return The value written back to the PCI configuration register.
1140 PciCf8BitFieldWrite32 (
1147 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1148 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1149 return IoBitFieldWrite32 (
1150 PCI_CONFIGURATION_DATA_PORT
,
1158 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1159 writes the result back to the bit field in the 32-bit port.
1161 Reads the 32-bit PCI configuration register specified by Address, performs a
1162 bitwise OR between the read result and the value specified by
1163 OrData, and writes the result to the 32-bit PCI configuration register
1164 specified by Address. The value written to the PCI configuration register is
1165 returned. This function must guarantee that all PCI read and write operations
1166 are serialized. Extra left bits in OrData are stripped.
1168 If Address > 0x0FFFFFFF, then ASSERT().
1169 If Address is not aligned on a 32-bit boundary, then ASSERT().
1170 If the register specified by Address >= 0x100, then ASSERT().
1171 If StartBit is greater than 31, then ASSERT().
1172 If EndBit is greater than 31, then ASSERT().
1173 If EndBit is less than StartBit, then ASSERT().
1175 @param Address PCI configuration register to write.
1176 @param StartBit The ordinal of the least significant bit in the bit field.
1178 @param EndBit The ordinal of the most significant bit in the bit field.
1180 @param OrData The value to OR with the PCI configuration register.
1182 @return The value written back to the PCI configuration register.
1187 PciCf8BitFieldOr32 (
1194 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1195 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1196 return IoBitFieldOr32 (
1197 PCI_CONFIGURATION_DATA_PORT
,
1205 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1206 AND, and writes the result back to the bit field in the 32-bit register.
1208 Reads the 32-bit PCI configuration register specified by Address, performs a
1209 bitwise AND between the read result and the value specified by AndData, and
1210 writes the result to the 32-bit PCI configuration register specified by
1211 Address. The value written to the PCI configuration register is returned.
1212 This function must guarantee that all PCI read and write operations are
1213 serialized. Extra left bits in AndData are stripped.
1215 If Address > 0x0FFFFFFF, then ASSERT().
1216 If Address is not aligned on a 32-bit boundary, then ASSERT().
1217 If the register specified by Address >= 0x100, then ASSERT().
1218 If StartBit is greater than 31, then ASSERT().
1219 If EndBit is greater than 31, then ASSERT().
1220 If EndBit is less than StartBit, then ASSERT().
1222 @param Address PCI configuration register to write.
1223 @param StartBit The ordinal of the least significant bit in the bit field.
1225 @param EndBit The ordinal of the most significant bit in the bit field.
1227 @param AndData The value to AND with the PCI configuration register.
1229 @return The value written back to the PCI configuration register.
1234 PciCf8BitFieldAnd32 (
1241 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1242 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1243 return IoBitFieldAnd32 (
1244 PCI_CONFIGURATION_DATA_PORT
,
1252 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1253 bitwise OR, and writes the result back to the bit field in the
1256 Reads the 32-bit PCI configuration register specified by Address, performs a
1257 bitwise AND followed by a bitwise OR between the read result and
1258 the value specified by AndData, and writes the result to the 32-bit PCI
1259 configuration register specified by Address. The value written to the PCI
1260 configuration register is returned. This function must guarantee that all PCI
1261 read and write operations are serialized. Extra left bits in both AndData and
1262 OrData are stripped.
1264 If Address > 0x0FFFFFFF, then ASSERT().
1265 If Address is not aligned on a 32-bit boundary, then ASSERT().
1266 If the register specified by Address >= 0x100, then ASSERT().
1267 If StartBit is greater than 31, then ASSERT().
1268 If EndBit is greater than 31, then ASSERT().
1269 If EndBit is less than StartBit, then ASSERT().
1271 @param Address PCI configuration register to write.
1272 @param StartBit The ordinal of the least significant bit in the bit field.
1274 @param EndBit The ordinal of the most significant bit in the bit field.
1276 @param AndData The value to AND with the PCI configuration register.
1277 @param OrData The value to OR with the result of the AND operation.
1279 @return The value written back to the PCI configuration register.
1284 PciCf8BitFieldAndThenOr32(
1292 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1293 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1294 return IoBitFieldAndThenOr32 (
1295 PCI_CONFIGURATION_DATA_PORT
,
1304 Reads a range of PCI configuration registers into a caller supplied buffer.
1306 Reads the range of PCI configuration registers specified by StartAddress and
1307 Size into the buffer specified by Buffer. This function only allows the PCI
1308 configuration registers from a single PCI function to be read. Size is
1309 returned. When possible 32-bit PCI configuration read cycles are used to read
1310 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1311 and 16-bit PCI configuration read cycles may be used at the beginning and the
1314 If StartAddress > 0x0FFFFFFF, then ASSERT().
1315 If the register specified by StartAddress >= 0x100, then ASSERT().
1316 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1317 If Size > 0 and Buffer is NULL, then ASSERT().
1319 @param StartAddress Starting address that encodes the PCI Bus, Device,
1320 Function and Register.
1321 @param Size Size in bytes of the transfer.
1322 @param Buffer Pointer to a buffer receiving the data read.
1324 @return Size read from StartAddress.
1330 IN UINTN StartAddress
,
1337 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1338 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1344 ASSERT (Buffer
!= NULL
);
1347 // Save Size for return
1351 if ((StartAddress
& 1) != 0) {
1353 // Read a byte if StartAddress is byte aligned
1355 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1356 StartAddress
+= sizeof (UINT8
);
1357 Size
-= sizeof (UINT8
);
1358 Buffer
= (UINT8
*)Buffer
+ 1;
1361 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1363 // Read a word if StartAddress is word aligned
1365 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1367 StartAddress
+= sizeof (UINT16
);
1368 Size
-= sizeof (UINT16
);
1369 Buffer
= (UINT16
*)Buffer
+ 1;
1372 while (Size
>= sizeof (UINT32
)) {
1374 // Read as many double words as possible
1376 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
) PciCf8Read32 (StartAddress
));
1377 StartAddress
+= sizeof (UINT32
);
1378 Size
-= sizeof (UINT32
);
1379 Buffer
= (UINT32
*)Buffer
+ 1;
1382 if (Size
>= sizeof (UINT16
)) {
1384 // Read the last remaining word if exist
1386 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1387 StartAddress
+= sizeof (UINT16
);
1388 Size
-= sizeof (UINT16
);
1389 Buffer
= (UINT16
*)Buffer
+ 1;
1392 if (Size
>= sizeof (UINT8
)) {
1394 // Read the last remaining byte if exist
1396 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1403 Copies the data in a caller supplied buffer to a specified range of PCI
1404 configuration space.
1406 Writes the range of PCI configuration registers specified by StartAddress and
1407 Size from the buffer specified by Buffer. This function only allows the PCI
1408 configuration registers from a single PCI function to be written. Size is
1409 returned. When possible 32-bit PCI configuration write cycles are used to
1410 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1411 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1412 and the end of the range.
1414 If StartAddress > 0x0FFFFFFF, then ASSERT().
1415 If the register specified by StartAddress >= 0x100, then ASSERT().
1416 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1417 If Size > 0 and Buffer is NULL, then ASSERT().
1419 @param StartAddress Starting address that encodes the PCI Bus, Device,
1420 Function and Register.
1421 @param Size Size in bytes of the transfer.
1422 @param Buffer Pointer to a buffer containing the data to write.
1424 @return Size written to StartAddress.
1430 IN UINTN StartAddress
,
1437 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1438 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1444 ASSERT (Buffer
!= NULL
);
1447 // Save Size for return
1451 if ((StartAddress
& 1) != 0) {
1453 // Write a byte if StartAddress is byte aligned
1455 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1456 StartAddress
+= sizeof (UINT8
);
1457 Size
-= sizeof (UINT8
);
1458 Buffer
= (UINT8
*)Buffer
+ 1;
1461 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1463 // Write a word if StartAddress is word aligned
1465 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1466 StartAddress
+= sizeof (UINT16
);
1467 Size
-= sizeof (UINT16
);
1468 Buffer
= (UINT16
*)Buffer
+ 1;
1471 while (Size
>= sizeof (UINT32
)) {
1473 // Write as many double words as possible
1475 PciCf8Write32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1476 StartAddress
+= sizeof (UINT32
);
1477 Size
-= sizeof (UINT32
);
1478 Buffer
= (UINT32
*)Buffer
+ 1;
1481 if (Size
>= sizeof (UINT16
)) {
1483 // Write the last remaining word if exist
1485 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1486 StartAddress
+= sizeof (UINT16
);
1487 Size
-= sizeof (UINT16
);
1488 Buffer
= (UINT16
*)Buffer
+ 1;
1491 if (Size
>= sizeof (UINT8
)) {
1493 // Write the last remaining byte if exist
1495 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);