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 Register a PCI device so PCI configuration registers may be accessed after
65 SetVirtualAddressMap().
67 If Address > 0x0FFFFFFF, then ASSERT().
69 @param Address Address that encodes the PCI Bus, Device, Function and
72 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
73 @retval RETURN_UNSUPPORTED An attempt was made to call this function
74 after ExitBootServices().
75 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
76 at runtime could not be mapped.
77 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
78 complete the registration.
83 PciCf8RegisterForRuntimeAccess (
87 return RETURN_SUCCESS
;
91 Reads an 8-bit PCI configuration register.
93 Reads and returns the 8-bit PCI configuration register specified by Address.
94 This function must guarantee that all PCI read and write operations are
97 If Address > 0x0FFFFFFF, then ASSERT().
98 If the register specified by Address >= 0x100, then ASSERT().
100 @param Address Address that encodes the PCI Bus, Device, Function and
103 @return The read value from the PCI configuration register.
112 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
113 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
114 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
118 Writes an 8-bit PCI configuration register.
120 Writes the 8-bit PCI configuration register specified by Address with the
121 value specified by Value. Value is returned. This function must guarantee
122 that all PCI read and write operations are serialized.
124 If Address > 0x0FFFFFFF, then ASSERT().
125 If the register specified by Address >= 0x100, then ASSERT().
127 @param Address Address that encodes the PCI Bus, Device, Function and
129 @param Value The value to write.
131 @return The value written to the PCI configuration register.
141 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
142 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
144 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
150 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
153 Reads the 8-bit PCI configuration register specified by Address, performs a
154 bitwise inclusive OR between the read result and the value specified by
155 OrData, and writes the result to the 8-bit PCI configuration register
156 specified by Address. The value written to the PCI configuration register is
157 returned. This function must guarantee that all PCI read and write operations
160 If Address > 0x0FFFFFFF, then ASSERT().
161 If the register specified by Address >= 0x100, then ASSERT().
163 @param Address Address that encodes the PCI Bus, Device, Function and
165 @param OrData The value to OR with the PCI configuration register.
167 @return The value written back to the PCI configuration register.
177 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
178 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
180 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
186 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
189 Reads the 8-bit PCI configuration register specified by Address, performs a
190 bitwise AND between the read result and the value specified by AndData, and
191 writes the result to the 8-bit PCI configuration register specified by
192 Address. The value written to the PCI configuration register is returned.
193 This function must guarantee that all PCI read and write operations are
196 If Address > 0x0FFFFFFF, then ASSERT().
197 If the register specified by Address >= 0x100, then ASSERT().
199 @param Address Address that encodes the PCI Bus, Device, Function and
201 @param AndData The value to AND with the PCI configuration register.
203 @return The value written back to the PCI configuration register.
213 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
214 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
216 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
222 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
223 value, followed a bitwise inclusive OR with another 8-bit value.
225 Reads the 8-bit PCI configuration register specified by Address, performs a
226 bitwise AND between the read result and the value specified by AndData,
227 performs a bitwise inclusive OR between the result of the AND operation and
228 the value specified by OrData, and writes the result to the 8-bit PCI
229 configuration register specified by Address. The value written to the PCI
230 configuration register is returned. This function must guarantee that all PCI
231 read and write operations are serialized.
233 If Address > 0x0FFFFFFF, then ASSERT().
234 If the register specified by Address >= 0x100, then ASSERT().
236 @param Address Address that encodes the PCI Bus, Device, Function and
238 @param AndData The value to AND with the PCI configuration register.
239 @param OrData The value to OR with the result of the AND operation.
241 @return The value written back to the PCI configuration register.
252 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
253 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
254 return IoAndThenOr8 (
255 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
262 Reads a bit field of a PCI configuration register.
264 Reads the bit field in an 8-bit PCI configuration register. The bit field is
265 specified by the StartBit and the EndBit. The value of the bit field is
268 If Address > 0x0FFFFFFF, then ASSERT().
269 If the register specified by Address >= 0x100, then ASSERT().
270 If StartBit is greater than 7, then ASSERT().
271 If EndBit is greater than 7, then ASSERT().
272 If EndBit is less than StartBit, then ASSERT().
274 @param Address PCI configuration register to read.
275 @param StartBit The ordinal of the least significant bit in the bit field.
277 @param EndBit The ordinal of the most significant bit in the bit field.
280 @return The value of the bit field read from the PCI configuration register.
285 PciCf8BitFieldRead8 (
291 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
292 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
293 return IoBitFieldRead8 (
294 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
301 Writes a bit field to a PCI configuration register.
303 Writes Value to the bit field of the PCI configuration register. The bit
304 field is specified by the StartBit and the EndBit. All other bits in the
305 destination PCI configuration register are preserved. The new value of the
306 8-bit register is returned.
308 If Address > 0x0FFFFFFF, then ASSERT().
309 If the register specified by Address >= 0x100, then ASSERT().
310 If StartBit is greater than 7, then ASSERT().
311 If EndBit is greater than 7, then ASSERT().
312 If EndBit is less than StartBit, then ASSERT().
314 @param Address PCI configuration register to write.
315 @param StartBit The ordinal of the least significant bit in the bit field.
317 @param EndBit The ordinal of the most significant bit in the bit field.
319 @param Value New value of the bit field.
321 @return The value written back to the PCI configuration register.
326 PciCf8BitFieldWrite8 (
333 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
334 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
335 return IoBitFieldWrite8 (
336 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
344 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
345 writes the result back to the bit field in the 8-bit port.
347 Reads the 8-bit PCI configuration register specified by Address, performs a
348 bitwise inclusive OR between the read result and the value specified by
349 OrData, and writes the result to the 8-bit PCI configuration register
350 specified by Address. The value written to the PCI configuration register is
351 returned. This function must guarantee that all PCI read and write operations
352 are serialized. Extra left bits in OrData are stripped.
354 If Address > 0x0FFFFFFF, then ASSERT().
355 If the register specified by Address >= 0x100, then ASSERT().
356 If StartBit is greater than 7, then ASSERT().
357 If EndBit is greater than 7, then ASSERT().
358 If EndBit is less than StartBit, then ASSERT().
360 @param Address PCI configuration register to write.
361 @param StartBit The ordinal of the least significant bit in the bit field.
363 @param EndBit The ordinal of the most significant bit in the bit field.
365 @param OrData The value to OR with the PCI configuration register.
367 @return The value written back to the PCI configuration register.
379 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
380 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
381 return IoBitFieldOr8 (
382 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
390 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
391 AND, and writes the result back to the bit field in the 8-bit register.
393 Reads the 8-bit PCI configuration register specified by Address, performs a
394 bitwise AND between the read result and the value specified by AndData, and
395 writes the result to the 8-bit PCI configuration register specified by
396 Address. The value written to the PCI configuration register is returned.
397 This function must guarantee that all PCI read and write operations are
398 serialized. Extra left bits in AndData are stripped.
400 If Address > 0x0FFFFFFF, then ASSERT().
401 If the register specified by Address >= 0x100, then ASSERT().
402 If StartBit is greater than 7, then ASSERT().
403 If EndBit is greater than 7, then ASSERT().
404 If EndBit is less than StartBit, then ASSERT().
406 @param Address PCI configuration register to write.
407 @param StartBit The ordinal of the least significant bit in the bit field.
409 @param EndBit The ordinal of the most significant bit in the bit field.
411 @param AndData The value to AND with the PCI configuration register.
413 @return The value written back to the PCI configuration register.
425 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
426 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
427 return IoBitFieldAnd8 (
428 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
436 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
437 bitwise inclusive OR, and writes the result back to the bit field in the
440 Reads the 8-bit PCI configuration register specified by Address, performs a
441 bitwise AND followed by a bitwise inclusive OR between the read result and
442 the value specified by AndData, and writes the result to the 8-bit PCI
443 configuration register specified by Address. The value written to the PCI
444 configuration register is returned. This function must guarantee that all PCI
445 read and write operations are serialized. Extra left bits in both AndData and
448 If Address > 0x0FFFFFFF, then ASSERT().
449 If the register specified by Address >= 0x100, then ASSERT().
450 If StartBit is greater than 7, then ASSERT().
451 If EndBit is greater than 7, then ASSERT().
452 If EndBit is less than StartBit, then ASSERT().
454 @param Address PCI configuration register to write.
455 @param StartBit The ordinal of the least significant bit in the bit field.
457 @param EndBit The ordinal of the most significant bit in the bit field.
459 @param AndData The value to AND with the PCI configuration register.
460 @param OrData The value to OR with the result of the AND operation.
462 @return The value written back to the PCI configuration register.
467 PciCf8BitFieldAndThenOr8(
475 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
476 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
477 return IoBitFieldAndThenOr8 (
478 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
487 Reads a 16-bit PCI configuration register.
489 Reads and returns the 16-bit PCI configuration register specified by Address.
490 This function must guarantee that all PCI read and write operations are
493 If Address > 0x0FFFFFFF, then ASSERT().
494 If Address is not aligned on a 16-bit boundary, then ASSERT().
495 If the register specified by Address >= 0x100, then ASSERT().
497 @param Address Address that encodes the PCI Bus, Device, Function and
500 @return The read value from the PCI configuration register.
509 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
510 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
511 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
515 Writes a 16-bit PCI configuration register.
517 Writes the 16-bit PCI configuration register specified by Address with the
518 value specified by Value. Value is returned. This function must guarantee
519 that all PCI read and write operations are serialized.
521 If Address > 0x0FFFFFFF, then ASSERT().
522 If Address is not aligned on a 16-bit boundary, then ASSERT().
523 If the register specified by Address >= 0x100, then ASSERT().
525 @param Address Address that encodes the PCI Bus, Device, Function and
527 @param Value The value to write.
529 @return The value written to the PCI configuration register.
539 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
540 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
542 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
548 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
551 Reads the 16-bit PCI configuration register specified by Address, performs a
552 bitwise inclusive OR between the read result and the value specified by
553 OrData, and writes the result to the 16-bit PCI configuration register
554 specified by Address. The value written to the PCI configuration register is
555 returned. This function must guarantee that all PCI read and write operations
558 If Address > 0x0FFFFFFF, then ASSERT().
559 If Address is not aligned on a 16-bit boundary, then ASSERT().
560 If the register specified by Address >= 0x100, then ASSERT().
562 @param Address Address that encodes the PCI Bus, Device, Function and
564 @param OrData The value to OR with the PCI configuration register.
566 @return The value written back to the PCI configuration register.
576 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
577 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
579 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
585 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
588 Reads the 16-bit PCI configuration register specified by Address, performs a
589 bitwise AND between the read result and the value specified by AndData, and
590 writes the result to the 16-bit PCI configuration register specified by
591 Address. The value written to the PCI configuration register is returned.
592 This function must guarantee that all PCI read and write operations are
595 If Address > 0x0FFFFFFF, then ASSERT().
596 If Address is not aligned on a 16-bit boundary, then ASSERT().
597 If the register specified by Address >= 0x100, then ASSERT().
599 @param Address Address that encodes the PCI Bus, Device, Function and
601 @param AndData The value to AND with the PCI configuration register.
603 @return The value written back to the PCI configuration register.
613 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
614 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
616 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
622 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
623 value, followed a bitwise inclusive OR with another 16-bit value.
625 Reads the 16-bit PCI configuration register specified by Address, performs a
626 bitwise AND between the read result and the value specified by AndData,
627 performs a bitwise inclusive OR between the result of the AND operation and
628 the value specified by OrData, and writes the result to the 16-bit PCI
629 configuration register specified by Address. The value written to the PCI
630 configuration register is returned. This function must guarantee that all PCI
631 read and write operations are serialized.
633 If Address > 0x0FFFFFFF, then ASSERT().
634 If Address is not aligned on a 16-bit boundary, then ASSERT().
635 If the register specified by Address >= 0x100, then ASSERT().
637 @param Address Address that encodes the PCI Bus, Device, Function and
639 @param AndData The value to AND with the PCI configuration register.
640 @param OrData The value to OR with the result of the AND operation.
642 @return The value written back to the PCI configuration register.
653 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
654 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
655 return IoAndThenOr16 (
656 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
663 Reads a bit field of a PCI configuration register.
665 Reads the bit field in a 16-bit PCI configuration register. The bit field is
666 specified by the StartBit and the EndBit. The value of the bit field is
669 If Address > 0x0FFFFFFF, then ASSERT().
670 If Address is not aligned on a 16-bit boundary, then ASSERT().
671 If the register specified by Address >= 0x100, then ASSERT().
672 If StartBit is greater than 15, then ASSERT().
673 If EndBit is greater than 15, then ASSERT().
674 If EndBit is less than StartBit, then ASSERT().
676 @param Address PCI configuration register to read.
677 @param StartBit The ordinal of the least significant bit in the bit field.
679 @param EndBit The ordinal of the most significant bit in the bit field.
682 @return The value of the bit field read from the PCI configuration register.
687 PciCf8BitFieldRead16 (
693 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
694 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
695 return IoBitFieldRead16 (
696 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
703 Writes a bit field to a PCI configuration register.
705 Writes Value to the bit field of the PCI configuration register. The bit
706 field is specified by the StartBit and the EndBit. All other bits in the
707 destination PCI configuration register are preserved. The new value of the
708 16-bit register is returned.
710 If Address > 0x0FFFFFFF, then ASSERT().
711 If Address is not aligned on a 16-bit boundary, then ASSERT().
712 If the register specified by Address >= 0x100, 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().
717 @param Address PCI configuration register to write.
718 @param StartBit The ordinal of the least significant bit in the bit field.
720 @param EndBit The ordinal of the most significant bit in the bit field.
722 @param Value New value of the bit field.
724 @return The value written back to the PCI configuration register.
729 PciCf8BitFieldWrite16 (
736 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
737 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
738 return IoBitFieldWrite16 (
739 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
747 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
748 writes the result back to the bit field in the 16-bit port.
750 Reads the 16-bit PCI configuration register specified by Address, performs a
751 bitwise inclusive OR between the read result and the value specified by
752 OrData, and writes the result to the 16-bit PCI configuration register
753 specified by Address. The value written to the PCI configuration register is
754 returned. This function must guarantee that all PCI read and write operations
755 are serialized. Extra left bits in OrData are stripped.
757 If Address > 0x0FFFFFFF, then ASSERT().
758 If Address is not aligned on a 16-bit boundary, then ASSERT().
759 If the register specified by Address >= 0x100, then ASSERT().
760 If StartBit is greater than 15, then ASSERT().
761 If EndBit is greater than 15, then ASSERT().
762 If EndBit is less than StartBit, then ASSERT().
764 @param Address PCI configuration register to write.
765 @param StartBit The ordinal of the least significant bit in the bit field.
767 @param EndBit The ordinal of the most significant bit in the bit field.
769 @param OrData The value to OR with the PCI configuration register.
771 @return The value written back to the PCI configuration register.
783 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
784 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
785 return IoBitFieldOr16 (
786 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
794 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
795 AND, and writes the result back to the bit field in the 16-bit register.
797 Reads the 16-bit PCI configuration register specified by Address, performs a
798 bitwise AND between the read result and the value specified by AndData, and
799 writes the result to the 16-bit PCI configuration register specified by
800 Address. The value written to the PCI configuration register is returned.
801 This function must guarantee that all PCI read and write operations are
802 serialized. Extra left bits in AndData are stripped.
804 If Address > 0x0FFFFFFF, then ASSERT().
805 If Address is not aligned on a 16-bit boundary, then ASSERT().
806 If the register specified by Address >= 0x100, then ASSERT().
807 If StartBit is greater than 15, then ASSERT().
808 If EndBit is greater than 15, then ASSERT().
809 If EndBit is less than StartBit, then ASSERT().
811 @param Address PCI configuration register to write.
812 @param StartBit The ordinal of the least significant bit in the bit field.
814 @param EndBit The ordinal of the most significant bit in the bit field.
816 @param AndData The value to AND with the PCI configuration register.
818 @return The value written back to the PCI configuration register.
823 PciCf8BitFieldAnd16 (
830 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
831 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
832 return IoBitFieldAnd16 (
833 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
841 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
842 bitwise inclusive OR, and writes the result back to the bit field in the
845 Reads the 16-bit PCI configuration register specified by Address, performs a
846 bitwise AND followed by a bitwise inclusive OR between the read result and
847 the value specified by AndData, and writes the result to the 16-bit PCI
848 configuration register specified by Address. The value written to the PCI
849 configuration register is returned. This function must guarantee that all PCI
850 read and write operations are serialized. Extra left bits in both AndData and
853 If Address > 0x0FFFFFFF, then ASSERT().
854 If Address is not aligned on a 16-bit boundary, then ASSERT().
855 If the register specified by Address >= 0x100, then ASSERT().
856 If StartBit is greater than 15, then ASSERT().
857 If EndBit is greater than 15, then ASSERT().
858 If EndBit is less than StartBit, then ASSERT().
860 @param Address PCI configuration register to write.
861 @param StartBit The ordinal of the least significant bit in the bit field.
863 @param EndBit The ordinal of the most significant bit in the bit field.
865 @param AndData The value to AND with the PCI configuration register.
866 @param OrData The value to OR with the result of the AND operation.
868 @return The value written back to the PCI configuration register.
873 PciCf8BitFieldAndThenOr16(
881 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
882 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
883 return IoBitFieldAndThenOr16 (
884 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
893 Reads a 32-bit PCI configuration register.
895 Reads and returns the 32-bit PCI configuration register specified by Address.
896 This function must guarantee that all PCI read and write operations are
899 If Address > 0x0FFFFFFF, then ASSERT().
900 If Address is not aligned on a 32-bit boundary, then ASSERT().
901 If the register specified by Address >= 0x100, then ASSERT().
903 @param Address Address that encodes the PCI Bus, Device, Function and
906 @return The read value from the PCI configuration register.
915 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
916 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
917 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
921 Writes a 32-bit PCI configuration register.
923 Writes the 32-bit PCI configuration register specified by Address with the
924 value specified by Value. Value is returned. This function must guarantee
925 that all PCI read and write operations are serialized.
927 If Address > 0x0FFFFFFF, then ASSERT().
928 If Address is not aligned on a 32-bit boundary, then ASSERT().
929 If the register specified by Address >= 0x100, then ASSERT().
931 @param Address Address that encodes the PCI Bus, Device, Function and
933 @param Value The value to write.
935 @return The value written to the PCI configuration register.
945 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
946 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
948 PCI_CONFIGURATION_DATA_PORT
,
954 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
957 Reads the 32-bit PCI configuration register specified by Address, performs a
958 bitwise inclusive OR between the read result and the value specified by
959 OrData, and writes the result to the 32-bit PCI configuration register
960 specified by Address. The value written to the PCI configuration register is
961 returned. This function must guarantee that all PCI read and write operations
964 If Address > 0x0FFFFFFF, then ASSERT().
965 If Address is not aligned on a 32-bit boundary, then ASSERT().
966 If the register specified by Address >= 0x100, then ASSERT().
968 @param Address Address that encodes the PCI Bus, Device, Function and
970 @param OrData The value to OR with the PCI configuration register.
972 @return The value written back to the PCI configuration register.
982 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
983 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
985 PCI_CONFIGURATION_DATA_PORT
,
991 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
994 Reads the 32-bit PCI configuration register specified by Address, performs a
995 bitwise AND between the read result and the value specified by AndData, and
996 writes the result to the 32-bit PCI configuration register specified by
997 Address. The value written to the PCI configuration register is returned.
998 This function must guarantee that all PCI read and write operations are
1001 If Address > 0x0FFFFFFF, then ASSERT().
1002 If Address is not aligned on a 32-bit boundary, then ASSERT().
1003 If the register specified by Address >= 0x100, then ASSERT().
1005 @param Address Address that encodes the PCI Bus, Device, Function and
1007 @param AndData The value to AND with the PCI configuration register.
1009 @return The value written back to the PCI configuration register.
1019 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1020 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1022 PCI_CONFIGURATION_DATA_PORT
,
1028 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1029 value, followed a bitwise inclusive OR with another 32-bit value.
1031 Reads the 32-bit PCI configuration register specified by Address, performs a
1032 bitwise AND between the read result and the value specified by AndData,
1033 performs a bitwise inclusive OR between the result of the AND operation and
1034 the value specified by OrData, and writes the result to the 32-bit PCI
1035 configuration register specified by Address. The value written to the PCI
1036 configuration register is returned. This function must guarantee that all PCI
1037 read and write operations are serialized.
1039 If Address > 0x0FFFFFFF, then ASSERT().
1040 If Address is not aligned on a 32-bit boundary, then ASSERT().
1041 If the register specified by Address >= 0x100, then ASSERT().
1043 @param Address Address that encodes the PCI Bus, Device, Function and
1045 @param AndData The value to AND with the PCI configuration register.
1046 @param OrData The value to OR with the result of the AND operation.
1048 @return The value written back to the PCI configuration register.
1059 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1060 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1061 return IoAndThenOr32 (
1062 PCI_CONFIGURATION_DATA_PORT
,
1069 Reads a bit field of a PCI configuration register.
1071 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1072 specified by the StartBit and the EndBit. The value of the bit field is
1075 If Address > 0x0FFFFFFF, then ASSERT().
1076 If Address is not aligned on a 32-bit boundary, then ASSERT().
1077 If the register specified by Address >= 0x100, then ASSERT().
1078 If StartBit is greater than 31, then ASSERT().
1079 If EndBit is greater than 31, then ASSERT().
1080 If EndBit is less than StartBit, then ASSERT().
1082 @param Address PCI configuration register to read.
1083 @param StartBit The ordinal of the least significant bit in the bit field.
1085 @param EndBit The ordinal of the most significant bit in the bit field.
1088 @return The value of the bit field read from the PCI configuration register.
1093 PciCf8BitFieldRead32 (
1099 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1100 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1101 return IoBitFieldRead32 (
1102 PCI_CONFIGURATION_DATA_PORT
,
1109 Writes a bit field to a PCI configuration register.
1111 Writes Value to the bit field of the PCI configuration register. The bit
1112 field is specified by the StartBit and the EndBit. All other bits in the
1113 destination PCI configuration register are preserved. The new value of the
1114 32-bit register is returned.
1116 If Address > 0x0FFFFFFF, then ASSERT().
1117 If Address is not aligned on a 32-bit boundary, then ASSERT().
1118 If the register specified by Address >= 0x100, then ASSERT().
1119 If StartBit is greater than 31, then ASSERT().
1120 If EndBit is greater than 31, then ASSERT().
1121 If EndBit is less than StartBit, then ASSERT().
1123 @param Address PCI configuration register to write.
1124 @param StartBit The ordinal of the least significant bit in the bit field.
1126 @param EndBit The ordinal of the most significant bit in the bit field.
1128 @param Value New value of the bit field.
1130 @return The value written back to the PCI configuration register.
1135 PciCf8BitFieldWrite32 (
1142 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1143 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1144 return IoBitFieldWrite32 (
1145 PCI_CONFIGURATION_DATA_PORT
,
1153 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1154 writes the result back to the bit field in the 32-bit port.
1156 Reads the 32-bit PCI configuration register specified by Address, performs a
1157 bitwise inclusive OR between the read result and the value specified by
1158 OrData, and writes the result to the 32-bit PCI configuration register
1159 specified by Address. The value written to the PCI configuration register is
1160 returned. This function must guarantee that all PCI read and write operations
1161 are serialized. Extra left bits in OrData are stripped.
1163 If Address > 0x0FFFFFFF, then ASSERT().
1164 If Address is not aligned on a 32-bit boundary, then ASSERT().
1165 If the register specified by Address >= 0x100, then ASSERT().
1166 If StartBit is greater than 31, then ASSERT().
1167 If EndBit is greater than 31, then ASSERT().
1168 If EndBit is less than StartBit, then ASSERT().
1170 @param Address PCI configuration register to write.
1171 @param StartBit The ordinal of the least significant bit in the bit field.
1173 @param EndBit The ordinal of the most significant bit in the bit field.
1175 @param OrData The value to OR with the PCI configuration register.
1177 @return The value written back to the PCI configuration register.
1182 PciCf8BitFieldOr32 (
1189 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1190 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1191 return IoBitFieldOr32 (
1192 PCI_CONFIGURATION_DATA_PORT
,
1200 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1201 AND, and writes the result back to the bit field in the 32-bit register.
1203 Reads the 32-bit PCI configuration register specified by Address, performs a
1204 bitwise AND between the read result and the value specified by AndData, and
1205 writes the result to the 32-bit PCI configuration register specified by
1206 Address. The value written to the PCI configuration register is returned.
1207 This function must guarantee that all PCI read and write operations are
1208 serialized. Extra left bits in AndData are stripped.
1210 If Address > 0x0FFFFFFF, then ASSERT().
1211 If Address is not aligned on a 32-bit boundary, then ASSERT().
1212 If the register specified by Address >= 0x100, then ASSERT().
1213 If StartBit is greater than 31, then ASSERT().
1214 If EndBit is greater than 31, then ASSERT().
1215 If EndBit is less than StartBit, then ASSERT().
1217 @param Address PCI configuration register to write.
1218 @param StartBit The ordinal of the least significant bit in the bit field.
1220 @param EndBit The ordinal of the most significant bit in the bit field.
1222 @param AndData The value to AND with the PCI configuration register.
1224 @return The value written back to the PCI configuration register.
1229 PciCf8BitFieldAnd32 (
1236 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1237 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1238 return IoBitFieldAnd32 (
1239 PCI_CONFIGURATION_DATA_PORT
,
1247 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1248 bitwise inclusive OR, and writes the result back to the bit field in the
1251 Reads the 32-bit PCI configuration register specified by Address, performs a
1252 bitwise AND followed by a bitwise inclusive OR between the read result and
1253 the value specified by AndData, and writes the result to the 32-bit PCI
1254 configuration register specified by Address. The value written to the PCI
1255 configuration register is returned. This function must guarantee that all PCI
1256 read and write operations are serialized. Extra left bits in both AndData and
1257 OrData are stripped.
1259 If Address > 0x0FFFFFFF, then ASSERT().
1260 If Address is not aligned on a 32-bit boundary, then ASSERT().
1261 If the register specified by Address >= 0x100, then ASSERT().
1262 If StartBit is greater than 31, then ASSERT().
1263 If EndBit is greater than 31, then ASSERT().
1264 If EndBit is less than StartBit, then ASSERT().
1266 @param Address PCI configuration register to write.
1267 @param StartBit The ordinal of the least significant bit in the bit field.
1269 @param EndBit The ordinal of the most significant bit in the bit field.
1271 @param AndData The value to AND with the PCI configuration register.
1272 @param OrData The value to OR with the result of the AND operation.
1274 @return The value written back to the PCI configuration register.
1279 PciCf8BitFieldAndThenOr32(
1287 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1288 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1289 return IoBitFieldAndThenOr32 (
1290 PCI_CONFIGURATION_DATA_PORT
,
1299 Reads a range of PCI configuration registers into a caller supplied buffer.
1301 Reads the range of PCI configuration registers specified by StartAddress and
1302 Size into the buffer specified by Buffer. This function only allows the PCI
1303 configuration registers from a single PCI function to be read. Size is
1304 returned. When possible 32-bit PCI configuration read cycles are used to read
1305 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1306 and 16-bit PCI configuration read cycles may be used at the beginning and the
1309 If StartAddress > 0x0FFFFFFF, then ASSERT().
1310 If the register specified by StartAddress >= 0x100, then ASSERT().
1311 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1312 If Size > 0 and Buffer is NULL, then ASSERT().
1314 @param StartAddress Starting address that encodes the PCI Bus, Device,
1315 Function and Register.
1316 @param Size Size in bytes of the transfer.
1317 @param Buffer Pointer to a buffer receiving the data read.
1319 @return Size read from StartAddress.
1325 IN UINTN StartAddress
,
1332 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1333 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1339 ASSERT (Buffer
!= NULL
);
1342 // Save Size for return
1346 if ((StartAddress
& 1) != 0) {
1348 // Read a byte if StartAddress is byte aligned
1350 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1351 StartAddress
+= sizeof (UINT8
);
1352 Size
-= sizeof (UINT8
);
1353 Buffer
= (UINT8
*)Buffer
+ 1;
1356 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1358 // Read a word if StartAddress is word aligned
1360 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1362 StartAddress
+= sizeof (UINT16
);
1363 Size
-= sizeof (UINT16
);
1364 Buffer
= (UINT16
*)Buffer
+ 1;
1367 while (Size
>= sizeof (UINT32
)) {
1369 // Read as many double words as possible
1371 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
) PciCf8Read32 (StartAddress
));
1372 StartAddress
+= sizeof (UINT32
);
1373 Size
-= sizeof (UINT32
);
1374 Buffer
= (UINT32
*)Buffer
+ 1;
1377 if (Size
>= sizeof (UINT16
)) {
1379 // Read the last remaining word if exist
1381 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1382 StartAddress
+= sizeof (UINT16
);
1383 Size
-= sizeof (UINT16
);
1384 Buffer
= (UINT16
*)Buffer
+ 1;
1387 if (Size
>= sizeof (UINT8
)) {
1389 // Read the last remaining byte if exist
1391 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1398 Copies the data in a caller supplied buffer to a specified range of PCI
1399 configuration space.
1401 Writes the range of PCI configuration registers specified by StartAddress and
1402 Size from the buffer specified by Buffer. This function only allows the PCI
1403 configuration registers from a single PCI function to be written. Size is
1404 returned. When possible 32-bit PCI configuration write cycles are used to
1405 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1406 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1407 and the end of the range.
1409 If StartAddress > 0x0FFFFFFF, then ASSERT().
1410 If the register specified by StartAddress >= 0x100, then ASSERT().
1411 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1412 If Size > 0 and Buffer is NULL, then ASSERT().
1414 @param StartAddress Starting address that encodes the PCI Bus, Device,
1415 Function and Register.
1416 @param Size Size in bytes of the transfer.
1417 @param Buffer Pointer to a buffer containing the data to write.
1419 @return Size written to StartAddress.
1425 IN UINTN StartAddress
,
1432 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1433 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1439 ASSERT (Buffer
!= NULL
);
1442 // Save Size for return
1446 if ((StartAddress
& 1) != 0) {
1448 // Write a byte if StartAddress is byte aligned
1450 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1451 StartAddress
+= sizeof (UINT8
);
1452 Size
-= sizeof (UINT8
);
1453 Buffer
= (UINT8
*)Buffer
+ 1;
1456 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1458 // Write a word if StartAddress is word aligned
1460 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1461 StartAddress
+= sizeof (UINT16
);
1462 Size
-= sizeof (UINT16
);
1463 Buffer
= (UINT16
*)Buffer
+ 1;
1466 while (Size
>= sizeof (UINT32
)) {
1468 // Write as many double words as possible
1470 PciCf8Write32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1471 StartAddress
+= sizeof (UINT32
);
1472 Size
-= sizeof (UINT32
);
1473 Buffer
= (UINT32
*)Buffer
+ 1;
1476 if (Size
>= sizeof (UINT16
)) {
1478 // Write the last remaining word if exist
1480 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1481 StartAddress
+= sizeof (UINT16
);
1482 Size
-= sizeof (UINT16
);
1483 Buffer
= (UINT16
*)Buffer
+ 1;
1486 if (Size
>= sizeof (UINT8
)) {
1488 // Write the last remaining byte if exist
1490 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);