2 PCI Library using SMM PCI Root Bridge I/O Protocol.
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are
6 licensed and made available under the terms and conditions of
7 the BSD License which accompanies this distribution. The full
8 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.
16 #include <Protocol/SmmPciRootBridgeIo.h>
17 #include <Library/PciLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/SmmServicesTableLib.h>
24 Assert the validity of a PCI address. A valid PCI address should contain 1's
25 only in the low 28 bits.
27 @param A The address to validate.
28 @param M Additional bits to assert to be zero.
31 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
32 ASSERT (((A) & (~0xfffffff | (M))) == 0)
35 Translate PCI Lib address into format of PCI Root Bridge I/O Protocol.
37 @param A Address that encodes the PCI Bus, Device, Function and
41 #define PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS(A) \
42 ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))
45 // Global varible to cache pointer to PCI Root Bridge I/O protocol.
47 EFI_SMM_PCI_ROOT_BRIDGE_IO_PROTOCOL
*mSmmPciRootBridgeIo
= NULL
;
50 The constructor function caches the pointer to PCI Root Bridge I/O protocol.
52 The constructor function locates PCI Root Bridge I/O protocol from protocol database.
53 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
55 @param ImageHandle The firmware allocated handle for the EFI image.
56 @param SystemTable A pointer to the EFI System Table.
58 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
64 IN EFI_HANDLE ImageHandle
,
65 IN EFI_SYSTEM_TABLE
*SystemTable
70 Status
= gSmst
->SmmLocateProtocol (&gEfiSmmPciRootBridgeIoProtocolGuid
, NULL
, (VOID
**) &mSmmPciRootBridgeIo
);
71 ASSERT_EFI_ERROR (Status
);
72 ASSERT (mSmmPciRootBridgeIo
!= NULL
);
78 Internal worker function to read a PCI configuration register.
80 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.
81 It reads and returns the PCI configuration register specified by Address,
82 the width of data is specified by Width.
84 @param Address Address that encodes the PCI Bus, Device, Function and
86 @param Width Width of data to read
88 @return The value read from the PCI configuration register.
92 SmmPciLibPciRootBridgeIoReadWorker (
94 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
99 mSmmPciRootBridgeIo
->Pci
.Read (
102 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
111 Internal worker function to writes a PCI configuration register.
113 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.
114 It writes the PCI configuration register specified by Address with the
115 value specified by Data. The width of data is specifed by Width.
118 @param Address Address that encodes the PCI Bus, Device, Function and
120 @param Width Width of data to write
121 @param Data The value to write.
123 @return The value written to the PCI configuration register.
127 SmmPciLibPciRootBridgeIoWriteWorker (
129 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width
,
133 mSmmPciRootBridgeIo
->Pci
.Write (
136 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address
),
144 Registers a PCI device so PCI configuration registers may be accessed after
145 SetVirtualAddressMap().
147 Registers the PCI device specified by Address so all the PCI configuration registers
148 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
150 If Address > 0x0FFFFFFF, then ASSERT().
152 @param Address Address that encodes the PCI Bus, Device, Function and
155 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
156 @retval RETURN_UNSUPPORTED An attempt was made to call this function
157 after ExitBootServices().
158 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
159 at runtime could not be mapped.
160 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
161 complete the registration.
166 PciRegisterForRuntimeAccess (
170 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
171 return RETURN_UNSUPPORTED
;
175 Reads an 8-bit PCI configuration register.
177 Reads and returns the 8-bit PCI configuration register specified by Address.
178 This function must guarantee that all PCI read and write operations are
181 If Address > 0x0FFFFFFF, then ASSERT().
183 @param Address Address that encodes the PCI Bus, Device, Function and
186 @return The read value from the PCI configuration register.
195 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
197 return (UINT8
) SmmPciLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint8
);
201 Writes an 8-bit PCI configuration register.
203 Writes the 8-bit PCI configuration register specified by Address with the
204 value specified by Value. Value is returned. This function must guarantee
205 that all PCI read and write operations are serialized.
207 If Address > 0x0FFFFFFF, then ASSERT().
209 @param Address Address that encodes the PCI Bus, Device, Function and
211 @param Value The value to write.
213 @return The value written to the PCI configuration register.
223 ASSERT_INVALID_PCI_ADDRESS (Address
, 0);
225 return (UINT8
) SmmPciLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint8
, Value
);
229 Performs a bitwise OR of an 8-bit PCI configuration register with
232 Reads the 8-bit PCI configuration register specified by Address, performs a
233 bitwise OR between the read result and the value specified by
234 OrData, and writes the result to the 8-bit PCI configuration register
235 specified by Address. The value written to the PCI configuration register is
236 returned. This function must guarantee that all PCI read and write operations
239 If Address > 0x0FFFFFFF, then ASSERT().
241 @param Address Address that encodes the PCI Bus, Device, Function and
243 @param OrData The value to OR with the PCI configuration register.
245 @return The value written back to the PCI configuration register.
255 return PciWrite8 (Address
, (UINT8
) (PciRead8 (Address
) | OrData
));
259 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
262 Reads the 8-bit PCI configuration register specified by Address, performs a
263 bitwise AND between the read result and the value specified by AndData, and
264 writes the result to the 8-bit PCI configuration register specified by
265 Address. The value written to the PCI configuration register is returned.
266 This function must guarantee that all PCI read and write operations are
269 If Address > 0x0FFFFFFF, then ASSERT().
271 @param Address Address that encodes the PCI Bus, Device, Function and
273 @param AndData The value to AND with the PCI configuration register.
275 @return The value written back to the PCI configuration register.
285 return PciWrite8 (Address
, (UINT8
) (PciRead8 (Address
) & AndData
));
289 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
290 value, followed a bitwise OR with another 8-bit value.
292 Reads the 8-bit PCI configuration register specified by Address, performs a
293 bitwise AND between the read result and the value specified by AndData,
294 performs a bitwise OR between the result of the AND operation and
295 the value specified by OrData, and writes the result to the 8-bit PCI
296 configuration register specified by Address. The value written to the PCI
297 configuration register is returned. This function must guarantee that all PCI
298 read and write operations are serialized.
300 If Address > 0x0FFFFFFF, then ASSERT().
302 @param Address Address that encodes the PCI Bus, Device, Function and
304 @param AndData The value to AND with the PCI configuration register.
305 @param OrData The value to OR with the result of the AND operation.
307 @return The value written back to the PCI configuration register.
318 return PciWrite8 (Address
, (UINT8
) ((PciRead8 (Address
) & AndData
) | OrData
));
322 Reads a bit field of a PCI configuration register.
324 Reads the bit field in an 8-bit PCI configuration register. The bit field is
325 specified by the StartBit and the EndBit. The value of the bit field is
328 If Address > 0x0FFFFFFF, then ASSERT().
329 If StartBit is greater than 7, then ASSERT().
330 If EndBit is greater than 7, then ASSERT().
331 If EndBit is less than StartBit, then ASSERT().
333 @param Address PCI configuration register to read.
334 @param StartBit The ordinal of the least significant bit in the bit field.
336 @param EndBit The ordinal of the most significant bit in the bit field.
339 @return The value of the bit field read from the PCI configuration register.
350 return BitFieldRead8 (PciRead8 (Address
), StartBit
, EndBit
);
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 StartBit is greater than 7, then ASSERT().
363 If EndBit is greater than 7, then ASSERT().
364 If EndBit is less than StartBit, then ASSERT().
366 @param Address PCI configuration register to write.
367 @param StartBit The ordinal of the least significant bit in the bit field.
369 @param EndBit The ordinal of the most significant bit in the bit field.
371 @param Value New value of the bit field.
373 @return The value written back to the PCI configuration register.
387 BitFieldWrite8 (PciRead8 (Address
), StartBit
, EndBit
, Value
)
392 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
393 writes the result back to the bit field in the 8-bit port.
395 Reads the 8-bit PCI configuration register specified by Address, performs a
396 bitwise OR between the read result and the value specified by
397 OrData, and writes the result to the 8-bit PCI configuration register
398 specified by Address. The value written to the PCI configuration register is
399 returned. This function must guarantee that all PCI read and write operations
400 are serialized. Extra left bits in OrData are stripped.
402 If Address > 0x0FFFFFFF, then ASSERT().
403 If StartBit is greater than 7, then ASSERT().
404 If EndBit is greater than 7, then ASSERT().
405 If EndBit is less than StartBit, then ASSERT().
407 @param Address PCI configuration register to write.
408 @param StartBit The ordinal of the least significant bit in the bit field.
410 @param EndBit The ordinal of the most significant bit in the bit field.
412 @param OrData The value to OR with the PCI configuration register.
414 @return The value written back to the PCI configuration register.
428 BitFieldOr8 (PciRead8 (Address
), StartBit
, EndBit
, OrData
)
433 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
434 AND, and writes the result back to the bit field in the 8-bit register.
436 Reads the 8-bit PCI configuration register specified by Address, performs a
437 bitwise AND between the read result and the value specified by AndData, and
438 writes the result to the 8-bit PCI configuration register specified by
439 Address. The value written to the PCI configuration register is returned.
440 This function must guarantee that all PCI read and write operations are
441 serialized. Extra left bits in AndData are stripped.
443 If Address > 0x0FFFFFFF, then ASSERT().
444 If StartBit is greater than 7, then ASSERT().
445 If EndBit is greater than 7, then ASSERT().
446 If EndBit is less than StartBit, then ASSERT().
448 @param Address PCI configuration register to write.
449 @param StartBit The ordinal of the least significant bit in the bit field.
451 @param EndBit The ordinal of the most significant bit in the bit field.
453 @param AndData The value to AND with the PCI configuration register.
455 @return The value written back to the PCI configuration register.
469 BitFieldAnd8 (PciRead8 (Address
), StartBit
, EndBit
, AndData
)
474 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
475 bitwise OR, and writes the result back to the bit field in the
478 Reads the 8-bit PCI configuration register specified by Address, performs a
479 bitwise AND followed by a bitwise OR between the read result and
480 the value specified by AndData, and writes the result to the 8-bit PCI
481 configuration register specified by Address. The value written to the PCI
482 configuration register is returned. This function must guarantee that all PCI
483 read and write operations are serialized. Extra left bits in both AndData and
486 If Address > 0x0FFFFFFF, then ASSERT().
487 If StartBit is greater than 7, then ASSERT().
488 If EndBit is greater than 7, then ASSERT().
489 If EndBit is less than StartBit, then ASSERT().
491 @param Address PCI configuration register to write.
492 @param StartBit The ordinal of the least significant bit in the bit field.
494 @param EndBit The ordinal of the most significant bit in the bit field.
496 @param AndData The value to AND with the PCI configuration register.
497 @param OrData The value to OR with the result of the AND operation.
499 @return The value written back to the PCI configuration register.
504 PciBitFieldAndThenOr8 (
514 BitFieldAndThenOr8 (PciRead8 (Address
), StartBit
, EndBit
, AndData
, OrData
)
519 Reads a 16-bit PCI configuration register.
521 Reads and returns the 16-bit PCI configuration register specified by Address.
522 This function must guarantee that all PCI read and write operations are
525 If Address > 0x0FFFFFFF, then ASSERT().
526 If Address is not aligned on a 16-bit boundary, then ASSERT().
528 @param Address Address that encodes the PCI Bus, Device, Function and
531 @return The read value from the PCI configuration register.
540 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
542 return (UINT16
) SmmPciLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint16
);
546 Writes a 16-bit PCI configuration register.
548 Writes the 16-bit PCI configuration register specified by Address with the
549 value specified by Value. Value is returned. This function must guarantee
550 that all PCI read and write operations are serialized.
552 If Address > 0x0FFFFFFF, then ASSERT().
553 If Address is not aligned on a 16-bit boundary, then ASSERT().
555 @param Address Address that encodes the PCI Bus, Device, Function and
557 @param Value The value to write.
559 @return The value written to the PCI configuration register.
569 ASSERT_INVALID_PCI_ADDRESS (Address
, 1);
571 return (UINT16
) SmmPciLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint16
, Value
);
575 Performs a bitwise OR of a 16-bit PCI configuration register with
578 Reads the 16-bit PCI configuration register specified by Address, performs a
579 bitwise OR between the read result and the value specified by
580 OrData, and writes the result to the 16-bit PCI configuration register
581 specified by Address. The value written to the PCI configuration register is
582 returned. This function must guarantee that all PCI read and write operations
585 If Address > 0x0FFFFFFF, then ASSERT().
586 If Address is not aligned on a 16-bit boundary, then ASSERT().
588 @param Address Address that encodes the PCI Bus, Device, Function and
590 @param OrData The value to OR with the PCI configuration register.
592 @return The value written back to the PCI configuration register.
602 return PciWrite16 (Address
, (UINT16
) (PciRead16 (Address
) | OrData
));
606 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
609 Reads the 16-bit PCI configuration register specified by Address, performs a
610 bitwise AND between the read result and the value specified by AndData, and
611 writes the result to the 16-bit PCI configuration register specified by
612 Address. The value written to the PCI configuration register is returned.
613 This function must guarantee that all PCI read and write operations are
616 If Address > 0x0FFFFFFF, then ASSERT().
617 If Address is not aligned on a 16-bit boundary, then ASSERT().
619 @param Address Address that encodes the PCI Bus, Device, Function and
621 @param AndData The value to AND with the PCI configuration register.
623 @return The value written back to the PCI configuration register.
633 return PciWrite16 (Address
, (UINT16
) (PciRead16 (Address
) & AndData
));
637 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
638 value, followed a bitwise OR with another 16-bit value.
640 Reads the 16-bit PCI configuration register specified by Address, performs a
641 bitwise AND between the read result and the value specified by AndData,
642 performs a bitwise OR between the result of the AND operation and
643 the value specified by OrData, and writes the result to the 16-bit PCI
644 configuration register specified by Address. The value written to the PCI
645 configuration register is returned. This function must guarantee that all PCI
646 read and write operations are serialized.
648 If Address > 0x0FFFFFFF, then ASSERT().
649 If Address is not aligned on a 16-bit boundary, then ASSERT().
651 @param Address Address that encodes the PCI Bus, Device, Function and
653 @param AndData The value to AND with the PCI configuration register.
654 @param OrData The value to OR with the result of the AND operation.
656 @return The value written back to the PCI configuration register.
667 return PciWrite16 (Address
, (UINT16
) ((PciRead16 (Address
) & AndData
) | OrData
));
671 Reads a bit field of a PCI configuration register.
673 Reads the bit field in a 16-bit PCI configuration register. The bit field is
674 specified by the StartBit and the EndBit. The value of the bit field is
677 If Address > 0x0FFFFFFF, then ASSERT().
678 If Address is not aligned on a 16-bit boundary, then ASSERT().
679 If StartBit is greater than 15, then ASSERT().
680 If EndBit is greater than 15, then ASSERT().
681 If EndBit is less than StartBit, then ASSERT().
683 @param Address PCI configuration register to read.
684 @param StartBit The ordinal of the least significant bit in the bit field.
686 @param EndBit The ordinal of the most significant bit in the bit field.
689 @return The value of the bit field read from the PCI configuration register.
700 return BitFieldRead16 (PciRead16 (Address
), StartBit
, EndBit
);
704 Writes a bit field to a PCI configuration register.
706 Writes Value to the bit field of the PCI configuration register. The bit
707 field is specified by the StartBit and the EndBit. All other bits in the
708 destination PCI configuration register are preserved. The new value of the
709 16-bit register is returned.
711 If Address > 0x0FFFFFFF, then ASSERT().
712 If Address is not aligned on a 16-bit boundary, then ASSERT().
713 If StartBit is greater than 15, then ASSERT().
714 If EndBit is greater than 15, then ASSERT().
715 If EndBit is less than StartBit, then ASSERT().
717 @param Address PCI configuration register to write.
718 @param StartBit The ordinal of the least significant bit in the bit field.
720 @param EndBit The ordinal of the most significant bit in the bit field.
722 @param Value New value of the bit field.
724 @return The value written back to the PCI configuration register.
738 BitFieldWrite16 (PciRead16 (Address
), StartBit
, EndBit
, Value
)
743 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
744 writes the result back to the bit field in the 16-bit port.
746 Reads the 16-bit PCI configuration register specified by Address, performs a
747 bitwise OR between the read result and the value specified by
748 OrData, and writes the result to the 16-bit PCI configuration register
749 specified by Address. The value written to the PCI configuration register is
750 returned. This function must guarantee that all PCI read and write operations
751 are serialized. Extra left bits in OrData are stripped.
753 If Address > 0x0FFFFFFF, then ASSERT().
754 If Address is not aligned on a 16-bit boundary, then ASSERT().
755 If StartBit is greater than 15, then ASSERT().
756 If EndBit is greater than 15, then ASSERT().
757 If EndBit is less than StartBit, then ASSERT().
759 @param Address PCI configuration register to write.
760 @param StartBit The ordinal of the least significant bit in the bit field.
762 @param EndBit The ordinal of the most significant bit in the bit field.
764 @param OrData The value to OR with the PCI configuration register.
766 @return The value written back to the PCI configuration register.
780 BitFieldOr16 (PciRead16 (Address
), StartBit
, EndBit
, OrData
)
785 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
786 AND, and writes the result back to the bit field in the 16-bit register.
788 Reads the 16-bit PCI configuration register specified by Address, performs a
789 bitwise AND between the read result and the value specified by AndData, and
790 writes the result to the 16-bit PCI configuration register specified by
791 Address. The value written to the PCI configuration register is returned.
792 This function must guarantee that all PCI read and write operations are
793 serialized. Extra left bits in AndData are stripped.
795 If Address > 0x0FFFFFFF, then ASSERT().
796 If Address is not aligned on a 16-bit boundary, then ASSERT().
797 If StartBit is greater than 15, then ASSERT().
798 If EndBit is greater than 15, then ASSERT().
799 If EndBit is less than StartBit, then ASSERT().
801 @param Address PCI configuration register to write.
802 @param StartBit The ordinal of the least significant bit in the bit field.
804 @param EndBit The ordinal of the most significant bit in the bit field.
806 @param AndData The value to AND with the PCI configuration register.
808 @return The value written back to the PCI configuration register.
822 BitFieldAnd16 (PciRead16 (Address
), StartBit
, EndBit
, AndData
)
827 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
828 bitwise OR, and writes the result back to the bit field in the
831 Reads the 16-bit PCI configuration register specified by Address, performs a
832 bitwise AND followed by a bitwise OR between the read result and
833 the value specified by AndData, and writes the result to the 16-bit PCI
834 configuration register specified by Address. The value written to the PCI
835 configuration register is returned. This function must guarantee that all PCI
836 read and write operations are serialized. Extra left bits in both AndData and
839 If Address > 0x0FFFFFFF, then ASSERT().
840 If Address is not aligned on a 16-bit boundary, then ASSERT().
841 If StartBit is greater than 15, then ASSERT().
842 If EndBit is greater than 15, then ASSERT().
843 If EndBit is less than StartBit, then ASSERT().
845 @param Address PCI configuration register to write.
846 @param StartBit The ordinal of the least significant bit in the bit field.
848 @param EndBit The ordinal of the most significant bit in the bit field.
850 @param AndData The value to AND with the PCI configuration register.
851 @param OrData The value to OR with the result of the AND operation.
853 @return The value written back to the PCI configuration register.
858 PciBitFieldAndThenOr16 (
868 BitFieldAndThenOr16 (PciRead16 (Address
), StartBit
, EndBit
, AndData
, OrData
)
873 Reads a 32-bit PCI configuration register.
875 Reads and returns the 32-bit PCI configuration register specified by Address.
876 This function must guarantee that all PCI read and write operations are
879 If Address > 0x0FFFFFFF, then ASSERT().
880 If Address is not aligned on a 32-bit boundary, then ASSERT().
882 @param Address Address that encodes the PCI Bus, Device, Function and
885 @return The read value from the PCI configuration register.
894 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
896 return SmmPciLibPciRootBridgeIoReadWorker (Address
, EfiPciWidthUint32
);
900 Writes a 32-bit PCI configuration register.
902 Writes the 32-bit PCI configuration register specified by Address with the
903 value specified by Value. Value is returned. This function must guarantee
904 that all PCI read and write operations are serialized.
906 If Address > 0x0FFFFFFF, then ASSERT().
907 If Address is not aligned on a 32-bit boundary, then ASSERT().
909 @param Address Address that encodes the PCI Bus, Device, Function and
911 @param Value The value to write.
913 @return The value written to the PCI configuration register.
923 ASSERT_INVALID_PCI_ADDRESS (Address
, 3);
925 return SmmPciLibPciRootBridgeIoWriteWorker (Address
, EfiPciWidthUint32
, Value
);
929 Performs a bitwise OR of a 32-bit PCI configuration register with
932 Reads the 32-bit PCI configuration register specified by Address, performs a
933 bitwise OR between the read result and the value specified by
934 OrData, and writes the result to the 32-bit PCI configuration register
935 specified by Address. The value written to the PCI configuration register is
936 returned. This function must guarantee that all PCI read and write operations
939 If Address > 0x0FFFFFFF, then ASSERT().
940 If Address is not aligned on a 32-bit boundary, then ASSERT().
942 @param Address Address that encodes the PCI Bus, Device, Function and
944 @param OrData The value to OR with the PCI configuration register.
946 @return The value written back to the PCI configuration register.
956 return PciWrite32 (Address
, PciRead32 (Address
) | OrData
);
960 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
963 Reads the 32-bit PCI configuration register specified by Address, performs a
964 bitwise AND between the read result and the value specified by AndData, and
965 writes the result to the 32-bit PCI configuration register specified by
966 Address. The value written to the PCI configuration register is returned.
967 This function must guarantee that all PCI read and write operations are
970 If Address > 0x0FFFFFFF, then ASSERT().
971 If Address is not aligned on a 32-bit boundary, then ASSERT().
973 @param Address Address that encodes the PCI Bus, Device, Function and
975 @param AndData The value to AND with the PCI configuration register.
977 @return The value written back to the PCI configuration register.
987 return PciWrite32 (Address
, PciRead32 (Address
) & AndData
);
991 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
992 value, followed a bitwise OR with another 32-bit value.
994 Reads the 32-bit PCI configuration register specified by Address, performs a
995 bitwise AND between the read result and the value specified by AndData,
996 performs a bitwise OR between the result of the AND operation and
997 the value specified by OrData, and writes the result to the 32-bit PCI
998 configuration register specified by Address. The value written to the PCI
999 configuration register is returned. This function must guarantee that all PCI
1000 read and write operations are serialized.
1002 If Address > 0x0FFFFFFF, then ASSERT().
1003 If Address is not aligned on a 32-bit boundary, then ASSERT().
1005 @param Address Address that encodes the PCI Bus, Device, Function and
1007 @param AndData The value to AND with the PCI configuration register.
1008 @param OrData The value to OR with the result of the AND operation.
1010 @return The value written back to the PCI configuration register.
1021 return PciWrite32 (Address
, (PciRead32 (Address
) & AndData
) | OrData
);
1025 Reads a bit field of a PCI configuration register.
1027 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1028 specified by the StartBit and the EndBit. The value of the bit field is
1031 If Address > 0x0FFFFFFF, then ASSERT().
1032 If Address is not aligned on a 32-bit boundary, then ASSERT().
1033 If StartBit is greater than 31, then ASSERT().
1034 If EndBit is greater than 31, then ASSERT().
1035 If EndBit is less than StartBit, then ASSERT().
1037 @param Address PCI configuration register to read.
1038 @param StartBit The ordinal of the least significant bit in the bit field.
1040 @param EndBit The ordinal of the most significant bit in the bit field.
1043 @return The value of the bit field read from the PCI configuration register.
1054 return BitFieldRead32 (PciRead32 (Address
), StartBit
, EndBit
);
1058 Writes a bit field to a PCI configuration register.
1060 Writes Value to the bit field of the PCI configuration register. The bit
1061 field is specified by the StartBit and the EndBit. All other bits in the
1062 destination PCI configuration register are preserved. The new value of the
1063 32-bit register is returned.
1065 If Address > 0x0FFFFFFF, then ASSERT().
1066 If Address is not aligned on a 32-bit boundary, then ASSERT().
1067 If StartBit is greater than 31, then ASSERT().
1068 If EndBit is greater than 31, then ASSERT().
1069 If EndBit is less than StartBit, then ASSERT().
1071 @param Address PCI configuration register to write.
1072 @param StartBit The ordinal of the least significant bit in the bit field.
1074 @param EndBit The ordinal of the most significant bit in the bit field.
1076 @param Value New value of the bit field.
1078 @return The value written back to the PCI configuration register.
1083 PciBitFieldWrite32 (
1092 BitFieldWrite32 (PciRead32 (Address
), StartBit
, EndBit
, Value
)
1097 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1098 writes the result back to the bit field in the 32-bit port.
1100 Reads the 32-bit PCI configuration register specified by Address, performs a
1101 bitwise OR between the read result and the value specified by
1102 OrData, and writes the result to the 32-bit PCI configuration register
1103 specified by Address. The value written to the PCI configuration register is
1104 returned. This function must guarantee that all PCI read and write operations
1105 are serialized. Extra left bits in OrData are stripped.
1107 If Address > 0x0FFFFFFF, then ASSERT().
1108 If Address is not aligned on a 32-bit boundary, then ASSERT().
1109 If StartBit is greater than 31, then ASSERT().
1110 If EndBit is greater than 31, then ASSERT().
1111 If EndBit is less than StartBit, then ASSERT().
1113 @param Address PCI configuration register to write.
1114 @param StartBit The ordinal of the least significant bit in the bit field.
1116 @param EndBit The ordinal of the most significant bit in the bit field.
1118 @param OrData The value to OR with the PCI configuration register.
1120 @return The value written back to the PCI configuration register.
1134 BitFieldOr32 (PciRead32 (Address
), StartBit
, EndBit
, OrData
)
1139 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1140 AND, and writes the result back to the bit field in the 32-bit register.
1142 Reads the 32-bit PCI configuration register specified by Address, performs a
1143 bitwise AND between the read result and the value specified by AndData, and
1144 writes the result to the 32-bit PCI configuration register specified by
1145 Address. The value written to the PCI configuration register is returned.
1146 This function must guarantee that all PCI read and write operations are
1147 serialized. Extra left bits in AndData are stripped.
1149 If Address > 0x0FFFFFFF, then ASSERT().
1150 If Address is not aligned on a 32-bit boundary, then ASSERT().
1151 If StartBit is greater than 31, then ASSERT().
1152 If EndBit is greater than 31, then ASSERT().
1153 If EndBit is less than StartBit, then ASSERT().
1155 @param Address PCI configuration register to write.
1156 @param StartBit The ordinal of the least significant bit in the bit field.
1158 @param EndBit The ordinal of the most significant bit in the bit field.
1160 @param AndData The value to AND with the PCI configuration register.
1162 @return The value written back to the PCI configuration register.
1176 BitFieldAnd32 (PciRead32 (Address
), StartBit
, EndBit
, AndData
)
1181 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1182 bitwise OR, and writes the result back to the bit field in the
1185 Reads the 32-bit PCI configuration register specified by Address, performs a
1186 bitwise AND followed by a bitwise OR between the read result and
1187 the value specified by AndData, and writes the result to the 32-bit PCI
1188 configuration register specified by Address. The value written to the PCI
1189 configuration register is returned. This function must guarantee that all PCI
1190 read and write operations are serialized. Extra left bits in both AndData and
1191 OrData are stripped.
1193 If Address > 0x0FFFFFFF, then ASSERT().
1194 If Address is not aligned on a 32-bit boundary, then ASSERT().
1195 If StartBit is greater than 31, then ASSERT().
1196 If EndBit is greater than 31, then ASSERT().
1197 If EndBit is less than StartBit, then ASSERT().
1199 @param Address PCI configuration register to write.
1200 @param StartBit The ordinal of the least significant bit in the bit field.
1202 @param EndBit The ordinal of the most significant bit in the bit field.
1204 @param AndData The value to AND with the PCI configuration register.
1205 @param OrData The value to OR with the result of the AND operation.
1207 @return The value written back to the PCI configuration register.
1212 PciBitFieldAndThenOr32 (
1222 BitFieldAndThenOr32 (PciRead32 (Address
), StartBit
, EndBit
, AndData
, OrData
)
1227 Reads a range of PCI configuration registers into a caller supplied buffer.
1229 Reads the range of PCI configuration registers specified by StartAddress and
1230 Size into the buffer specified by Buffer. This function only allows the PCI
1231 configuration registers from a single PCI function to be read. Size is
1232 returned. When possible 32-bit PCI configuration read cycles are used to read
1233 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1234 and 16-bit PCI configuration read cycles may be used at the beginning and the
1237 If StartAddress > 0x0FFFFFFF, then ASSERT().
1238 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1239 If Size > 0 and Buffer is NULL, then ASSERT().
1241 @param StartAddress Starting address that encodes the PCI Bus, Device,
1242 Function and Register.
1243 @param Size Size in bytes of the transfer.
1244 @param Buffer Pointer to a buffer receiving the data read.
1252 IN UINTN StartAddress
,
1259 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1260 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1266 ASSERT (Buffer
!= NULL
);
1269 // Save Size for return
1273 if ((StartAddress
& BIT0
) != 0) {
1275 // Read a byte if StartAddress is byte aligned
1277 *(volatile UINT8
*)Buffer
= PciRead8 (StartAddress
);
1278 StartAddress
+= sizeof (UINT8
);
1279 Size
-= sizeof (UINT8
);
1280 Buffer
= (UINT8
*)Buffer
+ 1;
1283 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1285 // Read a word if StartAddress is word aligned
1287 WriteUnaligned16 (Buffer
, PciRead16 (StartAddress
));
1288 StartAddress
+= sizeof (UINT16
);
1289 Size
-= sizeof (UINT16
);
1290 Buffer
= (UINT16
*)Buffer
+ 1;
1293 while (Size
>= sizeof (UINT32
)) {
1295 // Read as many double words as possible
1297 WriteUnaligned32 (Buffer
, PciRead32 (StartAddress
));
1298 StartAddress
+= sizeof (UINT32
);
1299 Size
-= sizeof (UINT32
);
1300 Buffer
= (UINT32
*)Buffer
+ 1;
1303 if (Size
>= sizeof (UINT16
)) {
1305 // Read the last remaining word if exist
1307 WriteUnaligned16 (Buffer
, PciRead16 (StartAddress
));
1308 StartAddress
+= sizeof (UINT16
);
1309 Size
-= sizeof (UINT16
);
1310 Buffer
= (UINT16
*)Buffer
+ 1;
1313 if (Size
>= sizeof (UINT8
)) {
1315 // Read the last remaining byte if exist
1317 *(volatile UINT8
*)Buffer
= PciRead8 (StartAddress
);
1324 Copies the data in a caller supplied buffer to a specified range of PCI
1325 configuration space.
1327 Writes the range of PCI configuration registers specified by StartAddress and
1328 Size from the buffer specified by Buffer. This function only allows the PCI
1329 configuration registers from a single PCI function to be written. Size is
1330 returned. When possible 32-bit PCI configuration write cycles are used to
1331 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1332 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1333 and the end of the range.
1335 If StartAddress > 0x0FFFFFFF, then ASSERT().
1336 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
1337 If Size > 0 and Buffer is NULL, then ASSERT().
1339 @param StartAddress Starting address that encodes the PCI Bus, Device,
1340 Function and Register.
1341 @param Size Size in bytes of the transfer.
1342 @param Buffer Pointer to a buffer containing the data to write.
1344 @return Size written to StartAddress.
1350 IN UINTN StartAddress
,
1357 ASSERT_INVALID_PCI_ADDRESS (StartAddress
, 0);
1358 ASSERT (((StartAddress
& 0xFFF) + Size
) <= 0x1000);
1364 ASSERT (Buffer
!= NULL
);
1367 // Save Size for return
1371 if ((StartAddress
& BIT0
) != 0) {
1373 // Write a byte if StartAddress is byte aligned
1375 PciWrite8 (StartAddress
, *(UINT8
*)Buffer
);
1376 StartAddress
+= sizeof (UINT8
);
1377 Size
-= sizeof (UINT8
);
1378 Buffer
= (UINT8
*)Buffer
+ 1;
1381 if (Size
>= sizeof (UINT16
) && (StartAddress
& BIT1
) != 0) {
1383 // Write a word if StartAddress is word aligned
1385 PciWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1386 StartAddress
+= sizeof (UINT16
);
1387 Size
-= sizeof (UINT16
);
1388 Buffer
= (UINT16
*)Buffer
+ 1;
1391 while (Size
>= sizeof (UINT32
)) {
1393 // Write as many double words as possible
1395 PciWrite32 (StartAddress
, ReadUnaligned32 (Buffer
));
1396 StartAddress
+= sizeof (UINT32
);
1397 Size
-= sizeof (UINT32
);
1398 Buffer
= (UINT32
*)Buffer
+ 1;
1401 if (Size
>= sizeof (UINT16
)) {
1403 // Write the last remaining word if exist
1405 PciWrite16 (StartAddress
, ReadUnaligned16 (Buffer
));
1406 StartAddress
+= sizeof (UINT16
);
1407 Size
-= sizeof (UINT16
);
1408 Buffer
= (UINT16
*)Buffer
+ 1;
1411 if (Size
>= sizeof (UINT8
)) {
1413 // Write the last remaining byte if exist
1415 PciWrite8 (StartAddress
, *(UINT8
*)Buffer
);