2 PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
3 Layers on top of an I/O Library instance.
5 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/BaseLib.h>
20 #include <Library/PciCf8Lib.h>
21 #include <Library/IoLib.h>
22 #include <Library/DebugLib.h>
25 // Declare I/O Ports used to perform PCI Confguration Cycles
27 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
28 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
31 Convert a PCI Library address to PCI CF8 formatted address.
33 Declare macro to convert PCI Library address to PCI CF8 formatted address.
34 Bit fields of PCI Library and CF8 formatted address is as follows:
35 PCI Library formatted address CF8 Formatted Address
36 ============================= ======================
37 Bits 00..11 Register Bits 00..07 Register
38 Bits 12..14 Function Bits 08..10 Function
39 Bits 15..19 Device Bits 11..15 Device
40 Bits 20..27 Bus Bits 16..23 Bus
41 Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
44 @param A The address to convert.
46 @retval The coverted address.
49 #define PCI_TO_CF8_ADDRESS(A) \
50 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
53 Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's
54 only in the low 28 bits, excluding bits 08..11.
56 @param A The address to validate.
57 @param M Additional bits to assert to be zero.
60 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
61 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
64 Registers a PCI device so PCI configuration registers may be accessed after
65 SetVirtualAddressMap().
67 Registers the PCI device specified by Address so all the PCI configuration registers
68 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
70 If Address > 0x0FFFFFFF, then ASSERT().
71 If the register specified by Address >= 0x100, then ASSERT().
73 @param Address The address that encodes the PCI Bus, Device, Function and
76 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
77 @retval RETURN_UNSUPPORTED An attempt was made to call this function
78 after ExitBootServices().
79 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
80 at runtime could not be mapped.
81 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
82 complete the registration.
87 PciCf8RegisterForRuntimeAccess (
91 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
92 return RETURN_SUCCESS
;
96 Reads an 8-bit PCI configuration register.
98 Reads and returns the 8-bit PCI configuration register specified by Address.
99 This function must guarantee that all PCI read and write operations are
102 If Address > 0x0FFFFFFF, then ASSERT().
103 If the register specified by Address >= 0x100, then ASSERT().
105 @param Address The address that encodes the PCI Bus, Device, Function and
108 @return The read value from the PCI configuration register.
117 BOOLEAN InterruptState
;
121 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
122 InterruptState
= SaveAndDisableInterrupts ();
123 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
124 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
125 Result
= IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
126 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
127 SetInterruptState (InterruptState
);
132 Writes an 8-bit PCI configuration register.
134 Writes the 8-bit PCI configuration register specified by Address with the
135 value specified by Value. Value is returned. This function must guarantee
136 that all PCI read and write operations are serialized.
138 If Address > 0x0FFFFFFF, then ASSERT().
139 If the register specified by Address >= 0x100, then ASSERT().
141 @param Address The address that encodes the PCI Bus, Device, Function and
143 @param Value The value to write.
145 @return The value written to the PCI configuration register.
155 BOOLEAN InterruptState
;
159 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
160 InterruptState
= SaveAndDisableInterrupts ();
161 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
162 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
164 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
167 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
168 SetInterruptState (InterruptState
);
173 Performs a bitwise OR of an 8-bit PCI configuration register with
176 Reads the 8-bit PCI configuration register specified by Address, performs a
177 bitwise OR between the read result and the value specified by
178 OrData, and writes the result to the 8-bit PCI configuration register
179 specified by Address. The value written to the PCI configuration register is
180 returned. This function must guarantee that all PCI read and write operations
183 If Address > 0x0FFFFFFF, then ASSERT().
184 If the register specified by Address >= 0x100, then ASSERT().
186 @param Address The address that encodes the PCI Bus, Device, Function and
188 @param OrData The value to OR with the PCI configuration register.
190 @return The value written back to the PCI configuration register.
200 BOOLEAN InterruptState
;
204 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
205 InterruptState
= SaveAndDisableInterrupts ();
206 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
207 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
209 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
212 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
213 SetInterruptState (InterruptState
);
218 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
221 Reads the 8-bit PCI configuration register specified by Address, performs a
222 bitwise AND between the read result and the value specified by AndData, and
223 writes the result to the 8-bit PCI configuration register specified by
224 Address. The value written to the PCI configuration register is returned.
225 This function must guarantee that all PCI read and write operations are
228 If Address > 0x0FFFFFFF, then ASSERT().
229 If the register specified by Address >= 0x100, then ASSERT().
231 @param Address The address that encodes the PCI Bus, Device, Function and
233 @param AndData The value to AND with the PCI configuration register.
235 @return The value written back to the PCI configuration register.
245 BOOLEAN InterruptState
;
249 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
250 InterruptState
= SaveAndDisableInterrupts ();
251 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
252 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
254 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
257 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
258 SetInterruptState (InterruptState
);
263 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
264 value, followed a bitwise OR with another 8-bit value.
266 Reads the 8-bit PCI configuration register specified by Address, performs a
267 bitwise AND between the read result and the value specified by AndData,
268 performs a bitwise OR between the result of the AND operation and
269 the value specified by OrData, and writes the result to the 8-bit PCI
270 configuration register specified by Address. The value written to the PCI
271 configuration register is returned. This function must guarantee that all PCI
272 read and write operations are serialized.
274 If Address > 0x0FFFFFFF, then ASSERT().
275 If the register specified by Address >= 0x100, then ASSERT().
277 @param Address The address that encodes the PCI Bus, Device, Function and
279 @param AndData The value to AND with the PCI configuration register.
280 @param OrData The value to OR with the result of the AND operation.
282 @return The value written back to the PCI configuration register.
293 BOOLEAN InterruptState
;
297 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
298 InterruptState
= SaveAndDisableInterrupts ();
299 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
300 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
301 Result
= IoAndThenOr8 (
302 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
306 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
307 SetInterruptState (InterruptState
);
312 Reads a bit field of a PCI configuration register.
314 Reads the bit field in an 8-bit PCI configuration register. The bit field is
315 specified by the StartBit and the EndBit. The value of the bit field is
318 If Address > 0x0FFFFFFF, then ASSERT().
319 If the register specified by Address >= 0x100, then ASSERT().
320 If StartBit is greater than 7, then ASSERT().
321 If EndBit is greater than 7, then ASSERT().
322 If EndBit is less than StartBit, then ASSERT().
324 @param Address The PCI configuration register to read.
325 @param StartBit The ordinal of the least significant bit in the bit field.
327 @param EndBit The ordinal of the most significant bit in the bit field.
330 @return The value of the bit field read from the PCI configuration register.
335 PciCf8BitFieldRead8 (
341 BOOLEAN InterruptState
;
345 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
346 InterruptState
= SaveAndDisableInterrupts ();
347 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
348 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
349 Result
= IoBitFieldRead8 (
350 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
354 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
355 SetInterruptState (InterruptState
);
360 Writes a bit field to a PCI configuration register.
362 Writes Value to the bit field of the PCI configuration register. The bit
363 field is specified by the StartBit and the EndBit. All other bits in the
364 destination PCI configuration register are preserved. The new value of the
365 8-bit register is returned.
367 If Address > 0x0FFFFFFF, then ASSERT().
368 If the register specified by Address >= 0x100, then ASSERT().
369 If StartBit is greater than 7, then ASSERT().
370 If EndBit is greater than 7, then ASSERT().
371 If EndBit is less than StartBit, then ASSERT().
373 @param Address The PCI configuration register to write.
374 @param StartBit The ordinal of the least significant bit in the bit field.
376 @param EndBit The ordinal of the most significant bit in the bit field.
378 @param Value The new value of the bit field.
380 @return The value written back to the PCI configuration register.
385 PciCf8BitFieldWrite8 (
392 BOOLEAN InterruptState
;
396 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
397 InterruptState
= SaveAndDisableInterrupts ();
398 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
399 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
400 Result
= IoBitFieldWrite8 (
401 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
406 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
407 SetInterruptState (InterruptState
);
412 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
413 writes the result back to the bit field in the 8-bit port.
415 Reads the 8-bit PCI configuration register specified by Address, performs a
416 bitwise OR between the read result and the value specified by
417 OrData, and writes the result to the 8-bit PCI configuration register
418 specified by Address. The value written to the PCI configuration register is
419 returned. This function must guarantee that all PCI read and write operations
420 are serialized. Extra left bits in OrData are stripped.
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 The 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 OrData The value to OR with the PCI configuration register.
435 @return The value written back to the PCI configuration register.
447 BOOLEAN InterruptState
;
451 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
452 InterruptState
= SaveAndDisableInterrupts ();
453 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
454 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
455 Result
= IoBitFieldOr8 (
456 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
461 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
462 SetInterruptState (InterruptState
);
467 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
468 AND, and writes the result back to the bit field in the 8-bit register.
470 Reads the 8-bit PCI configuration register specified by Address, performs a
471 bitwise AND between the read result and the value specified by AndData, and
472 writes the result to the 8-bit PCI configuration register specified by
473 Address. The value written to the PCI configuration register is returned.
474 This function must guarantee that all PCI read and write operations are
475 serialized. Extra left bits in AndData are stripped.
477 If Address > 0x0FFFFFFF, then ASSERT().
478 If the register specified by Address >= 0x100, then ASSERT().
479 If StartBit is greater than 7, then ASSERT().
480 If EndBit is greater than 7, then ASSERT().
481 If EndBit is less than StartBit, then ASSERT().
483 @param Address The PCI configuration register to write.
484 @param StartBit The ordinal of the least significant bit in the bit field.
486 @param EndBit The ordinal of the most significant bit in the bit field.
488 @param AndData The value to AND with the PCI configuration register.
490 @return The value written back to the PCI configuration register.
502 BOOLEAN InterruptState
;
506 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
507 InterruptState
= SaveAndDisableInterrupts ();
508 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
509 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
510 Result
= IoBitFieldAnd8 (
511 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
516 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
517 SetInterruptState (InterruptState
);
522 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
523 bitwise OR, and writes the result back to the bit field in the
526 Reads the 8-bit PCI configuration register specified by Address, performs a
527 bitwise AND followed by a bitwise OR between the read result and
528 the value specified by AndData, and writes the result to the 8-bit PCI
529 configuration register specified by Address. The value written to the PCI
530 configuration register is returned. This function must guarantee that all PCI
531 read and write operations are serialized. Extra left bits in both AndData and
534 If Address > 0x0FFFFFFF, then ASSERT().
535 If the register specified by Address >= 0x100, then ASSERT().
536 If StartBit is greater than 7, then ASSERT().
537 If EndBit is greater than 7, then ASSERT().
538 If EndBit is less than StartBit, then ASSERT().
540 @param Address The PCI configuration register to write.
541 @param StartBit The ordinal of the least significant bit in the bit field.
543 @param EndBit The ordinal of the most significant bit in the bit field.
545 @param AndData The value to AND with the PCI configuration register.
546 @param OrData The value to OR with the result of the AND operation.
548 @return The value written back to the PCI configuration register.
553 PciCf8BitFieldAndThenOr8(
561 BOOLEAN InterruptState
;
565 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
566 InterruptState
= SaveAndDisableInterrupts ();
567 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
568 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
569 Result
= IoBitFieldAndThenOr8 (
570 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
576 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
577 SetInterruptState (InterruptState
);
582 Reads a 16-bit PCI configuration register.
584 Reads and returns the 16-bit PCI configuration register specified by Address.
585 This function must guarantee that all PCI read and write operations are
588 If Address > 0x0FFFFFFF, then ASSERT().
589 If Address is not aligned on a 16-bit boundary, then ASSERT().
590 If the register specified by Address >= 0x100, then ASSERT().
592 @param Address The address that encodes the PCI Bus, Device, Function and
595 @return The read value from the PCI configuration register.
604 BOOLEAN InterruptState
;
608 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
609 InterruptState
= SaveAndDisableInterrupts ();
610 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
611 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
612 Result
= IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
613 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
614 SetInterruptState (InterruptState
);
619 Writes a 16-bit PCI configuration register.
621 Writes the 16-bit PCI configuration register specified by Address with the
622 value specified by Value. Value is returned. This function must guarantee
623 that all PCI read and write operations are serialized.
625 If Address > 0x0FFFFFFF, then ASSERT().
626 If Address is not aligned on a 16-bit boundary, then ASSERT().
627 If the register specified by Address >= 0x100, then ASSERT().
629 @param Address The address that encodes the PCI Bus, Device, Function and
631 @param Value The value to write.
633 @return The value written to the PCI configuration register.
643 BOOLEAN InterruptState
;
647 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
648 InterruptState
= SaveAndDisableInterrupts ();
649 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
650 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
652 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
655 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
656 SetInterruptState (InterruptState
);
661 Performs a bitwise OR of a 16-bit PCI configuration register with
664 Reads the 16-bit PCI configuration register specified by Address, performs a
665 bitwise OR between the read result and the value specified by
666 OrData, and writes the result to the 16-bit PCI configuration register
667 specified by Address. The value written to the PCI configuration register is
668 returned. This function must guarantee that all PCI read and write operations
671 If Address > 0x0FFFFFFF, then ASSERT().
672 If Address is not aligned on a 16-bit boundary, then ASSERT().
673 If the register specified by Address >= 0x100, then ASSERT().
675 @param Address The address that encodes the PCI Bus, Device, Function and
677 @param OrData The value to OR with the PCI configuration register.
679 @return The value written back to the PCI configuration register.
689 BOOLEAN InterruptState
;
693 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
694 InterruptState
= SaveAndDisableInterrupts ();
695 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
696 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
698 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
701 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
702 SetInterruptState (InterruptState
);
707 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
710 Reads the 16-bit PCI configuration register specified by Address, performs a
711 bitwise AND between the read result and the value specified by AndData, and
712 writes the result to the 16-bit PCI configuration register specified by
713 Address. The value written to the PCI configuration register is returned.
714 This function must guarantee that all PCI read and write operations are
717 If Address > 0x0FFFFFFF, then ASSERT().
718 If Address is not aligned on a 16-bit boundary, then ASSERT().
719 If the register specified by Address >= 0x100, then ASSERT().
721 @param Address The address that encodes the PCI Bus, Device, Function and
723 @param AndData The value to AND with the PCI configuration register.
725 @return The value written back to the PCI configuration register.
735 BOOLEAN InterruptState
;
739 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
740 InterruptState
= SaveAndDisableInterrupts ();
741 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
742 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
744 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
747 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
748 SetInterruptState (InterruptState
);
753 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
754 value, followed a bitwise OR with another 16-bit value.
756 Reads the 16-bit PCI configuration register specified by Address, performs a
757 bitwise AND between the read result and the value specified by AndData,
758 performs a bitwise OR between the result of the AND operation and
759 the value specified by OrData, and writes the result to the 16-bit PCI
760 configuration register specified by Address. The value written to the PCI
761 configuration register is returned. This function must guarantee that all PCI
762 read and write operations are serialized.
764 If Address > 0x0FFFFFFF, then ASSERT().
765 If Address is not aligned on a 16-bit boundary, then ASSERT().
766 If the register specified by Address >= 0x100, then ASSERT().
768 @param Address The address that encodes the PCI Bus, Device, Function and
770 @param AndData The value to AND with the PCI configuration register.
771 @param OrData The value to OR with the result of the AND operation.
773 @return The value written back to the PCI configuration register.
784 BOOLEAN InterruptState
;
788 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
789 InterruptState
= SaveAndDisableInterrupts ();
790 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
791 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
792 Result
= IoAndThenOr16 (
793 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
797 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
798 SetInterruptState (InterruptState
);
803 Reads a bit field of a PCI configuration register.
805 Reads the bit field in a 16-bit PCI configuration register. The bit field is
806 specified by the StartBit and the EndBit. The value of the bit field is
809 If Address > 0x0FFFFFFF, then ASSERT().
810 If Address is not aligned on a 16-bit boundary, then ASSERT().
811 If the register specified by Address >= 0x100, then ASSERT().
812 If StartBit is greater than 15, then ASSERT().
813 If EndBit is greater than 15, then ASSERT().
814 If EndBit is less than StartBit, then ASSERT().
816 @param Address The PCI configuration register to read.
817 @param StartBit The ordinal of the least significant bit in the bit field.
819 @param EndBit The ordinal of the most significant bit in the bit field.
822 @return The value of the bit field read from the PCI configuration register.
827 PciCf8BitFieldRead16 (
833 BOOLEAN InterruptState
;
837 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
838 InterruptState
= SaveAndDisableInterrupts ();
839 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
840 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
841 Result
= IoBitFieldRead16 (
842 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
846 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
847 SetInterruptState (InterruptState
);
852 Writes a bit field to a PCI configuration register.
854 Writes Value to the bit field of the PCI configuration register. The bit
855 field is specified by the StartBit and the EndBit. All other bits in the
856 destination PCI configuration register are preserved. The new value of the
857 16-bit register is returned.
859 If Address > 0x0FFFFFFF, then ASSERT().
860 If Address is not aligned on a 16-bit boundary, then ASSERT().
861 If the register specified by Address >= 0x100, then ASSERT().
862 If StartBit is greater than 15, then ASSERT().
863 If EndBit is greater than 15, then ASSERT().
864 If EndBit is less than StartBit, then ASSERT().
866 @param Address The PCI configuration register to write.
867 @param StartBit The ordinal of the least significant bit in the bit field.
869 @param EndBit The ordinal of the most significant bit in the bit field.
871 @param Value The new value of the bit field.
873 @return The value written back to the PCI configuration register.
878 PciCf8BitFieldWrite16 (
885 BOOLEAN InterruptState
;
889 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
890 InterruptState
= SaveAndDisableInterrupts ();
891 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
892 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
893 Result
= IoBitFieldWrite16 (
894 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
899 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
900 SetInterruptState (InterruptState
);
905 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
906 writes the result back to the bit field in the 16-bit port.
908 Reads the 16-bit PCI configuration register specified by Address, performs a
909 bitwise OR between the read result and the value specified by
910 OrData, and writes the result to the 16-bit PCI configuration register
911 specified by Address. The value written to the PCI configuration register is
912 returned. This function must guarantee that all PCI read and write operations
913 are serialized. Extra left bits in OrData are stripped.
915 If Address > 0x0FFFFFFF, then ASSERT().
916 If Address is not aligned on a 16-bit boundary, then ASSERT().
917 If the register specified by Address >= 0x100, then ASSERT().
918 If StartBit is greater than 15, then ASSERT().
919 If EndBit is greater than 15, then ASSERT().
920 If EndBit is less than StartBit, then ASSERT().
922 @param Address The PCI configuration register to write.
923 @param StartBit The ordinal of the least significant bit in the bit field.
925 @param EndBit The ordinal of the most significant bit in the bit field.
927 @param OrData The value to OR with the PCI configuration register.
929 @return The value written back to the PCI configuration register.
941 BOOLEAN InterruptState
;
945 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
946 InterruptState
= SaveAndDisableInterrupts ();
947 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
948 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
949 Result
= IoBitFieldOr16 (
950 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
955 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
956 SetInterruptState (InterruptState
);
961 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
962 AND, and writes the result back to the bit field in the 16-bit register.
964 Reads the 16-bit PCI configuration register specified by Address, performs a
965 bitwise AND between the read result and the value specified by AndData, and
966 writes the result to the 16-bit PCI configuration register specified by
967 Address. The value written to the PCI configuration register is returned.
968 This function must guarantee that all PCI read and write operations are
969 serialized. Extra left bits in AndData are stripped.
971 If Address > 0x0FFFFFFF, then ASSERT().
972 If Address is not aligned on a 16-bit boundary, then ASSERT().
973 If the register specified by Address >= 0x100, then ASSERT().
974 If StartBit is greater than 15, then ASSERT().
975 If EndBit is greater than 15, then ASSERT().
976 If EndBit is less than StartBit, then ASSERT().
978 @param Address The PCI configuration register to write.
979 @param StartBit The ordinal of the least significant bit in the bit field.
981 @param EndBit The ordinal of the most significant bit in the bit field.
983 @param AndData The value to AND with the PCI configuration register.
985 @return The value written back to the PCI configuration register.
990 PciCf8BitFieldAnd16 (
997 BOOLEAN InterruptState
;
1001 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
1002 InterruptState
= SaveAndDisableInterrupts ();
1003 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1004 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1005 Result
= IoBitFieldAnd16 (
1006 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
1011 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1012 SetInterruptState (InterruptState
);
1017 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1018 bitwise OR, and writes the result back to the bit field in the
1021 Reads the 16-bit PCI configuration register specified by Address, performs a
1022 bitwise AND followed by a bitwise OR between the read result and
1023 the value specified by AndData, and writes the result to the 16-bit PCI
1024 configuration register specified by Address. The value written to the PCI
1025 configuration register is returned. This function must guarantee that all PCI
1026 read and write operations are serialized. Extra left bits in both AndData and
1027 OrData are stripped.
1029 If Address > 0x0FFFFFFF, then ASSERT().
1030 If Address is not aligned on a 16-bit boundary, then ASSERT().
1031 If the register specified by Address >= 0x100, then ASSERT().
1032 If StartBit is greater than 15, then ASSERT().
1033 If EndBit is greater than 15, then ASSERT().
1034 If EndBit is less than StartBit, then ASSERT().
1036 @param Address The PCI configuration register to write.
1037 @param StartBit The ordinal of the least significant bit in the bit field.
1039 @param EndBit The ordinal of the most significant bit in the bit field.
1041 @param AndData The value to AND with the PCI configuration register.
1042 @param OrData The value to OR with the result of the AND operation.
1044 @return The value written back to the PCI configuration register.
1049 PciCf8BitFieldAndThenOr16(
1057 BOOLEAN InterruptState
;
1061 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
1062 InterruptState
= SaveAndDisableInterrupts ();
1063 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1064 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1065 Result
= IoBitFieldAndThenOr16 (
1066 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
1072 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1073 SetInterruptState (InterruptState
);
1078 Reads a 32-bit PCI configuration register.
1080 Reads and returns the 32-bit PCI configuration register specified by Address.
1081 This function must guarantee that all PCI read and write operations are
1084 If Address > 0x0FFFFFFF, then ASSERT().
1085 If Address is not aligned on a 32-bit boundary, then ASSERT().
1086 If the register specified by Address >= 0x100, then ASSERT().
1088 @param Address The address that encodes the PCI Bus, Device, Function and
1091 @return The read value from the PCI configuration register.
1100 BOOLEAN InterruptState
;
1104 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1105 InterruptState
= SaveAndDisableInterrupts ();
1106 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1107 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1108 Result
= IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
1109 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1110 SetInterruptState (InterruptState
);
1115 Writes a 32-bit PCI configuration register.
1117 Writes the 32-bit PCI configuration register specified by Address with the
1118 value specified by Value. Value is returned. This function must guarantee
1119 that all PCI read and write operations are serialized.
1121 If Address > 0x0FFFFFFF, then ASSERT().
1122 If Address is not aligned on a 32-bit boundary, then ASSERT().
1123 If the register specified by Address >= 0x100, then ASSERT().
1125 @param Address The address that encodes the PCI Bus, Device, Function and
1127 @param Value The value to write.
1129 @return The value written to the PCI configuration register.
1139 BOOLEAN InterruptState
;
1143 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1144 InterruptState
= SaveAndDisableInterrupts ();
1145 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1146 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1147 Result
= IoWrite32 (
1148 PCI_CONFIGURATION_DATA_PORT
,
1151 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1152 SetInterruptState (InterruptState
);
1157 Performs a bitwise OR of a 32-bit PCI configuration register with
1160 Reads the 32-bit PCI configuration register specified by Address, performs a
1161 bitwise OR between the read result and the value specified by
1162 OrData, and writes the result to the 32-bit PCI configuration register
1163 specified by Address. The value written to the PCI configuration register is
1164 returned. This function must guarantee that all PCI read and write operations
1167 If Address > 0x0FFFFFFF, then ASSERT().
1168 If Address is not aligned on a 32-bit boundary, then ASSERT().
1169 If the register specified by Address >= 0x100, then ASSERT().
1171 @param Address The address that encodes the PCI Bus, Device, Function and
1173 @param OrData The value to OR with the PCI configuration register.
1175 @return The value written back to the PCI configuration register.
1185 BOOLEAN InterruptState
;
1189 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1190 InterruptState
= SaveAndDisableInterrupts ();
1191 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1192 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1194 PCI_CONFIGURATION_DATA_PORT
,
1197 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1198 SetInterruptState (InterruptState
);
1203 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1206 Reads the 32-bit PCI configuration register specified by Address, performs a
1207 bitwise AND between the read result and the value specified by AndData, and
1208 writes the result to the 32-bit PCI configuration register specified by
1209 Address. The value written to the PCI configuration register is returned.
1210 This function must guarantee that all PCI read and write operations are
1213 If Address > 0x0FFFFFFF, then ASSERT().
1214 If Address is not aligned on a 32-bit boundary, then ASSERT().
1215 If the register specified by Address >= 0x100, then ASSERT().
1217 @param Address The address that encodes the PCI Bus, Device, Function and
1219 @param AndData The value to AND with the PCI configuration register.
1221 @return The value written back to the PCI configuration register.
1231 BOOLEAN InterruptState
;
1235 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1236 InterruptState
= SaveAndDisableInterrupts ();
1237 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1238 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1240 PCI_CONFIGURATION_DATA_PORT
,
1243 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1244 SetInterruptState (InterruptState
);
1249 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1250 value, followed a bitwise OR with another 32-bit value.
1252 Reads the 32-bit PCI configuration register specified by Address, performs a
1253 bitwise AND between the read result and the value specified by AndData,
1254 performs a bitwise OR between the result of the AND operation and
1255 the value specified by OrData, and writes the result to the 32-bit PCI
1256 configuration register specified by Address. The value written to the PCI
1257 configuration register is returned. This function must guarantee that all PCI
1258 read and write operations are serialized.
1260 If Address > 0x0FFFFFFF, then ASSERT().
1261 If Address is not aligned on a 32-bit boundary, then ASSERT().
1262 If the register specified by Address >= 0x100, then ASSERT().
1264 @param Address The address that encodes the PCI Bus, Device, Function and
1266 @param AndData The value to AND with the PCI configuration register.
1267 @param OrData The value to OR with the result of the AND operation.
1269 @return The value written back to the PCI configuration register.
1280 BOOLEAN InterruptState
;
1284 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1285 InterruptState
= SaveAndDisableInterrupts ();
1286 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1287 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1288 Result
= IoAndThenOr32 (
1289 PCI_CONFIGURATION_DATA_PORT
,
1293 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1294 SetInterruptState (InterruptState
);
1299 Reads a bit field of a PCI configuration register.
1301 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1302 specified by the StartBit and the EndBit. The value of the bit field is
1305 If Address > 0x0FFFFFFF, then ASSERT().
1306 If Address is not aligned on a 32-bit boundary, then ASSERT().
1307 If the register specified by Address >= 0x100, then ASSERT().
1308 If StartBit is greater than 31, then ASSERT().
1309 If EndBit is greater than 31, then ASSERT().
1310 If EndBit is less than StartBit, then ASSERT().
1312 @param Address The PCI configuration register to read.
1313 @param StartBit The ordinal of the least significant bit in the bit field.
1315 @param EndBit The ordinal of the most significant bit in the bit field.
1318 @return The value of the bit field read from the PCI configuration register.
1323 PciCf8BitFieldRead32 (
1329 BOOLEAN InterruptState
;
1333 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1334 InterruptState
= SaveAndDisableInterrupts ();
1335 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1336 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1337 Result
= IoBitFieldRead32 (
1338 PCI_CONFIGURATION_DATA_PORT
,
1342 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1343 SetInterruptState (InterruptState
);
1348 Writes a bit field to a PCI configuration register.
1350 Writes Value to the bit field of the PCI configuration register. The bit
1351 field is specified by the StartBit and the EndBit. All other bits in the
1352 destination PCI configuration register are preserved. The new value of the
1353 32-bit register is returned.
1355 If Address > 0x0FFFFFFF, then ASSERT().
1356 If Address is not aligned on a 32-bit boundary, then ASSERT().
1357 If the register specified by Address >= 0x100, then ASSERT().
1358 If StartBit is greater than 31, then ASSERT().
1359 If EndBit is greater than 31, then ASSERT().
1360 If EndBit is less than StartBit, then ASSERT().
1362 @param Address The PCI configuration register to write.
1363 @param StartBit The ordinal of the least significant bit in the bit field.
1365 @param EndBit The ordinal of the most significant bit in the bit field.
1367 @param Value The new value of the bit field.
1369 @return The value written back to the PCI configuration register.
1374 PciCf8BitFieldWrite32 (
1381 BOOLEAN InterruptState
;
1385 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1386 InterruptState
= SaveAndDisableInterrupts ();
1387 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1388 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1389 Result
= IoBitFieldWrite32 (
1390 PCI_CONFIGURATION_DATA_PORT
,
1395 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1396 SetInterruptState (InterruptState
);
1401 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1402 writes the result back to the bit field in the 32-bit port.
1404 Reads the 32-bit PCI configuration register specified by Address, performs a
1405 bitwise OR between the read result and the value specified by
1406 OrData, and writes the result to the 32-bit PCI configuration register
1407 specified by Address. The value written to the PCI configuration register is
1408 returned. This function must guarantee that all PCI read and write operations
1409 are serialized. Extra left bits in OrData are stripped.
1411 If Address > 0x0FFFFFFF, then ASSERT().
1412 If Address is not aligned on a 32-bit boundary, then ASSERT().
1413 If the register specified by Address >= 0x100, then ASSERT().
1414 If StartBit is greater than 31, then ASSERT().
1415 If EndBit is greater than 31, then ASSERT().
1416 If EndBit is less than StartBit, then ASSERT().
1418 @param Address The PCI configuration register to write.
1419 @param StartBit The ordinal of the least significant bit in the bit field.
1421 @param EndBit The ordinal of the most significant bit in the bit field.
1423 @param OrData The value to OR with the PCI configuration register.
1425 @return The value written back to the PCI configuration register.
1430 PciCf8BitFieldOr32 (
1437 BOOLEAN InterruptState
;
1441 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1442 InterruptState
= SaveAndDisableInterrupts ();
1443 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1444 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1445 Result
= IoBitFieldOr32 (
1446 PCI_CONFIGURATION_DATA_PORT
,
1451 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1452 SetInterruptState (InterruptState
);
1457 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1458 AND, and writes the result back to the bit field in the 32-bit register.
1460 Reads the 32-bit PCI configuration register specified by Address, performs a
1461 bitwise AND between the read result and the value specified by AndData, and
1462 writes the result to the 32-bit PCI configuration register specified by
1463 Address. The value written to the PCI configuration register is returned.
1464 This function must guarantee that all PCI read and write operations are
1465 serialized. Extra left bits in AndData are stripped.
1467 If Address > 0x0FFFFFFF, then ASSERT().
1468 If Address is not aligned on a 32-bit boundary, then ASSERT().
1469 If the register specified by Address >= 0x100, then ASSERT().
1470 If StartBit is greater than 31, then ASSERT().
1471 If EndBit is greater than 31, then ASSERT().
1472 If EndBit is less than StartBit, then ASSERT().
1474 @param Address The PCI configuration register to write.
1475 @param StartBit The ordinal of the least significant bit in the bit field.
1477 @param EndBit The ordinal of the most significant bit in the bit field.
1479 @param AndData The value to AND with the PCI configuration register.
1481 @return The value written back to the PCI configuration register.
1486 PciCf8BitFieldAnd32 (
1493 BOOLEAN InterruptState
;
1497 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1498 InterruptState
= SaveAndDisableInterrupts ();
1499 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1500 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1501 Result
= IoBitFieldAnd32 (
1502 PCI_CONFIGURATION_DATA_PORT
,
1507 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1508 SetInterruptState (InterruptState
);
1513 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1514 bitwise OR, and writes the result back to the bit field in the
1517 Reads the 32-bit PCI configuration register specified by Address, performs a
1518 bitwise AND followed by a bitwise OR between the read result and
1519 the value specified by AndData, and writes the result to the 32-bit PCI
1520 configuration register specified by Address. The value written to the PCI
1521 configuration register is returned. This function must guarantee that all PCI
1522 read and write operations are serialized. Extra left bits in both AndData and
1523 OrData are stripped.
1525 If Address > 0x0FFFFFFF, then ASSERT().
1526 If Address is not aligned on a 32-bit boundary, then ASSERT().
1527 If the register specified by Address >= 0x100, then ASSERT().
1528 If StartBit is greater than 31, then ASSERT().
1529 If EndBit is greater than 31, then ASSERT().
1530 If EndBit is less than StartBit, then ASSERT().
1532 @param Address The PCI configuration register to write.
1533 @param StartBit The ordinal of the least significant bit in the bit field.
1535 @param EndBit The ordinal of the most significant bit in the bit field.
1537 @param AndData The value to AND with the PCI configuration register.
1538 @param OrData The value to OR with the result of the AND operation.
1540 @return The value written back to the PCI configuration register.
1545 PciCf8BitFieldAndThenOr32(
1553 BOOLEAN InterruptState
;
1557 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1558 InterruptState
= SaveAndDisableInterrupts ();
1559 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1560 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1561 Result
= IoBitFieldAndThenOr32 (
1562 PCI_CONFIGURATION_DATA_PORT
,
1568 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1569 SetInterruptState (InterruptState
);
1574 Reads a range of PCI configuration registers into a caller supplied buffer.
1576 Reads the range of PCI configuration registers specified by StartAddress and
1577 Size into the buffer specified by Buffer. This function only allows the PCI
1578 configuration registers from a single PCI function to be read. Size is
1579 returned. When possible 32-bit PCI configuration read cycles are used to read
1580 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1581 and 16-bit PCI configuration read cycles may be used at the beginning and the
1584 If StartAddress > 0x0FFFFFFF, then ASSERT().
1585 If the register specified by StartAddress >= 0x100, then ASSERT().
1586 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1587 If Size > 0 and Buffer is NULL, then ASSERT().
1589 @param StartAddress The starting address that encodes the PCI Bus, Device,
1590 Function and Register.
1591 @param Size The size in bytes of the transfer.
1592 @param Buffer The pointer to a buffer receiving the data read.
1594 @return Size read from StartAddress.
1600 IN UINTN StartAddress
,
1607 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1608 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1614 ASSERT (Buffer
!= NULL
);
1617 // Save Size for return
1621 if ((StartAddress
& 1) != 0) {
1623 // Read a byte if StartAddress is byte aligned
1625 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1626 StartAddress
+= sizeof (UINT8
);
1627 Size
-= sizeof (UINT8
);
1628 Buffer
= (UINT8
*)Buffer
+ 1;
1631 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1633 // Read a word if StartAddress is word aligned
1635 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1637 StartAddress
+= sizeof (UINT16
);
1638 Size
-= sizeof (UINT16
);
1639 Buffer
= (UINT16
*)Buffer
+ 1;
1642 while (Size
>= sizeof (UINT32
)) {
1644 // Read as many double words as possible
1646 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
) PciCf8Read32 (StartAddress
));
1647 StartAddress
+= sizeof (UINT32
);
1648 Size
-= sizeof (UINT32
);
1649 Buffer
= (UINT32
*)Buffer
+ 1;
1652 if (Size
>= sizeof (UINT16
)) {
1654 // Read the last remaining word if exist
1656 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1657 StartAddress
+= sizeof (UINT16
);
1658 Size
-= sizeof (UINT16
);
1659 Buffer
= (UINT16
*)Buffer
+ 1;
1662 if (Size
>= sizeof (UINT8
)) {
1664 // Read the last remaining byte if exist
1666 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1673 Copies the data in a caller supplied buffer to a specified range of PCI
1674 configuration space.
1676 Writes the range of PCI configuration registers specified by StartAddress and
1677 Size from the buffer specified by Buffer. This function only allows the PCI
1678 configuration registers from a single PCI function to be written. Size is
1679 returned. When possible 32-bit PCI configuration write cycles are used to
1680 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1681 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1682 and the end of the range.
1684 If StartAddress > 0x0FFFFFFF, then ASSERT().
1685 If the register specified by StartAddress >= 0x100, then ASSERT().
1686 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1687 If Size > 0 and Buffer is NULL, then ASSERT().
1689 @param StartAddress The starting address that encodes the PCI Bus, Device,
1690 Function and Register.
1691 @param Size The size in bytes of the transfer.
1692 @param Buffer The pointer to a buffer containing the data to write.
1694 @return Size written to StartAddress.
1700 IN UINTN StartAddress
,
1707 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1708 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1714 ASSERT (Buffer
!= NULL
);
1717 // Save Size for return
1721 if ((StartAddress
& 1) != 0) {
1723 // Write a byte if StartAddress is byte aligned
1725 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1726 StartAddress
+= sizeof (UINT8
);
1727 Size
-= sizeof (UINT8
);
1728 Buffer
= (UINT8
*)Buffer
+ 1;
1731 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1733 // Write a word if StartAddress is word aligned
1735 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1736 StartAddress
+= sizeof (UINT16
);
1737 Size
-= sizeof (UINT16
);
1738 Buffer
= (UINT16
*)Buffer
+ 1;
1741 while (Size
>= sizeof (UINT32
)) {
1743 // Write as many double words as possible
1745 PciCf8Write32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1746 StartAddress
+= sizeof (UINT32
);
1747 Size
-= sizeof (UINT32
);
1748 Buffer
= (UINT32
*)Buffer
+ 1;
1751 if (Size
>= sizeof (UINT16
)) {
1753 // Write the last remaining word if exist
1755 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1756 StartAddress
+= sizeof (UINT16
);
1757 Size
-= sizeof (UINT16
);
1758 Buffer
= (UINT16
*)Buffer
+ 1;
1761 if (Size
>= sizeof (UINT8
)) {
1763 // Write the last remaining byte if exist
1765 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);