summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/Library
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Chipset/LynxPoint/Library
downloadzprj-master.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/Library')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c2148
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf78
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak76
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl72
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl55
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak88
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl83
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c2201
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c295
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak112
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl93
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c831
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h29
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif8
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c54
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif9
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h25
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf63
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak74
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl59
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h25
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf64
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif9
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c225
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak69
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl73
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h49
37 files changed, 7285 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c
new file mode 100644
index 0000000..b9aab0a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c
@@ -0,0 +1,2148 @@
+/** @file
+ PCI Library using PC Express access.
+
+@copyright
+ Copyright (c) 2005 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "DxeRuntimePciLibPciExpress.h"
+
+/**
+ Assert the validity of a PCI address. A valid PCI address should contain 1's
+ only in the low 28 bits.
+
+ @param A The address to validate.
+**/
+#define ASSERT_INVALID_PCI_ADDRESS(A) ASSERT (((A) &~0xfffffff) == 0)
+
+/**
+ PCI Express base address
+**/
+STATIC UINTN mPciExpressBaseAddress;
+
+/**
+ Registered memory scope.
+**/
+typedef struct _REGISTERED_ADDRESS_MAP {
+ UINTN PciAddress;
+ UINTN Length;
+ UINTN RuntimeAddress;
+} REGISTERED_ADDRESS_MAP;
+
+#define PCI_LIB_ADDRESS_MAP_MAX_ITEM 64
+
+STATIC REGISTERED_ADDRESS_MAP mPciLibAddressMap[PCI_LIB_ADDRESS_MAP_MAX_ITEM];
+
+STATIC UINTN mPciLibAddressMapIndex = 0;
+
+/**
+ Virtual address notify event
+**/
+STATIC EFI_EVENT mVirtualNofityEvent;
+
+/**
+ Get the base address of PCI Express memory space.
+
+ @param[in] None
+
+ @retval VOID Return The base address of PCI Express.
+**/
+VOID *
+EFIAPI
+GetPciExpressBaseAddress (
+ VOID
+ )
+{
+ return (VOID *) (mPciExpressBaseAddress);
+}
+
+/**
+ Generate Pci Express address.
+ If Address > 0x0FFFFFFF or can't get the match Pci address, then ASSERT().
+
+ @param[in] Address Pci address.
+
+ @retval UINTN Pci Express address.
+**/
+static
+UINTN
+EFIAPI
+PreparePciExpressAddress (
+ IN UINTN Address
+ )
+{
+ UINTN Index;
+
+ ASSERT_INVALID_PCI_ADDRESS (Address);
+
+ if (EfiAtRuntime () == FALSE) {
+ return mPciExpressBaseAddress + Address;
+ }
+
+ for (Index = 0; Index < PCI_LIB_ADDRESS_MAP_MAX_ITEM; Index++) {
+ if ((Address >= mPciLibAddressMap[Index].PciAddress) &&
+ (Address < mPciLibAddressMap[Index].PciAddress + mPciLibAddressMap[Index].Length)
+ ) {
+ return mPciLibAddressMap[Index].RuntimeAddress + (Address - mPciLibAddressMap[Index].PciAddress);
+ }
+ }
+
+ ASSERT (FALSE);
+ EFI_DEADLOOP ();
+ return 0;
+}
+
+/**
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT8 return The read value from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressRead8 (
+ IN UINTN Address
+ )
+{
+ return MmioRead8 (PreparePciExpressAddress (Address));
+}
+
+/**
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Value The value to write
+
+ @retval UINT8 The value to write to the MMIO register.
+**/
+UINT8
+EFIAPI
+PciExpressWrite8 (
+ IN UINTN Address,
+ IN UINT8 Value
+ )
+{
+ return MmioWrite8 (PreparePciExpressAddress (Address), Value);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return MmioOr8 (PreparePciExpressAddress (Address), OrData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return MmioAnd8 (PreparePciExpressAddress (Address), AndData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return MmioAndThenOr8 (
+ PreparePciExpressAddress (Address),
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+
+ @retval UINT8 The value of the bit field read from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return MmioBitFieldRead8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit
+ );
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return MmioBitFieldWrite8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ Value
+ );
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return MmioBitFieldOr8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ OrData
+ );
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return MmioBitFieldAnd8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData
+ );
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return MmioBitFieldAndThenOr8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT16 The read value from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressRead16 (
+ IN UINTN Address
+ )
+{
+ return MmioRead16 (PreparePciExpressAddress (Address));
+}
+
+/**
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Value The value to write.
+
+ @retval UINT16 The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressWrite16 (
+ IN UINTN Address,
+ IN UINT16 Value
+ )
+{
+ return MmioWrite16 (PreparePciExpressAddress (Address), Value);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return MmioOr16 (PreparePciExpressAddress (Address), OrData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return MmioAnd16 (PreparePciExpressAddress (Address), AndData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return MmioAndThenOr16 (
+ PreparePciExpressAddress (Address),
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+
+ @retval UINT16 The value of the bit field read from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return MmioBitFieldRead16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit
+ );
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return MmioBitFieldWrite16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ Value
+ );
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return MmioBitFieldOr16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ OrData
+ );
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return MmioBitFieldAnd16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData
+ );
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return MmioBitFieldAndThenOr16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT32 The read value from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressRead32 (
+ IN UINTN Address
+ )
+{
+ return MmioRead32 (PreparePciExpressAddress (Address));
+}
+
+/**
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Value The value to write.
+
+ @retval UINT32 The value written to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ return MmioWrite32 (PreparePciExpressAddress (Address), Value);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return MmioOr32 (PreparePciExpressAddress (Address), OrData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return MmioAnd32 (PreparePciExpressAddress (Address), AndData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return MmioAndThenOr32 (
+ PreparePciExpressAddress (Address),
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+
+ @retval UNT32 The value of the bit field read from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return MmioBitFieldRead32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit
+ );
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return MmioBitFieldWrite32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ Value
+ );
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return MmioBitFieldOr32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ OrData
+ );
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return MmioBitFieldAnd32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData
+ );
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return MmioBitFieldAndThenOr32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer receiving the data read.
+
+ @retval UINTN Size in bytes of the transfer.
+**/
+UINTN
+EFIAPI
+PciExpressReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ UINTN ReturnValue;
+
+ ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+ if (Size == 0) {
+ return Size;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ //
+ // Save Size for return
+ //
+ ReturnValue = Size;
+
+ if ((StartAddress & 1) != 0) {
+ //
+ // Read a byte if StartAddress is byte aligned
+ //
+ *(volatile UINT8 *) Buffer = PciExpressRead8 (StartAddress);
+ StartAddress += sizeof (UINT8);
+ Size -= sizeof (UINT8);
+ Buffer = (UINT8 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
+ //
+ // Read a word if StartAddress is word aligned
+ //
+ *(volatile UINT16 *) Buffer = PciExpressRead16 (StartAddress);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ while (Size >= sizeof (UINT32)) {
+ //
+ // Read as many double words as possible
+ //
+ *(volatile UINT32 *) Buffer = PciExpressRead32 (StartAddress);
+ StartAddress += sizeof (UINT32);
+ Size -= sizeof (UINT32);
+ Buffer = (UINT32 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16)) {
+ //
+ // Read the last remaining word if exist
+ //
+ *(volatile UINT16 *) Buffer = PciExpressRead16 (StartAddress);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT8)) {
+ //
+ // Read the last remaining byte if exist
+ //
+ *(volatile UINT8 *) Buffer = PciExpressRead8 (StartAddress);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer containing the data to write.
+
+ @retval UINTN Size in bytes of the transfer.
+**/
+UINTN
+EFIAPI
+PciExpressWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ UINTN ReturnValue;
+
+ ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+ if (Size == 0) {
+ return 0;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ //
+ // Save Size for return
+ //
+ ReturnValue = Size;
+
+ if ((StartAddress & 1) != 0) {
+ //
+ // Write a byte if StartAddress is byte aligned
+ //
+ PciExpressWrite8 (StartAddress, *(UINT8 *) Buffer);
+ StartAddress += sizeof (UINT8);
+ Size -= sizeof (UINT8);
+ Buffer = (UINT8 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
+ //
+ // Write a word if StartAddress is word aligned
+ //
+ PciExpressWrite16 (StartAddress, *(UINT16 *) Buffer);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ while (Size >= sizeof (UINT32)) {
+ //
+ // Write as many double words as possible
+ //
+ PciExpressWrite32 (StartAddress, *(UINT32 *) Buffer);
+ StartAddress += sizeof (UINT32);
+ Size -= sizeof (UINT32);
+ Buffer = (UINT32 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16)) {
+ //
+ // Write the last remaining word if exist
+ //
+ PciExpressWrite16 (StartAddress, *(UINT16 *) Buffer);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT8)) {
+ //
+ // Write the last remaining byte if exist
+ //
+ PciExpressWrite8 (StartAddress, *(UINT8 *) Buffer);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT8 The read value from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciRead8 (
+ IN UINTN Address
+ )
+{
+ return PciExpressRead8 (Address);
+}
+
+/**
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Data The value to write.
+
+ @retval UINT8 The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciWrite8 (
+ IN UINTN Address,
+ IN UINT8 Data
+ )
+{
+ return PciExpressWrite8 (Address, Data);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressOr8 (Address, OrData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return PciExpressAnd8 (Address, AndData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressAndThenOr8 (Address, AndData, OrData);
+}
+
+/**
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+
+ @retval UINT8 The value of the bit field read from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return PciExpressBitFieldRead8 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT16 The read value from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciRead16 (
+ IN UINTN Address
+ )
+{
+ return PciExpressRead16 (Address);
+}
+
+/**
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Data The value to write.
+
+ @retval UINT16 The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciWrite16 (
+ IN UINTN Address,
+ IN UINT16 Data
+ )
+{
+ return PciExpressWrite16 (Address, Data);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressOr16 (Address, OrData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return PciExpressAnd16 (Address, AndData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressAndThenOr16 (Address, AndData, OrData);
+}
+
+/**
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+
+ @retval UINT16 The value of the bit field read from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return PciExpressBitFieldRead16 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT32 The read value from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciRead32 (
+ IN UINTN Address
+ )
+{
+ return PciExpressRead32 (Address);
+}
+
+/**
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Data The value to write.
+
+ @retval UINT32 The value written to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciWrite32 (
+ IN UINTN Address,
+ IN UINT32 Data
+ )
+{
+ return PciExpressWrite32 (Address, Data);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressOr32 (Address, OrData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return PciExpressAnd32 (Address, AndData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressAndThenOr32 (Address, AndData, OrData);
+}
+
+/**
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+
+ @retval UINT32 The value of the bit field read from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return PciExpressBitFieldRead32 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer receiving the data read.
+
+ @retval UINTN Size in bytes of the transfer.
+**/
+UINTN
+EFIAPI
+PciReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ return PciExpressReadBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer containing the data to write.
+
+ @retval UINTN The value written back to the PCI configuration register.
+**/
+UINTN
+EFIAPI
+PciWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ return PciExpressWriteBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Register memory space
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If SmPciLibAddressMapIndex) > PCI_LIB_ADDRESS_MAP_MAX_ITEM, then ASSERT().
+
+ @param[in] Address Starting address of the memory space
+ @param[in] Length Length of the memory space
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+PciLibRegisterMemory (
+ IN UINTN Address,
+ IN UINTN Length
+ )
+{
+ UINTN Index;
+
+ ASSERT_INVALID_PCI_ADDRESS (Address);
+ ASSERT (mPciLibAddressMapIndex < PCI_LIB_ADDRESS_MAP_MAX_ITEM);
+
+ //
+ // If already registered
+ //
+ for (Index = 0; Index < mPciLibAddressMapIndex; Index++) {
+ if (mPciLibAddressMap[Index].PciAddress == Address) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ mPciLibAddressMap[mPciLibAddressMapIndex].PciAddress = Address;
+ mPciLibAddressMap[mPciLibAddressMapIndex].Length = Length;
+ mPciLibAddressMap[mPciLibAddressMapIndex].RuntimeAddress = mPciExpressBaseAddress + Address;
+ mPciLibAddressMapIndex++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Virtual address nofity.
+ The event handler changes PCIE base address to an virtual address.
+ Starting address of registered memory scope is converted as well.
+
+ @param[in] Event The event that be siganlled when virtual address changed
+ @param[in] Context The pointer of the ESAL procedure instance
+
+ @retval None
+**/
+VOID
+EFIAPI
+VirtualAddressNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < PCI_LIB_ADDRESS_MAP_MAX_ITEM; Index++) {
+ if (mPciLibAddressMap[Index].PciAddress != 0) {
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mPciLibAddressMap[Index].RuntimeAddress));
+ }
+ }
+
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &mPciExpressBaseAddress);
+}
+
+/**
+ Constructor for Pci library. Register VirtualAddressNotifyEvent() notify function
+ It will ASSERT() if that operation fails
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+PciLibConstructor (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ mPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress);
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+ EFI_TPL_NOTIFY,
+ VirtualAddressNotifyEvent,
+ NULL,
+ &mVirtualNofityEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ZeroMem (mPciLibAddressMap, sizeof (mPciLibAddressMap));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif
new file mode 100644
index 0000000..179a995
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "DxeRuntimePciLibPciExpress"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\DxeRuntimePciLibPciExpress"
+ RefName = "DxeRuntimePciLibPciExpress"
+[files]
+"DxeRuntimePciLibPciExpress.sdl"
+"DxeRuntimePciLibPciExpress.mak"
+"DxeRuntimePciLibPciExpress.c"
+"DxeRuntimePciLibPciExpress.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf
new file mode 100644
index 0000000..20fec36
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf
@@ -0,0 +1,78 @@
+## @file
+# Component description file for the DxeRuntimePciLibPciExpress
+#
+#@copyright
+# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchDxeRuntimePciLibPciExpress
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ DxeRuntimePciLibPciExpress.c
+
+[sources.ia32]
+
+
+[sources.x64]
+
+
+[sources.ipf]
+
+
+[sources.ebc]
+
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+
+[libraries.common]
+ EdkIIGlueEdkDxeRuntimeDriverLib
+
+[libraries.ia32]
+
+
+[libraries.x64]
+
+
+[nmake.common]
+ LIB_STD_FLAGS = $(LIB_STD_FLAGS) /IGNORE:4006 /IGNORE:4221
+
+[nmake.ia32]
+ C_FLAGS = $(C_FLAGS) -DMDE_CPU_IA32
+
+[nmake.x64]
+ C_FLAGS = $(C_FLAGS) -DMDE_CPU_X64
+
+[nmake.ipf]
+ C_FLAGS = $(C_FLAGS) -DMDE_CPU_IPF
+
+[nmake.ebc]
+ EBC_C_STD_FLAGS = $(EBC_C_STD_FLAGS) -DEDKII_GLUE_LIBRARY_IMPLEMENTATION
+ EBC_LIB_STD_FLAGS = $(EBC_LIB_STD_FLAGS) /IGNORE:4006 /IGNORE:4221
+ EBC_C_STD_FLAGS = $(EBC_C_STD_FLAGS) -DMDE_CPU_EBC
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak
new file mode 100644
index 0000000..2a0bb30
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak
@@ -0,0 +1,76 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak 1 2/08/12 8:46a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:46a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak $
+#
+# 1 2/08/12 8:46a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+# MAK file for the ModulePart:DxeRuntimePciLibPciExpress
+EDK : DxeRuntimePciLibPciExpress
+
+DxeRuntimePciLibPciExpress : $(BUILD_DIR)\DxeRuntimePciLibPciExpress.mak DxeRuntimePciLibPciExpressBin
+
+$(BUILD_DIR)\DxeRuntimePciLibPciExpress.mak : $(DxeRuntimePciLibPciExpress_DIR)\$(@B).cif $(DxeRuntimePciLibPciExpress_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(DxeRuntimePciLibPciExpress_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+$(DxeRuntimePciLibPciExpressLib_LIB) : DxeRuntimePciLibPciExpress
+
+DxeRuntimePciLibPciExpress_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+DxeRuntimePciLibPciExpress_DEFINES = \
+$(CFLAGS) \
+$(DxeCpuBuildDefine) \
+
+DxeRuntimePciLibPciExpressBin:
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) \
+ /f $(BUILD_DIR)\DxeRuntimePciLibPciExpress.mak all \
+ "MY_INCLUDES=$(DxeRuntimePciLibPciExpress_INCLUDES)" \
+ "CFLAGS=$(DxeRuntimePciLibPciExpress_DEFINES)"\
+ TYPE=LIBRARY LIBRARIES= \
+ LIBRARY_NAME=$(DxeRuntimePciLibPciExpressLib_LIB)
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl
new file mode 100644
index 0000000..5c09ab6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl
@@ -0,0 +1,72 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl 1 2/08/12 8:46a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:46a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl $
+#
+# 1 2/08/12 8:46a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "DxeRuntimePciLibPciExpress_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable DxeRuntimePciLibPciExpress support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "DxeRuntimePciLibPciExpress_DIR"
+End
+
+MODULE
+ File = "DxeRuntimePciLibPciExpress.mak"
+ Help = "Includes DxeRuntimePciLibPciExpress.mak to Project"
+End
+
+ELINK
+ Name = "DxeRuntimePciLibPciExpressLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\DxeRuntimePciLibPciExpress_Lib.lib"
+ Parent = "DxeRuntimePciLibPciExpressLib_LIB"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif
new file mode 100644
index 0000000..2f066b4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\"
+ RefName = "PchLib"
+[files]
+"PchLib.sdl"
+[parts]
+"DxeRuntimePciLibPciExpress"
+"PchPciExpressHelpersLib"
+"PchPlatformLib"
+"PchSmbusLib"
+"RcFviDxeLib"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl
new file mode 100644
index 0000000..b73418a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl
@@ -0,0 +1,55 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchLib.sdl 1 2/08/12 8:46a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:46a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchLib.sdl $
+#
+# 1 2/08/12 8:46a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchLibrary_SUPPORT"
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchLibrary support in Project"
+End
+
+PATH
+ Name = "PchLibrary_DIR"
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif
new file mode 100644
index 0000000..bffca56
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PchPciExpressHelpersLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchPciExpressHelpersLib"
+ RefName = "PchPciExpressHelpersLib"
+[files]
+"PchPciExpressHelpersLib.sdl"
+"PchPciExpressHelpersLib.mak"
+"PchPciExpressHelpersLibrary.c"
+"PchPciExpressHelpersLibrary.h"
+"PchPciExpressHelpersLib.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf
new file mode 100644
index 0000000..aa731f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf
@@ -0,0 +1,66 @@
+## @file
+# Component description file for the PchPciExpressHelpersLib
+#
+#@copyright
+# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchPciExpressHelpersLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ PchPciExpressHelpersLibrary.c
+
+[sources.ia32]
+
+
+[sources.x64]
+
+
+[sources.ipf]
+
+
+[sources.ebc]
+
+
+[includes.common]
+ .
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ PchPlatformLib
+
+[libraries.ia32]
+
+
+[libraries.x64]
+
+
+[nmake.common] \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak
new file mode 100644
index 0000000..e8ce73e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak
@@ -0,0 +1,88 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak 2 10/16/12 4:57a Scottyang $
+#
+# $Revision: 2 $
+#
+# $Date: 10/16/12 4:57a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak $
+#
+# 2 10/16/12 4:57a Scottyang
+# [TAG] EIP84720
+# [Category] Improvement
+# [Description] Support Hot-Plug in Shark Bay
+# [Files] PchRootPort.c, PchPcie.asl, PchPciExpressHelpersLib.mak,
+# PchPciExpressHlpersLibrary.c, SB.sdl
+#
+# 1 2/08/12 8:47a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchPciExpressHelpersLib
+
+PchPciExpressHelpersLib : PchPciExpressHelpersDxeLib PchPciExpressHelpersPeiLib
+
+$(PchPciExpressHelpersDxeLib_LIB) : PchPciExpressHelpersDxeLib
+$(PchPciExpressHelpersPeiLib_LIB) : PchPciExpressHelpersPeiLib
+
+PchPciExpressHelpersDxeLib : $(BUILD_DIR)\PchPciExpressHelpersLib.mak PchPciExpressHelpersLibDxeBin
+PchPciExpressHelpersPeiLib : $(BUILD_DIR)\PchPciExpressHelpersLib.mak PchPciExpressHelpersLibPeiBin
+
+$(BUILD_DIR)\PchPciExpressHelpersLib.mak : $(PchPciExpressHelpersLib_DIR)\$(@B).cif $(PchPciExpressHelpersLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchPciExpressHelpersLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchPciExpressHelpersLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchPciExpressHelpersLib_DEFINES=\
+ $(CFLAGS)\
+
+PchPciExpressHelpersLibDxeBin:
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPciExpressHelpersLib.mak all \
+ "MY_INCLUDES=$(PchPciExpressHelpersLib_INCLUDES)" \
+ TYPE=LIBRARY LIBRARIES= \
+ LIBRARY_NAME=$(PchPciExpressHelpersDxeLib_LIB)
+
+PchPciExpressHelpersLibPeiBin:
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+!ENDIF
+ /f $(BUILD_DIR)\PchPciExpressHelpersLib.mak all \
+ "MY_INCLUDES=$(PchPciExpressHelpersLib_INCLUDES)" \
+ "MY_DEFINES=$(PchPciExpressHelpersLib_DEFINES)" \
+ LIBRARIES= \
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(PchPciExpressHelpersPeiLib_LIB)
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl
new file mode 100644
index 0000000..1bb4ebc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl
@@ -0,0 +1,83 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl 1 2/08/12 8:47a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:47a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl $
+#
+# 1 2/08/12 8:47a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchPciExpressHelpersLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchPciExpressHelpersLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchPciExpressHelpersLib_DIR"
+End
+
+MODULE
+ File = "PchPciExpressHelpersLib.mak"
+ Help = "Includes PchPciExpressHelpersLib.mak to Project"
+End
+
+ELINK
+ Name = "PchPciExpressHelpersDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPciExpressHelpersDxeLib_Lib.lib"
+ Parent = "PchPciExpressHelpersDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchPciExpressHelpersPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPciExpressHelpersPeiLib_Lib.lib"
+ Parent = "PchPciExpressHelpersPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
new file mode 100644
index 0000000..7d622b3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
@@ -0,0 +1,2201 @@
+/** @file
+ This file contains routines that support PCI Express initialization
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchPciExpressHelpersLibrary.h"
+// AMI_OVERRIDE, [EIP84720]>
+#include "Token.h"
+// AMI_OVERRIDE, [EIP84720]<
+
+/**
+ Find the Offset to a given Capabilities ID
+ CAPID list:
+ 0x01 = PCI Power Management Interface
+ 0x04 = Slot Identification
+ 0x05 = MSI Capability
+ 0x10 = PCI Express Capability
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] Function Pci Function Number
+ @param[in] CapId CAPID to search for
+
+ @retval 0 CAPID not found
+ @retval Other CAPID found, Offset of desired CAPID
+**/
+UINT8
+PcieFindCapId (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 CapId
+ )
+{
+ UINT8 CapHeaderOffset;
+ UINT8 CapHeaderId;
+ UINTN DeviceBase;
+
+ DeviceBase = MmPciAddress (0, Bus, Device, Function, 0);
+
+ ///
+ /// Check the header layout to determine the Offset of Capabilities Pointer Register
+ ///
+ if ((MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) {
+ ///
+ /// If CardBus bridge, start at Offset 0x14
+ ///
+ CapHeaderOffset = 0x14;
+ } else {
+ ///
+ /// Otherwise, start at Offset 0x34
+ ///
+ CapHeaderOffset = 0x34;
+ }
+ ///
+ /// Get Capability Header, A pointer value of 00h is used to indicate the last capability in the list.
+ ///
+ CapHeaderId = 0;
+ CapHeaderOffset = MmioRead8 (DeviceBase + CapHeaderOffset) & ((UINT8) ~(BIT0 | BIT1));
+ while (CapHeaderOffset != 0 && CapHeaderId != 0xFF) {
+ CapHeaderId = MmioRead8 (DeviceBase + CapHeaderOffset);
+ if (CapHeaderId == CapId) {
+ return CapHeaderOffset;
+ }
+ ///
+ /// Each capability must be DWORD aligned.
+ /// The bottom two bits of all pointers (including the initial pointer at 34h) are reserved
+ /// and must be implemented as 00b although software must mask them to allow for future uses of these bits.
+ ///
+ CapHeaderOffset = MmioRead8 (DeviceBase + CapHeaderOffset + 1) & ((UINT8) ~(BIT0 | BIT1));
+ }
+
+ return 0;
+}
+
+/**
+ Search and return the offset of desired Pci Express Capability ID
+ CAPID list:
+ 0x0001 = Advanced Error Rreporting Capability
+ 0x0002 = Virtual Channel Capability
+ 0x0003 = Device Serial Number Capability
+ 0x0004 = Power Budgeting Capability
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] Function Pci Function Number
+ @param[in] CapId Extended CAPID to search for
+
+ @retval 0 CAPID not found
+ @retval Other CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieFindExtendedCapId (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT16 CapId
+ )
+{
+ UINT16 CapHeaderOffset;
+ UINT16 CapHeaderId;
+ UINTN DeviceBase;
+
+ DeviceBase = MmPciAddress (0, Bus, Device, Function, 0);
+
+ ///
+ /// Start to search at Offset 0x100
+ /// Get Capability Header, A pointer value of 00h is used to indicate the last capability in the list.
+ ///
+ CapHeaderId = 0;
+ CapHeaderOffset = 0x100;
+ while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+ CapHeaderId = MmioRead16 (DeviceBase + CapHeaderOffset);
+ if (CapHeaderId == CapId) {
+ return CapHeaderOffset;
+ }
+ ///
+ /// Each capability must be DWORD aligned.
+ /// The bottom two bits of all pointers are reserved and must be implemented as 00b
+ /// although software must mask them to allow for future uses of these bits.
+ ///
+ CapHeaderOffset = (MmioRead16 (DeviceBase + CapHeaderOffset + 2) >> 4) & ((UINT16) ~(BIT0 | BIT1));
+ }
+
+ return 0;
+}
+
+/**
+ Map a TC to VC0 for port and endpoint
+
+ @param[in] Bus1 The bus number of the port
+ @param[in] Device1 The device number of the port
+ @param[in] Function1 The function number of the port
+ @param[in] Bus2 The bus number of the endpoint
+ @param[in] Device2 The device number of the endpoint
+ @param[in] TCx The TC number
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieMapTcxVc0 (
+ IN UINT8 Bus1,
+ IN UINT8 Device1,
+ IN UINT8 Function1,
+ IN UINT8 Bus2,
+ IN UINT8 Device2,
+ IN UINT8 TCx
+ )
+{
+ UINT16 Offset;
+ UINTN DeviceBase1;
+ UINTN DeviceBase2;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 Function2;
+
+ DeviceBase1 = MmPciAddress (0, Bus1, Device1, Function1, 0);
+
+ ///
+ /// Set TCx-VC0 value on the port
+ ///
+ Offset = PcieFindExtendedCapId (Bus1, Device1, Function1, 2);
+ if (Offset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MmioAndThenOr8 (DeviceBase1 + Offset + 0x014, (UINT8) (~0xF), 1);
+ MmioWrite8 (DeviceBase1 + Offset + 0x014, (UINT8) (1 << TCx));
+
+ ///
+ /// Set TCx-VC0 value on the Endpoint
+ ///
+ for (DeviceIndex = 0; DeviceIndex <= Device2; DeviceIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase2 + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase2 + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ Function2 = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ Function2 = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= Function2; FunctionIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, FunctionIndex, 0);
+
+ Offset = PcieFindExtendedCapId (Bus2, DeviceIndex, FunctionIndex, 2);
+ if (Offset == 0) {
+ continue;
+ }
+
+ MmioAndThenOr8 (DeviceBase2 + Offset + 0x014, (UINT8) (~0xF), 1);
+ MmioWrite8 (DeviceBase2 + Offset + 0x014, (UINT8) (1 << TCx));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set Common clock to Root port and Endpoint PCI device
+
+ @param[in] Bus1 Root port Pci Bus Number
+ @param[in] Device1 Root port Pci Device Number
+ @param[in] Function1 Root port Pci Function Number
+ @param[in] Bus2 Endpoint Pci Bus Number
+ @param[in] Device2 Endpoint Pci Device Number
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS VC mapping correctly initialized
+**/
+EFI_STATUS
+PcieSetCommonClock (
+ IN UINT8 Bus1,
+ IN UINT8 Device1,
+ IN UINT8 Function1,
+ IN UINT8 Bus2,
+ IN UINT8 Device2
+ )
+{
+ UINT8 CapOffset1;
+ UINT8 CapOffset2;
+ BOOLEAN CommonClockSupport;
+ EFI_STATUS Status;
+ UINTN DeviceBase1;
+ UINTN DeviceBase2;
+ UINT16 RegData16;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 Function2;
+
+ DeviceBase1 = MmPciAddress (0, Bus1, Device1, Function1, 0);
+
+ ///
+ /// Get the pointer to the Port PCI Express Capability Structure.
+ ///
+ CommonClockSupport = FALSE;
+ CapOffset1 = PcieFindCapId (Bus1, Device1, Function1, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (CapOffset1 == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Check the Port Slot Clock Configuration Bit.
+ ///
+ if ((MmioRead16 (DeviceBase1 + CapOffset1 + 0x012) & BIT12) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for (DeviceIndex = 0; DeviceIndex <= Device2; DeviceIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase2 + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase2 + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ Function2 = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ Function2 = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= Function2; FunctionIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, FunctionIndex, 0);
+ ///
+ /// Check the Endpoint Slot Clock Configuration Bit.
+ ///
+ CapOffset2 = PcieFindCapId (Bus2, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if ((CapOffset2 != 0) && ((MmioRead16 (DeviceBase2 + CapOffset2 + 0x012) & BIT12) != 0)) {
+ ///
+ /// Common clock is supported, set common clock bit on root port
+ /// and the endpoint
+ ///
+ if (CommonClockSupport == FALSE) {
+ MmioOr8 (DeviceBase1 + CapOffset1 + 0x010, BIT6);
+ CommonClockSupport = TRUE;
+ }
+
+ MmioOr8 (DeviceBase2 + CapOffset2 + 0x010, BIT6);
+ }
+ }
+ }
+ ///
+ /// If common clock not supported on root port and endpoint, return EFI_UNSUPPORTED
+ ///
+ if (CommonClockSupport == FALSE) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+ ///
+ /// Set Pci + D4h Bit 6 and Bit 12 to 1 for root port only
+ ///
+ if (Bus1 == 0) {
+ MmioOr32 (DeviceBase1 + 0xD4, ((UINT32)(BIT6 | BIT12)));
+ }
+ ///
+ /// Retrain the Link per PCI Express Specification.
+ ///
+ MmioOr8 (DeviceBase1 + CapOffset1 + 0x010, BIT5);
+
+// AMI_OVERRIDE >>>
+#ifdef PCIE_CLEAR_RETRAIN_BIT_SUPPORT_FLAG
+ PchPmTimerStall (1);
+
+ if((MmioRead8 (DeviceBase1 + CapOffset1 + 0x010) & BIT5) == 1){
+ MmioAnd8 (DeviceBase1 + CapOffset1 + 0x010, BIT5);
+ }
+#endif
+// AMI_OVERRIDE <<<
+
+ ///
+ /// Wait until Re-Training has completed.
+ ///
+ do {
+ RegData16 = MmioRead16 (DeviceBase1 + CapOffset1 + 0x012) & BIT11;
+ } while (RegData16 != 0);
+
+ return Status;
+}
+
+/**
+ This function enables the CLKREQ# PM on all the end point functions
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] RootFunction Rootport Function Number
+
+ @retval None
+**/
+VOID
+PcieSetClkreq (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 RootFunction
+ )
+{
+ UINT8 CapOffset;
+ UINTN DeviceBase;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 Function;
+ UINT32 Data32;
+ UINT16 GpioBase;
+ BOOLEAN ClkreqPerPortSupported;
+ PCH_SERIES PchSeries;
+ UINT8 RootPortNumber;
+ UINT32 RootComplexBar;
+
+
+ PchSeries = GetPchSeries();
+
+ if (PchSeries == PchLp) {
+ GpioBase = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE)
+ ) & B_PCH_LPC_GPIO_BASE_BAR;
+
+ RootComplexBar = PCH_RCRB_BASE;
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, RootFunction);
+ Data32 = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + RootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+
+ if (Data32 != 0) {
+ ///
+ /// CLKREQ not supported on root port
+ ///
+ return;
+ }
+ }
+
+ for (DeviceIndex = 0; DeviceIndex <= Device; DeviceIndex++) {
+ DeviceBase = MmPciAddress (0, Bus, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+
+ ClkreqPerPortSupported = TRUE;
+
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ Function = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ Function = 0;
+ }
+ ///
+ /// Parse thro all the functions of the endpoint and find the PCIe Cap ID (offset 10h) and if
+ /// exists then enable the CLKREQ# bit (BIT8) on that function
+ ///
+ for (FunctionIndex = 0; FunctionIndex <= Function; FunctionIndex++) {
+ ///
+ /// Find the PCIe Cap Id (offset 10h)
+ ///
+ CapOffset = PcieFindCapId (Bus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (CapOffset == 0) {
+ continue;
+ }
+
+ DeviceBase = MmPciAddress (0, Bus, DeviceIndex, FunctionIndex, 0);
+ ///
+ /// Check if CLKREQ# is supported by the endpoints
+ ///
+ if ((MmioRead32 (DeviceBase + CapOffset + 0x0C) & BIT18) == 0) {
+ ///
+ /// CLKREQ# is not supported so dont do anything
+ ///
+ ClkreqPerPortSupported = FALSE;
+ break;
+ }
+ }
+
+ if (ClkreqPerPortSupported == FALSE) {
+ continue;
+ }
+ ///
+ /// Now enable the CLKREQ#
+ ///
+ for (FunctionIndex = 0; FunctionIndex <= Function; FunctionIndex++) {
+ ///
+ /// Find the PCIe Cap Id (offset 10h)
+ ///
+ CapOffset = PcieFindCapId (Bus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (CapOffset == 0) {
+ continue;
+ }
+
+ DeviceBase = MmPciAddress (0, Bus, DeviceIndex, FunctionIndex, 0);
+ MmioOr16 (DeviceBase + CapOffset + 0x010, BIT8);
+ }
+ }
+}
+
+/**
+ This function get or set the Max Payload Size on all the end point functions
+
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] EndPointDevice The Device Number of the Endpoint
+ @param[in, out] MaxPayload The Max Payolad Size of the root port
+ @param[in] Operation True: Set the Max Payload Size on all the end point functions
+ False: Get the Max Payload Size on all the end point functions
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieMaxPayloadSize (
+ IN UINT8 EndPointBus,
+ IN UINT8 EndPointDevice,
+ IN OUT UINT16 *MaxPayload,
+ IN BOOLEAN Operation
+ )
+{
+ UINTN DeviceBase;
+ UINT8 PcieCapOffset;
+ UINT16 EndPointMaxPayload;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 EndPointFunction;
+
+ ///
+ /// Obtain the Max Payload Size for all the end point functions
+ ///
+ for (DeviceIndex = 0; DeviceIndex <= EndPointDevice; DeviceIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ EndPointFunction = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ EndPointFunction = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= EndPointFunction; FunctionIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, FunctionIndex, 0);
+ if (MmioRead16 (DeviceBase + 0x0) != 0xFFFF) {
+ ///
+ /// Get the pointer to the Endpoint PCI Express Capability Structure.
+ ///
+ PcieCapOffset = PcieFindCapId (EndPointBus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (PcieCapOffset == 0) {
+ continue;
+ }
+
+ if (Operation == TRUE) {
+ ///
+ /// Set the Max Payload Size of the end point function
+ ///
+ MmioAndThenOr16 (
+ DeviceBase + PcieCapOffset + 0x08,
+ (UINT16)~(BIT7 | BIT6 | BIT5),
+ *MaxPayload << 5
+ );
+ } else {
+ ///
+ /// Get the end point function Max Payload Size support
+ ///
+ EndPointMaxPayload = MmioRead16 (DeviceBase + PcieCapOffset + 0x04) & (BIT2 | BIT1 | BIT0);
+ ///
+ /// Obtain the minimum Max Payload Size between the PCIE root Port and the end point functions
+ ///
+ if (*MaxPayload > EndPointMaxPayload) {
+ *MaxPayload = EndPointMaxPayload;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function disable the forwarding of EOI messages unless it discovers
+ an IOAPIC behind this root port.
+
+ @param[in] RootBus The Bus Number of the root port
+ @param[in] RootDevice The Device Number of the root port
+ @param[in] RootFunction The Function Number of the root port
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] EndPointDevice The Device Number of the Endpoint
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieSetEoiFwdDisable (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ IN UINT8 EndPointBus,
+ IN UINT8 EndPointDevice
+ )
+{
+ BOOLEAN IoApicBehind;
+ UINTN RootDeviceBase;
+ UINTN DeviceBase;
+ UINT8 ProgInterface;
+ UINT8 SubClassCode;
+ UINT8 BaseClassCode;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 EndPointFunction;
+
+ IoApicBehind = FALSE;
+ RootDeviceBase = MmPciAddress (0, RootBus, RootDevice, RootFunction, 0);
+
+ ///
+ /// Check if an IOAPIC behind the root port
+ ///
+ for (DeviceIndex = 0; DeviceIndex <= EndPointDevice; DeviceIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ EndPointFunction = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ EndPointFunction = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= EndPointFunction; FunctionIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, FunctionIndex, 0);
+ BaseClassCode = MmioRead8 (DeviceBase + PCI_CLASSCODE_OFFSET + 2);
+ SubClassCode = MmioRead8 (DeviceBase + PCI_CLASSCODE_OFFSET + 1);
+ ProgInterface = MmioRead8 (DeviceBase + PCI_CLASSCODE_OFFSET);
+
+ if ((BaseClassCode == PCI_CLASS_SYSTEM_PERIPHERAL) &&
+ (SubClassCode == PCI_SUBCLASS_PIC) &&
+ ((ProgInterface == PCI_IF_APIC_CONTROLLER) ||
+ (ProgInterface == PCI_IF_APIC_CONTROLLER2))) {
+ IoApicBehind = TRUE;
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 20
+ /// If there is no IOAPIC behind the root port, set EOI Forwarding Disable bit (B0:D28:F0-F7:D4h[1]) to 1b.
+ ///
+ if (IoApicBehind == FALSE) {
+ #ifdef HOTPLUG_EOI_FLAG // AMI_OVERRIDE, [EIP84720]>
+ MmioOr8 (RootDeviceBase + 0xD4, (UINT8) (BIT1));
+ #else
+ //Supporting _RMV method in asl code, and reading hotplug capability register of root port
+ //if hotplug disable, then set EOI Forwarding Disable bit
+ #ifdef TBT_UP_PORT_FUNC_FLAG
+ if((TBT_UP_PORT_FUNC == RootFunction) || (!(MmioRead8 (DeviceBase + 0x54) & 0x40))){
+ #else
+ if(!(MmioRead8 (DeviceBase + 0x54) & 0x40)){
+ #endif
+ MmioOr8 (RootDeviceBase + 0xD4, (UINT8) (BIT1));
+ }
+ #endif // AMI_OVERRIDE, [EIP84720]<
+ }
+
+ return EFI_SUCCESS;
+}
+
+typedef enum {
+ CalculateAspm,
+ ManualAspm,
+ SetAspm
+} OPERATION;
+
+/**
+ This function compares the actual latency in LatencyValue1
+ with actual latency in LatencyValue2 and stores the minimum
+ back to LatencyValue1, in the required format.
+ If this is the first call, then LatencyValue1 will be replaced by LatencyValue2.
+
+ @param[in, out] LatencyValue1 - Current latency value
+ @param[in] LatencyValue2 - Latency value from the Table
+
+ @retval None
+**/
+VOID
+DetermineLatencyValue (
+ IN OUT UINT16 *LatencyValue1,
+ IN UINT16 *LatencyValue2
+ )
+{
+ ASSERT (LTR_SCALE_VALUE (*LatencyValue1) < 6);
+ ASSERT (LTR_SCALE_VALUE (*LatencyValue2) < 6);
+ ///
+ /// If there are more than one device behind a bridge that are part of the override table,
+ /// store the lower latency value and corresponding scale bits back to LatencyValue1
+ ///
+ if ((LTR_LATENCY_NS(*LatencyValue1) == 0) || (LTR_LATENCY_NS(*LatencyValue1) > LTR_LATENCY_NS(*LatencyValue2))) {
+ *LatencyValue1 = *LatencyValue2;
+ }
+}
+
+/**
+ Calculate/Set EndPoint device Power management settings
+
+ @param[in] RootDeviceBase The Root Port PCI Express address
+ @param[in] RootPcieCapOffset The pointer to the Root Port PCI Express Capability Structure
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] NumOfDevAspmOverride Number of Device specific ASPM policy override items
+ @param[in] DevAspmOverride Pointer to array of Device specific ASPM policy override items
+ @param[in, out] LinkAspmVal Resulting Link ASPM value programmed
+ @param[in] Operation Operation Types
+ @param[in] NumOfDevLtrOverride Number of Device specific LTR override items
+ @param[in] DevLtrOverride Pointer to array of Device specific LTR policy override items
+ @param[in, out] LtrOverrideVal Resulting LTR override value to be programmed
+ @param[in] RootL1SubstateExtCapOffset The register offset of Root Port L1 Substates
+ @param[in, out] L1SubstatesSupported Input and return the result of L1 Substates support
+ @param[in] L1SubstatesConfig L1 Substates configurations
+ @param[in, out] PortCommonModeRestoreTime Input and return common mode restore time of L1 Substate setting
+ @param[in, out] PortTpowerOnValue Input and return power on value of L1 Substate setting
+ @param[in, out] PortTpowerOnScale Input and return power on scale of L1 Substate setting
+ @param[in] PchPwrOptPcie Pcie Power Optimizer Configuration
+ @param[in, out] AspmOverride Input and return the Aspm Override enable for pre-1.1 devices
+ @param[in, out] ClkreqPerPortSupported Input to check if clkreq per port is supportted
+ @param[in, out] RpAndEndPointsLtrSupported Return to check if all endpoints support LTR
+ @param[in] PolicyRevision Policy revision for codes compatibility
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device
+ @retval EFI_OUT_OF_RESOURCES The endpoint device is a bridge, but the Subordinate Bus Number of
+ the root port is not greater than its Secondary Bus Number. You may
+ get this error if PCI emulation is not done before this function gets
+ called and the platform policy settings of "TempRootPortBusNumMax" and
+ "TempRootPortBusNumMin" do not provide enough resource for temp bus
+ number usage.
+**/
+EFI_STATUS
+PcieEndPointPm (
+ IN UINTN RootDeviceBase,
+ IN UINT32 RootPcieCapOffset,
+ IN UINT8 EndPointBus,
+ IN UINT8 NumOfDevAspmOverride,
+ IN PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride,
+ IN OUT UINT16 *LinkAspmVal,
+ IN OPERATION Operation,
+ IN UINT8 NumOfDevLtrOverride,
+ IN PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride,
+ IN OUT UINT32 *LtrOverrideVal,
+ IN UINT16 RootL1SubstateExtCapOffset,
+ IN OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN OUT UINT32 *PortCommonModeRestoreTime,
+ IN OUT UINT32 *PortTpowerOnValue,
+ IN OUT UINT32 *PortTpowerOnScale,
+ IN PCH_PCIE_PWR_OPT *PchPwrOptPcie,
+ IN OUT BOOLEAN *AspmOverride,
+ IN BOOLEAN *ClkreqPerPortSupported,
+ IN OUT BOOLEAN *RpAndEndPointsLtrSupported,
+ IN UINT8 PolicyRevision
+ )
+{
+ EFI_STATUS Status;
+ UINTN EndPointBase;
+ UINT8 EndPointFunction;
+ UINT8 EndPointPcieCapOffset;
+ UINT8 PcieDeviceIndex;
+ UINT16 EndPointAspm;
+ UINT16 EndPointVendorId;
+ UINT16 EndPointDeviceId;
+ UINT8 EndPointRevId;
+ UINT8 EndPointBaseClassCode;
+ UINT8 EndPointSubClassCode;
+ UINT32 PortLxLat;
+ UINT32 EndPointLxLat;
+ UINT32 LxLat;
+ UINT8 DownStreamBusMin;
+ UINT8 ClassCode;
+ UINT8 RootDevSubBusNum;
+ BOOLEAN BusAssign;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT16 LtrExtendedCapOffset;
+ UINT32 DeviceCapabilities2;
+ UINT16 DefaultMaxLatency;
+ UINT16 Data16;
+ UINT32 Data32;
+ UINT16 EndPointL1SubStateCapOffset;
+ UINT32 RootDeviceL1Substates;
+ UINT32 EndPointL1Substates;
+ UINT8 EndPointPortCommonModeRestoreTime;
+ UINT8 EndPointTpowerOnScale;
+ UINT8 EndPointTpowerOnValue;
+ UINT32 Multiplier[4] = {2, 10, 100, 0};
+ UINT32 EndPointL1SubstCapMask;
+ PCH_SERIES PchSeries;
+
+ DefaultMaxLatency = 0;
+ PchSeries = GetPchSeries();
+ for (DeviceIndex = 0; DeviceIndex <= PCI_MAX_DEVICE; DeviceIndex++) {
+ EndPointBase = MmPciAddress (0, EndPointBus, DeviceIndex, 0, 0);
+ if (MmioRead16 (EndPointBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (EndPointBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ EndPointFunction = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ EndPointFunction = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= EndPointFunction; FunctionIndex++) {
+ ///
+ /// Get the pointer to the Endpoint PCI Express Capability Structure.
+ ///
+ EndPointPcieCapOffset = PcieFindCapId (EndPointBus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+
+ if (EndPointPcieCapOffset == 0) {
+ if (FunctionIndex < EndPointFunction) {
+ continue;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ EndPointBase = MmPciAddress (0, EndPointBus, DeviceIndex, FunctionIndex, 0);
+ EndPointVendorId = MmioRead16 (EndPointBase + R_PCH_PCIE_VENDOR_ID);
+ EndPointDeviceId = MmioRead16 (EndPointBase + R_PCH_PCIE_DEVICE_ID);
+ EndPointRevId = MmioRead8 (EndPointBase + R_PCH_PCIE_RID);
+ EndPointL1SubStateCapOffset = 0;
+ RootDeviceL1Substates = 0;
+ EndPointL1Substates = 0;
+ EndPointL1SubstCapMask = 0x0000001F;
+ if (PchSeries == PchLp) {
+ ///
+ /// Get the endpoint supports L1 Substates Capabilities
+ ///
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevAspmOverride; PcieDeviceIndex++) {
+ if ((PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) &&
+ ((DevAspmOverride[PcieDeviceIndex].OverrideConfig & PchPcieL1SubstatesOverride) == PchPcieL1SubstatesOverride) &&
+ (EndPointVendorId == DevAspmOverride[PcieDeviceIndex].VendorId) &&
+ (EndPointDeviceId == DevAspmOverride[PcieDeviceIndex].DeviceId) &&
+ ((EndPointRevId == DevAspmOverride[PcieDeviceIndex].RevId) ||
+ (DevAspmOverride[PcieDeviceIndex].RevId == 0xFF))) {
+ if ((EndPointVendorId == 0x8086) &&
+ ((EndPointDeviceId == 0x08B1) || (EndPointDeviceId == 0x08B2) ||
+ (EndPointDeviceId == 0x08B3) || (EndPointDeviceId == 0x08B4))) {
+ if ((MmioRead32 (EndPointBase + DevAspmOverride[PcieDeviceIndex].L1SubstatesCapOffset) & 0xFFFF) == 0xCAFE) {
+ EndPointL1SubStateCapOffset = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapOffset;
+ EndPointL1SubstCapMask = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapMask;
+ }
+ } else {
+ EndPointL1SubStateCapOffset = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapOffset;
+ EndPointL1SubstCapMask = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapMask;
+ }
+ }
+ }
+ if (EndPointL1SubStateCapOffset == 0) {
+ EndPointL1SubStateCapOffset = PcieFindExtendedCapId (
+ EndPointBus,
+ DeviceIndex,
+ FunctionIndex,
+ 0x1E);
+ }
+ if (EndPointL1SubStateCapOffset != 0) {
+ RootDeviceL1Substates = MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04);
+ EndPointL1Substates = MmioRead32 (EndPointBase + EndPointL1SubStateCapOffset + 0x04);
+ }
+ }
+ DeviceCapabilities2 = MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x24);
+ if (((DeviceCapabilities2 & BIT11) == 0) || (PchPwrOptPcie->LtrEnable != TRUE)) {
+ *RpAndEndPointsLtrSupported = FALSE;
+ }
+ ///
+ /// Configure downstream device if present.
+ ///
+
+ if (Operation == CalculateAspm || Operation == ManualAspm) {
+ if ((MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x00C) & BIT18) != BIT18) {
+ *ClkreqPerPortSupported = FALSE;
+ }
+ EndPointAspm = (MmioRead16 (EndPointBase + EndPointPcieCapOffset + 0x00C) >> 10) & 3;
+ DEBUG ((EFI_D_INFO, "Endpoint Device %0x Capability ASPM: %0x\n", DeviceIndex, EndPointAspm));
+ if (Operation == CalculateAspm) {
+ ///
+ /// Check endpoint for pre-1.1 devices based on the Role based Error Reporting Capability bit
+ /// and enable Aspm Override
+ ///
+ if (!(MmioRead16 (EndPointBase + EndPointPcieCapOffset + 0x4) & BIT15)) {
+ DEBUG ((EFI_D_INFO, "Override root port ASPM to L1 for pre-1.1 devices\n"));
+ *AspmOverride = TRUE;
+ }
+ ///
+ /// Mask APMC with values from lookup table.
+ /// RevID of 0xFF applies to all steppings.
+ ///
+ EndPointBaseClassCode = MmioRead8 (EndPointBase + R_PCH_PCIE_BCC);
+ EndPointSubClassCode = MmioRead8 (EndPointBase + R_PCH_PCIE_SCC);
+
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevAspmOverride; PcieDeviceIndex++) {
+ if ((PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) &&
+ ((DevAspmOverride[PcieDeviceIndex].OverrideConfig & PchPcieL1L2Override) == PchPcieL1L2Override) &&
+ ((DevAspmOverride[PcieDeviceIndex].VendorId == EndPointVendorId) ||
+ (DevAspmOverride[PcieDeviceIndex].VendorId == 0xFFFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].DeviceId == EndPointDeviceId) ||
+ (DevAspmOverride[PcieDeviceIndex].DeviceId == 0xFFFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].RevId == EndPointRevId) ||
+ (DevAspmOverride[PcieDeviceIndex].RevId == 0xFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].BaseClassCode == EndPointBaseClassCode) ||
+ (DevAspmOverride[PcieDeviceIndex].BaseClassCode == 0xFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].SubClassCode == EndPointSubClassCode) ||
+ (DevAspmOverride[PcieDeviceIndex].SubClassCode == 0xFF))) {
+ ///
+ /// Override value of 0xFF applies to all.
+ ///
+ EndPointAspm = DevAspmOverride[PcieDeviceIndex].EndPointAspm;
+ break;
+ }
+ }
+ ///
+ /// Check if L1 should be enabled based on port and endpoint L1 exit latency.
+ ///
+ if (EndPointAspm & BIT1) {
+ PortLxLat = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x00C) & (BIT17 + BIT16 + BIT15);
+ EndPointLxLat = MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x00C) & (BIT17 + BIT16 + BIT15);
+
+ LxLat = PortLxLat;
+ if (PortLxLat < EndPointLxLat) {
+ LxLat = EndPointLxLat;
+ }
+ ///
+ /// check if the value is bigger than endpoint L1 acceptable exit latency, if it is
+ /// larger than accepted value, then we should disable L1
+ ///
+ LxLat >>= 6;
+ if (LxLat > (MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x004) & (BIT11 + BIT10 + BIT9))) {
+ EndPointAspm &= ~BIT1;
+ }
+ }
+ ///
+ /// Check if L0s should be enabled based on port and endpoint L0s exit latency.
+ ///
+ if (EndPointAspm & BIT0) {
+ PortLxLat = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x00C) & (BIT14 + BIT13 + BIT12);
+ EndPointLxLat = MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x00C) & (BIT14 + BIT13 + BIT12);
+
+ LxLat = PortLxLat;
+ if (PortLxLat < EndPointLxLat) {
+ LxLat = EndPointLxLat;
+ }
+ ///
+ /// check if the value is bigger than endpoint L0s acceptable exit latency, if it is
+ /// larger than accepted value, then we should disable L0s
+ ///
+ LxLat >>= 6;
+ if (LxLat > (MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x004) & (BIT8 + BIT7 + BIT6))) {
+ EndPointAspm &= ~BIT0;
+ }
+ }
+ }
+
+ *LinkAspmVal &= EndPointAspm;
+ DEBUG ((EFI_D_INFO, "Calculate Endpoint Device %0x Aspm Value: %0x\n", DeviceIndex, EndPointAspm));
+ if (PchSeries == PchLp) {
+ ///
+ /// Check if the endpoint supports L1 Substates Capabilities
+ ///
+ if ((EndPointL1SubStateCapOffset != 0) && (RootL1SubstateExtCapOffset != 0)) {
+ ///
+ /// If both Root and endpoint's L1 Sub-States Extended Capability Offset + 0x04[4:0] are 11111b,
+ /// a. Read L1 Sub-States Extended Capability Offset + 0x04[15:8], and program the highest value advertised
+ /// between PCIe rootport and device to L1 Sub-States Extended Capability Offset + 0x08[15:8] on
+ /// Pcie root port.
+ /// b. Read L1 Sub-States Extended Capability Offset + 0x04[23:19] and [17:16], and program the highest value
+ /// advertised between PCIe root port and device.to L1 Sub-States Extended Capability Offset + 0x08 [7:0] on
+ /// both Pcie root port and device.
+ /// c. Program L1 Sub-States Extended Capability Offset + 0x08[31:29] to 010b for both Pcie root port and device
+ /// d. Program L1 Sub-States Extended Capability Offset + 0x08[25:16] to 0010100000b for both Pcie root port and device
+ /// e. Program L1 Sub-States Extended Capability Offset + 0x08[4:0] to 01111b for both Pcie root port and device
+ ///
+ if (((RootDeviceL1Substates & 0x1F) == 0x1F) &&
+ ((EndPointL1Substates & EndPointL1SubstCapMask) == EndPointL1SubstCapMask) &&
+ (L1SubstatesConfig != PchPcieL1SubstatesDisabled)) {
+ *L1SubstatesSupported = TRUE;
+ EndPointPortCommonModeRestoreTime = (EndPointL1Substates >> 8) & 0xFF;
+ EndPointTpowerOnScale = (EndPointL1Substates >> 16) & 0x3;
+ EndPointTpowerOnValue = (EndPointL1Substates >> 19) & 0x1F;
+
+ if (EndPointPortCommonModeRestoreTime > *PortCommonModeRestoreTime) {
+ *PortCommonModeRestoreTime = EndPointPortCommonModeRestoreTime;
+ }
+
+ if ((EndPointTpowerOnValue * Multiplier[EndPointTpowerOnScale]) >
+ (*PortTpowerOnValue * Multiplier[*PortTpowerOnScale])) {
+ *PortTpowerOnValue = EndPointTpowerOnValue;
+ *PortTpowerOnScale = EndPointTpowerOnScale;
+ }
+ }
+ }
+ }
+ ///
+ /// For each device detected, scan the LTR override table
+ /// If there are endpoints connected directly to the rootport then
+ /// LtrOverrideVal will be replaced by the value from the table for that endpoint
+ /// If there are endpoints that are behind a bridge and that are also part of the table then
+ /// LtrOverrideVal will maintain the minimum of all such values.
+ /// A non zero value of LtrOverrideVal will indicate:
+ /// i):That there is atleast one entry in the LTR override Table
+ /// ii):The final value to be programmed in offset 0x400. This value will be applied for all the devices
+ /// connected to this root port
+ ///
+ Data32 = *LtrOverrideVal;
+ if (DevLtrOverride != NULL) {
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevLtrOverride; PcieDeviceIndex++) {
+ if ((DevLtrOverride[PcieDeviceIndex].VendorId == EndPointVendorId) &&
+ ((DevLtrOverride[PcieDeviceIndex].DeviceId == EndPointDeviceId) ||
+ (DevLtrOverride[PcieDeviceIndex].DeviceId == 0xFFFF)) &&
+ ((DevLtrOverride[PcieDeviceIndex].RevId == EndPointRevId) ||
+ (DevLtrOverride[PcieDeviceIndex].RevId == 0xFF))) {
+
+ ///
+ /// Get the Non-Snoop latency value from the table, compare and store the minimum
+ ///
+ if (DevLtrOverride[PcieDeviceIndex].NonSnoopLatency & BIT15) {
+ Data16 = (UINT16)((Data32 & 0xFFFF0000) >> 16);
+ DetermineLatencyValue(&Data16, &DevLtrOverride[PcieDeviceIndex].NonSnoopLatency);
+ Data32 = (Data32 & 0xFFFF) | ((UINT32)(Data16 << 16));
+ }
+
+ ///
+ /// Get the Snoop latency value from the table, compare and store the minimum
+ ///
+ if (DevLtrOverride[PcieDeviceIndex].SnoopLatency & BIT15) {
+ Data16 = (UINT16)(Data32 & 0xFFFF);
+ DetermineLatencyValue(&Data16, &DevLtrOverride[PcieDeviceIndex].SnoopLatency);
+ Data32 = (Data32 & 0xFFFF0000) | (UINT32)Data16;
+ }
+ *LtrOverrideVal = Data32;
+ break;
+ }
+ }
+ }
+ } else if (Operation == SetAspm) {
+ if (PchSeries == PchLp) {
+ if ((EndPointL1SubStateCapOffset != 0) && (*L1SubstatesSupported)) {
+ if (((RootDeviceL1Substates & 0x1F) == 0x1F) &&
+ ((EndPointL1Substates & EndPointL1SubstCapMask) == EndPointL1SubstCapMask)) {
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x0C,
+ (UINT32) ~(0xF8),
+ (*PortTpowerOnValue << 3)
+ );
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x0C,
+ (UINT32) ~(0x03),
+ *PortTpowerOnScale);
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x08,
+ (UINT32) ~(0xE3FF0000),
+ (UINT32) (BIT30 | BIT23 | BIT21)
+ );
+ Data32 = (BIT3 | BIT2 | BIT1 | BIT0);
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_1) {
+ Data32 &= (UINT32)~(BIT0);
+ }
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_2) {
+ Data32 &= (UINT32)~(BIT1);
+ }
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x08,
+ (UINT32) ~(0x1F),
+ Data32
+ );
+ }
+ }
+ }
+ ///
+ /// Write it to the Link Control register
+ ///
+ DEBUG ((EFI_D_INFO, "Program Endpoint Device %0x Aspm Value: %0x\n", DeviceIndex, *LinkAspmVal));
+ MmioAndThenOr16 (EndPointBase + EndPointPcieCapOffset + 0x10, 0xFFFC, *LinkAspmVal);
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 8.14.1 Power Optimizer Configuration
+ /// Step 3
+ /// For PCIe Endpoint,
+ /// If Endpoint device supported LTR, Device Capabilities 2 Register Offset 24h [11] = 1b,
+ ///
+ if ((DeviceCapabilities2 & BIT11) && (PchPwrOptPcie->LtrEnable == TRUE)) {
+ ///
+ /// Step 3.1
+ /// Program Endpoint LTR Mechanism Enable, Device Control 2 Register Offset 28h [10] = 1b
+ /// when device supports LTR but is not found in override table (table listing correct
+ /// latency requirements for devices that supports LTR and also for devices that do not
+ /// support LTR)
+ ///
+ if (DevLtrOverride != NULL) {
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevLtrOverride; PcieDeviceIndex++) {
+ if ((DevLtrOverride[PcieDeviceIndex].VendorId != EndPointVendorId) ||
+ ((DevLtrOverride[PcieDeviceIndex].DeviceId != EndPointDeviceId) &&
+ (DevLtrOverride[PcieDeviceIndex].DeviceId != 0xFFFF)) ||
+ ((DevLtrOverride[PcieDeviceIndex].RevId != EndPointRevId) &&
+ (DevLtrOverride[PcieDeviceIndex].RevId != 0xFF))) {
+ MmioOr16 (EndPointBase + EndPointPcieCapOffset + 0x28, BIT10);
+ break;
+ }
+ }
+ } else {
+ MmioOr16 (EndPointBase + EndPointPcieCapOffset + 0x28, BIT10);
+ }
+ }
+ ///
+ /// Get the pointer to the Endpoint PCI Express Extended Capability Structure
+ /// and configure the Max Snoop and Max No-Snoop Latency for the endpoint
+ ///
+ LtrExtendedCapOffset = PcieFindExtendedCapId (EndPointBus, DeviceIndex, FunctionIndex, 0x18);
+ if (LtrExtendedCapOffset != 0) {
+ Data32 = *LtrOverrideVal;
+ if (PchSeries == PchH) {
+ DefaultMaxLatency = 0x0846;
+ }
+ if (PchSeries == PchLp) {
+ DefaultMaxLatency = 0x1003;
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 8.14.1 Power Optimizer Configuration
+ /// Step 3.2
+ /// Program Endpoint Max Snoop Latency Register, Latency Tolerance Reporting(LTR)
+ /// Capability Offset 04h [15:0] with Intel recommended default value for max snoop
+ /// latency if there is no snoop latency override value getting programmed in the
+ /// override register else program the endpoint Max Snoop Latency Register with the
+ /// minimum of snoop latency override value for that root port and Intel recommended
+ /// default value for max snoop latency
+ /// Intel recommended default value for max snoop latency for LPT-H = 0x0846
+ /// Intel recommended default value for max snoop latency for LPT-LP = 0x1003
+ ///
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ DefaultMaxLatency = PchPwrOptPcie->LtrMaxSnoopLatency;
+ }
+
+ Data16 = (UINT16)(Data32 & 0xFFFF);
+ ///
+ /// Set the max snoop latency to either the default max snoop latency or to the snoop latency override value
+ /// that is being programmed for this root port
+ ///
+ DetermineLatencyValue(&Data16, &DefaultMaxLatency);
+ MmioAndThenOr16 (
+ EndPointBase + LtrExtendedCapOffset + 4,
+ (UINT16) (~0x1FFF),
+ Data16
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 8.14.1 Power Optimizer Configuration
+ /// Step 3.3
+ /// Program Endpoint Max No-Snoop Latency Register, Latency Tolerance Reporting(LTR)
+ /// Capability Offset 06h [15:0] with Intel recommended default value for max no-snoop
+ /// latency if there is no No-snoop latency override value getting programmed in the
+ /// override register else program the endpoint Max No-Snoop Latency Register with the
+ /// minimum of No-snoop latency override value for that root port and Intel recommended
+ /// default value for max no-snoop latency
+ /// Intel recommended default value for max no-snoop latency for LPT-H = 0x0846
+ /// Intel recommended default value for max no-snoop latency for LPT-LP = 0x1003
+ ///
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ DefaultMaxLatency = PchPwrOptPcie->LtrMaxNoSnoopLatency;
+ }
+ Data16 = (UINT16)((Data32 & 0xFFFF0000) >> 16);
+ DetermineLatencyValue(&Data16, &DefaultMaxLatency);
+ MmioAndThenOr16 (
+ EndPointBase + LtrExtendedCapOffset + 6,
+ (UINT16) (~0x1FFF),
+ Data16
+ );
+ }
+ ///
+ /// Step 4
+ /// For PCIe Endpoint,
+ /// If Endpoint device supported OBFF, Device Capabilities 2 Register Offset 24h [19:18] = 2h,
+ ///
+ if ((DeviceCapabilities2 & BIT19) && (PchPwrOptPcie->ObffEnable == PCH_DEVICE_ENABLE)) {
+ ///
+ /// Step 4.1
+ /// Program Endpoint OBFF Mechanism Enable, Device Control 2 Register Offset 28h [14:13] = 3h
+ ///
+ MmioOr16 (EndPointBase + EndPointPcieCapOffset + 0x28, (BIT14 + BIT13));
+ }
+ }
+ ///
+ /// Check if this device is a bridge
+ ///
+ ClassCode = MmioRead8 (EndPointBase + R_PCH_PCIE_BCC);
+
+ if (ClassCode == PCI_CLASS_BRIDGE) {
+ ///
+ /// Get the downstream Bus number
+ ///
+ DownStreamBusMin = (UINT8) (MmioRead32 (EndPointBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 8);
+ ///
+ /// If the Secondary Bus Number of endpoint device is not assigned
+ ///
+ if (DownStreamBusMin == 0) {
+ RootDevSubBusNum = (UINT8) (MmioRead32 (RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 16);
+ ///
+ /// If the endpoint device is a bridge, the Subordinate Bus Number of the root port will need to be greater
+ /// than the Secondary Bus Number of the root port (the Bus Number of endpoint device).
+ ///
+ if (RootDevSubBusNum > EndPointBus) {
+ ///
+ /// Assign the Primary, Secondary and Subordinate Bus Number to endpoint device
+ ///
+ MmioAndThenOr32 (
+ EndPointBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF000000,
+ EndPointBus | (((UINT32) (EndPointBus + 1) << 8)) | ((UINT32) (RootDevSubBusNum << 16))
+ );
+ DownStreamBusMin = EndPointBus + 1;
+ } else {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BusAssign = FALSE;
+ } else {
+ BusAssign = TRUE;
+ }
+
+ if (DownStreamBusMin > EndPointBus) {
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ DownStreamBusMin,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ LinkAspmVal,
+ Operation,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ LtrOverrideVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ PortCommonModeRestoreTime,
+ PortTpowerOnValue,
+ PortTpowerOnScale,
+ PchPwrOptPcie,
+ AspmOverride,
+ ClkreqPerPortSupported,
+ RpAndEndPointsLtrSupported,
+ PolicyRevision
+ );
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_INFO, "Check DownStreamBus:%d and no device found!\n", DownStreamBusMin));
+ }
+
+ if (BusAssign == FALSE) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (EndPointBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0xFF000000);
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function checks if the root port and downstream device support Clkreq per port, ASPM L1 and L1 substates
+
+ @param[in] RootBus Pci Bus Number of the root port
+ @param[in] RootDevice Pci Device Number of the root port
+ @param[in] RootFunction Pci Function Number of the root port
+ @param[in] RootPortAspm Root port Aspm configuration
+ @param[in] NumOfDevAspmOverride Number of Device specific ASPM policy override items
+ @param[in] DevAspmOverride Pointer to array of Device specific ASPM policy override items
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+ @param[in] NumOfDevLtrOverride Number of Device specific LTR override items
+ @param[in] DevLtrOverride Pointer to array of Device specific LTR policy override items
+ @param[in] PchPwrOptPcie Pcie Power Optimizer Configuration
+ @param[in, out] L1SubstatesSupported Flag to indicate if L1 Substates are supported
+ @param[in] L1SubstatesConfig L1 Substates configuration
+ @param[in] PolicyRevision Revision of the policy
+ @param[in, out] AspmVal Aspm value for both rootport and end point devices
+ @param[in, out] ClkreqPerPortSupported Clkreq support for both rootport and endpoint devices
+ @param[out] LtrSupported Check and return if all endpoints support LTR
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED The pointer to the Port PCI Express Capability Structure is not found
+**/
+EFI_STATUS
+PcieCheckPmConfig (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ IN PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspm,
+ IN UINT8 NumOfDevAspmOverride,
+ IN PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ IN UINT8 NumOfDevLtrOverride,
+ IN PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride,
+ IN PCH_PCIE_PWR_OPT *PchPwrOptPcie,
+ IN OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN OUT UINT16 *AspmVal,
+ IN OUT BOOLEAN *ClkreqPerPortSupported,
+ OUT BOOLEAN *LtrSupported
+ )
+{
+ EFI_STATUS Status;
+ UINTN RootDeviceBase;
+ UINT32 RootPcieCapOffset;
+ UINT8 EndPointBus;
+ OPERATION Operation;
+ UINT16 SlotStatus;
+ BOOLEAN BusAssign;
+ UINT32 DeviceCapabilities2;
+ UINT32 LtrOvrVal;
+ UINT32 Data32Or;
+ UINT16 GpioBase;
+ UINT32 RootComplexBar;
+ UINT16 RootL1SubstateExtCapOffset;
+ UINT32 PortCommonModeRestoreTime;
+ UINT32 PortTpowerOnValue;
+ UINT32 PortTpowerOnScale;
+ BOOLEAN AspmOverride;
+ PCH_SERIES PchSeries;
+ UINT8 RootPortNumber;
+
+ PchSeries = GetPchSeries();
+ Status = EFI_SUCCESS;
+ RootDeviceBase = MmPciAddress (0, RootBus, RootDevice, RootFunction, 0);
+ RootComplexBar = PCH_RCRB_BASE;
+ PortCommonModeRestoreTime = 0;
+ PortTpowerOnValue = 0;
+ PortTpowerOnScale = 0;
+ *L1SubstatesSupported = FALSE;
+ AspmOverride = FALSE;
+ *ClkreqPerPortSupported = FALSE;
+ GpioBase = 0;
+
+ if (MmioRead16 (RootDeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return EFI_NOT_FOUND;
+ }
+ if (PchSeries == PchLp) {
+ GpioBase = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE)
+ ) & B_PCH_LPC_GPIO_BASE_BAR;
+
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, RootFunction);
+ Data32Or = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + RootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+
+ if (Data32Or == 0) {
+ *ClkreqPerPortSupported = TRUE;
+ }
+ }
+
+ ///
+ /// Get the pointer to the Port PCI Express Capability Structure.
+ ///
+ RootPcieCapOffset = PcieFindCapId (RootBus, RootDevice, RootFunction, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (RootPcieCapOffset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ DeviceCapabilities2 = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x24);
+
+ *AspmVal = (MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x00C) >> 10) & 3;
+ if (RootPortAspm == PchPcieAspmAutoConfig) {
+ Operation = CalculateAspm;
+ } else {
+ Operation = ManualAspm;
+ *AspmVal &= RootPortAspm;
+ }
+ ///
+ /// Get the downstream Bus number
+ ///
+ EndPointBus = (UINT8) (MmioRead32 (RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 8);
+ ///
+ /// If the Secondary Bus Number of the root port is not assigned
+ /// Note:
+ /// It will be better that PCI emulation has been done before PcieSetPm(). Or, you will need to assign
+ /// a larger number to TempRootPortBusNumMax to support the specific card which has many bridges behind.
+ /// If it is not, the platform policy settings of "TempRootPortBusNumMax" and "TempRootPortBusNumMin"
+ /// will be assigned to the Subordinate and Secondary Bus Number of the root ports.
+ /// The assigned bus number will be cleared in the end of PcieSetPm().
+ ///
+ if (EndPointBus == 0) {
+ MmioAndThenOr32 (
+ RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF0000FF,
+ ((UINT32) (TempBusNumberMin << 8)) | ((UINT32) (TempBusNumberMax << 16))
+ );
+ EndPointBus = TempBusNumberMin;
+ BusAssign = FALSE;
+ } else {
+ BusAssign = TRUE;
+ }
+ ///
+ /// Check whether the slot has a device connected
+ ///
+ SlotStatus = MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x1A);
+ LtrOvrVal = 0;
+
+ RootL1SubstateExtCapOffset = 0;
+ if (PchSeries == PchLp) {
+ RootL1SubstateExtCapOffset = PcieFindExtendedCapId (RootBus, RootDevice, RootFunction, 0x1E);
+ if (RootL1SubstateExtCapOffset != 0) {
+ PortCommonModeRestoreTime = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 8) & 0xFF;
+ PortTpowerOnScale = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 16) & 0x3;
+ PortTpowerOnValue = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 19) & 0x1F;
+ }
+ }
+ ///
+ /// Obtain initial ASPM settings from respective port capability registers.
+ /// Scan LTR override table for device match and calculate the lowest override
+ /// value to be programmed into B0:D28:F0~F7 + 400h
+ ///
+ if (EndPointBus != 0 && (SlotStatus & BIT6) != 0) {
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ EndPointBus,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ AspmVal,
+ Operation,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ &LtrOvrVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ &PortCommonModeRestoreTime,
+ &PortTpowerOnValue,
+ &PortTpowerOnScale,
+ PchPwrOptPcie,
+ &AspmOverride,
+ ClkreqPerPortSupported,
+ LtrSupported,
+ PolicyRevision
+ );
+ }
+
+ if (BusAssign == FALSE) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (RootDeviceBase + 0x018, 0xFF0000FF);
+ }
+
+ return Status;
+}
+/**
+ This function performs the Power Management settings for root port and downstream device
+
+ @param[in] RootBus Pci Bus Number of the root port
+ @param[in] RootDevice Pci Device Number of the root port
+ @param[in] RootFunction Pci Function Number of the root port
+ @param[in] RootPortAspm Root port Aspm configuration
+ @param[in] NumOfDevAspmOverride Number of Device specific ASPM policy override items
+ @param[in] DevAspmOverride Pointer to array of Device specific ASPM policy override items
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+ @param[in] NumOfDevLtrOverride Number of Device specific LTR override items
+ @param[in] DevLtrOverride Pointer to array of Device specific LTR policy override items
+ @param[in] PchPwrOptPcie Pcie Power Optimizer Configuration
+ @param[in, out] L1SubstatesSupported Flag to indicate if L1 Substates are supported
+ @param[in] L1SubstatesConfig L1 Substates configuration
+ @param[in] PolicyRevision Policy revision for codes compatibility
+ @param[in] FirstRpToSetPm Indicates if this is the first root port to be set
+ @param[in] L1SupportedInAllEnabledPorts Check if L1 is supported in all enabled ports
+ @param[in] ClkreqSupportedInAllEnabledPorts Check if clkreq is supported in all enabled ports
+ @param[out] LtrSupported Check and return if all endpoints support LTR
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED The pointer to the Port PCI Express Capability Structure is not found
+**/
+EFI_STATUS
+PcieSetPm (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ IN PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspm,
+ IN UINT8 NumOfDevAspmOverride,
+ IN PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ IN UINT8 NumOfDevLtrOverride,
+ IN PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride,
+ IN PCH_PCIE_PWR_OPT *PchPwrOptPcie,
+ IN OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN BOOLEAN FirstRPToSetPm,
+ IN BOOLEAN L1SupportedInAllEnabledPorts,
+ IN BOOLEAN ClkreqSupportedInAllEnabledPorts,
+ OUT BOOLEAN *LtrSupported
+ )
+{
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ ///
+ /// When enabling L0s / L1 support, BIOS should enable upstream device before downstream
+ /// device. When disabling ASPM, BIOS should make sure downstream device is disabled
+ /// before upstream device.
+ /// The System BIOS must perform the following steps to enable
+ /// L0s/L1 on the root ports:
+ ///
+ /// 1. Determine whether the endpoint supports L1 by checking the Active State Link PM
+ /// Support field of the endpoint Link Capability Register. If the endpoint does not
+ /// support L1, the System BIOS can skip the L1 calculations below. Likewise, System
+ /// BIOS should not enable L1 on the root port or the endpoint if the endpoint does not
+ /// support L1.
+ /// 2. Calculate the total L0s and L1 exit latency. A description of this calculation
+ /// is provided in Section 8.3.1.1.
+ /// 3. Compare the calculated total exit latency with Endpoint L0s/L1 Acceptable Latency
+ /// read from the Device Capabilities Register of the Endpoint to determine if L0s or
+ /// L1 can be enabled for all or some of the links on the entire path to satisfy the
+ /// Acceptable Latency reported by the Endpoint. The Exit Latency fields reported by
+ /// the registers are given as a range. It is recommended that System BIOS uses the
+ /// high end of the range for the latency calculation and comparison. For example, if
+ /// the latency field reports "2 us to less than 4 us", then 4 us should be used for
+ /// the calculation.
+ /// 4. If the comparison in step 3 indicates L0s and L1 can be enabled on a root port and
+ /// the endpoints attached to the root port, then set the root port register
+ /// D28:F0~F7:Reg E8h[1], then set the APMC field, D28:F0~F7:Reg 50h[1:0] to 11b and write
+ /// the same value to the APMC field of the endpoint Link Control register. If the
+ /// comparison in step 1 indicates only L0s can be enabled on a root port and the
+ /// endpoints attached to the root port, then set the APMC field, D28:F0~F7:Reg 50h[1:0]
+ /// to 01b and write the same value to the APMC field of the endpoint Link Control
+ /// register.
+ ///
+ /// NOTE: current implementation does not support full length exit latency calculation
+ ///
+ UINT16 AspmVal;
+ EFI_STATUS Status;
+ UINTN RootDeviceBase;
+ UINT32 RootPcieCapOffset;
+ UINT8 EndPointBus;
+ OPERATION Operation;
+ UINT16 SlotStatus;
+ BOOLEAN BusAssign;
+ UINT32 DeviceCapabilities2;
+ UINT32 LtrOvrVal;
+ UINT32 Data32Or;
+ UINT8 Data8And;
+ UINT8 Data8Or;
+ UINT16 GpioBase;
+ BOOLEAN ClkreqPerPortSupported;
+ UINT32 RootComplexBar;
+ UINT16 RootL1SubstateExtCapOffset;
+ UINT32 PortCommonModeRestoreTime;
+ UINT32 PortTpowerOnValue;
+ UINT32 PortTpowerOnScale;
+ BOOLEAN AspmOverride;
+ PCH_SERIES PchSeries;
+ UINT8 RootPortNumber;
+#ifdef ULT_FLAG
+ UINT32 Data32;
+ UINT8 Response;
+#endif // ULT_FLAG
+
+ PchSeries = GetPchSeries();
+ Status = EFI_SUCCESS;
+ RootDeviceBase = MmPciAddress (0, RootBus, RootDevice, RootFunction, 0);
+ RootComplexBar = PCH_RCRB_BASE;
+ PortCommonModeRestoreTime = 0;
+ PortTpowerOnValue = 0;
+ PortTpowerOnScale = 0;
+ *L1SubstatesSupported = FALSE;
+ AspmOverride = FALSE;
+ ClkreqPerPortSupported = FALSE;
+ GpioBase = 0;
+
+ if (MmioRead16 (RootDeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return EFI_NOT_FOUND;
+ }
+ if (PchSeries == PchLp) {
+ GpioBase = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE)
+ ) & B_PCH_LPC_GPIO_BASE_BAR;
+
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, RootFunction);
+ Data32Or = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + RootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+
+ if (Data32Or == 0) {
+ ClkreqPerPortSupported = TRUE;
+ }
+ }
+
+ ///
+ /// Get the pointer to the Port PCI Express Capability Structure.
+ ///
+ RootPcieCapOffset = PcieFindCapId (RootBus, RootDevice, RootFunction, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (RootPcieCapOffset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ DeviceCapabilities2 = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x24);
+
+ ///
+ /// Enable LTR mechanism for this root port if it is capable
+ ///
+ if ((DeviceCapabilities2 & BIT11) && (PchPwrOptPcie->LtrEnable == TRUE)) {
+ MmioOr16 (RootDeviceBase + RootPcieCapOffset + 0x28, BIT10);
+ }
+
+ ///
+ /// Enable OBFF using WAKE# signaling for this root port if it is capable
+ ///
+ if ((DeviceCapabilities2 & BIT19) && (PchPwrOptPcie->ObffEnable == TRUE)) {
+ MmioOr16 (RootDeviceBase + RootPcieCapOffset + 0x28, (BIT14 + BIT13));
+ }
+ AspmVal = (MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x00C) >> 10) & 3;
+ if (RootPortAspm == PchPcieAspmAutoConfig) {
+ Operation = CalculateAspm;
+ } else {
+ Operation = ManualAspm;
+ AspmVal &= RootPortAspm;
+ }
+ ///
+ /// Get the downstream Bus number
+ ///
+ EndPointBus = (UINT8) (MmioRead32 (RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 8);
+ ///
+ /// If the Secondary Bus Number of the root port is not assigned
+ /// Note:
+ /// It will be better that PCI emulation has been done before PcieSetPm(). Or, you will need to assign
+ /// a larger number to TempRootPortBusNumMax to support the specific card which has many bridges behind.
+ /// If it is not, the platform policy settings of "TempRootPortBusNumMax" and "TempRootPortBusNumMin"
+ /// will be assigned to the Subordinate and Secondary Bus Number of the root ports.
+ /// The assigned bus number will be cleared in the end of PcieSetPm().
+ ///
+ if (EndPointBus == 0) {
+ MmioAndThenOr32 (
+ RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF0000FF,
+ ((UINT32) (TempBusNumberMin << 8)) | ((UINT32) (TempBusNumberMax << 16))
+ );
+ EndPointBus = TempBusNumberMin;
+ BusAssign = FALSE;
+ } else {
+ BusAssign = TRUE;
+ }
+ ///
+ /// Check whether the slot has a device connected
+ ///
+ SlotStatus = MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x1A);
+ LtrOvrVal = 0;
+
+ RootL1SubstateExtCapOffset = 0;
+ if (PchSeries == PchLp) {
+ RootL1SubstateExtCapOffset = PcieFindExtendedCapId (RootBus, RootDevice, RootFunction, 0x1E);
+ if (RootL1SubstateExtCapOffset != 0) {
+ PortCommonModeRestoreTime = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 8) & 0xFF;
+ PortTpowerOnScale = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 16) & 0x3;
+ PortTpowerOnValue = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 19) & 0x1F;
+ }
+ }
+ ///
+ /// Obtain initial ASPM settings from respective port capability registers.
+ /// Scan LTR override table for device match and calculate the lowest override
+ /// value to be programmed into B0:D28:F0~F7 + 400h
+ ///
+ if (EndPointBus != 0 && (SlotStatus & BIT6) != 0) {
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ EndPointBus,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ &AspmVal,
+ Operation,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ &LtrOvrVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ &PortCommonModeRestoreTime,
+ &PortTpowerOnValue,
+ &PortTpowerOnScale,
+ PchPwrOptPcie,
+ &AspmOverride,
+ &ClkreqPerPortSupported,
+ LtrSupported,
+ PolicyRevision
+ );
+ if (PchPwrOptPcie->LtrEnable == PCH_DEVICE_ENABLE) {
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ if (PchPwrOptPcie->SnoopLatencyOverrideMode == 1) {
+ LtrOvrVal &= 0xFFFF0000;
+ LtrOvrVal |= (UINT32) BIT15 |
+ (UINT32) (PchPwrOptPcie->SnoopLatencyOverrideMultiplier << 10) |
+ (UINT32) (PchPwrOptPcie->SnoopLatencyOverrideValue);
+ }
+
+ if (PchPwrOptPcie->NonSnoopLatencyOverrideMode == 1) {
+ LtrOvrVal &= 0x0000FFFF;
+ LtrOvrVal |= (UINT32) BIT31 |
+ (UINT32) (PchPwrOptPcie->NonSnoopLatencyOverrideMultiplier << 26) |
+ (UINT32) (PchPwrOptPcie->NonSnoopLatencyOverrideValue << 16);
+ }
+ }
+ if (LtrOvrVal != 0) {
+ ///
+ /// Program B0:D28:F0~F7 + 400h only if we find a device in the LTR override table
+ ///
+ MmioWrite32 (RootDeviceBase + R_PCH_PCIE_LTROVR, LtrOvrVal);
+ ///
+ /// Step 1.2
+ /// Program B0:D28:F0~F7 + 404h [1:0] = 11b for ports which has a PCIe device
+ /// device attached to it.
+ ///
+ Data32Or = BIT1 | BIT0;
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ if (PchPwrOptPcie->SnoopLatencyOverrideMode == 0) {
+ Data32Or &= (UINT32) ~BIT0;
+ }
+ if (PchPwrOptPcie->NonSnoopLatencyOverrideMode == 0) {
+ Data32Or &= (UINT32) ~BIT1;
+ }
+ if (PchPwrOptPcie->LtrConfigLock == PCH_DEVICE_ENABLE) {
+ ///
+ /// Set the lock bit
+ ///
+ Data32Or |= BIT2;
+ }
+ }
+ MmioWrite32 (RootDeviceBase + R_PCH_PCIE_LTROVR2, Data32Or);
+ }
+ }
+ }
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ ///
+ /// If both Root and endpoint's L1 Sub-States Extended Capability Offset + 0x04[4:0] are 11111b,
+ ///
+ if (*L1SubstatesSupported) {
+ ///
+ /// a. Read L1 Sub-States Extended Capability Offset + 0x04[15:8], and Set the highest value advertised
+ /// between PCIe rootport and device to L1 Sub-States Extended Capability Offset + 0x08[15:8] on both
+ /// Pcie root port and device.
+ ///
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x08,
+ (UINT32) ~(0xFF00),
+ (UINT32) PortCommonModeRestoreTime << 8
+ );
+
+ ///
+ /// b. Read L1 Sub-States Extended Capability Offset + 0x04[23:19] and [17:16], and Set the highest value
+ /// advertised between PCIe root port and device to L1 Sub-States Extended Capability Offset + 0x0C [7:0] on
+ /// both Pcie root port and device.
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x0C,
+ 0xFFFFFF04,
+ (UINT32) ((PortTpowerOnValue << 3) | PortTpowerOnScale)
+ );
+
+ ///
+ /// c. Set L1 Sub-States Extended Capability Offset + 0x08[31:29] to 010b for both Pcie root port and device
+ /// d. Set L1 Sub-States Extended Capability Offset + 0x08[25:16] to 0010100000b for both Pcie root port and device
+ ///
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x08,
+ (UINT32) ~(0xE3FF0000),
+ (UINT32) (BIT30 | BIT23 | BIT21)
+ );
+
+ ///
+ /// e. If clkreq per port is suported, set D28:F0~F5:420h[0] to 1b prior to L1 enabling
+ ///
+ if (((AspmVal & V_PCH_PCIE_LCTL_APMC_L1) == V_PCH_PCIE_LCTL_APMC_L1) && ClkreqPerPortSupported) {
+ MmioOr32 (RootDeviceBase + R_PCH_PCIE_PCIEPMECTL, BIT0);
+ }
+
+ ///
+ /// f. Set L1 Sub-States Extended Capability Offset + 0x08[4:0] to 01111b for both Pcie root port and device
+ ///
+ Data32Or = (BIT3 | BIT2 | BIT1 | BIT0);
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_1) {
+ Data32Or &= (UINT32)~(BIT0);
+ }
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_2) {
+ Data32Or &= (UINT32)~(BIT1);
+ }
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x08,
+ (UINT32) ~(BIT4 | BIT3 | BIT2 | BIT1 | BIT0),
+ Data32Or
+ );
+ }
+
+
+ if ((AspmVal & V_PCH_PCIE_LCTL_APMC_L1) == V_PCH_PCIE_LCTL_APMC_L1) {
+ ///
+ /// Program D28:F0~F5:E2h[5:4] to 11b prior to enabling ASPM L1,
+ /// if all enabled ports support ASPM L1
+ ///
+ if (FirstRPToSetPm && L1SupportedInAllEnabledPorts) {
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigRead,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ Data32 |= ((B_PCH_PCIE_RPPGEN_LMSDOCGE | B_PCH_PCIE_RPPGEN_SEOCGE) << 16);
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigWrite,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (ClkreqPerPortSupported) {
+ ///
+ /// Program D28:F0~F5:420h[17] to 0b prior to enabling ASPM L1
+ ///
+ if (*L1SubstatesSupported) {
+ MmioAnd32 (RootDeviceBase + R_PCH_PCIE_PCIEPMECTL, (UINT32)~B_PCH_PCIE_PCIEPMECTL_L1LE);
+ }
+
+ ///
+ /// Program D28:F0~F5:420h[29] to 1b, when D28:F0:E1h[6] is set to 1b
+ ///
+ Data32Or = B_PCH_PCIE_PCIEPMECTL_DLSULDLSD;
+ MmioOr32 (
+ RootDeviceBase + R_PCH_PCIE_PCIEPMECTL,
+ Data32Or
+ );
+
+ ///
+ /// If dedicated CLKREQ# per-port is supported on all enabled ports, set D28:F0:E1h[6] to 1b prior to enabling ASPM L1
+ ///
+ if (FirstRPToSetPm && ClkreqSupportedInAllEnabledPorts) {
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigRead,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ Data32 |= (B_PCH_PCIE_RPDCGEN_POCGE << 8);
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigWrite,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+ }
+#endif // ULT_FLAG
+ ///
+ /// Set Root Port Aspm and enable LTR capability of the device
+ ///
+ MmioAndThenOr16 (RootDeviceBase + RootPcieCapOffset + 0x010, 0xFFFC, AspmVal);
+ ///
+ /// Based on the Role based Error Reporting Capability bit, for pre-1.1 devices,
+ /// program root port 0xD4[4] to 1 and 0xD4[3:2] to 10.
+ ///
+ if (AspmOverride) {
+ MmioAndThenOr8 (RootDeviceBase + R_PCH_PCIE_MPC2,
+ (UINT8)~(B_PCH_PCIE_MPC2_ASPMCOEN | B_PCH_PCIE_MPC2_ASPMCO),
+ (B_PCH_PCIE_MPC2_ASPMCOEN | V_PCH_PCIE_MPC2_ASPMCO_L1)
+ );
+ } else {
+ MmioAnd8 (RootDeviceBase + R_PCH_PCIE_MPC2, (UINT8)~(B_PCH_PCIE_MPC2_ASPMCOEN | B_PCH_PCIE_MPC2_ASPMCO));
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 8.14.1 Power Optimizer Configuration
+ /// Step 1
+ /// Enable support Latency Tolerance Reporting (LTR)
+ ///
+
+ if (EndPointBus != 0 && (SlotStatus & BIT6) != 0) {
+ ///
+ /// Set Endpoint Aspm and LTR capabilities
+ ///
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ EndPointBus,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ &AspmVal,
+ SetAspm,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ &LtrOvrVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ &PortCommonModeRestoreTime,
+ &PortTpowerOnValue,
+ &PortTpowerOnScale,
+ PchPwrOptPcie,
+ &AspmOverride,
+ &ClkreqPerPortSupported,
+ LtrSupported,
+ PolicyRevision
+ );
+ }
+
+ if (BusAssign == FALSE) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (RootDeviceBase + 0x018, 0xFF0000FF);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// If L0s and L1 can be enabled on a root port and the endpoints attached to the root port,
+ /// then set the root port register D28:Fx:Reg E8h[1]
+ ///
+ if (AspmVal == V_PCH_PCIE_LCTL_APMC_L0S_L1) {
+ if (PchSeries == PchLp) {
+ ///
+ /// Set the root port register D28:Fx:REG E8h[3:2] to 10b before setting D28:Fx:Reg E8h[0] or E8h[1]
+ ///
+ Data8Or = BIT3;
+ Data8And = (UINT8) ~(V_PCH_PCIE_PECR1_FIELD_3);
+ MmioAndThenOr8 (
+ RootDeviceBase + R_PCH_PCIE_PECR1,
+ Data8And,
+ Data8Or
+ );
+ }
+ MmioOr8 (RootDeviceBase + R_PCH_PCIE_PECR1, B_PCH_PCIE_PECR1_FIELD_2);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Initializes the root port and its down stream devices
+
+ @param[in] RootPortBus Pci Bus Number of the root port
+ @param[in] RootPortDevice Pci Device Number of the root port
+ @param[in] RootPortFunc Pci Function Number of the root port
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+ @param[in, out] MaxPayload The Max Payolad Size of the root port
+ @param[out] DeviceClassDword Get the downstream device code dword for unstream RootPort reference
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device.
+**/
+EFI_STATUS
+PchPcieInitDownstreamDevices (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ IN OUT UINT16 *MaxPayload,
+ OUT UINT32 *DeviceClassDword
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINTN RPBase;
+ UINTN EndPointBase;
+
+ RPBase = MmPciAddress (0, RootPortBus, RootPortDevice, RootPortFunc, 0);
+ ///
+ /// Temporarily Hardcode the Root Port Bridge Number to TempBusNumberMin
+ ///
+ MmioAndThenOr32 (
+ RPBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF000000,
+ RootPortBus | ((UINT32) (TempBusNumberMin << 8)) | ((UINT32) (TempBusNumberMax << 16))
+ );
+ ///
+ /// This Endpoint check should immediately pass. Howerver, a 1.0s delay
+ /// has been added to match the timing requirements of the PCI Express Base
+ /// Specification, Revision 1.0A, Section 6.6 ("...software must allow 1.0s
+ /// after a reset of a device, before it may determine that a device which
+ /// fails to return a Successful Completion status for a valid Configuration
+ /// Request is a broken device").
+ ///
+ EndPointBase = MmPciAddress (0, TempBusNumberMin, 0, 0, 0);
+ ///
+ /// A config write is required in order for the device to re-capture the Bus number,
+ /// according to PCI Express Base Specification, 2.2.6.2 ("Note that the Bus Number
+ /// and Device Number may be changed at run time, and so it is necessary to re-capture
+ /// this information with each and every Configuration Write Request")
+ ///
+ MmioWrite8 (EndPointBase + 0x0, 0);
+ for (Index = 0; Index < 100000; Index++) {
+ if (MmioRead16 (EndPointBase + PCI_VENDOR_ID_OFFSET) != 0xFFFF) {
+ break;
+ }
+
+ PchPmTimerStall (10);
+ }
+
+ if (Index >= 100000) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (RPBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0xFF000000);
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Get the device class code dword for upstream RootPort reference
+ ///
+ if (DeviceClassDword != NULL) {
+ *DeviceClassDword = MmioRead32 (EndPointBase + R_PCH_PCIE_RID);
+ }
+ ///
+ /// Get the Max Payload Size on all the end point functions
+ ///
+ PcieMaxPayloadSize (TempBusNumberMin, PCI_MAX_DEVICE, MaxPayload, FALSE);
+ ///
+ /// Check if this device is a bridge
+ ///
+ if (MmioRead8 (EndPointBase + R_PCH_PCIE_BCC) == PCI_CLASS_BRIDGE) {
+ ///
+ /// Initialize downstream devices
+ ///
+ if (TempBusNumberMax > TempBusNumberMin) {
+ Status = PchPcieInitDownstreamDevices (
+ TempBusNumberMin,
+ 0,
+ 0,
+ TempBusNumberMin + 1,
+ TempBusNumberMax,
+ MaxPayload,
+ NULL
+ );
+ }
+ }
+ ///
+ /// Complete Common Port and Endpoint Configuration.
+ ///
+ ///
+ /// Map TC0-VC0
+ ///
+ PcieMapTcxVc0 (RootPortBus, RootPortDevice, (UINT8) RootPortFunc, TempBusNumberMin, PCI_MAX_DEVICE, 0x0);
+
+ ///
+ /// Set Common Clock for inserted cards
+ ///
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ /// Before determining whether ASPM can be enabled or not,
+ /// the System BIOS must perform the following steps:
+ ///
+ /// For PCH H
+ /// 1. Update the Link Capabilities of the DMI to indicate L1 is
+ /// supported on the interface by setting the LCAP Register
+ /// RCBA + 21A4h [11:10] = 11b
+ /// (Done in PchPm.c)
+ ///
+ /// 2. Enable L0s on DMI for Desktop platforms by setting the APMC field,
+ /// RCBA + offset 21A8h[1:0] to 01b.
+ /// Enable L0s/L1 on DMI by setting RCBA + offset 21A8h[1:0] to 11b.
+ /// (Done in PchPm.c)
+ ///
+ /// 3. For each root port, read the Slot Clock Configuration bit, D28:F0~F7:Reg 52h[12],
+ /// of the root port and the endpoint device connected to the port (i.e., D0:F0 on the
+ /// secondary bus behind the root port). If both components have this bit set, then the
+ /// System BIOS should set the Common Clock Configuration (CCC) bit, D28:F0~F7:Reg 50h[6],
+ /// for both components at both sides of the link to indicate that components at both ends
+ /// of the link use a common clock source.
+ ///
+ /// 4. If the CCC bit was changed by the System BIOS in step 3, System BIOS should initiate
+ /// a link training by setting the Retrain Link (RL) bit, D28:F0~F7:Reg 50h[5], and then poll the Link
+ /// Training (LT) bit, D28:F0~F7:Reg 52h[11], until it is clear.
+ /// Note that System BIOS should save and restore CCC bit on S3.
+ ///
+ PcieSetCommonClock (RootPortBus, RootPortDevice, (UINT8) RootPortFunc, TempBusNumberMin, PCI_MAX_DEVICE);
+
+ ///
+ /// Enable the PCIe CLKREQ#
+ ///
+ PcieSetClkreq (TempBusNumberMin, PCI_MAX_DEVICE, (UINT8) RootPortFunc);
+
+ ///
+ /// Set the Max Payload Size on all the end point functions
+ ///
+ PcieMaxPayloadSize (TempBusNumberMin, PCI_MAX_DEVICE, MaxPayload, TRUE);
+
+ ///
+ /// Disable the forwarding of EOI messages unless it discovers an IOAPIC behind this root port
+ ///
+ PcieSetEoiFwdDisable (RootPortBus, RootPortDevice, RootPortFunc, TempBusNumberMin, PCI_MAX_DEVICE);
+ ///
+ /// Clear Bus Numbers
+ ///
+ MmioAnd32 (RPBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0xFF000000);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes the root port and its down stream devices
+
+ @param[in] RootPortBus Pci Bus Number of the root port
+ @param[in] RootPortDevice Pci Device Number of the root port
+ @param[in] RootPortFunc Pci Function Number of the root port
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+ @param[out] DeviceClassDword Get the downstream device code dword for unstream RootPort reference
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device.
+**/
+EFI_STATUS
+PchPcieInitRootPortDownstreamDevices (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ OUT UINT32 *DeviceClassDword
+ )
+{
+ UINT16 SlotStatus;
+ UINTN RPBase;
+ UINT16 RootPortMaxPayload;
+ UINT8 PcieCapOffset;
+ EFI_STATUS Status;
+
+ RPBase = MmPciAddress (0, RootPortBus, RootPortDevice, RootPortFunc, 0);
+ ///
+ /// Check for a Presence Detect Change.
+ ///
+ SlotStatus = MmioRead16 (RPBase + R_PCH_PCIE_SLSTS);
+
+ ///
+ /// Check whether the slot has a device connected
+ ///
+ if ((SlotStatus & BIT6) == 0) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Get the pointer to the Endpoint PCI Express Capability Structure.
+ ///
+ PcieCapOffset = PcieFindCapId (
+ RootPortBus,
+ RootPortDevice,
+ RootPortFunc,
+ EFI_PCI_CAPABILITY_ID_PCIEXP
+ );
+
+ ///
+ /// Get the root port Max Payload Size support
+ ///
+ RootPortMaxPayload = MmioRead16 (RPBase + PcieCapOffset + 0x04) & (BIT2 | BIT1 | BIT0);
+
+ ///
+ /// Initialize downstream devices
+ ///
+ Status = PchPcieInitDownstreamDevices (
+ RootPortBus,
+ RootPortDevice,
+ RootPortFunc,
+ TempBusNumberMin,
+ TempBusNumberMax,
+ &RootPortMaxPayload,
+ DeviceClassDword
+ );
+
+ ///
+ /// Set the PCIE root Port Max Payload Size
+ ///
+ MmioAndThenOr16 (RPBase + PcieCapOffset + 0x08, (UINT16)~(BIT7 | BIT6 | BIT5), RootPortMaxPayload << 5);
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
new file mode 100644
index 0000000..7f32fe0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
@@ -0,0 +1,42 @@
+/** @file
+ Header file for PCH Pci Express helps library implementation.
+
+@copyright
+ Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+**/
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
+#define _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "PchPlatformPolicy.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchPciExpressHelperslib.h"
+#include "pci23.h"
+#include "pci22.h"
+#endif
+
+#define LTR_VALUE_MASK (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7 + BIT8 + BIT9)
+#define LTR_SCALE_MASK (BIT10 + BIT11 + BIT12)
+
+//
+// LTR related macros
+//
+#define LTR_LATENCY_VALUE(x) ((x) & LTR_VALUE_MASK)
+#define LTR_SCALE_VALUE(x) (((x) & LTR_SCALE_MASK) >> 10)
+#define LTR_LATENCY_NS(x) (LTR_LATENCY_VALUE(x) * (1 << (5 * LTR_SCALE_VALUE(x))))
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c
new file mode 100644
index 0000000..d21a181
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c
@@ -0,0 +1,295 @@
+/** @file
+ Program IOBP register.
+
+@copyright
+ Copyright (c) 2009 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchPlatformLibrary.h"
+
+/**
+ Configures PCH IOBP
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+ProgramIobp (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ UINT32 Data32;
+ UINT8 ResponseStatus;
+ EFI_STATUS Status;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 7.1.4 IOSF SBI Programming
+ /// Step 1 to Step 8
+ ///
+ Status = ReadIobp (RootComplexBar, Address, &Data32);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Step 9
+ /// Update the SBI data accordingly
+ ///
+ Data32 &= AndMask;
+ Data32 |= OrMask;
+ ///
+ /// Step 10
+ /// Set RCBA + 2338h[15:8] = 00000111b
+ ///
+ MmioAndThenOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA),
+ (UINT16) V_PCH_RCRB_IOBPS_IOBPIA_W
+ );
+ ///
+ /// Step 11
+ /// Write RCBA + 2334h[31:0] with updated SBI data
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPD), Data32);
+
+ ///
+ /// Step 12
+ /// Set RCBA + 233Ah[15:0] = F000h
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x233A),
+ 0xF000
+ );
+
+ ///
+ /// Step 13
+ /// Set RCBA + 2338h[0] = 1b
+ ///
+ MmioOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) BIT0
+ );
+
+ ///
+ /// Step 14
+ /// Poll RCBA + Offset 2338h[0] = 0b
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 15
+ /// Check if RCBA + 2338h[2:1] = 00b for successful transaction
+ ///
+ ResponseStatus = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS;
+ if (ResponseStatus == V_PCH_RCRB_IOBPS_SUCCESS) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
+
+/**
+ Read data from PCH IOBP register block
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[out] Data Data contain in the IOBP register block
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+ReadIobp (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ OUT UINT32 *Data
+ )
+{
+ UINT8 ResponseStatus;
+
+ ///
+ /// Step 1 Poll RCBA + 2338[0] = 0b
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 2
+ /// Write RCBA + Offset 2330h[31:0] with IOBP register address
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPIRI), Address);
+ ///
+ /// Step 3
+ /// Set RCBA + 2338h[15:8] = 00000110b
+ ///
+ MmioAndThenOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA),
+ (UINT16) V_PCH_RCRB_IOBPS_IOBPIA_R
+ );
+ ///
+ /// Step 4
+ /// Set RCBA + 233Ah[15:0] = F000h
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x233A),
+ 0xF000
+ );
+ ///
+ /// Step 5
+ /// Set RCBA + 2338h[0] = 1b
+ ///
+ MmioOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) BIT0
+ );
+
+ ///
+ /// Step 6
+ /// Poll RCBA + Offset 2338h[0] = 0b, Polling for Busy bit
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 7
+ /// Check if RCBA + 2338h[2:1] = 00b for successful transaction
+ ///
+ ResponseStatus = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS;
+ if (ResponseStatus == V_PCH_RCRB_IOBPS_SUCCESS) {
+ ///
+ /// Step 8
+ /// Read RCBA + 2334h[31:0] for IOBP data
+ ///
+ *Data = MmioRead32 (RootComplexBar + R_PCH_RCRB_IOBPD);
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
+
+/**
+ Configures PCH IOBP
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] Opcode Iobp Opcode
+ @param[in] RouteId Route Id
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+PchIobpExecution (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN PCH_IOBP_OPCODE Opcode,
+ IN UINT8 RouteId,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ )
+{
+ ///
+ /// Step 1 Poll RCBA + 2338[0] = 0b
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+ ///
+ /// Step 2
+ /// Write RCBA + Offset 2330h[31:0] with IOBP register address
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPIRI), Address);
+ ///
+ /// Step 3
+ /// Set RCBA + 2338h[15:8] to the opcode passed in
+ ///
+ MmioAndThenOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA),
+ (UINT16) (Opcode << 8)
+ );
+ ///
+ /// Step 4
+ /// Set RCBA + 233Ah[15:8] = F0h
+ /// Set RCBA + 233Ah[7:0] = Route Id passed in
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x233A),
+ (0xF000 | RouteId)
+ );
+ switch (Opcode) {
+ case MemoryMapWrite:
+ case IoMapWrite:
+ case PciConfigWrite:
+ case PrivateControlWrite:
+ ///
+ /// Step 5
+ /// Write RCBA + 2334h[31:0] with updated SBI data
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPD), *Data32);
+ break;
+ default:
+ break;
+ }
+ ///
+ /// Step 6
+ /// Set RCBA + 2338h[0] = 1b
+ ///
+ MmioOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) BIT0
+ );
+
+ ///
+ /// Step 7
+ /// Poll RCBA + Offset 2338h[0] = 0b, Polling for Busy bit
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 8
+ /// Check if RCBA + 2338h[2:1] = 00b for successful transaction
+ ///
+ *Response = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS;
+ if (*Response == V_PCH_RCRB_IOBPS_SUCCESS) {
+ switch (Opcode) {
+ case MemoryMapRead:
+ case IoMapRead:
+ case PciConfigRead:
+ case PrivateControlRead:
+ ///
+ /// Step 9
+ /// Read RCBA + 2334h[31:0] for IOBP data
+ ///
+ *Data32 = MmioRead32 (RootComplexBar + R_PCH_RCRB_IOBPD);
+ break;
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif
new file mode 100644
index 0000000..d146e3b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchPlatformLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchPlatformLib"
+ RefName = "PchPlatformLib"
+[files]
+"PchPlatformLib.mak"
+"PchPlatformLib.sdl"
+"PchPlatformLibrary.h"
+"PchPlatformLibrary.c"
+"PchPlatformLib.inf"
+"IobpAccess.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf
new file mode 100644
index 0000000..2aa9a25
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf
@@ -0,0 +1,67 @@
+## @file
+# Component description file for PEI/DXE PCH Platform Lib
+#
+#@copyright
+# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+
+[defines]
+BASE_NAME = PchPlatformLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ PchPlatformLibrary.h
+ PchPlatformLibrary.c
+ IobpAccess.c
+
+[sources.ia32]
+
+[sources.x64]
+
+[sources.ipf]
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[libraries.common]
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueBaseLib
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak
new file mode 100644
index 0000000..d6ca967
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak
@@ -0,0 +1,112 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.mak 3 10/16/12 2:52a Scottyang $
+#
+# $Revision: 3 $
+#
+# $Date: 10/16/12 2:52a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.mak $
+#
+# 3 10/16/12 2:52a Scottyang
+# [TAG] EIP103924
+# [Category] Improvement
+# [Description] Update RC 0.7.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 2 7/02/12 9:17a Victortu
+#
+# 1 2/08/12 8:48a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+# MAK file for the ModulePart:PchPlatformLib
+EDK : PchPlatformLib
+
+PchPlatformLib : PchPlatformSmmLib PchPlatformDxeLib PchPlatformPeiLib
+
+$(PchPlatformSmmLib_LIB) : PchPlatformSmmLib
+$(PchPlatformDxeLib_LIB) : PchPlatformDxeLib
+$(PchPlatformPeiLib_LIB) : PchPlatformPeiLib
+
+PchPlatformSmmLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibSmmBin
+
+PchPlatformDxeLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibDxeBin
+
+PchPlatformPeiLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibPeiBin
+
+$(BUILD_DIR)\PchPlatformLib.mak : $(PchPlatformLib_DIR)\$(@B).cif $(PchPlatformLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchPlatformLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchPlatformLib_INCLUDES =\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(EDK_INCLUDES)\
+
+PchPlatformLib_LIBS=\
+ $(EdkIIGlueBaseLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+
+PchPlatformLibSmmBin : $(PchPlatformLib_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPlatformLib.mak all\
+ "MY_INCLUDES=$(PchPlatformLib_INCLUDES)" \
+ TYPE=LIBRARY \
+ LIBRARIES=\
+ LIBRARY_NAME=$(PchPlatformSmmLib_LIB)
+
+PchPlatformLibDxeBin : $(PchPlatformLib_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPlatformLib.mak all\
+ "MY_INCLUDES=$(PchPlatformLib_INCLUDES)" \
+ "CFLAGS=$(CFLAGS) $(PchPlatformLib_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARIES=\
+ LIBRARY_NAME=$(PchPlatformDxeLib_LIB)
+
+PchPlatformLibPeiBin : $(PchPlatformLib_LIBS)
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+!ENDIF
+ /f $(BUILD_DIR)\PchPlatformLib.mak all\
+ "MY_INCLUDES=$(PchPlatformLib_INCLUDES)"\
+ "CFLAGS=$(CFLAGS) $(PchPlatformLib_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARIES=\
+ LIBRARY_NAME=$(PchPlatformPeiLib_LIB)
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl
new file mode 100644
index 0000000..4704a8c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl
@@ -0,0 +1,93 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.sdl 1 2/08/12 8:48a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:48a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.sdl $
+#
+# 1 2/08/12 8:48a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchPlatformLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchPlatformLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchPlatformLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchPlatformLib.mak to Project"
+ File = "PchPlatformLib.mak"
+End
+
+ELINK
+ Name = "PchPlatformSmmLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPlatformSmmLib.lib"
+ Parent = "PchPlatformSmmLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchPlatformDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPlatformDxeLib.lib"
+ Parent = "PchPlatformDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchPlatformPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPlatformPeiLib.lib"
+ Parent = "PchPlatformPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c
new file mode 100644
index 0000000..2d9c6ac
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c
@@ -0,0 +1,831 @@
+/** @file
+ PCH Platform Lib implementation.
+@copyright
+ Copyright (c) 2004 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchPlatformLibrary.h"
+
+/**
+ Delay for at least the request number of microseconds.
+ This function would be called by runtime driver, please do not use any MMIO marco here.
+
+ @param[in] Microseconds Number of microseconds to delay.
+
+ @retval NONE
+**/
+VOID
+EFIAPI
+PchPmTimerStall (
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINTN CurrentTick;
+ UINTN OriginalTick;
+ UINTN RemainingTick;
+ UINT16 AcpiBaseAddr;
+
+ if (Microseconds == 0) {
+ return;
+ }
+ ///
+ /// Please use PciRead here, it will link to MmioRead
+ /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer
+ /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details.
+ /// For the rest please use EdkIIGlueBasePciLibPciExpress library
+ ///
+ AcpiBaseAddr = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ OriginalTick = IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ CurrentTick = OriginalTick;
+
+ ///
+ /// The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+ ///
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+ ///
+ /// The loops needed by timer overflow
+ ///
+ Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ ///
+ /// Remaining clocks within one loop
+ ///
+ RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ ///
+ /// not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+ /// one I/O operation, and maybe generate SMI
+ ///
+ while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+ CurrentTick = IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ ///
+ /// Check if timer overflow
+ ///
+ if ((CurrentTick < OriginalTick)) {
+ if (Counts != 0) {
+ Counts--;
+ } else {
+ ///
+ /// If timer overflow and Counts equ to 0, that means we already stalled more than
+ /// RemainingTick, break the loop here
+ ///
+ break;
+ }
+ }
+
+ OriginalTick = CurrentTick;
+ }
+}
+
+/**
+ Check whether SPI is in descriptor mode
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+
+ @retval TRUE SPI is in descriptor mode
+ @retval FALSE SPI is not in descriptor mode
+**/
+BOOLEAN
+EFIAPI
+PchIsSpiDescriptorMode (
+ IN UINTN PchRootComplexBar
+ )
+{
+ if ((MmioRead16 (PchRootComplexBar + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
+ MmioAndThenOr32 (
+ PchRootComplexBar + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)),
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_FSDM | R_PCH_SPI_FDBAR_FLVALSIG)
+ );
+ if ((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FDOD)) == V_PCH_SPI_FDBAR_FLVALSIG) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Return Pch stepping type
+
+ @param[in] None
+
+ @retval PCH_STEPPING Pch stepping type
+**/
+PCH_STEPPING
+EFIAPI
+PchStepping (
+ VOID
+ )
+{
+ UINT8 RevId;
+ UINT16 LpcDeviceId;
+
+ RevId = MmioRead8 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_RID)
+ );
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_DEVICE_ID)
+ );
+
+ if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) {
+ switch (RevId) {
+ case V_PCH_LPT_LPC_RID_2:
+ return LptHB0;
+ break;
+
+ case V_PCH_LPT_LPC_RID_3:
+ return LptHC0;
+ break;
+
+ case V_PCH_LPT_LPC_RID_4:
+ return LptHC1;
+ break;
+
+ case V_PCH_LPT_LPC_RID_5:
+ return LptHC2;
+ break;
+
+ default:
+ return PchSteppingMax;
+ break;
+ }
+ }
+
+ if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) {
+ switch (RevId) {
+ case V_PCH_LPT_LPC_RID_2:
+ return LptLpB0;
+ break;
+
+ case V_PCH_LPT_LPC_RID_3:
+ return LptLpB1;
+ break;
+
+ case V_PCH_LPT_LPC_RID_4:
+ return LptLpB2;
+ break;
+
+ default:
+ return PchSteppingMax;
+ break;
+ }
+ }
+
+ return PchSteppingMax;
+}
+
+/**
+ Determine if PCH is supported
+
+ @param[in] None
+
+ @retval TRUE PCH is supported
+ @retval FALSE PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+ VOID
+ )
+{
+ UINT16 LpcDeviceId;
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_DEVICE_ID)
+ );
+
+ ///
+ /// Verify that this is a supported chipset
+ ///
+ if (MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_VENDOR_ID)
+ ) != V_PCH_LPC_VENDOR_ID ||
+ !IS_PCH_LPT_LPC_DEVICE_ID (LpcDeviceId)) {
+ DEBUG ((EFI_D_ERROR, "PCH code doesn't support the LpcDeviceId: 0x%04x!\n", LpcDeviceId));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ This function can be called to enable/disable Alternate Access Mode
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+ @param[in] AmeCtrl If TRUE, enable Alternate Access Mode.
+ If FALSE, disable Alternate Access Mode.
+
+ @retval NONE
+**/
+VOID
+EFIAPI
+PchAlternateAccessMode (
+ IN UINTN PchRootComplexBar,
+ IN BOOLEAN AmeCtrl
+ )
+{
+ UINT32 Data32Or;
+ UINT32 Data32And;
+
+ Data32Or = 0;
+ Data32And = 0xFFFFFFFF;
+
+ if (AmeCtrl == TRUE) {
+ ///
+ /// Enable Alternate Access Mode
+ /// Note: The RTC Index field (including the NMI mask at bit7) is write-only
+ /// for normal operation and can only be read in Alt Access Mode.
+ ///
+ Data32Or = (UINT32) (B_PCH_RCRB_GCS_AME);
+ }
+
+ if (AmeCtrl == FALSE) {
+ ///
+ /// Disable Alternate Access Mode
+ ///
+ Data32And = (UINT32) ~(B_PCH_RCRB_GCS_AME);
+ }
+
+ ///
+ /// Program Alternate Access Mode Enable bit
+ ///
+ MmioAndThenOr32 (
+ PchRootComplexBar + R_PCH_RCRB_GCS,
+ Data32And,
+ Data32Or
+ );
+
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32(PchRootComplexBar + R_PCH_RCRB_GCS);
+}
+
+/**
+ Check whether Gbe Region is valid in SPI Flash
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+
+ @retval TRUE Gbe Region is valid
+ @retval FALSE Gbe Region is invalid
+**/
+BOOLEAN
+EFIAPI
+PchIsGbeRegionValid (
+ IN UINTN PchRootComplexBar
+ )
+{
+ ///
+ /// If the GbE region is not used,
+ /// Region Limit of Flash Region 3 (GbE) Register (SPIBAR + 60h[30:16]) must be programmed to 0000h
+ /// Region Base of Flash Region 3 (GbE) Register (SPIBAR + 60h[14:0] ) must be programmed to 7FFFh
+ ///
+ if (PchIsSpiDescriptorMode (PchRootComplexBar) == TRUE) {
+ if (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG3_GBE) == 0x00007FFF) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Check if integrated Gbe controller present
+
+ @param[in] None
+
+ @retval TRUE Integrated Gbe present
+ @retval FALSE Integrated Gbe not present
+**/
+BOOLEAN
+EFIAPI
+PchIsIntegratedGbePresent (
+ IN VOID
+ )
+{
+ UINT32 Softstrap4;
+ UINT32 Softstrap15;
+ BOOLEAN IntegratedGbe;
+
+ ///
+ /// Check if Gbe region is present by reading PCH straps 15 (bit 6) and 4 (bits 1:0)
+ ///
+ MmioAnd32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK))
+ );
+
+ MmioOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP4)
+ );
+
+ Softstrap4 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ MmioAnd32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK))
+ );
+
+ MmioOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP15)
+ );
+
+ Softstrap15 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ ///
+ /// Both values have to be non-zero if integrated phy present
+ ///
+ IntegratedGbe = !!(Softstrap4 & B_PCH_SPI_STRP4_PHYCON) && !!(Softstrap15 & B_PCH_SPI_STRP15_IWL_EN);
+
+ return IntegratedGbe;
+}
+
+/**
+ Return Pch Series
+
+ @param[in] None
+
+ @retval PCH_SERIES Pch Series
+**/
+PCH_SERIES
+EFIAPI
+GetPchSeries (
+ VOID
+ )
+{
+ UINT16 LpcDeviceId;
+ UINT32 PchSeries;
+
+ ///
+ /// Please use PciRead here, it will link to MmioRead
+ /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer
+ /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details.
+ /// For the rest please use EdkIIGlueBasePciLibPciExpress library
+ ///
+ LpcDeviceId = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_DEVICE_ID)
+ );
+
+ if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) {
+ PchSeries = PchH;
+ } else if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) {
+ PchSeries = PchLp;
+ } else {
+ PchSeries = PchUnknownSeries;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", LpcDeviceId));
+ ASSERT (FALSE);
+ }
+
+ return PchSeries;
+}
+
+/**
+ Get Pch Maximum Pcie Root Port Number
+
+ @param[in] None
+
+ @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+EFIAPI
+GetPchMaxPciePortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_PCIE_MAX_ROOT_PORTS;
+
+ case PchH:
+ return LPTH_PCIE_MAX_ROOT_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Sata Port Number
+
+ @param[in] None
+
+ @retval Pch Maximum Sata Port Number
+**/
+UINT8
+EFIAPI
+GetPchMaxSataPortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_AHCI_MAX_PORTS;
+
+ case PchH:
+ return LPTH_AHCI_MAX_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Sata Controller Number
+
+ @param[in] None
+
+ @retval Pch Maximum Sata Controller Number
+**/
+UINT8
+EFIAPI
+GetPchMaxSataControllerNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_SATA_MAX_CONTROLLERS;
+
+ case PchH:
+ return LPTH_SATA_MAX_CONTROLLERS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Usb Port Number of EHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb Port Number of EHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchEhciMaxUsbPortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_EHCI_MAX_PORTS;
+
+ case PchH:
+ return LPTH_EHCI_MAX_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum EHCI Controller Number
+
+ @param[in] None
+
+ @retval Pch Maximum EHCI Controller Number
+**/
+UINT8
+EFIAPI
+GetPchEhciMaxControllerNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_EHCI_MAX_CONTROLLERS;
+
+ case PchH:
+ return LPTH_EHCI_MAX_CONTROLLERS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Usb Maximum Physical Port Number
+
+ @param[in] None
+
+ @retval Pch Usb Maximum Physical Port Number
+**/
+UINT8
+EFIAPI
+GetPchUsbMaxPhysicalPortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_USB_MAX_PHYSICAL_PORTS;
+
+ case PchH:
+ return LPTH_USB_MAX_PHYSICAL_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchXhciMaxUsb2PortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_XHCI_MAX_USB2_PORTS;
+
+ case PchH:
+ return LPTH_XHCI_MAX_USB2_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchXhciMaxUsb3PortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_XHCI_MAX_USB3_PORTS;
+
+ case PchH:
+ return LPTH_XHCI_MAX_USB3_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Query PCH to determine the Pm Status
+
+ @param[in] PmStatus - The Pch Pm Status to be probed
+
+ @retval Return TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+ PCH_PM_STATUS PmStatus
+ )
+{
+ UINT16 PmCon2;
+ UINT16 PmCon3;
+
+ PmCon2 = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GEN_PMCON_2
+ )
+ );
+ PmCon3 = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GEN_PMCON_3
+ )
+ );
+
+ switch(PmStatus){
+ case WarmBoot:
+ if (PmCon2 & B_PCH_LPC_GEN_PMCON_MEM_SR) {
+ return TRUE;
+ }
+ break;
+
+ case PwrFlr:
+ if (PmCon3 & B_PCH_LPC_GEN_PMCON_PWR_FLR) {
+ return TRUE;
+ }
+ break;
+
+ case PwrFlrSys:
+ if (PmCon2 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) {
+ return TRUE;
+ }
+ break;
+
+ case PwrFlrPch:
+ if (PmCon2 & B_PCH_LPC_GEN_PMCON_PWROK_FLR) {
+ return TRUE;
+ }
+ break;
+
+ case ColdBoot:
+ ///
+ /// Check following conditions for cold boot.
+ /// (1)GEN_PMCON_2 (0:31:0 offset 0A2) bit[5] = 0
+ /// (2)GEN_PMCON_2 (0:31:0 offset 0A2) bit[1] = 1
+ /// (3)GEN_PMCON_3 (0:31:0 offset 0A4) bit[1] = 1
+ ///
+ if ((PmCon3 & B_PCH_LPC_GEN_PMCON_PWR_FLR) &&
+ (PmCon2 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) &&
+ (!(PmCon2 & B_PCH_LPC_GEN_PMCON_MEM_SR))) {
+ return TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+/**
+ Get Pch Pcie Root Port Function Number by Root Port Number
+
+ @param[in] UINT8 Root Port Number (start from 0)
+
+ @retval Pch Pcie Root Port Function Number
+**/
+UINT8
+EFIAPI
+GetPchPcieRpfn (
+ IN UINTN PchRootComplexBar,
+ IN UINT8 RpNumber
+ )
+{
+ return ((MmioRead32(PchRootComplexBar + R_PCH_RCRB_RPFN) >> (RpNumber * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN);
+}
+
+/**
+ Get Pch Pcie Root Port Number by Root Port Function Number
+
+ @param[in] UINT8 Root Port Function Number
+
+ @retval Pch Pcie Root Port Number
+ @retval 0xFF No Root Port Number found
+**/
+UINT8
+EFIAPI
+GetPchPcieRpNumber (
+ IN UINTN PchRootComplexBar,
+ IN UINT8 Rpfn
+ )
+{
+ UINT8 PortIndex;
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum(); PortIndex++) {
+ if (((MmioRead32(PchRootComplexBar + R_PCH_RCRB_RPFN) >> (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN) == Rpfn) {
+ return PortIndex;
+ }
+ }
+
+ //Assert if function number not found for a root port
+ ASSERT (FALSE);
+ return 0xff;
+}
+
+
+/**
+ Returns GbE over PCIe port number.
+
+ @return Root port number (0-based)
+ @retval 0xff
+**/
+UINTN
+PchGetGbePortNumber (
+ VOID
+ )
+{
+ UINT32 Softstrap9;
+ UINT32 GbePortSel;
+
+ ///
+ /// Check if Intel PHY Over PCI Express Enable by reading PCH straps 9 (bit 11)
+ ///
+ MmioAnd32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK))
+ );
+
+ MmioOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9)
+ );
+
+ Softstrap9 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ ///
+ /// If Intel PHY Over PCI Express Enable bit is set, return GbE port number
+ ///
+ if (Softstrap9 & B_PCH_SPI_STRP9_GBE_PCIE_EN) {
+ GbePortSel = (Softstrap9 & B_PCH_SPI_STRP9_GBE_PCIE_PSC) >> N_PCH_SPI_STRP9_GBE_PCIE_PSC;
+ DEBUG ((EFI_D_INFO, "GbePortSel=%d\n", GbePortSel));
+ if (GetPchSeries () == PchLp) {
+ switch (GbePortSel) {
+ case 0: return 2; // Root Port 3
+ case 1: return 3; // Root Port 4
+ case 2: // Root Port 5, lane 0
+ case 3: // Root Port 5, lane 1
+ case 4: // Root Port 5, lane 2
+ case 5: // Root Port 5, lane 3
+ return 4;
+ default:
+ ASSERT (FALSE);
+ }
+ } else {
+ return GbePortSel;
+ }
+ }
+
+ return 0xff;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h
new file mode 100644
index 0000000..0eec474
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h
@@ -0,0 +1,29 @@
+/** @file
+ Header file for PCH Platform Lib implementation.
+
+@copyright
+ Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+**/
+#ifndef _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "Library/EdkIIGlueMemoryAllocationLib.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif
new file mode 100644
index 0000000..c6371c9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif
@@ -0,0 +1,8 @@
+<component>
+ name = "PchSmbusComLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Common\"
+ RefName = "PchSmbusComLib"
+[files]
+"PchSmbusLib.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c
new file mode 100644
index 0000000..dcb46e2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c
@@ -0,0 +1,54 @@
+/** @file
+ This file contains routines that support PCH SMBUS FUNCTION
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchSmbusLib.h"
+
+/**
+ This function provides a standard way to execute Smbus sequential
+ I2C Read. This function allows the PCH to perform block reads to
+ certain I2C devices, such as serial E2PROMs. Typically these data
+ bytes correspond to an offset (address) within the serial memory
+ chips.
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Buffer Pointer to the buffer to store the bytes read
+ from the SMBUS
+ @param[out] Status eturn status for the executed command.
+
+ @retval UINTN The number of bytes read
+**/
+UINTN
+EFIAPI
+SmBusSeqI2CRead (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS * Status OPTIONAL
+ )
+{
+ UINTN Length;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+ ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);
+
+ Length = SMBUS_LIB_LENGTH (SmBusAddress);
+ return InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, Length, Buffer, Status);
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif
new file mode 100644
index 0000000..b1b49b0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "PchSmbusDxeLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Dxe\"
+ RefName = "PchSmbusDxeLib"
+[files]
+"PchSmbusLib.h"
+"PchSmbusLibDxe.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h
new file mode 100644
index 0000000..64c639d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h
@@ -0,0 +1,25 @@
+/** @file
+ Header file for PCH Smbus DXE Lib implementation.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+**/
+#ifndef _PCH_SMBUS_DXE_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_SMBUS_DXE_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "DxeSmbusLibInternal.h"
+#endif
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf
new file mode 100644
index 0000000..57c7e50
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf
@@ -0,0 +1,63 @@
+## @file
+# Component description file for DXE PCH Smbus Lib
+#
+#@copyright
+# Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchSmbusLibDxe
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ ../Common/PchSmbusLib.c
+
+[sources.ia32]
+
+[sources.x64]
+
+[sources.ipf]
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Library/DxeSmbusLib
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[libraries.common]
+
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif
new file mode 100644
index 0000000..3263fa9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\"
+ RefName = "PchSmbusLib"
+[files]
+"PchSmbusLib.sdl"
+"PchSmbusLib.mak"
+"Common\PchSmbusComLib.cif"
+"Common\PchSmbusLib.c"
+[parts]
+"PchSmbusDxeLib"
+"PchSmbusPeiLib"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak
new file mode 100644
index 0000000..35a4d8e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak
@@ -0,0 +1,74 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchSmbusLib/PchSmbusLib.mak 1 2/08/12 8:49a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:49a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchSmbusLib/PchSmbusLib.mak $
+#
+# 1 2/08/12 8:49a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchSmbusLib
+
+$(PchSmbusLib_LIB) : PchSmbusLib
+
+PchSmbusLib : $(BUILD_DIR)\PchSmbusLib.mak PchSmbusLibBin
+
+$(BUILD_DIR)\PchSmbusLib.mak : $(PchSmbusLib_DIR)\$(@B).cif $(PchSmbusLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusPeiLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ /I$(EdkIIGluePeiSmbusLib_DIR)\
+ /I$(PchSmbusLib_DIR)\Pei\
+
+PchSmbusDxeLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ /I$(EdkIIGlueDxeSmbusLib_DIR)\
+ /I$(PchSmbusLib_DIR)\Dxe\
+
+PchSmbusLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusLib.mak all\
+ "MY_INCLUDES=$(PchSmbusDxeLib_INCLUDES)" \
+ TYPE=LIBRARY
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\PchSmbusLib.mak all\
+ "MY_INCLUDES=$(PchSmbusPeiLib_INCLUDES)" \
+ TYPE=PEI_LIBRARY
+!ENDIF
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl
new file mode 100644
index 0000000..4f41e9a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl
@@ -0,0 +1,59 @@
+TOKEN
+ Name = "PchSmbusLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmbusLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchSmbusLib.mak to Project"
+ File = "PchSmbusLib.mak"
+End
+
+ELINK
+ Name = "PchSmbusDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PchSmbusPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+TOKEN
+ Name = "PchSmbusLib_LIB"
+ Value = "$$(LIB_BUILD_DIR)\PchSmbusLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+ELINK
+ Name = "$(PchSmbusLib_LIB)"
+ Parent = "PchSmbusDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(EdkIIGlueDxeSmbusLib_LIB)"
+ Parent = "PchSmbusDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PchSmbusLib_LIB)"
+ Parent = "PchSmbusPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(EdkIIGluePeiSmbusLib_LIB)"
+ Parent = "PchSmbusPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h
new file mode 100644
index 0000000..b169af6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h
@@ -0,0 +1,25 @@
+/** @file
+ Header file for PCH Smbus PEI Lib implementation.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+**/
+#ifndef _PCH_SMBUS_PEI_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_SMBUS_PEI_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "PeiSmbusLibInternal.h"
+#endif
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf
new file mode 100644
index 0000000..e533165
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf
@@ -0,0 +1,64 @@
+## @file
+# Component description file for PEI PCH Smbus Lib
+#
+#@copyright
+# Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchSmbusLibPei
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ ../Common/PchSmbusLib.c
+
+[sources.ia32]
+
+[sources.x64]
+
+[sources.ipf]
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Library/PeiSmbusLib
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[libraries.common]
+
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif
new file mode 100644
index 0000000..22aba6f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "PchSmbusPeiLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Pei\"
+ RefName = "PchSmbusPeiLib"
+[files]
+"PchSmbusLib.h"
+"PchSmbusLibPei.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c
new file mode 100644
index 0000000..e97d65b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c
@@ -0,0 +1,225 @@
+/** @file
+ Firmware Version Info Interface Lib implementation.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "RcFviLib.h"
+
+EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;
+
+/**
+ Initialize callback context for Firmware Version Info (FVI) Interface Spec v0.7
+ implementation.
+
+ @param[in] String The pointer to the string for calculating length
+
+ @retval None
+**/
+UINT32
+GetStringLen (
+ IN UINT8 *String
+ )
+{
+ UINT8 Length;
+
+ for (Length = 0; *String != 0; String++, Length++) {
+ if (Length >= SMBIOS_STRING_MAX_LENGTH) {
+ break;
+ }
+ }
+
+ return (UINT32) (Length + 1);
+}
+
+/**
+ Initialize callback context for Firmware Version Info (FVI) Interface Spec v0.7
+ implementation.
+
+ @param[in] Type Value is defined in SMBIOS Type 14 - Group Associaction structure - item type.
+ @param[in] Count Number of elements included by this SMBIOS table
+ @param[in] FviContext Context of FVI elements for data hub log
+
+ @retval None
+**/
+VOID
+InitFviDataHubCbContext (
+ IN UINT8 Type,
+ IN UINT8 Count,
+ IN FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext
+ )
+{
+ ///
+ /// Locate the Data hub protocol
+ ///
+ if (mDataHub == NULL) {
+ gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **)&mDataHub);
+ }
+
+ if (FviContext != NULL) {
+ FviContext->FviHeader.FviHdr.Header.Type = Type;
+ FviContext->FviHeader.FviHdr.Count = Count;
+ FviContext->FviHeader.FviHdr.Header.Length = sizeof (FVI_HEADER) + FVI_ELEMENTS_SIZE_NOSTRING * Count;
+ } else {
+ ASSERT (FALSE);
+ }
+
+ return ;
+}
+
+/**
+ Create the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ to Data Hub.
+
+ @param[in] FviContext Pointer to the notification functions context, which is context of FVI
+ elements for data hub log
+
+ @retval None
+**/
+VOID
+CreateRcFviDatahub (
+ IN FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext
+ )
+{
+ VOID *Registration;
+
+ if (mDataHub == NULL) {
+ EfiCreateProtocolNotifyEvent (
+ &gEfiDataHubProtocolGuid,
+ EFI_TPL_CALLBACK,
+ DataHubCallback,
+ (VOID *) FviContext,
+ &Registration
+ );
+ } else {
+ DataHubCallback ((EFI_EVENT) NULL, (VOID *) FviContext);
+ }
+}
+
+/**
+ Publish the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ using MiscSubClass Data Hub.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification functions context, which is implementation dependent.
+
+ @retval None
+**/
+VOID
+EFIAPI
+DataHubCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext;
+ UINT8 Index;
+ UINT8 StrIndex;
+ UINT8 *Record;
+ UINT8 *LastRecord;
+ UINT8 *String;
+ UINT8 Count;
+ UINT32 Length;
+ FVI_ELEMENT_AND_FUNCTION *NewElement;
+
+ Status = EFI_SUCCESS;
+ if (mDataHub == NULL) {
+ Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **)&mDataHub);
+ }
+
+ if ((mDataHub != NULL) && (Context != NULL)) {
+
+ if (Event != NULL) {
+ gBS->CloseEvent (Event);
+ }
+
+ FviContext = (FVI_DATA_HUB_CALLBACK_CONTEXT *) Context;
+ Count = FviContext->FviHeader.FviHdr.Count;
+
+ ///
+ /// Allocate a buffer to record data sorted later
+ ///
+ Length = sizeof (MISC_SUBCLASS_FVI_HEADER) + (sizeof (FVI_ELEMENTS) * Count);
+
+ Status = EFI_OUT_OF_RESOURCES;
+ Record = (UINT8 *) AllocateZeroPool (Length);
+ if (Record != NULL) {
+ LastRecord = Record;
+
+ ///
+ /// Copy the headers including Data Hub and SMBIOS FviSmbios OEM type
+ ///
+ CopyMem (LastRecord, &(FviContext->FviHeader), sizeof (MISC_SUBCLASS_FVI_HEADER));
+ LastRecord += sizeof (MISC_SUBCLASS_FVI_HEADER);
+ String = LastRecord + FVI_ELEMENTS_SIZE_NOSTRING * Count;
+
+ NewElement = FviContext->Elements;
+
+ ///
+ /// Copy elements including strings
+ ///
+ for (Index = 0, StrIndex = 1; Index < Count; Index++) {
+ if (NewElement->Function != NULL) {
+ NewElement->Function (&(NewElement->Element));
+ }
+
+ ///
+ /// If string is implemented for ComponentName or VersionString, and then string
+ /// index of ComponentName or VersionString can't be zero. The string index of
+ /// ComponentName and VersionString will be updated and calculated while analyse
+ /// all elements here.String index must be non-zero if implemented.
+ ///
+ if (NewElement->Element.ComponentName != 0) {
+ NewElement->Element.ComponentName = StrIndex;
+ Length = GetStringLen (NewElement->Element.NameString);
+ CopyMem (String, &(NewElement->Element.NameString), Length);
+ String += Length;
+ StrIndex++;
+ }
+
+ if (NewElement->Element.VersionString != 0) {
+ NewElement->Element.VersionString = StrIndex;
+ Length = GetStringLen (NewElement->Element.VerString);
+ CopyMem (String, &(NewElement->Element.VerString), Length);
+ String += Length;
+ StrIndex++;
+ }
+
+ CopyMem (LastRecord, &(NewElement->Element), FVI_ELEMENTS_SIZE_NOSTRING);
+ LastRecord += FVI_ELEMENTS_SIZE_NOSTRING;
+
+ NewElement++;
+ }
+
+ Length = (UINT32) (String - Record) + 1;
+ Status = mDataHub->LogData (
+ mDataHub,
+ &gMiscSubClassName,
+ &gMiscProducerGuid,
+ EFI_DATA_RECORD_CLASS_DATA,
+ (VOID *) Record,
+ Length
+ );
+ }
+
+ ASSERT (!EFI_ERROR (Status));
+ if (Record != NULL) {
+ FreePool (Record);
+ }
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif
new file mode 100644
index 0000000..57f9263
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "RcFviDxeLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\RcFviDxeLib"
+ RefName = "RcFviDxeLib"
+[files]
+"RcFviDxeLib.sdl"
+"RcFviDxeLib.mak"
+"CreateFviLibrary.c"
+"RcFviLib.h"
+"RcFviDxeLib.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf
new file mode 100644
index 0000000..ad9f04c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf
@@ -0,0 +1,67 @@
+## @file
+# Component description file for the PchRcFviDxeLib
+#
+#@copyright
+# Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = RcFviDxeLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ CreateFviLibrary.c
+
+[sources.ia32]
+
+
+[sources.x64]
+
+
+[sources.ipf]
+
+
+[sources.ebc]
+
+
+[includes.common]
+ .
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkFrameworkProtocolLib
+[libraries.ia32]
+
+
+[libraries.x64]
+
+
+[nmake.common] \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak
new file mode 100644
index 0000000..4e8a698
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak
@@ -0,0 +1,69 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/RcFviDxeLib/RcFviDxeLib.mak 1 2/08/12 8:50a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:50a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/RcFviDxeLib/RcFviDxeLib.mak $
+#
+# 1 2/08/12 8:50a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#
+#*************************************************************************
+all : RcFviDxeLib
+
+$(RcFviDxeLib_LIB) : RcFviDxeLib
+
+RcFviDxeLib : $(BUILD_DIR)\RcFviDxeLib.mak RcFviDxeLibBin
+
+$(BUILD_DIR)\RcFviDxeLib.mak : $(RcFviDxeLib_DIR)\$(@B).cif $(RcFviDxeLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(RcFviDxeLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+RcFviDxeLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+RcFviDxeLib_LIB_LINKS =\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+
+RcFviDxeLibBin:
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\RcFviDxeLib.mak all \
+ "MY_INCLUDES=$(RcFviDxeLib_INCLUDES)" \
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(RcFviDxeLib_LIB)
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl
new file mode 100644
index 0000000..15c1fd4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl
@@ -0,0 +1,73 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/RcFviDxeLib/RcFviDxeLib.sdl 1 2/08/12 8:50a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:50a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/RcFviDxeLib/RcFviDxeLib.sdl $
+#
+# 1 2/08/12 8:50a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#
+#*************************************************************************
+TOKEN
+ Name = "RcFviDxeLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable RcFviDxeLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "RcFviDxeLib_DIR"
+End
+
+MODULE
+ File = "RcFviDxeLib.mak"
+ Help = "Includes RcFviDxeLib.mak to Project"
+End
+
+ELINK
+ Name = "RcFviDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\RcFviDxeLib_Lib.lib"
+ Parent = "RcFviDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h
new file mode 100644
index 0000000..70a5556
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h
@@ -0,0 +1,49 @@
+/** @file
+ Header file for Reference code Firmware Version Info Interface Lib implementation.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+**/
+#ifndef _RC_FVI_LIBRARY_IMPLEMENTATION_H_
+#define _RC_FVI_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "EdkIIGlueDxe.h"
+#include "Library/EdkIIGlueMemoryAllocationLib.h"
+
+#include EFI_GUID_DEFINITION (DataHubRecords)
+#include EFI_PROTOCOL_CONSUMER (DataHub)
+
+#include "RcFviDxeLib.h"
+
+#endif
+
+/**
+ Publish the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ using MiscSubClass Data Hub.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification functions context, which is implementation dependent.
+
+ @retval None
+**/
+VOID
+EFIAPI
+DataHubCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+#endif