diff options
Diffstat (limited to 'Chipset/SB/SmBus')
-rw-r--r-- | Chipset/SB/SmBus/SmBus.cif | 20 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBus.mak | 146 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBus.sdl | 61 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusCommon.c | 559 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusCommon.h | 226 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusDxe.c | 940 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusDxe.dxs | 82 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusDxe.h | 219 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusPciHooks.c | 129 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusPei.c | 527 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusPei.dxs | 73 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusPei.h | 182 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusPorting.c | 705 | ||||
-rw-r--r-- | Chipset/SB/SmBus/SmBusSmm.dxs | 65 |
14 files changed, 3934 insertions, 0 deletions
diff --git a/Chipset/SB/SmBus/SmBus.cif b/Chipset/SB/SmBus/SmBus.cif new file mode 100644 index 0000000..5f3dee2 --- /dev/null +++ b/Chipset/SB/SmBus/SmBus.cif @@ -0,0 +1,20 @@ +<component> + name = "SmBus" + category = ModulePart + LocalRoot = "Chipset\SB\SmBus\" + RefName = "SmBus" +[files] +"SmBus.sdl" +"SmBus.mak" +"SmBusCommon.h" +"SmBusPei.h" +"SmBusDxe.h" +"SmBusCommon.c" +"SmBusPorting.c" +"SmBusPei.c" +"SmBusDxe.c" +"SmBusPciHooks.c" +"SmBusPei.dxs" +"SmBusDxe.dxs" +"SmBusSmm.dxs" +<endComponent> diff --git a/Chipset/SB/SmBus/SmBus.mak b/Chipset/SB/SmBus/SmBus.mak new file mode 100644 index 0000000..7a5148e --- /dev/null +++ b/Chipset/SB/SmBus/SmBus.mak @@ -0,0 +1,146 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (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 Chipset/SmBus/SmBus.mak 1 6/06/12 8:00a Victortu $ +# +# $Revision: 1 $ +# +# $Date: 6/06/12 8:00a $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBus.mak $ +# +# 1 6/06/12 8:00a Victortu +# Implement EFI_PEI_SMBUS2_PPI Support. +# +# 6 7/19/11 8:28a Abelwu +# [TAG] EIP63768 +# [Category] Improvement +# [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +# [Files] SmBus.mak +# +# 5 6/17/11 5:52p Artems +# EIP 53378: Replaced tabs with spaces, formatted to follow coding +# standard +# +# 4 5/18/11 11:50a Artems +# +# 3 1/27/11 9:48p Abelwu +# Supports SMBUS Protocol in early DXE phase. (EIP#40778) +# +# 2 10/16/09 7:06p Artems +# Updated copyright header +# +# 1 1/09/09 6:53p Artems +# New implementation of SMBus EIP 16730 +# +# 1 3/18/07 5:23p Felixp +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: SmBus.mak +# +# Description: This make file builds SMBus PEI and DXE components +# and link them to respective binary. +# +#<AMI_FHDR_END> +#********************************************************************** +!IFNDEF PI_SPECIFICATION_VERSION +PI_SPECIFICATION_VERSION = 0 +!ENDIF + +all : SmBusPei #SmBusDxe + +SMBUS_PEI_OBJECTS=\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusCommon.obj\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPorting.obj\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPei.obj + +#SMBUS_DXE_OBJECTS=\ +#$$(BUILD_DIR)\$(SmBus_DIR)\SmBusCommon.obj\ +#$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPorting.obj\ +#$$(BUILD_DIR)\$(SmBus_DIR)\SmBusDxe.obj + +SMBUS_PCI_OBJECTS=\ +$$(BUILD_DIR)\$(SmBus_DIR)\SmBusPciHooks.obj\ + +$(BUILD_DIR)\SmBus.mak : $(SmBus_DIR)\$(@B).cif $(SmBus_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(SmBus_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +#SmBusDxe : $(BUILD_DIR)\SmBus.mak SmBusDxeBin +SmBusPei : $(BUILD_DIR)\SmBus.mak SmBusPeiBin +#PciBusSrc : $(BUILD_DIR)\SmBus.mak SmBusPciHooksBin +$(BUILD_DIR)\AMISmBusLib.lib : $(BUILD_DIR)\SmBus.mak SmBusPciHooksBin + +#SmBusDxeBin : $(AMIDXELIB) +# $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ +# /f $(BUILD_DIR)\SmBus.mak all\ +# NAME=SmBusDxe\ +# MAKEFILE=$(BUILD_DIR)\SmBus.mak \ +# "OBJECTS=$(SMBUS_DXE_OBJECTS)" \ +# GUID=4B680E2D-0D63-4f62-B930-7AE995B9B3A3\ +# ENTRY_POINT=SmBusDxeEntryPoint\ +#!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A +# TYPE=DXESMM_DRIVER \ +# DEPEX1=$(SmBus_DIR)\SmBusSmm.DXS DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \ +# DEPEX2=$(SmBus_DIR)\SmBusDxe.DXS DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \ +#!ELSE +# TYPE=BS_DRIVER \ +# DEPEX1=$(SmBus_DIR)\SmBusDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \ +#!ENDIF +# COMPRESS=1\ + +SmBusPeiBin : $(AMICSPLib) $(AMIPEILIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmBus.mak all\ + NAME=SmBusPei\ + MAKEFILE=$(BUILD_DIR)\SmBus.mak \ +!IF "$(x64_BUILD)"=="1" + BUILD_DIR=$(BUILD_DIR)\IA32\ +!ELSE + BUILD_DIR=$(BUILD_DIR)\ +!ENDIF + "OBJECTS=$(SMBUS_PEI_OBJECTS)" \ + GUID=9EA28D33-0175-4788-BEA8-6950516030A5 \ + ENTRY_POINT=SmBusPeiEntryPoint \ + TYPE=PEIM \ + "MY_INCLUDES=$(INTEL_PCH_INCLUDES)" \ + DEPEX1=$(SmBus_DIR)\SmBusPei.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 + +SmBusPciHooksBin : + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\SmBus.mak all\ + NAME=AMISmBusLib\ + MAKEFILE=$(BUILD_DIR)\SmBus.mak\ + OBJECTS="$(SMBUS_PCI_OBJECTS)"\ + TYPE=LIBRARY\ + "CFLAGS=$(CFLAGS)" + +#************************************************************************* +#************************************************************************* +#** ** +#** (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/Chipset/SB/SmBus/SmBus.sdl b/Chipset/SB/SmBus/SmBus.sdl new file mode 100644 index 0000000..e7e6dcb --- /dev/null +++ b/Chipset/SB/SmBus/SmBus.sdl @@ -0,0 +1,61 @@ +TOKEN + Name = "SmBus_SUPPORT" + Value = "1" + Help = "Main switch to enable SmBus support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "PI_SPECIFICATION_VERSION" ">=" "0x10000" +End + +TOKEN + Name = "SMBUS_BLINDING_PROTOCOL_SUPPORT" + Value = "1" + Help = "On - SMBus EFI 1.1 driver support." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "PCH_SPD_WRITE_DISABLE" + Value = "1" + Help = "0: Turn off SPD Write Disable.\1: Turn on SPD Write Disable." + TokenType = Integer + TargetH = Yes +End + +PATH + Name = "SmBus_DIR" +End + +MODULE + Help = "Includes SmBus.mak to Project" + File = "SmBus.mak" +End + +ELINK + Name = "$(BUILD_DIR)\SmBusPei.ffs" + Parent = "FV_BB" + Help = "Template Smbus PEI component" + InvokeOrder = AfterParent +End + +#ELINK +# Name = "$(BUILD_DIR)\SmBusDxe.ffs" +# Parent = "FV_MAIN" +# Help = "Template Smbus DXE component" +# InvokeOrder = AfterParent +#End + +ELINK + Name = "OEM_PCI_DEVICE_CALLBACK(0, 0, SmBusProtectedPciDevice)," + Parent = "OEM_SKIP_PCI_DEVICE" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(BUILD_DIR)\AMISmBusLib.lib" + Parent = "PCIBUSSRCLIB" + InvokeOrder = AfterParent +End diff --git a/Chipset/SB/SmBus/SmBusCommon.c b/Chipset/SB/SmBus/SmBusCommon.c new file mode 100644 index 0000000..e4fbae7 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusCommon.c @@ -0,0 +1,559 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusCommon.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusCommon.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 5 6/27/11 2:26p Artems +// Updated year in file header +// +// 4 6/17/11 5:53p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 3 10/16/09 7:21p Artems +// Updated copyright header +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusCommon.c +// +// Description: SMBUS driver common functions implementation +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <AmiLib.h> +#include "SmBusCommon.h" + +UINT8 SmBusSpecReservedAddress[SMBUS_SPEC_RESERVED_ADDRESS] = { + 0x00, // 0000 000 0 General Call Address + // 0000 000 1 START byte + 0x01, // 0000 001 X CBUS address + 0x02, // 0000 010 X Address reserved for different bus format + 0x03, // 0000 011 X Reserved for future use + 0x04, // 0000 1XX X Reserved for future use + 0x05, + 0x06, + 0x07, + 0x28, // 0101 000 X Reserved for ACCESS.bus host + 0x37, // 0110 111 X Reserved for ACCESS.bus default address + 0x78, // 1111 0XX X 10-bit slave addressing + 0x79, + 0x7a, + 0x7b, + 0x7c, // 1111 1XX X Reserved for future use + 0x7d, + 0x7e, + 0x7f, + 0x08, // 0001 000 X SMBus Host + 0x0c, // 0001 100 X SMBus Alert Response Address + 0x61 // 1100 001 X SMBus Device Default Address +}; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusRead +// +// Description: This function reads given number of bytes from SMBUS device +// +// Input: IN UINT16 SmBusBase - SMBUS device IO address base +// IN UINT16 Offset - SMBUS device IO address offset +// IN UINTN ByteCount - number of bytes to read +// OUT UINT8 *Buffer - pointer to buffer to store data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusRead ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + OUT UINT8 *Buffer +) +{ + UINTN i; + + for(i = 0; i < ByteCount; i++) + Buffer[i] = IoRead8(SmBusBase + Offset); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusWrite +// +// Description: This function writes given number of bytes to SMBUS device +// +// Input: IN UINT16 SmBusBase - SMBUS device IO address base +// IN UINT16 Offset - SMBUS device IO address offset +// IN UINTN ByteCount - number of bytes to write +// IN UINT8 *Buffer - pointer to buffer to get data from +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusWrite ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + IN UINT8 *Buffer +) +{ + UINTN i; + + for(i = 0; i < ByteCount; i++) + IoWrite8(SmBusBase + Offset, Buffer[i]); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ArpDevice +// +// Description: This function assign address to specific or all devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN BOOLEAN ArpAll - Enumerate all devices flag +// IN EFI_SMBUS_UDID *SmbusUdid - pointer to device ID to assign new address +// IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return assigned address +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ArpDevice ( + IN SMBUS_PRIVATE *Context, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +) +{ + if(ArpAll) + return ArpDeviceFull(Context); + else + return ArpDeviceDirected(Context, SmbusUdid, SlaveAddress); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetArpMap +// +// Description: This function returns list of enumerated devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN OUT UINTN *Length - pointer to store size of address map +// IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap - pointer to store pointer to address map +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS GetArpMap ( + IN SMBUS_PRIVATE *Context, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +) +{ + *Length = Context->ArpDeviceCount; + *SmbusDeviceMap = Context->ArpDeviceList; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PrepareToArp +// +// Description: This function sends PREPARE_TO_ARP command to devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS PrepareToArp ( + IN SMBUS_PRIVATE *Context +) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer; + + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + Length = 1; + Buffer = SMBUS_DATA_PREPARE_TO_ARP; + + Status = Execute ( + Context, + SlaveAddress, + SMBUS_DATA_PREPARE_TO_ARP, + EfiSmbusSendByte, + TRUE, + &Length, + &Buffer ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: IsAddressAvailable +// +// Description: This function checks if given address is available +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN UINT8 Address - address to check +// +// Output: TRUE - address is available +// FALSE - address is not available +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN IsAddressAvailable ( + IN SMBUS_PRIVATE *Context, + IN UINT8 Address +) +{ + UINTN Index; + + for(Index = 0; Index < Context->ArpDeviceCount; Index++) + if(Address == Context->ArpDeviceList[Index].SmbusDeviceAddress.SmbusDeviceAddress) + return FALSE; + + for(Index = 0; Index < Context->BoardReservedAddressCount; Index++) + if(Address == Context->BoardReservedAddressList[Index]) + return FALSE; + + for(Index = 0; Index < SMBUS_SPEC_RESERVED_ADDRESS; Index++) + if(Address == SmBusSpecReservedAddress[Index]) + return FALSE; + + return TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetAvailableAddress +// +// Description: This function returns available address +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// +// Output: UINT8 - address +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 GetAvailableAddress ( + IN SMBUS_PRIVATE *Context +) +{ + UINT8 Address; + + for(Address = SMBUS_LOWEST_AVAILABLE_ADDRESS; + Address <= SMBUS_HIGHEST_AVAILABLE_ADDRESS; + Address++) + if(IsAddressAvailable(Context, Address)) + return Address; + + return 0xff; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ArpDeviceFull +// +// Description: This function enumerates all devices connected to SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ArpDeviceFull ( + IN SMBUS_PRIVATE *Context +) +{ + EFI_SMBUS_DEVICE_MAP DeviceMap; + EFI_STATUS Status; + + Status = PrepareToArp(Context); + if(EFI_ERROR(Status)) + return (Status == EFI_DEVICE_ERROR) ? EFI_SUCCESS : Status; + + do + { + Status = GetUdidGeneral(Context, &DeviceMap); + if(EFI_ERROR(Status)) + break; + + if(DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress == 0x7f) //0xff >> 1 + { + DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress = GetAvailableAddress(Context); + if(DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress == 0xff) + return EFI_OUT_OF_RESOURCES; + } + else + { + if((DeviceMap.SmbusDeviceUdid.DeviceCapabilities & 0xC0) != 0 && + !IsAddressAvailable(Context, (UINT8)DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress)) + { + DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress = GetAvailableAddress(Context); + if(DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress == 0xff) + return EFI_OUT_OF_RESOURCES; + } + } + + Status = AssignAddress(Context, &DeviceMap); + if(EFI_ERROR(Status)) + return Status; + + //save assigned address to our database + Context->ArpDeviceList[Context->ArpDeviceCount] = DeviceMap; + Context->ArpDeviceCount++; + } while(Context->ArpDeviceCount < Context->MaxDevices); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ArpDeviceDirected +// +// Description: This function assign given address to given device +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN EFI_SMBUS_UDID *SmbusUdid - pointer to device ID +// IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return assigned address +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ArpDeviceDirected ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_UDID *SmbusUdid, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress +) +{ + UINT8 AssignedAddress; + EFI_SMBUS_DEVICE_MAP DeviceMap; + EFI_STATUS Status; + + if(Context->ArpDeviceCount > Context->MaxDevices) + return EFI_OUT_OF_RESOURCES; + + AssignedAddress = GetAvailableAddress(Context); + if(AssignedAddress == 0xff) + return EFI_OUT_OF_RESOURCES; + + DeviceMap.SmbusDeviceAddress.SmbusDeviceAddress = AssignedAddress; + DeviceMap.SmbusDeviceUdid = *SmbusUdid; + + Status = AssignAddress(Context, &DeviceMap); + if(EFI_ERROR(Status)) + return Status; + +//save assigned address to our database + Context->ArpDeviceList[Context->ArpDeviceCount] = DeviceMap; + Context->ArpDeviceCount++; + + *SlaveAddress = DeviceMap.SmbusDeviceAddress; + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: AssignAddress +// +// Description: This function sends ASSIGN_ADDRESS command via SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to device Udid/Address pair +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS AssignAddress ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_DEVICE_MAP *DeviceMap + ) +{ + UINT8 Buffer[GET_UDID_BUFFER_SIZE]; + UINTN Length; + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + + ConvertMapToBuffer(DeviceMap, Buffer); + + Length = GET_UDID_BUFFER_SIZE; + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + + Status = Execute ( + Context, + SlaveAddress, + SMBUS_DATA_ASSIGN_ADDRESS, + EfiSmbusWriteBlock, + TRUE, + &Length, + Buffer ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetUdidGeneral +// +// Description: This function sends GET_UDID_GENERAL command via SMBUS +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// OUT EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to store device Udid/Address pair +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS GetUdidGeneral ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap +) +{ + UINT8 Buffer[GET_UDID_BUFFER_SIZE]; + UINTN Length; + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + + Length = GET_UDID_BUFFER_SIZE; + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + + Status = Execute ( + Context, + SlaveAddress, + SMBUS_DATA_GET_UDID_GENERAL, + EfiSmbusReadBlock, + TRUE, + &Length, + Buffer ); + + if(EFI_ERROR(Status) || Length != GET_UDID_BUFFER_SIZE) + return EFI_DEVICE_ERROR; + + ConvertBufferToMap(DeviceMap, Buffer); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConvertMapToBuffer +// +// Description: This function converts EFI_SMBUS_DEVICE_MAP structure into UINT8[] buffer +// +// Input: IN EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to structure to convert from +// OUT UINT8 *Buffer - pointer buffer to convert to +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ConvertMapToBuffer ( + IN EFI_SMBUS_DEVICE_MAP *DeviceMap, + OUT UINT8 *Buffer +) +{ + 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); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConvertBufferToMap +// +// Description: This function converts UINT8[] buffer into EFI_SMBUS_DEVICE_MAP structure +// +// Input: OUT EFI_SMBUS_DEVICE_MAP *DeviceMap - pointer to structure to convert to +// IN UINT8 *Buffer - pointer buffer to convert from +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ConvertBufferToMap ( + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap, + IN UINT8 *Buffer + ) +{ + 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); +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Chipset/SB/SmBus/SmBusCommon.h b/Chipset/SB/SmBus/SmBusCommon.h new file mode 100644 index 0000000..0dda40d --- /dev/null +++ b/Chipset/SB/SmBus/SmBusCommon.h @@ -0,0 +1,226 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusCommon.h 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusCommon.h $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 5 6/27/11 2:26p Artems +// Updated year in file header +// +// 4 6/17/11 5:52p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 3 10/16/09 7:08p Artems +// Updated copyright header +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusCommon.h +// +// Description: This file contains shared PEI and DXE Smbus functions and +// data structures definitions +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> +#ifndef __SMBUS_COMMON__H__ +#define __SMBUS_COMMON__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Efi.h> +#include <AmiCspLib.h> +#include <SmBus.h> + +#define SMBUS_ADDRESS_ARP 0x61 // 1100 001 X SMBus Device Default Address + +#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_SPEC_RESERVED_ADDRESS 21 +#define GET_UDID_BUFFER_SIZE 17 + +#define SMBUS_LOWEST_AVAILABLE_ADDRESS 0x08 +#define SMBUS_HIGHEST_AVAILABLE_ADDRESS 0x77 + +typedef VOID (* SMBUS_WAIT ) ( + IN UINTN Microseconds + ); + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: SMBUS_PRIVATE +// +// Description: AMI SMBUS driver private data structure +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// SmBusBase UINT16 SMBUS device base IO address +// SmBusWait SMBUS_WAIT Pointer to Wait function +// MaxDevices UINT8 Maximum number of supported devices +// BoardReservedAddressCount UINT8 Number of board reserved addesses +// BoardReservedAddressList UINT8* Pointer to board reserved addresses list +// ArpDeviceCount UINT8 Number of current devices +// ArpDeviceList EFI_SMBUS_DEVICE_MAP* Pointer to list of current devices +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct _SMBUS_PRIVATE +{ + UINT16 SmBusBase; + SMBUS_WAIT SmBusWait; + UINT8 MaxDevices; + UINT8 BoardReservedAddressCount; + UINT8 *BoardReservedAddressList; + UINT8 ArpDeviceCount; + EFI_SMBUS_DEVICE_MAP *ArpDeviceList; + +} SMBUS_PRIVATE; + + +//******************************************************* +// Shared functions prototypes +//******************************************************* + +VOID SmBusRead ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + OUT UINT8 *Buffer +); + +VOID SmBusWrite ( + IN UINT16 SmBusBase, + IN UINT16 Offset, + IN UINTN ByteCount, + IN UINT8 *Buffer +); + +EFI_STATUS Execute ( + IN SMBUS_PRIVATE *Context, + 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 CheckNotify ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress, + OUT UINTN *Data +); + +EFI_STATUS ArpDevice ( + IN SMBUS_PRIVATE *Context, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +); + +EFI_STATUS GetArpMap ( + IN SMBUS_PRIVATE *Context, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +); + +EFI_STATUS PrepareToArp ( + IN SMBUS_PRIVATE *Context +); + +EFI_STATUS ArpDeviceDirected ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_UDID *SmbusUdid, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress +); + +EFI_STATUS ArpDeviceFull ( + IN SMBUS_PRIVATE *Context +); + +EFI_STATUS AssignAddress ( + IN SMBUS_PRIVATE *Context, + IN EFI_SMBUS_DEVICE_MAP *DeviceMap +); + +EFI_STATUS GetUdidGeneral ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap +); + +BOOLEAN IsAddressAvailable ( + IN SMBUS_PRIVATE *Context, + IN UINT8 Address +); + +UINT8 GetAvailableAddress ( + IN SMBUS_PRIVATE *Context +); + +VOID ConvertMapToBuffer ( + IN EFI_SMBUS_DEVICE_MAP *DeviceMap, + OUT UINT8 *Buffer +); + +VOID ConvertBufferToMap ( + OUT EFI_SMBUS_DEVICE_MAP *DeviceMap, + IN UINT8 *Buffer +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + diff --git a/Chipset/SB/SmBus/SmBusDxe.c b/Chipset/SB/SmBus/SmBusDxe.c new file mode 100644 index 0000000..2aee2ff --- /dev/null +++ b/Chipset/SB/SmBus/SmBusDxe.c @@ -0,0 +1,940 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusDxe.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 11 7/21/11 7:32a Abelwu +// [TAG] None +// [Category] New Feature +// [Description] Added SMBus SMM protocol support. +// [Files] SmBusDxe.c +// +// 10 7/19/11 8:28a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] 1. Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 +// compliance +// 2. Added SMBus SMM protocol support. +// +// 9 6/17/11 5:54p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 8 5/18/11 11:51a Artems +// +// 7 1/27/11 9:48p Abelwu +// Supports SMBUS Protocol in early DXE phase. (EIP#40778) +// +// 6 10/13/10 4:16p Artems +// EIP 45184 - fixed pointer size to be same in IA32 and X64 mode +// +// 5 10/16/09 7:32p Artems +// Updated copyright header +// +// 4 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 3 1/29/09 4:20p Artems +// Change "Note" to "Notes" for HelpBuilder +// +// 2 1/28/09 6:51p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusDxe.c +// +// Description: SMBUS DXE functions implementation +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <AmiHobs.h> +#include "SmBusDxe.h" +#include <Protocol\PciRootBridgeIo.h> + +#define MICROSECOND 10 +#define MILLISECOND (1000 * MICROSECOND) +#define ONESECOND (1000 * MILLISECOND) + +extern EFI_GUID SmBusIdentifierGuid; + +EFI_DRIVER_BINDING_PROTOCOL SmBusDriverBindingProtocol = { + DriverBindingSupported, + DriverBindingStart, + DriverBindingStop, + 0x10, + NULL, + NULL + }; + +SMBUS_DXE_PRIVATE *gPrivate; +EFI_HANDLE gControllerHandle = NULL; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusEarlyDxeDriver +// +// Description: This function configures and installs SMBUS protocol before +// SMBus EFI 1.1 drvier is installed. +// +// Input: None +// +// Output: EFI_STATUS +// EFI_SUCCESS - SMBUS protocol has been installed. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusEarlyDxeDriver ( VOID ) +{ + EFI_STATUS Status; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo = NULL; + EFI_GUID EfiPciRootBridgeIoProtocolGuid = \ + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID; +/* Porting Required + UINT32 IoBase32; + UINT16 Cmd16; +Porting End */ + + Status = pBS->AllocatePool( EfiBootServicesData, \ + sizeof(SMBUS_DXE_PRIVATE), \ + &gPrivate ); + if (EFI_ERROR(Status)) return Status; + + Status = pBS->AllocatePool( \ + EfiBootServicesData, \ + sizeof(EFI_SMBUS_DEVICE_MAP) * MAX_DXE_ARP_DEVICES, \ + &(gPrivate->SmBusContext.ArpDeviceList) ); + if (EFI_ERROR(Status)) { + pBS->FreePool( gPrivate ); + return Status; + } + + gPrivate->SmBusProtocol.Execute = SmBusDxeExecute; + gPrivate->SmBusProtocol.ArpDevice = SmBusDxeArpDevice; + gPrivate->SmBusProtocol.GetArpMap = SmBusDxeGetArpMap; + gPrivate->SmBusProtocol.Notify = SmBusDxeNotify; + + gPrivate->NotifyEvent = NULL; + gPrivate->Identifier = SmBusIdentifierGuid; + + gPrivate->SmBusContext.SmBusWait = SmBusDxeWait; + gPrivate->SmBusContext.MaxDevices = MAX_DXE_ARP_DEVICES; + RetrieveHobData( gPrivate ); + +/* Porting Required + Status = pBS->LocateProtocol( &EfiPciRootBridgeIoProtocolGuid, \ + NULL, \ + &PciRootBridgeIo ); + // Update SMBus I/O Base Address + PciRootBridgeIo->Pci.Read( PciRootBridgeIo, \ + EfiPciWidthUint32, \ + SMBUS_REG(SMBUS_REG_BASE_ADDR), \ + 1, \ + &IoBase32 ); + IoBase32 &= 0xfffffffe; + gPrivate->SmBusContext.SmBusBase = (UINT16)IoBase32; + + // Enable SMBus controller I/O decode. + PciRootBridgeIo->Pci.Read( PciRootBridgeIo, \ + EfiPciWidthUint16, \ + SMBUS_REG(SMBUS_REG_PCICMD), \ + 1, \ + &Cmd16 ); + Cmd16 |= 1; + PciRootBridgeIo->Pci.Write( PciRootBridgeIo, \ + EfiPciWidthUint16, \ + SMBUS_REG(SMBUS_REG_PCICMD), \ + 1, \ + &Cmd16 ); +Porting End */ + + Status = pBS->InstallProtocolInterface( &gControllerHandle, \ + &gEfiSmbusProtocolGuid, \ + EFI_NATIVE_INTERFACE, + &gPrivate->SmBusProtocol ); + + if (EFI_ERROR(Status)) { + TRACE((-1, "SBSmbusDxe: Install Protocol Interface Failed.\n")); + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusSmmExecute +// +// Description: This Protocol Function can be used to execute SMBus command +// on a particular SMBus controller in SMM. +// +// Input: *This - Pointer to the SMBus Protocol structure +// SlaveAddress - Address of the SMBus device +// Command - Command to be sent to the device +// Operation - SMBus operation to be performed +// PecCheck - Flag indicating the usage of PEC +// *Length - Length of the data in the Buffer (IN or OUT) +// *Buffer - Pointer to the buffer with the data (IN or OUT) +// +// Output: EFI_STATUS +// +// Notes: PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusSmmExecute ( + 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 ) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; +/* + // Porting Required + UINT16 SmBusBase = READ_PCI16_SMBUS(SMBUS_REG_BASE_ADDR) & 0xfff0; + UINT16 SmBusCmd = READ_PCI16_SMBUS(SMBUS_REG_PCICMD); + + if (SmBusBase == 0) { // Assign a new I/O if the original address is 0 + WRITE_PCI16_SMBUS(SMBUS_REG_BASE_ADDR, SMBUS_BASE_ADDRESS); + SmBusBase = SMBUS_BASE_ADDRESS; + } + + gPrivate->SmBusContext.SmBusBase = SmBusBase; + + if ((SmBusCmd & 1) == 0) { // Enable I/O command if needed. + WRITE_PCI16_SMBUS(SMBUS_REG_PCICMD, 1); + } + // Porting End + + Status = Execute( &(((SMBUS_DXE_PRIVATE *)This)->SmBusContext), \ + SlaveAddress, \ + Command, \ + Operation, \ + PecCheck, \ + Length, \ + Buffer ); + + // Porting Required + // Restore the SMBus PCI Command Register + WRITE_PCI16_SMBUS(SMBUS_REG_PCICMD, SmBusCmd); + // Porting End +*/ + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SMBusInSmmInit +// +// Description: This function installs SMBus SMM protocol for the SMBus +// controller present in the SB. +// +// Input: ImageHandle - Image handle for the SB component +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SMBusInSmmInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_HANDLE Handle = NULL; + EFI_GUID SmmSmbusProtocolGuid = \ + AMI_SMBUS_SMM_PROTOCOL_GUID; + static SMBUS_DXE_PRIVATE SmbusSmmPrivate; + + gPrivate = &SmbusSmmPrivate; + gPrivate->SmBusProtocol.Execute = SmBusSmmExecute; + gPrivate->SmBusProtocol.ArpDevice = SmBusDxeArpDevice; + gPrivate->SmBusProtocol.GetArpMap = SmBusDxeGetArpMap; + gPrivate->SmBusProtocol.Notify = SmBusDxeNotify; + +#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A) + Status = InitAmiSmmLib( ImageHandle, SystemTable ); + if (EFI_ERROR(Status)) return Status; + + return pSmst->SmmInstallProtocolInterface( &Handle, \ + &SmmSmbusProtocolGuid, \ + EFI_NATIVE_INTERFACE, \ + &gPrivate->SmBusProtocol ); +#else + return pBS->InstallProtocolInterface( &Handle, + &SmmSmbusProtocolGuid, + EFI_NATIVE_INTERFACE, + &gPrivate->SmBusProtocol ); +#endif +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SMBusNotInSmmInit +// +// Description: This function installs SMBus DXE protocol for the SMBus +// controller present in the SB. +// +// Input: ImageHandle - Image handle for the SB component +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SMBusNotInSmmInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status; + + Status = SmBusEarlyDxeDriver(); + +#if SMBUS_BLINDING_PROTOCOL_SUPPORT + SmBusDriverBindingProtocol.ImageHandle = ImageHandle; + SmBusDriverBindingProtocol.DriverBindingHandle = ImageHandle; + Status = pBS->InstallMultipleProtocolInterfaces( \ + &ImageHandle, \ + &gEfiDriverBindingProtocolGuid, \ + &SmBusDriverBindingProtocol, \ + NULL ); +#endif + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusDxeEntryPoint +// +// Description: This function installs SMBus DXE/SMM protocols for the SMBus +// controller present in the SB. +// +// Input: ImageHandle - Image handle for the SB component +// *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS +// +// Notes: GENERALLY NO PORTING REQUIRED +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + InitAmiLib(ImageHandle, SystemTable); + + return InitSmmHandlerEx( ImageHandle, \ + SystemTable, \ + SMBusInSmmInit, \ + SMBusNotInSmmInit ); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverBindingSupported +// +// Description: SMBUS DXE Driver binding protocol Supported function +// +// Input: IN EFI_DRIVER_BINDING_PROTOCOL* This - pointer to EFI_DRIVER_BINDING_PROTOCOL structure +// IN EFI_HANDLE ControllerHandle - handle of controller to serve +// IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath - pointer to EFI_DEVICE_PATH_PROTOCOL structure +// +// Output: EFI_SUCCESS - driver supports given controller +// EFI_UNSUPPORTED - given controller not supported +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 PciData[4]; + + Status = pBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR (Status)) + return EFI_UNSUPPORTED; + + // + // See if this is a PCI Smbus Controller by looking at the Class Code Register + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0x8, + 1, + (VOID *)PciData ); + if (EFI_ERROR (Status)) + return EFI_UNSUPPORTED; + + pBS->CloseProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + + return (PciData[3] == 0x0c && PciData[2] == 0x05) ? EFI_SUCCESS : EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverBindingStart +// +// Description: SMBUS DXE Driver binding protocol Start function +// +// Input: IN EFI_DRIVER_BINDING_PROTOCOL* This - pointer to EFI_DRIVER_BINDING_PROTOCOL structure +// IN EFI_HANDLE ControllerHandle - handle of controller to serve +// IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath - pointer to EFI_DEVICE_PATH_PROTOCOL structure +// +// Output: EFI_SUCCESS - driver supports given controller +// EFI_UNSUPPORTED - given controller not supported +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +) +{ + EFI_STATUS Status; + SMBUS_DXE_PRIVATE *Private; + static BOOLEAN EarlyDxeProtocol = TRUE; + + if (EarlyDxeProtocol) { + Status = pBS->UninstallProtocolInterface( gControllerHandle, \ + &gEfiSmbusProtocolGuid, \ + &gPrivate->SmBusProtocol ); + if (Status == EFI_SUCCESS) { + pBS->FreePool( gPrivate->SmBusContext.ArpDeviceList ); + pBS->FreePool( gPrivate ); + } + EarlyDxeProtocol = FALSE; + } + + Status = pBS->AllocatePool(EfiBootServicesData, + sizeof(SMBUS_DXE_PRIVATE), + &Private); + if(EFI_ERROR(Status)) + return Status; + + Status = pBS->AllocatePool(EfiBootServicesData, + sizeof(EFI_SMBUS_DEVICE_MAP) * MAX_DXE_ARP_DEVICES, + &(Private->SmBusContext.ArpDeviceList)); + if(EFI_ERROR(Status)) + return Status; + + Status = pBS->OpenProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + (VOID **) &(Private->PciIo), + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR (Status)) + { + pBS->FreePool(Private->SmBusContext.ArpDeviceList); + pBS->FreePool(Private); + return Status; + } + + Private->SmBusProtocol.Execute = SmBusDxeExecute; + Private->SmBusProtocol.ArpDevice = SmBusDxeArpDevice; + Private->SmBusProtocol.GetArpMap = SmBusDxeGetArpMap; + Private->SmBusProtocol.Notify = SmBusDxeNotify; + + Private->NotifyEvent = NULL; + Private->Identifier = SmBusIdentifierGuid; + + Private->SmBusContext.SmBusWait = SmBusDxeWait; + Private->SmBusContext.MaxDevices = MAX_DXE_ARP_DEVICES; + RetrieveHobData(Private); + +//TODO Fill Private->SmBusContext.SmBusBase with value read from PCI device + + DListInit(&(Private->NotifyList)); + + Status = pBS->InstallMultipleProtocolInterfaces( + &ControllerHandle, + &gEfiSmbusProtocolGuid, &Private->SmBusProtocol, + NULL); + if (EFI_ERROR (Status)) + { + pBS->CloseProtocol( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + pBS->FreePool(Private->SmBusContext.ArpDeviceList); + pBS->FreePool(Private); + } + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DriverBindingStop +// +// Description: SMBUS DXE Driver binding protocol Stop function +// +// Input: IN EFI_DRIVER_BINDING_PROTOCOL* This - pointer to EFI_DRIVER_BINDING_PROTOCOL structure +// IN EFI_HANDLE ControllerHandle - handle of controller to serve +// IN UINTN NumberOfChildren - number of child devices of controller +// IN EFI_HANDLE* ChildHandleBuffer - pointer to child devices handles array +// +// Output: EFI_SUCCESS - driver was successfully uninstalled from controller +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer +) +{ + EFI_STATUS Status; + SMBUS_DXE_PRIVATE *Private; + EFI_SMBUS_HC_PROTOCOL *SmBusProtocol; + + Status = pBS->OpenProtocol ( + ControllerHandle, + &gEfiSmbusProtocolGuid, + &SmBusProtocol, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL ); + if (EFI_ERROR (Status)) + return EFI_NOT_STARTED; + + pBS->CloseProtocol ( + ControllerHandle, + &gEfiSmbusProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + + Private = (SMBUS_DXE_PRIVATE *) SmBusProtocol; + + // uninstall the protocol + Status = pBS->UninstallMultipleProtocolInterfaces ( + ControllerHandle, + &gEfiSmbusProtocolGuid, &Private->SmBusProtocol, + NULL ); + if (EFI_ERROR (Status)) + return Status; + + if(Private->NotifyEvent != 0) + { + SMBUS_NOTIFY_LINK *NotifyLink = (SMBUS_NOTIFY_LINK *)(Private->NotifyList.pHead); + SMBUS_NOTIFY_LINK *DeleteLink; + + pBS->CloseEvent(Private->NotifyEvent); + while(NotifyLink != 0) + { + DeleteLink = NotifyLink; + NotifyLink = (SMBUS_NOTIFY_LINK *)NotifyLink->Link.pNext; + pBS->FreePool(DeleteLink); + } + } + + pBS->CloseProtocol ( + ControllerHandle, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + pBS->FreePool(Private->SmBusContext.ArpDeviceList); + pBS->FreePool(Private); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiExecute +// +// Description: EFI_SMBUS_HC_PROTOCOL Execute function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - slave address +// IN EFI_SMBUS_DEVICE_COMMAND Command - command +// IN EFI_SMBUS_OPERATION Operation - operation +// IN BOOLEAN PecCheck - parity check flag +// IN OUT UINTN *Length - pointer to size of data buffer +// IN OUT VOID *Buffer - pointer to data buffer +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeExecute ( + 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_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + + return Execute( + &(Private->SmBusContext), + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeArpDevice +// +// Description: EFI_SMBUS_HC_PROTOCOL ArpDevice function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN EFI_PEI_SMBUS_PPI *This - pointer to PPI +// IN BOOLEAN ArpAll - Enumerate all devices flag +// IN EFI_SMBUS_UDID *SmbusUdid - pointer to device ID to assign new address +// IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return assigned address +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeArpDevice ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + + return ArpDevice( + &(Private->SmBusContext), + ArpAll, + SmbusUdid, + SlaveAddress); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeGetArpMap +// +// Description: EFI_SMBUS_HC_PROTOCOL GetArpMap function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN OUT UINTN *Length - pointer to store size of address map +// IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap - pointer to store pointer to address map +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeGetArpMap ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + + return GetArpMap( + &(Private->SmBusContext), + Length, + SmbusDeviceMap); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeNotify +// +// Description: EFI_SMBUS_HC_PROTOCOL Notify function +// +// Input: IN EFI_SMBUS_HC_PROTOCOL *This - pointer to EFI_SMBUS_HC_PROTOCOL structure +// IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - address of notification device +// IN UINTN Data - notification data +// IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction - pointer to callback function +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusDxeNotify ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction +) +{ + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)This; + SMBUS_NOTIFY_LINK *NewLink; + EFI_STATUS Status; + + if(NotifyFunction == NULL) + return EFI_INVALID_PARAMETER; + + Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SMBUS_NOTIFY_LINK), &NewLink); + if(EFI_ERROR(Status)) + return Status; + + NewLink->SlaveAddress = SlaveAddress; + NewLink->Data = Data; + NewLink->NotifyFunction = NotifyFunction; + + DListAdd(&(Private->NotifyList), (DLINK *)NewLink); + if(Private->NotifyList.Size == 1) + Status = InitializeNotifyPolling(Private); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitializeNotifyPolling +// +// Description: Function initializes host notify polling periodic event +// +// Input: IN SMBUS_DXE_PRIVATE *Context - pointer to SMBUS device private data +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS InitializeNotifyPolling ( + IN SMBUS_DXE_PRIVATE *Context +) +{ + EFI_STATUS Status; + + Status = pBS->CreateEvent ( + (EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL), + TPL_CALLBACK, + PollSmbusNotify, + Context, + &Context->NotifyEvent ); + if (EFI_ERROR(Status)) + return Status; + + Status = pBS->SetTimer ( + Context->NotifyEvent, + TimerPeriodic, + ONESECOND ); + if (EFI_ERROR(Status)) + return Status; + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PollSmbusNotify +// +// Description: Function performs periodic check of host notifications +// +// Input: IN EFI_EVENT Event - periodic check event +// IN VOID *Context - event calling context +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID PollSmbusNotify ( + IN EFI_EVENT Event, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_ADDRESS Address; + UINTN Data; + SMBUS_DXE_PRIVATE *Private = (SMBUS_DXE_PRIVATE *)Context; + SMBUS_NOTIFY_LINK *NotifyLink = (SMBUS_NOTIFY_LINK *)(Private->NotifyList.pHead); + + Status = CheckNotify(&(Private->SmBusContext), &Address, &Data); + if (EFI_ERROR(Status)) + return; + + while(NotifyLink != NULL) + { + if(Address.SmbusDeviceAddress == NotifyLink->SlaveAddress.SmbusDeviceAddress && + Data == NotifyLink->Data) + NotifyLink->NotifyFunction(Address, Data); + + NotifyLink = (SMBUS_NOTIFY_LINK *)NotifyLink->Link.pNext; + } +} + +//------------------------------------------------------------------- +// Struct EFI_SMBUS_DEVICE_MAP has one member, that declared as UINTN +// Due to this declaration this struct may have different size if +// compiled in x64 mode - 4 bytes in PEI and 8 bytes in DXE +// So we need mediator structure, to convert from PEI to DXE map, that +// was saved in Hob in PEI phase +//------------------------------------------------------------------- + +#pragma pack(1) +typedef struct { + UINT32 Address; + EFI_SMBUS_UDID Udid; +} PEI_EFI_SMBUS_DEVICE_MAP; +#pragma pack() + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RetrieveHobData +// +// Description: Function reads device map created in PEI phase +// +// Input: IN OUT SMBUS_DXE_PRIVATE *Context - pointer to device private data +// +// Output: None +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID RetrieveHobData ( + IN OUT SMBUS_DXE_PRIVATE *Private +) +{ + AMI_SMBUS_HOB *Hob; + EFI_GUID HobListGuid = HOB_LIST_GUID; + EFI_STATUS Status; + SMBUS_PRIVATE *Context = &(Private->SmBusContext); + + PEI_EFI_SMBUS_DEVICE_MAP *PeiMap; + UINT32 i; + + Context->BoardReservedAddressCount = 0; + Context->BoardReservedAddressList = 0; + Context->ArpDeviceCount = 0; + + Hob = (AMI_SMBUS_HOB *)GetEfiConfigurationTable(pST, &HobListGuid); + + if(Hob == NULL) + return; + + Status = FindNextHobByGuid(&(Private->Identifier), &Hob); + if(EFI_ERROR(Status)) + return; + + Context->BoardReservedAddressCount = Hob->BoardReservedAddressCount; + Context->BoardReservedAddressList = (UINT8 *)(UINTN)Hob->BoardReservedAddressList; + Context->ArpDeviceCount = Hob->ArpDeviceCount; + + PeiMap = (PEI_EFI_SMBUS_DEVICE_MAP *)Hob->ArpDeviceList; + for(i = 0; i < Hob->ArpDeviceCount; i++) + { + Context->ArpDeviceList[i].SmbusDeviceAddress.SmbusDeviceAddress = PeiMap[i].Address; + Context->ArpDeviceList[i].SmbusDeviceUdid = PeiMap[i].Udid; + } +/* + MemCpy(Context->ArpDeviceList, + Hob->ArpDeviceList, + Context->ArpDeviceCount * sizeof(EFI_SMBUS_DEVICE_MAP)); +*/ +} + +//********************************************************************** +// Porting functions +//********************************************************************** + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusDxeWait +// +// Description: This function waits given number of microseconds +// +// Input: IN UINTN Microseconds - number of microseconds to wait +// +// Output: None +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusDxeWait( + IN UINTN Microseconds +) +{ +//Porting required - implement wait function for pei phase +} + +/* +VOID SmBusDxeInitialize( + IN SMBUS_PRIVATE *Context + ) +{ +//Porting required - initialize PCI device and fill SmBusBase + +} +*/ + +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Chipset/SB/SmBus/SmBusDxe.dxs b/Chipset/SB/SmBus/SmBusDxe.dxs new file mode 100644 index 0000000..7de1921 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusDxe.dxs @@ -0,0 +1,82 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusDxe.dxs 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.dxs $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 4 6/17/11 5:55p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 3 1/27/11 9:48p Abelwu +// Supports SMBUS Protocol in early DXE phase. (EIP#40778) +// +// 2 10/16/09 7:25p Artems +// Updated copyright header +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 4 7/24/07 12:33p Sivagarn +// Copyright year update +// +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: SmBusDxe.DXS +// +// Description: This file is the dependency file for the Smbus DXE +// driver +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + + +#include <Protocol\PciRootBridgeIo.h> + +DEPENDENCY_START + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID +DEPENDENCY_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/Chipset/SB/SmBus/SmBusDxe.h b/Chipset/SB/SmBus/SmBusDxe.h new file mode 100644 index 0000000..955ea21 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusDxe.h @@ -0,0 +1,219 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusDxe.h 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusDxe.h $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 9 8/03/11 8:18a Abelwu +// Updated AMI_SMBUS_SMM_PROTOCOL_GUID for following INTEL RC. +// +// 8 7/19/11 8:27a Abelwu +// [TAG] NONE +// [Category] New Feature +// [Description] Added SMBus SMM Protocol support. +// [Files] SmBusDxe.h +// +// 7 6/27/11 2:26p Artems +// Updated year in file header +// +// 6 6/17/11 5:52p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 5 5/18/11 11:50a Artems +// +// 4 10/16/09 7:11p Artems +// Updated copyright header +// +// 3 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusDxe.h +// +// Description: This file contains DXE SMBUS Driver functions and data +// structures definition. +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> +#ifndef __SMBUS_DXE__H__ +#define __SMBUS_DXE__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <AmiDxeLib.h> +#include <Protocol/Smbus.h> +#include <Protocol/DriverBinding.h> +#include <Protocol/PciIo.h> +#include <Protocol/PciRootBridgeIo.h> +#include "SmBusCommon.h" + +#define AMI_SMBUS_SMM_PROTOCOL_GUID \ + {0x72e40094, 0x2ee1, 0x497a, 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0xc} + +#define MAX_DXE_ARP_DEVICES 0x30 + +#pragma pack(1) + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: SMBUS_DXE_PRIVATE +// +// Description: AMI SMBUS driver PEI private data structure +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// SmBusProtocol EFI_SMBUS_HC_PROTOCOL SMBUS host controller protocol structure +// Identifier EFI_GUID SMBUS host controller identifier +// SmBusContext SMBUS_PRIVATE SMBUS private data structure +// PciIo EFI_PCI_IO_PROTOCOL* Pointer to PCI IO protocol of SMBUS device +// NotifyList DLIST Linked list of notify callbacks +// NotifyEvent EFI_EVENT EFI_EVENT structure +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct _SMBUS_DXE_PRIVATE +{ + EFI_SMBUS_HC_PROTOCOL SmBusProtocol; + EFI_GUID Identifier; + SMBUS_PRIVATE SmBusContext; + EFI_PCI_IO_PROTOCOL *PciIo; + DLIST NotifyList; + EFI_EVENT NotifyEvent; +} SMBUS_DXE_PRIVATE; + +#pragma pack() + +typedef struct { + DLINK Link; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + UINTN Data; + EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction; +} SMBUS_NOTIFY_LINK; + +EFI_STATUS SmBusDxeExecute ( + 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 +); + +EFI_STATUS SmBusDxeArpDevice ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +); + +EFI_STATUS SmBusDxeGetArpMap ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +); + +EFI_STATUS SmBusDxeNotify ( + IN EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction +); + +EFI_STATUS DriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +); + +EFI_STATUS DriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +); + +EFI_STATUS DriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer +); + +EFI_STATUS InitializeNotifyPolling ( + IN SMBUS_DXE_PRIVATE *Context +); + +VOID PollSmbusNotify ( + IN EFI_EVENT Event, + IN VOID *Context +); + +VOID RetrieveHobData ( + IN OUT SMBUS_DXE_PRIVATE *Context +); + +VOID SmBusDxeWait( + IN UINTN Microseconds + ); + +/* +VOID SmBusDxeInitialize( + IN SMBUS_PRIVATE *Context + ); +*/ + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusPciHooks.c b/Chipset/SB/SmBus/SmBusPciHooks.c new file mode 100644 index 0000000..7362140 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPciHooks.c @@ -0,0 +1,129 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (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 Chipset/SmBus/SmBusPciHooks.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPciHooks.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 2 1/27/11 9:44p Abelwu +// Supports SMBUS Protocol in early DXE phase. (EIP#40778) +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmbusPciHooks.c +// +// Description: This file contains PCI initialized hooks for SMBus porting. +// +// Notes: Porting required if SMBus early DXE supported +// +//<AMI_FHDR_END> +//************************************************************************* + +//--------------------------------------------------------------------------- +// Include(s) +//--------------------------------------------------------------------------- + +#include <Efi.h> +#include <Token.h> +#include <AmiDxeLib.h> +#include <AmiCspLib.h> +#include <PciBus.h> + +//--------------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//--------------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + +// Local variable + +// GUID Definition(s) + +// Protocol Definition(s) + +// External Declaration(s) + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: SmBusProtectedPciDevice +// +// Description: This function is called by PCI Bus Driver before configuring +// or disabling any PCI device. This function should examine the +// Vendor/Device ID or PCI Bus, Device and Function numbers to +// make sure it is not a south bridge device or any other device +// which should no be configured by PCI Bus Driver. +// +// Input: *PciDevice - Pointer to PCI Device Info structure. +// +// Output: EFI_STATUS +// EFI_SUCCESS - SKIP this device, do not touch +// PCI Command register. +// EFI_UNSUPPORTED - DON'T SKIP this device do complete +// enumeration as usual. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS SmBusProtectedPciDevice ( + IN PCI_DEV_INFO *PciDevice ) +{ +/* +if ((PciDevice->Address.Addr.Bus == SMBUS_BUS) && \ + (PciDevice->Address.Addr.Device == SMBUS_DEV) && \ + (PciDevice->Address.Addr.Function == SMBUS_FUN)) { + + return EFI_SUCCESS; +} +*/ + return EFI_UNSUPPORTED; +} + +//************************************************************************* +//************************************************************************* +//** ** +//** (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/Chipset/SB/SmBus/SmBusPei.c b/Chipset/SB/SmBus/SmBusPei.c new file mode 100644 index 0000000..f9c5665 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPei.c @@ -0,0 +1,527 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusPei.c 3 3/27/13 10:29p Wesleychen $ +// +// $Revision: 3 $ +// +// $Date: 3/27/13 10:29p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.c $ +// +// 3 3/27/13 10:29p Wesleychen +// Fix coding error. +// +// 2 11/25/12 10:40p Scottyang +// [TAG] EIP107376 +// [Category] Improvement +// [Description] Add token "PCH_SPD_WRITE_DISABLE" for SMBus reg 40h bit +// 4. +// [Files] SmBus.sdl +// SmBusPei.c +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 10 7/21/11 7:31a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.c +// +// 9 7/19/11 8:03a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.c +// +// 8 6/27/11 2:26p Artems +// Updated year in file header +// +// 7 6/17/11 5:53p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 6 10/13/10 4:15p Artems +// EIP 45184 - fixed pointer size to be same in IA32 and X64 mode +// +// 5 10/19/09 12:48p Artems +// Updated copyright header +// +// 4 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 3 1/29/09 4:20p Artems +// Change "Note" to "Notes" for HelpBuilder +// +// 2 1/28/09 6:51p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusPei.c +// +// Description: SMBUS driver PEI functions implementation +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include <AmiLib.h> +#include <AmiHobs.h> +#include "SmBusPei.h" + // [EIP82310]> +#include <Ppi\SmbusPolicy\SmbusPolicy.h> +#include <PchAccess.h> + +static EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID; +EFI_GUID mPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID; + +extern EFI_GUID SmBusIdentifierGuid; +extern UINT8 SmBusPlatformReservedAddress[]; +extern UINT8 SmBusPlatformReservedAddressSize; + // <[EIP82310] + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiEntryPoint +// +// Description: SMBUS driver PEI entry point +// +// Input: EFI_FFS_FILE_HEADER *FfsHeader - pointer to file header +// EFI_PEI_SERVICES **PeiServices - pointer to PEI services table +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +) +{ + EFI_STATUS Status; + SMBUS_PEI_PRIVATE *Private; + + Status = (*PeiServices)->AllocatePool( + PeiServices, + sizeof(SMBUS_PEI_PRIVATE), + &Private); + if(EFI_ERROR(Status)) + return Status; + + Status = (*PeiServices)->AllocatePool( + PeiServices, + sizeof(EFI_SMBUS_DEVICE_MAP) * MAX_PEI_ARP_DEVICES, + &(Private->SmBusContext.ArpDeviceList)); + if(EFI_ERROR(Status)) + return Status; + + Private->SmBusPpi.Execute = SmBusPeiExecute; + Private->SmBusPpi.ArpDevice = SmBusPeiArpDevice; + Private->SmBusPpi.GetArpMap = SmBusPeiGetArpMap; + Private->SmBusPpi.Notify = SmBusPeiNotify; + + Private->SmBusPpiDesc.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + Private->SmBusPpiDesc.Guid = &gEfiPeiSmbus2PpiGuid; + Private->SmBusPpiDesc.Ppi = &Private->SmBusPpi; + + Private->NotifyDesc.Flags = EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + Private->NotifyDesc.Guid = &gEfiPeiEndOfPeiPhasePpiGuid; + Private->NotifyDesc.Notify = SmBusEndOfPeiCallback; + + Private->SmBusContext.ArpDeviceCount = 0; + Private->SmBusContext.MaxDevices = MAX_PEI_ARP_DEVICES; + Private->SmBusContext.SmBusWait = SmBusPeiWait; + + Private->SmBusPpi.Identifier = SmBusIdentifierGuid; + + SmBusPeiInitialize(PeiServices, &Private->SmBusContext); + + Status = (*PeiServices)->NotifyPpi(PeiServices, &Private->NotifyDesc); + if(EFI_ERROR(Status)) + return Status; + + return (*PeiServices)->InstallPpi(PeiServices, &Private->SmBusPpiDesc); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiExecute +// +// Description: SMBUS driver PPI Execute function +// +// Input: PI 0.91 +// **PeiServices - Pointer to the PEI services table +// *This - Pointer to the SMBus PPI structure +// +// PI 1.X +// *This - Pointer to the SMBus2 PPI structure +// +// SlaveAddress - Address of the SMBus device to be used to +// send this command +// Command - Command to be sent to the device +// Operation - SMBus operation to be performed +// PecCheck - Flag indicating the usage of PEC +// *Length - Length of the data in the Buffer (IN/OUT) +// *Buffer - Pointer to the buffer with the data (IN/OUT) +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiExecute ( + IN CONST EFI_PEI_SMBUS2_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 +) +{ + SMBUS_PEI_PRIVATE *Private = (SMBUS_PEI_PRIVATE *)This; + + return Execute( + &(Private->SmBusContext), + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiArpDevice +// +// Description: SMBUS driver PPI ArpDevice function +// +// Input: PI 0.91 +// **PeiServices - Pointer to the PEI services table +// *This - Pointer to the SMBus PPI structure +// +// PI 1.X +// *This - Pointer to the SMBus2 PPI structure +// +// ArpAll - Flag indicating ARP type - ALL or specific +// *SmbusUdid - SMBus UDID for the device whose Address has +// to be resolved +// *SlaveAddress - Slave address to be assigned to the device +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiArpDevice ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +) +{ + SMBUS_PEI_PRIVATE *Private = (SMBUS_PEI_PRIVATE *)This; + + return ArpDevice( + &(Private->SmBusContext), + ArpAll, + SmbusUdid, + SlaveAddress); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiGetArpMap +// +// Description: SMBUS driver PPI GetArpMap function +// +// Input: PI 0.91 +// **PeiServices - Pointer to the PEI services table +// *This - Pointer to the SMBus PPI structure +// +// PI 1.X +// *This - Pointer to the SMBus2 PPI structure +// +// *Length - Length of the Device map structure(IN & OUT) +// *SmBusDeviceMap - Pointer to the buffer where the SMBus +// device map will be filled in +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiGetArpMap ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +) +{ + SMBUS_PEI_PRIVATE *Private = (SMBUS_PEI_PRIVATE *)This; + + return GetArpMap( + &(Private->SmBusContext), + Length, + SmbusDeviceMap); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiNotify +// +// Description: SMBUS driver PPI Notify function +// +// Input: EFI_PEI_SERVICES **PeiServices - pointer to PEI services table +// EFI_PEI_SMBUS_PPI *This - pointer to PPI +// EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - address of notification device +// UINTN Data - notification data +// EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction - pointer to callback function +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusPeiNotify ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY2_FUNCTION NotifyFunction +) +{ + return EFI_UNSUPPORTED; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusEndOfPeiCallback +// +// Description: This function creates map of devices connected to SMBUS at the end of PEI phase +// +// Input: EFI_PEI_SERVICES **PeiServices - pointer to PEI services table +// EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor - pointer to notify descriptor +// VOID *Ppi - pointer to notify PPI +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmBusEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi +) +{ + SMBUS_PEI_PRIVATE *Private = OUTTER(NotifyDescriptor, NotifyDesc, SMBUS_PEI_PRIVATE); + UINTN HobSize; + AMI_SMBUS_HOB *Hob; + EFI_STATUS Status; + + HobSize = sizeof(AMI_SMBUS_HOB) + Private->SmBusContext.ArpDeviceCount * sizeof(EFI_SMBUS_DEVICE_MAP); + Status = (*PeiServices)->CreateHob(PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, HobSize, &Hob); + if(!EFI_ERROR(Status)) + { + Hob->Header.Name = Private->SmBusPpi.Identifier; + Hob->BoardReservedAddressCount = Private->SmBusContext.BoardReservedAddressCount; + Hob->BoardReservedAddressList = (UINT32) (Private->SmBusContext.BoardReservedAddressList); + Hob->ArpDeviceCount = Private->SmBusContext.ArpDeviceCount; + MemCpy(Hob->ArpDeviceList, + Private->SmBusContext.ArpDeviceList, + Private->SmBusContext.ArpDeviceCount * sizeof(EFI_SMBUS_DEVICE_MAP)); + } + return Status; +} + +//********************************************************************** +// Porting functions +//********************************************************************** + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiWait +// +// Description: This function waits given number of microseconds +// +// Input: UINTN Microseconds - number of microseconds to wait +// +// Output: None +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusPeiWait( + IN UINTN Microseconds +) +{ + // The following code is to generate delay for specified amount of micro + // seconds using ACPI timer. + UINT16 AcpiTmrReg = PM_BASE_ADDRESS + ACPI_IOREG_PM1_TMR; + UINTN TicksNeeded; + UINT32 TimerValue; + UINT32 NewTimerValue; + UINTN OverFlow = 0; + UINTN TheRest; + UINTN EndValue; + + // There are 3.58 ticks per us, so we have to convert the number of us + // passed in to the number of ticks that need to pass before the timer has + // expired convert us to Ticks, don't loose significant figures or as few + // as possible do integer math in ticks/tens of ns and then divide by 100 + // to get ticks per us + + TicksNeeded = Microseconds * 3; // (Microseconds * 3) + TicksNeeded += (Microseconds) / 2; // (Microseconds * 5)/10 + TicksNeeded += (Microseconds * 2) / 25; // (Microseconds * 8)/100 + TheRest = TicksNeeded; + + // 32 bits corresponds to approz 71 mins no delay should be that long + // otherwise get the number of times the counter will have to overflow + // to delay as long as needed + if (NUM_BITS_IN_ACPI_TIMER < MAX_ACPI_TIMER_BITS) { + OverFlow = TicksNeeded / (1 << NUM_BITS_IN_ACPI_TIMER); + TheRest = TicksNeeded % (1 << NUM_BITS_IN_ACPI_TIMER); + } + + // Read ACPI Timer + TimerValue = IoRead32( AcpiTmrReg ); + + // Need to adjust the values based off of the start time + EndValue = TheRest + TimerValue; + + // Check for overflow on addition. possibly a problem + if (EndValue < TimerValue) { + OverFlow++; + } else { + if (NUM_BITS_IN_ACPI_TIMER < MAX_ACPI_TIMER_BITS) { + // Here make sure that EndValue is less than the max value + // of the counter + OverFlow += EndValue / (1 << NUM_BITS_IN_ACPI_TIMER); + EndValue = EndValue % (1 << NUM_BITS_IN_ACPI_TIMER); + } + } + + // Let the timer wrap around as many times as calculated + while (OverFlow) { + // read timer amd look to see if the new value read is less than + // the current timer value. if this happens the timer overflowed + NewTimerValue = IoRead32( AcpiTmrReg ); + + if (NewTimerValue < TimerValue) OverFlow--; + + TimerValue = NewTimerValue; + } + + // Now wait for the correct number of ticks that need to occur after + // all the needed overflows + while (EndValue > TimerValue) { + NewTimerValue = IoRead32( AcpiTmrReg ); + + // check to see if the timer overflowed. if it did then + // the time has elapsed. Because EndValue should be greater than + // TimerValue + if (NewTimerValue < TimerValue) break; + + TimerValue = NewTimerValue; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmBusPeiInitialize +// +// Description: This function initializes SMBUS PCI device and fills device context +// +// Input: **PeiServices - Pointer to the PEI Services table +// *Context - Pointer to the SMBus private structure. +// +// Output: None +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SmBusPeiInitialize( + IN EFI_PEI_SERVICES **PeiServices, + IN OUT SMBUS_PRIVATE *Context ) +{ + // [EIP82310]> + EFI_STATUS Status; + PEI_SMBUS_POLICY_PPI *SmbusPolicy; + UINTN SmbusRegBase; + + Context->BoardReservedAddressCount = SmBusPlatformReservedAddressSize; + Context->BoardReservedAddressList = SmBusPlatformReservedAddress; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &mPeiSmbusPolicyPpiGuid, + 0, + NULL, + &SmbusPolicy + ); + if (EFI_ERROR(Status)) return; + + SmbusRegBase = SB_PCIE_CFG_ADDRESS (SMBUS_BUS, SMBUS_DEV, SMBUS_FUN, 0); + + if (MEM_READ16(SmbusRegBase + R_PCH_SMBUS_VENDOR_ID) != 0xFFFF) { + Context->SmBusBase = MEM_READ16(SmbusRegBase + R_PCH_SMBUS_BASE) & (UINT16) B_PCH_SMBUS_BASE_BAR; + if (Context->SmBusBase == SmbusPolicy->BaseAddress) { + return; + } else if (Context->SmBusBase == 0) { + Context->SmBusBase = SmbusPolicy->BaseAddress; + + // Set the BAR & I/O space enable ourselves + MEM_WRITE16(SmbusRegBase + SMBUS_REG_BASE_ADDR, Context->SmBusBase); + MEM_SET8(SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE); + + // Reset the SMBus host controller + MEM_SET8(SmbusRegBase + R_PCH_SMBUS_HOSTC, (PCH_SPD_WRITE_DISABLE << 4) | B_PCH_SMBUS_HOSTC_SSRESET); + + // Enable the SMBus host controller + MEM_RW8(SmbusRegBase + R_PCH_SMBUS_HOSTC, \ + B_PCH_SMBUS_HOSTC_HST_EN, \ + B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN); + + // Clear Status Register before anyone uses the interfaces + IoWrite8 (Context->SmBusBase + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); + } + } + // <[EIP82310] +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Chipset/SB/SmBus/SmBusPei.dxs b/Chipset/SB/SmBus/SmBusPei.dxs new file mode 100644 index 0000000..79abc58 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPei.dxs @@ -0,0 +1,73 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.dxs 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.dxs $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 3 6/27/11 2:26p Artems +// Updated year in file header +// +// 2 10/16/09 7:25p Artems +// Updated copyright header +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 7/30/07 6:19p Sivagarn +// Initial check-in for the template +// +//********************************************************************** + +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// +// Name: SmBusPei.DXS +// +// Description: Dependency file for the Smbus PEI driver +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> + + // [EIP82310]> +#include <Ppi\SmbusPolicy\SmbusPolicy.h> + +DEPENDENCY_START + PEI_SMBUS_POLICY_PPI_GUID +DEPENDENCY_END + // <[EIP82310] + +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Chipset/SB/SmBus/SmBusPei.h b/Chipset/SB/SmBus/SmBusPei.h new file mode 100644 index 0000000..6857196 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPei.h @@ -0,0 +1,182 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusPei.h 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPei.h $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 8 7/21/11 7:31a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.h +// +// 7 7/19/11 8:02a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusPei.h +// +// 6 6/27/11 2:26p Artems +// Updated year in file header +// +// 5 6/17/11 5:52p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 4 10/16/09 7:10p Artems +// Updated copyright header +// +// 3 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusPei.h +// +// Description: This file contains PEI SMBUS Driver functions and data structures definition +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#ifndef __SMBUS_PEI__H__ +#define __SMBUS_PEI__H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include <Ppi/Smbus2.h> + +#include "SmBusCommon.h" + +#define MAX_PEI_ARP_DEVICES 8 + +#pragma pack(1) + +//<AMI_THDR_START> +//---------------------------------------------------------------------------- +// Name: SMBUS_PEI_PRIVATE +// +// Description: AMI SMBUS driver PEI private data structure +// +// Fields: Name Type Description +//---------------------------------------------------------------------------- +// SmBusPpi EFI_PEI_SMBUS/2_PPI SMBUS (2) PPI structure +// Identifier EFI_GUID SMBUS controller identifier +// SmBusContext SMBUS_PRIVATE SMBUS private data structure +// NotifyDesc EFI_PEI_NOTIFY_DESCRIPTOR Notify descriptor structure +// SmBusPpiDesc EFI_PEI_PPI_DESCRIPTOR PPI descriptor structure +// +//---------------------------------------------------------------------------- +//<AMI_THDR_END> +typedef struct _SMBUS_PEI_PRIVATE +{ + EFI_PEI_SMBUS2_PPI SmBusPpi; + SMBUS_PRIVATE SmBusContext; + EFI_PEI_NOTIFY_DESCRIPTOR NotifyDesc; + EFI_PEI_PPI_DESCRIPTOR SmBusPpiDesc; +} SMBUS_PEI_PRIVATE; + +#pragma pack() + +EFI_STATUS SmBusPeiEntryPoint ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +); + +EFI_STATUS SmBusPeiExecute ( + IN CONST EFI_PEI_SMBUS2_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 SmBusPeiArpDevice ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL +); + +EFI_STATUS SmBusPeiGetArpMap ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap +); + +EFI_STATUS SmBusPeiNotify ( + IN CONST EFI_PEI_SMBUS2_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY2_FUNCTION NotifyFunction +); + +EFI_STATUS SmBusEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi +); + +VOID SmBusPeiWait( + IN UINTN Microseconds +); + +VOID SmBusPeiInitialize( + IN EFI_PEI_SERVICES **PeiServices, + IN SMBUS_PRIVATE *Context +); + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Chipset/SB/SmBus/SmBusPorting.c b/Chipset/SB/SmBus/SmBusPorting.c new file mode 100644 index 0000000..eb4ad69 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusPorting.c @@ -0,0 +1,705 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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 Chipset/SmBus/SmBusPorting.c 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusPorting.c $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 7 6/27/11 2:26p Artems +// Updated year in file header +// +// 6 6/17/11 5:53p Artems +// EIP 53378: Replaced tabs with spaces, formatted to follow coding +// standard +// +// 5 10/16/09 7:24p Artems +// Updated copyright header +// +// 4 3/03/09 4:36p Artems +// EIP 19949 Added support for multiple SM Bus controllers that +// represented by different PCI devices +// +// 3 1/29/09 4:20p Artems +// Change "Note" to "Notes" for HelpBuilder +// +// 2 1/28/09 6:52p Artems +// Modified in accordance with coding standard +// +// 1 1/09/09 6:53p Artems +// New implementation of SMBus EIP 16730 +// +// 1 3/18/07 5:23p Felixp +// +//********************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------- +// +// Name: SmBusPorting.c +// +// Description: SMBUS driver porting functions +// +//---------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include "SmBusCommon.h" + +//Porting Required - Put unique GUID for given SMBUS controller +#define SM_BUS_CONTROLLER_IDENTIFIER_GUID \ + {0x882f2546, 0xef1f, 0x4090, 0x9f, 0x9c, 0x93, 0x84, 0x5a, 0xd7, 0x84, 0x1c} + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +//--------------------------------------------------------------------------- +// Variable and External Declaration(s) +//--------------------------------------------------------------------------- +// Variable Declaration(s) + + // [EIP82310]> +UINT8 SmBusPlatformReservedAddress[] = { + DIMM1_SMBUS_ADDRESS, + DIMM2_SMBUS_ADDRESS, + DIMM3_SMBUS_ADDRESS, + DIMM4_SMBUS_ADDRESS +}; + // <[EIP82310] + +UINT8 SmBusPlatformReservedAddressSize = \ + sizeof(SmBusPlatformReservedAddress) / sizeof(UINT8); + +// GUID Definition(s) + +EFI_GUID SmBusIdentifierGuid = SM_BUS_CONTROLLER_IDENTIFIER_GUID; + +// Protocol/PPI Definition(s) + +// External Declaration(s) + +// Function Definition(s) + +//--------------------------------------------------------------------------- + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: BeforeSMBusTransfer +// +// Description: Set an enviornment for SMBus transfering. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// +// Output: EFI_STATUS +// EFI_TIMEOUT - The caller can't obtain ownership of SMBus. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS BeforeSMBusTransfer ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8 ) +{ + UINT16 Timeout = 0xffff; + + // Waiting for other software's usage. + while (IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS) & HST_STS_INUSE_STS) { + IoRead8(0xed); // I/O Delay + Timeout--; + if (Timeout == 0) return EFI_TIMEOUT; + } + + // BIOS obtains ownership of SMBus & Waiting for transmission completed. + while (IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS) & HST_STS_HOST_BUSY) { + Timeout--; + if (Timeout == 0) break; + } + + // Clears all statues + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_ALL); + + if (Protocol8 == SMB_CMD_BLOCK) { +//#### SET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_E32B); // 0x0D +//#### // Reset Buffer Pointer +//#### IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_CNT); // 0x02 + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteCommand +// +// Description: This support function writes command field to SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Command8 - SMBus command to be performed +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteCommand ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Command8 ) +{ + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CMD, Command8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteSlAddr +// +// Description: This support function writes slave address to SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// SlAddr8 - Address of the SMBus device +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteSlAddr ( + IN UINT16 SmBusIoAddr16, + IN UINT8 SlAddr8 ) +{ + IoWrite8(SmBusIoAddr16 + SMB_IOREG_XMIT_SLVA, SlAddr8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteSMBusData +// +// Description: This support function writes data(s) to SMBus Controller for +// SMBus write operation. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// Length8 - Size of data buffer in bytes +// *Data8 - Buffer to be written +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID WriteSMBusData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8, + IN UINT8 Length8, + IN UINT8 *Data8 ) +{ + UINT8 i; + + for (i = 0; i < Length8; i++) { + if (Protocol8 == SMB_CMD_BLOCK) { + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_D0, Length8); + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HOST_BLOCK_DB, *Data8++); + break; + } else { + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_D0 + i, *Data8++); + } + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WaitForHostByteDoneStatus +// +// Description: This support function waits the Byte Done bit to be set for +// SMBus Block operation. +// +// Input: SmBusStsReg - 16 Bit I/O address for SMBus status register +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - The Byte Done bit had been set. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WaitForHostByteDoneStatus ( + IN UINT16 SmBusStsReg ) +{ + UINT8 HostSts; + + while (1) { + HostSts = IoRead8( SmBusStsReg ); + IoWrite8( IO_DELAY_PORT, HostSts ); + if ( HostSts & HST_STS_ERROR ) return EFI_DEVICE_ERROR; + if ( HostSts & HST_STS_BDS ) return EFI_SUCCESS; + } +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WriteSmBusBlockData +// +// Description: This support function writes to SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Length8 - Size of data buffer in bytes +// *Data8 - Buffer to be written +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - Write SMBus Block data successfully. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WriteSmBusBlockData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Length8, + IN UINT8 *Data8 ) +{ + EFI_STATUS Status; + UINT8 i; + UINT16 StatusReg = SmBusIoAddr16 + SMB_IOREG_HST_STS; + + for (i = 1; i < Length8; i++) { + if (WaitForHostByteDoneStatus(StatusReg)) return EFI_DEVICE_ERROR; + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HOST_BLOCK_DB, *Data8++); + IoWrite8(StatusReg, HST_STS_BDS); + } + Status = WaitForHostByteDoneStatus(StatusReg); + IoWrite8(StatusReg, HST_STS_BDS); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ReadSmBusData +// +// Description: This support function reads from SMBus Controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// Length8 - Size of data buffer in bytes +// *Data8 - Buffer for the read data +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - Read SMBus data successfully. +// +// Modified: *Data8 - The Pointer will store data(s) read from the SMBus +// device if EFI_SUCCESS is returned. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS ReadSmBusData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8, + IN UINT8 Length8, + OUT UINT8 *Data8 ) +{ + UINT8 i; + + if (Protocol8 == SMB_CMD_BLOCK) + Length8 = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_D0); + + for (i = 0; i < Length8; i++) { + if (Protocol8 == SMB_CMD_BLOCK) { + if (WaitForHostByteDoneStatus(SmBusIoAddr16 + SMB_IOREG_HST_STS)) + return EFI_DEVICE_ERROR; + *Data8++ = IoRead8(SmBusIoAddr16 + SMB_IOREG_HOST_BLOCK_DB); + if (i == (Length8 - 1)) { + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CNT, \ + HST_CNT_LAST_BYTE | SMB_CMD_BLOCK); + } + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_BDS); + } else { + *Data8++ = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_D0 + i); + } + } + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: StartSmBusTransition +// +// Description: This support function starts SMBus operation. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// PecCheck - TRUE will set PecCheck bit. +// +// Ouput: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID StartSmBusTransition ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8, + IN BOOLEAN PecCheck ) +{ + UINT8 Buffer8; + + Buffer8 = Protocol8; + if (PecCheck) { + Buffer8 |= HST_CNT_PEC_EN; + SET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_AAC); // 0x0D + } + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CNT, Buffer8); + + Buffer8 |= HST_CNT_START; + + if (Protocol8 == SMB_CMD_BLOCK) + // Clear SECOND_TO_STS status before SMBus block read/write. + WRITE_IO8_TCO(TCO_IOREG_STS2, 2); // 0x06 + + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_CNT, Buffer8); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: WaitForSmBusComplete +// +// Description: This support function waits for the operation complete +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// +// Output: EFI_STATUS +// EFI_DEVICE_ERROR - An error on the SMBus device. +// EFI_SUCCESS - SMBus transaction is successfully +// completed. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS WaitForSmBusComplete ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8 ) +{ + volatile UINT8 Buffer8; + UINT8 StsChkBit; + UINT16 TimeoutCounter; + + for (TimeoutCounter = 0; TimeoutCounter < 0x6000; TimeoutCounter++) { + Buffer8 = IoRead8(IO_DELAY_PORT); // I/O Delay + Buffer8 = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS); + if (Buffer8 & (HST_STS_BDS | HST_STS_ERROR | HST_STS_INTR)) break; + } + + StsChkBit = (Protocol8 == SMB_CMD_BLOCK) ? HST_STS_BDS : HST_STS_INTR; + if (Buffer8 & StsChkBit) + return (Buffer8 & HST_STS_ERROR) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + return EFI_DEVICE_ERROR; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: ClearSmBusStatusAndDelay +// +// Description: This support function clears all statues of the SMBus +// controller +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// +// Ouptut: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID ClearSmBusStatusAndDelay ( + IN UINT16 SmBusIoAddr16 ) +{ + UINT16 Timeout = 0x4000; + volatile UINT8 HstSts; + + // Waiting for transmission completed. + do { + Timeout--; + if (Timeout == 0) break; + HstSts = IoRead8(SmBusIoAddr16 + SMB_IOREG_HST_STS); + if (HstSts & HST_STS_HOST_BUSY) continue; + } while ((HstSts & (HST_STS_ERROR | HST_STS_INTR | HST_STS_BDS)) == 0); + + // Clears all statues. + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_ALL); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: AfterSMBusTransfer +// +// Description: Restore the enviornment. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// Protocol8 - SMBus operation to be performed +// +// Output: None +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +VOID AfterSMBusTransfer ( + IN UINT16 SmBusIoAddr16, + IN UINT8 Protocol8 ) +{ +//#### if (Protocol8 == SMB_CMD_BLOCK) +//#### RESET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_E32B); // 0x0D + RESET_IO8(SmBusIoAddr16 + SMB_IOREG_AUX_CTL, AUX_CTL_AAC); // 0x0D + + // BIOS releases the ownership of SMBus. + IoWrite8(SmBusIoAddr16 + SMB_IOREG_HST_STS, HST_STS_INUSE_STS); + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// +// Procedure: RwSmBusData +// +// Description: This support function reads/writes from/to SMBus Controller. +// +// Input: SmBusIoAddr16 - I/O base address of the SMBus Controller +// SlAddr8 - Address of the SMBus device +// Command8 - SMBus command to be performed +// Protocol8 - SMBus operation to be performed +// PecCheck - TRUE will set PecCheck bit. +// Length8 - Size of data buffer in bytes +// Data8 - Buffer for the read/write data(s) +// +// Output: Return Status based on errors that occurred while SMBus +// transaction. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS RwSmBusData ( + IN UINT16 SmBusIoAddr16, + IN UINT8 SlAddr8, + IN UINT8 Command8, + IN UINT8 Protocol8, + IN BOOLEAN PecCheck, + IN UINT8 Length8, + IN OUT UINT8 *Data8 ) +{ + EFI_STATUS Status; + BOOLEAN IsWriteOperation = (!(SlAddr8 & XMIT_SLVA_RW)); + + Status = BeforeSMBusTransfer(SmBusIoAddr16, Protocol8); + if (Status != EFI_SUCCESS) return Status; + WriteCommand(SmBusIoAddr16, Command8); + WriteSlAddr(SmBusIoAddr16, SlAddr8); + if (IsWriteOperation) + WriteSMBusData(SmBusIoAddr16, Protocol8, Length8, Data8); + StartSmBusTransition(SmBusIoAddr16, Protocol8, PecCheck); + Status = WaitForSmBusComplete(SmBusIoAddr16, Protocol8); + if (Status == EFI_SUCCESS) { + if (IsWriteOperation) { + if (Protocol8 == SMB_CMD_BLOCK) + WriteSmBusBlockData(SmBusIoAddr16, Length8, &Data8[1]); + } else { + Status = ReadSmBusData(SmBusIoAddr16, Protocol8, Length8, Data8); + } + } + + ClearSmBusStatusAndDelay(SmBusIoAddr16); + AfterSMBusTransfer(SmBusIoAddr16, Protocol8); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Execute +// +// Description: This function sends commands via SMBUS interface +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress - slave address value +// IN EFI_SMBUS_DEVICE_COMMAND Command - command +// IN EFI_SMBUS_OPERATION Operation - operation +// IN BOOLEAN PecCheck - parity check flag +// IN OUT UINTN *Length - pointer to size of data buffer +// IN OUT VOID *Buffer - pointer to data buffer +// +// Output: EFI_STATUS +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS Execute ( + IN SMBUS_PRIVATE *Context, + 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 +) +{ + // Porting required - implement internal Smbus protocols here + EFI_STATUS Status = EFI_UNSUPPORTED; + UINT8 *bData = (UINT8 *)Buffer; + UINT8 bSlAddr = (UINT8)(SlaveAddress.SmbusDeviceAddress << 1); + UINT8 bCommand = (UINT8)Command; + UINT8 bLength = (UINT8)(*Length); + + // Wait for SMBus transaction to finish if needed. +//#### while (IoRead8(Context->SmBusBase + SMB_IOREG_CNTL) & 3); + + if (bLength > 32) bLength = 32; + if (bLength == 0) return EFI_INVALID_PARAMETER; + + switch (Operation) { + case EfiSmbusQuickRead: + case EfiSmbusQuickWrite: + break; + + case EfiSmbusReceiveByte: + break; + + case EfiSmbusSendByte: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_BYTE, \ + PecCheck, \ + 1, \ + bData ); + break; + + case EfiSmbusReadByte: + Status = RwSmBusData( Context->SmBusBase , \ + (bSlAddr | XMIT_SLVA_RW), \ + bCommand, \ + SMB_CMD_BYTE_DATA, \ + PecCheck, \ + 1, \ + bData ); + break; + case EfiSmbusReadWord: + Status = RwSmBusData( Context->SmBusBase , \ + (bSlAddr | XMIT_SLVA_RW), \ + bCommand, \ + SMB_CMD_WORD_DATA, \ + PecCheck, \ + 2, \ + bData ); + break; + + case EfiSmbusWriteByte: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_BYTE_DATA, \ + PecCheck, \ + 1, \ + bData ); + break; + case EfiSmbusWriteWord: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_WORD_DATA, \ + PecCheck, \ + 2, \ + bData ); + break; + + case EfiSmbusReadBlock: + Status = RwSmBusData( Context->SmBusBase , \ + (bSlAddr | XMIT_SLVA_RW), \ + bCommand, \ + SMB_CMD_BLOCK, \ + PecCheck, \ + bLength, \ + bData ); + *Length = IoRead8( Context->SmBusBase + SMB_IOREG_HST_D0 ); + break; + + case EfiSmbusWriteBlock: + Status = RwSmBusData( Context->SmBusBase , \ + bSlAddr, \ + bCommand, \ + SMB_CMD_BLOCK, \ + PecCheck, \ + bLength, \ + bData ); + *Length = IoRead8( Context->SmBusBase + SMB_IOREG_HST_D0 ); + break; + + case EfiSmbusProcessCall: + break; + + case EfiSmbusBWBRProcessCall: + break; + + default: + break; + } + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckNotify +// +// Description: This function checks if SMBUS host received any notifications +// +// Input: IN SMBUS_PRIVATE *Context - SMBUS device private data +// OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress - pointer to return address of notificaion device +// OUT UINTN *Data - pointer to notification data +// +// Output: EFI_STATUS +// +// Notes: Porting required +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CheckNotify ( + IN SMBUS_PRIVATE *Context, + OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress, + OUT UINTN *Data +) +{ +//Porting required + return EFI_UNSUPPORTED; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (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/Chipset/SB/SmBus/SmBusSmm.dxs b/Chipset/SB/SmBus/SmBusSmm.dxs new file mode 100644 index 0000000..dc90908 --- /dev/null +++ b/Chipset/SB/SmBus/SmBusSmm.dxs @@ -0,0 +1,65 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (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 Chipset/SmBus/SmBusSmm.dxs 1 6/06/12 8:00a Victortu $ +// +// $Revision: 1 $ +// +// $Date: 6/06/12 8:00a $ +//************************************************************************* +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmBus/SmBusSmm.dxs $ +// +// 1 6/06/12 8:00a Victortu +// Implement EFI_PEI_SMBUS2_PPI Support. +// +// 1 7/19/11 8:09a Abelwu +// [TAG] EIP63768 +// [Category] Improvement +// [Description] Supported Core 4.6.5.x PI 1.2 / uEFI 2.3.1 compliance +// [Files] SmBusSmm.dxs +// +//************************************************************************* +//<AMI_FHDR_START> +// +// Name: SmBusSmm.DXS +// +// Description: This file is the dependency file for the Smbus SMM +// driver +// +//<AMI_FHDR_END> +//************************************************************************* + +#include <Protocol\SmmBase2.h> +#include <Protocol\SmBus.h> +DEPENDENCY_START + EFI_SMM_BASE2_PROTOCOL_GUID AND + EFI_SMBUS_HC_PROTOCOL_GUID +DEPENDENCY_END + +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* |