4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 // The package level header files this module uses
22 // The protocols, PPI and GUID defintions for this module
25 // The Library classes this module consumes
27 #include <Library/PciCf8Lib.h>
28 #include <Library/IoLib.h>
29 #include <Library/DebugLib.h>
32 // Declare I/O Ports used to perform PCI Confguration Cycles
34 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
35 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
38 // Declare macro to convert PCI Library formatted address to CF8 formatted address
40 // PCI Library formatted address CF8 Formatted Address
41 // ============================= ======================
42 // Bits 00..11 Register Bits 00..07 Register
43 // Bits 12..14 Function Bits 08..10 Function
44 // Bits 15..19 Device Bits 11..15 Device
45 // Bits 20..27 Bus Bits 16..23 Bus
46 // Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
47 // Bits 31..31 Must be 1
51 Assert the validity of a PCI address. A valid PCI address should contain 1's
52 only in the low 28 bits.
54 @param A The address to validate.
55 @param M Additional bits to assert to be zero.
58 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
59 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
62 Convert a PCI Express address to PCI CF8 address.
64 @param A The address to convert.
66 @retval The coverted address.
69 #define PCI_TO_CF8_ADDRESS(A) \
70 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
73 Reads an 8-bit PCI configuration register.
75 Reads and returns the 8-bit PCI configuration register specified by Address.
76 This function must guarantee that all PCI read and write operations are
79 If Address > 0x0FFFFFFF, then ASSERT().
80 If the register specified by Address >= 0x100, then ASSERT().
82 @param Address Address that encodes the PCI Bus, Device, Function and
85 @return The read value from the PCI configuration register.
94 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
95 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
96 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
100 Writes an 8-bit PCI configuration register.
102 Writes the 8-bit PCI configuration register specified by Address with the
103 value specified by Value. Value is returned. This function must guarantee
104 that all PCI read and write operations are serialized.
106 If Address > 0x0FFFFFFF, then ASSERT().
107 If the register specified by Address >= 0x100, then ASSERT().
109 @param Address Address that encodes the PCI Bus, Device, Function and
111 @param Value The value to write.
113 @return The value written to the PCI configuration register.
123 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
124 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
126 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
132 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
135 Reads the 8-bit PCI configuration register specified by Address, performs a
136 bitwise inclusive OR between the read result and the value specified by
137 OrData, and writes the result to the 8-bit PCI configuration register
138 specified by Address. The value written to the PCI configuration register is
139 returned. This function must guarantee that all PCI read and write operations
142 If Address > 0x0FFFFFFF, then ASSERT().
143 If the register specified by Address >= 0x100, then ASSERT().
145 @param Address Address that encodes the PCI Bus, Device, Function and
147 @param OrData The value to OR with the PCI configuration register.
149 @return The value written back to the PCI configuration register.
159 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
160 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
162 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
168 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
171 Reads the 8-bit PCI configuration register specified by Address, performs a
172 bitwise AND between the read result and the value specified by AndData, and
173 writes the result to the 8-bit PCI configuration register specified by
174 Address. The value written to the PCI configuration register is returned.
175 This function must guarantee that all PCI read and write operations are
178 If Address > 0x0FFFFFFF, then ASSERT().
179 If the register specified by Address >= 0x100, then ASSERT().
181 @param Address Address that encodes the PCI Bus, Device, Function and
183 @param AndData The value to AND with the PCI configuration register.
185 @return The value written back to the PCI configuration register.
195 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
196 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
198 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
204 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
205 value, followed a bitwise inclusive OR with another 8-bit value.
207 Reads the 8-bit PCI configuration register specified by Address, performs a
208 bitwise AND between the read result and the value specified by AndData,
209 performs a bitwise inclusive OR between the result of the AND operation and
210 the value specified by OrData, and writes the result to the 8-bit PCI
211 configuration register specified by Address. The value written to the PCI
212 configuration register is returned. This function must guarantee that all PCI
213 read and write operations are serialized.
215 If Address > 0x0FFFFFFF, then ASSERT().
216 If the register specified by Address >= 0x100, then ASSERT().
218 @param Address Address that encodes the PCI Bus, Device, Function and
220 @param AndData The value to AND with the PCI configuration register.
221 @param OrData The value to OR with the result of the AND operation.
223 @return The value written back to the PCI configuration register.
234 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
235 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
236 return IoAndThenOr8 (
237 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
244 Reads a bit field of a PCI configuration register.
246 Reads the bit field in an 8-bit PCI configuration register. The bit field is
247 specified by the StartBit and the EndBit. The value of the bit field is
250 If Address > 0x0FFFFFFF, then ASSERT().
251 If the register specified by Address >= 0x100, then ASSERT().
252 If StartBit is greater than 7, then ASSERT().
253 If EndBit is greater than 7, then ASSERT().
254 If EndBit is less than StartBit, then ASSERT().
256 @param Address PCI configuration register to read.
257 @param StartBit The ordinal of the least significant bit in the bit field.
259 @param EndBit The ordinal of the most significant bit in the bit field.
262 @return The value of the bit field read from the PCI configuration register.
267 PciCf8BitFieldRead8 (
273 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
274 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
275 return IoBitFieldRead8 (
276 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
283 Writes a bit field to a PCI configuration register.
285 Writes Value to the bit field of the PCI configuration register. The bit
286 field is specified by the StartBit and the EndBit. All other bits in the
287 destination PCI configuration register are preserved. The new value of the
288 8-bit register is returned.
290 If Address > 0x0FFFFFFF, then ASSERT().
291 If the register specified by Address >= 0x100, then ASSERT().
292 If StartBit is greater than 7, then ASSERT().
293 If EndBit is greater than 7, then ASSERT().
294 If EndBit is less than StartBit, then ASSERT().
296 @param Address PCI configuration register to write.
297 @param StartBit The ordinal of the least significant bit in the bit field.
299 @param EndBit The ordinal of the most significant bit in the bit field.
301 @param Value New value of the bit field.
303 @return The value written back to the PCI configuration register.
308 PciCf8BitFieldWrite8 (
315 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
316 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
317 return IoBitFieldWrite8 (
318 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
326 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
327 writes the result back to the bit field in the 8-bit port.
329 Reads the 8-bit PCI configuration register specified by Address, performs a
330 bitwise inclusive OR between the read result and the value specified by
331 OrData, and writes the result to the 8-bit PCI configuration register
332 specified by Address. The value written to the PCI configuration register is
333 returned. This function must guarantee that all PCI read and write operations
334 are serialized. Extra left bits in OrData are stripped.
336 If Address > 0x0FFFFFFF, then ASSERT().
337 If the register specified by Address >= 0x100, then ASSERT().
338 If StartBit is greater than 7, then ASSERT().
339 If EndBit is greater than 7, then ASSERT().
340 If EndBit is less than StartBit, then ASSERT().
342 @param Address PCI configuration register to write.
343 @param StartBit The ordinal of the least significant bit in the bit field.
345 @param EndBit The ordinal of the most significant bit in the bit field.
347 @param OrData The value to OR with the PCI configuration register.
349 @return The value written back to the PCI configuration register.
361 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
362 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
363 return IoBitFieldOr8 (
364 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
372 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
373 AND, and writes the result back to the bit field in the 8-bit register.
375 Reads the 8-bit PCI configuration register specified by Address, performs a
376 bitwise AND between the read result and the value specified by AndData, and
377 writes the result to the 8-bit PCI configuration register specified by
378 Address. The value written to the PCI configuration register is returned.
379 This function must guarantee that all PCI read and write operations are
380 serialized. Extra left bits in AndData are stripped.
382 If Address > 0x0FFFFFFF, then ASSERT().
383 If the register specified by Address >= 0x100, then ASSERT().
384 If StartBit is greater than 7, then ASSERT().
385 If EndBit is greater than 7, then ASSERT().
386 If EndBit is less than StartBit, then ASSERT().
388 @param Address PCI configuration register to write.
389 @param StartBit The ordinal of the least significant bit in the bit field.
391 @param EndBit The ordinal of the most significant bit in the bit field.
393 @param AndData The value to AND with the PCI configuration register.
395 @return The value written back to the PCI configuration register.
407 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
408 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
409 return IoBitFieldAnd8 (
410 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
418 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
419 bitwise inclusive OR, and writes the result back to the bit field in the
422 Reads the 8-bit PCI configuration register specified by Address, performs a
423 bitwise AND followed by a bitwise inclusive OR between the read result and
424 the value specified by AndData, and writes the result to the 8-bit PCI
425 configuration register specified by Address. The value written to the PCI
426 configuration register is returned. This function must guarantee that all PCI
427 read and write operations are serialized. Extra left bits in both AndData and
430 If Address > 0x0FFFFFFF, then ASSERT().
431 If the register specified by Address >= 0x100, then ASSERT().
432 If StartBit is greater than 7, then ASSERT().
433 If EndBit is greater than 7, then ASSERT().
434 If EndBit is less than StartBit, then ASSERT().
436 @param Address PCI configuration register to write.
437 @param StartBit The ordinal of the least significant bit in the bit field.
439 @param EndBit The ordinal of the most significant bit in the bit field.
441 @param AndData The value to AND with the PCI configuration register.
442 @param OrData The value to OR with the result of the AND operation.
444 @return The value written back to the PCI configuration register.
449 PciCf8BitFieldAndThenOr8(
457 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
458 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
459 return IoBitFieldAndThenOr8 (
460 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
469 Reads a 16-bit PCI configuration register.
471 Reads and returns the 16-bit PCI configuration register specified by Address.
472 This function must guarantee that all PCI read and write operations are
475 If Address > 0x0FFFFFFF, then ASSERT().
476 If Address is not aligned on a 16-bit boundary, then ASSERT().
477 If the register specified by Address >= 0x100, then ASSERT().
479 @param Address Address that encodes the PCI Bus, Device, Function and
482 @return The read value from the PCI configuration register.
491 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
492 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
493 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
497 Writes a 16-bit PCI configuration register.
499 Writes the 16-bit PCI configuration register specified by Address with the
500 value specified by Value. Value is returned. This function must guarantee
501 that all PCI read and write operations are serialized.
503 If Address > 0x0FFFFFFF, then ASSERT().
504 If Address is not aligned on a 16-bit boundary, then ASSERT().
505 If the register specified by Address >= 0x100, then ASSERT().
507 @param Address Address that encodes the PCI Bus, Device, Function and
509 @param Value The value to write.
511 @return The value written to the PCI configuration register.
521 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
522 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
524 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
530 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
533 Reads the 16-bit PCI configuration register specified by Address, performs a
534 bitwise inclusive OR between the read result and the value specified by
535 OrData, and writes the result to the 16-bit PCI configuration register
536 specified by Address. The value written to the PCI configuration register is
537 returned. This function must guarantee that all PCI read and write operations
540 If Address > 0x0FFFFFFF, then ASSERT().
541 If Address is not aligned on a 16-bit boundary, then ASSERT().
542 If the register specified by Address >= 0x100, then ASSERT().
544 @param Address Address that encodes the PCI Bus, Device, Function and
546 @param OrData The value to OR with the PCI configuration register.
548 @return The value written back to the PCI configuration register.
558 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
559 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
561 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
567 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
570 Reads the 16-bit PCI configuration register specified by Address, performs a
571 bitwise AND between the read result and the value specified by AndData, and
572 writes the result to the 16-bit PCI configuration register specified by
573 Address. The value written to the PCI configuration register is returned.
574 This function must guarantee that all PCI read and write operations are
577 If Address > 0x0FFFFFFF, then ASSERT().
578 If Address is not aligned on a 16-bit boundary, then ASSERT().
579 If the register specified by Address >= 0x100, then ASSERT().
581 @param Address Address that encodes the PCI Bus, Device, Function and
583 @param AndData The value to AND with the PCI configuration register.
585 @return The value written back to the PCI configuration register.
595 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
596 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
598 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
604 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
605 value, followed a bitwise inclusive OR with another 16-bit value.
607 Reads the 16-bit PCI configuration register specified by Address, performs a
608 bitwise AND between the read result and the value specified by AndData,
609 performs a bitwise inclusive OR between the result of the AND operation and
610 the value specified by OrData, and writes the result to the 16-bit PCI
611 configuration register specified by Address. The value written to the PCI
612 configuration register is returned. This function must guarantee that all PCI
613 read and write operations are serialized.
615 If Address > 0x0FFFFFFF, then ASSERT().
616 If Address is not aligned on a 16-bit boundary, then ASSERT().
617 If the register specified by Address >= 0x100, then ASSERT().
619 @param Address Address that encodes the PCI Bus, Device, Function and
621 @param AndData The value to AND with the PCI configuration register.
622 @param OrData The value to OR with the result of the AND operation.
624 @return The value written back to the PCI configuration register.
635 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
636 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
637 return IoAndThenOr16 (
638 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
645 Reads a bit field of a PCI configuration register.
647 Reads the bit field in a 16-bit PCI configuration register. The bit field is
648 specified by the StartBit and the EndBit. The value of the bit field is
651 If Address > 0x0FFFFFFF, then ASSERT().
652 If Address is not aligned on a 16-bit boundary, then ASSERT().
653 If the register specified by Address >= 0x100, then ASSERT().
654 If StartBit is greater than 15, then ASSERT().
655 If EndBit is greater than 15, then ASSERT().
656 If EndBit is less than StartBit, then ASSERT().
658 @param Address PCI configuration register to read.
659 @param StartBit The ordinal of the least significant bit in the bit field.
661 @param EndBit The ordinal of the most significant bit in the bit field.
664 @return The value of the bit field read from the PCI configuration register.
669 PciCf8BitFieldRead16 (
675 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
676 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
677 return IoBitFieldRead16 (
678 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
685 Writes a bit field to a PCI configuration register.
687 Writes Value to the bit field of the PCI configuration register. The bit
688 field is specified by the StartBit and the EndBit. All other bits in the
689 destination PCI configuration register are preserved. The new value of the
690 16-bit register is returned.
692 If Address > 0x0FFFFFFF, then ASSERT().
693 If Address is not aligned on a 16-bit boundary, then ASSERT().
694 If the register specified by Address >= 0x100, then ASSERT().
695 If StartBit is greater than 15, then ASSERT().
696 If EndBit is greater than 15, then ASSERT().
697 If EndBit is less than StartBit, then ASSERT().
699 @param Address PCI configuration register to write.
700 @param StartBit The ordinal of the least significant bit in the bit field.
702 @param EndBit The ordinal of the most significant bit in the bit field.
704 @param Value New value of the bit field.
706 @return The value written back to the PCI configuration register.
711 PciCf8BitFieldWrite16 (
718 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
719 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
720 return IoBitFieldWrite16 (
721 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
729 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
730 writes the result back to the bit field in the 16-bit port.
732 Reads the 16-bit PCI configuration register specified by Address, performs a
733 bitwise inclusive OR between the read result and the value specified by
734 OrData, and writes the result to the 16-bit PCI configuration register
735 specified by Address. The value written to the PCI configuration register is
736 returned. This function must guarantee that all PCI read and write operations
737 are serialized. Extra left bits in OrData are stripped.
739 If Address > 0x0FFFFFFF, then ASSERT().
740 If Address is not aligned on a 16-bit boundary, then ASSERT().
741 If the register specified by Address >= 0x100, then ASSERT().
742 If StartBit is greater than 15, then ASSERT().
743 If EndBit is greater than 15, then ASSERT().
744 If EndBit is less than StartBit, then ASSERT().
746 @param Address PCI configuration register to write.
747 @param StartBit The ordinal of the least significant bit in the bit field.
749 @param EndBit The ordinal of the most significant bit in the bit field.
751 @param OrData The value to OR with the PCI configuration register.
753 @return The value written back to the PCI configuration register.
765 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
766 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
767 return IoBitFieldOr16 (
768 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
776 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
777 AND, and writes the result back to the bit field in the 16-bit register.
779 Reads the 16-bit PCI configuration register specified by Address, performs a
780 bitwise AND between the read result and the value specified by AndData, and
781 writes the result to the 16-bit PCI configuration register specified by
782 Address. The value written to the PCI configuration register is returned.
783 This function must guarantee that all PCI read and write operations are
784 serialized. Extra left bits in AndData are stripped.
786 If Address > 0x0FFFFFFF, then ASSERT().
787 If Address is not aligned on a 16-bit boundary, then ASSERT().
788 If the register specified by Address >= 0x100, then ASSERT().
789 If StartBit is greater than 15, then ASSERT().
790 If EndBit is greater than 15, then ASSERT().
791 If EndBit is less than StartBit, then ASSERT().
793 @param Address PCI configuration register to write.
794 @param StartBit The ordinal of the least significant bit in the bit field.
796 @param EndBit The ordinal of the most significant bit in the bit field.
798 @param AndData The value to AND with the PCI configuration register.
800 @return The value written back to the PCI configuration register.
805 PciCf8BitFieldAnd16 (
812 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
813 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
814 return IoBitFieldAnd16 (
815 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
823 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
824 bitwise inclusive OR, and writes the result back to the bit field in the
827 Reads the 16-bit PCI configuration register specified by Address, performs a
828 bitwise AND followed by a bitwise inclusive OR between the read result and
829 the value specified by AndData, and writes the result to the 16-bit PCI
830 configuration register specified by Address. The value written to the PCI
831 configuration register is returned. This function must guarantee that all PCI
832 read and write operations are serialized. Extra left bits in both AndData and
835 If Address > 0x0FFFFFFF, then ASSERT().
836 If Address is not aligned on a 16-bit boundary, then ASSERT().
837 If the register specified by Address >= 0x100, then ASSERT().
838 If StartBit is greater than 15, then ASSERT().
839 If EndBit is greater than 15, then ASSERT().
840 If EndBit is less than StartBit, then ASSERT().
842 @param Address PCI configuration register to write.
843 @param StartBit The ordinal of the least significant bit in the bit field.
845 @param EndBit The ordinal of the most significant bit in the bit field.
847 @param AndData The value to AND with the PCI configuration register.
848 @param OrData The value to OR with the result of the AND operation.
850 @return The value written back to the PCI configuration register.
855 PciCf8BitFieldAndThenOr16(
863 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
864 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
865 return IoBitFieldAndThenOr16 (
866 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
875 Reads a 32-bit PCI configuration register.
877 Reads and returns the 32-bit PCI configuration register specified by Address.
878 This function must guarantee that all PCI read and write operations are
881 If Address > 0x0FFFFFFF, then ASSERT().
882 If Address is not aligned on a 32-bit boundary, then ASSERT().
883 If the register specified by Address >= 0x100, then ASSERT().
885 @param Address Address that encodes the PCI Bus, Device, Function and
888 @return The read value from the PCI configuration register.
897 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
898 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
899 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
903 Writes a 32-bit PCI configuration register.
905 Writes the 32-bit PCI configuration register specified by Address with the
906 value specified by Value. Value is returned. This function must guarantee
907 that all PCI read and write operations are serialized.
909 If Address > 0x0FFFFFFF, then ASSERT().
910 If Address is not aligned on a 32-bit boundary, then ASSERT().
911 If the register specified by Address >= 0x100, then ASSERT().
913 @param Address Address that encodes the PCI Bus, Device, Function and
915 @param Value The value to write.
917 @return The value written to the PCI configuration register.
927 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
928 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
930 PCI_CONFIGURATION_DATA_PORT
,
936 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
939 Reads the 32-bit PCI configuration register specified by Address, performs a
940 bitwise inclusive OR between the read result and the value specified by
941 OrData, and writes the result to the 32-bit PCI configuration register
942 specified by Address. The value written to the PCI configuration register is
943 returned. This function must guarantee that all PCI read and write operations
946 If Address > 0x0FFFFFFF, then ASSERT().
947 If Address is not aligned on a 32-bit boundary, then ASSERT().
948 If the register specified by Address >= 0x100, then ASSERT().
950 @param Address Address that encodes the PCI Bus, Device, Function and
952 @param OrData The value to OR with the PCI configuration register.
954 @return The value written back to the PCI configuration register.
964 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
965 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
967 PCI_CONFIGURATION_DATA_PORT
,
973 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
976 Reads the 32-bit PCI configuration register specified by Address, performs a
977 bitwise AND between the read result and the value specified by AndData, and
978 writes the result to the 32-bit PCI configuration register specified by
979 Address. The value written to the PCI configuration register is returned.
980 This function must guarantee that all PCI read and write operations are
983 If Address > 0x0FFFFFFF, then ASSERT().
984 If Address is not aligned on a 32-bit boundary, then ASSERT().
985 If the register specified by Address >= 0x100, then ASSERT().
987 @param Address Address that encodes the PCI Bus, Device, Function and
989 @param AndData The value to AND with the PCI configuration register.
991 @return The value written back to the PCI configuration register.
1001 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1002 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1004 PCI_CONFIGURATION_DATA_PORT
,
1010 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1011 value, followed a bitwise inclusive OR with another 32-bit value.
1013 Reads the 32-bit PCI configuration register specified by Address, performs a
1014 bitwise AND between the read result and the value specified by AndData,
1015 performs a bitwise inclusive OR between the result of the AND operation and
1016 the value specified by OrData, and writes the result to the 32-bit PCI
1017 configuration register specified by Address. The value written to the PCI
1018 configuration register is returned. This function must guarantee that all PCI
1019 read and write operations are serialized.
1021 If Address > 0x0FFFFFFF, then ASSERT().
1022 If Address is not aligned on a 32-bit boundary, then ASSERT().
1023 If the register specified by Address >= 0x100, then ASSERT().
1025 @param Address Address that encodes the PCI Bus, Device, Function and
1027 @param AndData The value to AND with the PCI configuration register.
1028 @param OrData The value to OR with the result of the AND operation.
1030 @return The value written back to the PCI configuration register.
1041 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1042 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1043 return IoAndThenOr32 (
1044 PCI_CONFIGURATION_DATA_PORT
,
1051 Reads a bit field of a PCI configuration register.
1053 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1054 specified by the StartBit and the EndBit. The value of the bit field is
1057 If Address > 0x0FFFFFFF, then ASSERT().
1058 If Address is not aligned on a 32-bit boundary, then ASSERT().
1059 If the register specified by Address >= 0x100, then ASSERT().
1060 If StartBit is greater than 31, then ASSERT().
1061 If EndBit is greater than 31, then ASSERT().
1062 If EndBit is less than StartBit, then ASSERT().
1064 @param Address PCI configuration register to read.
1065 @param StartBit The ordinal of the least significant bit in the bit field.
1067 @param EndBit The ordinal of the most significant bit in the bit field.
1070 @return The value of the bit field read from the PCI configuration register.
1075 PciCf8BitFieldRead32 (
1081 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1082 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1083 return IoBitFieldRead32 (
1084 PCI_CONFIGURATION_DATA_PORT
,
1091 Writes a bit field to a PCI configuration register.
1093 Writes Value to the bit field of the PCI configuration register. The bit
1094 field is specified by the StartBit and the EndBit. All other bits in the
1095 destination PCI configuration register are preserved. The new value of the
1096 32-bit register is returned.
1098 If Address > 0x0FFFFFFF, then ASSERT().
1099 If Address is not aligned on a 32-bit boundary, then ASSERT().
1100 If the register specified by Address >= 0x100, then ASSERT().
1101 If StartBit is greater than 31, then ASSERT().
1102 If EndBit is greater than 31, then ASSERT().
1103 If EndBit is less than StartBit, then ASSERT().
1105 @param Address PCI configuration register to write.
1106 @param StartBit The ordinal of the least significant bit in the bit field.
1108 @param EndBit The ordinal of the most significant bit in the bit field.
1110 @param Value New value of the bit field.
1112 @return The value written back to the PCI configuration register.
1117 PciCf8BitFieldWrite32 (
1124 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1125 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1126 return IoBitFieldWrite32 (
1127 PCI_CONFIGURATION_DATA_PORT
,
1135 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1136 writes the result back to the bit field in the 32-bit port.
1138 Reads the 32-bit PCI configuration register specified by Address, performs a
1139 bitwise inclusive OR between the read result and the value specified by
1140 OrData, and writes the result to the 32-bit PCI configuration register
1141 specified by Address. The value written to the PCI configuration register is
1142 returned. This function must guarantee that all PCI read and write operations
1143 are serialized. Extra left bits in OrData are stripped.
1145 If Address > 0x0FFFFFFF, then ASSERT().
1146 If Address is not aligned on a 32-bit boundary, then ASSERT().
1147 If the register specified by Address >= 0x100, then ASSERT().
1148 If StartBit is greater than 31, then ASSERT().
1149 If EndBit is greater than 31, then ASSERT().
1150 If EndBit is less than StartBit, then ASSERT().
1152 @param Address PCI configuration register to write.
1153 @param StartBit The ordinal of the least significant bit in the bit field.
1155 @param EndBit The ordinal of the most significant bit in the bit field.
1157 @param OrData The value to OR with the PCI configuration register.
1159 @return The value written back to the PCI configuration register.
1164 PciCf8BitFieldOr32 (
1171 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1172 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1173 return IoBitFieldOr32 (
1174 PCI_CONFIGURATION_DATA_PORT
,
1182 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1183 AND, and writes the result back to the bit field in the 32-bit register.
1185 Reads the 32-bit PCI configuration register specified by Address, performs a
1186 bitwise AND between the read result and the value specified by AndData, and
1187 writes the result to the 32-bit PCI configuration register specified by
1188 Address. The value written to the PCI configuration register is returned.
1189 This function must guarantee that all PCI read and write operations are
1190 serialized. Extra left bits in AndData are stripped.
1192 If Address > 0x0FFFFFFF, then ASSERT().
1193 If Address is not aligned on a 32-bit boundary, then ASSERT().
1194 If the register specified by Address >= 0x100, then ASSERT().
1195 If StartBit is greater than 31, then ASSERT().
1196 If EndBit is greater than 31, then ASSERT().
1197 If EndBit is less than StartBit, then ASSERT().
1199 @param Address PCI configuration register to write.
1200 @param StartBit The ordinal of the least significant bit in the bit field.
1202 @param EndBit The ordinal of the most significant bit in the bit field.
1204 @param AndData The value to AND with the PCI configuration register.
1206 @return The value written back to the PCI configuration register.
1211 PciCf8BitFieldAnd32 (
1218 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1219 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1220 return IoBitFieldAnd32 (
1221 PCI_CONFIGURATION_DATA_PORT
,
1229 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1230 bitwise inclusive OR, and writes the result back to the bit field in the
1233 Reads the 32-bit PCI configuration register specified by Address, performs a
1234 bitwise AND followed by a bitwise inclusive OR between the read result and
1235 the value specified by AndData, and writes the result to the 32-bit PCI
1236 configuration register specified by Address. The value written to the PCI
1237 configuration register is returned. This function must guarantee that all PCI
1238 read and write operations are serialized. Extra left bits in both AndData and
1239 OrData are stripped.
1241 If Address > 0x0FFFFFFF, then ASSERT().
1242 If Address is not aligned on a 32-bit boundary, then ASSERT().
1243 If the register specified by Address >= 0x100, then ASSERT().
1244 If StartBit is greater than 31, then ASSERT().
1245 If EndBit is greater than 31, then ASSERT().
1246 If EndBit is less than StartBit, then ASSERT().
1248 @param Address PCI configuration register to write.
1249 @param StartBit The ordinal of the least significant bit in the bit field.
1251 @param EndBit The ordinal of the most significant bit in the bit field.
1253 @param AndData The value to AND with the PCI configuration register.
1254 @param OrData The value to OR with the result of the AND operation.
1256 @return The value written back to the PCI configuration register.
1261 PciCf8BitFieldAndThenOr32(
1269 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1270 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1271 return IoBitFieldAndThenOr32 (
1272 PCI_CONFIGURATION_DATA_PORT
,
1281 Reads a range of PCI configuration registers into a caller supplied buffer.
1283 Reads the range of PCI configuration registers specified by StartAddress and
1284 Size into the buffer specified by Buffer. This function only allows the PCI
1285 configuration registers from a single PCI function to be read. Size is
1286 returned. When possible 32-bit PCI configuration read cycles are used to read
1287 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1288 and 16-bit PCI configuration read cycles may be used at the beginning and the
1291 If StartAddress > 0x0FFFFFFF, then ASSERT().
1292 If the register specified by StartAddress >= 0x100, then ASSERT().
1293 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1294 If Size > 0 and Buffer is NULL, then ASSERT().
1296 @param StartAddress Starting address that encodes the PCI Bus, Device,
1297 Function and Register.
1298 @param Size Size in bytes of the transfer.
1299 @param Buffer Pointer to a buffer receiving the data read.
1307 IN UINTN StartAddress
,
1314 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1315 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1321 ASSERT (Buffer
!= NULL
);
1324 // Save Size for return
1328 if ((StartAddress
& 1) != 0) {
1330 // Read a byte if StartAddress is byte aligned
1332 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1333 StartAddress
+= sizeof (UINT8
);
1334 Size
-= sizeof (UINT8
);
1335 Buffer
= (UINT8
*)Buffer
+ 1;
1338 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1340 // Read a word if StartAddress is word aligned
1342 *(volatile UINT16
*)Buffer
= PciCf8Read16 (StartAddress
);
1343 StartAddress
+= sizeof (UINT16
);
1344 Size
-= sizeof (UINT16
);
1345 Buffer
= (UINT16
*)Buffer
+ 1;
1348 while (Size
>= sizeof (UINT32
)) {
1350 // Read as many double words as possible
1352 *(volatile UINT32
*)Buffer
= PciCf8Read32 (StartAddress
);
1353 StartAddress
+= sizeof (UINT32
);
1354 Size
-= sizeof (UINT32
);
1355 Buffer
= (UINT32
*)Buffer
+ 1;
1358 if (Size
>= sizeof (UINT16
)) {
1360 // Read the last remaining word if exist
1362 *(volatile UINT16
*)Buffer
= PciCf8Read16 (StartAddress
);
1363 StartAddress
+= sizeof (UINT16
);
1364 Size
-= sizeof (UINT16
);
1365 Buffer
= (UINT16
*)Buffer
+ 1;
1368 if (Size
>= sizeof (UINT8
)) {
1370 // Read the last remaining byte if exist
1372 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1379 Copies the data in a caller supplied buffer to a specified range of PCI
1380 configuration space.
1382 Writes the range of PCI configuration registers specified by StartAddress and
1383 Size from the buffer specified by Buffer. This function only allows the PCI
1384 configuration registers from a single PCI function to be written. Size is
1385 returned. When possible 32-bit PCI configuration write cycles are used to
1386 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1387 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1388 and the end of the range.
1390 If StartAddress > 0x0FFFFFFF, then ASSERT().
1391 If the register specified by StartAddress >= 0x100, then ASSERT().
1392 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1393 If Size > 0 and Buffer is NULL, then ASSERT().
1395 @param StartAddress Starting address that encodes the PCI Bus, Device,
1396 Function and Register.
1397 @param Size Size in bytes of the transfer.
1398 @param Buffer Pointer to a buffer containing the data to write.
1406 IN UINTN StartAddress
,
1413 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1414 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1420 ASSERT (Buffer
!= NULL
);
1423 // Save Size for return
1427 if ((StartAddress
& 1) != 0) {
1429 // Write a byte if StartAddress is byte aligned
1431 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1432 StartAddress
+= sizeof (UINT8
);
1433 Size
-= sizeof (UINT8
);
1434 Buffer
= (UINT8
*)Buffer
+ 1;
1437 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1439 // Write a word if StartAddress is word aligned
1441 PciCf8Write16 (StartAddress
, *(UINT16
*)Buffer
);
1442 StartAddress
+= sizeof (UINT16
);
1443 Size
-= sizeof (UINT16
);
1444 Buffer
= (UINT16
*)Buffer
+ 1;
1447 while (Size
>= sizeof (UINT32
)) {
1449 // Write as many double words as possible
1451 PciCf8Write32 (StartAddress
, *(UINT32
*)Buffer
);
1452 StartAddress
+= sizeof (UINT32
);
1453 Size
-= sizeof (UINT32
);
1454 Buffer
= (UINT32
*)Buffer
+ 1;
1457 if (Size
>= sizeof (UINT16
)) {
1459 // Write the last remaining word if exist
1461 PciCf8Write16 (StartAddress
, *(UINT16
*)Buffer
);
1462 StartAddress
+= sizeof (UINT16
);
1463 Size
-= sizeof (UINT16
);
1464 Buffer
= (UINT16
*)Buffer
+ 1;
1467 if (Size
>= sizeof (UINT8
)) {
1469 // Write the last remaining byte if exist
1471 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);