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.
16 // The package level header files this module uses
20 // The protocols, PPI and GUID defintions for this module
23 // The Library classes this module consumes
25 #include <Library/PciCf8Lib.h>
26 #include <Library/IoLib.h>
27 #include <Library/DebugLib.h>
30 // Declare I/O Ports used to perform PCI Confguration Cycles
32 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
33 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
36 // Declare macro to convert PCI Library formatted address to CF8 formatted address
38 // PCI Library formatted address CF8 Formatted Address
39 // ============================= ======================
40 // Bits 00..11 Register Bits 00..07 Register
41 // Bits 12..14 Function Bits 08..10 Function
42 // Bits 15..19 Device Bits 11..15 Device
43 // Bits 20..27 Bus Bits 16..23 Bus
44 // Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
45 // Bits 31..31 Must be 1
49 Assert the validity of a PCI address. A valid PCI address should contain 1's
50 only in the low 28 bits.
52 @param A The address to validate.
53 @param M Additional bits to assert to be zero.
56 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
57 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
60 Convert a PCI Express address to PCI CF8 address.
62 @param A The address to convert.
64 @retval The coverted address.
67 #define PCI_TO_CF8_ADDRESS(A) \
68 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
71 Reads an 8-bit PCI configuration register.
73 Reads and returns the 8-bit PCI configuration register specified by Address.
74 This function must guarantee that all PCI read and write operations are
77 If Address > 0x0FFFFFFF, then ASSERT().
78 If the register specified by Address >= 0x100, then ASSERT().
80 @param Address Address that encodes the PCI Bus, Device, Function and
83 @return The read value from the PCI configuration register.
92 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
93 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
94 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
98 Writes an 8-bit PCI configuration register.
100 Writes the 8-bit PCI configuration register specified by Address with the
101 value specified by Value. Value is returned. This function must guarantee
102 that all PCI read and write operations are serialized.
104 If Address > 0x0FFFFFFF, then ASSERT().
105 If the register specified by Address >= 0x100, then ASSERT().
107 @param Address Address that encodes the PCI Bus, Device, Function and
109 @param Value The value to write.
111 @return The value written to the PCI configuration register.
121 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
122 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
124 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
130 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
133 Reads the 8-bit PCI configuration register specified by Address, performs a
134 bitwise inclusive OR between the read result and the value specified by
135 OrData, and writes the result to the 8-bit PCI configuration register
136 specified by Address. The value written to the PCI configuration register is
137 returned. This function must guarantee that all PCI read and write operations
140 If Address > 0x0FFFFFFF, then ASSERT().
141 If the register specified by Address >= 0x100, then ASSERT().
143 @param Address Address that encodes the PCI Bus, Device, Function and
145 @param OrData The value to OR with the PCI configuration register.
147 @return The value written back to the PCI configuration register.
157 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
158 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
160 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
166 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
169 Reads the 8-bit PCI configuration register specified by Address, performs a
170 bitwise AND between the read result and the value specified by AndData, and
171 writes the result to the 8-bit PCI configuration register specified by
172 Address. The value written to the PCI configuration register is returned.
173 This function must guarantee that all PCI read and write operations are
176 If Address > 0x0FFFFFFF, then ASSERT().
177 If the register specified by Address >= 0x100, then ASSERT().
179 @param Address Address that encodes the PCI Bus, Device, Function and
181 @param AndData The value to AND with the PCI configuration register.
183 @return The value written back to the PCI configuration register.
193 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
194 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
196 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
202 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
203 value, followed a bitwise inclusive OR with another 8-bit value.
205 Reads the 8-bit PCI configuration register specified by Address, performs a
206 bitwise AND between the read result and the value specified by AndData,
207 performs a bitwise inclusive OR between the result of the AND operation and
208 the value specified by OrData, and writes the result to the 8-bit PCI
209 configuration register specified by Address. The value written to the PCI
210 configuration register is returned. This function must guarantee that all PCI
211 read and write operations are serialized.
213 If Address > 0x0FFFFFFF, then ASSERT().
214 If the register specified by Address >= 0x100, then ASSERT().
216 @param Address Address that encodes the PCI Bus, Device, Function and
218 @param AndData The value to AND with the PCI configuration register.
219 @param OrData The value to OR with the result of the AND operation.
221 @return The value written back to the PCI configuration register.
232 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
233 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
234 return IoAndThenOr8 (
235 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
242 Reads a bit field of a PCI configuration register.
244 Reads the bit field in an 8-bit PCI configuration register. The bit field is
245 specified by the StartBit and the EndBit. The value of the bit field is
248 If Address > 0x0FFFFFFF, then ASSERT().
249 If the register specified by Address >= 0x100, then ASSERT().
250 If StartBit is greater than 7, then ASSERT().
251 If EndBit is greater than 7, then ASSERT().
252 If EndBit is less than StartBit, then ASSERT().
254 @param Address PCI configuration register to read.
255 @param StartBit The ordinal of the least significant bit in the bit field.
257 @param EndBit The ordinal of the most significant bit in the bit field.
260 @return The value of the bit field read from the PCI configuration register.
265 PciCf8BitFieldRead8 (
271 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
272 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
273 return IoBitFieldRead8 (
274 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
281 Writes a bit field to a PCI configuration register.
283 Writes Value to the bit field of the PCI configuration register. The bit
284 field is specified by the StartBit and the EndBit. All other bits in the
285 destination PCI configuration register are preserved. The new value of the
286 8-bit register is returned.
288 If Address > 0x0FFFFFFF, then ASSERT().
289 If the register specified by Address >= 0x100, then ASSERT().
290 If StartBit is greater than 7, then ASSERT().
291 If EndBit is greater than 7, then ASSERT().
292 If EndBit is less than StartBit, then ASSERT().
294 @param Address PCI configuration register to write.
295 @param StartBit The ordinal of the least significant bit in the bit field.
297 @param EndBit The ordinal of the most significant bit in the bit field.
299 @param Value New value of the bit field.
301 @return The value written back to the PCI configuration register.
306 PciCf8BitFieldWrite8 (
313 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
314 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
315 return IoBitFieldWrite8 (
316 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
324 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
325 writes the result back to the bit field in the 8-bit port.
327 Reads the 8-bit PCI configuration register specified by Address, performs a
328 bitwise inclusive OR between the read result and the value specified by
329 OrData, and writes the result to the 8-bit PCI configuration register
330 specified by Address. The value written to the PCI configuration register is
331 returned. This function must guarantee that all PCI read and write operations
332 are serialized. Extra left bits in OrData are stripped.
334 If Address > 0x0FFFFFFF, then ASSERT().
335 If the register specified by Address >= 0x100, then ASSERT().
336 If StartBit is greater than 7, then ASSERT().
337 If EndBit is greater than 7, then ASSERT().
338 If EndBit is less than StartBit, then ASSERT().
340 @param Address PCI configuration register to write.
341 @param StartBit The ordinal of the least significant bit in the bit field.
343 @param EndBit The ordinal of the most significant bit in the bit field.
345 @param OrData The value to OR with the PCI configuration register.
347 @return The value written back to the PCI configuration register.
359 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
360 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
361 return IoBitFieldOr8 (
362 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
370 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
371 AND, and writes the result back to the bit field in the 8-bit register.
373 Reads the 8-bit PCI configuration register specified by Address, performs a
374 bitwise AND between the read result and the value specified by AndData, and
375 writes the result to the 8-bit PCI configuration register specified by
376 Address. The value written to the PCI configuration register is returned.
377 This function must guarantee that all PCI read and write operations are
378 serialized. Extra left bits in AndData are stripped.
380 If Address > 0x0FFFFFFF, then ASSERT().
381 If the register specified by Address >= 0x100, then ASSERT().
382 If StartBit is greater than 7, then ASSERT().
383 If EndBit is greater than 7, then ASSERT().
384 If EndBit is less than StartBit, then ASSERT().
386 @param Address PCI configuration register to write.
387 @param StartBit The ordinal of the least significant bit in the bit field.
389 @param EndBit The ordinal of the most significant bit in the bit field.
391 @param AndData The value to AND with the PCI configuration register.
393 @return The value written back to the PCI configuration register.
405 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
406 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
407 return IoBitFieldAnd8 (
408 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
416 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
417 bitwise inclusive OR, and writes the result back to the bit field in the
420 Reads the 8-bit PCI configuration register specified by Address, performs a
421 bitwise AND followed by a bitwise inclusive OR between the read result and
422 the value specified by AndData, and writes the result to the 8-bit PCI
423 configuration register specified by Address. The value written to the PCI
424 configuration register is returned. This function must guarantee that all PCI
425 read and write operations are serialized. Extra left bits in both AndData and
428 If Address > 0x0FFFFFFF, then ASSERT().
429 If the register specified by Address >= 0x100, then ASSERT().
430 If StartBit is greater than 7, then ASSERT().
431 If EndBit is greater than 7, then ASSERT().
432 If EndBit is less than StartBit, then ASSERT().
434 @param Address PCI configuration register to write.
435 @param StartBit The ordinal of the least significant bit in the bit field.
437 @param EndBit The ordinal of the most significant bit in the bit field.
439 @param AndData The value to AND with the PCI configuration register.
440 @param OrData The value to OR with the result of the AND operation.
442 @return The value written back to the PCI configuration register.
447 PciCf8BitFieldAndThenOr8(
455 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
456 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
457 return IoBitFieldAndThenOr8 (
458 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
467 Reads a 16-bit PCI configuration register.
469 Reads and returns the 16-bit PCI configuration register specified by Address.
470 This function must guarantee that all PCI read and write operations are
473 If Address > 0x0FFFFFFF, then ASSERT().
474 If Address is not aligned on a 16-bit boundary, then ASSERT().
475 If the register specified by Address >= 0x100, then ASSERT().
477 @param Address Address that encodes the PCI Bus, Device, Function and
480 @return The read value from the PCI configuration register.
489 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
490 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
491 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
495 Writes a 16-bit PCI configuration register.
497 Writes the 16-bit PCI configuration register specified by Address with the
498 value specified by Value. Value is returned. This function must guarantee
499 that all PCI read and write operations are serialized.
501 If Address > 0x0FFFFFFF, then ASSERT().
502 If Address is not aligned on a 16-bit boundary, then ASSERT().
503 If the register specified by Address >= 0x100, then ASSERT().
505 @param Address Address that encodes the PCI Bus, Device, Function and
507 @param Value The value to write.
509 @return The value written to the PCI configuration register.
519 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
520 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
522 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
528 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
531 Reads the 16-bit PCI configuration register specified by Address, performs a
532 bitwise inclusive OR between the read result and the value specified by
533 OrData, and writes the result to the 16-bit PCI configuration register
534 specified by Address. The value written to the PCI configuration register is
535 returned. This function must guarantee that all PCI read and write operations
538 If Address > 0x0FFFFFFF, then ASSERT().
539 If Address is not aligned on a 16-bit boundary, then ASSERT().
540 If the register specified by Address >= 0x100, then ASSERT().
542 @param Address Address that encodes the PCI Bus, Device, Function and
544 @param OrData The value to OR with the PCI configuration register.
546 @return The value written back to the PCI configuration register.
556 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
557 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
559 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
565 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
568 Reads the 16-bit PCI configuration register specified by Address, performs a
569 bitwise AND between the read result and the value specified by AndData, and
570 writes the result to the 16-bit PCI configuration register specified by
571 Address. The value written to the PCI configuration register is returned.
572 This function must guarantee that all PCI read and write operations are
575 If Address > 0x0FFFFFFF, then ASSERT().
576 If Address is not aligned on a 16-bit boundary, then ASSERT().
577 If the register specified by Address >= 0x100, then ASSERT().
579 @param Address Address that encodes the PCI Bus, Device, Function and
581 @param AndData The value to AND with the PCI configuration register.
583 @return The value written back to the PCI configuration register.
593 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
594 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
596 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
602 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
603 value, followed a bitwise inclusive OR with another 16-bit value.
605 Reads the 16-bit PCI configuration register specified by Address, performs a
606 bitwise AND between the read result and the value specified by AndData,
607 performs a bitwise inclusive OR between the result of the AND operation and
608 the value specified by OrData, and writes the result to the 16-bit PCI
609 configuration register specified by Address. The value written to the PCI
610 configuration register is returned. This function must guarantee that all PCI
611 read and write operations are serialized.
613 If Address > 0x0FFFFFFF, then ASSERT().
614 If Address is not aligned on a 16-bit boundary, then ASSERT().
615 If the register specified by Address >= 0x100, then ASSERT().
617 @param Address Address that encodes the PCI Bus, Device, Function and
619 @param AndData The value to AND with the PCI configuration register.
620 @param OrData The value to OR with the result of the AND operation.
622 @return The value written back to the PCI configuration register.
633 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
634 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
635 return IoAndThenOr16 (
636 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
643 Reads a bit field of a PCI configuration register.
645 Reads the bit field in a 16-bit PCI configuration register. The bit field is
646 specified by the StartBit and the EndBit. The value of the bit field is
649 If Address > 0x0FFFFFFF, then ASSERT().
650 If Address is not aligned on a 16-bit boundary, then ASSERT().
651 If the register specified by Address >= 0x100, then ASSERT().
652 If StartBit is greater than 15, then ASSERT().
653 If EndBit is greater than 15, then ASSERT().
654 If EndBit is less than StartBit, then ASSERT().
656 @param Address PCI configuration register to read.
657 @param StartBit The ordinal of the least significant bit in the bit field.
659 @param EndBit The ordinal of the most significant bit in the bit field.
662 @return The value of the bit field read from the PCI configuration register.
667 PciCf8BitFieldRead16 (
673 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
674 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
675 return IoBitFieldRead16 (
676 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
683 Writes a bit field to a PCI configuration register.
685 Writes Value to the bit field of the PCI configuration register. The bit
686 field is specified by the StartBit and the EndBit. All other bits in the
687 destination PCI configuration register are preserved. The new value of the
688 16-bit register is returned.
690 If Address > 0x0FFFFFFF, then ASSERT().
691 If Address is not aligned on a 16-bit boundary, then ASSERT().
692 If the register specified by Address >= 0x100, then ASSERT().
693 If StartBit is greater than 15, then ASSERT().
694 If EndBit is greater than 15, then ASSERT().
695 If EndBit is less than StartBit, then ASSERT().
697 @param Address PCI configuration register to write.
698 @param StartBit The ordinal of the least significant bit in the bit field.
700 @param EndBit The ordinal of the most significant bit in the bit field.
702 @param Value New value of the bit field.
704 @return The value written back to the PCI configuration register.
709 PciCf8BitFieldWrite16 (
716 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
717 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
718 return IoBitFieldWrite16 (
719 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
727 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
728 writes the result back to the bit field in the 16-bit port.
730 Reads the 16-bit PCI configuration register specified by Address, performs a
731 bitwise inclusive OR between the read result and the value specified by
732 OrData, and writes the result to the 16-bit PCI configuration register
733 specified by Address. The value written to the PCI configuration register is
734 returned. This function must guarantee that all PCI read and write operations
735 are serialized. Extra left bits in OrData are stripped.
737 If Address > 0x0FFFFFFF, then ASSERT().
738 If Address is not aligned on a 16-bit boundary, then ASSERT().
739 If the register specified by Address >= 0x100, then ASSERT().
740 If StartBit is greater than 15, then ASSERT().
741 If EndBit is greater than 15, then ASSERT().
742 If EndBit is less than StartBit, then ASSERT().
744 @param Address PCI configuration register to write.
745 @param StartBit The ordinal of the least significant bit in the bit field.
747 @param EndBit The ordinal of the most significant bit in the bit field.
749 @param OrData The value to OR with the PCI configuration register.
751 @return The value written back to the PCI configuration register.
763 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
764 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
765 return IoBitFieldOr16 (
766 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
774 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
775 AND, and writes the result back to the bit field in the 16-bit register.
777 Reads the 16-bit PCI configuration register specified by Address, performs a
778 bitwise AND between the read result and the value specified by AndData, and
779 writes the result to the 16-bit PCI configuration register specified by
780 Address. The value written to the PCI configuration register is returned.
781 This function must guarantee that all PCI read and write operations are
782 serialized. Extra left bits in AndData are stripped.
784 If Address > 0x0FFFFFFF, then ASSERT().
785 If Address is not aligned on a 16-bit boundary, then ASSERT().
786 If the register specified by Address >= 0x100, then ASSERT().
787 If StartBit is greater than 15, then ASSERT().
788 If EndBit is greater than 15, then ASSERT().
789 If EndBit is less than StartBit, then ASSERT().
791 @param Address PCI configuration register to write.
792 @param StartBit The ordinal of the least significant bit in the bit field.
794 @param EndBit The ordinal of the most significant bit in the bit field.
796 @param AndData The value to AND with the PCI configuration register.
798 @return The value written back to the PCI configuration register.
803 PciCf8BitFieldAnd16 (
810 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
811 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
812 return IoBitFieldAnd16 (
813 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
821 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
822 bitwise inclusive OR, and writes the result back to the bit field in the
825 Reads the 16-bit PCI configuration register specified by Address, performs a
826 bitwise AND followed by a bitwise inclusive OR between the read result and
827 the value specified by AndData, and writes the result to the 16-bit PCI
828 configuration register specified by Address. The value written to the PCI
829 configuration register is returned. This function must guarantee that all PCI
830 read and write operations are serialized. Extra left bits in both AndData and
833 If Address > 0x0FFFFFFF, then ASSERT().
834 If Address is not aligned on a 16-bit boundary, then ASSERT().
835 If the register specified by Address >= 0x100, then ASSERT().
836 If StartBit is greater than 15, then ASSERT().
837 If EndBit is greater than 15, then ASSERT().
838 If EndBit is less than StartBit, then ASSERT().
840 @param Address PCI configuration register to write.
841 @param StartBit The ordinal of the least significant bit in the bit field.
843 @param EndBit The ordinal of the most significant bit in the bit field.
845 @param AndData The value to AND with the PCI configuration register.
846 @param OrData The value to OR with the result of the AND operation.
848 @return The value written back to the PCI configuration register.
853 PciCf8BitFieldAndThenOr16(
861 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
862 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
863 return IoBitFieldAndThenOr16 (
864 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
873 Reads a 32-bit PCI configuration register.
875 Reads and returns the 32-bit PCI configuration register specified by Address.
876 This function must guarantee that all PCI read and write operations are
879 If Address > 0x0FFFFFFF, then ASSERT().
880 If Address is not aligned on a 32-bit boundary, then ASSERT().
881 If the register specified by Address >= 0x100, then ASSERT().
883 @param Address Address that encodes the PCI Bus, Device, Function and
886 @return The read value from the PCI configuration register.
895 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
896 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
897 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
901 Writes a 32-bit PCI configuration register.
903 Writes the 32-bit PCI configuration register specified by Address with the
904 value specified by Value. Value is returned. This function must guarantee
905 that all PCI read and write operations are serialized.
907 If Address > 0x0FFFFFFF, then ASSERT().
908 If Address is not aligned on a 32-bit boundary, then ASSERT().
909 If the register specified by Address >= 0x100, then ASSERT().
911 @param Address Address that encodes the PCI Bus, Device, Function and
913 @param Value The value to write.
915 @return The value written to the PCI configuration register.
925 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
926 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
928 PCI_CONFIGURATION_DATA_PORT
,
934 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
937 Reads the 32-bit PCI configuration register specified by Address, performs a
938 bitwise inclusive OR between the read result and the value specified by
939 OrData, and writes the result to the 32-bit PCI configuration register
940 specified by Address. The value written to the PCI configuration register is
941 returned. This function must guarantee that all PCI read and write operations
944 If Address > 0x0FFFFFFF, then ASSERT().
945 If Address is not aligned on a 32-bit boundary, then ASSERT().
946 If the register specified by Address >= 0x100, then ASSERT().
948 @param Address Address that encodes the PCI Bus, Device, Function and
950 @param OrData The value to OR with the PCI configuration register.
952 @return The value written back to the PCI configuration register.
962 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
963 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
965 PCI_CONFIGURATION_DATA_PORT
,
971 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
974 Reads the 32-bit PCI configuration register specified by Address, performs a
975 bitwise AND between the read result and the value specified by AndData, and
976 writes the result to the 32-bit PCI configuration register specified by
977 Address. The value written to the PCI configuration register is returned.
978 This function must guarantee that all PCI read and write operations are
981 If Address > 0x0FFFFFFF, then ASSERT().
982 If Address is not aligned on a 32-bit boundary, then ASSERT().
983 If the register specified by Address >= 0x100, then ASSERT().
985 @param Address Address that encodes the PCI Bus, Device, Function and
987 @param AndData The value to AND with the PCI configuration register.
989 @return The value written back to the PCI configuration register.
999 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1000 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1002 PCI_CONFIGURATION_DATA_PORT
,
1008 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1009 value, followed a bitwise inclusive OR with another 32-bit value.
1011 Reads the 32-bit PCI configuration register specified by Address, performs a
1012 bitwise AND between the read result and the value specified by AndData,
1013 performs a bitwise inclusive OR between the result of the AND operation and
1014 the value specified by OrData, and writes the result to the 32-bit PCI
1015 configuration register specified by Address. The value written to the PCI
1016 configuration register is returned. This function must guarantee that all PCI
1017 read and write operations are serialized.
1019 If Address > 0x0FFFFFFF, then ASSERT().
1020 If Address is not aligned on a 32-bit boundary, then ASSERT().
1021 If the register specified by Address >= 0x100, then ASSERT().
1023 @param Address Address that encodes the PCI Bus, Device, Function and
1025 @param AndData The value to AND with the PCI configuration register.
1026 @param OrData The value to OR with the result of the AND operation.
1028 @return The value written back to the PCI configuration register.
1039 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1040 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1041 return IoAndThenOr32 (
1042 PCI_CONFIGURATION_DATA_PORT
,
1049 Reads a bit field of a PCI configuration register.
1051 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1052 specified by the StartBit and the EndBit. The value of the bit field is
1055 If Address > 0x0FFFFFFF, then ASSERT().
1056 If Address is not aligned on a 32-bit boundary, then ASSERT().
1057 If the register specified by Address >= 0x100, then ASSERT().
1058 If StartBit is greater than 31, then ASSERT().
1059 If EndBit is greater than 31, then ASSERT().
1060 If EndBit is less than StartBit, then ASSERT().
1062 @param Address PCI configuration register to read.
1063 @param StartBit The ordinal of the least significant bit in the bit field.
1065 @param EndBit The ordinal of the most significant bit in the bit field.
1068 @return The value of the bit field read from the PCI configuration register.
1073 PciCf8BitFieldRead32 (
1079 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1080 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1081 return IoBitFieldRead32 (
1082 PCI_CONFIGURATION_DATA_PORT
,
1089 Writes a bit field to a PCI configuration register.
1091 Writes Value to the bit field of the PCI configuration register. The bit
1092 field is specified by the StartBit and the EndBit. All other bits in the
1093 destination PCI configuration register are preserved. The new value of the
1094 32-bit register is returned.
1096 If Address > 0x0FFFFFFF, then ASSERT().
1097 If Address is not aligned on a 32-bit boundary, then ASSERT().
1098 If the register specified by Address >= 0x100, then ASSERT().
1099 If StartBit is greater than 31, then ASSERT().
1100 If EndBit is greater than 31, then ASSERT().
1101 If EndBit is less than StartBit, then ASSERT().
1103 @param Address PCI configuration register to write.
1104 @param StartBit The ordinal of the least significant bit in the bit field.
1106 @param EndBit The ordinal of the most significant bit in the bit field.
1108 @param Value New value of the bit field.
1110 @return The value written back to the PCI configuration register.
1115 PciCf8BitFieldWrite32 (
1122 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1123 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1124 return IoBitFieldWrite32 (
1125 PCI_CONFIGURATION_DATA_PORT
,
1133 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1134 writes the result back to the bit field in the 32-bit port.
1136 Reads the 32-bit PCI configuration register specified by Address, performs a
1137 bitwise inclusive OR between the read result and the value specified by
1138 OrData, and writes the result to the 32-bit PCI configuration register
1139 specified by Address. The value written to the PCI configuration register is
1140 returned. This function must guarantee that all PCI read and write operations
1141 are serialized. Extra left bits in OrData are stripped.
1143 If Address > 0x0FFFFFFF, then ASSERT().
1144 If Address is not aligned on a 32-bit boundary, then ASSERT().
1145 If the register specified by Address >= 0x100, then ASSERT().
1146 If StartBit is greater than 31, then ASSERT().
1147 If EndBit is greater than 31, then ASSERT().
1148 If EndBit is less than StartBit, then ASSERT().
1150 @param Address PCI configuration register to write.
1151 @param StartBit The ordinal of the least significant bit in the bit field.
1153 @param EndBit The ordinal of the most significant bit in the bit field.
1155 @param OrData The value to OR with the PCI configuration register.
1157 @return The value written back to the PCI configuration register.
1162 PciCf8BitFieldOr32 (
1169 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1170 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1171 return IoBitFieldOr32 (
1172 PCI_CONFIGURATION_DATA_PORT
,
1180 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1181 AND, and writes the result back to the bit field in the 32-bit register.
1183 Reads the 32-bit PCI configuration register specified by Address, performs a
1184 bitwise AND between the read result and the value specified by AndData, and
1185 writes the result to the 32-bit PCI configuration register specified by
1186 Address. The value written to the PCI configuration register is returned.
1187 This function must guarantee that all PCI read and write operations are
1188 serialized. Extra left bits in AndData are stripped.
1190 If Address > 0x0FFFFFFF, then ASSERT().
1191 If Address is not aligned on a 32-bit boundary, then ASSERT().
1192 If the register specified by Address >= 0x100, then ASSERT().
1193 If StartBit is greater than 31, then ASSERT().
1194 If EndBit is greater than 31, then ASSERT().
1195 If EndBit is less than StartBit, then ASSERT().
1197 @param Address PCI configuration register to write.
1198 @param StartBit The ordinal of the least significant bit in the bit field.
1200 @param EndBit The ordinal of the most significant bit in the bit field.
1202 @param AndData The value to AND with the PCI configuration register.
1204 @return The value written back to the PCI configuration register.
1209 PciCf8BitFieldAnd32 (
1216 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1217 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1218 return IoBitFieldAnd32 (
1219 PCI_CONFIGURATION_DATA_PORT
,
1227 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1228 bitwise inclusive OR, and writes the result back to the bit field in the
1231 Reads the 32-bit PCI configuration register specified by Address, performs a
1232 bitwise AND followed by a bitwise inclusive OR between the read result and
1233 the value specified by AndData, and writes the result to the 32-bit PCI
1234 configuration register specified by Address. The value written to the PCI
1235 configuration register is returned. This function must guarantee that all PCI
1236 read and write operations are serialized. Extra left bits in both AndData and
1237 OrData are stripped.
1239 If Address > 0x0FFFFFFF, then ASSERT().
1240 If Address is not aligned on a 32-bit boundary, then ASSERT().
1241 If the register specified by Address >= 0x100, then ASSERT().
1242 If StartBit is greater than 31, then ASSERT().
1243 If EndBit is greater than 31, then ASSERT().
1244 If EndBit is less than StartBit, then ASSERT().
1246 @param Address PCI configuration register to write.
1247 @param StartBit The ordinal of the least significant bit in the bit field.
1249 @param EndBit The ordinal of the most significant bit in the bit field.
1251 @param AndData The value to AND with the PCI configuration register.
1252 @param OrData The value to OR with the result of the AND operation.
1254 @return The value written back to the PCI configuration register.
1259 PciCf8BitFieldAndThenOr32(
1267 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1268 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1269 return IoBitFieldAndThenOr32 (
1270 PCI_CONFIGURATION_DATA_PORT
,
1279 Reads a range of PCI configuration registers into a caller supplied buffer.
1281 Reads the range of PCI configuration registers specified by StartAddress and
1282 Size into the buffer specified by Buffer. This function only allows the PCI
1283 configuration registers from a single PCI function to be read. Size is
1284 returned. When possible 32-bit PCI configuration read cycles are used to read
1285 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1286 and 16-bit PCI configuration read cycles may be used at the beginning and the
1289 If StartAddress > 0x0FFFFFFF, then ASSERT().
1290 If the register specified by StartAddress >= 0x100, then ASSERT().
1291 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1292 If Size > 0 and Buffer is NULL, then ASSERT().
1294 @param StartAddress Starting address that encodes the PCI Bus, Device,
1295 Function and Register.
1296 @param Size Size in bytes of the transfer.
1297 @param Buffer Pointer to a buffer receiving the data read.
1305 IN UINTN StartAddress
,
1312 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1313 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1319 ASSERT (Buffer
!= NULL
);
1322 // Save Size for return
1326 if ((StartAddress
& 1) != 0) {
1328 // Read a byte if StartAddress is byte aligned
1330 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1331 StartAddress
+= sizeof (UINT8
);
1332 Size
-= sizeof (UINT8
);
1333 Buffer
= (UINT8
*)Buffer
+ 1;
1336 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1338 // Read a word if StartAddress is word aligned
1340 *(volatile UINT16
*)Buffer
= PciCf8Read16 (StartAddress
);
1341 StartAddress
+= sizeof (UINT16
);
1342 Size
-= sizeof (UINT16
);
1343 Buffer
= (UINT16
*)Buffer
+ 1;
1346 while (Size
>= sizeof (UINT32
)) {
1348 // Read as many double words as possible
1350 *(volatile UINT32
*)Buffer
= PciCf8Read32 (StartAddress
);
1351 StartAddress
+= sizeof (UINT32
);
1352 Size
-= sizeof (UINT32
);
1353 Buffer
= (UINT32
*)Buffer
+ 1;
1356 if (Size
>= sizeof (UINT16
)) {
1358 // Read the last remaining word if exist
1360 *(volatile UINT16
*)Buffer
= PciCf8Read16 (StartAddress
);
1361 StartAddress
+= sizeof (UINT16
);
1362 Size
-= sizeof (UINT16
);
1363 Buffer
= (UINT16
*)Buffer
+ 1;
1366 if (Size
>= sizeof (UINT8
)) {
1368 // Read the last remaining byte if exist
1370 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1377 Copies the data in a caller supplied buffer to a specified range of PCI
1378 configuration space.
1380 Writes the range of PCI configuration registers specified by StartAddress and
1381 Size from the buffer specified by Buffer. This function only allows the PCI
1382 configuration registers from a single PCI function to be written. Size is
1383 returned. When possible 32-bit PCI configuration write cycles are used to
1384 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1385 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1386 and the end of the range.
1388 If StartAddress > 0x0FFFFFFF, then ASSERT().
1389 If the register specified by StartAddress >= 0x100, then ASSERT().
1390 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1391 If Size > 0 and Buffer is NULL, then ASSERT().
1393 @param StartAddress Starting address that encodes the PCI Bus, Device,
1394 Function and Register.
1395 @param Size Size in bytes of the transfer.
1396 @param Buffer Pointer to a buffer containing the data to write.
1404 IN UINTN StartAddress
,
1411 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1412 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1418 ASSERT (Buffer
!= NULL
);
1421 // Save Size for return
1425 if ((StartAddress
& 1) != 0) {
1427 // Write a byte if StartAddress is byte aligned
1429 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1430 StartAddress
+= sizeof (UINT8
);
1431 Size
-= sizeof (UINT8
);
1432 Buffer
= (UINT8
*)Buffer
+ 1;
1435 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1437 // Write a word if StartAddress is word aligned
1439 PciCf8Write16 (StartAddress
, *(UINT16
*)Buffer
);
1440 StartAddress
+= sizeof (UINT16
);
1441 Size
-= sizeof (UINT16
);
1442 Buffer
= (UINT16
*)Buffer
+ 1;
1445 while (Size
>= sizeof (UINT32
)) {
1447 // Write as many double words as possible
1449 PciCf8Write32 (StartAddress
, *(UINT32
*)Buffer
);
1450 StartAddress
+= sizeof (UINT32
);
1451 Size
-= sizeof (UINT32
);
1452 Buffer
= (UINT32
*)Buffer
+ 1;
1455 if (Size
>= sizeof (UINT16
)) {
1457 // Write the last remaining word if exist
1459 PciCf8Write16 (StartAddress
, *(UINT16
*)Buffer
);
1460 StartAddress
+= sizeof (UINT16
);
1461 Size
-= sizeof (UINT16
);
1462 Buffer
= (UINT16
*)Buffer
+ 1;
1465 if (Size
>= sizeof (UINT8
)) {
1467 // Write the last remaining byte if exist
1469 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);