From nobody Thu May 2 04:14:25 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1518501346290414.8896742155383; Mon, 12 Feb 2018 21:55:46 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 179B121CF1CEF; Mon, 12 Feb 2018 21:49:54 -0800 (PST) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 72F2121CF1CE5 for ; Mon, 12 Feb 2018 21:49:52 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Feb 2018 21:55:42 -0800 Received: from zwei4-mobl1.ccr.corp.intel.com ([10.239.158.43]) by fmsmga002.fm.intel.com with ESMTP; 12 Feb 2018 21:55:41 -0800 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.151; helo=mga17.intel.com; envelope-from=david.wei@intel.com; receiver=edk2-devel@lists.01.org X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,506,1511856000"; d="scan'208";a="19529174" From: zwei4 To: edk2-devel@lists.01.org Date: Tue, 13 Feb 2018 13:55:35 +0800 Message-Id: <20180213055535.24196-1-david.wei@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 Subject: [edk2] [Patch][edk2-platforms/devel-MinnowBoard3-UDK2017] SMBus Host driver. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add Apollo Lake SMBus host controller DXE driver. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: zwei4 --- .../BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbus.h | 358 +++++++++++ .../SouthCluster/Smbus/Dxe/PchSmbusArp.c | 673 +++++++++++++++++= ++++ .../SouthCluster/Smbus/Dxe/PchSmbusDxe.inf | 63 ++ .../SouthCluster/Smbus/Dxe/PchSmbusEntry.c | 155 +++++ 4 files changed, 1249 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/= PchSmbus.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/= PchSmbusArp.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/= PchSmbusDxe.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/= PchSmbusEntry.c diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbu= s.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbus.h new file mode 100644 index 000000000..5e226a80d --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbus.h @@ -0,0 +1,358 @@ +/** @file + PCH SMBus Protocol. + + Copyright (c) 2018, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ +#ifndef _DXE_PCH_SMBUS_H +#define _DXE_PCH_SMBUS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Definitions +// + +/// +/// Max number of SMBus devices (7 bit address yields 128 combinations but= 21 of those are reserved) +/// +#define MAX_SMBUS_DEVICES 107 +#define MICROSECOND 10 +#define MILLISECOND (1000 * MICROSECOND) +#define ONESECOND (1000 * MILLISECOND) + +/// +/// Private Data Structures +/// +typedef struct _SMBUS_NOTIFY_FUNCTION_LIST_NODE { + UINT32 Signature; + LIST_ENTRY Link; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + UINTN Data; + EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction; +} SMBUS_NOTIFY_FUNCTION_LIST_NODE; + +#define SMBUS_NOTIFY_FUNCTION_LIST_NODE_FROM_LINK(_node) \ + CR ( \ + _node, \ + SMBUS_NOTIFY_FUNCTION_LIST_NODE, \ + Link, \ + PCH_SMBUS_PRIVATE_DATA_SIGNATURE \ + ) + +/// +/// Declare a local instance structure for this driver +/// +typedef struct _SMBUS_INSTANCE { + UINTN Signature; + EFI_HANDLE Handle; + + UINT32 SmbusIoBase; + SMBUS_IO_READ SmbusIoRead; + SMBUS_IO_WRITE SmbusIoWrite; + SMBUS_IO_DONE IoDone; + + /// + /// Published interface + /// + EFI_SMBUS_HC_PROTOCOL SmbusController; + + UINT8 DeviceMapEntries; + EFI_SMBUS_DEVICE_MAP DeviceMap[MAX_SMBUS_DEVICES]; + + UINT8 PlatformNumRsvd; + CONST UINT8 *PlatformRsvdAddr; + + LIST_ENTRY NotifyFunctionList; + EFI_EVENT NotificationEvent; + +} SMBUS_INSTANCE; + +// +// Driver global data +// +SMBUS_INSTANCE *mSmbusContext; + +// +// Prototypes +// + +/** + Execute an SMBUS operation + + @param[in] This The protocol instance + @param[in] SlaveAddress The address of the SMBUS slave device + @param[in] Command The SMBUS command + @param[in] Operation Which SMBus protocol will be issued + @param[in] PecCheck If Packet Error Code Checking is to be u= sed + @param[in, out] Length Length of dta + @param[in, out] Buffer Data buffer + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +EFIAPI +SmbusExecute ( + IN CONST 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 Module Entry Point. + =20 + - Introduction + The SMBus module is a DXE driver that provides a standard way to execu= te an SMBus command. + + - @pre + - @link SC_POLICY SC_POLICY_HOB @endlink + - This module uses the parameters in SmbusConfig for platform reserv= ed (non ARP capable) addresses. + + - @result + The SMBus driver produces EFI_SMBUS_HC_PROTOCOL which is documented in= the SMBus Host Controller + Protocol Specification. + + @param[in] ImageHandle ImageHandle of this module + @param[in] SystemTable EFI System Table + + @retval EFI_SUCCESS Driver initializes successfully + @retval Others Some error occurred +**/ +EFI_STATUS +EFIAPI +InitializePchSmbus ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Set Slave address for an Smbus device with a known UDID or perform a gen= eral + ARP of all devices. + + @param[in] This Pointer to the instance of the EFI_SMBUS= _HC_PROTOCOL. + @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just = ARP the specified UDID. + @param[in] SmbusUdid When doing a directed ARP, ARP the devic= e with this UDID. + @param[in, out] SlaveAddress Buffer to store new Slave Address during = directed ARP. On output,If + ArpAlll =3D=3D TRUE, this will contain t= he newly assigned Slave address. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER ArpAll =3D=3D FALSE but SmbusUdid or Sla= veAddress are NULL. + @retval Others Return value from SmbusFullArp() or Smbu= sDirectedArp(). +**/ +EFI_STATUS +EFIAPI +SmbusArpDevice ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL + ); + +/** + Get a pointer to the assigned mappings of UDID's to Slave Addresses. + + @param[in] This Pointer to the instance of the EFI_SMBUS= _HC_PROTOCOL. + @param[in, out] Length Buffer to contain the lenght of the Devi= ce Map, it will be updated to + contain the number of pairs of UDID's ma= pped to Slave Addresses. + @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Devic= e Map, it will be updated to + point to the first pair in the Device Map + + @retval EFI_SUCCESS Function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusGetArpMap ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap + ); + +/** + Register a callback in the event of a Host Notify command being sent by a + specified Slave Device. + + @param[in] This Pointer to the instance of the EFI_SMBUS= _HC_PROTOCOL. + @param[in] SlaveAddress Address of the device whose Host Notify = command we want to + trap. + @param[in] Data Data of the Host Notify command we want = to trap. + @param[in] NotifyFunction Function to be called in the event the d= esired Host Notify + command occurs. + + @retval EFI_UNSUPPORTED Unable to create the event needed for no= tifications. + @retval EFI_INVALID_PARAMETER NotifyFunction was NULL. + @retval EFI_OUT_OF_RESOURCES Unable to allocate space to register the= notification. + @retval EFI_SUCCESS Function completed successfully +**/ +EFI_STATUS +EFIAPI +SmbusNotify ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction + ); + +/** + Set up a periodic event so that we can check if any Slave Device has sen= t a + Notify ARP Master command. + + @retval EFI_SUCCESS Periodic event successfully set up. + @retval Others Failed to set up Periodic event. + Error value from CreateEvent(). + Error value from SetTimer(). +**/ +EFI_STATUS +InitializePeriodicEvent ( + VOID + ); + +/** + Function to be called every time periodic event happens. This will check= if + the SMBus Host Controller has received a Host Notify command. If so, it = will + see if a notification has been reqested on that event and make any callb= acks + that may be necessary. + + @param[in] Event The periodic event that occured and got = us into this callback. + @param[in] Context Event context. Will be NULL in this case= , since we already have our + private data in a module global variable. +**/ +VOID +EFIAPI +PollSmbusNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Issue a prepare ARP command to informs all devices that the ARP Master i= s starting the ARP process + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +SmbusPrepareToArp ( + IN SMBUS_INSTANCE *Private + ); + +/** + Issue a Get UDID (general) command to requests ARP-capable and/or Discov= erable 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 s= lave device return + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +SmbusGetUdidGeneral ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ); + +/** + Issue a Assign address command to assigns an address to a specific slave= device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] DeviceMap Pointer to SMBUS device map table that s= end to slave device + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +SmbusAssignAddress ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ); + +/** + Do a fully (general) Arp procress to assign the slave address of all ARP= -capable device. + This function will issue the "Prepare to ARP", "Get UDID" and "Assign Ad= dress" 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-c= apable device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SmbusUdid When doing a directed ARP, ARP the devic= e 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 assi= gn + @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 + ); + +#endif diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbu= sArp.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbusArp= .c new file mode 100644 index 000000000..7d616be8a --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbusArp.c @@ -0,0 +1,673 @@ +/** @file + PCH SMBus Driver, ARP functions. + + Copyright (c) 2018, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ +#include "PchSmbus.h" + +/// +/// These addresses are reserved by the SMBus 2.0 specification +/// +static UINT8 mReservedAddress[SMBUS_NUM_RESERVED] =3D { + 0x00, + 0x02, + 0x04, + 0x06, + 0x08, + 0x0A, + 0x0C, + 0x0E, + 0x10, + 0x18, + 0x50, + 0x6E, + 0xC2, + 0xF0, + 0xF2, + 0xF4, + 0xF6, + 0xF8, + 0xFA, + 0xFC, + 0xFE, + 0x12, + 0x14, + 0x16, + 0x58, + 0x5A, + 0x80, + 0x82, + 0x84, + 0x86, + 0x88, + 0x90, + 0x92, + 0x94, + 0x96, + 0x1A, + 0x1C, + 0x1E +}; + +/** + Set Slave address for an SMBus device with a known UDID or perform a gen= eral + ARP of all devices. + + @param[in] This Pointer to the instance of the EFI_SMBUS= _HC_PROTOCOL. + @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just = ARP the specified UDID. + @param[in] SmbusUdid When doing a directed ARP, ARP the devic= e with this UDID. + @@param[in, out] SlaveAddress Buffer to store new Slave Address during= directed ARP. On output,If + ArpAlll =3D=3D TRUE, this will contain t= he newly assigned Slave address. + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER ArpAll =3D=3D FALSE but SmbusUdid or Sla= veAddress are NULL. + @retval Others Return value from SmbusFullArp() or Smbu= sDirectedArp(). +**/ +EFI_STATUS +EFIAPI +SmbusArpDevice ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL + ) +{ + DEBUG ((DEBUG_INFO, "SmbusArpDevice() Start\n")); + + InitializeSmbusRegisters (); + + DEBUG ((DEBUG_INFO, "SmbusArpDevice() End\n")); + + if (ArpAll) { + return SmbusFullArp (mSmbusContext); + } else { + if ((SmbusUdid =3D=3D NULL) || (SlaveAddress =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + return SmbusDirectedArp (mSmbusContext, SmbusUdid, SlaveAddress); + } +} + +/** + Get a pointer to the assigned mappings of UDID's to Slave Addresses. + + @param[in] This Pointer to the instance of the EFI_SMBUS= _HC_PROTOCOL. + @param[in, out] Length Buffer to contain the lenght of the Devi= ce Map, it will be updated to + contain the number of pairs of UDID's ma= pped to Slave Addresses. + @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Devic= e Map, it will be updated to + point to the first pair in the Device Map + + @retval EFI_SUCCESS Function completed successfully. +**/ +EFI_STATUS +EFIAPI +SmbusGetArpMap ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap + ) +{ + *Length =3D mSmbusContext->DeviceMapEntries * sizeof (EFI_SMBUS_= DEVICE_MAP); + *SmbusDeviceMap =3D mSmbusContext->DeviceMap; + return EFI_SUCCESS; +} + +/** + Register a callback in the event of a Host Notify command being sent by a + specified Slave Device. + + @param[in] This Pointer to the instance of the EFI_SMBUS= _HC_PROTOCOL. + @param[in] SlaveAddress Address of the device whose Host Notify = command we want to + trap. + @param[in] Data Data of the Host Notify command we want = to trap. + @param[in] NotifyFunction Function to be called in the event the d= esired Host Notify + command occurs. + + @retval EFI_UNSUPPORTED Unable to create the event needed for no= tifications. + @retval EFI_INVALID_PARAMETER NotifyFunction was NULL. + @retval EFI_OUT_OF_RESOURCES Unable to allocate space to register the= notification. + @retval EFI_SUCCESS Function completed successfully +**/ +EFI_STATUS +EFIAPI +SmbusNotify ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction + ) +{ + EFI_STATUS Status; + SMBUS_NOTIFY_FUNCTION_LIST_NODE *NewNode; + + DEBUG ((DEBUG_INFO, "SmbusNotify() Start\n")); + + if (NotifyFunction =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + NewNode =3D (SMBUS_NOTIFY_FUNCTION_LIST_NODE *) AllocatePool (sizeof (SM= BUS_NOTIFY_FUNCTION_LIST_NODE)); + if (NewNode =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate memory for NewNode! \n")); + return EFI_OUT_OF_RESOURCES; + } + // + // If this is the first notification request, start an event to periodic= ally + // check for a Notify master command. + // + if (!mSmbusContext->NotificationEvent) { + Status =3D InitializePeriodicEvent (); + if (EFI_ERROR (Status)) { + FreePool (NewNode); + return EFI_UNSUPPORTED; + } + } + + NewNode->Signature =3D PCH_SMBUS_PRIVATE_DATA_SIG= NATURE; + NewNode->SlaveAddress.SmbusDeviceAddress =3D SlaveAddress.SmbusDeviceAd= dress; + NewNode->Data =3D Data; + NewNode->NotifyFunction =3D NotifyFunction; + + InsertTailList (&mSmbusContext->NotifyFunctionList, &NewNode->Link); + + DEBUG ((DEBUG_INFO, "SmbusNotify() End\n")); + return EFI_SUCCESS; +} + +/** + Set up a periodic event so that we can check if any Slave Device has sen= t a + Notify ARP Master command. + + @retval EFI_SUCCESS Periodic event successfully set up. + @retval Others Failed to set up Periodic event. + Error value from CreateEvent(). + Error value from SetTimer(). +**/ +EFI_STATUS +InitializePeriodicEvent ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D gBS->CreateEvent ( + (EVT_TIMER | EVT_NOTIFY_SIGNAL), + TPL_CALLBACK, + PollSmbusNotify, + NULL, + &mSmbusContext->NotificationEvent + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gBS->SetTimer ( + mSmbusContext->NotificationEvent, + TimerPeriodic, + 1000 * MILLISECOND + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + Function to be called every time periodic event happens. This will check= if + the SMBus Host Controller has received a Host Notify command. If so, it = will + see if a notification has been reqested on that event and make any callb= acks + that may be necessary. + + @param[in] Event The periodic event that occured and got = us into this callback. + @param[in] Context Event context. Will be NULL in this case= , since we already have our + private data in a module global variable. +**/ +VOID +EFIAPI +PollSmbusNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + LIST_ENTRY *Link; + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + SMBUS_NOTIFY_FUNCTION_LIST_NODE *Node; + UINT8 SstsReg; + UINTN Data; + + DEBUG ((DEBUG_INFO, "PollSmbusNotify() Start\n")); + + InitializeSmbusRegisters (); + + SstsReg =3D SmbusIoRead (R_SMBUS_SSTS); + if (!(SstsReg & B_SMBUS_HOST_NOTIFY_STS)) { + // + // Host Notify has not been received + // + return; + } + =20 + // + // There was a Host Notify, see if any one wants to know about it + // + SlaveAddress.SmbusDeviceAddress =3D (SmbusIoRead (R_SMBUS_NDA)) >> 1; + + Link =3D GetFirstNode (&mSmbusContext->NotifyFunctionList); + + while (!IsNull (&mSmbusContext->NotifyFunctionList, Link)) { + Node =3D SMBUS_NOTIFY_FUNCTION_LIST_NODE_FROM_LINK (Link); + + if (Node->SlaveAddress.SmbusDeviceAddress =3D=3D SlaveAddress.SmbusDev= iceAddress) { + Data =3D (SmbusIoRead (R_SMBUS_NDHB) << 8) + (SmbusIoRead (R_SMBUS_N= DLB)); + if ((UINT16) Node->Data =3D=3D (UINT16) Data) { + // + // We have a match, notify the requested function + // + Node->NotifyFunction (SlaveAddress, Data); + } + } + + Link =3D GetNextNode (&mSmbusContext->NotifyFunctionList, &Node->Link); + } + =20 + // + // Clear the Notify Status bit and exit. + // + SmbusIoWrite (R_SMBUS_SSTS, B_SMBUS_HOST_NOTIFY_STS); + + DEBUG ((DEBUG_INFO, "PollSmbusNotify() End\n")); + + return; +} + +/** + Issue a prepare ARP command to informs all devices that the ARP Master i= s starting the ARP process + + @param[in] Private Pointer to the SMBUS_INSTANCE + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +SmbusPrepareToArp ( + IN SMBUS_INSTANCE *Private + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer; + + DEBUG ((DEBUG_INFO, "SmbusPrepareToArp() Start\n")); + + SlaveAddress.SmbusDeviceAddress =3D SMBUS_ADDRESS_ARP; + Length =3D 1; + Buffer =3D SMBUS_DATA_PREPARE_TO_ARP; + + Status =3D SmbusExec ( + SlaveAddress, + 0, + EfiSmbusSendByte, + TRUE, + &Length, + &Buffer + ); + + DEBUG ((DEBUG_INFO, "SmbusPrepareToArp() End\n")); + + return Status; +} + +/** + Issue a Get UDID (general) command to requests ARP-capable and/or Discov= erable 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 s= lave device return + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +SmbusGetUdidGeneral ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer[SMBUS_GET_UDID_LENGTH]; + + DEBUG ((DEBUG_INFO, "SmbusGetUdidGeneral() Start\n")); + + SlaveAddress.SmbusDeviceAddress =3D SMBUS_ADDRESS_ARP; + Length =3D SMBUS_GET_UDID_LENGTH; + + Status =3D SmbusExec ( + SlaveAddress, + SMBUS_DATA_GET_UDID_GENERAL, + EfiSmbusReadBlock, + TRUE, + &Length, + Buffer + ); + + if (!EFI_ERROR (Status)) { + if (Length =3D=3D SMBUS_GET_UDID_LENGTH) { + DeviceMap->SmbusDeviceUdid.DeviceCapabilities =3D Buffer[0]; + DeviceMap->SmbusDeviceUdid.VendorRevision =3D Buffer[1]; + DeviceMap->SmbusDeviceUdid.VendorId =3D (UINT16) ((Buffer[= 2] << 8) + Buffer[3]); + DeviceMap->SmbusDeviceUdid.DeviceId =3D (UINT16) ((Buffer[= 4] << 8) + Buffer[5]); + DeviceMap->SmbusDeviceUdid.Interface =3D (UINT16) ((Buffer[= 6] << 8) + Buffer[7]); + DeviceMap->SmbusDeviceUdid.SubsystemVendorId =3D (UINT16) ((Buffer[= 8] << 8) + Buffer[9]); + DeviceMap->SmbusDeviceUdid.SubsystemDeviceId =3D (UINT16) ((Buffer[= 10] << 8) + Buffer[11]); + DeviceMap->SmbusDeviceUdid.VendorSpecificId =3D (UINT32) ((Buffer[12= ] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]); + DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress =3D (UINT8) (Buffer= [16] >> 1); + } else { + Status =3D EFI_DEVICE_ERROR; + } + } + + DEBUG ((DEBUG_INFO, "SmbusGetUdidGeneral() End\n")); + + return Status; +} + +/** + Issue a Assign address command to assigns an address to a specific slave= device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in, out] DeviceMap Pointer to SMBus device map table that s= end to slave device + + @retval EFI_SUCCESS The SMBus operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +SmbusAssignAddress ( + IN SMBUS_INSTANCE *Private, + IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap + ) +{ + EFI_SMBUS_DEVICE_ADDRESS SlaveAddress; + EFI_STATUS Status; + UINTN Length; + UINT8 Buffer[SMBUS_GET_UDID_LENGTH]; + + DEBUG ((DEBUG_INFO, "SmbusAssignAddress() Start\n")); + + Buffer[0] =3D DeviceMap->SmbusDeviceUdid.DeviceCapabilities; + Buffer[1] =3D DeviceMap->SmbusDeviceUdid.VendorRevision; + Buffer[2] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId >> 8); + Buffer[3] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId); + Buffer[4] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId >> 8); + Buffer[5] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId); + Buffer[6] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.Interface >> 8); + Buffer[7] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.Interface); + Buffer[8] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8= ); + Buffer[9] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId); + Buffer[10] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> = 8); + Buffer[11] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId); + Buffer[12] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 2= 4); + Buffer[13] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 1= 6); + Buffer[14] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8= ); + Buffer[15] =3D (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId); + Buffer[16] =3D (UINT8) (DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress= << 1); + + SlaveAddress.SmbusDeviceAddress =3D SMBUS_ADDRESS_ARP; + Length =3D SMBUS_GET_UDID_LENGTH; + + Status =3D SmbusExec ( + SlaveAddress, + SMBUS_DATA_ASSIGN_ADDRESS, + EfiSmbusWriteBlock, + TRUE, + &Length, + Buffer + ); + + DEBUG ((DEBUG_INFO, "SmbusAssignAddress() End\n")); + + return Status; +} + +/** + Do a fully (general) Arp procress to assign the slave address of all ARP= -capable device. + This function will issue issue the "Prepare to ARP", "Get UDID" and "Ass= ign 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 ((DEBUG_INFO, "SmbusFullArp() Start\n")); + + Status =3D SmbusPrepareToArp (Private); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_DEVICE_ERROR) { + // + // ARP is complete + // + return EFI_SUCCESS; + } else { + return Status; + } + } + // + // Main loop to ARP all ARP-capable devices + // + do { + CurrentDeviceMap =3D &Private->DeviceMap[Private->DeviceMapEntries]; + Status =3D SmbusGetUdidGeneral (Private, CurrentDeviceMap); + if (EFI_ERROR (Status)) { + break; + } + + if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress =3D=3D (0x= FF >> 1)) { + // + // If address is unassigned, assign it + // + Status =3D GetNextAvailableAddress ( + Private, + &CurrentDeviceMap->SmbusDeviceAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0= xC0) !=3D 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 =3D GetNextAvailableAddress ( + Private, + &CurrentDeviceMap->SmbusDeviceAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + } + } + + Status =3D 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 !=3D EFI_DEVICE_ERROR) { + return Status; + } + } else { + // + // If there was no error, the address was assigned and we must updat= e our + // records. + // + Private->DeviceMapEntries++; + } + + } while (Private->DeviceMapEntries < MAX_SMBUS_DEVICES); + + DEBUG ((DEBUG_INFO, "SmbusFullArp() End\n")); + + return EFI_SUCCESS; +} + +/** + Do a directed Arp procress to assign the slave address of a single ARP-c= apable device. + + @param[in] Private Pointer to the SMBUS_INSTANCE + @param[in] SmbusUdid When doing a directed ARP, ARP the devic= e 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 assi= gn + @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 ((DEBUG_INFO, "SmbusDirectedArp() Start\n")); + + if (Private->DeviceMapEntries >=3D MAX_SMBUS_DEVICES) { + return EFI_OUT_OF_RESOURCES; + } + + CurrentDeviceMap =3D &Private->DeviceMap[Private->DeviceMapEntries]; + + // + // Find an available address to assign + // + Status =3D GetNextAvailableAddress ( + Private, + &CurrentDeviceMap->SmbusDeviceAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities =3D SmbusUdid->Dev= iceCapabilities; + CurrentDeviceMap->SmbusDeviceUdid.DeviceId =3D SmbusUdid->Dev= iceId; + CurrentDeviceMap->SmbusDeviceUdid.Interface =3D SmbusUdid->Int= erface; + CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId =3D SmbusUdid->Sub= systemDeviceId; + CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId =3D SmbusUdid->Sub= systemVendorId; + CurrentDeviceMap->SmbusDeviceUdid.VendorId =3D SmbusUdid->Ven= dorId; + CurrentDeviceMap->SmbusDeviceUdid.VendorRevision =3D SmbusUdid->Ven= dorRevision; + CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId =3D SmbusUdid->Ven= dorSpecificId; + + Status =3D SmbusAssignAddress (Private, CurrentDeviceMap); + if (EFI_ERROR (Status)) { + return Status; + } + + Private->DeviceMapEntries++; + SlaveAddress->SmbusDeviceAddress =3D CurrentDeviceMap->SmbusDeviceAddres= s.SmbusDeviceAddress; + + DEBUG ((DEBUG_INFO, "SmbusDirectedArp() End\n")); + + return EFI_SUCCESS; +} + +/** + 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 + ) +{ + for (SlaveAddress->SmbusDeviceAddress =3D 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 =3D 0; Index < Private->DeviceMapEntries; Index++) { + if (SlaveAddress.SmbusDeviceAddress =3D=3D Private->DeviceMap[Index].S= mbusDeviceAddress.SmbusDeviceAddress) { + return FALSE; + } + } + // + // See if this address is claimed by a platform non-ARP-capable device + // + for (Index =3D 0; Index < Private->PlatformNumRsvd; Index++) { + if ((SlaveAddress.SmbusDeviceAddress << 1) =3D=3D Private->PlatformRsv= dAddr[Index]) { + return FALSE; + } + } + // + // See if this is a reserved address + // + for (Index =3D 0; Index < SMBUS_NUM_RESERVED; Index++) { + if ((SlaveAddress.SmbusDeviceAddress << 1) =3D=3D (UINTN) mReservedAdd= ress[Index]) { + return FALSE; + } + } + + return TRUE; +} diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbu= sDxe.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbusD= xe.inf new file mode 100644 index 000000000..ef083d09b --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbusDxe.inf @@ -0,0 +1,63 @@ +## @file +# SMBus driver. +# +# Copyright (c) 2018, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may b= e found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D ScSmbusDxe + FILE_GUID =3D E052D8A6-224A-4c32-8D37-2E0AE162364D + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InitializeScSmbus + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC + +[Sources] + PchSmbusEntry.c + PchSmbus.h + PchSmbusArp.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonSiPkg/BroxtonSiPrivate.dec + +[LibraryClasses] + UefiDriverEntryPoint + IoLib + BaseLib + DebugLib + TimerLib + UefiBootServicesTableLib + ScPlatformLib + UefiLib + HobLib + BaseMemoryLib + ScSmbusCommonLib + ConfigBlockLib + +[Protocols] + gEfiSmbusHcProtocolGuid ## PRODUCES + +[Guids] + gEfiSmbusArpMapGuid ## UNDEFINED + gEfiHobListGuid ## UNDEFINED + gScPolicyHobGuid ## UNDEFINED + gSmbusConfigGuid + +[Depex] + TRUE \ No newline at end of file diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbu= sEntry.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbusE= ntry.c new file mode 100644 index 000000000..6ae16f343 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Smbus/Dxe/PchSmbusEntry.c @@ -0,0 +1,155 @@ +/** @file + PCH SMBus Driver. + + Copyright (c) 2018, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ +#include "PchSmbus.h" +#include + +extern EFI_GUID gEfiSmbusArpMapGuid; + +/** + Execute an SMBus operation + + @param[in] This The protocol instance + @param[in] SlaveAddress The address of the SMBUS slave device + @param[in] Command The SMBUS command + @param[in] Operation Which SMBus protocol will be issued + @param[in] PecCheck If Packet Error Code Checking is to be u= sed + @param[in, out] Length Length of data + @param[in, out] Buffer Data buffer + + @retval EFI_SUCCESS The SMBUS operation is successful + @retval Others Something error occurred +**/ +EFI_STATUS +EFIAPI +SmbusExecute ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN EFI_SMBUS_OPERATION Operation, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + DEBUG ((DEBUG_INFO, "SmbusExecute() Start, SmbusDeviceAddress=3D%x, Comm= and=3D%x, Operation=3D%x\n", (SlaveAddress.SmbusDeviceAddress << 1), Comman= d, Operation)); + InitializeSmbusRegisters (); + + return SmbusExec ( + SlaveAddress, + Command, + Operation, + PecCheck, + Length, + Buffer + ); +} + +/** + SMBus DXE Module Entry Point\n + - Introduction\n + The SMBus module is a DXE driver that provides a standard way to execu= te an SMBus command. + + - @pre + - @link SC_POLICY SC_POLICY_HOB @endlink + - This module uses the parameters in SmbusConfig for platform reserv= ed (non ARP capable) addresses. + + - @result + The SMBus driver produces EFI_SMBUS_HC_PROTOCOL which is documented in= the SMBus Host Controller + Protocol Specification. + + @param[in] ImageHandle ImageHandle of this module + @param[in] SystemTable EFI System Table + + @retval EFI_SUCCESS Driver initializes successfully + @retval Others Some error occurred +**/ +EFI_STATUS +EFIAPI +InitializeScSmbus ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + SC_POLICY_HOB *ScPolicy; + EFI_STATUS Status; + UINTN DataSize; + VOID *Data; + EFI_PEI_HOB_POINTERS HobList; + SC_SMBUS_CONFIG *SmbusConfig; + + DEBUG ((DEBUG_INFO, "InitializeScSmbus() Start\n")); + + HobList.Guid =3D GetFirstGuidHob (&gScPolicyHobGuid); + ASSERT (HobList.Guid !=3D NULL); + ScPolicy =3D GET_GUID_HOB_DATA (HobList.Guid); + Status =3D GetConfigBlock ((VOID *) ScPolicy, &gSmbusConfigGuid, (VOID= *) &SmbusConfig); + ASSERT_EFI_ERROR (Status); + + mSmbusContext =3D AllocateZeroPool (sizeof (SMBUS_INSTANCE)); + if (mSmbusContext =3D=3D NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + mSmbusContext->Signature =3D PCH_SMBUS_PRIVATE_DATA_SIG= NATURE; + mSmbusContext->IoDone =3D IoDone; + mSmbusContext->SmbusIoRead =3D SmbusIoRead; + mSmbusContext->SmbusIoWrite =3D SmbusIoWrite; + mSmbusContext->SmbusController.Execute =3D SmbusExecute; + mSmbusContext->SmbusController.ArpDevice =3D SmbusArpDevice; + mSmbusContext->SmbusController.GetArpMap =3D SmbusGetArpMap; + mSmbusContext->SmbusController.Notify =3D SmbusNotify; + mSmbusContext->PlatformNumRsvd =3D SmbusConfig->NumRsvdSmbusA= ddresses; + mSmbusContext->PlatformRsvdAddr =3D SmbusConfig->RsvdSmbusAddr= essTable; + ASSERT (mSmbusContext->PlatformNumRsvd <=3D SC_MAX_SMBUS_RESERVED_ADDRES= S); + + // + // See if PEI already ARPed any devices, and if so, update our device ma= p. + // + // Get Hob list + // + Status =3D EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &= HobList.Raw); + ASSERT_EFI_ERROR (Status); + + HobList.Raw =3D GetNextGuidHob (&gEfiSmbusArpMapGuid, HobList.Raw); + // + // If we found the right hob, store the information. Otherwise, continue. + // + if (HobList.Raw !=3D NULL) { + Data =3D (VOID *) ((UINT8 *) (&HobList.Guid->Name) + sizeof (EFI_= GUID)); + DataSize =3D HobList.Header->HobLength - sizeof (EFI_HOB_GUID_TYPE); + CopyMem (mSmbusContext->DeviceMap, Data, DataSize); + mSmbusContext->DeviceMapEntries =3D (UINT8) (DataSize / sizeof (EFI_SM= BUS_DEVICE_MAP)); + } + // + // Initialize the NotifyFunctionList + // + InitializeListHead (&mSmbusContext->NotifyFunctionList); + + // + // Install the SMBus interface + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mSmbusContext->Handle, + &gEfiSmbusHcProtocolGuid, + &mSmbusContext->SmbusController, + NULL + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "InitializeScSmbus() End\n")); + + return EFI_SUCCESS; +} --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel