3 Copyright (c) 2004 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include "EdkIIGlueBase.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 // Declare macro to convert PCI Library formatted address to CF8 formatted address
33 // PCI Library formatted address CF8 Formatted Address
34 // ============================= ======================
35 // Bits 00..11 Register Bits 00..07 Register
36 // Bits 12..14 Function Bits 08..10 Function
37 // Bits 15..19 Device Bits 11..15 Device
38 // Bits 20..27 Bus Bits 16..23 Bus
39 // Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
40 // Bits 31..31 Must be 1
44 Assert the validity of a PCI address. A valid PCI address should contain 1's
45 only in the low 28 bits.
47 @param A The address to validate.
48 @param M Additional bits to assert to be zero.
51 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
52 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
55 Convert a PCI Express address to PCI CF8 address.
57 @param A The address to convert.
59 @retval The coverted address.
62 #define PCI_TO_CF8_ADDRESS(A) \
63 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
66 Reads an 8-bit PCI configuration register.
68 Reads and returns the 8-bit PCI configuration register specified by Address.
69 This function must guarantee that all PCI read and write operations are
72 If Address > 0x0FFFFFFF, then ASSERT().
73 If the register specified by Address >= 0x100, then ASSERT().
75 @param Address Address that encodes the PCI Bus, Device, Function and
78 @return The read value from the PCI configuration register.
87 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
88 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
89 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
93 Writes an 8-bit PCI configuration register.
95 Writes the 8-bit PCI configuration register specified by Address with the
96 value specified by Value. Value is returned. This function must guarantee
97 that all PCI read and write operations are serialized.
99 If Address > 0x0FFFFFFF, then ASSERT().
100 If the register specified by Address >= 0x100, then ASSERT().
102 @param Address Address that encodes the PCI Bus, Device, Function and
104 @param Value The value to write.
106 @return The value written to the PCI configuration register.
116 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
117 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
119 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
125 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
128 Reads the 8-bit PCI configuration register specified by Address, performs a
129 bitwise inclusive OR between the read result and the value specified by
130 OrData, and writes the result to the 8-bit PCI configuration register
131 specified by Address. The value written to the PCI configuration register is
132 returned. This function must guarantee that all PCI read and write operations
135 If Address > 0x0FFFFFFF, then ASSERT().
136 If the register specified by Address >= 0x100, then ASSERT().
138 @param Address Address that encodes the PCI Bus, Device, Function and
140 @param OrData The value to OR with the PCI configuration register.
142 @return The value written back to the PCI configuration register.
152 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
153 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
155 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
161 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
164 Reads the 8-bit PCI configuration register specified by Address, performs a
165 bitwise AND between the read result and the value specified by AndData, and
166 writes the result to the 8-bit PCI configuration register specified by
167 Address. The value written to the PCI configuration register is returned.
168 This function must guarantee that all PCI read and write operations are
171 If Address > 0x0FFFFFFF, then ASSERT().
172 If the register specified by Address >= 0x100, then ASSERT().
174 @param Address Address that encodes the PCI Bus, Device, Function and
176 @param AndData The value to AND with the PCI configuration register.
178 @return The value written back to the PCI configuration register.
188 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
189 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
191 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
197 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
198 value, followed a bitwise inclusive OR with another 8-bit value.
200 Reads the 8-bit PCI configuration register specified by Address, performs a
201 bitwise AND between the read result and the value specified by AndData,
202 performs a bitwise inclusive OR between the result of the AND operation and
203 the value specified by OrData, and writes the result to the 8-bit PCI
204 configuration register specified by Address. The value written to the PCI
205 configuration register is returned. This function must guarantee that all PCI
206 read and write operations are serialized.
208 If Address > 0x0FFFFFFF, then ASSERT().
209 If the register specified by Address >= 0x100, then ASSERT().
211 @param Address Address that encodes the PCI Bus, Device, Function and
213 @param AndData The value to AND with the PCI configuration register.
214 @param OrData The value to OR with the result of the AND operation.
216 @return The value written back to the PCI configuration register.
227 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
228 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
229 return IoAndThenOr8 (
230 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
237 Reads a bit field of a PCI configuration register.
239 Reads the bit field in an 8-bit PCI configuration register. The bit field is
240 specified by the StartBit and the EndBit. The value of the bit field is
243 If Address > 0x0FFFFFFF, then ASSERT().
244 If the register specified by Address >= 0x100, then ASSERT().
245 If StartBit is greater than 7, then ASSERT().
246 If EndBit is greater than 7, then ASSERT().
247 If EndBit is less than StartBit, then ASSERT().
249 @param Address PCI configuration register to read.
250 @param StartBit The ordinal of the least significant bit in the bit field.
252 @param EndBit The ordinal of the most significant bit in the bit field.
255 @return The value of the bit field read from the PCI configuration register.
260 PciCf8BitFieldRead8 (
266 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
267 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
268 return IoBitFieldRead8 (
269 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
276 Writes a bit field to a PCI configuration register.
278 Writes Value to the bit field of the PCI configuration register. The bit
279 field is specified by the StartBit and the EndBit. All other bits in the
280 destination PCI configuration register are preserved. The new value of the
281 8-bit register is returned.
283 If Address > 0x0FFFFFFF, then ASSERT().
284 If the register specified by Address >= 0x100, then ASSERT().
285 If StartBit is greater than 7, then ASSERT().
286 If EndBit is greater than 7, then ASSERT().
287 If EndBit is less than StartBit, then ASSERT().
289 @param Address PCI configuration register to write.
290 @param StartBit The ordinal of the least significant bit in the bit field.
292 @param EndBit The ordinal of the most significant bit in the bit field.
294 @param Value New value of the bit field.
296 @return The value written back to the PCI configuration register.
301 PciCf8BitFieldWrite8 (
308 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
309 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
310 return IoBitFieldWrite8 (
311 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
319 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
320 writes the result back to the bit field in the 8-bit port.
322 Reads the 8-bit PCI configuration register specified by Address, performs a
323 bitwise inclusive OR between the read result and the value specified by
324 OrData, and writes the result to the 8-bit PCI configuration register
325 specified by Address. The value written to the PCI configuration register is
326 returned. This function must guarantee that all PCI read and write operations
327 are serialized. Extra left bits in OrData are stripped.
329 If Address > 0x0FFFFFFF, then ASSERT().
330 If the register specified by Address >= 0x100, then ASSERT().
331 If StartBit is greater than 7, then ASSERT().
332 If EndBit is greater than 7, then ASSERT().
333 If EndBit is less than StartBit, then ASSERT().
335 @param Address PCI configuration register to write.
336 @param StartBit The ordinal of the least significant bit in the bit field.
338 @param EndBit The ordinal of the most significant bit in the bit field.
340 @param OrData The value to OR with the PCI configuration register.
342 @return The value written back to the PCI configuration register.
354 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
355 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
356 return IoBitFieldOr8 (
357 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
365 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
366 AND, and writes the result back to the bit field in the 8-bit register.
368 Reads the 8-bit PCI configuration register specified by Address, performs a
369 bitwise AND between the read result and the value specified by AndData, and
370 writes the result to the 8-bit PCI configuration register specified by
371 Address. The value written to the PCI configuration register is returned.
372 This function must guarantee that all PCI read and write operations are
373 serialized. Extra left bits in AndData are stripped.
375 If Address > 0x0FFFFFFF, then ASSERT().
376 If the register specified by Address >= 0x100, then ASSERT().
377 If StartBit is greater than 7, then ASSERT().
378 If EndBit is greater than 7, then ASSERT().
379 If EndBit is less than StartBit, then ASSERT().
381 @param Address PCI configuration register to write.
382 @param StartBit The ordinal of the least significant bit in the bit field.
384 @param EndBit The ordinal of the most significant bit in the bit field.
386 @param AndData The value to AND with the PCI configuration register.
388 @return The value written back to the PCI configuration register.
400 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
401 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
402 return IoBitFieldAnd8 (
403 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
411 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
412 bitwise inclusive OR, and writes the result back to the bit field in the
415 Reads the 8-bit PCI configuration register specified by Address, performs a
416 bitwise AND followed by a bitwise inclusive OR between the read result and
417 the value specified by AndData, and writes the result to the 8-bit PCI
418 configuration register specified by Address. The value written to the PCI
419 configuration register is returned. This function must guarantee that all PCI
420 read and write operations are serialized. Extra left bits in both AndData and
423 If Address > 0x0FFFFFFF, then ASSERT().
424 If the register specified by Address >= 0x100, then ASSERT().
425 If StartBit is greater than 7, then ASSERT().
426 If EndBit is greater than 7, then ASSERT().
427 If EndBit is less than StartBit, then ASSERT().
429 @param Address PCI configuration register to write.
430 @param StartBit The ordinal of the least significant bit in the bit field.
432 @param EndBit The ordinal of the most significant bit in the bit field.
434 @param AndData The value to AND with the PCI configuration register.
435 @param OrData The value to OR with the result of the AND operation.
437 @return The value written back to the PCI configuration register.
442 PciCf8BitFieldAndThenOr8(
450 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
451 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
452 return IoBitFieldAndThenOr8 (
453 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
462 Reads a 16-bit PCI configuration register.
464 Reads and returns the 16-bit PCI configuration register specified by Address.
465 This function must guarantee that all PCI read and write operations are
468 If Address > 0x0FFFFFFF, then ASSERT().
469 If Address is not aligned on a 16-bit boundary, then ASSERT().
470 If the register specified by Address >= 0x100, then ASSERT().
472 @param Address Address that encodes the PCI Bus, Device, Function and
475 @return The read value from the PCI configuration register.
484 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
485 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
486 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
490 Writes a 16-bit PCI configuration register.
492 Writes the 16-bit PCI configuration register specified by Address with the
493 value specified by Value. Value is returned. This function must guarantee
494 that all PCI read and write operations are serialized.
496 If Address > 0x0FFFFFFF, then ASSERT().
497 If Address is not aligned on a 16-bit boundary, then ASSERT().
498 If the register specified by Address >= 0x100, then ASSERT().
500 @param Address Address that encodes the PCI Bus, Device, Function and
502 @param Value The value to write.
504 @return The value written to the PCI configuration register.
514 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
515 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
517 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
523 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
526 Reads the 16-bit PCI configuration register specified by Address, performs a
527 bitwise inclusive OR between the read result and the value specified by
528 OrData, and writes the result to the 16-bit PCI configuration register
529 specified by Address. The value written to the PCI configuration register is
530 returned. This function must guarantee that all PCI read and write operations
533 If Address > 0x0FFFFFFF, then ASSERT().
534 If Address is not aligned on a 16-bit boundary, then ASSERT().
535 If the register specified by Address >= 0x100, then ASSERT().
537 @param Address Address that encodes the PCI Bus, Device, Function and
539 @param OrData The value to OR with the PCI configuration register.
541 @return The value written back to the PCI configuration register.
551 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
552 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
554 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
560 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
563 Reads the 16-bit PCI configuration register specified by Address, performs a
564 bitwise AND between the read result and the value specified by AndData, and
565 writes the result to the 16-bit PCI configuration register specified by
566 Address. The value written to the PCI configuration register is returned.
567 This function must guarantee that all PCI read and write operations are
570 If Address > 0x0FFFFFFF, then ASSERT().
571 If Address is not aligned on a 16-bit boundary, then ASSERT().
572 If the register specified by Address >= 0x100, then ASSERT().
574 @param Address Address that encodes the PCI Bus, Device, Function and
576 @param AndData The value to AND with the PCI configuration register.
578 @return The value written back to the PCI configuration register.
588 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
589 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
591 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
597 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
598 value, followed a bitwise inclusive OR with another 16-bit value.
600 Reads the 16-bit PCI configuration register specified by Address, performs a
601 bitwise AND between the read result and the value specified by AndData,
602 performs a bitwise inclusive OR between the result of the AND operation and
603 the value specified by OrData, and writes the result to the 16-bit PCI
604 configuration register specified by Address. The value written to the PCI
605 configuration register is returned. This function must guarantee that all PCI
606 read and write operations are serialized.
608 If Address > 0x0FFFFFFF, then ASSERT().
609 If Address is not aligned on a 16-bit boundary, then ASSERT().
610 If the register specified by Address >= 0x100, then ASSERT().
612 @param Address Address that encodes the PCI Bus, Device, Function and
614 @param AndData The value to AND with the PCI configuration register.
615 @param OrData The value to OR with the result of the AND operation.
617 @return The value written back to the PCI configuration register.
628 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
629 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
630 return IoAndThenOr16 (
631 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
638 Reads a bit field of a PCI configuration register.
640 Reads the bit field in a 16-bit PCI configuration register. The bit field is
641 specified by the StartBit and the EndBit. The value of the bit field is
644 If Address > 0x0FFFFFFF, then ASSERT().
645 If Address is not aligned on a 16-bit boundary, then ASSERT().
646 If the register specified by Address >= 0x100, then ASSERT().
647 If StartBit is greater than 15, then ASSERT().
648 If EndBit is greater than 15, then ASSERT().
649 If EndBit is less than StartBit, then ASSERT().
651 @param Address PCI configuration register to read.
652 @param StartBit The ordinal of the least significant bit in the bit field.
654 @param EndBit The ordinal of the most significant bit in the bit field.
657 @return The value of the bit field read from the PCI configuration register.
662 PciCf8BitFieldRead16 (
668 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
669 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
670 return IoBitFieldRead16 (
671 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
678 Writes a bit field to a PCI configuration register.
680 Writes Value to the bit field of the PCI configuration register. The bit
681 field is specified by the StartBit and the EndBit. All other bits in the
682 destination PCI configuration register are preserved. The new value of the
683 16-bit register is returned.
685 If Address > 0x0FFFFFFF, then ASSERT().
686 If Address is not aligned on a 16-bit boundary, then ASSERT().
687 If the register specified by Address >= 0x100, then ASSERT().
688 If StartBit is greater than 15, then ASSERT().
689 If EndBit is greater than 15, then ASSERT().
690 If EndBit is less than StartBit, then ASSERT().
692 @param Address PCI configuration register to write.
693 @param StartBit The ordinal of the least significant bit in the bit field.
695 @param EndBit The ordinal of the most significant bit in the bit field.
697 @param Value New value of the bit field.
699 @return The value written back to the PCI configuration register.
704 PciCf8BitFieldWrite16 (
711 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
712 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
713 return IoBitFieldWrite16 (
714 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
722 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
723 writes the result back to the bit field in the 16-bit port.
725 Reads the 16-bit PCI configuration register specified by Address, performs a
726 bitwise inclusive OR between the read result and the value specified by
727 OrData, and writes the result to the 16-bit PCI configuration register
728 specified by Address. The value written to the PCI configuration register is
729 returned. This function must guarantee that all PCI read and write operations
730 are serialized. Extra left bits in OrData are stripped.
732 If Address > 0x0FFFFFFF, then ASSERT().
733 If Address is not aligned on a 16-bit boundary, then ASSERT().
734 If the register specified by Address >= 0x100, then ASSERT().
735 If StartBit is greater than 15, then ASSERT().
736 If EndBit is greater than 15, then ASSERT().
737 If EndBit is less than StartBit, then ASSERT().
739 @param Address PCI configuration register to write.
740 @param StartBit The ordinal of the least significant bit in the bit field.
742 @param EndBit The ordinal of the most significant bit in the bit field.
744 @param OrData The value to OR with the PCI configuration register.
746 @return The value written back to the PCI configuration register.
758 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
759 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
760 return IoBitFieldOr16 (
761 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
769 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
770 AND, and writes the result back to the bit field in the 16-bit register.
772 Reads the 16-bit PCI configuration register specified by Address, performs a
773 bitwise AND between the read result and the value specified by AndData, and
774 writes the result to the 16-bit PCI configuration register specified by
775 Address. The value written to the PCI configuration register is returned.
776 This function must guarantee that all PCI read and write operations are
777 serialized. Extra left bits in AndData are stripped.
779 If Address > 0x0FFFFFFF, then ASSERT().
780 If Address is not aligned on a 16-bit boundary, then ASSERT().
781 If the register specified by Address >= 0x100, then ASSERT().
782 If StartBit is greater than 15, then ASSERT().
783 If EndBit is greater than 15, then ASSERT().
784 If EndBit is less than StartBit, then ASSERT().
786 @param Address PCI configuration register to write.
787 @param StartBit The ordinal of the least significant bit in the bit field.
789 @param EndBit The ordinal of the most significant bit in the bit field.
791 @param AndData The value to AND with the PCI configuration register.
793 @return The value written back to the PCI configuration register.
798 PciCf8BitFieldAnd16 (
805 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
806 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
807 return IoBitFieldAnd16 (
808 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
816 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
817 bitwise inclusive OR, and writes the result back to the bit field in the
820 Reads the 16-bit PCI configuration register specified by Address, performs a
821 bitwise AND followed by a bitwise inclusive OR between the read result and
822 the value specified by AndData, and writes the result to the 16-bit PCI
823 configuration register specified by Address. The value written to the PCI
824 configuration register is returned. This function must guarantee that all PCI
825 read and write operations are serialized. Extra left bits in both AndData and
828 If Address > 0x0FFFFFFF, then ASSERT().
829 If Address is not aligned on a 16-bit boundary, then ASSERT().
830 If the register specified by Address >= 0x100, then ASSERT().
831 If StartBit is greater than 15, then ASSERT().
832 If EndBit is greater than 15, then ASSERT().
833 If EndBit is less than StartBit, then ASSERT().
835 @param Address PCI configuration register to write.
836 @param StartBit The ordinal of the least significant bit in the bit field.
838 @param EndBit The ordinal of the most significant bit in the bit field.
840 @param AndData The value to AND with the PCI configuration register.
841 @param OrData The value to OR with the result of the AND operation.
843 @return The value written back to the PCI configuration register.
848 PciCf8BitFieldAndThenOr16(
856 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
857 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
858 return IoBitFieldAndThenOr16 (
859 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
868 Reads a 32-bit PCI configuration register.
870 Reads and returns the 32-bit PCI configuration register specified by Address.
871 This function must guarantee that all PCI read and write operations are
874 If Address > 0x0FFFFFFF, then ASSERT().
875 If Address is not aligned on a 32-bit boundary, then ASSERT().
876 If the register specified by Address >= 0x100, then ASSERT().
878 @param Address Address that encodes the PCI Bus, Device, Function and
881 @return The read value from the PCI configuration register.
890 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
891 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
892 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
896 Writes a 32-bit PCI configuration register.
898 Writes the 32-bit PCI configuration register specified by Address with the
899 value specified by Value. Value is returned. This function must guarantee
900 that all PCI read and write operations are serialized.
902 If Address > 0x0FFFFFFF, then ASSERT().
903 If Address is not aligned on a 32-bit boundary, then ASSERT().
904 If the register specified by Address >= 0x100, then ASSERT().
906 @param Address Address that encodes the PCI Bus, Device, Function and
908 @param Value The value to write.
910 @return The value written to the PCI configuration register.
920 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
921 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
923 PCI_CONFIGURATION_DATA_PORT
,
929 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
932 Reads the 32-bit PCI configuration register specified by Address, performs a
933 bitwise inclusive OR between the read result and the value specified by
934 OrData, and writes the result to the 32-bit PCI configuration register
935 specified by Address. The value written to the PCI configuration register is
936 returned. This function must guarantee that all PCI read and write operations
939 If Address > 0x0FFFFFFF, then ASSERT().
940 If Address is not aligned on a 32-bit boundary, then ASSERT().
941 If the register specified by Address >= 0x100, then ASSERT().
943 @param Address Address that encodes the PCI Bus, Device, Function and
945 @param OrData The value to OR with the PCI configuration register.
947 @return The value written back to the PCI configuration register.
957 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
958 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
960 PCI_CONFIGURATION_DATA_PORT
,
966 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
969 Reads the 32-bit PCI configuration register specified by Address, performs a
970 bitwise AND between the read result and the value specified by AndData, and
971 writes the result to the 32-bit PCI configuration register specified by
972 Address. The value written to the PCI configuration register is returned.
973 This function must guarantee that all PCI read and write operations are
976 If Address > 0x0FFFFFFF, then ASSERT().
977 If Address is not aligned on a 32-bit boundary, then ASSERT().
978 If the register specified by Address >= 0x100, then ASSERT().
980 @param Address Address that encodes the PCI Bus, Device, Function and
982 @param AndData The value to AND with the PCI configuration register.
984 @return The value written back to the PCI configuration register.
994 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
995 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
997 PCI_CONFIGURATION_DATA_PORT
,
1003 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1004 value, followed a bitwise inclusive OR with another 32-bit value.
1006 Reads the 32-bit PCI configuration register specified by Address, performs a
1007 bitwise AND between the read result and the value specified by AndData,
1008 performs a bitwise inclusive OR between the result of the AND operation and
1009 the value specified by OrData, and writes the result to the 32-bit PCI
1010 configuration register specified by Address. The value written to the PCI
1011 configuration register is returned. This function must guarantee that all PCI
1012 read and write operations are serialized.
1014 If Address > 0x0FFFFFFF, then ASSERT().
1015 If Address is not aligned on a 32-bit boundary, then ASSERT().
1016 If the register specified by Address >= 0x100, then ASSERT().
1018 @param Address Address that encodes the PCI Bus, Device, Function and
1020 @param AndData The value to AND with the PCI configuration register.
1021 @param OrData The value to OR with the result of the AND operation.
1023 @return The value written back to the PCI configuration register.
1034 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1035 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1036 return IoAndThenOr32 (
1037 PCI_CONFIGURATION_DATA_PORT
,
1044 Reads a bit field of a PCI configuration register.
1046 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1047 specified by the StartBit and the EndBit. The value of the bit field is
1050 If Address > 0x0FFFFFFF, then ASSERT().
1051 If Address is not aligned on a 32-bit boundary, then ASSERT().
1052 If the register specified by Address >= 0x100, then ASSERT().
1053 If StartBit is greater than 31, then ASSERT().
1054 If EndBit is greater than 31, then ASSERT().
1055 If EndBit is less than StartBit, then ASSERT().
1057 @param Address PCI configuration register to read.
1058 @param StartBit The ordinal of the least significant bit in the bit field.
1060 @param EndBit The ordinal of the most significant bit in the bit field.
1063 @return The value of the bit field read from the PCI configuration register.
1068 PciCf8BitFieldRead32 (
1074 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1075 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1076 return IoBitFieldRead32 (
1077 PCI_CONFIGURATION_DATA_PORT
,
1084 Writes a bit field to a PCI configuration register.
1086 Writes Value to the bit field of the PCI configuration register. The bit
1087 field is specified by the StartBit and the EndBit. All other bits in the
1088 destination PCI configuration register are preserved. The new value of the
1089 32-bit register is returned.
1091 If Address > 0x0FFFFFFF, then ASSERT().
1092 If Address is not aligned on a 32-bit boundary, then ASSERT().
1093 If the register specified by Address >= 0x100, then ASSERT().
1094 If StartBit is greater than 31, then ASSERT().
1095 If EndBit is greater than 31, then ASSERT().
1096 If EndBit is less than StartBit, then ASSERT().
1098 @param Address PCI configuration register to write.
1099 @param StartBit The ordinal of the least significant bit in the bit field.
1101 @param EndBit The ordinal of the most significant bit in the bit field.
1103 @param Value New value of the bit field.
1105 @return The value written back to the PCI configuration register.
1110 PciCf8BitFieldWrite32 (
1117 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1118 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1119 return IoBitFieldWrite32 (
1120 PCI_CONFIGURATION_DATA_PORT
,
1128 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1129 writes the result back to the bit field in the 32-bit port.
1131 Reads the 32-bit PCI configuration register specified by Address, performs a
1132 bitwise inclusive OR between the read result and the value specified by
1133 OrData, and writes the result to the 32-bit PCI configuration register
1134 specified by Address. The value written to the PCI configuration register is
1135 returned. This function must guarantee that all PCI read and write operations
1136 are serialized. Extra left bits in OrData are stripped.
1138 If Address > 0x0FFFFFFF, then ASSERT().
1139 If Address is not aligned on a 32-bit boundary, then ASSERT().
1140 If the register specified by Address >= 0x100, then ASSERT().
1141 If StartBit is greater than 31, then ASSERT().
1142 If EndBit is greater than 31, then ASSERT().
1143 If EndBit is less than StartBit, then ASSERT().
1145 @param Address PCI configuration register to write.
1146 @param StartBit The ordinal of the least significant bit in the bit field.
1148 @param EndBit The ordinal of the most significant bit in the bit field.
1150 @param OrData The value to OR with the PCI configuration register.
1152 @return The value written back to the PCI configuration register.
1157 PciCf8BitFieldOr32 (
1164 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1165 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1166 return IoBitFieldOr32 (
1167 PCI_CONFIGURATION_DATA_PORT
,
1175 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1176 AND, and writes the result back to the bit field in the 32-bit register.
1178 Reads the 32-bit PCI configuration register specified by Address, performs a
1179 bitwise AND between the read result and the value specified by AndData, and
1180 writes the result to the 32-bit PCI configuration register specified by
1181 Address. The value written to the PCI configuration register is returned.
1182 This function must guarantee that all PCI read and write operations are
1183 serialized. Extra left bits in AndData are stripped.
1185 If Address > 0x0FFFFFFF, then ASSERT().
1186 If Address is not aligned on a 32-bit boundary, then ASSERT().
1187 If the register specified by Address >= 0x100, then ASSERT().
1188 If StartBit is greater than 31, then ASSERT().
1189 If EndBit is greater than 31, then ASSERT().
1190 If EndBit is less than StartBit, then ASSERT().
1192 @param Address PCI configuration register to write.
1193 @param StartBit The ordinal of the least significant bit in the bit field.
1195 @param EndBit The ordinal of the most significant bit in the bit field.
1197 @param AndData The value to AND with the PCI configuration register.
1199 @return The value written back to the PCI configuration register.
1204 PciCf8BitFieldAnd32 (
1211 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1212 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1213 return IoBitFieldAnd32 (
1214 PCI_CONFIGURATION_DATA_PORT
,
1222 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1223 bitwise inclusive OR, and writes the result back to the bit field in the
1226 Reads the 32-bit PCI configuration register specified by Address, performs a
1227 bitwise AND followed by a bitwise inclusive OR between the read result and
1228 the value specified by AndData, and writes the result to the 32-bit PCI
1229 configuration register specified by Address. The value written to the PCI
1230 configuration register is returned. This function must guarantee that all PCI
1231 read and write operations are serialized. Extra left bits in both AndData and
1232 OrData are stripped.
1234 If Address > 0x0FFFFFFF, then ASSERT().
1235 If Address is not aligned on a 32-bit boundary, then ASSERT().
1236 If the register specified by Address >= 0x100, then ASSERT().
1237 If StartBit is greater than 31, then ASSERT().
1238 If EndBit is greater than 31, then ASSERT().
1239 If EndBit is less than StartBit, then ASSERT().
1241 @param Address PCI configuration register to write.
1242 @param StartBit The ordinal of the least significant bit in the bit field.
1244 @param EndBit The ordinal of the most significant bit in the bit field.
1246 @param AndData The value to AND with the PCI configuration register.
1247 @param OrData The value to OR with the result of the AND operation.
1249 @return The value written back to the PCI configuration register.
1254 PciCf8BitFieldAndThenOr32(
1262 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1263 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1264 return IoBitFieldAndThenOr32 (
1265 PCI_CONFIGURATION_DATA_PORT
,
1274 Reads a range of PCI configuration registers into a caller supplied buffer.
1276 Reads the range of PCI configuration registers specified by StartAddress and
1277 Size into the buffer specified by Buffer. This function only allows the PCI
1278 configuration registers from a single PCI function to be read. Size is
1279 returned. When possible 32-bit PCI configuration read cycles are used to read
1280 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1281 and 16-bit PCI configuration read cycles may be used at the beginning and the
1284 If StartAddress > 0x0FFFFFFF, then ASSERT().
1285 If the register specified by StartAddress >= 0x100, then ASSERT().
1286 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1287 If Size > 0 and Buffer is NULL, then ASSERT().
1289 @param StartAddress Starting address that encodes the PCI Bus, Device,
1290 Function and Register.
1291 @param Size Size in bytes of the transfer.
1292 @param Buffer Pointer to a buffer receiving the data read.
1300 IN UINTN StartAddress
,
1307 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1308 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1314 ASSERT (Buffer
!= NULL
);
1317 // Save Size for return
1321 if ((StartAddress
& 1) != 0) {
1323 // Read a byte if StartAddress is byte aligned
1325 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1326 StartAddress
+= sizeof (UINT8
);
1327 Size
-= sizeof (UINT8
);
1328 Buffer
= (UINT8
*)Buffer
+ 1;
1331 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1333 // Read a word if StartAddress is word aligned
1335 *(volatile UINT16
*)Buffer
= PciCf8Read16 (StartAddress
);
1336 StartAddress
+= sizeof (UINT16
);
1337 Size
-= sizeof (UINT16
);
1338 Buffer
= (UINT16
*)Buffer
+ 1;
1341 while (Size
>= sizeof (UINT32
)) {
1343 // Read as many double words as possible
1345 *(volatile UINT32
*)Buffer
= PciCf8Read32 (StartAddress
);
1346 StartAddress
+= sizeof (UINT32
);
1347 Size
-= sizeof (UINT32
);
1348 Buffer
= (UINT32
*)Buffer
+ 1;
1351 if (Size
>= sizeof (UINT16
)) {
1353 // Read the last remaining word if exist
1355 *(volatile UINT16
*)Buffer
= PciCf8Read16 (StartAddress
);
1356 StartAddress
+= sizeof (UINT16
);
1357 Size
-= sizeof (UINT16
);
1358 Buffer
= (UINT16
*)Buffer
+ 1;
1361 if (Size
>= sizeof (UINT8
)) {
1363 // Read the last remaining byte if exist
1365 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1372 Copies the data in a caller supplied buffer to a specified range of PCI
1373 configuration space.
1375 Writes the range of PCI configuration registers specified by StartAddress and
1376 Size from the buffer specified by Buffer. This function only allows the PCI
1377 configuration registers from a single PCI function to be written. Size is
1378 returned. When possible 32-bit PCI configuration write cycles are used to
1379 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1380 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1381 and the end of the range.
1383 If StartAddress > 0x0FFFFFFF, then ASSERT().
1384 If the register specified by StartAddress >= 0x100, then ASSERT().
1385 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1386 If Size > 0 and Buffer is NULL, then ASSERT().
1388 @param StartAddress Starting address that encodes the PCI Bus, Device,
1389 Function and Register.
1390 @param Size Size in bytes of the transfer.
1391 @param Buffer Pointer to a buffer containing the data to write.
1399 IN UINTN StartAddress
,
1406 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1407 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1413 ASSERT (Buffer
!= NULL
);
1416 // Save Size for return
1420 if ((StartAddress
& 1) != 0) {
1422 // Write a byte if StartAddress is byte aligned
1424 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1425 StartAddress
+= sizeof (UINT8
);
1426 Size
-= sizeof (UINT8
);
1427 Buffer
= (UINT8
*)Buffer
+ 1;
1430 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1432 // Write a word if StartAddress is word aligned
1434 PciCf8Write16 (StartAddress
, *(UINT16
*)Buffer
);
1435 StartAddress
+= sizeof (UINT16
);
1436 Size
-= sizeof (UINT16
);
1437 Buffer
= (UINT16
*)Buffer
+ 1;
1440 while (Size
>= sizeof (UINT32
)) {
1442 // Write as many double words as possible
1444 PciCf8Write32 (StartAddress
, *(UINT32
*)Buffer
);
1445 StartAddress
+= sizeof (UINT32
);
1446 Size
-= sizeof (UINT32
);
1447 Buffer
= (UINT32
*)Buffer
+ 1;
1450 if (Size
>= sizeof (UINT16
)) {
1452 // Write the last remaining word if exist
1454 PciCf8Write16 (StartAddress
, *(UINT16
*)Buffer
);
1455 StartAddress
+= sizeof (UINT16
);
1456 Size
-= sizeof (UINT16
);
1457 Buffer
= (UINT16
*)Buffer
+ 1;
1460 if (Size
>= sizeof (UINT8
)) {
1462 // Write the last remaining byte if exist
1464 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);