From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- .../LynxPoint/Smbus/Common/PchSmbusCommon.h | 190 ++++++ .../LynxPoint/Smbus/Common/PchSmbusCommonLib.cif | 11 + .../LynxPoint/Smbus/Common/PchSmbusCommonLib.mak | 124 ++++ .../LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl | 92 +++ .../Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c | 661 ++++++++++++++++++++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs | 40 ++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h | 360 +++++++++++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c | 681 +++++++++++++++++++++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif | 14 + .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf | 93 +++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak | 103 ++++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl | 67 ++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c | 149 +++++ .../Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs | 44 ++ .../Chipset/LynxPoint/Smbus/Pei/PchSmbus.h | 409 +++++++++++++ .../Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c | 444 ++++++++++++++ .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif | 14 + .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf | 88 +++ .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak | 97 +++ .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl | 67 ++ .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c | 291 +++++++++ .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif | 15 + .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf | 91 +++ .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak | 97 +++ .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl | 67 ++ .../LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c | 117 ++++ .../Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c | 241 ++++++++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs | 41 ++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbus.h | 183 ++++++ .../LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c | 103 ++++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c | 128 ++++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif | 14 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf | 95 +++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak | 105 ++++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl | 67 ++ 35 files changed, 5403 insertions(+) create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl (limited to 'ReferenceCode/Chipset/LynxPoint/Smbus') 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 @@ + + name = "PchSmbusCommonLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Common" + RefName = "PchSmbusCommonLib" +[files] +"PchSmbusCommonLib.sdl" +"PchSmbusCommonLib.mak" +"PchSmbusExec.c" +"PchSmbusCommon.h" + \ 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 ** +#** ** +#************************************************************************* +#************************************************************************* -- cgit v1.2.3