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 #include <Library/BaseLib.h>
19 #include <Library/PciCf8Lib.h>
20 #include <Library/IoLib.h>
21 #include <Library/DebugLib.h>
24 // Declare I/O Ports used to perform PCI Confguration Cycles
26 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
27 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
30 // Declare macro to convert PCI Library formatted address to CF8 formatted address
32 // PCI Library formatted address CF8 Formatted Address
33 // ============================= ======================
34 // Bits 00..11 Register Bits 00..07 Register
35 // Bits 12..14 Function Bits 08..10 Function
36 // Bits 15..19 Device Bits 11..15 Device
37 // Bits 20..27 Bus Bits 16..23 Bus
38 // Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
39 // Bits 31..31 Must be 1
43 Assert the validity of a PCI address. A valid PCI address should contain 1's
44 only in the low 28 bits.
46 @param A The address to validate.
47 @param M Additional bits to assert to be zero.
50 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
51 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
54 Convert a PCI Express address to PCI CF8 address.
56 @param A The address to convert.
58 @retval The coverted address.
61 #define PCI_TO_CF8_ADDRESS(A) \
62 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
65 Reads an 8-bit PCI configuration register.
67 Reads and returns the 8-bit PCI configuration register specified by Address.
68 This function must guarantee that all PCI read and write operations are
71 If Address > 0x0FFFFFFF, then ASSERT().
72 If the register specified by Address >= 0x100, then ASSERT().
74 @param Address Address that encodes the PCI Bus, Device, Function and
77 @return The read value from the PCI configuration register.
86 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
87 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
88 return IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
92 Writes an 8-bit PCI configuration register.
94 Writes the 8-bit PCI configuration register specified by Address with the
95 value specified by Value. Value is returned. This function must guarantee
96 that all PCI read and write operations are serialized.
98 If Address > 0x0FFFFFFF, then ASSERT().
99 If the register specified by Address >= 0x100, then ASSERT().
101 @param Address Address that encodes the PCI Bus, Device, Function and
103 @param Value The value to write.
105 @return The value written to the PCI configuration register.
115 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
116 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
118 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
124 Performs a bitwise inclusive OR of an 8-bit PCI configuration register with
127 Reads the 8-bit PCI configuration register specified by Address, performs a
128 bitwise inclusive OR between the read result and the value specified by
129 OrData, and writes the result to the 8-bit PCI configuration register
130 specified by Address. The value written to the PCI configuration register is
131 returned. This function must guarantee that all PCI read and write operations
134 If Address > 0x0FFFFFFF, then ASSERT().
135 If the register specified by Address >= 0x100, then ASSERT().
137 @param Address Address that encodes the PCI Bus, Device, Function and
139 @param OrData The value to OR with the PCI configuration register.
141 @return The value written back to the PCI configuration register.
151 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
152 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
154 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
160 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
163 Reads the 8-bit PCI configuration register specified by Address, performs a
164 bitwise AND between the read result and the value specified by AndData, and
165 writes the result to the 8-bit PCI configuration register specified by
166 Address. The value written to the PCI configuration register is returned.
167 This function must guarantee that all PCI read and write operations are
170 If Address > 0x0FFFFFFF, then ASSERT().
171 If the register specified by Address >= 0x100, then ASSERT().
173 @param Address Address that encodes the PCI Bus, Device, Function and
175 @param AndData The value to AND with the PCI configuration register.
177 @return The value written back to the PCI configuration register.
187 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
188 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
190 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
196 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
197 value, followed a bitwise inclusive OR with another 8-bit value.
199 Reads the 8-bit PCI configuration register specified by Address, performs a
200 bitwise AND between the read result and the value specified by AndData,
201 performs a bitwise inclusive OR between the result of the AND operation and
202 the value specified by OrData, and writes the result to the 8-bit PCI
203 configuration register specified by Address. The value written to the PCI
204 configuration register is returned. This function must guarantee that all PCI
205 read and write operations are serialized.
207 If Address > 0x0FFFFFFF, then ASSERT().
208 If the register specified by Address >= 0x100, then ASSERT().
210 @param Address Address that encodes the PCI Bus, Device, Function and
212 @param AndData The value to AND with the PCI configuration register.
213 @param OrData The value to OR with the result of the AND operation.
215 @return The value written back to the PCI configuration register.
226 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
227 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
228 return IoAndThenOr8 (
229 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
236 Reads a bit field of a PCI configuration register.
238 Reads the bit field in an 8-bit PCI configuration register. The bit field is
239 specified by the StartBit and the EndBit. The value of the bit field is
242 If Address > 0x0FFFFFFF, then ASSERT().
243 If the register specified by Address >= 0x100, then ASSERT().
244 If StartBit is greater than 7, then ASSERT().
245 If EndBit is greater than 7, then ASSERT().
246 If EndBit is less than StartBit, then ASSERT().
248 @param Address PCI configuration register to read.
249 @param StartBit The ordinal of the least significant bit in the bit field.
251 @param EndBit The ordinal of the most significant bit in the bit field.
254 @return The value of the bit field read from the PCI configuration register.
259 PciCf8BitFieldRead8 (
265 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
266 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
267 return IoBitFieldRead8 (
268 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
275 Writes a bit field to a PCI configuration register.
277 Writes Value to the bit field of the PCI configuration register. The bit
278 field is specified by the StartBit and the EndBit. All other bits in the
279 destination PCI configuration register are preserved. The new value of the
280 8-bit register is returned.
282 If Address > 0x0FFFFFFF, then ASSERT().
283 If the register specified by Address >= 0x100, then ASSERT().
284 If StartBit is greater than 7, then ASSERT().
285 If EndBit is greater than 7, then ASSERT().
286 If EndBit is less than StartBit, then ASSERT().
288 @param Address PCI configuration register to write.
289 @param StartBit The ordinal of the least significant bit in the bit field.
291 @param EndBit The ordinal of the most significant bit in the bit field.
293 @param Value New value of the bit field.
295 @return The value written back to the PCI configuration register.
300 PciCf8BitFieldWrite8 (
307 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
308 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
309 return IoBitFieldWrite8 (
310 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
318 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
319 writes the result back to the bit field in the 8-bit port.
321 Reads the 8-bit PCI configuration register specified by Address, performs a
322 bitwise inclusive OR between the read result and the value specified by
323 OrData, and writes the result to the 8-bit PCI configuration register
324 specified by Address. The value written to the PCI configuration register is
325 returned. This function must guarantee that all PCI read and write operations
326 are serialized. Extra left bits in OrData are stripped.
328 If Address > 0x0FFFFFFF, then ASSERT().
329 If the register specified by Address >= 0x100, then ASSERT().
330 If StartBit is greater than 7, then ASSERT().
331 If EndBit is greater than 7, then ASSERT().
332 If EndBit is less than StartBit, then ASSERT().
334 @param Address PCI configuration register to write.
335 @param StartBit The ordinal of the least significant bit in the bit field.
337 @param EndBit The ordinal of the most significant bit in the bit field.
339 @param OrData The value to OR with the PCI configuration register.
341 @return The value written back to the PCI configuration register.
353 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
354 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
355 return IoBitFieldOr8 (
356 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
364 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
365 AND, and writes the result back to the bit field in the 8-bit register.
367 Reads the 8-bit PCI configuration register specified by Address, performs a
368 bitwise AND between the read result and the value specified by AndData, and
369 writes the result to the 8-bit PCI configuration register specified by
370 Address. The value written to the PCI configuration register is returned.
371 This function must guarantee that all PCI read and write operations are
372 serialized. Extra left bits in AndData are stripped.
374 If Address > 0x0FFFFFFF, then ASSERT().
375 If the register specified by Address >= 0x100, then ASSERT().
376 If StartBit is greater than 7, then ASSERT().
377 If EndBit is greater than 7, then ASSERT().
378 If EndBit is less than StartBit, then ASSERT().
380 @param Address PCI configuration register to write.
381 @param StartBit The ordinal of the least significant bit in the bit field.
383 @param EndBit The ordinal of the most significant bit in the bit field.
385 @param AndData The value to AND with the PCI configuration register.
387 @return The value written back to the PCI configuration register.
399 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
400 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
401 return IoBitFieldAnd8 (
402 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
410 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
411 bitwise inclusive OR, and writes the result back to the bit field in the
414 Reads the 8-bit PCI configuration register specified by Address, performs a
415 bitwise AND followed by a bitwise inclusive OR between the read result and
416 the value specified by AndData, and writes the result to the 8-bit PCI
417 configuration register specified by Address. The value written to the PCI
418 configuration register is returned. This function must guarantee that all PCI
419 read and write operations are serialized. Extra left bits in both AndData and
422 If Address > 0x0FFFFFFF, then ASSERT().
423 If the register specified by Address >= 0x100, then ASSERT().
424 If StartBit is greater than 7, then ASSERT().
425 If EndBit is greater than 7, then ASSERT().
426 If EndBit is less than StartBit, then ASSERT().
428 @param Address PCI configuration register to write.
429 @param StartBit The ordinal of the least significant bit in the bit field.
431 @param EndBit The ordinal of the most significant bit in the bit field.
433 @param AndData The value to AND with the PCI configuration register.
434 @param OrData The value to OR with the result of the AND operation.
436 @return The value written back to the PCI configuration register.
441 PciCf8BitFieldAndThenOr8(
449 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
450 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
451 return IoBitFieldAndThenOr8 (
452 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
461 Reads a 16-bit PCI configuration register.
463 Reads and returns the 16-bit PCI configuration register specified by Address.
464 This function must guarantee that all PCI read and write operations are
467 If Address > 0x0FFFFFFF, then ASSERT().
468 If Address is not aligned on a 16-bit boundary, then ASSERT().
469 If the register specified by Address >= 0x100, then ASSERT().
471 @param Address Address that encodes the PCI Bus, Device, Function and
474 @return The read value from the PCI configuration register.
483 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
484 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
485 return IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
489 Writes a 16-bit PCI configuration register.
491 Writes the 16-bit PCI configuration register specified by Address with the
492 value specified by Value. Value is returned. This function must guarantee
493 that all PCI read and write operations are serialized.
495 If Address > 0x0FFFFFFF, then ASSERT().
496 If Address is not aligned on a 16-bit boundary, then ASSERT().
497 If the register specified by Address >= 0x100, then ASSERT().
499 @param Address Address that encodes the PCI Bus, Device, Function and
501 @param Value The value to write.
503 @return The value written to the PCI configuration register.
513 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
514 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
516 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
522 Performs a bitwise inclusive OR of a 16-bit PCI configuration register with
525 Reads the 16-bit PCI configuration register specified by Address, performs a
526 bitwise inclusive OR between the read result and the value specified by
527 OrData, and writes the result to the 16-bit PCI configuration register
528 specified by Address. The value written to the PCI configuration register is
529 returned. This function must guarantee that all PCI read and write operations
532 If Address > 0x0FFFFFFF, then ASSERT().
533 If Address is not aligned on a 16-bit boundary, then ASSERT().
534 If the register specified by Address >= 0x100, then ASSERT().
536 @param Address Address that encodes the PCI Bus, Device, Function and
538 @param OrData The value to OR with the PCI configuration register.
540 @return The value written back to the PCI configuration register.
550 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
551 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
553 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
559 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
562 Reads the 16-bit PCI configuration register specified by Address, performs a
563 bitwise AND between the read result and the value specified by AndData, and
564 writes the result to the 16-bit PCI configuration register specified by
565 Address. The value written to the PCI configuration register is returned.
566 This function must guarantee that all PCI read and write operations are
569 If Address > 0x0FFFFFFF, then ASSERT().
570 If Address is not aligned on a 16-bit boundary, then ASSERT().
571 If the register specified by Address >= 0x100, then ASSERT().
573 @param Address Address that encodes the PCI Bus, Device, Function and
575 @param AndData The value to AND with the PCI configuration register.
577 @return The value written back to the PCI configuration register.
587 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
588 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
590 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
596 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
597 value, followed a bitwise inclusive OR with another 16-bit value.
599 Reads the 16-bit PCI configuration register specified by Address, performs a
600 bitwise AND between the read result and the value specified by AndData,
601 performs a bitwise inclusive OR between the result of the AND operation and
602 the value specified by OrData, and writes the result to the 16-bit PCI
603 configuration register specified by Address. The value written to the PCI
604 configuration register is returned. This function must guarantee that all PCI
605 read and write operations are serialized.
607 If Address > 0x0FFFFFFF, then ASSERT().
608 If Address is not aligned on a 16-bit boundary, then ASSERT().
609 If the register specified by Address >= 0x100, then ASSERT().
611 @param Address Address that encodes the PCI Bus, Device, Function and
613 @param AndData The value to AND with the PCI configuration register.
614 @param OrData The value to OR with the result of the AND operation.
616 @return The value written back to the PCI configuration register.
627 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
628 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
629 return IoAndThenOr16 (
630 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
637 Reads a bit field of a PCI configuration register.
639 Reads the bit field in a 16-bit PCI configuration register. The bit field is
640 specified by the StartBit and the EndBit. The value of the bit field is
643 If Address > 0x0FFFFFFF, then ASSERT().
644 If Address is not aligned on a 16-bit boundary, then ASSERT().
645 If the register specified by Address >= 0x100, then ASSERT().
646 If StartBit is greater than 15, then ASSERT().
647 If EndBit is greater than 15, then ASSERT().
648 If EndBit is less than StartBit, then ASSERT().
650 @param Address PCI configuration register to read.
651 @param StartBit The ordinal of the least significant bit in the bit field.
653 @param EndBit The ordinal of the most significant bit in the bit field.
656 @return The value of the bit field read from the PCI configuration register.
661 PciCf8BitFieldRead16 (
667 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
668 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
669 return IoBitFieldRead16 (
670 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
677 Writes a bit field to a PCI configuration register.
679 Writes Value to the bit field of the PCI configuration register. The bit
680 field is specified by the StartBit and the EndBit. All other bits in the
681 destination PCI configuration register are preserved. The new value of the
682 16-bit register is returned.
684 If Address > 0x0FFFFFFF, then ASSERT().
685 If Address is not aligned on a 16-bit boundary, then ASSERT().
686 If the register specified by Address >= 0x100, then ASSERT().
687 If StartBit is greater than 15, then ASSERT().
688 If EndBit is greater than 15, then ASSERT().
689 If EndBit is less than StartBit, then ASSERT().
691 @param Address PCI configuration register to write.
692 @param StartBit The ordinal of the least significant bit in the bit field.
694 @param EndBit The ordinal of the most significant bit in the bit field.
696 @param Value New value of the bit field.
698 @return The value written back to the PCI configuration register.
703 PciCf8BitFieldWrite16 (
710 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
711 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
712 return IoBitFieldWrite16 (
713 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
721 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
722 writes the result back to the bit field in the 16-bit port.
724 Reads the 16-bit PCI configuration register specified by Address, performs a
725 bitwise inclusive OR between the read result and the value specified by
726 OrData, and writes the result to the 16-bit PCI configuration register
727 specified by Address. The value written to the PCI configuration register is
728 returned. This function must guarantee that all PCI read and write operations
729 are serialized. Extra left bits in OrData are stripped.
731 If Address > 0x0FFFFFFF, then ASSERT().
732 If Address is not aligned on a 16-bit boundary, then ASSERT().
733 If the register specified by Address >= 0x100, then ASSERT().
734 If StartBit is greater than 15, then ASSERT().
735 If EndBit is greater than 15, then ASSERT().
736 If EndBit is less than StartBit, then ASSERT().
738 @param Address PCI configuration register to write.
739 @param StartBit The ordinal of the least significant bit in the bit field.
741 @param EndBit The ordinal of the most significant bit in the bit field.
743 @param OrData The value to OR with the PCI configuration register.
745 @return The value written back to the PCI configuration register.
757 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
758 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
759 return IoBitFieldOr16 (
760 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
768 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
769 AND, and writes the result back to the bit field in the 16-bit register.
771 Reads the 16-bit PCI configuration register specified by Address, performs a
772 bitwise AND between the read result and the value specified by AndData, and
773 writes the result to the 16-bit PCI configuration register specified by
774 Address. The value written to the PCI configuration register is returned.
775 This function must guarantee that all PCI read and write operations are
776 serialized. Extra left bits in AndData are stripped.
778 If Address > 0x0FFFFFFF, then ASSERT().
779 If Address is not aligned on a 16-bit boundary, then ASSERT().
780 If the register specified by Address >= 0x100, then ASSERT().
781 If StartBit is greater than 15, then ASSERT().
782 If EndBit is greater than 15, then ASSERT().
783 If EndBit is less than StartBit, then ASSERT().
785 @param Address PCI configuration register to write.
786 @param StartBit The ordinal of the least significant bit in the bit field.
788 @param EndBit The ordinal of the most significant bit in the bit field.
790 @param AndData The value to AND with the PCI configuration register.
792 @return The value written back to the PCI configuration register.
797 PciCf8BitFieldAnd16 (
804 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
805 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
806 return IoBitFieldAnd16 (
807 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
815 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
816 bitwise inclusive OR, and writes the result back to the bit field in the
819 Reads the 16-bit PCI configuration register specified by Address, performs a
820 bitwise AND followed by a bitwise inclusive OR between the read result and
821 the value specified by AndData, and writes the result to the 16-bit PCI
822 configuration register specified by Address. The value written to the PCI
823 configuration register is returned. This function must guarantee that all PCI
824 read and write operations are serialized. Extra left bits in both AndData and
827 If Address > 0x0FFFFFFF, then ASSERT().
828 If Address is not aligned on a 16-bit boundary, then ASSERT().
829 If the register specified by Address >= 0x100, then ASSERT().
830 If StartBit is greater than 15, then ASSERT().
831 If EndBit is greater than 15, then ASSERT().
832 If EndBit is less than StartBit, then ASSERT().
834 @param Address PCI configuration register to write.
835 @param StartBit The ordinal of the least significant bit in the bit field.
837 @param EndBit The ordinal of the most significant bit in the bit field.
839 @param AndData The value to AND with the PCI configuration register.
840 @param OrData The value to OR with the result of the AND operation.
842 @return The value written back to the PCI configuration register.
847 PciCf8BitFieldAndThenOr16(
855 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
856 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
857 return IoBitFieldAndThenOr16 (
858 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
867 Reads a 32-bit PCI configuration register.
869 Reads and returns the 32-bit PCI configuration register specified by Address.
870 This function must guarantee that all PCI read and write operations are
873 If Address > 0x0FFFFFFF, then ASSERT().
874 If Address is not aligned on a 32-bit boundary, then ASSERT().
875 If the register specified by Address >= 0x100, then ASSERT().
877 @param Address Address that encodes the PCI Bus, Device, Function and
880 @return The read value from the PCI configuration register.
889 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
890 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
891 return IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
895 Writes a 32-bit PCI configuration register.
897 Writes the 32-bit PCI configuration register specified by Address with the
898 value specified by Value. Value is returned. This function must guarantee
899 that all PCI read and write operations are serialized.
901 If Address > 0x0FFFFFFF, then ASSERT().
902 If Address is not aligned on a 32-bit boundary, then ASSERT().
903 If the register specified by Address >= 0x100, then ASSERT().
905 @param Address Address that encodes the PCI Bus, Device, Function and
907 @param Value The value to write.
909 @return The value written to the PCI configuration register.
919 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
920 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
922 PCI_CONFIGURATION_DATA_PORT
,
928 Performs a bitwise inclusive OR of a 32-bit PCI configuration register with
931 Reads the 32-bit PCI configuration register specified by Address, performs a
932 bitwise inclusive OR between the read result and the value specified by
933 OrData, and writes the result to the 32-bit PCI configuration register
934 specified by Address. The value written to the PCI configuration register is
935 returned. This function must guarantee that all PCI read and write operations
938 If Address > 0x0FFFFFFF, then ASSERT().
939 If Address is not aligned on a 32-bit boundary, then ASSERT().
940 If the register specified by Address >= 0x100, then ASSERT().
942 @param Address Address that encodes the PCI Bus, Device, Function and
944 @param OrData The value to OR with the PCI configuration register.
946 @return The value written back to the PCI configuration register.
956 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
957 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
959 PCI_CONFIGURATION_DATA_PORT
,
965 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
968 Reads the 32-bit PCI configuration register specified by Address, performs a
969 bitwise AND between the read result and the value specified by AndData, and
970 writes the result to the 32-bit PCI configuration register specified by
971 Address. The value written to the PCI configuration register is returned.
972 This function must guarantee that all PCI read and write operations are
975 If Address > 0x0FFFFFFF, then ASSERT().
976 If Address is not aligned on a 32-bit boundary, then ASSERT().
977 If the register specified by Address >= 0x100, then ASSERT().
979 @param Address Address that encodes the PCI Bus, Device, Function and
981 @param AndData The value to AND with the PCI configuration register.
983 @return The value written back to the PCI configuration register.
993 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
994 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
996 PCI_CONFIGURATION_DATA_PORT
,
1002 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1003 value, followed a bitwise inclusive OR with another 32-bit value.
1005 Reads the 32-bit PCI configuration register specified by Address, performs a
1006 bitwise AND between the read result and the value specified by AndData,
1007 performs a bitwise inclusive OR between the result of the AND operation and
1008 the value specified by OrData, and writes the result to the 32-bit PCI
1009 configuration register specified by Address. The value written to the PCI
1010 configuration register is returned. This function must guarantee that all PCI
1011 read and write operations are serialized.
1013 If Address > 0x0FFFFFFF, then ASSERT().
1014 If Address is not aligned on a 32-bit boundary, then ASSERT().
1015 If the register specified by Address >= 0x100, then ASSERT().
1017 @param Address Address that encodes the PCI Bus, Device, Function and
1019 @param AndData The value to AND with the PCI configuration register.
1020 @param OrData The value to OR with the result of the AND operation.
1022 @return The value written back to the PCI configuration register.
1033 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1034 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1035 return IoAndThenOr32 (
1036 PCI_CONFIGURATION_DATA_PORT
,
1043 Reads a bit field of a PCI configuration register.
1045 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1046 specified by the StartBit and the EndBit. The value of the bit field is
1049 If Address > 0x0FFFFFFF, then ASSERT().
1050 If Address is not aligned on a 32-bit boundary, then ASSERT().
1051 If the register specified by Address >= 0x100, then ASSERT().
1052 If StartBit is greater than 31, then ASSERT().
1053 If EndBit is greater than 31, then ASSERT().
1054 If EndBit is less than StartBit, then ASSERT().
1056 @param Address PCI configuration register to read.
1057 @param StartBit The ordinal of the least significant bit in the bit field.
1059 @param EndBit The ordinal of the most significant bit in the bit field.
1062 @return The value of the bit field read from the PCI configuration register.
1067 PciCf8BitFieldRead32 (
1073 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1074 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1075 return IoBitFieldRead32 (
1076 PCI_CONFIGURATION_DATA_PORT
,
1083 Writes a bit field to a PCI configuration register.
1085 Writes Value to the bit field of the PCI configuration register. The bit
1086 field is specified by the StartBit and the EndBit. All other bits in the
1087 destination PCI configuration register are preserved. The new value of the
1088 32-bit register is returned.
1090 If Address > 0x0FFFFFFF, then ASSERT().
1091 If Address is not aligned on a 32-bit boundary, then ASSERT().
1092 If the register specified by Address >= 0x100, then ASSERT().
1093 If StartBit is greater than 31, then ASSERT().
1094 If EndBit is greater than 31, then ASSERT().
1095 If EndBit is less than StartBit, then ASSERT().
1097 @param Address PCI configuration register to write.
1098 @param StartBit The ordinal of the least significant bit in the bit field.
1100 @param EndBit The ordinal of the most significant bit in the bit field.
1102 @param Value New value of the bit field.
1104 @return The value written back to the PCI configuration register.
1109 PciCf8BitFieldWrite32 (
1116 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1117 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1118 return IoBitFieldWrite32 (
1119 PCI_CONFIGURATION_DATA_PORT
,
1127 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1128 writes the result back to the bit field in the 32-bit port.
1130 Reads the 32-bit PCI configuration register specified by Address, performs a
1131 bitwise inclusive OR between the read result and the value specified by
1132 OrData, and writes the result to the 32-bit PCI configuration register
1133 specified by Address. The value written to the PCI configuration register is
1134 returned. This function must guarantee that all PCI read and write operations
1135 are serialized. Extra left bits in OrData are stripped.
1137 If Address > 0x0FFFFFFF, then ASSERT().
1138 If Address is not aligned on a 32-bit boundary, then ASSERT().
1139 If the register specified by Address >= 0x100, then ASSERT().
1140 If StartBit is greater than 31, then ASSERT().
1141 If EndBit is greater than 31, then ASSERT().
1142 If EndBit is less than StartBit, then ASSERT().
1144 @param Address PCI configuration register to write.
1145 @param StartBit The ordinal of the least significant bit in the bit field.
1147 @param EndBit The ordinal of the most significant bit in the bit field.
1149 @param OrData The value to OR with the PCI configuration register.
1151 @return The value written back to the PCI configuration register.
1156 PciCf8BitFieldOr32 (
1163 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1164 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1165 return IoBitFieldOr32 (
1166 PCI_CONFIGURATION_DATA_PORT
,
1174 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1175 AND, and writes the result back to the bit field in the 32-bit register.
1177 Reads the 32-bit PCI configuration register specified by Address, performs a
1178 bitwise AND between the read result and the value specified by AndData, and
1179 writes the result to the 32-bit PCI configuration register specified by
1180 Address. The value written to the PCI configuration register is returned.
1181 This function must guarantee that all PCI read and write operations are
1182 serialized. Extra left bits in AndData are stripped.
1184 If Address > 0x0FFFFFFF, then ASSERT().
1185 If Address is not aligned on a 32-bit boundary, then ASSERT().
1186 If the register specified by Address >= 0x100, then ASSERT().
1187 If StartBit is greater than 31, then ASSERT().
1188 If EndBit is greater than 31, then ASSERT().
1189 If EndBit is less than StartBit, then ASSERT().
1191 @param Address PCI configuration register to write.
1192 @param StartBit The ordinal of the least significant bit in the bit field.
1194 @param EndBit The ordinal of the most significant bit in the bit field.
1196 @param AndData The value to AND with the PCI configuration register.
1198 @return The value written back to the PCI configuration register.
1203 PciCf8BitFieldAnd32 (
1210 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1211 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1212 return IoBitFieldAnd32 (
1213 PCI_CONFIGURATION_DATA_PORT
,
1221 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1222 bitwise inclusive OR, and writes the result back to the bit field in the
1225 Reads the 32-bit PCI configuration register specified by Address, performs a
1226 bitwise AND followed by a bitwise inclusive OR between the read result and
1227 the value specified by AndData, and writes the result to the 32-bit PCI
1228 configuration register specified by Address. The value written to the PCI
1229 configuration register is returned. This function must guarantee that all PCI
1230 read and write operations are serialized. Extra left bits in both AndData and
1231 OrData are stripped.
1233 If Address > 0x0FFFFFFF, then ASSERT().
1234 If Address is not aligned on a 32-bit boundary, then ASSERT().
1235 If the register specified by Address >= 0x100, then ASSERT().
1236 If StartBit is greater than 31, then ASSERT().
1237 If EndBit is greater than 31, then ASSERT().
1238 If EndBit is less than StartBit, then ASSERT().
1240 @param Address PCI configuration register to write.
1241 @param StartBit The ordinal of the least significant bit in the bit field.
1243 @param EndBit The ordinal of the most significant bit in the bit field.
1245 @param AndData The value to AND with the PCI configuration register.
1246 @param OrData The value to OR with the result of the AND operation.
1248 @return The value written back to the PCI configuration register.
1253 PciCf8BitFieldAndThenOr32(
1261 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1262 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1263 return IoBitFieldAndThenOr32 (
1264 PCI_CONFIGURATION_DATA_PORT
,
1273 Reads a range of PCI configuration registers into a caller supplied buffer.
1275 Reads the range of PCI configuration registers specified by StartAddress and
1276 Size into the buffer specified by Buffer. This function only allows the PCI
1277 configuration registers from a single PCI function to be read. Size is
1278 returned. When possible 32-bit PCI configuration read cycles are used to read
1279 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1280 and 16-bit PCI configuration read cycles may be used at the beginning and the
1283 If StartAddress > 0x0FFFFFFF, then ASSERT().
1284 If the register specified by StartAddress >= 0x100, then ASSERT().
1285 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1286 If Size > 0 and Buffer is NULL, then ASSERT().
1288 @param StartAddress Starting address that encodes the PCI Bus, Device,
1289 Function and Register.
1290 @param Size Size in bytes of the transfer.
1291 @param Buffer Pointer to a buffer receiving the data read.
1299 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 Value
= (UINTN
) PciCf8Read16 (StartAddress
);
1336 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) Value
);
1338 StartAddress
+= sizeof (UINT16
);
1339 Size
-= sizeof (UINT16
);
1340 Buffer
= (UINT16
*)Buffer
+ 1;
1343 while (Size
>= sizeof (UINT32
)) {
1345 // Read as many double words as possible
1347 Value
= (UINTN
) PciCf8Read32 (StartAddress
);
1348 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
) Value
);
1349 StartAddress
+= sizeof (UINT32
);
1350 Size
-= sizeof (UINT32
);
1351 Buffer
= (UINT32
*)Buffer
+ 1;
1354 if (Size
>= sizeof (UINT16
)) {
1356 // Read the last remaining word if exist
1358 Value
= (UINTN
) PciCf8Read16 (StartAddress
);
1359 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) Value
);
1360 StartAddress
+= sizeof (UINT16
);
1361 Size
-= sizeof (UINT16
);
1362 Buffer
= (UINT16
*)Buffer
+ 1;
1365 if (Size
>= sizeof (UINT8
)) {
1367 // Read the last remaining byte if exist
1369 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1376 Copies the data in a caller supplied buffer to a specified range of PCI
1377 configuration space.
1379 Writes the range of PCI configuration registers specified by StartAddress and
1380 Size from the buffer specified by Buffer. This function only allows the PCI
1381 configuration registers from a single PCI function to be written. Size is
1382 returned. When possible 32-bit PCI configuration write cycles are used to
1383 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1384 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1385 and the end of the range.
1387 If StartAddress > 0x0FFFFFFF, then ASSERT().
1388 If the register specified by StartAddress >= 0x100, then ASSERT().
1389 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1390 If Size > 0 and Buffer is NULL, then ASSERT().
1392 @param StartAddress Starting address that encodes the PCI Bus, Device,
1393 Function and Register.
1394 @param Size Size in bytes of the transfer.
1395 @param Buffer Pointer to a buffer containing the data to write.
1403 IN UINTN StartAddress
,
1410 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1411 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1417 ASSERT (Buffer
!= NULL
);
1420 // Save Size for return
1424 if ((StartAddress
& 1) != 0) {
1426 // Write a byte if StartAddress is byte aligned
1428 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1429 StartAddress
+= sizeof (UINT8
);
1430 Size
-= sizeof (UINT8
);
1431 Buffer
= (UINT8
*)Buffer
+ 1;
1434 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1436 // Write a word if StartAddress is word aligned
1438 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1439 StartAddress
+= sizeof (UINT16
);
1440 Size
-= sizeof (UINT16
);
1441 Buffer
= (UINT16
*)Buffer
+ 1;
1444 while (Size
>= sizeof (UINT32
)) {
1446 // Write as many double words as possible
1448 PciCf8Write32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1449 StartAddress
+= sizeof (UINT32
);
1450 Size
-= sizeof (UINT32
);
1451 Buffer
= (UINT32
*)Buffer
+ 1;
1454 if (Size
>= sizeof (UINT16
)) {
1456 // Write the last remaining word if exist
1458 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1459 StartAddress
+= sizeof (UINT16
);
1460 Size
-= sizeof (UINT16
);
1461 Buffer
= (UINT16
*)Buffer
+ 1;
1464 if (Size
>= sizeof (UINT8
)) {
1466 // Write the last remaining byte if exist
1468 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);