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 - 2008, 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().
72 @param Address Address that encodes the PCI Bus, Device, Function and
75 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
76 @retval RETURN_UNSUPPORTED An attempt was made to call this function
77 after ExitBootServices().
78 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
79 at runtime could not be mapped.
80 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
81 complete the registration.
86 PciCf8RegisterForRuntimeAccess (
90 return RETURN_SUCCESS
;
94 Reads an 8-bit PCI configuration register.
96 Reads and returns the 8-bit PCI configuration register specified by Address.
97 This function must guarantee that all PCI read and write operations are
100 If Address > 0x0FFFFFFF, then ASSERT().
101 If the register specified by Address >= 0x100, then ASSERT().
103 @param Address Address that encodes the PCI Bus, Device, Function and
106 @return The read value from the PCI configuration register.
115 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
116 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
117 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
121 Writes an 8-bit PCI configuration register.
123 Writes the 8-bit PCI configuration register specified by Address with the
124 value specified by Value. Value is returned. This function must guarantee
125 that all PCI read and write operations are serialized.
127 If Address > 0x0FFFFFFF, then ASSERT().
128 If the register specified by Address >= 0x100, then ASSERT().
130 @param Address Address that encodes the PCI Bus, Device, Function and
132 @param Value The value to write.
134 @return The value written to the PCI configuration register.
144 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
145 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
147 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
153 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
156 Reads the 8-bit PCI configuration register specified by Address, performs a
157 bitwise inclusive OR between the read result and the value specified by
158 OrData, and writes the result to the 8-bit PCI configuration register
159 specified by Address. The value written to the PCI configuration register is
160 returned. This function must guarantee that all PCI read and write operations
163 If Address > 0x0FFFFFFF, then ASSERT().
164 If the register specified by Address >= 0x100, then ASSERT().
166 @param Address Address that encodes the PCI Bus, Device, Function and
168 @param OrData The value to OR with the PCI configuration register.
170 @return The value written back to the PCI configuration register.
180 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
181 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
183 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
189 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
192 Reads the 8-bit PCI configuration register specified by Address, performs a
193 bitwise AND between the read result and the value specified by AndData, and
194 writes the result to the 8-bit PCI configuration register specified by
195 Address. The value written to the PCI configuration register is returned.
196 This function must guarantee that all PCI read and write operations are
199 If Address > 0x0FFFFFFF, then ASSERT().
200 If the register specified by Address >= 0x100, then ASSERT().
202 @param Address Address that encodes the PCI Bus, Device, Function and
204 @param AndData The value to AND with the PCI configuration register.
206 @return The value written back to the PCI configuration register.
216 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
217 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
219 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
225 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
226 value, followed a bitwise inclusive OR with another 8-bit value.
228 Reads the 8-bit PCI configuration register specified by Address, performs a
229 bitwise AND between the read result and the value specified by AndData,
230 performs a bitwise inclusive OR between the result of the AND operation and
231 the value specified by OrData, and writes the result to the 8-bit PCI
232 configuration register specified by Address. The value written to the PCI
233 configuration register is returned. This function must guarantee that all PCI
234 read and write operations are serialized.
236 If Address > 0x0FFFFFFF, then ASSERT().
237 If the register specified by Address >= 0x100, then ASSERT().
239 @param Address Address that encodes the PCI Bus, Device, Function and
241 @param AndData The value to AND with the PCI configuration register.
242 @param OrData The value to OR with the result of the AND operation.
244 @return The value written back to the PCI configuration register.
255 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
256 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
257 return IoAndThenOr8 (
258 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
265 Reads a bit field of a PCI configuration register.
267 Reads the bit field in an 8-bit PCI configuration register. The bit field is
268 specified by the StartBit and the EndBit. The value of the bit field is
271 If Address > 0x0FFFFFFF, then ASSERT().
272 If the register specified by Address >= 0x100, then ASSERT().
273 If StartBit is greater than 7, then ASSERT().
274 If EndBit is greater than 7, then ASSERT().
275 If EndBit is less than StartBit, then ASSERT().
277 @param Address PCI configuration register to read.
278 @param StartBit The ordinal of the least significant bit in the bit field.
280 @param EndBit The ordinal of the most significant bit in the bit field.
283 @return The value of the bit field read from the PCI configuration register.
288 PciCf8BitFieldRead8 (
294 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
295 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
296 return IoBitFieldRead8 (
297 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
304 Writes a bit field to a PCI configuration register.
306 Writes Value to the bit field of the PCI configuration register. The bit
307 field is specified by the StartBit and the EndBit. All other bits in the
308 destination PCI configuration register are preserved. The new value of the
309 8-bit register is returned.
311 If Address > 0x0FFFFFFF, then ASSERT().
312 If the register specified by Address >= 0x100, then ASSERT().
313 If StartBit is greater than 7, then ASSERT().
314 If EndBit is greater than 7, then ASSERT().
315 If EndBit is less than StartBit, then ASSERT().
317 @param Address PCI configuration register to write.
318 @param StartBit The ordinal of the least significant bit in the bit field.
320 @param EndBit The ordinal of the most significant bit in the bit field.
322 @param Value New value of the bit field.
324 @return The value written back to the PCI configuration register.
329 PciCf8BitFieldWrite8 (
336 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
337 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
338 return IoBitFieldWrite8 (
339 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
347 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
348 writes the result back to the bit field in the 8-bit port.
350 Reads the 8-bit PCI configuration register specified by Address, performs a
351 bitwise inclusive OR between the read result and the value specified by
352 OrData, and writes the result to the 8-bit PCI configuration register
353 specified by Address. The value written to the PCI configuration register is
354 returned. This function must guarantee that all PCI read and write operations
355 are serialized. Extra left bits in OrData are stripped.
357 If Address > 0x0FFFFFFF, then ASSERT().
358 If the register specified by Address >= 0x100, then ASSERT().
359 If StartBit is greater than 7, then ASSERT().
360 If EndBit is greater than 7, then ASSERT().
361 If EndBit is less than StartBit, then ASSERT().
363 @param Address PCI configuration register to write.
364 @param StartBit The ordinal of the least significant bit in the bit field.
366 @param EndBit The ordinal of the most significant bit in the bit field.
368 @param OrData The value to OR with the PCI configuration register.
370 @return The value written back to the PCI configuration register.
382 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
383 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
384 return IoBitFieldOr8 (
385 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
393 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
394 AND, and writes the result back to the bit field in the 8-bit register.
396 Reads the 8-bit PCI configuration register specified by Address, performs a
397 bitwise AND between the read result and the value specified by AndData, and
398 writes the result to the 8-bit PCI configuration register specified by
399 Address. The value written to the PCI configuration register is returned.
400 This function must guarantee that all PCI read and write operations are
401 serialized. Extra left bits in AndData are stripped.
403 If Address > 0x0FFFFFFF, then ASSERT().
404 If the register specified by Address >= 0x100, then ASSERT().
405 If StartBit is greater than 7, then ASSERT().
406 If EndBit is greater than 7, then ASSERT().
407 If EndBit is less than StartBit, then ASSERT().
409 @param Address PCI configuration register to write.
410 @param StartBit The ordinal of the least significant bit in the bit field.
412 @param EndBit The ordinal of the most significant bit in the bit field.
414 @param AndData The value to AND with the PCI configuration register.
416 @return The value written back to the PCI configuration register.
428 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
429 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
430 return IoBitFieldAnd8 (
431 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
439 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
440 bitwise inclusive OR, and writes the result back to the bit field in the
443 Reads the 8-bit PCI configuration register specified by Address, performs a
444 bitwise AND followed by a bitwise inclusive OR between the read result and
445 the value specified by AndData, and writes the result to the 8-bit PCI
446 configuration register specified by Address. The value written to the PCI
447 configuration register is returned. This function must guarantee that all PCI
448 read and write operations are serialized. Extra left bits in both AndData and
451 If Address > 0x0FFFFFFF, then ASSERT().
452 If the register specified by Address >= 0x100, then ASSERT().
453 If StartBit is greater than 7, then ASSERT().
454 If EndBit is greater than 7, then ASSERT().
455 If EndBit is less than StartBit, then ASSERT().
457 @param Address PCI configuration register to write.
458 @param StartBit The ordinal of the least significant bit in the bit field.
460 @param EndBit The ordinal of the most significant bit in the bit field.
462 @param AndData The value to AND with the PCI configuration register.
463 @param OrData The value to OR with the result of the AND operation.
465 @return The value written back to the PCI configuration register.
470 PciCf8BitFieldAndThenOr8(
478 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
479 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
480 return IoBitFieldAndThenOr8 (
481 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
490 Reads a 16-bit PCI configuration register.
492 Reads and returns the 16-bit PCI configuration register specified by Address.
493 This function must guarantee that all PCI read and write operations are
496 If Address > 0x0FFFFFFF, then ASSERT().
497 If Address is not aligned on a 16-bit boundary, then ASSERT().
498 If the register specified by Address >= 0x100, then ASSERT().
500 @param Address Address that encodes the PCI Bus, Device, Function and
503 @return The read value from the PCI configuration register.
512 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
513 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
514 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
518 Writes a 16-bit PCI configuration register.
520 Writes the 16-bit PCI configuration register specified by Address with the
521 value specified by Value. Value is returned. This function must guarantee
522 that all PCI read and write operations are serialized.
524 If Address > 0x0FFFFFFF, then ASSERT().
525 If Address is not aligned on a 16-bit boundary, then ASSERT().
526 If the register specified by Address >= 0x100, then ASSERT().
528 @param Address Address that encodes the PCI Bus, Device, Function and
530 @param Value The value to write.
532 @return The value written to the PCI configuration register.
542 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
543 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
545 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
551 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
554 Reads the 16-bit PCI configuration register specified by Address, performs a
555 bitwise inclusive OR between the read result and the value specified by
556 OrData, and writes the result to the 16-bit PCI configuration register
557 specified by Address. The value written to the PCI configuration register is
558 returned. This function must guarantee that all PCI read and write operations
561 If Address > 0x0FFFFFFF, then ASSERT().
562 If Address is not aligned on a 16-bit boundary, then ASSERT().
563 If the register specified by Address >= 0x100, then ASSERT().
565 @param Address Address that encodes the PCI Bus, Device, Function and
567 @param OrData The value to OR with the PCI configuration register.
569 @return The value written back to the PCI configuration register.
579 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
580 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
582 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
588 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
591 Reads the 16-bit PCI configuration register specified by Address, performs a
592 bitwise AND between the read result and the value specified by AndData, and
593 writes the result to the 16-bit PCI configuration register specified by
594 Address. The value written to the PCI configuration register is returned.
595 This function must guarantee that all PCI read and write operations are
598 If Address > 0x0FFFFFFF, then ASSERT().
599 If Address is not aligned on a 16-bit boundary, then ASSERT().
600 If the register specified by Address >= 0x100, then ASSERT().
602 @param Address Address that encodes the PCI Bus, Device, Function and
604 @param AndData The value to AND with the PCI configuration register.
606 @return The value written back to the PCI configuration register.
616 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
617 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
619 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
625 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
626 value, followed a bitwise inclusive OR with another 16-bit value.
628 Reads the 16-bit PCI configuration register specified by Address, performs a
629 bitwise AND between the read result and the value specified by AndData,
630 performs a bitwise inclusive OR between the result of the AND operation and
631 the value specified by OrData, and writes the result to the 16-bit PCI
632 configuration register specified by Address. The value written to the PCI
633 configuration register is returned. This function must guarantee that all PCI
634 read and write operations are serialized.
636 If Address > 0x0FFFFFFF, then ASSERT().
637 If Address is not aligned on a 16-bit boundary, then ASSERT().
638 If the register specified by Address >= 0x100, then ASSERT().
640 @param Address Address that encodes the PCI Bus, Device, Function and
642 @param AndData The value to AND with the PCI configuration register.
643 @param OrData The value to OR with the result of the AND operation.
645 @return The value written back to the PCI configuration register.
656 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
657 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
658 return IoAndThenOr16 (
659 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
666 Reads a bit field of a PCI configuration register.
668 Reads the bit field in a 16-bit PCI configuration register. The bit field is
669 specified by the StartBit and the EndBit. The value of the bit field is
672 If Address > 0x0FFFFFFF, then ASSERT().
673 If Address is not aligned on a 16-bit boundary, then ASSERT().
674 If the register specified by Address >= 0x100, then ASSERT().
675 If StartBit is greater than 15, then ASSERT().
676 If EndBit is greater than 15, then ASSERT().
677 If EndBit is less than StartBit, then ASSERT().
679 @param Address PCI configuration register to read.
680 @param StartBit The ordinal of the least significant bit in the bit field.
682 @param EndBit The ordinal of the most significant bit in the bit field.
685 @return The value of the bit field read from the PCI configuration register.
690 PciCf8BitFieldRead16 (
696 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
697 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
698 return IoBitFieldRead16 (
699 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
706 Writes a bit field to a PCI configuration register.
708 Writes Value to the bit field of the PCI configuration register. The bit
709 field is specified by the StartBit and the EndBit. All other bits in the
710 destination PCI configuration register are preserved. The new value of the
711 16-bit register is returned.
713 If Address > 0x0FFFFFFF, then ASSERT().
714 If Address is not aligned on a 16-bit boundary, then ASSERT().
715 If the register specified by Address >= 0x100, 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().
720 @param Address PCI configuration register to write.
721 @param StartBit The ordinal of the least significant bit in the bit field.
723 @param EndBit The ordinal of the most significant bit in the bit field.
725 @param Value New value of the bit field.
727 @return The value written back to the PCI configuration register.
732 PciCf8BitFieldWrite16 (
739 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
740 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
741 return IoBitFieldWrite16 (
742 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
750 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
751 writes the result back to the bit field in the 16-bit port.
753 Reads the 16-bit PCI configuration register specified by Address, performs a
754 bitwise inclusive OR between the read result and the value specified by
755 OrData, and writes the result to the 16-bit PCI configuration register
756 specified by Address. The value written to the PCI configuration register is
757 returned. This function must guarantee that all PCI read and write operations
758 are serialized. Extra left bits in OrData are stripped.
760 If Address > 0x0FFFFFFF, then ASSERT().
761 If Address is not aligned on a 16-bit boundary, then ASSERT().
762 If the register specified by Address >= 0x100, then ASSERT().
763 If StartBit is greater than 15, then ASSERT().
764 If EndBit is greater than 15, then ASSERT().
765 If EndBit is less than StartBit, then ASSERT().
767 @param Address PCI configuration register to write.
768 @param StartBit The ordinal of the least significant bit in the bit field.
770 @param EndBit The ordinal of the most significant bit in the bit field.
772 @param OrData The value to OR with the PCI configuration register.
774 @return The value written back to the PCI configuration register.
786 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
787 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
788 return IoBitFieldOr16 (
789 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
797 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
798 AND, and writes the result back to the bit field in the 16-bit register.
800 Reads the 16-bit PCI configuration register specified by Address, performs a
801 bitwise AND between the read result and the value specified by AndData, and
802 writes the result to the 16-bit PCI configuration register specified by
803 Address. The value written to the PCI configuration register is returned.
804 This function must guarantee that all PCI read and write operations are
805 serialized. Extra left bits in AndData are stripped.
807 If Address > 0x0FFFFFFF, then ASSERT().
808 If Address is not aligned on a 16-bit boundary, then ASSERT().
809 If the register specified by Address >= 0x100, then ASSERT().
810 If StartBit is greater than 15, then ASSERT().
811 If EndBit is greater than 15, then ASSERT().
812 If EndBit is less than StartBit, then ASSERT().
814 @param Address PCI configuration register to write.
815 @param StartBit The ordinal of the least significant bit in the bit field.
817 @param EndBit The ordinal of the most significant bit in the bit field.
819 @param AndData The value to AND with the PCI configuration register.
821 @return The value written back to the PCI configuration register.
826 PciCf8BitFieldAnd16 (
833 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
834 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
835 return IoBitFieldAnd16 (
836 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
844 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
845 bitwise inclusive OR, and writes the result back to the bit field in the
848 Reads the 16-bit PCI configuration register specified by Address, performs a
849 bitwise AND followed by a bitwise inclusive OR between the read result and
850 the value specified by AndData, and writes the result to the 16-bit PCI
851 configuration register specified by Address. The value written to the PCI
852 configuration register is returned. This function must guarantee that all PCI
853 read and write operations are serialized. Extra left bits in both AndData and
856 If Address > 0x0FFFFFFF, then ASSERT().
857 If Address is not aligned on a 16-bit boundary, then ASSERT().
858 If the register specified by Address >= 0x100, then ASSERT().
859 If StartBit is greater than 15, then ASSERT().
860 If EndBit is greater than 15, then ASSERT().
861 If EndBit is less than StartBit, then ASSERT().
863 @param Address PCI configuration register to write.
864 @param StartBit The ordinal of the least significant bit in the bit field.
866 @param EndBit The ordinal of the most significant bit in the bit field.
868 @param AndData The value to AND with the PCI configuration register.
869 @param OrData The value to OR with the result of the AND operation.
871 @return The value written back to the PCI configuration register.
876 PciCf8BitFieldAndThenOr16(
884 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
885 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
886 return IoBitFieldAndThenOr16 (
887 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
896 Reads a 32-bit PCI configuration register.
898 Reads and returns the 32-bit PCI configuration register specified by Address.
899 This function must guarantee that all PCI read and write operations are
902 If Address > 0x0FFFFFFF, then ASSERT().
903 If Address is not aligned on a 32-bit boundary, then ASSERT().
904 If the register specified by Address >= 0x100, then ASSERT().
906 @param Address Address that encodes the PCI Bus, Device, Function and
909 @return The read value from the PCI configuration register.
918 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
919 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
920 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
924 Writes a 32-bit PCI configuration register.
926 Writes the 32-bit PCI configuration register specified by Address with the
927 value specified by Value. Value is returned. This function must guarantee
928 that all PCI read and write operations are serialized.
930 If Address > 0x0FFFFFFF, then ASSERT().
931 If Address is not aligned on a 32-bit boundary, then ASSERT().
932 If the register specified by Address >= 0x100, then ASSERT().
934 @param Address Address that encodes the PCI Bus, Device, Function and
936 @param Value The value to write.
938 @return The value written to the PCI configuration register.
948 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
949 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
951 PCI_CONFIGURATION_DATA_PORT
,
957 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
960 Reads the 32-bit PCI configuration register specified by Address, performs a
961 bitwise inclusive OR between the read result and the value specified by
962 OrData, and writes the result to the 32-bit PCI configuration register
963 specified by Address. The value written to the PCI configuration register is
964 returned. This function must guarantee that all PCI read and write operations
967 If Address > 0x0FFFFFFF, then ASSERT().
968 If Address is not aligned on a 32-bit boundary, then ASSERT().
969 If the register specified by Address >= 0x100, then ASSERT().
971 @param Address Address that encodes the PCI Bus, Device, Function and
973 @param OrData The value to OR with the PCI configuration register.
975 @return The value written back to the PCI configuration register.
985 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
986 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
988 PCI_CONFIGURATION_DATA_PORT
,
994 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
997 Reads the 32-bit PCI configuration register specified by Address, performs a
998 bitwise AND between the read result and the value specified by AndData, and
999 writes the result to the 32-bit PCI configuration register specified by
1000 Address. The value written to the PCI configuration register is returned.
1001 This function must guarantee that all PCI read and write operations are
1004 If Address > 0x0FFFFFFF, then ASSERT().
1005 If Address is not aligned on a 32-bit boundary, then ASSERT().
1006 If the register specified by Address >= 0x100, then ASSERT().
1008 @param Address Address that encodes the PCI Bus, Device, Function and
1010 @param AndData The value to AND with the PCI configuration register.
1012 @return The value written back to the PCI configuration register.
1022 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1023 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1025 PCI_CONFIGURATION_DATA_PORT
,
1031 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1032 value, followed a bitwise inclusive OR with another 32-bit value.
1034 Reads the 32-bit PCI configuration register specified by Address, performs a
1035 bitwise AND between the read result and the value specified by AndData,
1036 performs a bitwise inclusive OR between the result of the AND operation and
1037 the value specified by OrData, and writes the result to the 32-bit PCI
1038 configuration register specified by Address. The value written to the PCI
1039 configuration register is returned. This function must guarantee that all PCI
1040 read and write operations are serialized.
1042 If Address > 0x0FFFFFFF, then ASSERT().
1043 If Address is not aligned on a 32-bit boundary, then ASSERT().
1044 If the register specified by Address >= 0x100, then ASSERT().
1046 @param Address Address that encodes the PCI Bus, Device, Function and
1048 @param AndData The value to AND with the PCI configuration register.
1049 @param OrData The value to OR with the result of the AND operation.
1051 @return The value written back to the PCI configuration register.
1062 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1063 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1064 return IoAndThenOr32 (
1065 PCI_CONFIGURATION_DATA_PORT
,
1072 Reads a bit field of a PCI configuration register.
1074 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1075 specified by the StartBit and the EndBit. The value of the bit field is
1078 If Address > 0x0FFFFFFF, then ASSERT().
1079 If Address is not aligned on a 32-bit boundary, then ASSERT().
1080 If the register specified by Address >= 0x100, then ASSERT().
1081 If StartBit is greater than 31, then ASSERT().
1082 If EndBit is greater than 31, then ASSERT().
1083 If EndBit is less than StartBit, then ASSERT().
1085 @param Address PCI configuration register to read.
1086 @param StartBit The ordinal of the least significant bit in the bit field.
1088 @param EndBit The ordinal of the most significant bit in the bit field.
1091 @return The value of the bit field read from the PCI configuration register.
1096 PciCf8BitFieldRead32 (
1102 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1103 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1104 return IoBitFieldRead32 (
1105 PCI_CONFIGURATION_DATA_PORT
,
1112 Writes a bit field to a PCI configuration register.
1114 Writes Value to the bit field of the PCI configuration register. The bit
1115 field is specified by the StartBit and the EndBit. All other bits in the
1116 destination PCI configuration register are preserved. The new value of the
1117 32-bit register is returned.
1119 If Address > 0x0FFFFFFF, then ASSERT().
1120 If Address is not aligned on a 32-bit boundary, then ASSERT().
1121 If the register specified by Address >= 0x100, then ASSERT().
1122 If StartBit is greater than 31, then ASSERT().
1123 If EndBit is greater than 31, then ASSERT().
1124 If EndBit is less than StartBit, then ASSERT().
1126 @param Address PCI configuration register to write.
1127 @param StartBit The ordinal of the least significant bit in the bit field.
1129 @param EndBit The ordinal of the most significant bit in the bit field.
1131 @param Value New value of the bit field.
1133 @return The value written back to the PCI configuration register.
1138 PciCf8BitFieldWrite32 (
1145 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1146 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1147 return IoBitFieldWrite32 (
1148 PCI_CONFIGURATION_DATA_PORT
,
1156 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1157 writes the result back to the bit field in the 32-bit port.
1159 Reads the 32-bit PCI configuration register specified by Address, performs a
1160 bitwise inclusive OR between the read result and the value specified by
1161 OrData, and writes the result to the 32-bit PCI configuration register
1162 specified by Address. The value written to the PCI configuration register is
1163 returned. This function must guarantee that all PCI read and write operations
1164 are serialized. Extra left bits in OrData are stripped.
1166 If Address > 0x0FFFFFFF, then ASSERT().
1167 If Address is not aligned on a 32-bit boundary, then ASSERT().
1168 If the register specified by Address >= 0x100, then ASSERT().
1169 If StartBit is greater than 31, then ASSERT().
1170 If EndBit is greater than 31, then ASSERT().
1171 If EndBit is less than StartBit, then ASSERT().
1173 @param Address PCI configuration register to write.
1174 @param StartBit The ordinal of the least significant bit in the bit field.
1176 @param EndBit The ordinal of the most significant bit in the bit field.
1178 @param OrData The value to OR with the PCI configuration register.
1180 @return The value written back to the PCI configuration register.
1185 PciCf8BitFieldOr32 (
1192 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1193 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1194 return IoBitFieldOr32 (
1195 PCI_CONFIGURATION_DATA_PORT
,
1203 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1204 AND, and writes the result back to the bit field in the 32-bit register.
1206 Reads the 32-bit PCI configuration register specified by Address, performs a
1207 bitwise AND between the read result and the value specified by AndData, and
1208 writes the result to the 32-bit PCI configuration register specified by
1209 Address. The value written to the PCI configuration register is returned.
1210 This function must guarantee that all PCI read and write operations are
1211 serialized. Extra left bits in AndData are stripped.
1213 If Address > 0x0FFFFFFF, then ASSERT().
1214 If Address is not aligned on a 32-bit boundary, then ASSERT().
1215 If the register specified by Address >= 0x100, then ASSERT().
1216 If StartBit is greater than 31, then ASSERT().
1217 If EndBit is greater than 31, then ASSERT().
1218 If EndBit is less than StartBit, then ASSERT().
1220 @param Address PCI configuration register to write.
1221 @param StartBit The ordinal of the least significant bit in the bit field.
1223 @param EndBit The ordinal of the most significant bit in the bit field.
1225 @param AndData The value to AND with the PCI configuration register.
1227 @return The value written back to the PCI configuration register.
1232 PciCf8BitFieldAnd32 (
1239 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1240 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1241 return IoBitFieldAnd32 (
1242 PCI_CONFIGURATION_DATA_PORT
,
1250 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1251 bitwise inclusive OR, and writes the result back to the bit field in the
1254 Reads the 32-bit PCI configuration register specified by Address, performs a
1255 bitwise AND followed by a bitwise inclusive OR between the read result and
1256 the value specified by AndData, and writes the result to the 32-bit PCI
1257 configuration register specified by Address. The value written to the PCI
1258 configuration register is returned. This function must guarantee that all PCI
1259 read and write operations are serialized. Extra left bits in both AndData and
1260 OrData are stripped.
1262 If Address > 0x0FFFFFFF, then ASSERT().
1263 If Address is not aligned on a 32-bit boundary, then ASSERT().
1264 If the register specified by Address >= 0x100, then ASSERT().
1265 If StartBit is greater than 31, then ASSERT().
1266 If EndBit is greater than 31, then ASSERT().
1267 If EndBit is less than StartBit, then ASSERT().
1269 @param Address PCI configuration register to write.
1270 @param StartBit The ordinal of the least significant bit in the bit field.
1272 @param EndBit The ordinal of the most significant bit in the bit field.
1274 @param AndData The value to AND with the PCI configuration register.
1275 @param OrData The value to OR with the result of the AND operation.
1277 @return The value written back to the PCI configuration register.
1282 PciCf8BitFieldAndThenOr32(
1290 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1291 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1292 return IoBitFieldAndThenOr32 (
1293 PCI_CONFIGURATION_DATA_PORT
,
1302 Reads a range of PCI configuration registers into a caller supplied buffer.
1304 Reads the range of PCI configuration registers specified by StartAddress and
1305 Size into the buffer specified by Buffer. This function only allows the PCI
1306 configuration registers from a single PCI function to be read. Size is
1307 returned. When possible 32-bit PCI configuration read cycles are used to read
1308 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1309 and 16-bit PCI configuration read cycles may be used at the beginning and the
1312 If StartAddress > 0x0FFFFFFF, then ASSERT().
1313 If the register specified by StartAddress >= 0x100, then ASSERT().
1314 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1315 If Size > 0 and Buffer is NULL, then ASSERT().
1317 @param StartAddress Starting address that encodes the PCI Bus, Device,
1318 Function and Register.
1319 @param Size Size in bytes of the transfer.
1320 @param Buffer Pointer to a buffer receiving the data read.
1322 @return Size read from StartAddress.
1328 IN UINTN StartAddress
,
1335 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1336 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1342 ASSERT (Buffer
!= NULL
);
1345 // Save Size for return
1349 if ((StartAddress
& 1) != 0) {
1351 // Read a byte if StartAddress is byte aligned
1353 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1354 StartAddress
+= sizeof (UINT8
);
1355 Size
-= sizeof (UINT8
);
1356 Buffer
= (UINT8
*)Buffer
+ 1;
1359 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1361 // Read a word if StartAddress is word aligned
1363 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1365 StartAddress
+= sizeof (UINT16
);
1366 Size
-= sizeof (UINT16
);
1367 Buffer
= (UINT16
*)Buffer
+ 1;
1370 while (Size
>= sizeof (UINT32
)) {
1372 // Read as many double words as possible
1374 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
) PciCf8Read32 (StartAddress
));
1375 StartAddress
+= sizeof (UINT32
);
1376 Size
-= sizeof (UINT32
);
1377 Buffer
= (UINT32
*)Buffer
+ 1;
1380 if (Size
>= sizeof (UINT16
)) {
1382 // Read the last remaining word if exist
1384 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1385 StartAddress
+= sizeof (UINT16
);
1386 Size
-= sizeof (UINT16
);
1387 Buffer
= (UINT16
*)Buffer
+ 1;
1390 if (Size
>= sizeof (UINT8
)) {
1392 // Read the last remaining byte if exist
1394 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1401 Copies the data in a caller supplied buffer to a specified range of PCI
1402 configuration space.
1404 Writes the range of PCI configuration registers specified by StartAddress and
1405 Size from the buffer specified by Buffer. This function only allows the PCI
1406 configuration registers from a single PCI function to be written. Size is
1407 returned. When possible 32-bit PCI configuration write cycles are used to
1408 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1409 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1410 and the end of the range.
1412 If StartAddress > 0x0FFFFFFF, then ASSERT().
1413 If the register specified by StartAddress >= 0x100, then ASSERT().
1414 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1415 If Size > 0 and Buffer is NULL, then ASSERT().
1417 @param StartAddress Starting address that encodes the PCI Bus, Device,
1418 Function and Register.
1419 @param Size Size in bytes of the transfer.
1420 @param Buffer Pointer to a buffer containing the data to write.
1422 @return Size written to StartAddress.
1428 IN UINTN StartAddress
,
1435 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1436 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1442 ASSERT (Buffer
!= NULL
);
1445 // Save Size for return
1449 if ((StartAddress
& 1) != 0) {
1451 // Write a byte if StartAddress is byte aligned
1453 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1454 StartAddress
+= sizeof (UINT8
);
1455 Size
-= sizeof (UINT8
);
1456 Buffer
= (UINT8
*)Buffer
+ 1;
1459 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1461 // Write a word if StartAddress is word aligned
1463 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1464 StartAddress
+= sizeof (UINT16
);
1465 Size
-= sizeof (UINT16
);
1466 Buffer
= (UINT16
*)Buffer
+ 1;
1469 while (Size
>= sizeof (UINT32
)) {
1471 // Write as many double words as possible
1473 PciCf8Write32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1474 StartAddress
+= sizeof (UINT32
);
1475 Size
-= sizeof (UINT32
);
1476 Buffer
= (UINT32
*)Buffer
+ 1;
1479 if (Size
>= sizeof (UINT16
)) {
1481 // Write the last remaining word if exist
1483 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1484 StartAddress
+= sizeof (UINT16
);
1485 Size
-= sizeof (UINT16
);
1486 Buffer
= (UINT16
*)Buffer
+ 1;
1489 if (Size
>= sizeof (UINT8
)) {
1491 // Write the last remaining byte if exist
1493 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);