summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/Smbus
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/Smbus
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/Smbus')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h190
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak124
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c661
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs40
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h360
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c681
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf93
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c149
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h409
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c444
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf88
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c291
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif15
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf91
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c117
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c241
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs41
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h183
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c128
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf95
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak105
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl67
35 files changed, 5403 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h
new file mode 100644
index 0000000..35cf2e5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h
@@ -0,0 +1,190 @@
+/** @file
+ PCH Smbus Protocol
+
+@copyright
+ Copyright (c) 2004 - 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
+**/
+#ifndef _PCH_SMBUS_COMMON_H
+#define _PCH_SMBUS_COMMON_H
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "EfiSmbus.h"
+
+#endif
+//
+// Definitions
+//
+#define STALL_PERIOD 10 * STALL_ONE_MICRO_SECOND ///< 10 microseconds
+#define STALL_TIME STALL_ONE_SECOND ///< 1 second
+#define BUS_TRIES 3 ///< How many times to retry on Bus Errors
+#define SMBUS_NUM_RESERVED 38 ///< Number of device addresses that are reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP 0xC2 >> 1
+#define SMBUS_DATA_PREPARE_TO_ARP 0x01
+#define SMBUS_DATA_RESET_DEVICE 0x02
+#define SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define SMBUS_DATA_ASSIGN_ADDRESS 0x04
+#define SMBUS_GET_UDID_LENGTH 17 ///< 16 byte UDID + 1 byte address
+//
+// Private data and functions
+//
+
+typedef
+UINT8
+(EFIAPI *SMBUS_IO_READ) (
+ IN UINT8 Offset
+ );
+
+typedef
+VOID
+(EFIAPI *SMBUS_IO_WRITE) (
+ IN UINT8 Offset,
+ IN UINT8 Data
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *SMBUS_IO_DONE) (
+ IN UINT8 *StsReg
+ );
+
+#define PCH_SMBUS_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('p', 's', 'm', 'b')
+
+/**
+ Get SMBUS IO Base address
+
+ @param[in] None
+
+ @retval UINT32 The SMBUS IO Base Address
+**/
+UINT32
+SmbusGetIoBase (
+ VOID
+ );
+
+/**
+ This function provides a standard way to read PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+
+ @retval UINT8 Returns data read from IO.
+**/
+UINT8
+EFIAPI
+SmbusIoRead (
+ IN UINT8 Offset
+ );
+
+/**
+ This function provides a standard way to write PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+ @param[in] Data Data to write to register.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+SmbusIoWrite (
+ IN UINT8 Offset,
+ IN UINT8 Data
+ );
+
+/**
+ This function provides a standard way to check if an SMBus transaction has
+ completed.
+
+ @param[in] StsReg Not used for input. On return, contains the
+ value of the SMBus status register.
+
+ @retval TRUE Transaction is complete
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+IoDone (
+ IN UINT8 *StsReg
+ );
+
+/**
+ Check if it's ok to use the bus.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS SmBus is acquired and it's safe to send commands.
+ @retval EFI_TIMEOUT SmBus is busy, it's not safe to send commands.
+**/
+EFI_STATUS
+AcquireBus (
+ VOID
+ );
+
+/**
+ This function provides a standard way to execute Smbus protocols
+ as defined in the SMBus Specification. The data can either be of
+ the Length byte, word, or a block of data. The resulting transaction will be
+ either the SMBus Slave Device accepts this transaction or this function
+ returns with an error
+
+ @param[in] SlaveAddress Smbus Slave device the command is directed at
+ @param[in] Command Slave Device dependent
+ @param[in] Operation Which SMBus protocol will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read. Must be 0 <= Length <= 32 depending on Operation
+ It will contain the actual number of bytes read/written.
+ @param[in, out] Buffer Contain the data read/written.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @exception EFI_UNSUPPORTED The operation is unsupported.
+
+ @retval EFI_INVALID_PARAMETER Length or Buffer is NULL for any operation besides
+ quick read or quick write.
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period, or the controller is not
+ available for use.
+ @retval EFI_DEVICE_ERROR There was an Smbus error (NACK) during the operation.
+ This could indicate the slave device is not present
+ or is in a hung condition.
+**/
+EFI_STATUS
+SmbusExec (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ This function initializes the Smbus Registers.
+
+ @param[in] None.
+
+ @retval None.
+**/
+VOID
+InitializeSmbusRegisters (
+ VOID
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif
new file mode 100644
index 0000000..e62b886
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PchSmbusCommonLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Common"
+ RefName = "PchSmbusCommonLib"
+[files]
+"PchSmbusCommonLib.sdl"
+"PchSmbusCommonLib.mak"
+"PchSmbusExec.c"
+"PchSmbusCommon.h"
+<endComponent> \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak
new file mode 100644
index 0000000..2eb1277
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak
@@ -0,0 +1,124 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusCommonLib/PchSmbusCommonLib.mak 1 2/08/12 9:18a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:18a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusCommonLib/PchSmbusCommonLib.mak $
+#
+# 1 2/08/12 9:18a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchSmbusCommonLib
+
+PchSmbusCommonLib : PchSmbusCommonDxeLib PchSmbusCommonSmmLib PchSmbusCommonPeiLib
+
+$(PchSmbusCommonSmmLib_LIB) : PchSmbusCommonSmmLib
+$(PchSmbusCommonDxeLib_LIB) : PchSmbusCommonDxeLib
+$(PchSmbusCommonPeiLib_LIB) : PchSmbusCommonPeiLib
+
+PchSmbusCommonSmmLib : $(BUILD_DIR)\PchSmbusCommonLib.mak PchSmbusCommonLibSmmBin
+
+PchSmbusCommonDxeLib : $(BUILD_DIR)\PchSmbusCommonLib.mak PchSmbusCommonLibDxeBin
+
+PchSmbusCommonPeiLib : $(BUILD_DIR)\PchSmbusCommonLib.mak PchSmbusCommonLibPeiBin
+
+$(BUILD_DIR)\PchSmbusCommonLib.mak : $(PchSmbusCommonLib_DIR)\$(@B).cif $(PchSmbusCommonLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusCommonLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchSmbusCommonLibSmm_INCLUDES=\
+ $(PchSmbusCommonLib_INCLUDES)
+
+PchSmbusCommonLibDxe_INCLUDES=\
+ $(PchSmbusCommonLib_INCLUDES)
+
+PchSmbusCommonLibPeim_INCLUDES=\
+ $(PchSmbusCommonLib_INCLUDES)
+
+PchSmbusCommonLib_DEFINES = \
+ $(CFLAGS)
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+PeimCpuBuildDefine = \
+ /DMDE_CPU_IA32\
+
+PchSmbusCommonLibPeim_DEFINES = \
+ $(PchSmbusCommonLib_DEFINES)\
+ $(PeimCpuBuildDefine)\
+
+PchSmbusCommonLibDxe_DEFINES = \
+ $(PchSmbusCommonLib_DEFINES)\
+ $(DxeCpuBuildDefine)\
+
+PchSmbusCommonLibSmm_DEFINES = \
+ $(PchSmbusCommonLibDxe_DEFINES)\
+
+PchSmbusCommonLibDxeBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchSmbusCommonLib.mak all\
+ "MY_INCLUDES=$(PchSmbusCommonLibDxe_INCLUDES)" \
+ "CFLAGS=$(PchSmbusCommonLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(PchSmbusCommonDxeLib_LIB)
+
+PchSmbusCommonLibSmmBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchSmbusCommonLib.mak all\
+ "MY_INCLUDES=$(PchSmbusCommonLibSmm_INCLUDES)" \
+ "CFLAGS=$(PchSmbusCommonLibSmm_DEFINES)"\
+ TYPE=LIBRARY \
+ BUILD_DIR=$(BUILD_DIR)\Smm\
+ LIBRARY_NAME=$(PchSmbusCommonSmmLib_LIB)
+
+PchSmbusCommonLibPeiBin :
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32 \
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+!ENDIF
+ /f $(BUILD_DIR)\PchSmbusCommonLib.mak all\
+ "MY_INCLUDES=$(PchSmbusCommonLibPeim_INCLUDES)" \
+ "CFLAGS=$(PchSmbusCommonLibPeim_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(PchSmbusCommonPeiLib_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/Smbus/Common/PchSmbusCommonLib.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl
new file mode 100644
index 0000000..7785408
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl
@@ -0,0 +1,92 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusCommonLib/PchSmbusCommonLib.sdl 1 2/08/12 9:18a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:18a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusCommonLib/PchSmbusCommonLib.sdl $
+#
+# 1 2/08/12 9:18a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusCommonLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmbusCommonLib support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusCommonLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchSmbusCommonLib.mak to Project"
+ File = "PchSmbusCommonLib.mak"
+End
+
+ELINK
+ Name = "PchSmbusCommonDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusCommonDxeLib.lib"
+ Parent = "PchSmbusCommonDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchSmbusCommonPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusCommonPeiLib.lib"
+ Parent = "PchSmbusCommonPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchSmbusCommonSmmLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusCommonSmmLib.lib"
+ Parent = "PchSmbusCommonSmmLib_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/Smbus/Common/PchSmbusExec.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c
new file mode 100644
index 0000000..4015dda
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c
@@ -0,0 +1,661 @@
+/** @file
+ PCH Smbus Executive Code (common PEI/DXE/SMM code)
+
+@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 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 "PchSmbusCommon.h"
+
+/**
+ Get SMBUS IO Base address
+
+ @param[in] None
+
+ @retval UINT32 The SMBUS IO Base Address
+**/
+UINT32
+SmbusGetIoBase (
+ VOID
+ )
+{
+ UINT32 SmbusIoBase;
+
+ SmbusIoBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ R_PCH_SMBUS_BASE)
+ ) & B_PCH_SMBUS_BASE_BAR;
+
+ ASSERT (SmbusIoBase != B_PCH_SMBUS_BASE_BAR && SmbusIoBase != 0);
+
+ return SmbusIoBase;
+}
+
+/**
+ This function provides a standard way to read PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+
+ @retval UINT8 Returns data read from IO.
+**/
+UINT8
+EFIAPI
+SmbusIoRead (
+ IN UINT8 Offset
+ )
+{
+ return IoRead8 (SmbusGetIoBase () + Offset);
+}
+
+/**
+ This function provides a standard way to write PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+ @param[in] Data Data to write to register.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+SmbusIoWrite (
+ IN UINT8 Offset,
+ IN UINT8 Data
+ )
+{
+ ///
+ /// Write New Value
+ ///
+ IoWrite8 (SmbusGetIoBase () + Offset, Data);
+ return;
+}
+
+/**
+ This function provides a standard way to check if an SMBus transaction has
+ completed.
+
+ @param[in] StsReg Not used for input. On return, contains the
+ value of the SMBus status register.
+
+ @retval TRUE Transaction is complete
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+IoDone (
+ IN UINT8 *StsReg
+ )
+{
+ ///
+ /// Wait for IO to complete
+ ///
+ UINTN StallIndex;
+ UINTN StallTries;
+
+ StallTries = STALL_TIME / STALL_PERIOD;
+
+ for (StallIndex = 0; StallIndex < StallTries; StallIndex++) {
+ *StsReg = SmbusIoRead (R_PCH_SMBUS_HSTS);
+ if (*StsReg & (B_PCH_SMBUS_INTR | B_PCH_SMBUS_BYTE_DONE_STS | B_PCH_SMBUS_DERR | B_PCH_SMBUS_BERR)) {
+ return TRUE;
+ } else {
+ PchPmTimerStall (STALL_PERIOD);
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Check if it's ok to use the bus.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS SmBus is acquired and it's safe to send commands.
+ @retval EFI_TIMEOUT SmBus is busy, it's not safe to send commands.
+**/
+EFI_STATUS
+AcquireBus (
+ VOID
+ )
+{
+ UINT8 StsReg;
+
+ StsReg = 0;
+ StsReg = SmbusIoRead (R_PCH_SMBUS_HSTS);
+ if (StsReg & B_PCH_SMBUS_IUS) {
+ return EFI_TIMEOUT;
+ } else if (StsReg & B_PCH_SMBUS_HBSY) {
+ ///
+ /// Clear Status Register and exit
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ return EFI_TIMEOUT;
+ } else {
+ ///
+ /// Clear out any odd status information (Will Not Clear In Use)
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, StsReg);
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ This function provides a standard way to execute Smbus protocols
+ as defined in the SMBus Specification. The data can either be of
+ the Length byte, word, or a block of data. The resulting transaction will be
+ either the SMBus Slave Device accepts this transaction or this function
+ returns with an error
+
+ @param[in] SlaveAddress Smbus Slave device the command is directed at
+ @param[in] Command Slave Device dependent
+ @param[in] Operation Which SMBus protocol will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read. Must be 0 <= Length <= 32 depending on Operation
+ It will contain the actual number of bytes read/written.
+ @param[in, out] Buffer Contain the data read/written.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @exception EFI_UNSUPPORTED The operation is unsupported.
+
+ @retval EFI_INVALID_PARAMETER Length or Buffer is NULL for any operation besides
+ quick read or quick write.
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period, or the controller is not
+ available for use.
+ @retval EFI_DEVICE_ERROR There was an Smbus error (NACK) during the operation.
+ This could indicate the slave device is not present
+ or is in a hung condition.
+**/
+EFI_STATUS
+SmbusExec (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 AuxcReg;
+ UINT8 AuxStsReg;
+ UINT8 SmbusOperation;
+ UINT8 StsReg;
+ UINT8 SlvAddrReg;
+ UINT8 HostCmdReg;
+ UINT8 BlockCount;
+ BOOLEAN BufferTooSmall;
+ UINTN Index;
+ UINTN BusIndex;
+ UINT8 *CallBuffer;
+ UINT8 SmbusHctl;
+ UINT32 Timeout;
+
+ CallBuffer = Buffer;
+ BlockCount = 0;
+
+ ///
+ /// For any operations besides quick read & write, the pointers to
+ /// Length and Buffer must not be NULL.
+ ///
+ if ((Operation != EfiSmbusQuickRead) && (Operation != EfiSmbusQuickWrite)) {
+ if ((Length == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ ///
+ /// See if its ok to use the bus based upon INUSE_STS bit.
+ ///
+ Status = AcquireBus ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// This is the main operation loop. If the operation results in a Smbus
+ /// collision with another master on the bus, it attempts the requested
+ /// transaction again at least BUS_TRIES attempts.
+ ///
+ for (BusIndex = 0; BusIndex < BUS_TRIES; BusIndex++) {
+ ///
+ /// Operation Specifics (pre-execution)
+ ///
+ Status = EFI_SUCCESS;
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_QUICK;
+ SlvAddrReg = (UINT8) ((SlaveAddress.SmbusDeviceAddress << 1) | 1);
+ HostCmdReg = (UINT8) Command;
+ AuxcReg = 0;
+
+ switch (Operation) {
+
+ case EfiSmbusQuickWrite:
+ SlvAddrReg--;
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusQuickRead:
+ if (PecCheck == TRUE) {
+ Status = EFI_UNSUPPORTED;
+ }
+ break;
+
+ case EfiSmbusSendByte:
+ HostCmdReg = CallBuffer[0];
+ SlvAddrReg--;
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusReceiveByte:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE;
+ if (*Length < 1) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 1;
+ break;
+
+ case EfiSmbusWriteByte:
+ SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]);
+ SlvAddrReg--;
+ *Length = 1;
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusReadByte:
+ if (*Length < 1) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else if (*Length == 1) {
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
+ } else if (*Length <= 256) {
+ if (PecCheck == TRUE) {
+ ///
+ /// The I2C Read command with either PEC_EN or AAC bit set
+ /// produces undefined results.
+ ///
+ Status = EFI_UNSUPPORTED;
+ }
+
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_IIC_READ;
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ break;
+
+ case EfiSmbusReadWord:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_WORD_DATA;
+ if (*Length < 2) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 2;
+ break;
+
+ case EfiSmbusWriteWord:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_WORD_DATA;
+ SlvAddrReg--;
+ SmbusIoWrite (R_PCH_SMBUS_HD1, CallBuffer[1]);
+ SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]);
+ if (*Length < 2) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 2;
+ break;
+
+ case EfiSmbusWriteBlock:
+ SmbusIoWrite (R_PCH_SMBUS_HD0, *(UINT8 *) Length);
+ SlvAddrReg--;
+ BlockCount = (UINT8) (*Length);
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusReadBlock:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
+ if ((*Length < 1) || (*Length > 32)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ AuxcReg |= B_PCH_SMBUS_E32B;
+ break;
+
+ case EfiSmbusProcessCall:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_PROCESS_CALL;
+ SmbusIoWrite (R_PCH_SMBUS_HD1, CallBuffer[1]);
+ SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]);
+ if (*Length < 2) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 2;
+ break;
+
+ case EfiSmbusBWBRProcessCall:
+ ///
+ /// The write byte count cannot be zero or more than
+ /// 32 bytes.
+ ///
+ if ((*Length < 1) || (*Length > 32)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ SmbusIoWrite (R_PCH_SMBUS_HD0, *(UINT8 *) Length);
+ BlockCount = (UINT8) (*Length);
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS;
+
+ AuxcReg |= B_PCH_SMBUS_E32B;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (PecCheck == TRUE) {
+ AuxcReg |= B_PCH_SMBUS_AAC;
+ }
+ ///
+ /// Set Auxiliary Control register
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_AUXC, AuxcReg);
+
+ ///
+ /// Reset the pointer of the internal buffer
+ ///
+ SmbusIoRead (R_PCH_SMBUS_HCTL);
+
+ ///
+ /// Now that the 32 byte buffer is turned on, we can write th block data
+ /// into it
+ ///
+ if ((Operation == EfiSmbusWriteBlock) || (Operation == EfiSmbusBWBRProcessCall)) {
+ for (Index = 0; Index < BlockCount; Index++) {
+ ///
+ /// Write next byte
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HBD, CallBuffer[Index]);
+ }
+ }
+ ///
+ /// Set SMBus slave address for the device to send/receive from
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_TSA, SlvAddrReg);
+
+ ///
+ /// For I2C read, send DATA1 register for the offset (address)
+ /// within the serial memory chips
+ ///
+ if ((Operation == EfiSmbusReadByte) && (*Length > 1)) {
+ SmbusIoWrite (R_PCH_SMBUS_HD1, HostCmdReg);
+ } else {
+ ///
+ /// Set Command register
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HCMD, HostCmdReg);
+ }
+ ///
+ /// Set Control Register (Initiate Operation, Interrupt disabled)
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));
+
+ ///
+ /// Wait for IO to complete
+ ///
+ if (!IoDone (&StsReg)) {
+ Status = EFI_TIMEOUT;
+ break;
+ } else if (StsReg & B_PCH_SMBUS_DERR) {
+ AuxStsReg = SmbusIoRead (R_PCH_SMBUS_AUXS);
+ if (AuxStsReg & B_PCH_SMBUS_CRCE) {
+ Status = EFI_CRC_ERROR;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ break;
+ } else if (StsReg & B_PCH_SMBUS_BERR) {
+ ///
+ /// Clear the Bus Error for another try
+ ///
+ Status = EFI_DEVICE_ERROR;
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+ ///
+ /// Clear Status Registers
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ SmbusIoWrite (R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+ ///
+ /// If bus collision happens, stall some time, then try again
+ /// Here we choose 10 milliseconds to avoid MTCP transfer.
+ ///
+ PchPmTimerStall (STALL_PERIOD);
+ continue;
+ }
+ ///
+ /// successfull completion
+ /// Operation Specifics (post-execution)
+ ///
+ switch (Operation) {
+
+ case EfiSmbusReadWord:
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusProcessCall:
+ CallBuffer[1] = SmbusIoRead (R_PCH_SMBUS_HD1);
+ CallBuffer[0] = SmbusIoRead (R_PCH_SMBUS_HD0);
+ break;
+
+ case EfiSmbusReadByte:
+ if (*Length > 1) {
+ for (Index = 0; Index < *Length; Index++) {
+ ///
+ /// Read the byte
+ ///
+ CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD);
+ ///
+ /// After receiving byte n-1 (1-base) of the message, the
+ /// software will then set the LAST BYTE bit. The software
+ /// will then clear the BYTE_DONE_STS bit.
+ ///
+ if (Index == ((*Length - 1) - 1)) {
+ SmbusHctl = SmbusIoRead (R_PCH_SMBUS_HCTL) | (UINT8) B_PCH_SMBUS_LAST_BYTE;
+ SmbusIoWrite (R_PCH_SMBUS_HCTL, SmbusHctl);
+ } else if (Index == (*Length - 1)) {
+ ///
+ /// Clear the LAST BYTE bit after receiving byte n (1-base) of the message
+ ///
+ SmbusHctl = SmbusIoRead (R_PCH_SMBUS_HCTL) & (UINT8) ~B_PCH_SMBUS_LAST_BYTE;
+ SmbusIoWrite (R_PCH_SMBUS_HCTL, SmbusHctl);
+ }
+ ///
+ /// Clear the BYTE_DONE_STS bit
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
+ ///
+ /// Check BYTE_DONE_STS bit to know if it has completed transmission
+ /// of a byte. No need to check it for the last byte.
+ ///
+ if (Index < (*Length - 1)) {
+ ///
+ /// If somehow board operates at 10Khz, it will take 0.9 ms (9/10Khz) for another byte.
+ /// Add 10 us delay for a loop of 100 that the total timeout is 1 ms to take care of
+ /// the slowest case.
+ ///
+ for (Timeout = 0; Timeout < 100; Timeout++) {
+ if ((SmbusIoRead (R_PCH_SMBUS_HSTS) & (UINT8) B_PCH_SMBUS_BYTE_DONE_STS) != 0) {
+ break;
+ }
+ ///
+ /// Delay 10 us
+ ///
+ PchPmTimerStall (STALL_PERIOD);
+ }
+
+ if (Timeout >= 100) {
+ Status = EFI_TIMEOUT;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case EfiSmbusReceiveByte:
+ CallBuffer[0] = SmbusIoRead (R_PCH_SMBUS_HD0);
+ break;
+
+ case EfiSmbusWriteBlock:
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
+ break;
+
+ case EfiSmbusReadBlock:
+ BufferTooSmall = FALSE;
+ ///
+ /// Find out how many bytes will be in the block
+ ///
+ BlockCount = SmbusIoRead (R_PCH_SMBUS_HD0);
+ if (*Length < BlockCount) {
+ BufferTooSmall = TRUE;
+ } else {
+ for (Index = 0; Index < BlockCount; Index++) {
+ ///
+ /// Read the byte
+ ///
+ CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD);
+ }
+ }
+
+ *Length = BlockCount;
+ if (BufferTooSmall) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ case EfiSmbusBWBRProcessCall:
+ ///
+ /// Find out how many bytes will be in the block
+ ///
+ BlockCount = SmbusIoRead (R_PCH_SMBUS_HD0);
+ ///
+ /// The read byte count cannot be zero.
+ ///
+ if (BlockCount < 1) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ break;
+ }
+ ///
+ /// The combined data payload (the write byte count + the read byte count)
+ /// must not exceed 32 bytes
+ ///
+ if (((UINT8) (*Length) + BlockCount) > 32) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ for (Index = 0; Index < BlockCount; Index++) {
+ ///
+ /// Read the byte
+ ///
+ CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD);
+ }
+
+ *Length = BlockCount;
+ break;
+
+ default:
+ break;
+ };
+
+ if ((StsReg & B_PCH_SMBUS_BERR) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ ///
+ /// Clear the Bus Error for another try
+ ///
+ Status = EFI_DEVICE_ERROR;
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+ ///
+ /// If bus collision happens, stall some time, then try again
+ /// Here we choose 10 milliseconds to avoid MTCP transfer.
+ ///
+ PchPmTimerStall (STALL_PERIOD);
+ continue;
+ } else {
+ break;
+ }
+ }
+ ///
+ /// Clear Status Registers and exit
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ SmbusIoWrite (R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+ SmbusIoWrite (R_PCH_SMBUS_AUXC, 0);
+ return Status;
+}
+
+/**
+ This function initializes the Smbus Registers.
+
+ @param[in] None.
+
+ @retval None.
+**/
+VOID
+InitializeSmbusRegisters (
+ VOID
+ )
+{
+ UINTN SmbusRegBase;
+
+ SmbusRegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ 0
+ );
+ ///
+ /// Enable the Smbus I/O Enable
+ ///
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
+
+ ///
+ /// Enable the Smbus host controller
+ ///
+ MmioAndThenOr8 (
+ SmbusRegBase + R_PCH_SMBUS_HOSTC,
+ (UINT8) (~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)),
+ B_PCH_SMBUS_HOSTC_HST_EN
+ );
+
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs
new file mode 100644
index 0000000..a64aee1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs
@@ -0,0 +1,40 @@
+/** @file
+ Dispatch dependency expression file for the DXE PchSmbus driver.
+
+@copyright
+ Copyright (c) 2004 - 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
+
+**/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+#include EFI_PROTOCOL_DEFINITION (PchPlatformPolicy)
+#endif
+
+DEPENDENCY_START
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h
new file mode 100644
index 0000000..6c6b93b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h
@@ -0,0 +1,360 @@
+/** @file
+ PCH Smbus Protocol
+
+@copyright
+ Copyright (c) 2004 - 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
+
+**/
+#ifndef _DXE_PCH_SMBUS_H
+#define _DXE_PCH_SMBUS_H
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGlueDxe.h"
+//
+// Driver Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_PRODUCER (Smbus)
+#include EFI_GUID_DEFINITION (SmbusArpMap)
+//
+// Driver Consumed Protcol Prototypes
+//
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#include "PchSmbusCommon.h"
+#endif
+//
+// Definitions
+//
+///
+/// Max number of SMBus devices (7 bit address yields 128 combinations but 21 of those are reserved)
+///
+#define MAX_SMBUS_DEVICES 107
+#define MICROSECOND 10
+#define MILLISECOND (1000 * MICROSECOND)
+#define ONESECOND (1000 * MILLISECOND)
+
+///
+/// Private Data Structures
+///
+typedef struct _SMBUS_NOTIFY_FUNCTION_LIST_NODE {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ UINTN Data;
+ EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction;
+} SMBUS_NOTIFY_FUNCTION_LIST_NODE;
+
+#define SMBUS_NOTIFY_FUNCTION_LIST_NODE_FROM_LINK(_node) \
+ CR ( \
+ _node, \
+ SMBUS_NOTIFY_FUNCTION_LIST_NODE, \
+ Link, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+///
+/// Declare a local instance structure for this driver
+///
+typedef struct _SMBUS_INSTANCE {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+
+ UINT32 SmbusIoBase;
+ SMBUS_IO_READ SmbusIoRead;
+ SMBUS_IO_WRITE SmbusIoWrite;
+ SMBUS_IO_DONE IoDone;
+
+ ///
+ /// Published interface
+ ///
+ EFI_SMBUS_HC_PROTOCOL SmbusController;
+
+ UINT8 DeviceMapEntries;
+ EFI_SMBUS_DEVICE_MAP DeviceMap[MAX_SMBUS_DEVICES];
+
+ UINT8 PlatformNumRsvd;
+ UINT8 *PlatformRsvdAddr;
+
+ LIST_ENTRY NotifyFunctionList;
+ EFI_EVENT NotificationEvent;
+
+} SMBUS_INSTANCE;
+
+//
+// Driver global data
+//
+SMBUS_INSTANCE *mSmbusContext;
+
+//
+// Prototypes
+//
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[out] Length Length of data
+ @param[out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @@param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @retval EFI_INVALID_PARAMETER ArpAll == FALSE but SmbusUdid or SlaveAddress are NULL.
+ Return value from SmbusFullArp() or SmbusDirectedArp().
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ );
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @retval EFI_SUCCESS Function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED Unable to create the event needed for notifications.
+ @retval EFI_INVALID_PARAMETER NotifyFunction was NULL.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate space to register the notification.
+ @retval EFI_SUCCESS Function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+/**
+ Set up a periodic event so that we can check if any Slave Device has sent a
+ Notify ARP Master command.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS Periodic event successfully set up.
+ @retval Other Errors Failed to set up Periodic event.
+ Error value from CreateEvent().
+ Error value from SetTimer().
+**/
+EFI_STATUS
+InitializePeriodicEvent (
+ VOID
+ );
+
+/**
+ Function to be called every time periodic event happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Event The periodic event that occured and got us into this callback.
+ @param[in] Context Event context. Will be NULL in this case, since we already have our
+ private data in a module global variable.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PollSmbusNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices
+ Or there is no available address to assign
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c
new file mode 100644
index 0000000..88124d4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c
@@ -0,0 +1,681 @@
+/** @file
+ PCH Smbus Driver, ARP functions common to PEI and DXE
+
+@copyright
+ Copyright (c) 2004 - 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 "PchSmbus.h"
+
+///
+/// These addresses are reserved by the SMBus 2.0 specification
+///
+static UINT8 mReservedAddress[SMBUS_NUM_RESERVED] = {
+ 0x00,
+ 0x02,
+ 0x04,
+ 0x06,
+ 0x08,
+ 0x0A,
+ 0x0C,
+ 0x0E,
+ 0x10,
+ 0x18,
+ 0x50,
+ 0x6E,
+ 0xC2,
+ 0xF0,
+ 0xF2,
+ 0xF4,
+ 0xF6,
+ 0xF8,
+ 0xFA,
+ 0xFC,
+ 0xFE,
+ 0x12,
+ 0x14,
+ 0x16,
+ 0x58,
+ 0x5A,
+ 0x80,
+ 0x82,
+ 0x84,
+ 0x86,
+ 0x88,
+ 0x90,
+ 0x92,
+ 0x94,
+ 0x96,
+ 0x1A,
+ 0x1C,
+ 0x1E
+};
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @@param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @retval EFI_INVALID_PARAMETER ArpAll == FALSE but SmbusUdid or SlaveAddress are NULL.
+ Return value from SmbusFullArp() or SmbusDirectedArp().
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ DEBUG ((EFI_D_INFO, "SmbusArpDevice() Start\n"));
+
+ InitializeSmbusRegisters ();
+
+ DEBUG ((EFI_D_INFO, "SmbusArpDevice() End\n"));
+
+ if (ArpAll) {
+ return SmbusFullArp (mSmbusContext);
+ } else {
+ if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmbusDirectedArp (mSmbusContext, SmbusUdid, SlaveAddress);
+ }
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @retval EFI_SUCCESS Function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ *Length = mSmbusContext->DeviceMapEntries * sizeof (EFI_SMBUS_DEVICE_MAP);
+ *SmbusDeviceMap = mSmbusContext->DeviceMap;
+ return EFI_SUCCESS;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED Unable to create the event needed for notifications.
+ @retval EFI_INVALID_PARAMETER NotifyFunction was NULL.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate space to register the notification.
+ @retval EFI_SUCCESS Function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ EFI_STATUS Status;
+ SMBUS_NOTIFY_FUNCTION_LIST_NODE *NewNode;
+
+ DEBUG ((EFI_D_INFO, "SmbusNotify() Start\n"));
+
+ if (NotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NewNode = (SMBUS_NOTIFY_FUNCTION_LIST_NODE *) AllocatePool (sizeof (SMBUS_NOTIFY_FUNCTION_LIST_NODE));
+ if (NewNode == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for NewNode! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ///
+ /// If this is the first notification request, start an event to periodically
+ /// check for a Notify master command.
+ ///
+ if (!mSmbusContext->NotificationEvent) {
+ Status = InitializePeriodicEvent ();
+ if (EFI_ERROR (Status)) {
+ FreePool (NewNode);
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ NewNode->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ NewNode->SlaveAddress.SmbusDeviceAddress = SlaveAddress.SmbusDeviceAddress;
+ NewNode->Data = Data;
+ NewNode->NotifyFunction = NotifyFunction;
+
+ InsertTailList (&mSmbusContext->NotifyFunctionList, &NewNode->Link);
+
+ DEBUG ((EFI_D_INFO, "SmbusNotify() End\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Set up a periodic event so that we can check if any Slave Device has sent a
+ Notify ARP Master command.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS Periodic event successfully set up.
+ @retval Other Errors Failed to set up Periodic event.
+ Error value from CreateEvent().
+**/
+EFI_STATUS
+InitializePeriodicEvent (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEvent (
+ (EVENT_TIMER | EVENT_NOTIFY_SIGNAL),
+ TPL_CALLBACK,
+ PollSmbusNotify,
+ NULL,
+ &mSmbusContext->NotificationEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->SetTimer (
+ mSmbusContext->NotificationEvent,
+ TimerPeriodic,
+ 1000 * MILLISECOND
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to be called every time periodic event happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Event The periodic event that occured and got us into this callback.
+ @param[in] Context Event context. Will be NULL in this case, since we already have our
+ private data in a module global variable.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PollSmbusNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ LIST_ENTRY *Link;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ SMBUS_NOTIFY_FUNCTION_LIST_NODE *Node;
+ UINT8 SstsReg;
+ UINTN Data;
+
+ DEBUG ((EFI_D_INFO, "PollSmbusNotify() Start\n"));
+
+ InitializeSmbusRegisters ();
+
+ SstsReg = SmbusIoRead (R_PCH_SMBUS_SSTS);
+ if (!(SstsReg & B_PCH_SMBUS_HOST_NOTIFY_STS)) {
+ ///
+ /// Host Notify has not been received
+ ///
+ return;
+ }
+ ///
+ /// There was a Host Notify, see if any one wants to know about it
+ ///
+ SlaveAddress.SmbusDeviceAddress = (SmbusIoRead (R_PCH_SMBUS_NDA)) >> 1;
+
+ Link = GetFirstNode (&mSmbusContext->NotifyFunctionList);
+
+ while (!IsNull (&mSmbusContext->NotifyFunctionList, Link)) {
+ Node = SMBUS_NOTIFY_FUNCTION_LIST_NODE_FROM_LINK (Link);
+
+ if (Node->SlaveAddress.SmbusDeviceAddress == SlaveAddress.SmbusDeviceAddress) {
+ Data = (SmbusIoRead (R_PCH_SMBUS_NDHB) << 8) + (SmbusIoRead (R_PCH_SMBUS_NDLB));
+ if ((UINT16) Node->Data == (UINT16) Data) {
+ ///
+ /// We have a match, notify the requested function
+ ///
+ Node->NotifyFunction (SlaveAddress, Data);
+ }
+ }
+
+ Link = GetNextNode (&mSmbusContext->NotifyFunctionList, &Node->Link);
+ }
+ ///
+ /// Clear the Notify Status bit and exit.
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_SSTS, B_PCH_SMBUS_HOST_NOTIFY_STS);
+
+ DEBUG ((EFI_D_INFO, "PollSmbusNotify() End\n"));
+
+ return;
+}
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer;
+
+ DEBUG ((EFI_D_INFO, "SmbusPrepareToArp() Start\n"));
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = 1;
+ Buffer = SMBUS_DATA_PREPARE_TO_ARP;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ 0,
+ EfiSmbusSendByte,
+ TRUE,
+ &Length,
+ &Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "SmbusPrepareToArp() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ DEBUG ((EFI_D_INFO, "SmbusGetUdidGeneral() Start\n"));
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_GET_UDID_GENERAL,
+ EfiSmbusReadBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ if (!EFI_ERROR (Status)) {
+ if (Length == SMBUS_GET_UDID_LENGTH) {
+ DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0];
+ DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1];
+ DeviceMap->SmbusDeviceUdid.VendorId = (UINT16) ((Buffer[2] << 8) + Buffer[3]);
+ DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16) ((Buffer[4] << 8) + Buffer[5]);
+ DeviceMap->SmbusDeviceUdid.Interface = (UINT16) ((Buffer[6] << 8) + Buffer[7]);
+ DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16) ((Buffer[8] << 8) + Buffer[9]);
+ DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16) ((Buffer[10] << 8) + Buffer[11]);
+ DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32) ((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]);
+ DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8) (Buffer[16] >> 1);
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "SmbusGetUdidGeneral() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ DEBUG ((EFI_D_INFO, "SmbusAssignAddress() Start\n"));
+
+ Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities;
+ Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision;
+ Buffer[2] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId >> 8);
+ Buffer[3] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId);
+ Buffer[4] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId >> 8);
+ Buffer[5] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId);
+ Buffer[6] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface >> 8);
+ Buffer[7] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface);
+ Buffer[8] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8);
+ Buffer[9] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId);
+ Buffer[10] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8);
+ Buffer[11] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId);
+ Buffer[12] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24);
+ Buffer[13] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16);
+ Buffer[14] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8);
+ Buffer[15] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId);
+ Buffer[16] = (UINT8) (DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1);
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_ASSIGN_ADDRESS,
+ EfiSmbusWriteBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "SmbusAssignAddress() End\n"));
+
+ return Status;
+}
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "SmbusFullArp() Start\n"));
+
+ Status = SmbusPrepareToArp (Private);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ ///
+ /// ARP is complete
+ ///
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
+ }
+ ///
+ /// Main loop to ARP all ARP-capable devices
+ ///
+ do {
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+ Status = SmbusGetUdidGeneral (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) {
+ ///
+ /// If address is unassigned, assign it
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) {
+ ///
+ /// if address is not fixed, check if the current address is available
+ ///
+ if (!IsAddressAvailable (
+ Private,
+ CurrentDeviceMap->SmbusDeviceAddress
+ )) {
+ ///
+ /// if currently assigned address is already used, get a new one
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ ///
+ /// If there was a device error, just continue on and try again.
+ /// Other errors should be reported.
+ ///
+ if (Status != EFI_DEVICE_ERROR) {
+ return Status;
+ }
+ } else {
+ ///
+ /// If there was no error, the address was assigned and we must update our
+ /// records.
+ ///
+ Private->DeviceMapEntries++;
+ }
+
+ } while (Private->DeviceMapEntries < MAX_SMBUS_DEVICES);
+
+ DEBUG ((EFI_D_INFO, "SmbusFullArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices
+ Or there is no available address to assign
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "SmbusDirectedArp() Start\n"));
+
+ if (Private->DeviceMapEntries >= MAX_SMBUS_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+
+ ///
+ /// Find an available address to assign
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities = SmbusUdid->DeviceCapabilities;
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceId = SmbusUdid->DeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.Interface = SmbusUdid->Interface;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId = SmbusUdid->SubsystemDeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId = SmbusUdid->SubsystemVendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorId = SmbusUdid->VendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorRevision = SmbusUdid->VendorRevision;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId = SmbusUdid->VendorSpecificId;
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private->DeviceMapEntries++;
+ SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress;
+
+ DEBUG ((EFI_D_INFO, "SmbusDirectedArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ for (SlaveAddress->SmbusDeviceAddress = 0x03;
+ SlaveAddress->SmbusDeviceAddress < 0x7F;
+ SlaveAddress->SmbusDeviceAddress++
+ ) {
+ if (IsAddressAvailable (Private, *SlaveAddress)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ )
+{
+ UINT8 Index;
+
+ ///
+ /// See if we have already assigned this address to a device
+ ///
+ for (Index = 0; Index < Private->DeviceMapEntries; Index++) {
+ if (SlaveAddress.SmbusDeviceAddress == Private->DeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this address is claimed by a platform non-ARP-capable device
+ ///
+ for (Index = 0; Index < Private->PlatformNumRsvd; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == Private->PlatformRsvdAddr[Index]) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this is a reserved address
+ ///
+ for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == (UINTN) mReservedAddress[Index]) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif
new file mode 100644
index 0000000..5a97eaa
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Dxe"
+ RefName = "PchSmbusDxe"
+[files]
+"PchSmbusDxe.sdl"
+"PchSmbusDxe.mak"
+"PchSmbus.h"
+"PchSmbusArp.c"
+"PchSmbusEntry.c"
+"PchSmbus.dxs"
+"PchSmbusDxe.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf
new file mode 100644
index 0000000..ae41336
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf
@@ -0,0 +1,93 @@
+## @file
+# Component description file for PchSmbus driver
+#
+#@copyright
+# Copyright (c) 2004 - 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 = PchSmbusDxe
+FILE_GUID = E052D8A6-224A-4c32-8D37-2E0AE162364D
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSmbusEntry.c
+ PchSmbus.h
+ PchSmbusArp.c
+ ../Common/PchSmbusExec.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ ../Common
+ $(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]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseLib
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeHobLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbus
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_HOB_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak
new file mode 100644
index 0000000..3e74002
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak
@@ -0,0 +1,103 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusDxe/PchSmbusDxe.mak 2 2/24/12 2:22a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:22a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusDxe/PchSmbusDxe.mak $
+#
+# 2 2/24/12 2:22a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:19a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbusDxe Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusDxe
+PchSmbusDxe : $(BUILD_DIR)\PchSmbusDxe.mak PchSmbusDxeBin
+
+
+$(BUILD_DIR)\PchSmbusDxe.mak : $(PchSmbusDxe_DIR)\$(@B).cif $(PchSmbusDxe_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusDxe_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusDxe_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbus"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_HOB_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusDxe_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(PchSmbusCommonDxeLib_LIB)
+
+PchSmbusDxeBin: $(PchSmbusDxe_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusDxe.mak all \
+ "MY_INCLUDES=$(PchSmbusDxe_INCLUDES)"\
+ "MY_DEFINES=$(PchSmbusDxe_DEFINES)"\
+ GUID=E052D8A6-224A-4c32-8D37-2E0AE162364D\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(PchSmbusDxe_DIR)\PchSmbus.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Smbus/Dxe/PchSmbusDxe.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl
new file mode 100644
index 0000000..8d5afd7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusDxe/PchSmbusDxe.sdl 1 2/08/12 9:19a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:19a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusDxe/PchSmbusDxe.sdl $
+#
+# 1 2/08/12 9:19a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusDxe_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSmbusDxe support in Project"
+End
+
+PATH
+ Name = "PchSmbusDxe_DIR"
+ Help = "PchSmbusDxe file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusDxe.mak to Project"
+ File = "PchSmbusDxe.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusDxe.ffs"
+ Parent = "FV_MAIN"
+ 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/Smbus/Dxe/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c
new file mode 100644
index 0000000..35cab3f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c
@@ -0,0 +1,149 @@
+/** @file
+ PCH Smbus Driver
+
+@copyright
+ Copyright (c) 2004 - 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 "PchSmbus.h"
+
+EFI_GUID mEfiSmbusArpMapGuid = EFI_SMBUS_ARP_MAP_GUID;
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[in, out] Length Length of data
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ DEBUG ((EFI_D_INFO, "SmbusExecute() Start, SmbusDeviceAddress=%x, Command=%x, Operation=%x\n", (SlaveAddress.SmbusDeviceAddress << 1), Command, Operation));
+ InitializeSmbusRegisters ();
+
+ return SmbusExec (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+}
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ EFI_STATUS Status;
+ UINTN DataSize;
+ VOID *Data;
+ EFI_PEI_HOB_POINTERS HobList;
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbus() Start\n"));
+
+ Status = gBS->LocateProtocol (
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mSmbusContext = AllocateZeroPool (sizeof (SMBUS_INSTANCE));
+ if (mSmbusContext == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mSmbusContext->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ mSmbusContext->IoDone = IoDone;
+ mSmbusContext->SmbusIoRead = SmbusIoRead;
+ mSmbusContext->SmbusIoWrite = SmbusIoWrite;
+ mSmbusContext->SmbusController.Execute = SmbusExecute;
+ mSmbusContext->SmbusController.ArpDevice = SmbusArpDevice;
+ mSmbusContext->SmbusController.GetArpMap = SmbusGetArpMap;
+ mSmbusContext->SmbusController.Notify = SmbusNotify;
+ mSmbusContext->PlatformNumRsvd = PchPlatformPolicy->SmbusConfig->NumRsvdSmbusAddresses;
+ mSmbusContext->PlatformRsvdAddr = PchPlatformPolicy->SmbusConfig->RsvdSmbusAddressTable;
+
+ ///
+ /// See if PEI already ARPed any devices, and if so, update our device map.
+ ///
+ /// Get Hob list
+ ///
+ Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &HobList.Raw);
+ ASSERT_EFI_ERROR (Status);
+
+ HobList.Raw = GetNextGuidHob (&mEfiSmbusArpMapGuid, HobList.Raw);
+ ///
+ /// If we found the right hob, store the information. Otherwise, continue.
+ ///
+ if (HobList.Raw != NULL) {
+ Data = (VOID *) ((UINT8 *) (&HobList.Guid->Name) + sizeof (EFI_GUID));
+ DataSize = HobList.Header->HobLength - sizeof (EFI_HOB_GUID_TYPE);
+ CopyMem (mSmbusContext->DeviceMap, Data, DataSize);
+ mSmbusContext->DeviceMapEntries = (UINT8) (DataSize / sizeof (EFI_SMBUS_DEVICE_MAP));
+ }
+ ///
+ /// Initialize the NotifyFunctionList
+ ///
+ InitializeListHead (&mSmbusContext->NotifyFunctionList);
+
+ ///
+ /// Install the SMBUS interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmbusContext->Handle,
+ &gEfiSmbusProtocolGuid,
+ &mSmbusContext->SmbusController,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbus() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs
new file mode 100644
index 0000000..30bfdc5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs
@@ -0,0 +1,44 @@
+/** @file
+ Dependency expression file for PCH SMBUS PEIM.
+
+@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
+
+**/
+
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "PeimDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+#include "Common/EdkIIGlueDefinitionChangesPeim.h"
+
+#include EFI_PPI_DEFINITION (SmbusPolicy)
+#endif
+
+DEPENDENCY_START
+ PEI_SMBUS_POLICY_PPI_GUID
+DEPENDENCY_END
+
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h
new file mode 100644
index 0000000..fe64e8a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h
@@ -0,0 +1,409 @@
+/** @file
+ PCH Smbus PPI
+
+@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 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
+
+**/
+#ifndef _PEI_PCH_SMBUS_H_
+#define _PEI_PCH_SMBUS_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGluePeim.h"
+
+//
+// Driver Produced PPI Prototypes
+//
+#include EFI_PPI_PRODUCER (Smbus)
+//
+// Driver Consumed PPI Prototypes
+//
+#include EFI_PPI_CONSUMER (EndOfPeiSignal)
+#include EFI_PPI_CONSUMER (SmbusPolicy)
+#include EFI_PPI_CONSUMER (MemoryDiscovered)
+#include EFI_GUID_DEFINITION (SmbusArpMap)
+#include "PchSmbusCommon.h"
+#endif
+///
+/// Max number of SMBus devices
+/// (7 bit address yields 128 combinations but 21 of those are reserved)
+/// Due to limited resources, we only allow 8 in PEI.
+///
+#define MAX_SMBUS_DEVICES 8
+
+#define MAX_SMBUS_NOTIFICATION 8
+
+///
+/// Private Data Structures
+///
+typedef struct _PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE {
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ UINTN Data;
+ EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction;
+} PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE;
+
+///
+/// Declare a local instance structure for this PEIM
+///
+typedef struct _SMBUS_INSTANCE {
+ UINTN Signature;
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_SMBUS_POLICY_PPI *SmbusPolicy;
+ UINTN SmbusIoBase;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ EFI_PEI_SMBUS_PPI SmbusPpi;
+ EFI_PEI_NOTIFY_DESCRIPTOR NotifyDescriptor;
+ UINT8 DeviceMapEntries;
+ EFI_SMBUS_DEVICE_MAP DeviceMap[MAX_SMBUS_DEVICES];
+ UINT8 PlatformNumRsvd;
+ UINT8 *PlatformRsvdAddr;
+
+ UINT8 NotifyFunctionNum;
+ PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE NotifyFunctionList[MAX_SMBUS_NOTIFICATION];
+} SMBUS_INSTANCE;
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define SMBUS_PRIVATE_DATA_FROM_PPI_THIS(a) PEI_CR (a, SMBUS_INSTANCE, SmbusPpi, PCH_SMBUS_PRIVATE_DATA_SIGNATURE)
+
+#define SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS(a) \
+ PEI_CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ PpiDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#define SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS(a) \
+ PEI_CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ NotifyDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#else
+
+#define SMBUS_PRIVATE_DATA_FROM_PPI_THIS(a) CR (a, SMBUS_INSTANCE, SmbusPpi, PCH_SMBUS_PRIVATE_DATA_SIGNATURE)
+
+#define SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS(a) \
+ CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ PpiDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#define SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS(a) \
+ CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ NotifyDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#endif
+//
+// Prototypes
+//
+
+/**
+ This function provides a standard way to execute an SMBUS command
+ PPI as defined in the SMBus Specification. The data can either be of
+ the length byte, word, or a block of data (1 to 32 bytes long).
+ The resulting transaction will be either the SMBus Slave Device accepts
+ this transaction or this function returns with an error
+
+ @param[in] PeiServices PEI services table pointer
+ @param[in] This PEI_SMBUS_PPI instance
+ @param[in] SlaveAddress Smbus Slave device address
+ @param[in] Command Command to be sent
+ @param[in] Operation Which SMBus PPI will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read/write. Must be 1 <= Length <= 32 depending on the Operation
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS Operation success.
+ Length will contain the actual number of bytes read.
+ Buffer will contain the data read.
+ @retval Otherwise Operation failed.
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Initialize the Smbus PPI and program the Smbus BAR
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+InitializePchSmbusPeim (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ Fix up pointers since they are located in real memory now.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ );
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] PeiServices The general PEI Services
+ @param[in] This The PPI instance
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+/**
+ This function initializes the SmBus driver in PEI.
+
+ @param[in] PeiServices Standard PEI services
+ @param[in] Private SMBUS private data structure
+
+ @retval None.
+**/
+VOID
+InitializePeiPrivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices.
+ Or there is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ );
+
+/**
+ This function gets called back at the end of PEI if any devices were ARPed
+ during PEI. It will build a HOB to describe to DXE what devices were ARPed.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The EndOfPeiSignal PPI.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Function to be called when SMBus.Execute happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval None
+**/
+VOID
+CheckNotification (
+ IN SMBUS_INSTANCE *Private
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c
new file mode 100644
index 0000000..9ba5647
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c
@@ -0,0 +1,444 @@
+/** @file
+ PCH Smbus PEIM. This file is used when we want ARP support.
+
+@copyright
+ Copyright (c) 2009 - 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 "PchSmbus.h"
+
+///
+/// These addresses are reserved by the SMBus 2.0 specification
+///
+static UINT8 mReservedAddress[SMBUS_NUM_RESERVED] = {
+ 0x00,
+ 0x02,
+ 0x04,
+ 0x06,
+ 0x08,
+ 0x0A,
+ 0x0C,
+ 0x0E,
+ 0x10,
+ 0x18,
+ 0x50,
+ 0x6E,
+ 0xC2,
+ 0xF0,
+ 0xF2,
+ 0xF4,
+ 0xF6,
+ 0xF8,
+ 0xFA,
+ 0xFC,
+ 0xFE,
+ 0x12,
+ 0x14,
+ 0x16,
+ 0x58,
+ 0x5A,
+ 0x80,
+ 0x82,
+ 0x84,
+ 0x86,
+ 0x88,
+ 0x90,
+ 0x92,
+ 0x94,
+ 0x96,
+ 0x1A,
+ 0x1C,
+ 0x1E
+};
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusPrepareToArp() Start\n"));
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = 1;
+ Buffer = SMBUS_DATA_PREPARE_TO_ARP;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ 0,
+ EfiSmbusSendByte,
+ TRUE,
+ &Length,
+ &Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusPrepareToArp() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusGetUdidGeneral() Start\n"));
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_GET_UDID_GENERAL,
+ EfiSmbusReadBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ if (!EFI_ERROR (Status)) {
+ if (Length == SMBUS_GET_UDID_LENGTH) {
+ DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0];
+ DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1];
+ DeviceMap->SmbusDeviceUdid.VendorId = (UINT16) ((Buffer[2] << 8) + Buffer[3]);
+ DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16) ((Buffer[4] << 8) + Buffer[5]);
+ DeviceMap->SmbusDeviceUdid.Interface = (UINT16) ((Buffer[6] << 8) + Buffer[7]);
+ DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16) ((Buffer[8] << 8) + Buffer[9]);
+ DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16) ((Buffer[10] << 8) + Buffer[11]);
+ DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32) ((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]);
+ DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8) (Buffer[16] >> 1);
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusGetUdidGeneral() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusAssignAddress() Start\n"));
+
+ Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities;
+ Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision;
+ Buffer[2] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId >> 8);
+ Buffer[3] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId);
+ Buffer[4] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId >> 8);
+ Buffer[5] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId);
+ Buffer[6] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface >> 8);
+ Buffer[7] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface);
+ Buffer[8] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8);
+ Buffer[9] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId);
+ Buffer[10] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8);
+ Buffer[11] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId);
+ Buffer[12] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24);
+ Buffer[13] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16);
+ Buffer[14] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8);
+ Buffer[15] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId);
+ Buffer[16] = (UINT8) (DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1);
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_ASSIGN_ADDRESS,
+ EfiSmbusWriteBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusAssignAddress() End\n"));
+
+ return Status;
+}
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusFullArp() Start\n"));
+
+ Status = SmbusPrepareToArp (Private);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ ///
+ /// ARP is complete
+ ///
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
+ }
+ ///
+ /// Main loop to ARP all ARP-capable devices
+ ///
+ do {
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+ Status = SmbusGetUdidGeneral (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) {
+ ///
+ /// If address is unassigned, assign it
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) {
+ ///
+ /// if address is not fixed, check if the current address is available
+ ///
+ if (!IsAddressAvailable (
+ Private,
+ CurrentDeviceMap->SmbusDeviceAddress
+ )) {
+ ///
+ /// if currently assigned address is already used, get a new one
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ ///
+ /// If there was a device error, just continue on and try again.
+ /// Other errors should be reported.
+ ///
+ if (Status != EFI_DEVICE_ERROR) {
+ return Status;
+ }
+ } else {
+ ///
+ /// If there was no error, the address was assigned and we must update our
+ /// records.
+ ///
+ Private->DeviceMapEntries++;
+ }
+
+ } while (Private->DeviceMapEntries < MAX_SMBUS_DEVICES);
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusFullArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices.
+ Or there is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusDirectedArp() Start\n"));
+
+ if (Private->DeviceMapEntries >= MAX_SMBUS_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+
+ ///
+ /// Find an available address to assign
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities = SmbusUdid->DeviceCapabilities;
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceId = SmbusUdid->DeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.Interface = SmbusUdid->Interface;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId = SmbusUdid->SubsystemDeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId = SmbusUdid->SubsystemVendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorId = SmbusUdid->VendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorRevision = SmbusUdid->VendorRevision;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId = SmbusUdid->VendorSpecificId;
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private->DeviceMapEntries++;
+ SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusDirectedArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ for (SlaveAddress->SmbusDeviceAddress = 0x03;
+ SlaveAddress->SmbusDeviceAddress < 0x7F;
+ SlaveAddress->SmbusDeviceAddress++
+ ) {
+ if (IsAddressAvailable (Private, *SlaveAddress)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ )
+{
+ UINT8 Index;
+
+ ///
+ /// See if we have already assigned this address to a device
+ ///
+ for (Index = 0; Index < Private->DeviceMapEntries; Index++) {
+ if (SlaveAddress.SmbusDeviceAddress == Private->DeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this address is claimed by a platform non-ARP-capable device
+ ///
+ for (Index = 0; Index < Private->PlatformNumRsvd; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == Private->PlatformRsvdAddr[Index]) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this is a reserved address
+ ///
+ for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == (UINTN) mReservedAddress[Index]) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif
new file mode 100644
index 0000000..6682817
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusArpDisabled"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Pei"
+ RefName = "PchSmbusArpDisabled"
+[files]
+"PchSmbusArpDisabled.sdl"
+"PchSmbusArpDisabled.mak"
+"PchSmbusEntry.c"
+"PchSmbus.h"
+"PchSmbusArpdisabled.c"
+"PchSmbus.dxs"
+"PchSmbusArpDisabled.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf
new file mode 100644
index 0000000..a66047e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf
@@ -0,0 +1,88 @@
+## @file
+# Component description file for PchSmbus module
+# This version will NOT include ARP support.
+#
+#@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 = PchSmbusArpDisabled
+FILE_GUID = 643DF777-F312-42ed-81CC-1B1F57E18AD6
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchSmbus.h
+ PchSmbusEntry.c
+ PchSmbusArpDisabled.c
+ ../Common/PchSmbusExec.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/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]
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ -D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak
new file mode 100644
index 0000000..531b08e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak
@@ -0,0 +1,97 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusArpDisabled/PchSmbusArpDisabled.mak 2 2/24/12 2:23a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:23a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.mak $
+#
+# 2 2/24/12 2:23a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:20a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbusArpDisabled Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusArpDisabled
+PchSmbusArpDisabled : $(BUILD_DIR)\PchSmbusArpDisabled.mak PchSmbusArpDisabledBin
+
+
+$(BUILD_DIR)\PchSmbusArpDisabled.mak : $(PchSmbusArpDisabled_DIR)\$(@B).cif $(PchSmbusArpDisabled_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusArpDisabled_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusArpDisabled_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusArpDisabled_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_CF8_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusArpDisabled_LIB_LINKS =\
+ $(EDKFRAMEWORKPPILIB)\
+ $(PchPlatformPeiLib_LIB)\
+ $(PchSmbusCommonPeiLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGluePeiMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBasePciLibCf8_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchSmbusArpDisabledBin: $(PchSmbusArpDisabled_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusArpDisabled.mak all\
+ NAME=PchSmbusArpDisabled\
+ MAKEFILE=$(BUILD_DIR)\PchSmbusArpDisabled.mak \
+ GUID=643DF777-F312-42ed-81CC-1B1F57E18AD6\
+ "MY_INCLUDES=$(PchSmbusArpDisabled_INCLUDES)"\
+ "MY_DEFINES=$(MY_DEFINES) $(PchSmbusArpDisabled_DEFINES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchSmbusArpDisabled_DIR)\PchSmbus.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=0
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Smbus/Pei/PchSmbusArpDisabled.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl
new file mode 100644
index 0000000..23e79a5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusArpDisabled/PchSmbusArpDisabled.sdl 1 2/08/12 9:20a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:20a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.sdl $
+#
+# 1 2/08/12 9:20a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusArpDisabled_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmbusArpDisabled support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusArpDisabled_DIR"
+ Help = "PchSmbusArpDisabled file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusArpDisabled.mak to Project"
+ File = "PchSmbusArpDisabled.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusArpDisabled.ffs"
+ Parent = "FV_BB"
+ 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/Smbus/Pei/PchSmbusArpEnabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c
new file mode 100644
index 0000000..91a8614
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c
@@ -0,0 +1,291 @@
+/** @file
+ PCH Smbus PEIM. This file is used when we want ARP support.
+
+@copyright
+ Copyright (c) 2009 - 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 "PchSmbus.h"
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEndOfPeiSignalPpiGuid,
+ EndOfPeiCallback
+};
+
+EFI_GUID mEfiSmbusArpMapGuid = EFI_SMBUS_ARP_MAP_GUID;
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid OPTIONAL,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ SMBUS_INSTANCE *Private;
+ EFI_STATUS Status;
+ UINT8 OldMapEntries;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusArpDevice() Start\n"));
+
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ OldMapEntries = Private->DeviceMapEntries;
+
+ if (ArpAll) {
+ Status = SmbusFullArp (Private);
+ } else {
+ if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SmbusDirectedArp (Private, SmbusUdid, SlaveAddress);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// If we just added the first entry in the device map, set up a callback so
+ /// we can pass the map to DXE via a HOB at the end of PEI.
+ ///
+ if ((OldMapEntries == 0) && (Private->DeviceMapEntries > 0)) {
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mNotifyList);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusArpDevice() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ SMBUS_INSTANCE *Private;
+
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ *Length = Private->DeviceMapEntries * sizeof (EFI_SMBUS_DEVICE_MAP);
+ *SmbusDeviceMap = Private->DeviceMap;
+ return EFI_SUCCESS;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] PeiServices The general PEI Services
+ @param[in] This The PPI instance
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ SMBUS_INSTANCE *Private;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusNotify() Start\n"));
+
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ if (NotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// NOTE: Currently there is no periodic event in PEI.
+ /// So we just check the Notification at the end of in each
+ /// Smbus.Execute function.
+ ///
+ if (Private->NotifyFunctionNum >= MAX_SMBUS_NOTIFICATION) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Private->NotifyFunctionList[Private->NotifyFunctionNum].SlaveAddress.SmbusDeviceAddress = SlaveAddress.SmbusDeviceAddress;
+ Private->NotifyFunctionList[Private->NotifyFunctionNum].Data = Data;
+ Private->NotifyFunctionList[Private->NotifyFunctionNum].NotifyFunction = NotifyFunction;
+ Private->NotifyFunctionNum++;
+
+ ///
+ /// Last step, check notification
+ ///
+ CheckNotification (Private);
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusNotify() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function gets called back at the end of PEI if any devices were ARPed
+ during PEI. It will build a HOB to describe to DXE what devices were ARPed.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The EndOfPeiSignal PPI.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *SmbusDescriptor;
+ PEI_SMBUS_PPI *SmbusPpi;
+ SMBUS_INSTANCE *Private;
+ UINTN BufferSize;
+ VOID *Hob;
+
+ DEBUG ((EFI_D_INFO, "PEI EndOfPeiCallback() Start\n"));
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPeiSmbusPpiGuid, /// GUID
+ 0, /// INSTANCE
+ &SmbusDescriptor, /// PEI_PPI_DESCRIPTOR
+ &SmbusPpi /// PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Private = SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS (SmbusDescriptor);
+ BufferSize = sizeof (EFI_SMBUS_DEVICE_MAP) * Private->DeviceMapEntries;
+
+ Hob = BuildGuidDataHob (
+ &mEfiSmbusArpMapGuid,
+ Private->DeviceMap,
+ BufferSize
+ );
+ ASSERT (Hob != NULL);
+
+ DEBUG ((EFI_D_INFO, "PEI EndOfPeiCallback() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to be called when SMBus.Execute happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval None
+**/
+VOID
+CheckNotification (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ UINT8 SstsReg;
+ UINTN Data;
+ UINTN Index;
+
+ DEBUG ((EFI_D_INFO, "PEI CheckNotification() Start\n"));
+
+ if (Private->NotifyFunctionNum == 0) {
+ ///
+ /// Since no one register it, not need to check.
+ ///
+ return;
+ }
+
+ SstsReg = SmbusIoRead (R_PCH_SMBUS_SSTS);
+ if (!(SstsReg & B_PCH_SMBUS_HOST_NOTIFY_STS)) {
+ ///
+ /// Host Notify has not been received
+ ///
+ return;
+ }
+ ///
+ /// There was a Host Notify, see if any one wants to know about it
+ ///
+ SlaveAddress.SmbusDeviceAddress = (SmbusIoRead (R_PCH_SMBUS_NDA)) >> 1;
+
+ for (Index = 0; Index < Private->NotifyFunctionNum; Index++) {
+
+ if (Private->NotifyFunctionList[Index].SlaveAddress.SmbusDeviceAddress == SlaveAddress.SmbusDeviceAddress) {
+ Data = (SmbusIoRead (R_PCH_SMBUS_NDHB) << 8) + (SmbusIoRead (R_PCH_SMBUS_NDLB));
+ if ((UINT16) Private->NotifyFunctionList[Index].Data == (UINT16) Data) {
+ ///
+ /// We have a match, notify the requested function
+ ///
+ Private->NotifyFunctionList[Index].NotifyFunction (
+ Private->PeiServices,
+ &Private->SmbusPpi,
+ SlaveAddress,
+ Data
+ );
+ }
+ }
+ }
+ ///
+ /// Clear the Notify Status bit and exit.
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_SSTS, B_PCH_SMBUS_HOST_NOTIFY_STS);
+
+ DEBUG ((EFI_D_INFO, "PEI CheckNotification() End\n"));
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif
new file mode 100644
index 0000000..5674891
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "PchSmbusArpEnabled"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Pei"
+ RefName = "PchSmbusArpEnabled"
+[files]
+"PchSmbusArpEnabled.sdl"
+"PchSmbusArpEnabled.mak"
+"PchSmbusEntry.c"
+"PchSmbus.h"
+"PchSmbusArpEnabled.c"
+"PchSmbusArp.c"
+"PchSmbus.dxs"
+"PchSmbusArpEnabled.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf
new file mode 100644
index 0000000..c4a23f1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf
@@ -0,0 +1,91 @@
+## @file
+# Component description file for PchSmbus module
+# This version will include ARP support.
+#
+#@copyright
+# Copyright (c) 2009 - 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 = PchSmbusArpEnabled
+FILE_GUID = 22B194B4-CC0E-46c7-9FCE-DA10D6ED1731
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchSmbus.h
+ PchSmbusEntry.c
+ PchSmbusArpEnabled.c
+ PchSmbusArp.c
+ ../Common/PchSmbusExec.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/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]
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGluePeiHobLib
+ EdkIIGlueBasePciLibPciExpress
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PeimInitializePchSmbus
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ -D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_PEI_HOB_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak
new file mode 100644
index 0000000..b1b2ce9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak
@@ -0,0 +1,97 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusArpEnabled/PchSmbusArpEnabled.mak 2 2/24/12 2:29a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:29a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.mak $
+#
+# 2 2/24/12 2:29a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:28a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbusArpEnabled Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusArpEnabled
+PchSmbusArpEnabled : $(BUILD_DIR)\PchSmbusArpEnabled.mak PchSmbusArpEnabledBin
+
+
+$(BUILD_DIR)\PchSmbusArpEnabled.mak : $(PchSmbusArpEnabled_DIR)\$(@B).cif $(PchSmbusArpEnabled_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusArpEnabled_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusArpEnabled_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusArpEnabled_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_PEI_HOB_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusArpEnabled_LIB_LINKS =\
+ $(EDKFRAMEWORKPPILIB)\
+ $(PchPlatformPeiLib_LIB)\
+ $(PchSmbusCommonPeiLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGluePeiMemoryAllocationLib_LIB)\
+ $(EdkIIGluePeiHobLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchSmbusArpEnabledBin: $(PchSmbusArpEnabled_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusArpEnabled.mak all\
+ NAME=PchSmbusArpEnabled\
+ MAKEFILE=$(BUILD_DIR)\PchSmbusArpEnabled.mak \
+ GUID=22B194B4-CC0E-46c7-9FCE-DA10D6ED1731\
+ "MY_INCLUDES=$(PchSmbusArpEnabled_INCLUDES)"\
+ "MY_DEFINES=$(MY_DEFINES) $(PchSmbusArpEnabled_DEFINES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchSmbusArpEnabled_DIR)\PchSmbus.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=0
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Smbus/Pei/PchSmbusArpEnabled.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl
new file mode 100644
index 0000000..dcb1377
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusArpEnabled/PchSmbusArpEnabled.sdl 1 2/08/12 9:28a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:28a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.sdl $
+#
+# 1 2/08/12 9:28a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusArpEnabled_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable PchSmbusArpEnabled support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusArpEnabled_DIR"
+ Help = "PchSmbusArpEnabled file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusArpEnabled.mak to Project"
+ File = "PchSmbusArpEnabled.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusArpEnabled.ffs"
+ Parent = "FV_BB"
+ 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/Smbus/Pei/PchSmbusArpdisabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c
new file mode 100644
index 0000000..b249317
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c
@@ -0,0 +1,117 @@
+/** @file
+ PCH Smbus PEIM. This file is used when we do not want ARP support.
+
+@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 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 "PchSmbus.h"
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid OPTIONAL,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] PeiServices The general PEI Services
+ @param[in] This The PPI instance
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ ///
+ /// Requires a periodic event, not supported in PEI
+ ///
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Function to be called when SMBus.Execute happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval None
+**/
+VOID
+CheckNotification (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ return;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c
new file mode 100644
index 0000000..3e4a6a0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c
@@ -0,0 +1,241 @@
+/** @file
+ PCH Smbus PEIM.
+
+@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 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 "PchSmbus.h"
+
+///
+/// Global variables
+///
+EFI_GUID mPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID;
+
+//
+// Functions
+//
+
+/**
+ This function provides a standard way to execute an SMBUS command
+ PPI as defined in the SMBus Specification. The data can either be of
+ the length byte, word, or a block of data (1 to 32 bytes long).
+ The resulting transaction will be either the SMBus Slave Device accepts
+ this transaction or this function returns with an error
+
+ @param[in] PeiServices PEI services table pointer
+ @param[in] This PEI_SMBUS_PPI instance
+ @param[in] SlaveAddress Smbus Slave device address
+ @param[in] Command Command to be sent
+ @param[in] Operation Which SMBus PPI will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read/write. Must be 1 <= Length <= 32 depending on the Operation
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS Operation success.
+ Length will contain the actual number of bytes read.
+ Buffer will contain the data read.
+ @retval Otherwise Operation failed.
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ SMBUS_INSTANCE *Private;
+ DEBUG ((EFI_D_EVENT, "PEI SmbusExecute() Start, SmbusDeviceAddress=%x, Command=%x, Operation=%x\n", (SlaveAddress.SmbusDeviceAddress << 1), Command, Operation));
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ Status = SmbusExec (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+ ///
+ /// Last step, check notification
+ ///
+ CheckNotification (Private);
+ DEBUG ((EFI_D_EVENT, "PEI SmbusExecute() End\n"));
+ return Status;
+}
+
+/**
+ Initialize the Smbus PPI and program the Smbus BAR
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+InitializePchSmbusPeim (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ SMBUS_INSTANCE *Private;
+ UINTN SmbusRegBase;
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbusPeim() Start\n"));
+
+ Private = (SMBUS_INSTANCE *) AllocatePool (sizeof (SMBUS_INSTANCE));
+ if (Private == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for Private! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializePeiPrivate (PeiServices, Private);
+
+ SmbusRegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ 0
+ );
+ ///
+ /// Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
+ ///
+ MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, Private->SmbusIoBase);
+
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
+
+ ///
+ /// Reset the SMBus host controller
+ ///
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_HOSTC, B_PCH_SMBUS_HOSTC_SSRESET);
+
+ ///
+ /// Enable the SMBus host controller
+ ///
+ MmioAndThenOr8 (
+ SmbusRegBase + R_PCH_SMBUS_HOSTC,
+ (UINT8) (~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)),
+ B_PCH_SMBUS_HOSTC_HST_EN
+ );
+
+ ///
+ /// Clear Status Register before anyone uses the interfaces
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+
+ Status = PeiServicesInstallPpi (&Private->PpiDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Install a call-back for the permanent-memory so that we can fix up internal pointers
+ ///
+ Status = (**PeiServices).NotifyPpi (PeiServices, &Private->NotifyDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbusPeim() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function initializes the SmBus driver in PEI.
+
+ @param[in] PeiServices Standard PEI services
+ @param[in] Private SMBUS private data structure
+
+ @retval None.
+**/
+VOID
+InitializePeiPrivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_STATUS Status;
+
+ Private->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ Private->PeiServices = PeiServices;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &mPeiSmbusPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &(Private->SmbusPolicy)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Private->SmbusIoBase = Private->SmbusPolicy->BaseAddress;
+
+ Private->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ Private->PpiDescriptor.Guid = &gEfiPeiSmbusPpiGuid;
+
+ Private->PpiDescriptor.Ppi = &Private->SmbusPpi;
+
+ Private->SmbusPpi.Execute = SmbusExecute;
+ Private->SmbusPpi.ArpDevice = SmbusArpDevice;
+ Private->SmbusPpi.GetArpMap = SmbusGetArpMap;
+ Private->SmbusPpi.Notify = SmbusNotify;
+
+ Private->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ Private->NotifyDescriptor.Guid = &gEfiPeiMemoryDiscoveredPpiGuid;
+ Private->NotifyDescriptor.Notify = MemoryDiscoveredPpiNotifyCallback;
+
+ Private->DeviceMapEntries = 0;
+ Private->PlatformNumRsvd = Private->SmbusPolicy->NumRsvdAddress;
+ Private->PlatformRsvdAddr = Private->SmbusPolicy->RsvdAddress;
+
+ Private->NotifyFunctionNum = 0;
+
+ return;
+}
+
+/**
+ Fix up pointers since they are located in real memory now.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ SMBUS_INSTANCE *Private;
+
+ Private = SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS (NotifyDescriptor);
+
+ InitializePeiPrivate (PeiServices, Private);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs
new file mode 100644
index 0000000..287dd96
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs
@@ -0,0 +1,41 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 2009 - 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
+
+**/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+#include EFI_PROTOCOL_DEFINITION (SmmBase)
+#include EFI_PROTOCOL_DEFINITION (Smbus)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h
new file mode 100644
index 0000000..8b99bcd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h
@@ -0,0 +1,183 @@
+/** @file
+ PCH Smbus Protocol
+
+@copyright
+ Copyright (c) 2009 - 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
+**/
+#ifndef _SMM_PCH_SMBUS_H
+#define _SMM_PCH_SMBUS_H
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGlueDxe.h"
+
+//
+// Driver Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION (Smbus)
+#include EFI_PROTOCOL_PRODUCER (SmmSmbus)
+
+//
+// Driver Consumed Protcol Prototypes
+//
+#include "PchSmbusCommon.h"
+#endif
+//
+// Definitions
+//
+///
+/// Max number of SMBus devices (7 bit address yields 128 combinations but 21 of those are reserved)
+///
+#define MAX_SMBUS_DEVICES 107
+#define MICROSECOND 10
+#define MILLISECOND (1000 * MICROSECOND)
+#define ONESECOND (1000 * MILLISECOND)
+
+///
+/// Declare a local instance structure for this driver
+///
+typedef struct _SMBUS_INSTANCE {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+
+ UINT32 SmbusIoBase;
+ SMBUS_IO_READ SmbusIoRead;
+ SMBUS_IO_WRITE SmbusIoWrite;
+ SMBUS_IO_DONE IoDone;
+
+ ///
+ /// Published interface
+ ///
+ EFI_SMBUS_HC_PROTOCOL SmbusController;
+
+} SMBUS_INSTANCE;
+
+SMBUS_INSTANCE *mSmbusContext;
+
+//
+// Prototypes
+//
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[in, out] Length Length of data
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbusSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ );
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c
new file mode 100644
index 0000000..89b9fbc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c
@@ -0,0 +1,103 @@
+/** @file
+ PCH Smbus Driver, ARP functions not supported
+
+@copyright
+ Copyright (c) 2009 - 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 "PchSmbus.h"
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ ///
+ /// ARP should be done in DXE SMBUS driver.
+ /// Not needed here.
+ ///
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ ///
+ /// ARP should be done in DXE SMBUS driver.
+ /// Not needed here.
+ ///
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ ///
+ /// Not needed for SMM.
+ ///
+ return EFI_UNSUPPORTED;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c
new file mode 100644
index 0000000..37cb621
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c
@@ -0,0 +1,128 @@
+/** @file
+ PCH Smbus Driver Entry
+
+@copyright
+ Copyright (c) 2009 - 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 "PchSmbus.h"
+
+//
+// Global variables
+//
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+EFI_SMM_SYSTEM_TABLE *mSmst;
+
+EFI_GUID mEfiSmmSmbusProtocolGuid = EFI_SMM_SMBUS_PROTOCOL_GUID;
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[in, out] Length Length of data
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ InitializeSmbusRegisters ();
+
+ return SmbusExec (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+}
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbusSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate SMM Base Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize our module variables
+ ///
+ Status = mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = mSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (SMBUS_INSTANCE), (VOID **) &mSmbusContext);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else {
+ ZeroMem (mSmbusContext, sizeof (SMBUS_INSTANCE));
+
+ mSmbusContext->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ mSmbusContext->IoDone = IoDone;
+ mSmbusContext->SmbusIoRead = SmbusIoRead;
+ mSmbusContext->SmbusIoWrite = SmbusIoWrite;
+ mSmbusContext->SmbusController.Execute = SmbusExecute;
+ mSmbusContext->SmbusController.ArpDevice = SmbusArpDevice;
+ mSmbusContext->SmbusController.GetArpMap = SmbusGetArpMap;
+ mSmbusContext->SmbusController.Notify = SmbusNotify;
+
+ ///
+ /// Install the SMBUS interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmbusContext->Handle,
+ &mEfiSmmSmbusProtocolGuid,
+ &mSmbusContext->SmbusController,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif
new file mode 100644
index 0000000..884f322
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Smm"
+ RefName = "PchSmbusSmm"
+[files]
+"PchSmbusSmm.sdl"
+"PchSmbusSmm.mak"
+"PchSmbus.h"
+"PchSmbusArpDisabled.c"
+"PchSmbusEntry.c"
+"PchSmbus.dxs"
+"PchSmbusSmm.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf
new file mode 100644
index 0000000..bd5a8f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf
@@ -0,0 +1,95 @@
+## @file
+# Component description file for PchSmbus driver
+#
+#@copyright
+# Copyright (c) 2009 - 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 = PchSmbusSmm
+FILE_GUID = 59287178-59B2-49ca-BC63-532B12EA2C53
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSmbusEntry.c
+ PchSmbus.h
+ PchSmbusArpDisabled.c
+ ../Common/PchSmbusExec.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ ../Common
+ $(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]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkProtocolLib
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusSmm
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak
new file mode 100644
index 0000000..32274ff
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak
@@ -0,0 +1,105 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusSmm/PchSmbusSmm.mak 2 2/24/12 2:28a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:28a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusSmm/PchSmbusSmm.mak $
+#
+# 2 2/24/12 2:28a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:27a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbus SMM Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusSmm
+PchSmbusSmm : $(BUILD_DIR)\PchSmbusSmm.mak PchSmbusSmmBin
+
+
+$(BUILD_DIR)\PchSmbusSmm.mak : $(PchSmbusSmm_DIR)\$(@B).cif $(PchSmbusSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusSmm_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusSmm"\
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusSmm_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformSmmLib_LIB) \
+ $(PchSmbusCommonSmmLib_LIB)
+
+PchSmbusSmmBin: $(PchSmbusSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusSmm.mak all \
+ "MY_INCLUDES=$(PchSmbusSmm_INCLUDES)"\
+ "MY_DEFINES=$(PchSmbusSmm_DEFINES)"\
+ GUID=59287178-59B2-49ca-BC63-532B12EA2C53\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchSmbusSmm_DIR)\PchSmbus.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Smbus/Smm/PchSmbusSmm.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl
new file mode 100644
index 0000000..b2db358
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusSmm/PchSmbusSmm.sdl 1 2/08/12 9:27a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:27a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusSmm/PchSmbusSmm.sdl $
+#
+# 1 2/08/12 9:27a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusSmm_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSmbusSmm support in Project"
+End
+
+PATH
+ Name = "PchSmbusSmm_DIR"
+ Help = "PchSmbusSmm file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusSmm.mak to Project"
+ File = "PchSmbusSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusSmm.ffs"
+ Parent = "FV_MAIN"
+ 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 **
+#** **
+#*************************************************************************
+#*************************************************************************