summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/Smbus/Pei
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/Smbus/Pei')
-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
14 files changed, 2082 insertions, 0 deletions
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;
+}