From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com []) by mx.groups.io with SMTP id smtpd.web08.27712.1612143430402429223 for ; Sun, 31 Jan 2021 17:37:33 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: heng.luo@intel.com) IronPort-SDR: FJzBjGgyoQ6m9B2Vm6Du0zALw8S9+uWJkB1it394Fe1Kr/RA83RHgdyU/uQcsbNXZbIO8PSu5W gr4Oyj1/eFYQ== X-IronPort-AV: E=McAfee;i="6000,8403,9881"; a="177113921" X-IronPort-AV: E=Sophos;i="5.79,391,1602572400"; d="scan'208";a="177113921" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Jan 2021 17:37:26 -0800 IronPort-SDR: V824MAnJtdmLymy4PiBw+nwYqaXCdxGHooAR/uHbOYQdsiKoOJSHqmW9JSYgoXMrppD8GyqQ9d R4L76lJsmOHg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,391,1602572400"; d="scan'208";a="368718640" Received: from hengluo-dev.ccr.corp.intel.com ([10.239.153.154]) by fmsmga008.fm.intel.com with ESMTP; 31 Jan 2021 17:37:25 -0800 From: "Heng Luo" To: devel@edk2.groups.io Cc: Sai Chaganty , Nate DeSimone Subject: [PATCH 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component Date: Mon, 1 Feb 2021 09:36:32 +0800 Message-Id: <20210201013657.1833-15-heng.luo@intel.com> X-Mailer: git-send-email 2.24.0.windows.2 In-Reply-To: <20210201013657.1833-1-heng.luo@intel.com> References: <20210201013657.1833-1-heng.luo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3171 Adds the following files: * IpBlock/Espi/Library Cc: Sai Chaganty Cc: Nate DeSimone Signed-off-by: Heng Luo --- Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/Es= piLib.c | 469 ++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/Pe= iDxeSmmEspiLib.inf | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 507 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeS= mmEspiLib/EspiLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Librar= y/PeiDxeSmmEspiLib/EspiLib.c new file mode 100644 index 0000000000..2d1928ce18 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiL= ib/EspiLib.c @@ -0,0 +1,469 @@ +/** @file=0D + This file contains routines for eSPI=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#define CHANNEL_RESET_TIMEOUT 100 ///< Channel reset timeout in us a= fter which to report error=0D +#define SLAVE_CHANNELS_MAX 7 ///< Max number of channels=0D +=0D +//=0D +// eSPI Slave registers=0D +//=0D +#define R_ESPI_SLAVE_GENCAP 0x08 ///< General Capabilit= ies and Configurations=0D +#define B_ESPI_SLAVE_GENCAP_SUPPCHAN 0xFF ///< Channels supporte= d bit mask=0D +#define R_ESPI_SLAVE_CHACAP_BASE 0x10 ///< Base address from= which channel Cap and Conf registers start on slave=0D +#define S_ESPI_SLAVE_CHACAP_OFFSET 0x10 ///< Offset for each c= hannel from base=0D +#define B_ESPI_SLAVE_CHACAP_CHEN BIT0 ///< Slave Channel ena= ble bit=0D +#define B_ESPI_SLAVE_CHACAP_CHRDY BIT1 ///< Slave Channel rea= dy bit=0D +=0D +/**=0D + Checks if second slave capability is enabled=0D +=0D + @retval TRUE There's second slave=0D + @retval FALSE There's no second slave=0D +**/=0D +BOOLEAN=0D +IsEspiSecondSlaveSupported (=0D + VOID=0D + )=0D +{=0D + return FALSE;=0D +}=0D +=0D +/**=0D + Checks in slave General Capabilities register if it supports channel wit= h requested number=0D +=0D + @param[in] SlaveId Id of slave to check=0D + @param[in] ChannelNumber Number of channel of which to check=0D +=0D + @retval TRUE Channel with requested number is supported by slave de= vice=0D + @retval FALSE Channel with requested number is not supported by slav= e device=0D +**/=0D +BOOLEAN=0D +IsEspiSlaveChannelSupported (=0D + UINT8 SlaveId,=0D + UINT8 ChannelNumber=0D + )=0D +{=0D + UINT32 Data32;=0D + UINT8 SupportedChannels;=0D +=0D + PchEspiSlaveGetConfig (SlaveId, R_ESPI_SLAVE_GENCAP, &Data32);=0D + SupportedChannels =3D (UINT8) (Data32 & B_ESPI_SLAVE_GENCAP_SUPPCHAN);=0D +=0D + DEBUG ((DEBUG_INFO, "Slave %d supported channels 0x%4X\n", SlaveId, Supp= ortedChannels));=0D +=0D + if (ChannelNumber > SLAVE_CHANNELS_MAX || !(SupportedChannels & (BIT0 <<= ChannelNumber))) {=0D + // Incorrect channel number was specified. Either exceeded max or Slav= e doesn't support that channel.=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Is eSPI enabled in strap.=0D +=0D + @retval TRUE Espi is enabled in strap=0D + @retval FALSE Espi is disabled in strap=0D +**/=0D +BOOLEAN=0D +IsEspiEnabled (=0D + VOID=0D + )=0D +{=0D + return (PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_CFG_VAL) & B_ESPI_PCR_CFG_= VAL_ESPI_EN) !=3D 0;=0D +}=0D +=0D +/**=0D + eSPI helper function to clear slave configuration register status=0D +=0D + @retval EFI_SUCCESS Write to private config space succeed=0D + @retval others Read / Write failed=0D +**/=0D +STATIC=0D +VOID=0D +EspiClearScrs (=0D + VOID=0D + )=0D +{=0D + PchPcrAndThenOr32 (=0D + PID_ESPISPI,=0D + R_ESPI_PCR_SLV_CFG_REG_CTL,=0D + (UINT32) ~0,=0D + B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS=0D + );=0D +}=0D +=0D +/**=0D + eSPI helper function to poll slave configuration register enable for 0=0D + and to check for slave configuration register status=0D +=0D + @retval EFI_SUCCESS Enable bit is zero and no error in status bits= =0D + @retval EFI_DEVICE_ERROR Error in SCRS=0D + @retval others Read / Write to private config space failed=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +EspiPollScreAndCheckScrs (=0D + VOID=0D + )=0D +{=0D + UINT32 ScrStat;=0D +=0D + do {=0D + ScrStat =3D PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SLV_CFG_REG_CTL);=0D + } while ((ScrStat & B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE) !=3D 0);=0D +=0D + ScrStat =3D (ScrStat & B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS) >> N_ESPI_PCR_SL= V_CFG_REG_CTL_SCRS;=0D + if (ScrStat !=3D V_ESPI_PCR_SLV_CFG_REG_CTL_SCRS_NOERR) {=0D + DEBUG ((DEBUG_ERROR, "eSPI slave config register status (error) is %x = \n", ScrStat));=0D + return EFI_DEVICE_ERROR;=0D + }=0D + return EFI_SUCCESS;=0D +}=0D +=0D +typedef enum {=0D + EspiSlaveOperationConfigRead,=0D + EspiSlaveOperationConfigWrite,=0D + EspiSlaveOperationStatusRead,=0D + EspiSlaveOperationInBandReset=0D +} ESPI_SLAVE_OPERATION;=0D +=0D +/**=0D + Helper library to do all the operations regards to eSPI slave=0D +=0D + @param[in] SlaveId eSPI Slave ID=0D + @param[in] SlaveAddress Slave address to be put in R_ESPI_PCR_SL= V_CFG_REG_CTL[11:0]=0D + @param[in] SlaveOperation Based on ESPI_SLAVE_OPERATION=0D + @param[in,out] Data=0D +=0D + @retval EFI_SUCCESS Operation succeed=0D + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is = used in PCH_LP=0D + @retval EFI_INVALID_PARAMETER Slave configuration register address excee= d maximum allowed=0D + @retval EFI_INVALID_PARAMETER Slave configuration register address is no= t DWord aligned=0D + @retval EFI_ACCESS_DENIED eSPI Slave write to address range 0 to 0x7= FF has been locked=0D + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of oper= ation=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +EspiSlaveOperationHelper (=0D + IN UINT32 SlaveId,=0D + IN UINT32 SlaveAddress,=0D + IN ESPI_SLAVE_OPERATION SlaveOperation,=0D + IN OUT UINT32 *Data=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 Data32;=0D +=0D + //=0D + // Check the SlaveId is 0 or 1=0D + //=0D + if (SlaveId >=3D PCH_MAX_ESPI_SLAVES) {=0D + DEBUG ((DEBUG_ERROR, "eSPI Slave ID of %d or more is not accepted \n",= PCH_MAX_ESPI_SLAVES));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + //=0D + // Check if SlaveId 1 is used, it is not a PCH_LP=0D + //=0D + if (SlaveId =3D=3D 1) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + //=0D + // Check the address is not more then 0xFFF=0D + //=0D + if (SlaveAddress > B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA) {=0D + DEBUG ((DEBUG_ERROR, "eSPI Slave address must be less than 0x%x \n", (= B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA + 1)));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + //=0D + // Check the address is DWord aligned=0D + //=0D + if ((SlaveAddress & 0x3) !=3D 0) {=0D + DEBUG ((DEBUG_ERROR, "eSPI Slave address must be DWord aligned \n"));= =0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Check if write is allowed=0D + //=0D + if ((SlaveOperation =3D=3D EspiSlaveOperationConfigWrite) &&=0D + (SlaveAddress <=3D 0x7FF)) {=0D +=0D + //=0D + // If the SLCRR is not set in corresponding slave, we will check the l= ock bit=0D + //=0D + Data32 =3D PchPcrRead32 (PID_ESPISPI, (UINT16) (R_ESPI_PCR_LNKERR_SLV0= + (SlaveId * S_ESPI_PCR_LNKERR_SLV0)));=0D + if ((Data32 & B_ESPI_PCR_LNKERR_SLV0_SLCRR) =3D=3D 0) {=0D +=0D + Data32 =3D PchPcrRead32 (PID_ESPISPI, (UINT16) R_ESPI_PCR_SLV_CFG_RE= G_CTL);=0D + if ((Data32 & B_ESPI_PCR_SLV_CFG_REG_CTL_SBLCL) !=3D 0) {=0D + DEBUG ((DEBUG_ERROR, "eSPI Slave write to address range 0 to 0x7FF= has been locked \n"));=0D + return EFI_ACCESS_DENIED;=0D + }=0D + }=0D + }=0D +=0D + //=0D + // Input check done, now go through all the processes=0D + //=0D + EspiClearScrs ();=0D +=0D + if (SlaveOperation =3D=3D EspiSlaveOperationConfigWrite) {=0D + PchPcrWrite32 (=0D + PID_ESPISPI,=0D + (UINT16) R_ESPI_PCR_SLV_CFG_REG_DATA,=0D + *Data=0D + );=0D + }=0D +=0D + PchPcrAndThenOr32 (=0D + PID_ESPISPI,=0D + (UINT16) R_ESPI_PCR_SLV_CFG_REG_CTL,=0D + (UINT32) ~(B_ESPI_PCR_SLV_CFG_REG_CTL_SID | B_ESPI_PCR_SLV_CFG_REG_CTL= _SCRT | B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA),=0D + (B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE |=0D + (SlaveId << N_ESPI_PCR_SLV_CFG_REG_CTL_SID) |=0D + (((UINT32) SlaveOperation) << N_ESPI_PCR_SLV_CFG_REG_CTL_SCRT) |=0D + SlaveAddress=0D + )=0D + );=0D +=0D + Status =3D EspiPollScreAndCheckScrs ();=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + if ((SlaveOperation =3D=3D EspiSlaveOperationConfigRead) || (SlaveOperat= ion =3D=3D EspiSlaveOperationStatusRead)) {=0D + Data32 =3D PchPcrRead32 (=0D + PID_ESPISPI,=0D + (UINT16) R_ESPI_PCR_SLV_CFG_REG_DATA=0D + );=0D + if (SlaveOperation =3D=3D EspiSlaveOperationStatusRead) {=0D + *Data =3D Data32 & 0xFFFF;=0D + } else {=0D + *Data =3D Data32;=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Get configuration from eSPI slave=0D +=0D + @param[in] SlaveId eSPI slave ID=0D + @param[in] SlaveAddress Slave Configuration Register Address=0D + @param[out] OutData Configuration data read=0D +=0D + @retval EFI_SUCCESS Operation succeed=0D + @retval EFI_INVALID_PARAMETER Slave ID is not supported=0D + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is = used in PCH_LP=0D + @retval EFI_INVALID_PARAMETER Slave configuration register address excee= d maximum allowed=0D + @retval EFI_INVALID_PARAMETER Slave configuration register address is no= t DWord aligned=0D + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of oper= ation=0D +**/=0D +EFI_STATUS=0D +PchEspiSlaveGetConfig (=0D + IN UINT32 SlaveId,=0D + IN UINT32 SlaveAddress,=0D + OUT UINT32 *OutData=0D + )=0D +{=0D + //=0D + // 1. Clear status from previous transaction by writing 111b to status i= n SCRS, PCR[eSPI] + 4000h [30:28]=0D + // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit [2= 0:19]=3D, Bit [17:16] =3D 00b, Bit[11:0] =3D .=0D + // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0=0D + // 4. Check the transaction status in SCRS (bits [30:28])=0D + // 5. Read SLV_CFG_REG_DATA.=0D + //=0D + return EspiSlaveOperationHelper (SlaveId, SlaveAddress, EspiSlaveOperati= onConfigRead, OutData);=0D +}=0D +=0D +/**=0D + Set eSPI slave configuration=0D +=0D + Note: A Set_Configuration must always be followed by a Get_Configuration= in order to ensure=0D + that the internal state of the eSPI-MC is consistent with the Slave's re= gister settings.=0D +=0D + @param[in] SlaveId eSPI slave ID=0D + @param[in] SlaveAddress Slave Configuration Register Address=0D + @param[in] InData Configuration data to write=0D +=0D + @retval EFI_SUCCESS Operation succeed=0D + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is = used in PCH_LP=0D + @retval EFI_INVALID_PARAMETER Slave configuration register address excee= d maximum allowed=0D + @retval EFI_INVALID_PARAMETER Slave configuration register address is no= t DWord aligned=0D + @retval EFI_ACCESS_DENIED eSPI Slave write to address range 0 to 0x7= FF has been locked=0D + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of oper= ation=0D +**/=0D +EFI_STATUS=0D +PchEspiSlaveSetConfig (=0D + IN UINT32 SlaveId,=0D + IN UINT32 SlaveAddress,=0D + IN UINT32 InData=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 Data32;=0D +=0D + //=0D + // 1. Clear status from previous transaction by writing 111b to status i= n SCRS, PCR[eSPI] + 4000h [30:28]=0D + // 2. Program SLV_CFG_REG_DATA with the write value.=0D + // 3. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit [2= 0:19]=3D, Bit [17:16] =3D 01b, Bit[11:0] =3D .=0D + // 4. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0=0D + // 5. Check the transaction status in SCRS (bits [30:28])=0D + //=0D + Status =3D EspiSlaveOperationHelper (SlaveId, SlaveAddress, EspiSlaveOpe= rationConfigWrite, &InData);=0D + PchEspiSlaveGetConfig (SlaveId, SlaveAddress, &Data32);=0D + return Status;=0D +}=0D +=0D +/**=0D + Get status from eSPI slave=0D +=0D + @param[in] SlaveId eSPI slave ID=0D + @param[out] OutData Configuration data read=0D +=0D + @retval EFI_SUCCESS Operation succeed=0D + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is = used in PCH_LP=0D + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of oper= ation=0D +**/=0D +EFI_STATUS=0D +PchEspiSlaveGetStatus (=0D + IN UINT32 SlaveId,=0D + OUT UINT16 *OutData=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 TempOutData;=0D +=0D + TempOutData =3D 0;=0D +=0D + //=0D + // 1. Clear status from previous transaction by writing 111b to status i= n SCRS, PCR[eSPI] + 4000h [30:28]=0D + // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit [2= 0:19]=3D, Bit [17:16] =3D 10b, Bit[11:0] =3D .=0D + // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0=0D + // 4. Check the transaction status in SCRS (bits [30:28])=0D + // 5. Read SLV_CFG_REG_DATA [15:0].=0D + //=0D + Status =3D EspiSlaveOperationHelper (SlaveId, 0, EspiSlaveOperationStatu= sRead, &TempOutData);=0D + *OutData =3D (UINT16) TempOutData;=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + eSPI slave in-band reset=0D +=0D + @param[in] SlaveId eSPI slave ID=0D +=0D + @retval EFI_SUCCESS Operation succeed=0D + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is = used in PCH_LP=0D + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of oper= ation=0D +**/=0D +EFI_STATUS=0D +PchEspiSlaveInBandReset (=0D + IN UINT32 SlaveId=0D + )=0D +{=0D + //=0D + // 1. Clear status from previous transaction by writing 111b to status i= n SCRS, PCR[eSPI] + 4000h [30:28]=0D + // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit [2= 0:19]=3D, Bit [17:16] =3D 11b).=0D + // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0=0D + // 4. Check the transaction status in SCRS (bits [30:28])=0D + //=0D + return EspiSlaveOperationHelper (SlaveId, 0, EspiSlaveOperationInBandRes= et, NULL);=0D +}=0D +=0D +/**=0D + eSPI Slave channel reset helper function=0D +=0D + @param[in] SlaveId eSPI slave ID=0D + @param[in] ChannelNumber Number of channel to reset=0D +=0D + @retval EFI_SUCCESS Operation succeeded=0D + @retval EFI_UNSUPPORTED Slave doesn't support that channel or inva= lid number specified=0D + @retval EFI_TIMEOUT Operation has timeouted=0D +**/=0D +EFI_STATUS=0D +PchEspiSlaveChannelReset (=0D + IN UINT8 SlaveId,=0D + IN UINT8 ChannelNumber=0D + )=0D +{=0D + UINT8 Timeout;=0D + UINT32 Data32;=0D + UINT32 SlaveChannelAddress;=0D + BOOLEAN SlaveBmeSet;=0D +=0D + DEBUG ((DEBUG_INFO, "eSPI slave %d channel %d reset\n", SlaveId, Channel= Number));=0D +=0D + Timeout =3D CHANNEL_RESET_TIMEOUT;=0D + SlaveBmeSet =3D FALSE;=0D +=0D + if (!IsEspiSlaveChannelSupported (SlaveId, ChannelNumber)) {=0D + // Incorrect channel number was specified. Either exceeded max or Slav= e doesn't support that channel.=0D + DEBUG ((DEBUG_ERROR, "Channel %d is not valid channel number for slave= %d!\n", ChannelNumber, SlaveId));=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + // Calculating slave channel address=0D + SlaveChannelAddress =3D R_ESPI_SLAVE_CHACAP_BASE + (S_ESPI_SLAVE_CHACAP_= OFFSET * ChannelNumber);=0D +=0D + // If we're resetting Peripheral Channel then we need to disable Bus Mas= tering first and reenable after reset=0D + if (ChannelNumber =3D=3D 0) {=0D + PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);=0D + if ((Data32 & B_ESPI_SLAVE_BME) !=3D 0) {=0D + Data32 &=3D ~(B_ESPI_SLAVE_BME);=0D + PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);=0D + SlaveBmeSet =3D TRUE;=0D + }=0D + }=0D +=0D + // Disable channel=0D + PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);=0D + Data32 &=3D ~(B_ESPI_SLAVE_CHACAP_CHEN);=0D + PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);=0D +=0D + // Enable channel=0D + PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);=0D + Data32 |=3D B_ESPI_SLAVE_CHACAP_CHEN;=0D + PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);=0D +=0D + DEBUG ((DEBUG_INFO, "Waiting for Channel Ready bit\n"));=0D + // Wait until channel is ready by polling Channel Ready bit=0D + while (((Data32 & B_ESPI_SLAVE_CHACAP_CHRDY) =3D=3D 0) && (Timeout > 0))= {=0D + PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);=0D + MicroSecondDelay (1);=0D + --Timeout;=0D + }=0D +=0D + if (Timeout =3D=3D 0) {=0D + // The waiting for channel to be ready has timed out=0D + DEBUG ((DEBUG_ERROR, "The operation of channel %d reset for slave %d h= as timed out!\n", ChannelNumber, SlaveId));=0D + return EFI_TIMEOUT;=0D + }=0D +=0D + if (ChannelNumber =3D=3D 0 && SlaveBmeSet) {=0D + PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);=0D + Data32 |=3D B_ESPI_SLAVE_BME;=0D + PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeS= mmEspiLib/PeiDxeSmmEspiLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/= Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf new file mode 100644 index 0000000000..440051432f --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiL= ib/PeiDxeSmmEspiLib.inf @@ -0,0 +1,38 @@ +## @file=0D +# Component description file for the PeiDxeSmmPchEspiLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D PeiDxeSmmEspiLib=0D +FILE_GUID =3D 7F25F990-7989-4413-B414-1EDE557E9389=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D EspiLib=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D +#=0D +=0D +=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +PchPcrLib=0D +TimerLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +=0D +[Sources]=0D +EspiLib.c=0D --=20 2.24.0.windows.2