diff options
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/Smbus/Pei')
14 files changed, 2082 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs new file mode 100644 index 0000000..30bfdc5 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs @@ -0,0 +1,44 @@ +/** @file + Dependency expression file for PCH SMBUS PEIM. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ + + +// +// Common for R8 and R9 codebase +// +#include "AutoGen.h" +#include "PeimDepex.h" + +// +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase; +// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version +// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase. +// +#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB) +#include "EfiDepex.h" +#include "Common/EdkIIGlueDefinitionChangesPeim.h" + +#include EFI_PPI_DEFINITION (SmbusPolicy) +#endif + +DEPENDENCY_START + PEI_SMBUS_POLICY_PPI_GUID +DEPENDENCY_END + + diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h new file mode 100644 index 0000000..fe64e8a --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h @@ -0,0 +1,409 @@ +/** @file + PCH Smbus PPI + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#ifndef _PEI_PCH_SMBUS_H_ +#define _PEI_PCH_SMBUS_H_ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) + +#include "EdkIIGluePeim.h" + +// +// Driver Produced PPI Prototypes +// +#include EFI_PPI_PRODUCER (Smbus) +// +// Driver Consumed PPI Prototypes +// +#include EFI_PPI_CONSUMER (EndOfPeiSignal) +#include EFI_PPI_CONSUMER (SmbusPolicy) +#include EFI_PPI_CONSUMER (MemoryDiscovered) +#include EFI_GUID_DEFINITION (SmbusArpMap) +#include "PchSmbusCommon.h" +#endif +/// +/// Max number of SMBus devices +/// (7 bit address yields 128 combinations but 21 of those are reserved) +/// Due to limited resources, we only allow 8 in PEI. +/// +#define MAX_SMBUS_DEVICES 8 + +#define MAX_SMBUS_NOTIFICATION 8 + +/// +/// Private Data Structures +/// +typedef struct _PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE { + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + UINTN Data; + EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction; +} PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE; + +/// +/// Declare a local instance structure for this PEIM +/// +typedef struct _SMBUS_INSTANCE { + UINTN Signature; + EFI_PEI_SERVICES **PeiServices; + PEI_SMBUS_POLICY_PPI *SmbusPolicy; + UINTN SmbusIoBase; + EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; + EFI_PEI_SMBUS_PPI SmbusPpi; + EFI_PEI_NOTIFY_DESCRIPTOR NotifyDescriptor; + UINT8 DeviceMapEntries; + EFI_SMBUS_DEVICE_MAP DeviceMap[MAX_SMBUS_DEVICES]; + UINT8 PlatformNumRsvd; + UINT8 *PlatformRsvdAddr; + + UINT8 NotifyFunctionNum; + PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE NotifyFunctionList[MAX_SMBUS_NOTIFICATION]; +} SMBUS_INSTANCE; + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#define SMBUS_PRIVATE_DATA_FROM_PPI_THIS(a) PEI_CR (a, SMBUS_INSTANCE, SmbusPpi, PCH_SMBUS_PRIVATE_DATA_SIGNATURE) + +#define SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS(a) \ + PEI_CR ( \ + a, \ + SMBUS_INSTANCE, \ + PpiDescriptor, \ + PCH_SMBUS_PRIVATE_DATA_SIGNATURE \ + ) + +#define SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS(a) \ + PEI_CR ( \ + a, \ + SMBUS_INSTANCE, \ + NotifyDescriptor, \ + PCH_SMBUS_PRIVATE_DATA_SIGNATURE \ + ) + +#else + +#define SMBUS_PRIVATE_DATA_FROM_PPI_THIS(a) CR (a, SMBUS_INSTANCE, SmbusPpi, PCH_SMBUS_PRIVATE_DATA_SIGNATURE) + +#define SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS(a) \ + CR ( \ + a, \ + SMBUS_INSTANCE, \ + PpiDescriptor, \ + PCH_SMBUS_PRIVATE_DATA_SIGNATURE \ + ) + +#define SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS(a) \ + CR ( \ + a, \ + SMBUS_INSTANCE, \ + NotifyDescriptor, \ + PCH_SMBUS_PRIVATE_DATA_SIGNATURE \ + ) + +#endif +// +// Prototypes +// + +/** + This function provides a standard way to execute an SMBUS command + PPI as defined in the SMBus Specification. The data can either be of + the length byte, word, or a block of data (1 to 32 bytes long). + The resulting transaction will be either the SMBus Slave Device accepts + this transaction or this function returns with an error + + @param[in] PeiServices PEI services table pointer + @param[in] This PEI_SMBUS_PPI instance + @param[in] SlaveAddress Smbus Slave device address + @param[in] Command Command to be sent + @param[in] Operation Which SMBus PPI will be used + @param[in] PecCheck Defines if Packet Error Code Checking is to be used + @param[in, out] Length How many bytes to read/write. Must be 1 <= Length <= 32 depending on the Operation + @param[in, out] Buffer Data buffer + + @retval EFI_SUCCESS Operation success. + Length will contain the actual number of bytes read. + Buffer will contain the data read. + @retval Otherwise Operation failed. +**/ +EFI_STATUS +EFIAPI +SmbusExecute ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ); + +/** + Initialize the Smbus PPI and program the Smbus BAR + + @param[in] FfsHeader Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database +**/ +EFI_STATUS +InitializePchSmbusPeim ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ); + +/** + Fix up pointers since they are located in real memory now. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +MemoryDiscoveredPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +/** + Set Slave address for an Smbus device with a known UDID or perform a general + ARP of all devices. + + @param[in] PeiServices Pointer to the PEI Services table. + @param[in] This Pointer to the instance of the PEI_SMBUS_PPI. + @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID. + @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID. + @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusArpDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI * This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL + ); + +/** + Get a pointer to the assigned mappings of UDID's to Slave Addresses. + + @param[in] PeiServices Pointer to the PEI Services table. + @param[in] This Pointer to the instance of the PEI_SMBUS_PPI. + @param[in, out] Length Buffer to contain the lenght of the Device Map. + @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusGetArpMap ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap + ); + +/** + Register a callback in the event of a Host Notify command being sent by a + specified Slave Device. + + @param[in] PeiServices The general PEI Services + @param[in] This The PPI instance + @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap. + @param[in] Data Data of the Host Notify command we want to trap. + @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction + ); + +/** + This function initializes the SmBus driver in PEI. + + @param[in] PeiServices Standard PEI services + @param[in] Private SMBUS private data structure + + @retval None. +**/ +VOID +InitializePeiPrivate ( + IN EFI_PEI_SERVICES **PeiServices, + IN SMBUS_INSTANCE *Private + ); + +/** + Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusPrepareToArp ( + IN SMBUS_INSTANCE *Private + ); + +/** + Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to + return their slave address along with their UDID. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusGetUdidGeneral ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ); + +/** + Issue a Assign address command to assigns an address to a specific slave device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusAssignAddress ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ); + +/** + Do a fully (general) Arp procress to assign the slave address of all ARP-capable device. + This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands. + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval EFI_OUT_OF_RESOURCES No available address to assign + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusFullArp ( + IN SMBUS_INSTANCE *Private + ); + +/** + Do a directed Arp procress to assign the slave address of a single ARP-capable device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID. + @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices. + Or there is no available address to assign + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusDirectedArp ( + IN SMBUS_INSTANCE *Private, + IN EFI_SMBUS_UDID *SmbusUdid, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress + ); + +/** + Find an available address to assign + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @retval EFI_OUT_OF_RESOURCES There is no available address to assign + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +GetNextAvailableAddress ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress + ); + +/** + Check whether the address is assignable. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SlaveAddress The Slave Address for checking + + @retval TRUE The address is assignable + @retval FALSE The address is not assignable +**/ +BOOLEAN +IsAddressAvailable ( + IN SMBUS_INSTANCE *Private, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress + ); + +/** + This function gets called back at the end of PEI if any devices were ARPed + during PEI. It will build a HOB to describe to DXE what devices were ARPed. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The EndOfPeiSignal PPI. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +/** + Function to be called when SMBus.Execute happens. This will check if + the SMBus Host Controller has received a Host Notify command. If so, it will + see if a notification has been reqested on that event and make any callbacks + that may be necessary. + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval None +**/ +VOID +CheckNotification ( + IN SMBUS_INSTANCE *Private + ); + +#endif diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c new file mode 100644 index 0000000..9ba5647 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c @@ -0,0 +1,444 @@ +/** @file + PCH Smbus PEIM. This file is used when we want ARP support. + +@copyright + Copyright (c) 2009 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "PchSmbus.h" + +/// +/// These addresses are reserved by the SMBus 2.0 specification +/// +static UINT8 mReservedAddress[SMBUS_NUM_RESERVED] = { + 0x00, + 0x02, + 0x04, + 0x06, + 0x08, + 0x0A, + 0x0C, + 0x0E, + 0x10, + 0x18, + 0x50, + 0x6E, + 0xC2, + 0xF0, + 0xF2, + 0xF4, + 0xF6, + 0xF8, + 0xFA, + 0xFC, + 0xFE, + 0x12, + 0x14, + 0x16, + 0x58, + 0x5A, + 0x80, + 0x82, + 0x84, + 0x86, + 0x88, + 0x90, + 0x92, + 0x94, + 0x96, + 0x1A, + 0x1C, + 0x1E +}; + +/** + Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusPrepareToArp ( + IN SMBUS_INSTANCE *Private + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer; + + DEBUG ((EFI_D_INFO, "PEI SmbusPrepareToArp() Start\n")); + + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + Length = 1; + Buffer = SMBUS_DATA_PREPARE_TO_ARP; + + Status = SmbusExec ( + SlaveAddress, + 0, + EfiSmbusSendByte, + TRUE, + &Length, + &Buffer + ); + + DEBUG ((EFI_D_INFO, "PEI SmbusPrepareToArp() End\n")); + + return Status; +} + +/** + Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to + return their slave address along with their UDID. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusGetUdidGeneral ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer[SMBUS_GET_UDID_LENGTH]; + + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + Length = SMBUS_GET_UDID_LENGTH; + + DEBUG ((EFI_D_INFO, "PEI SmbusGetUdidGeneral() Start\n")); + + Status = SmbusExec ( + SlaveAddress, + SMBUS_DATA_GET_UDID_GENERAL, + EfiSmbusReadBlock, + TRUE, + &Length, + Buffer + ); + + if (!EFI_ERROR (Status)) { + if (Length == SMBUS_GET_UDID_LENGTH) { + DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0]; + DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1]; + DeviceMap->SmbusDeviceUdid.VendorId = (UINT16) ((Buffer[2] << 8) + Buffer[3]); + DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16) ((Buffer[4] << 8) + Buffer[5]); + DeviceMap->SmbusDeviceUdid.Interface = (UINT16) ((Buffer[6] << 8) + Buffer[7]); + DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16) ((Buffer[8] << 8) + Buffer[9]); + DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16) ((Buffer[10] << 8) + Buffer[11]); + DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32) ((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]); + DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8) (Buffer[16] >> 1); + } else { + Status = EFI_DEVICE_ERROR; + } + } + + DEBUG ((EFI_D_INFO, "PEI SmbusGetUdidGeneral() End\n")); + + return Status; +} + +/** + Issue a Assign address command to assigns an address to a specific slave device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusAssignAddress ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer[SMBUS_GET_UDID_LENGTH]; + + DEBUG ((EFI_D_INFO, "PEI SmbusAssignAddress() Start\n")); + + Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities; + Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision; + Buffer[2] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId >> 8); + Buffer[3] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId); + Buffer[4] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId >> 8); + Buffer[5] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId); + Buffer[6] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface >> 8); + Buffer[7] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface); + Buffer[8] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8); + Buffer[9] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId); + Buffer[10] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8); + Buffer[11] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId); + Buffer[12] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24); + Buffer[13] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16); + Buffer[14] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8); + Buffer[15] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId); + Buffer[16] = (UINT8) (DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1); + + SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP; + Length = SMBUS_GET_UDID_LENGTH; + + Status = SmbusExec ( + SlaveAddress, + SMBUS_DATA_ASSIGN_ADDRESS, + EfiSmbusWriteBlock, + TRUE, + &Length, + Buffer + ); + + DEBUG ((EFI_D_INFO, "PEI SmbusAssignAddress() End\n")); + + return Status; +} + +/** + Do a fully (general) Arp procress to assign the slave address of all ARP-capable device. + This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands. + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval EFI_OUT_OF_RESOURCES No available address to assign + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusFullArp ( + IN SMBUS_INSTANCE *Private + ) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap; + + DEBUG ((EFI_D_INFO, "PEI SmbusFullArp() Start\n")); + + Status = SmbusPrepareToArp (Private); + if (EFI_ERROR (Status)) { + if (Status == EFI_DEVICE_ERROR) { + /// + /// ARP is complete + /// + return EFI_SUCCESS; + } else { + return Status; + } + } + /// + /// Main loop to ARP all ARP-capable devices + /// + do { + CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries]; + Status = SmbusGetUdidGeneral (Private, CurrentDeviceMap); + if (EFI_ERROR (Status)) { + break; + } + + if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) { + /// + /// If address is unassigned, assign it + /// + Status = GetNextAvailableAddress ( + Private, + &CurrentDeviceMap->SmbusDeviceAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) { + /// + /// if address is not fixed, check if the current address is available + /// + if (!IsAddressAvailable ( + Private, + CurrentDeviceMap->SmbusDeviceAddress + )) { + /// + /// if currently assigned address is already used, get a new one + /// + Status = GetNextAvailableAddress ( + Private, + &CurrentDeviceMap->SmbusDeviceAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + } + } + + Status = SmbusAssignAddress (Private, CurrentDeviceMap); + if (EFI_ERROR (Status)) { + /// + /// If there was a device error, just continue on and try again. + /// Other errors should be reported. + /// + if (Status != EFI_DEVICE_ERROR) { + return Status; + } + } else { + /// + /// If there was no error, the address was assigned and we must update our + /// records. + /// + Private->DeviceMapEntries++; + } + + } while (Private->DeviceMapEntries < MAX_SMBUS_DEVICES); + + DEBUG ((EFI_D_INFO, "PEI SmbusFullArp() End\n")); + + return EFI_SUCCESS; +} + +/** + Do a directed Arp procress to assign the slave address of a single ARP-capable device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID. + @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices. + Or there is no available address to assign + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +SmbusDirectedArp ( + IN SMBUS_INSTANCE *Private, + IN EFI_SMBUS_UDID *SmbusUdid, + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress + ) +{ + EFI_STATUS Status; + EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap; + + DEBUG ((EFI_D_INFO, "PEI SmbusDirectedArp() Start\n")); + + if (Private->DeviceMapEntries >= MAX_SMBUS_DEVICES) { + return EFI_OUT_OF_RESOURCES; + } + + CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries]; + + /// + /// Find an available address to assign + /// + Status = GetNextAvailableAddress ( + Private, + &CurrentDeviceMap->SmbusDeviceAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities = SmbusUdid->DeviceCapabilities; + CurrentDeviceMap->SmbusDeviceUdid.DeviceId = SmbusUdid->DeviceId; + CurrentDeviceMap->SmbusDeviceUdid.Interface = SmbusUdid->Interface; + CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId = SmbusUdid->SubsystemDeviceId; + CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId = SmbusUdid->SubsystemVendorId; + CurrentDeviceMap->SmbusDeviceUdid.VendorId = SmbusUdid->VendorId; + CurrentDeviceMap->SmbusDeviceUdid.VendorRevision = SmbusUdid->VendorRevision; + CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId = SmbusUdid->VendorSpecificId; + + Status = SmbusAssignAddress (Private, CurrentDeviceMap); + if (EFI_ERROR (Status)) { + return Status; + } + + Private->DeviceMapEntries++; + SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress; + + DEBUG ((EFI_D_INFO, "PEI SmbusDirectedArp() End\n")); + + return EFI_SUCCESS; +} + +/** + Find an available address to assign + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @retval EFI_OUT_OF_RESOURCES There is no available address to assign + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +GetNextAvailableAddress ( + IN SMBUS_INSTANCE *Private, + IN EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress + ) +{ + for (SlaveAddress->SmbusDeviceAddress = 0x03; + SlaveAddress->SmbusDeviceAddress < 0x7F; + SlaveAddress->SmbusDeviceAddress++ + ) { + if (IsAddressAvailable (Private, *SlaveAddress)) { + return EFI_SUCCESS; + } + } + + return EFI_OUT_OF_RESOURCES; +} + +/** + Check whether the address is assignable. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SlaveAddress The Slave Address for checking + + @retval TRUE The address is assignable + @retval FALSE The address is not assignable +**/ +BOOLEAN +IsAddressAvailable ( + IN SMBUS_INSTANCE *Private, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress + ) +{ + UINT8 Index; + + /// + /// See if we have already assigned this address to a device + /// + for (Index = 0; Index < Private->DeviceMapEntries; Index++) { + if (SlaveAddress.SmbusDeviceAddress == Private->DeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) { + return FALSE; + } + } + /// + /// See if this address is claimed by a platform non-ARP-capable device + /// + for (Index = 0; Index < Private->PlatformNumRsvd; Index++) { + if ((SlaveAddress.SmbusDeviceAddress << 1) == Private->PlatformRsvdAddr[Index]) { + return FALSE; + } + } + /// + /// See if this is a reserved address + /// + for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) { + if ((SlaveAddress.SmbusDeviceAddress << 1) == (UINTN) mReservedAddress[Index]) { + return FALSE; + } + } + + return TRUE; +} diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif new file mode 100644 index 0000000..6682817 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif @@ -0,0 +1,14 @@ +<component> + name = "PchSmbusArpDisabled" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Pei" + RefName = "PchSmbusArpDisabled" +[files] +"PchSmbusArpDisabled.sdl" +"PchSmbusArpDisabled.mak" +"PchSmbusEntry.c" +"PchSmbus.h" +"PchSmbusArpdisabled.c" +"PchSmbus.dxs" +"PchSmbusArpDisabled.inf" +<endComponent> diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf new file mode 100644 index 0000000..a66047e --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf @@ -0,0 +1,88 @@ +## @file +# Component description file for PchSmbus module +# This version will NOT include ARP support. +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + +[defines] +BASE_NAME = PchSmbusArpDisabled +FILE_GUID = 643DF777-F312-42ed-81CC-1B1F57E18AD6 +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + PchSmbus.h + PchSmbusEntry.c + PchSmbusArpDisabled.c + ../Common/PchSmbusExec.c +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[includes.common] + . + ../Common + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Pei/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library +# +# EDK II Glue Library utilizes some standard headers from EDK +# + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode + +[libraries.common] + EdkFrameworkPpiLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + EdkIIGluePeiMemoryAllocationLib + EdkIIGlueBasePciLibPciExpress + PchPlatformLib + +[nmake.common] + IMAGE_ENTRY_POINT=_ModuleEntryPoint + DPX_SOURCE=PchSmbus.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + -D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak new file mode 100644 index 0000000..531b08e --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak @@ -0,0 +1,97 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.mak 2 2/24/12 2:23a Victortu $ +# +# $Revision: 2 $ +# +# $Date: 2/24/12 2:23a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.mak $ +# +# 2 2/24/12 2:23a Victortu +# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00. +# +# 1 2/08/12 9:20a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* + +#--------------------------------------------------------------------------- +# Create PchSmbusArpDisabled Driver +#--------------------------------------------------------------------------- +EDK : PchSmbusArpDisabled +PchSmbusArpDisabled : $(BUILD_DIR)\PchSmbusArpDisabled.mak PchSmbusArpDisabledBin + + +$(BUILD_DIR)\PchSmbusArpDisabled.mak : $(PchSmbusArpDisabled_DIR)\$(@B).cif $(PchSmbusArpDisabled_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PchSmbusArpDisabled_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PchSmbusArpDisabled_INCLUDES=\ + $(INTEL_PCH_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + +PchSmbusArpDisabled_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_CF8_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ + +PchSmbusArpDisabled_LIB_LINKS =\ + $(EDKFRAMEWORKPPILIB)\ + $(PchPlatformPeiLib_LIB)\ + $(PchSmbusCommonPeiLib_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGluePeiReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(EdkIIGluePeiMemoryAllocationLib_LIB)\ + $(EdkIIGlueBasePciLibCf8_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + +PchSmbusArpDisabledBin: $(PchSmbusArpDisabled_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PchSmbusArpDisabled.mak all\ + NAME=PchSmbusArpDisabled\ + MAKEFILE=$(BUILD_DIR)\PchSmbusArpDisabled.mak \ + GUID=643DF777-F312-42ed-81CC-1B1F57E18AD6\ + "MY_INCLUDES=$(PchSmbusArpDisabled_INCLUDES)"\ + "MY_DEFINES=$(MY_DEFINES) $(PchSmbusArpDisabled_DEFINES)"\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=PEIM \ + EDKIIModule=PEIM\ + DEPEX1=$(PchSmbusArpDisabled_DIR)\PchSmbus.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl new file mode 100644 index 0000000..23e79a5 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl @@ -0,0 +1,67 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.sdl 1 2/08/12 9:20a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 9:20a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.sdl $ +# +# 1 2/08/12 9:20a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "PchSmbusArpDisabled_SUPPORT" + Value = "1" + Help = "Main switch to enable PchSmbusArpDisabled support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "PchSmbusArpDisabled_DIR" + Help = "PchSmbusArpDisabled file source directory" +End + +MODULE + Help = "Includes PchSmbusArpDisabled.mak to Project" + File = "PchSmbusArpDisabled.mak" +End + +ELINK + Name = "$(BUILD_DIR)\PchSmbusArpDisabled.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c new file mode 100644 index 0000000..91a8614 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c @@ -0,0 +1,291 @@ +/** @file + PCH Smbus PEIM. This file is used when we want ARP support. + +@copyright + Copyright (c) 2009 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "PchSmbus.h" + +static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEndOfPeiSignalPpiGuid, + EndOfPeiCallback +}; + +EFI_GUID mEfiSmbusArpMapGuid = EFI_SMBUS_ARP_MAP_GUID; + +/** + Set Slave address for an Smbus device with a known UDID or perform a general + ARP of all devices. + + @param[in] PeiServices Pointer to the PEI Services table. + @param[in] This Pointer to the instance of the PEI_SMBUS_PPI. + @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID. + @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID. + @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusArpDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI * This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID * SmbusUdid OPTIONAL, + IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL + ) +{ + SMBUS_INSTANCE *Private; + EFI_STATUS Status; + UINT8 OldMapEntries; + + DEBUG ((EFI_D_INFO, "PEI SmbusArpDevice() Start\n")); + + Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This); + + OldMapEntries = Private->DeviceMapEntries; + + if (ArpAll) { + Status = SmbusFullArp (Private); + } else { + if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Status = SmbusDirectedArp (Private, SmbusUdid, SlaveAddress); + } + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// If we just added the first entry in the device map, set up a callback so + /// we can pass the map to DXE via a HOB at the end of PEI. + /// + if ((OldMapEntries == 0) && (Private->DeviceMapEntries > 0)) { + Status = (**PeiServices).NotifyPpi (PeiServices, &mNotifyList); + ASSERT_EFI_ERROR (Status); + } + + DEBUG ((EFI_D_INFO, "PEI SmbusArpDevice() End\n")); + + return EFI_SUCCESS; +} + +/** + Get a pointer to the assigned mappings of UDID's to Slave Addresses. + + @param[in] PeiServices Pointer to the PEI Services table. + @param[in] This Pointer to the instance of the PEI_SMBUS_PPI. + @param[in, out] Length Buffer to contain the lenght of the Device Map. + @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusGetArpMap ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap + ) +{ + SMBUS_INSTANCE *Private; + + Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This); + + *Length = Private->DeviceMapEntries * sizeof (EFI_SMBUS_DEVICE_MAP); + *SmbusDeviceMap = Private->DeviceMap; + return EFI_SUCCESS; +} + +/** + Register a callback in the event of a Host Notify command being sent by a + specified Slave Device. + + @param[in] PeiServices The general PEI Services + @param[in] This The PPI instance + @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap. + @param[in] Data Data of the Host Notify command we want to trap. + @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction + ) +{ + SMBUS_INSTANCE *Private; + + DEBUG ((EFI_D_INFO, "PEI SmbusNotify() Start\n")); + + Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This); + + if (NotifyFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + /// + /// NOTE: Currently there is no periodic event in PEI. + /// So we just check the Notification at the end of in each + /// Smbus.Execute function. + /// + if (Private->NotifyFunctionNum >= MAX_SMBUS_NOTIFICATION) { + return EFI_OUT_OF_RESOURCES; + } + + Private->NotifyFunctionList[Private->NotifyFunctionNum].SlaveAddress.SmbusDeviceAddress = SlaveAddress.SmbusDeviceAddress; + Private->NotifyFunctionList[Private->NotifyFunctionNum].Data = Data; + Private->NotifyFunctionList[Private->NotifyFunctionNum].NotifyFunction = NotifyFunction; + Private->NotifyFunctionNum++; + + /// + /// Last step, check notification + /// + CheckNotification (Private); + + DEBUG ((EFI_D_INFO, "PEI SmbusNotify() End\n")); + + return EFI_SUCCESS; +} + +/** + This function gets called back at the end of PEI if any devices were ARPed + during PEI. It will build a HOB to describe to DXE what devices were ARPed. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The EndOfPeiSignal PPI. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *SmbusDescriptor; + PEI_SMBUS_PPI *SmbusPpi; + SMBUS_INSTANCE *Private; + UINTN BufferSize; + VOID *Hob; + + DEBUG ((EFI_D_INFO, "PEI EndOfPeiCallback() Start\n")); + + Status = (**PeiServices).LocatePpi ( + PeiServices, + &gPeiSmbusPpiGuid, /// GUID + 0, /// INSTANCE + &SmbusDescriptor, /// PEI_PPI_DESCRIPTOR + &SmbusPpi /// PPI + ); + ASSERT_EFI_ERROR (Status); + + Private = SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS (SmbusDescriptor); + BufferSize = sizeof (EFI_SMBUS_DEVICE_MAP) * Private->DeviceMapEntries; + + Hob = BuildGuidDataHob ( + &mEfiSmbusArpMapGuid, + Private->DeviceMap, + BufferSize + ); + ASSERT (Hob != NULL); + + DEBUG ((EFI_D_INFO, "PEI EndOfPeiCallback() End\n")); + + return EFI_SUCCESS; +} + +/** + Function to be called when SMBus.Execute happens. This will check if + the SMBus Host Controller has received a Host Notify command. If so, it will + see if a notification has been reqested on that event and make any callbacks + that may be necessary. + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval None +**/ +VOID +CheckNotification ( + IN SMBUS_INSTANCE *Private + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + UINT8 SstsReg; + UINTN Data; + UINTN Index; + + DEBUG ((EFI_D_INFO, "PEI CheckNotification() Start\n")); + + if (Private->NotifyFunctionNum == 0) { + /// + /// Since no one register it, not need to check. + /// + return; + } + + SstsReg = SmbusIoRead (R_PCH_SMBUS_SSTS); + if (!(SstsReg & B_PCH_SMBUS_HOST_NOTIFY_STS)) { + /// + /// Host Notify has not been received + /// + return; + } + /// + /// There was a Host Notify, see if any one wants to know about it + /// + SlaveAddress.SmbusDeviceAddress = (SmbusIoRead (R_PCH_SMBUS_NDA)) >> 1; + + for (Index = 0; Index < Private->NotifyFunctionNum; Index++) { + + if (Private->NotifyFunctionList[Index].SlaveAddress.SmbusDeviceAddress == SlaveAddress.SmbusDeviceAddress) { + Data = (SmbusIoRead (R_PCH_SMBUS_NDHB) << 8) + (SmbusIoRead (R_PCH_SMBUS_NDLB)); + if ((UINT16) Private->NotifyFunctionList[Index].Data == (UINT16) Data) { + /// + /// We have a match, notify the requested function + /// + Private->NotifyFunctionList[Index].NotifyFunction ( + Private->PeiServices, + &Private->SmbusPpi, + SlaveAddress, + Data + ); + } + } + } + /// + /// Clear the Notify Status bit and exit. + /// + SmbusIoWrite (R_PCH_SMBUS_SSTS, B_PCH_SMBUS_HOST_NOTIFY_STS); + + DEBUG ((EFI_D_INFO, "PEI CheckNotification() End\n")); +} diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif new file mode 100644 index 0000000..5674891 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif @@ -0,0 +1,15 @@ +<component> + name = "PchSmbusArpEnabled" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Pei" + RefName = "PchSmbusArpEnabled" +[files] +"PchSmbusArpEnabled.sdl" +"PchSmbusArpEnabled.mak" +"PchSmbusEntry.c" +"PchSmbus.h" +"PchSmbusArpEnabled.c" +"PchSmbusArp.c" +"PchSmbus.dxs" +"PchSmbusArpEnabled.inf" +<endComponent> diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf new file mode 100644 index 0000000..c4a23f1 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf @@ -0,0 +1,91 @@ +## @file +# Component description file for PchSmbus module +# This version will include ARP support. +# +#@copyright +# Copyright (c) 2009 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + +[defines] +BASE_NAME = PchSmbusArpEnabled +FILE_GUID = 22B194B4-CC0E-46c7-9FCE-DA10D6ED1731 +COMPONENT_TYPE = PE32_PEIM + +[sources.common] + PchSmbus.h + PchSmbusEntry.c + PchSmbusArpEnabled.c + PchSmbusArp.c + ../Common/PchSmbusExec.c +# +# Edk II Glue Driver Entry Point +# + EdkIIGluePeimEntryPoint.c + +[includes.common] + . + ../Common + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Pei/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library +# +# EDK II Glue Library utilizes some standard headers from EDK +# + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode + +[libraries.common] + EdkFrameworkPpiLib + EdkIIGlueBaseIoLibIntrinsic + EdkIIGluePeiDebugLibReportStatusCode + EdkIIGluePeiReportStatusCodeLib + EdkIIGluePeiServicesLib + EdkIIGluePeiMemoryAllocationLib + EdkIIGluePeiHobLib + EdkIIGlueBasePciLibPciExpress + PchPlatformLib + +[nmake.common] + IMAGE_ENTRY_POINT=_ModuleEntryPoint + DPX_SOURCE=PchSmbus.dxs +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PeimInitializePchSmbus + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + -D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \ + -D __EDKII_GLUE_PEI_HOB_LIB__ \ + -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak new file mode 100644 index 0000000..b1b2ce9 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak @@ -0,0 +1,97 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.mak 2 2/24/12 2:29a Victortu $ +# +# $Revision: 2 $ +# +# $Date: 2/24/12 2:29a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.mak $ +# +# 2 2/24/12 2:29a Victortu +# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00. +# +# 1 2/08/12 9:28a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* + +#--------------------------------------------------------------------------- +# Create PchSmbusArpEnabled Driver +#--------------------------------------------------------------------------- +EDK : PchSmbusArpEnabled +PchSmbusArpEnabled : $(BUILD_DIR)\PchSmbusArpEnabled.mak PchSmbusArpEnabledBin + + +$(BUILD_DIR)\PchSmbusArpEnabled.mak : $(PchSmbusArpEnabled_DIR)\$(@B).cif $(PchSmbusArpEnabled_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PchSmbusArpEnabled_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PchSmbusArpEnabled_INCLUDES=\ + $(INTEL_PCH_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + +PchSmbusArpEnabled_DEFINES = $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim"\ + /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \ + /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_PEI_SERVICES_LIB__ \ + /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \ + /D __EDKII_GLUE_PEI_HOB_LIB__ \ + /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ + +PchSmbusArpEnabled_LIB_LINKS =\ + $(EDKFRAMEWORKPPILIB)\ + $(PchPlatformPeiLib_LIB)\ + $(PchSmbusCommonPeiLib_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ + $(EdkIIGlueBaseLibIA32_LIB)\ + $(EdkIIGlueBaseIoLibIntrinsic_LIB)\ + $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\ + $(EdkIIGluePeiReportStatusCodeLib_LIB)\ + $(EdkIIGluePeiServicesLib_LIB)\ + $(EdkIIGluePeiMemoryAllocationLib_LIB)\ + $(EdkIIGluePeiHobLib_LIB)\ + $(EdkIIGlueBasePciLibPciExpress_LIB)\ + +PchSmbusArpEnabledBin: $(PchSmbusArpEnabled_LIB_LINKS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PchSmbusArpEnabled.mak all\ + NAME=PchSmbusArpEnabled\ + MAKEFILE=$(BUILD_DIR)\PchSmbusArpEnabled.mak \ + GUID=22B194B4-CC0E-46c7-9FCE-DA10D6ED1731\ + "MY_INCLUDES=$(PchSmbusArpEnabled_INCLUDES)"\ + "MY_DEFINES=$(MY_DEFINES) $(PchSmbusArpEnabled_DEFINES)"\ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=PEIM \ + EDKIIModule=PEIM\ + DEPEX1=$(PchSmbusArpEnabled_DIR)\PchSmbus.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \ + COMPRESS=0 +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl new file mode 100644 index 0000000..dcb1377 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl @@ -0,0 +1,67 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.sdl 1 2/08/12 9:28a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 9:28a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.sdl $ +# +# 1 2/08/12 9:28a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "PchSmbusArpEnabled_SUPPORT" + Value = "0" + Help = "Main switch to enable PchSmbusArpEnabled support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "PchSmbusArpEnabled_DIR" + Help = "PchSmbusArpEnabled file source directory" +End + +MODULE + Help = "Includes PchSmbusArpEnabled.mak to Project" + File = "PchSmbusArpEnabled.mak" +End + +ELINK + Name = "$(BUILD_DIR)\PchSmbusArpEnabled.ffs" + Parent = "FV_BB" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c new file mode 100644 index 0000000..b249317 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c @@ -0,0 +1,117 @@ +/** @file + PCH Smbus PEIM. This file is used when we do not want ARP support. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement +**/ +#include "PchSmbus.h" + +/** + Set Slave address for an Smbus device with a known UDID or perform a general + ARP of all devices. + + @param[in] PeiServices Pointer to the PEI Services table. + @param[in] This Pointer to the instance of the PEI_SMBUS_PPI. + @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID. + @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID. + @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusArpDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI * This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID * SmbusUdid OPTIONAL, + IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Get a pointer to the assigned mappings of UDID's to Slave Addresses. + + @param[in] PeiServices Pointer to the PEI Services table. + @param[in] This Pointer to the instance of the PEI_SMBUS_PPI. + @param[in, out] Length Buffer to contain the lenght of the Device Map. + @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusGetArpMap ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Register a callback in the event of a Host Notify command being sent by a + specified Slave Device. + + @param[in] PeiServices The general PEI Services + @param[in] This The PPI instance + @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap. + @param[in] Data Data of the Host Notify command we want to trap. + @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs. + + @exception EFI_UNSUPPORTED This functionality is not supported + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction + ) +{ + /// + /// Requires a periodic event, not supported in PEI + /// + return EFI_UNSUPPORTED; +} + +/** + Function to be called when SMBus.Execute happens. This will check if + the SMBus Host Controller has received a Host Notify command. If so, it will + see if a notification has been reqested on that event and make any callbacks + that may be necessary. + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval None +**/ +VOID +CheckNotification ( + IN SMBUS_INSTANCE *Private + ) +{ + return; +}
\ No newline at end of file diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c new file mode 100644 index 0000000..3e4a6a0 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c @@ -0,0 +1,241 @@ +/** @file + PCH Smbus PEIM. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "PchSmbus.h" + +/// +/// Global variables +/// +EFI_GUID mPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID; + +// +// Functions +// + +/** + This function provides a standard way to execute an SMBUS command + PPI as defined in the SMBus Specification. The data can either be of + the length byte, word, or a block of data (1 to 32 bytes long). + The resulting transaction will be either the SMBus Slave Device accepts + this transaction or this function returns with an error + + @param[in] PeiServices PEI services table pointer + @param[in] This PEI_SMBUS_PPI instance + @param[in] SlaveAddress Smbus Slave device address + @param[in] Command Command to be sent + @param[in] Operation Which SMBus PPI will be used + @param[in] PecCheck Defines if Packet Error Code Checking is to be used + @param[in, out] Length How many bytes to read/write. Must be 1 <= Length <= 32 depending on the Operation + @param[in, out] Buffer Data buffer + + @retval EFI_SUCCESS Operation success. + Length will contain the actual number of bytes read. + Buffer will contain the data read. + @retval Otherwise Operation failed. +**/ +EFI_STATUS +EFIAPI +SmbusExecute ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_SMBUS_PPI *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + SMBUS_INSTANCE *Private; + DEBUG ((EFI_D_EVENT, "PEI SmbusExecute() Start, SmbusDeviceAddress=%x, Command=%x, Operation=%x\n", (SlaveAddress.SmbusDeviceAddress << 1), Command, Operation)); + Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This); + + Status = SmbusExec ( + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer + ); + /// + /// Last step, check notification + /// + CheckNotification (Private); + DEBUG ((EFI_D_EVENT, "PEI SmbusExecute() End\n")); + return Status; +} + +/** + Initialize the Smbus PPI and program the Smbus BAR + + @param[in] FfsHeader Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database +**/ +EFI_STATUS +InitializePchSmbusPeim ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + SMBUS_INSTANCE *Private; + UINTN SmbusRegBase; + + DEBUG ((EFI_D_INFO, "InitializePchSmbusPeim() Start\n")); + + Private = (SMBUS_INSTANCE *) AllocatePool (sizeof (SMBUS_INSTANCE)); + if (Private == NULL) { + DEBUG ((EFI_D_ERROR, "Failed to allocate memory for Private! \n")); + return EFI_OUT_OF_RESOURCES; + } + + InitializePeiPrivate (PeiServices, Private); + + SmbusRegBase = MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_SMBUS, + PCI_FUNCTION_NUMBER_PCH_SMBUS, + 0 + ); + /// + /// Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves + /// + MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, Private->SmbusIoBase); + + MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE); + + /// + /// Reset the SMBus host controller + /// + MmioOr8 (SmbusRegBase + R_PCH_SMBUS_HOSTC, B_PCH_SMBUS_HOSTC_SSRESET); + + /// + /// Enable the SMBus host controller + /// + MmioAndThenOr8 ( + SmbusRegBase + R_PCH_SMBUS_HOSTC, + (UINT8) (~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)), + B_PCH_SMBUS_HOSTC_HST_EN + ); + + /// + /// Clear Status Register before anyone uses the interfaces + /// + SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); + + Status = PeiServicesInstallPpi (&Private->PpiDescriptor); + ASSERT_EFI_ERROR (Status); + + /// + /// Install a call-back for the permanent-memory so that we can fix up internal pointers + /// + Status = (**PeiServices).NotifyPpi (PeiServices, &Private->NotifyDescriptor); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "InitializePchSmbusPeim() End\n")); + + return EFI_SUCCESS; +} + +/** + This function initializes the SmBus driver in PEI. + + @param[in] PeiServices Standard PEI services + @param[in] Private SMBUS private data structure + + @retval None. +**/ +VOID +InitializePeiPrivate ( + IN EFI_PEI_SERVICES **PeiServices, + IN SMBUS_INSTANCE *Private + ) +{ + EFI_STATUS Status; + + Private->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE; + Private->PeiServices = PeiServices; + + Status = (**PeiServices).LocatePpi ( + PeiServices, + &mPeiSmbusPolicyPpiGuid, + 0, + NULL, + (VOID **) &(Private->SmbusPolicy) + ); + ASSERT_EFI_ERROR (Status); + + Private->SmbusIoBase = Private->SmbusPolicy->BaseAddress; + + Private->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + Private->PpiDescriptor.Guid = &gEfiPeiSmbusPpiGuid; + + Private->PpiDescriptor.Ppi = &Private->SmbusPpi; + + Private->SmbusPpi.Execute = SmbusExecute; + Private->SmbusPpi.ArpDevice = SmbusArpDevice; + Private->SmbusPpi.GetArpMap = SmbusGetArpMap; + Private->SmbusPpi.Notify = SmbusNotify; + + Private->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + Private->NotifyDescriptor.Guid = &gEfiPeiMemoryDiscoveredPpiGuid; + Private->NotifyDescriptor.Notify = MemoryDiscoveredPpiNotifyCallback; + + Private->DeviceMapEntries = 0; + Private->PlatformNumRsvd = Private->SmbusPolicy->NumRsvdAddress; + Private->PlatformRsvdAddr = Private->SmbusPolicy->RsvdAddress; + + Private->NotifyFunctionNum = 0; + + return; +} + +/** + Fix up pointers since they are located in real memory now. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] NotifyDescriptor The notification structure this PEIM registered on install. + @param[in] Ppi The memory discovered PPI. Not used. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +MemoryDiscoveredPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + SMBUS_INSTANCE *Private; + + Private = SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS (NotifyDescriptor); + + InitializePeiPrivate (PeiServices, Private); + + return EFI_SUCCESS; +} |