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 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Library/BaseLib.h>
14 #include <Library/PciCf8Lib.h>
15 #include <Library/IoLib.h>
16 #include <Library/DebugLib.h>
19 // Declare I/O Ports used to perform PCI Confguration Cycles
21 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
22 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
25 Convert a PCI Library address to PCI CF8 formatted address.
27 Declare macro to convert PCI Library address to PCI CF8 formatted address.
28 Bit fields of PCI Library and CF8 formatted address is as follows:
29 PCI Library formatted address CF8 Formatted Address
30 ============================= ======================
31 Bits 00..11 Register Bits 00..07 Register
32 Bits 12..14 Function Bits 08..10 Function
33 Bits 15..19 Device Bits 11..15 Device
34 Bits 20..27 Bus Bits 16..23 Bus
35 Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
38 @param A The address to convert.
40 @retval The coverted address.
43 #define PCI_TO_CF8_ADDRESS(A) \
44 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
47 Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's
48 only in the low 28 bits, excluding bits 08..11.
50 @param A The address to validate.
51 @param M Additional bits to assert to be zero.
54 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
55 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
58 Registers a PCI device so PCI configuration registers may be accessed after
59 SetVirtualAddressMap().
61 Registers the PCI device specified by Address so all the PCI configuration registers
62 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
64 If Address > 0x0FFFFFFF, then ASSERT().
65 If the register specified by Address >= 0x100, then ASSERT().
67 @param Address The address that encodes the PCI Bus, Device, Function and
70 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
71 @retval RETURN_UNSUPPORTED An attempt was made to call this function
72 after ExitBootServices().
73 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
74 at runtime could not be mapped.
75 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
76 complete the registration.
81 PciCf8RegisterForRuntimeAccess (
85 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
86 return RETURN_SUCCESS
;
90 Reads an 8-bit PCI configuration register.
92 Reads and returns the 8-bit PCI configuration register specified by Address.
93 This function must guarantee that all PCI read and write operations are
96 If Address > 0x0FFFFFFF, then ASSERT().
97 If the register specified by Address >= 0x100, then ASSERT().
99 @param Address The address that encodes the PCI Bus, Device, Function and
102 @return The read value from the PCI configuration register.
111 BOOLEAN InterruptState
;
115 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
116 InterruptState
= SaveAndDisableInterrupts ();
117 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
118 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
119 Result
= IoRead8 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3));
120 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
121 SetInterruptState (InterruptState
);
126 Writes an 8-bit PCI configuration register.
128 Writes the 8-bit PCI configuration register specified by Address with the
129 value specified by Value. Value is returned. This function must guarantee
130 that all PCI read and write operations are serialized.
132 If Address > 0x0FFFFFFF, then ASSERT().
133 If the register specified by Address >= 0x100, then ASSERT().
135 @param Address The address that encodes the PCI Bus, Device, Function and
137 @param Value The value to write.
139 @return The value written to the PCI configuration register.
149 BOOLEAN InterruptState
;
153 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
154 InterruptState
= SaveAndDisableInterrupts ();
155 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
156 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
158 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
161 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
162 SetInterruptState (InterruptState
);
167 Performs a bitwise OR of an 8-bit PCI configuration register with
170 Reads the 8-bit PCI configuration register specified by Address, performs a
171 bitwise OR between the read result and the value specified by
172 OrData, and writes the result to the 8-bit PCI configuration register
173 specified by Address. The value written to the PCI configuration register is
174 returned. This function must guarantee that all PCI read and write operations
177 If Address > 0x0FFFFFFF, then ASSERT().
178 If the register specified by Address >= 0x100, then ASSERT().
180 @param Address The address that encodes the PCI Bus, Device, Function and
182 @param OrData The value to OR with the PCI configuration register.
184 @return The value written back to the PCI configuration register.
194 BOOLEAN InterruptState
;
198 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
199 InterruptState
= SaveAndDisableInterrupts ();
200 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
201 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
203 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
206 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
207 SetInterruptState (InterruptState
);
212 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
215 Reads the 8-bit PCI configuration register specified by Address, performs a
216 bitwise AND between the read result and the value specified by AndData, and
217 writes the result to the 8-bit PCI configuration register specified by
218 Address. The value written to the PCI configuration register is returned.
219 This function must guarantee that all PCI read and write operations are
222 If Address > 0x0FFFFFFF, then ASSERT().
223 If the register specified by Address >= 0x100, then ASSERT().
225 @param Address The address that encodes the PCI Bus, Device, Function and
227 @param AndData The value to AND with the PCI configuration register.
229 @return The value written back to the PCI configuration register.
239 BOOLEAN InterruptState
;
243 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
244 InterruptState
= SaveAndDisableInterrupts ();
245 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
246 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
248 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
251 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
252 SetInterruptState (InterruptState
);
257 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
258 value, followed a bitwise OR with another 8-bit value.
260 Reads the 8-bit PCI configuration register specified by Address, performs a
261 bitwise AND between the read result and the value specified by AndData,
262 performs a bitwise OR between the result of the AND operation and
263 the value specified by OrData, and writes the result to the 8-bit PCI
264 configuration register specified by Address. The value written to the PCI
265 configuration register is returned. This function must guarantee that all PCI
266 read and write operations are serialized.
268 If Address > 0x0FFFFFFF, then ASSERT().
269 If the register specified by Address >= 0x100, then ASSERT().
271 @param Address The address that encodes the PCI Bus, Device, Function and
273 @param AndData The value to AND with the PCI configuration register.
274 @param OrData The value to OR with the result of the AND operation.
276 @return The value written back to the PCI configuration register.
287 BOOLEAN InterruptState
;
291 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
292 InterruptState
= SaveAndDisableInterrupts ();
293 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
294 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
295 Result
= IoAndThenOr8 (
296 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
300 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
301 SetInterruptState (InterruptState
);
306 Reads a bit field of a PCI configuration register.
308 Reads the bit field in an 8-bit PCI configuration register. The bit field is
309 specified by the StartBit and the EndBit. The value of the bit field is
312 If Address > 0x0FFFFFFF, then ASSERT().
313 If the register specified by Address >= 0x100, then ASSERT().
314 If StartBit is greater than 7, then ASSERT().
315 If EndBit is greater than 7, then ASSERT().
316 If EndBit is less than StartBit, then ASSERT().
318 @param Address The PCI configuration register to read.
319 @param StartBit The ordinal of the least significant bit in the bit field.
321 @param EndBit The ordinal of the most significant bit in the bit field.
324 @return The value of the bit field read from the PCI configuration register.
329 PciCf8BitFieldRead8 (
335 BOOLEAN InterruptState
;
339 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
340 InterruptState
= SaveAndDisableInterrupts ();
341 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
342 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
343 Result
= IoBitFieldRead8 (
344 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
348 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
349 SetInterruptState (InterruptState
);
354 Writes a bit field to a PCI configuration register.
356 Writes Value to the bit field of the PCI configuration register. The bit
357 field is specified by the StartBit and the EndBit. All other bits in the
358 destination PCI configuration register are preserved. The new value of the
359 8-bit register is returned.
361 If Address > 0x0FFFFFFF, then ASSERT().
362 If the register specified by Address >= 0x100, then ASSERT().
363 If StartBit is greater than 7, then ASSERT().
364 If EndBit is greater than 7, then ASSERT().
365 If EndBit is less than StartBit, then ASSERT().
366 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
368 @param Address The PCI configuration register to write.
369 @param StartBit The ordinal of the least significant bit in the bit field.
371 @param EndBit The ordinal of the most significant bit in the bit field.
373 @param Value The new value of the bit field.
375 @return The value written back to the PCI configuration register.
380 PciCf8BitFieldWrite8 (
387 BOOLEAN InterruptState
;
391 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
392 InterruptState
= SaveAndDisableInterrupts ();
393 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
394 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
395 Result
= IoBitFieldWrite8 (
396 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
401 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
402 SetInterruptState (InterruptState
);
407 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
408 writes the result back to the bit field in the 8-bit port.
410 Reads the 8-bit PCI configuration register specified by Address, performs a
411 bitwise OR between the read result and the value specified by
412 OrData, and writes the result to the 8-bit PCI configuration register
413 specified by Address. The value written to the PCI configuration register is
414 returned. This function must guarantee that all PCI read and write operations
415 are serialized. Extra left bits in OrData are stripped.
417 If Address > 0x0FFFFFFF, then ASSERT().
418 If the register specified by Address >= 0x100, then ASSERT().
419 If StartBit is greater than 7, then ASSERT().
420 If EndBit is greater than 7, then ASSERT().
421 If EndBit is less than StartBit, then ASSERT().
422 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
424 @param Address The PCI configuration register to write.
425 @param StartBit The ordinal of the least significant bit in the bit field.
427 @param EndBit The ordinal of the most significant bit in the bit field.
429 @param OrData The value to OR with the PCI configuration register.
431 @return The value written back to the PCI configuration register.
443 BOOLEAN InterruptState
;
447 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
448 InterruptState
= SaveAndDisableInterrupts ();
449 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
450 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
451 Result
= IoBitFieldOr8 (
452 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
457 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
458 SetInterruptState (InterruptState
);
463 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
464 AND, and writes the result back to the bit field in the 8-bit register.
466 Reads the 8-bit PCI configuration register specified by Address, performs a
467 bitwise AND between the read result and the value specified by AndData, and
468 writes the result to the 8-bit PCI configuration register specified by
469 Address. The value written to the PCI configuration register is returned.
470 This function must guarantee that all PCI read and write operations are
471 serialized. Extra left bits in AndData are stripped.
473 If Address > 0x0FFFFFFF, then ASSERT().
474 If the register specified by Address >= 0x100, then ASSERT().
475 If StartBit is greater than 7, then ASSERT().
476 If EndBit is greater than 7, then ASSERT().
477 If EndBit is less than StartBit, then ASSERT().
478 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
480 @param Address The PCI configuration register to write.
481 @param StartBit The ordinal of the least significant bit in the bit field.
483 @param EndBit The ordinal of the most significant bit in the bit field.
485 @param AndData The value to AND with the PCI configuration register.
487 @return The value written back to the PCI configuration register.
499 BOOLEAN InterruptState
;
503 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
504 InterruptState
= SaveAndDisableInterrupts ();
505 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
506 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
507 Result
= IoBitFieldAnd8 (
508 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
513 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
514 SetInterruptState (InterruptState
);
519 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
520 bitwise OR, and writes the result back to the bit field in the
523 Reads the 8-bit PCI configuration register specified by Address, performs a
524 bitwise AND followed by a bitwise OR between the read result and
525 the value specified by AndData, and writes the result to the 8-bit PCI
526 configuration register specified by Address. The value written to the PCI
527 configuration register is returned. This function must guarantee that all PCI
528 read and write operations are serialized. Extra left bits in both AndData and
531 If Address > 0x0FFFFFFF, then ASSERT().
532 If the register specified by Address >= 0x100, then ASSERT().
533 If StartBit is greater than 7, then ASSERT().
534 If EndBit is greater than 7, then ASSERT().
535 If EndBit is less than StartBit, then ASSERT().
536 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
537 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
539 @param Address The PCI configuration register to write.
540 @param StartBit The ordinal of the least significant bit in the bit field.
542 @param EndBit The ordinal of the most significant bit in the bit field.
544 @param AndData The value to AND with the PCI configuration register.
545 @param OrData The value to OR with the result of the AND operation.
547 @return The value written back to the PCI configuration register.
552 PciCf8BitFieldAndThenOr8(
560 BOOLEAN InterruptState
;
564 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
565 InterruptState
= SaveAndDisableInterrupts ();
566 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
567 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
568 Result
= IoBitFieldAndThenOr8 (
569 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 3),
575 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
576 SetInterruptState (InterruptState
);
581 Reads a 16-bit PCI configuration register.
583 Reads and returns the 16-bit PCI configuration register specified by Address.
584 This function must guarantee that all PCI read and write operations are
587 If Address > 0x0FFFFFFF, then ASSERT().
588 If Address is not aligned on a 16-bit boundary, then ASSERT().
589 If the register specified by Address >= 0x100, then ASSERT().
591 @param Address The address that encodes the PCI Bus, Device, Function and
594 @return The read value from the PCI configuration register.
603 BOOLEAN InterruptState
;
607 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
608 InterruptState
= SaveAndDisableInterrupts ();
609 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
610 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
611 Result
= IoRead16 (PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2));
612 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
613 SetInterruptState (InterruptState
);
618 Writes a 16-bit PCI configuration register.
620 Writes the 16-bit PCI configuration register specified by Address with the
621 value specified by Value. Value is returned. This function must guarantee
622 that all PCI read and write operations are serialized.
624 If Address > 0x0FFFFFFF, then ASSERT().
625 If Address is not aligned on a 16-bit boundary, then ASSERT().
626 If the register specified by Address >= 0x100, then ASSERT().
628 @param Address The address that encodes the PCI Bus, Device, Function and
630 @param Value The value to write.
632 @return The value written to the PCI configuration register.
642 BOOLEAN InterruptState
;
646 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
647 InterruptState
= SaveAndDisableInterrupts ();
648 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
649 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
651 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
654 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
655 SetInterruptState (InterruptState
);
660 Performs a bitwise OR of a 16-bit PCI configuration register with
663 Reads the 16-bit PCI configuration register specified by Address, performs a
664 bitwise OR between the read result and the value specified by
665 OrData, and writes the result to the 16-bit PCI configuration register
666 specified by Address. The value written to the PCI configuration register is
667 returned. This function must guarantee that all PCI read and write operations
670 If Address > 0x0FFFFFFF, then ASSERT().
671 If Address is not aligned on a 16-bit boundary, then ASSERT().
672 If the register specified by Address >= 0x100, then ASSERT().
674 @param Address The address that encodes the PCI Bus, Device, Function and
676 @param OrData The value to OR with the PCI configuration register.
678 @return The value written back to the PCI configuration register.
688 BOOLEAN InterruptState
;
692 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
693 InterruptState
= SaveAndDisableInterrupts ();
694 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
695 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
697 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
700 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
701 SetInterruptState (InterruptState
);
706 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
709 Reads the 16-bit PCI configuration register specified by Address, performs a
710 bitwise AND between the read result and the value specified by AndData, and
711 writes the result to the 16-bit PCI configuration register specified by
712 Address. The value written to the PCI configuration register is returned.
713 This function must guarantee that all PCI read and write operations are
716 If Address > 0x0FFFFFFF, then ASSERT().
717 If Address is not aligned on a 16-bit boundary, then ASSERT().
718 If the register specified by Address >= 0x100, then ASSERT().
720 @param Address The address that encodes the PCI Bus, Device, Function and
722 @param AndData The value to AND with the PCI configuration register.
724 @return The value written back to the PCI configuration register.
734 BOOLEAN InterruptState
;
738 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
739 InterruptState
= SaveAndDisableInterrupts ();
740 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
741 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
743 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
746 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
747 SetInterruptState (InterruptState
);
752 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
753 value, followed a bitwise OR with another 16-bit value.
755 Reads the 16-bit PCI configuration register specified by Address, performs a
756 bitwise AND between the read result and the value specified by AndData,
757 performs a bitwise OR between the result of the AND operation and
758 the value specified by OrData, and writes the result to the 16-bit PCI
759 configuration register specified by Address. The value written to the PCI
760 configuration register is returned. This function must guarantee that all PCI
761 read and write operations are serialized.
763 If Address > 0x0FFFFFFF, then ASSERT().
764 If Address is not aligned on a 16-bit boundary, then ASSERT().
765 If the register specified by Address >= 0x100, then ASSERT().
767 @param Address The address that encodes the PCI Bus, Device, Function and
769 @param AndData The value to AND with the PCI configuration register.
770 @param OrData The value to OR with the result of the AND operation.
772 @return The value written back to the PCI configuration register.
783 BOOLEAN InterruptState
;
787 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
788 InterruptState
= SaveAndDisableInterrupts ();
789 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
790 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
791 Result
= IoAndThenOr16 (
792 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
796 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
797 SetInterruptState (InterruptState
);
802 Reads a bit field of a PCI configuration register.
804 Reads the bit field in a 16-bit PCI configuration register. The bit field is
805 specified by the StartBit and the EndBit. The value of the bit field is
808 If Address > 0x0FFFFFFF, then ASSERT().
809 If Address is not aligned on a 16-bit boundary, then ASSERT().
810 If the register specified by Address >= 0x100, then ASSERT().
811 If StartBit is greater than 15, then ASSERT().
812 If EndBit is greater than 15, then ASSERT().
813 If EndBit is less than StartBit, then ASSERT().
815 @param Address The PCI configuration register to read.
816 @param StartBit The ordinal of the least significant bit in the bit field.
818 @param EndBit The ordinal of the most significant bit in the bit field.
821 @return The value of the bit field read from the PCI configuration register.
826 PciCf8BitFieldRead16 (
832 BOOLEAN InterruptState
;
836 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
837 InterruptState
= SaveAndDisableInterrupts ();
838 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
839 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
840 Result
= IoBitFieldRead16 (
841 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
845 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
846 SetInterruptState (InterruptState
);
851 Writes a bit field to a PCI configuration register.
853 Writes Value to the bit field of the PCI configuration register. The bit
854 field is specified by the StartBit and the EndBit. All other bits in the
855 destination PCI configuration register are preserved. The new value of the
856 16-bit register is returned.
858 If Address > 0x0FFFFFFF, then ASSERT().
859 If Address is not aligned on a 16-bit boundary, then ASSERT().
860 If the register specified by Address >= 0x100, then ASSERT().
861 If StartBit is greater than 15, then ASSERT().
862 If EndBit is greater than 15, then ASSERT().
863 If EndBit is less than StartBit, then ASSERT().
864 If Value is larger than the bitmask value range specified by StartBit and EndBit, 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().
921 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
923 @param Address The PCI configuration register to write.
924 @param StartBit The ordinal of the least significant bit in the bit field.
926 @param EndBit The ordinal of the most significant bit in the bit field.
928 @param OrData The value to OR with the PCI configuration register.
930 @return The value written back to the PCI configuration register.
942 BOOLEAN InterruptState
;
946 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
947 InterruptState
= SaveAndDisableInterrupts ();
948 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
949 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
950 Result
= IoBitFieldOr16 (
951 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
956 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
957 SetInterruptState (InterruptState
);
962 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
963 AND, and writes the result back to the bit field in the 16-bit register.
965 Reads the 16-bit PCI configuration register specified by Address, performs a
966 bitwise AND between the read result and the value specified by AndData, and
967 writes the result to the 16-bit PCI configuration register specified by
968 Address. The value written to the PCI configuration register is returned.
969 This function must guarantee that all PCI read and write operations are
970 serialized. Extra left bits in AndData are stripped.
972 If Address > 0x0FFFFFFF, then ASSERT().
973 If Address is not aligned on a 16-bit boundary, then ASSERT().
974 If the register specified by Address >= 0x100, then ASSERT().
975 If StartBit is greater than 15, then ASSERT().
976 If EndBit is greater than 15, then ASSERT().
977 If EndBit is less than StartBit, then ASSERT().
978 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
980 @param Address The PCI configuration register to write.
981 @param StartBit The ordinal of the least significant bit in the bit field.
983 @param EndBit The ordinal of the most significant bit in the bit field.
985 @param AndData The value to AND with the PCI configuration register.
987 @return The value written back to the PCI configuration register.
992 PciCf8BitFieldAnd16 (
999 BOOLEAN InterruptState
;
1003 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
1004 InterruptState
= SaveAndDisableInterrupts ();
1005 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1006 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1007 Result
= IoBitFieldAnd16 (
1008 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
1013 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1014 SetInterruptState (InterruptState
);
1019 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1020 bitwise OR, and writes the result back to the bit field in the
1023 Reads the 16-bit PCI configuration register specified by Address, performs a
1024 bitwise AND followed by a bitwise OR between the read result and
1025 the value specified by AndData, and writes the result to the 16-bit PCI
1026 configuration register specified by Address. The value written to the PCI
1027 configuration register is returned. This function must guarantee that all PCI
1028 read and write operations are serialized. Extra left bits in both AndData and
1029 OrData are stripped.
1031 If Address > 0x0FFFFFFF, then ASSERT().
1032 If Address is not aligned on a 16-bit boundary, then ASSERT().
1033 If the register specified by Address >= 0x100, then ASSERT().
1034 If StartBit is greater than 15, then ASSERT().
1035 If EndBit is greater than 15, then ASSERT().
1036 If EndBit is less than StartBit, then ASSERT().
1037 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1038 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1040 @param Address The PCI configuration register to write.
1041 @param StartBit The ordinal of the least significant bit in the bit field.
1043 @param EndBit The ordinal of the most significant bit in the bit field.
1045 @param AndData The value to AND with the PCI configuration register.
1046 @param OrData The value to OR with the result of the AND operation.
1048 @return The value written back to the PCI configuration register.
1053 PciCf8BitFieldAndThenOr16(
1061 BOOLEAN InterruptState
;
1065 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
1066 InterruptState
= SaveAndDisableInterrupts ();
1067 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1068 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1069 Result
= IoBitFieldAndThenOr16 (
1070 PCI_CONFIGURATION_DATA_PORT
+ (UINT16
)(Address
& 2),
1076 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1077 SetInterruptState (InterruptState
);
1082 Reads a 32-bit PCI configuration register.
1084 Reads and returns the 32-bit PCI configuration register specified by Address.
1085 This function must guarantee that all PCI read and write operations are
1088 If Address > 0x0FFFFFFF, then ASSERT().
1089 If Address is not aligned on a 32-bit boundary, then ASSERT().
1090 If the register specified by Address >= 0x100, then ASSERT().
1092 @param Address The address that encodes the PCI Bus, Device, Function and
1095 @return The read value from the PCI configuration register.
1104 BOOLEAN InterruptState
;
1108 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1109 InterruptState
= SaveAndDisableInterrupts ();
1110 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1111 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1112 Result
= IoRead32 (PCI_CONFIGURATION_DATA_PORT
);
1113 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1114 SetInterruptState (InterruptState
);
1119 Writes a 32-bit PCI configuration register.
1121 Writes the 32-bit PCI configuration register specified by Address with the
1122 value specified by Value. Value is returned. This function must guarantee
1123 that all PCI read and write operations are serialized.
1125 If Address > 0x0FFFFFFF, then ASSERT().
1126 If Address is not aligned on a 32-bit boundary, then ASSERT().
1127 If the register specified by Address >= 0x100, then ASSERT().
1129 @param Address The address that encodes the PCI Bus, Device, Function and
1131 @param Value The value to write.
1133 @return The value written to the PCI configuration register.
1143 BOOLEAN InterruptState
;
1147 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1148 InterruptState
= SaveAndDisableInterrupts ();
1149 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1150 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1151 Result
= IoWrite32 (
1152 PCI_CONFIGURATION_DATA_PORT
,
1155 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1156 SetInterruptState (InterruptState
);
1161 Performs a bitwise OR of a 32-bit PCI configuration register with
1164 Reads the 32-bit PCI configuration register specified by Address, performs a
1165 bitwise OR between the read result and the value specified by
1166 OrData, and writes the result to the 32-bit PCI configuration register
1167 specified by Address. The value written to the PCI configuration register is
1168 returned. This function must guarantee that all PCI read and write operations
1171 If Address > 0x0FFFFFFF, then ASSERT().
1172 If Address is not aligned on a 32-bit boundary, then ASSERT().
1173 If the register specified by Address >= 0x100, then ASSERT().
1175 @param Address The address that encodes the PCI Bus, Device, Function and
1177 @param OrData The value to OR with the PCI configuration register.
1179 @return The value written back to the PCI configuration register.
1189 BOOLEAN InterruptState
;
1193 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1194 InterruptState
= SaveAndDisableInterrupts ();
1195 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1196 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1198 PCI_CONFIGURATION_DATA_PORT
,
1201 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1202 SetInterruptState (InterruptState
);
1207 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1210 Reads the 32-bit PCI configuration register specified by Address, performs a
1211 bitwise AND between the read result and the value specified by AndData, and
1212 writes the result to the 32-bit PCI configuration register specified by
1213 Address. The value written to the PCI configuration register is returned.
1214 This function must guarantee that all PCI read and write operations are
1217 If Address > 0x0FFFFFFF, then ASSERT().
1218 If Address is not aligned on a 32-bit boundary, then ASSERT().
1219 If the register specified by Address >= 0x100, then ASSERT().
1221 @param Address The address that encodes the PCI Bus, Device, Function and
1223 @param AndData The value to AND with the PCI configuration register.
1225 @return The value written back to the PCI configuration register.
1235 BOOLEAN InterruptState
;
1239 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1240 InterruptState
= SaveAndDisableInterrupts ();
1241 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1242 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1244 PCI_CONFIGURATION_DATA_PORT
,
1247 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1248 SetInterruptState (InterruptState
);
1253 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1254 value, followed a bitwise OR with another 32-bit value.
1256 Reads the 32-bit PCI configuration register specified by Address, performs a
1257 bitwise AND between the read result and the value specified by AndData,
1258 performs a bitwise OR between the result of the AND operation and
1259 the value specified by OrData, and writes the result to the 32-bit PCI
1260 configuration register specified by Address. The value written to the PCI
1261 configuration register is returned. This function must guarantee that all PCI
1262 read and write operations are serialized.
1264 If Address > 0x0FFFFFFF, then ASSERT().
1265 If Address is not aligned on a 32-bit boundary, then ASSERT().
1266 If the register specified by Address >= 0x100, then ASSERT().
1268 @param Address The address that encodes the PCI Bus, Device, Function and
1270 @param AndData The value to AND with the PCI configuration register.
1271 @param OrData The value to OR with the result of the AND operation.
1273 @return The value written back to the PCI configuration register.
1284 BOOLEAN InterruptState
;
1288 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1289 InterruptState
= SaveAndDisableInterrupts ();
1290 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1291 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1292 Result
= IoAndThenOr32 (
1293 PCI_CONFIGURATION_DATA_PORT
,
1297 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1298 SetInterruptState (InterruptState
);
1303 Reads a bit field of a PCI configuration register.
1305 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1306 specified by the StartBit and the EndBit. The value of the bit field is
1309 If Address > 0x0FFFFFFF, then ASSERT().
1310 If Address is not aligned on a 32-bit boundary, then ASSERT().
1311 If the register specified by Address >= 0x100, then ASSERT().
1312 If StartBit is greater than 31, then ASSERT().
1313 If EndBit is greater than 31, then ASSERT().
1314 If EndBit is less than StartBit, then ASSERT().
1316 @param Address The PCI configuration register to read.
1317 @param StartBit The ordinal of the least significant bit in the bit field.
1319 @param EndBit The ordinal of the most significant bit in the bit field.
1322 @return The value of the bit field read from the PCI configuration register.
1327 PciCf8BitFieldRead32 (
1333 BOOLEAN InterruptState
;
1337 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1338 InterruptState
= SaveAndDisableInterrupts ();
1339 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1340 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1341 Result
= IoBitFieldRead32 (
1342 PCI_CONFIGURATION_DATA_PORT
,
1346 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1347 SetInterruptState (InterruptState
);
1352 Writes a bit field to a PCI configuration register.
1354 Writes Value to the bit field of the PCI configuration register. The bit
1355 field is specified by the StartBit and the EndBit. All other bits in the
1356 destination PCI configuration register are preserved. The new value of the
1357 32-bit register is returned.
1359 If Address > 0x0FFFFFFF, then ASSERT().
1360 If Address is not aligned on a 32-bit boundary, then ASSERT().
1361 If the register specified by Address >= 0x100, then ASSERT().
1362 If StartBit is greater than 31, then ASSERT().
1363 If EndBit is greater than 31, then ASSERT().
1364 If EndBit is less than StartBit, then ASSERT().
1365 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1367 @param Address The PCI configuration register to write.
1368 @param StartBit The ordinal of the least significant bit in the bit field.
1370 @param EndBit The ordinal of the most significant bit in the bit field.
1372 @param Value The new value of the bit field.
1374 @return The value written back to the PCI configuration register.
1379 PciCf8BitFieldWrite32 (
1386 BOOLEAN InterruptState
;
1390 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1391 InterruptState
= SaveAndDisableInterrupts ();
1392 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1393 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1394 Result
= IoBitFieldWrite32 (
1395 PCI_CONFIGURATION_DATA_PORT
,
1400 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1401 SetInterruptState (InterruptState
);
1406 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1407 writes the result back to the bit field in the 32-bit port.
1409 Reads the 32-bit PCI configuration register specified by Address, performs a
1410 bitwise OR between the read result and the value specified by
1411 OrData, and writes the result to the 32-bit PCI configuration register
1412 specified by Address. The value written to the PCI configuration register is
1413 returned. This function must guarantee that all PCI read and write operations
1414 are serialized. Extra left bits in OrData are stripped.
1416 If Address > 0x0FFFFFFF, then ASSERT().
1417 If Address is not aligned on a 32-bit boundary, then ASSERT().
1418 If the register specified by Address >= 0x100, then ASSERT().
1419 If StartBit is greater than 31, then ASSERT().
1420 If EndBit is greater than 31, then ASSERT().
1421 If EndBit is less than StartBit, then ASSERT().
1422 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1424 @param Address The PCI configuration register to write.
1425 @param StartBit The ordinal of the least significant bit in the bit field.
1427 @param EndBit The ordinal of the most significant bit in the bit field.
1429 @param OrData The value to OR with the PCI configuration register.
1431 @return The value written back to the PCI configuration register.
1436 PciCf8BitFieldOr32 (
1443 BOOLEAN InterruptState
;
1447 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1448 InterruptState
= SaveAndDisableInterrupts ();
1449 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1450 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1451 Result
= IoBitFieldOr32 (
1452 PCI_CONFIGURATION_DATA_PORT
,
1457 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1458 SetInterruptState (InterruptState
);
1463 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1464 AND, and writes the result back to the bit field in the 32-bit register.
1466 Reads the 32-bit PCI configuration register specified by Address, performs a
1467 bitwise AND between the read result and the value specified by AndData, and
1468 writes the result to the 32-bit PCI configuration register specified by
1469 Address. The value written to the PCI configuration register is returned.
1470 This function must guarantee that all PCI read and write operations are
1471 serialized. Extra left bits in AndData are stripped.
1473 If Address > 0x0FFFFFFF, then ASSERT().
1474 If Address is not aligned on a 32-bit boundary, then ASSERT().
1475 If the register specified by Address >= 0x100, then ASSERT().
1476 If StartBit is greater than 31, then ASSERT().
1477 If EndBit is greater than 31, then ASSERT().
1478 If EndBit is less than StartBit, then ASSERT().
1479 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1481 @param Address The PCI configuration register to write.
1482 @param StartBit The ordinal of the least significant bit in the bit field.
1484 @param EndBit The ordinal of the most significant bit in the bit field.
1486 @param AndData The value to AND with the PCI configuration register.
1488 @return The value written back to the PCI configuration register.
1493 PciCf8BitFieldAnd32 (
1500 BOOLEAN InterruptState
;
1504 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1505 InterruptState
= SaveAndDisableInterrupts ();
1506 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1507 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1508 Result
= IoBitFieldAnd32 (
1509 PCI_CONFIGURATION_DATA_PORT
,
1514 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1515 SetInterruptState (InterruptState
);
1520 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1521 bitwise OR, and writes the result back to the bit field in the
1524 Reads the 32-bit PCI configuration register specified by Address, performs a
1525 bitwise AND followed by a bitwise OR between the read result and
1526 the value specified by AndData, and writes the result to the 32-bit PCI
1527 configuration register specified by Address. The value written to the PCI
1528 configuration register is returned. This function must guarantee that all PCI
1529 read and write operations are serialized. Extra left bits in both AndData and
1530 OrData are stripped.
1532 If Address > 0x0FFFFFFF, then ASSERT().
1533 If Address is not aligned on a 32-bit boundary, then ASSERT().
1534 If the register specified by Address >= 0x100, then ASSERT().
1535 If StartBit is greater than 31, then ASSERT().
1536 If EndBit is greater than 31, then ASSERT().
1537 If EndBit is less than StartBit, then ASSERT().
1538 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1539 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1541 @param Address The PCI configuration register to write.
1542 @param StartBit The ordinal of the least significant bit in the bit field.
1544 @param EndBit The ordinal of the most significant bit in the bit field.
1546 @param AndData The value to AND with the PCI configuration register.
1547 @param OrData The value to OR with the result of the AND operation.
1549 @return The value written back to the PCI configuration register.
1554 PciCf8BitFieldAndThenOr32(
1562 BOOLEAN InterruptState
;
1566 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
1567 InterruptState
= SaveAndDisableInterrupts ();
1568 AddressPort
= IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT
);
1569 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, PCI_TO_CF8_ADDRESS (Address
));
1570 Result
= IoBitFieldAndThenOr32 (
1571 PCI_CONFIGURATION_DATA_PORT
,
1577 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT
, AddressPort
);
1578 SetInterruptState (InterruptState
);
1583 Reads a range of PCI configuration registers into a caller supplied buffer.
1585 Reads the range of PCI configuration registers specified by StartAddress and
1586 Size into the buffer specified by Buffer. This function only allows the PCI
1587 configuration registers from a single PCI function to be read. Size is
1588 returned. When possible 32-bit PCI configuration read cycles are used to read
1589 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1590 and 16-bit PCI configuration read cycles may be used at the beginning and the
1593 If StartAddress > 0x0FFFFFFF, then ASSERT().
1594 If the register specified by StartAddress >= 0x100, then ASSERT().
1595 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1596 If Size > 0 and Buffer is NULL, then ASSERT().
1598 @param StartAddress The starting address that encodes the PCI Bus, Device,
1599 Function and Register.
1600 @param Size The size in bytes of the transfer.
1601 @param Buffer The pointer to a buffer receiving the data read.
1603 @return Size read from StartAddress.
1609 IN UINTN StartAddress
,
1616 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1617 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1623 ASSERT (Buffer
!= NULL
);
1626 // Save Size for return
1630 if ((StartAddress
& 1) != 0) {
1632 // Read a byte if StartAddress is byte aligned
1634 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1635 StartAddress
+= sizeof (UINT8
);
1636 Size
-= sizeof (UINT8
);
1637 Buffer
= (UINT8
*)Buffer
+ 1;
1640 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1642 // Read a word if StartAddress is word aligned
1644 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1646 StartAddress
+= sizeof (UINT16
);
1647 Size
-= sizeof (UINT16
);
1648 Buffer
= (UINT16
*)Buffer
+ 1;
1651 while (Size
>= sizeof (UINT32
)) {
1653 // Read as many double words as possible
1655 WriteUnaligned32 ((UINT32
*)Buffer
, (UINT32
) PciCf8Read32 (StartAddress
));
1656 StartAddress
+= sizeof (UINT32
);
1657 Size
-= sizeof (UINT32
);
1658 Buffer
= (UINT32
*)Buffer
+ 1;
1661 if (Size
>= sizeof (UINT16
)) {
1663 // Read the last remaining word if exist
1665 WriteUnaligned16 ((UINT16
*)Buffer
, (UINT16
) PciCf8Read16 (StartAddress
));
1666 StartAddress
+= sizeof (UINT16
);
1667 Size
-= sizeof (UINT16
);
1668 Buffer
= (UINT16
*)Buffer
+ 1;
1671 if (Size
>= sizeof (UINT8
)) {
1673 // Read the last remaining byte if exist
1675 *(volatile UINT8
*)Buffer
= PciCf8Read8 (StartAddress
);
1682 Copies the data in a caller supplied buffer to a specified range of PCI
1683 configuration space.
1685 Writes the range of PCI configuration registers specified by StartAddress and
1686 Size from the buffer specified by Buffer. This function only allows the PCI
1687 configuration registers from a single PCI function to be written. Size is
1688 returned. When possible 32-bit PCI configuration write cycles are used to
1689 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1690 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1691 and the end of the range.
1693 If StartAddress > 0x0FFFFFFF, then ASSERT().
1694 If the register specified by StartAddress >= 0x100, then ASSERT().
1695 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1696 If Size > 0 and Buffer is NULL, then ASSERT().
1698 @param StartAddress The starting address that encodes the PCI Bus, Device,
1699 Function and Register.
1700 @param Size The size in bytes of the transfer.
1701 @param Buffer The pointer to a buffer containing the data to write.
1703 @return Size written to StartAddress.
1709 IN UINTN StartAddress
,
1716 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1717 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x100);
1723 ASSERT (Buffer
!= NULL
);
1726 // Save Size for return
1730 if ((StartAddress
& 1) != 0) {
1732 // Write a byte if StartAddress is byte aligned
1734 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);
1735 StartAddress
+= sizeof (UINT8
);
1736 Size
-= sizeof (UINT8
);
1737 Buffer
= (UINT8
*)Buffer
+ 1;
1740 if (Size
>= sizeof (UINT16
) && (StartAddress
& 2) != 0) {
1742 // Write a word if StartAddress is word aligned
1744 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1745 StartAddress
+= sizeof (UINT16
);
1746 Size
-= sizeof (UINT16
);
1747 Buffer
= (UINT16
*)Buffer
+ 1;
1750 while (Size
>= sizeof (UINT32
)) {
1752 // Write as many double words as possible
1754 PciCf8Write32 (StartAddress
, ReadUnaligned32 ((UINT32
*)Buffer
));
1755 StartAddress
+= sizeof (UINT32
);
1756 Size
-= sizeof (UINT32
);
1757 Buffer
= (UINT32
*)Buffer
+ 1;
1760 if (Size
>= sizeof (UINT16
)) {
1762 // Write the last remaining word if exist
1764 PciCf8Write16 (StartAddress
, ReadUnaligned16 ((UINT16
*)Buffer
));
1765 StartAddress
+= sizeof (UINT16
);
1766 Size
-= sizeof (UINT16
);
1767 Buffer
= (UINT16
*)Buffer
+ 1;
1770 if (Size
>= sizeof (UINT8
)) {
1772 // Write the last remaining byte if exist
1774 PciCf8Write8 (StartAddress
, *(UINT8
*)Buffer
);