From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web09.27638.1612143460154346141 for ; Sun, 31 Jan 2021 17:37:40 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: heng.luo@intel.com) IronPort-SDR: 4CcLcYBvPnLuKSAyof+myIYpJMgGPzQmiWOZiGKp/NftzVukTV2KwEFqMWsoELfo5OXHGDlTrq /caM4CMRecNQ== X-IronPort-AV: E=McAfee;i="6000,8403,9881"; a="177113982" X-IronPort-AV: E=Sophos;i="5.79,391,1602572400"; d="scan'208";a="177113982" 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:34 -0800 IronPort-SDR: VjxuNUTnJVYNJiZlNTc50OcgOF3It72BzXi1OIEV0NhHNGL7JuBvCMJqgEw6X3QQ5JHvSY+CaU uqsIHXLun2BA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,391,1602572400"; d="scan'208";a="368718692" Received: from hengluo-dev.ccr.corp.intel.com ([10.239.153.154]) by fmsmga008.fm.intel.com with ESMTP; 31 Jan 2021 17:37:33 -0800 From: "Heng Luo" To: devel@edk2.groups.io Cc: Sai Chaganty , Nate DeSimone Subject: [PATCH 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component Date: Mon, 1 Feb 2021 09:36:38 +0800 Message-Id: <20210201013657.1833-21-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/P2sb/IncludePrivate * IpBlock/P2sb/Library * IpBlock/P2sb/LibraryPrivate Cc: Sai Chaganty Cc: Nate DeSimone Signed-off-by: Heng Luo --- Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchS= biAccessLib.h | 112 +++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2s= bRegs.h | 65 +++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarA= ccessLib/CpuRegbarAccessLib.c | 494 +++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarA= ccessLib/PeiDxeSmmCpuRegbarAccessLib.inf | 35 +++++++++++++++++++++++++++= ++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/= PchPcrLib.c | 313 +++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/= PeiDxeSmmPchPcrLib.inf | 35 +++++++++++++++++++++++++++= ++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPch= SbiAccessLib/PchSbiAccessLib.c | 253 +++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPch= SbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf | 36 +++++++++++++++++++++++++++= +++++++++ 8 files changed, 1343 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/= Library/PchSbiAccessLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/= IncludePrivate/Library/PchSbiAccessLib.h new file mode 100644 index 0000000000..3fab933bbd --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library= /PchSbiAccessLib.h @@ -0,0 +1,112 @@ +/** @file=0D + Header file for PchSbiAccessLib.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _PCH_SBI_ACCESS_LIB_H_=0D +#define _PCH_SBI_ACCESS_LIB_H_=0D +=0D +#include =0D +=0D +/**=0D + PCH SBI opcode definitions=0D +**/=0D +typedef enum {=0D + MemoryRead =3D 0x0,=0D + MemoryWrite =3D 0x1,=0D + PciConfigRead =3D 0x4,=0D + PciConfigWrite =3D 0x5,=0D + PrivateControlRead =3D 0x6,=0D + PrivateControlWrite =3D 0x7,=0D + GpioLockUnlock =3D 0x13=0D +} PCH_SBI_OPCODE;=0D +=0D +/**=0D + PCH SBI response status definitions=0D +**/=0D +typedef enum {=0D + SBI_SUCCESSFUL =3D 0,=0D + SBI_UNSUCCESSFUL =3D 1,=0D + SBI_POWERDOWN =3D 2,=0D + SBI_MIXED =3D 3,=0D + SBI_INVALID_RESPONSE=0D +} PCH_SBI_RESPONSE;=0D +=0D +/**=0D + Execute PCH SBI message=0D + Take care of that there is no lock protection when using SBI programming= in both POST time and SMI.=0D + It will clash with POST time SBI programming when SMI happen.=0D + Programmer MUST do the save and restore opration while using the PchSbiE= xecution inside SMI=0D + to prevent from racing condition.=0D + This function will reveal P2SB and hide P2SB if it's originally hidden. = If more than one SBI access=0D + needed, it's better to unhide the P2SB before calling and hide it back a= fter done.=0D +=0D + When the return value is "EFI_SUCCESS", the "Response" do not need to be= checked as it would have been=0D + SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would = provide additional information=0D + when needed.=0D +=0D + @param[in] Pid Port ID of the SBI message=0D + @param[in] Offset Offset of the SBI message=0D + @param[in] Opcode Opcode=0D + @param[in] Posted Posted message=0D + @param[in, out] Data32 Read/Write data=0D + @param[out] Response Response=0D +=0D + @retval EFI_SUCCESS Successfully completed.=0D + @retval EFI_DEVICE_ERROR Transaction fail=0D + @retval EFI_INVALID_PARAMETER Invalid parameter=0D + @retval EFI_TIMEOUT Timeout while waiting for response= =0D +**/=0D +EFI_STATUS=0D +PchSbiExecution (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT64 Offset,=0D + IN PCH_SBI_OPCODE Opcode,=0D + IN BOOLEAN Posted,=0D + IN OUT UINT32 *Data32,=0D + OUT UINT8 *Response=0D + );=0D +=0D +/**=0D + Full function for executing PCH SBI message=0D + Take care of that there is no lock protection when using SBI programming= in both POST time and SMI.=0D + It will clash with POST time SBI programming when SMI happen.=0D + Programmer MUST do the save and restore opration while using the PchSbiE= xecution inside SMI=0D + to prevent from racing condition.=0D + This function will reveal P2SB and hide P2SB if it's originally hidden. = If more than one SBI access=0D + needed, it's better to unhide the P2SB before calling and hide it back a= fter done.=0D +=0D + When the return value is "EFI_SUCCESS", the "Response" do not need to be= checked as it would have been=0D + SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would = provide additional information=0D + when needed.=0D +=0D + @param[in] Pid Port ID of the SBI message=0D + @param[in] Offset Offset of the SBI message=0D + @param[in] Opcode Opcode=0D + @param[in] Posted Posted message=0D + @param[in] Fbe First byte enable=0D + @param[in] Bar Bar=0D + @param[in] Fid Function ID=0D + @param[in, out] Data32 Read/Write data=0D + @param[out] Response Response=0D +=0D + @retval EFI_SUCCESS Successfully completed.=0D + @retval EFI_DEVICE_ERROR Transaction fail=0D + @retval EFI_INVALID_PARAMETER Invalid parameter=0D + @retval EFI_TIMEOUT Timeout while waiting for response= =0D +**/=0D +EFI_STATUS=0D +PchSbiExecutionEx (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT64 Offset,=0D + IN PCH_SBI_OPCODE Opcode,=0D + IN BOOLEAN Posted,=0D + IN UINT16 Fbe,=0D + IN UINT16 Bar,=0D + IN UINT16 Fid,=0D + IN OUT UINT32 *Data32,=0D + OUT UINT8 *Response=0D + );=0D +=0D +#endif // _PCH_SBI_ACCESS_LIB_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/= Register/P2sbRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Includ= ePrivate/Register/P2sbRegs.h new file mode 100644 index 0000000000..44c71af719 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Registe= r/P2sbRegs.h @@ -0,0 +1,65 @@ +/** @file=0D + Register names for PCH P2SB device=0D +=0D + Conventions:=0D +=0D + - Register definition format:=0D + Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_Re= gisterName=0D + - Prefix:=0D + Definitions beginning with "R_" are registers=0D + Definitions beginning with "B_" are bits within registers=0D + Definitions beginning with "V_" are meaningful values within the bits= =0D + Definitions beginning with "S_" are register size=0D + Definitions beginning with "N_" are the bit position=0D + - [GenerationName]:=0D + Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.)= .=0D + Register name without GenerationName applies to all generations.=0D + - [ComponentName]:=0D + This field indicates the component name that the register belongs to (= e.g. PCH, SA etc.)=0D + Register name without ComponentName applies to all components.=0D + Register that is specific to -LP denoted by "_PCH_LP_" in component na= me.=0D + - SubsystemName:=0D + This field indicates the subsystem name of the component that the regi= ster belongs to=0D + (e.g. PCIE, USB, SATA, GPIO, PMC etc.).=0D + - RegisterSpace:=0D + MEM - MMIO space register of subsystem.=0D + IO - IO space register of subsystem.=0D + PCR - Private configuration register of subsystem.=0D + CFG - PCI configuration space register of subsystem.=0D + - RegisterName:=0D + Full register name.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _P2SB_REGS_H_=0D +#define _P2SB_REGS_H_=0D +=0D +//=0D +// PCI to P2SB Bridge Registers=0D +//=0D +=0D +#define R_IO_APIC_MEM_INDEX_OFFSET 0x00=0D +#define R_IO_APIC_MEM_DATA_OFFSET 0x10=0D +#define V_P2SB_CFG_IBDF_BUS 0=0D +#define V_P2SB_CFG_IBDF_DEV 30=0D +#define V_P2SB_CFG_IBDF_FUNC 7=0D +#define V_P2SB_CFG_HBDF_BUS 0=0D +#define V_P2SB_CFG_HBDF_DEV 30=0D +#define V_P2SB_CFG_HBDF_FUNC 6=0D +=0D +//=0D +// Definition for SBI=0D +//=0D +#define R_P2SB_CFG_SBIADDR 0xD0=0D +#define R_P2SB_CFG_SBIDATA 0xD4=0D +#define R_P2SB_CFG_SBISTAT 0xD8=0D +#define B_P2SB_CFG_SBISTAT_OPCODE 0xFF00=0D +#define B_P2SB_CFG_SBISTAT_POSTED BIT7=0D +#define B_P2SB_CFG_SBISTAT_RESPONSE 0x0006=0D +#define N_P2SB_CFG_SBISTAT_RESPONSE 1=0D +#define B_P2SB_CFG_SBISTAT_INITRDY BIT0=0D +#define R_P2SB_CFG_SBIRID 0xDA=0D +#define R_P2SB_CFG_SBIEXTADDR 0xDC=0D +=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeS= mmCpuRegbarAccessLib/CpuRegbarAccessLib.c b/Silicon/Intel/TigerlakeSiliconP= kg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c new file mode 100644 index 0000000000..9d8851ac37 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRe= gbarAccessLib/CpuRegbarAccessLib.c @@ -0,0 +1,494 @@ +/** @file=0D + CPU REGBAR ACCESS library.=0D + All function in this library is available for PEI, DXE, and SMM,=0D + But do not support UEFI RUNTIME environment call.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Definition for REGBAR address=0D + The REGBAR address is used for the CPU IP's SB register access=0D +**/=0D +#define CPU_REGBAR_ADDRESS(Pid, Offset) (PcdGet32(PcdRegBarBaseAddress)= | ((UINT8)(Pid) << 16) | (UINT16)(Offset))=0D +=0D +/**=0D + Read REGBAR register.=0D + It returns REGBAR register and size in 8bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT64 REGBAR register value.=0D +**/=0D +UINT64=0D +CpuRegbarRead64 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset=0D + )=0D +{=0D + UINT8 Pid;=0D +=0D + Pid =3D CpuSbDevicePid;=0D + if (Pid !=3D INVALID_PID)=0D + return ((UINT64) MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset)) + LShif= tU64 ((UINT64) MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset+4)), 32));=0D + else=0D + return INVALID_DATA_64;=0D +}=0D +=0D +=0D +/**=0D + Read REGBAR register.=0D + It returns REGBAR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT32 REGBAR register value.=0D +**/=0D +UINT32=0D +CpuRegbarRead32 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset=0D + )=0D +{=0D + UINT8 Pid;=0D +=0D + Pid =3D CpuSbDevicePid;=0D + if (Pid !=3D INVALID_PID)=0D + return MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset));=0D + else=0D + return INVALID_DATA_32;=0D +}=0D +=0D +/**=0D + Read REGBAR register.=0D + It returns REGBAR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT16 REGBAR register value.=0D +**/=0D +UINT16=0D +CpuRegbarRead16 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset=0D + )=0D +{=0D + UINT16 DwOffset;=0D + UINT32 Data32;=0D + UINT16 Data16;=0D +=0D + Data16 =3D 0;=0D + Data32 =3D 0;=0D + DwOffset =3D 0;=0D +=0D + if (CpuSbDevicePid =3D=3D INVALID_PID) {=0D + return INVALID_DATA_16;=0D + }=0D + switch (Offset & 0x0003) {=0D + case 0:=0D + DwOffset =3D Offset;=0D + break;=0D + case 2:=0D + DwOffset =3D Offset - 0x2;=0D + break;=0D + }=0D + Data32 =3D MmioRead32 (CPU_REGBAR_ADDRESS (CpuSbDevicePid, DwOffset));=0D + switch (Offset & 0x0003) {=0D + case 0:=0D + Data16 =3D (UINT16) Data32;=0D + break;=0D + case 2:=0D + Data16 =3D (UINT16) (Data32 >> 16);=0D + break;=0D + }=0D + return Data16;=0D +}=0D +=0D +/**=0D + Read REGBAR register.=0D + It returns REGBAR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT8 REGBAR regsiter value=0D +**/=0D +UINT8=0D +CpuRegbarRead8 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset=0D + )=0D +{=0D + UINT16 DwOffset;=0D + UINT32 Data32;=0D + UINT8 Data8;=0D +=0D + DwOffset =3D 0;=0D + Data32 =3D 0;=0D + Data8 =3D 0;=0D +=0D + if (CpuSbDevicePid =3D=3D INVALID_PID)=0D + return INVALID_DATA_8;=0D + switch (Offset & 0x0003) {=0D + case 0:=0D + DwOffset =3D Offset;=0D + break;=0D + case 1:=0D + DwOffset =3D Offset - 0x1;=0D + break;=0D + case 2:=0D + DwOffset =3D Offset - 0x2;=0D + break;=0D + case 3:=0D + DwOffset =3D Offset - 0x3;=0D + break;=0D + }=0D + Data32 =3D MmioRead32 (CPU_REGBAR_ADDRESS (CpuSbDevicePid, DwOffset));=0D + switch (Offset & 0x0003) {=0D + case 0:=0D + Data8 =3D (UINT8) Data32;=0D + break;=0D + case 1:=0D + Data8 =3D (UINT8) (Data32 >> 8);=0D + break;=0D + case 2:=0D + Data8 =3D (UINT8) (Data32 >> 16);=0D + break;=0D + case 3:=0D + Data8 =3D (UINT8) (Data32 >> 24);=0D + break;=0D + }=0D + return Data8;=0D +}=0D +=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 8bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size p= arameter.=0D +=0D + @retval UINT64 Value written to register=0D +**/=0D +UINT64=0D +CpuRegbarWrite64 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT64 Data=0D + )=0D +{=0D + UINT8 Pid;=0D +=0D + Pid =3D CpuSbDevicePid;=0D + if (Pid !=3D INVALID_PID) {=0D + MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset) + 4, (UINT32) RShiftU64 = (Data, 32));=0D + MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset), (UINT32) Data);=0D + return Data;=0D + }=0D + else=0D + return INVALID_DATA_64;=0D +}=0D +=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size p= arameter.=0D +=0D + @retval UINT32 Value written to register=0D +**/=0D +UINT32=0D +CpuRegbarWrite32 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT32 Data=0D + )=0D +{=0D + UINT8 Pid;=0D +=0D + Pid =3D CpuSbDevicePid;=0D + if (Pid !=3D INVALID_PID)=0D + return MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);=0D + else=0D + return INVALID_DATA_32;=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size p= arameter.=0D +=0D + @retval UINT16 Value written to register=0D +**/=0D +UINT16=0D +CpuRegbarWrite16 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT16 Data=0D + )=0D +{=0D + UINT8 Pid;=0D +=0D + Pid =3D CpuSbDevicePid;=0D + if (Pid !=3D INVALID_PID)=0D + return MmioWrite16 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);=0D + else=0D + return INVALID_DATA_16;=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size p= arameter.=0D +=0D + @retval UINT8 Value written to register=0D +**/=0D +UINT8=0D +CpuRegbarWrite8 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT8 Data=0D + )=0D +{=0D + UINT8 Pid;=0D +=0D + Pid =3D CpuSbDevicePid;=0D + if (Pid !=3D INVALID_PID)=0D + return MmioWrite8 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);=0D + else=0D + return INVALID_DATA_8;=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] OrData OR Data. Must be the same size as Size para= meter.=0D +=0D + @retval UINT32 Value written to register=0D +=0D +**/=0D +UINT32=0D +CpuRegbarOr32 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return CpuRegbarWrite32 (CpuSbDevicePid, Offset, CpuRegbarRead32(CpuSbDe= vicePid, Offset) | OrData);=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] OrData OR Data. Must be the same size as Size para= meter.=0D +=0D + @retval UINT16 Value written to register=0D +=0D +**/=0D +UINT16=0D +CpuRegbarOr16 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return CpuRegbarWrite16 (CpuSbDevicePid, Offset, CpuRegbarRead16(CpuSbDe= vicePid, Offset) | OrData);=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] OrData OR Data. Must be the same size as Size para= meter.=0D +=0D + @retval UINT8 Value written to register=0D +=0D +**/=0D +UINT8=0D +CpuRegbarOr8(=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8(CpuSbDevi= cePid, Offset) | OrData);=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of a 32-bit data.=0D + It programs REGBAR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevice CPU SB Device=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData And Data. Must be the same size as Size par= ameter.=0D +=0D + @retval UINT32 Value written to register=0D +=0D +**/=0D +UINT32=0D +CpuRegbarAnd32 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT32 AndData=0D + )=0D +{=0D + return CpuRegbarWrite32 (CpuSbDevicePid, Offset, CpuRegbarRead32 (CpuSbD= evicePid, Offset) & AndData);=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of a 16-bit data.=0D + It programs REGBAR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevice CPU SB Device=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData And Data. Must be the same size as Size par= ameter.=0D +=0D + @retval UINT16 Value written to register=0D +=0D +**/=0D +UINT16=0D +CpuRegbarAnd16 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT16 AndData=0D + )=0D +{=0D + return CpuRegbarWrite16 (CpuSbDevicePid, Offset, CpuRegbarRead16 (CpuSbD= evicePid, Offset) & AndData);=0D +}=0D +=0D +/**=0D +Performs a bitwise AND of a 8-bit data.=0D +It programs REGBAR register and size in 1byte.=0D +The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D +@param[in] CpuSbDevice CPU SB Device=0D +@param[in] Offset Register offset of Port ID.=0D +@param[in] AndData And Data. Must be the same size as Size param= eter.=0D +=0D +@retval UINT8 Value written to register=0D +=0D +**/=0D +UINT8=0D +CpuRegbarAnd8 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT8 AndData=0D + )=0D +{=0D + return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8 (CpuSbDev= icePid, Offset) & AndData);=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size par= ameter.=0D + @param[in] OrData OR Data. Must be the same size as Size para= meter.=0D +=0D + @retval UINT32 Value written to register=0D +=0D +**/=0D +UINT32=0D +CpuRegbarAndThenOr32 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT32 AndData,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return CpuRegbarWrite32 (CpuSbDevicePid, Offset, (CpuRegbarRead32 (CpuSb= DevicePid, Offset) & AndData) | OrData);=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size par= ameter.=0D + @param[in] OrData OR Data. Must be the same size as Size para= meter.=0D +=0D + @retval UINT16 Value written to register=0D +=0D +**/=0D +UINT16=0D +CpuRegbarAndThenOr16 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT16 AndData,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return CpuRegbarWrite16 (CpuSbDevicePid, Offset, (CpuRegbarRead16 (CpuSb= DevicePid, Offset) & AndData) | OrData);=0D +}=0D +=0D +/**=0D + Write REGBAR register.=0D + It programs REGBAR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] CpuSbDevicePid CPU SB Device Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size par= ameter.=0D + @param[in] OrData OR Data. Must be the same size as Size para= meter.=0D +=0D + @retval UINT8 Value written to register=0D +=0D +**/=0D +UINT8=0D +CpuRegbarAndThenOr8 (=0D + IN CPU_SB_DEVICE_PID CpuSbDevicePid,=0D + IN UINT16 Offset,=0D + IN UINT8 AndData,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return CpuRegbarWrite8 (CpuSbDevicePid, Offset, (CpuRegbarRead8 (CpuSbDe= vicePid, Offset) & AndData) | OrData);=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeS= mmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf b/Silicon/Intel/Tigerl= akeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpu= RegbarAccessLib.inf new file mode 100644 index 0000000000..596543f34f --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRe= gbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf @@ -0,0 +1,35 @@ +## @file=0D +# CPU REGBAR ACCESS Library.=0D +#=0D +# All function in this library is available for PEI, DXE, and SMM,=0D +# But do not support UEFI RUNTIME environment call.=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 PeiDxeSmmCpuRegbarAccessLib=0D +FILE_GUID =3D CA92B911-528D-4FBB-9A5A-7BC22AA1A6D0=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D CpuRegbarAccessLib=0D +=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Pcd]=0D +gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress=0D +=0D +[Sources]=0D +CpuRegbarAccessLib.c=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeS= mmPchPcrLib/PchPcrLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Li= brary/PeiDxeSmmPchPcrLib/PchPcrLib.c new file mode 100644 index 0000000000..c4f3740c86 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPc= rLib/PchPcrLib.c @@ -0,0 +1,313 @@ +/** @file=0D + PCH PCR library.=0D + All function in this library is available for PEI, DXE, and SMM,=0D + But do not support UEFI RUNTIME environment call.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#ifndef MDEPKG_NDEBUG=0D +/**=0D + Checks if the offset is valid for a given memory access width. Offset mu= st align to width size.=0D +=0D + @param[in] Offset Offset of a register=0D + @param[in] Size Size of memory access in bytes=0D +=0D + @retval FALSE Offset is not valid for a given memory access=0D + @retval TRUE Offset is valid=0D +**/=0D +STATIC=0D +BOOLEAN=0D +PchIsPcrOffsetValid (=0D + IN UINT32 Offset,=0D + IN UINTN Size=0D + )=0D +{=0D + if (!IsP2sb20bPcrSupported ()) {=0D + if (((Offset & (Size - 1)) !=3D 0) || (Offset > 0xFFFF)) {=0D + DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x"= , Offset, Size));=0D + return FALSE;=0D + } else {=0D + return TRUE;=0D + }=0D + } else {=0D + if (((Offset & (Size - 1)) !=3D 0) || (Offset > 0xFFFFF)) {=0D + DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x"= , Offset, Size));=0D + return FALSE;=0D + } else {=0D + return TRUE;=0D + }=0D + }=0D +}=0D +#endif=0D +=0D +/**=0D + Read PCR register.=0D + It returns PCR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT32 PCR register value.=0D +**/=0D +UINT32=0D +PchPcrRead32 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset=0D + )=0D +{=0D +#ifndef MDEPKG_NDEBUG=0D + ASSERT (PchIsPcrOffsetValid (Offset, 4));=0D +#endif=0D + return MmioRead32 (PCH_PCR_ADDRESS (Pid, Offset));=0D +}=0D +=0D +/**=0D + Read PCR register.=0D + It returns PCR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT16 PCR register value.=0D +**/=0D +UINT16=0D +PchPcrRead16 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset=0D + )=0D +{=0D +#ifndef MDEPKG_NDEBUG=0D + ASSERT (PchIsPcrOffsetValid (Offset, 2));=0D +#endif=0D + return MmioRead16 (PCH_PCR_ADDRESS (Pid, Offset));=0D +}=0D +=0D +/**=0D + Read PCR register.=0D + It returns PCR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of this Port ID=0D +=0D + @retval UINT8 PCR register value=0D +**/=0D +UINT8=0D +PchPcrRead8 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset=0D + )=0D +{=0D + return MmioRead8 (PCH_PCR_ADDRESS (Pid, Offset));=0D +}=0D +=0D +/**=0D + Write PCR register.=0D + It programs PCR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size parameter= .=0D +=0D + @retval UINT32 Value written to register=0D +**/=0D +UINT32=0D +PchPcrWrite32 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT32 Data=0D + )=0D +{=0D +#ifndef MDEPKG_NDEBUG=0D + ASSERT (PchIsPcrOffsetValid (Offset, 4));=0D +#endif=0D + MmioWrite32 (PCH_PCR_ADDRESS (Pid, Offset), Data);=0D +=0D + return Data;=0D +=0D +}=0D +=0D +/**=0D + Write PCR register.=0D + It programs PCR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size parameter= .=0D +=0D + @retval UINT16 Value written to register=0D +**/=0D +UINT16=0D +PchPcrWrite16 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT16 Data=0D + )=0D +{=0D +#ifndef MDEPKG_NDEBUG=0D + ASSERT (PchIsPcrOffsetValid (Offset, 2));=0D +#endif=0D + MmioWrite16 (PCH_PCR_ADDRESS (Pid, Offset), Data);=0D +=0D + return Data;=0D +}=0D +=0D +/**=0D + Write PCR register.=0D + It programs PCR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] Data Input Data. Must be the same size as Size parameter= .=0D +=0D + @retval UINT8 Value written to register=0D +**/=0D +UINT8=0D +PchPcrWrite8 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT8 Data=0D + )=0D +{=0D +=0D + MmioWrite8 (PCH_PCR_ADDRESS (Pid, Offset), Data);=0D +=0D + return Data;=0D +}=0D +=0D +/**=0D + Write PCR register.=0D + It programs PCR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size parameter.= =0D + @param[in] OrData OR Data. Must be the same size as Size parameter.=0D +=0D + @retval UINT32 Value written to register=0D +=0D +**/=0D +UINT32=0D +PchPcrAndThenOr32 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT32 AndData,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData= ) | OrData);=0D +}=0D +=0D +/**=0D + Write PCR register and read back.=0D + The read back ensures the PCR cycle is completed before next operation.= =0D + It programs PCR register and size in 4bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size parameter.= =0D + @param[in] OrData OR Data. Must be the same size as Size parameter.=0D +=0D + @retval UINT32 Value read back from the register=0D +**/=0D +UINT32=0D +PchPcrAndThenOr32WithReadback (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT32 AndData,=0D + IN UINT32 OrData=0D + )=0D +{=0D + PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData) | OrD= ata);=0D + return PchPcrRead32 (Pid, Offset);=0D +}=0D +=0D +/**=0D + Write PCR register.=0D + It programs PCR register and size in 2bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size parameter.= =0D + @param[in] OrData OR Data. Must be the same size as Size parameter.=0D +=0D + @retval UINT16 Value written to register=0D +=0D +**/=0D +UINT16=0D +PchPcrAndThenOr16 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT16 AndData,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return PchPcrWrite16 (Pid, Offset, (PchPcrRead16 (Pid, Offset) & AndData= ) | OrData);=0D +}=0D +=0D +/**=0D + Write PCR register.=0D + It programs PCR register and size in 1bytes.=0D + The Offset should not exceed 0xFFFF and must be aligned with size.=0D +=0D + @param[in] Pid Port ID=0D + @param[in] Offset Register offset of Port ID.=0D + @param[in] AndData AND Data. Must be the same size as Size parameter.= =0D + @param[in] OrData OR Data. Must be the same size as Size parameter.=0D +=0D + @retval UINT8 Value written to register=0D +=0D +**/=0D +UINT8=0D +PchPcrAndThenOr8 (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT32 Offset,=0D + IN UINT8 AndData,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return PchPcrWrite8 (Pid, Offset, (PchPcrRead8 (Pid, Offset) & AndData) = | OrData);=0D +}=0D +=0D +/**=0D + Get PCH IP PID number=0D +=0D + @param[in] IpEnum PCH IP in PCH_IP_PID_ENUM=0D +=0D + @retval 0 PID of this IP is not supported=0D + !0 PID of the IP.=0D +**/=0D +PCH_SBI_PID=0D +PchPcrGetPid (=0D + PCH_IP_PID_ENUM IpEnum=0D + )=0D +{=0D + switch (IpEnum) {=0D + case PchIpDmi:=0D + return PID_DMI;=0D + case PchIpIclk:=0D + return PID_ICLK;=0D + default:=0D + ASSERT (FALSE);=0D + return PCH_INVALID_PID;=0D + }=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeS= mmPchPcrLib/PeiDxeSmmPchPcrLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBl= ock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf new file mode 100644 index 0000000000..2efeba374f --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPc= rLib/PeiDxeSmmPchPcrLib.inf @@ -0,0 +1,35 @@ +## @file=0D +# PCH PCR Library.=0D +#=0D +# All function in this library is available for PEI, DXE, and SMM,=0D +# But do not support UEFI RUNTIME environment call.=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 PeiDxeSmmPchPcrLib=0D +FILE_GUID =3D 117C8D19-445B-46BF-B624-109F63709375=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D PchPcrLib=0D +=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +PchInfoLib=0D +=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +=0D +[Sources]=0D +PchPcrLib.c=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/= PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c b/Silicon/Intel/TigerlakeSilicon= Pkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c new file mode 100644 index 0000000000..8017dee3aa --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeS= mmPchSbiAccessLib/PchSbiAccessLib.c @@ -0,0 +1,253 @@ +/** @file=0D + PCH SBI access library.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Execute PCH SBI message=0D + Take care of that there is no lock protection when using SBI programming= in both POST time and SMI.=0D + It will clash with POST time SBI programming when SMI happen.=0D + Programmer MUST do the save and restore opration while using the PchSbiE= xecution inside SMI=0D + to prevent from racing condition.=0D + This function will reveal P2SB and hide P2SB if it's originally hidden. = If more than one SBI access=0D + needed, it's better to unhide the P2SB before calling and hide it back a= fter done.=0D +=0D + When the return value is "EFI_SUCCESS", the "Response" do not need to be= checked as it would have been=0D + SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would = provide additional information=0D + when needed.=0D +=0D + @param[in] Pid Port ID of the SBI message=0D + @param[in] Offset Offset of the SBI message=0D + @param[in] Opcode Opcode=0D + @param[in] Posted Posted message=0D + @param[in, out] Data32 Read/Write data=0D + @param[out] Response Response=0D +=0D + @retval EFI_SUCCESS Successfully completed.=0D + @retval EFI_DEVICE_ERROR Transaction fail=0D + @retval EFI_INVALID_PARAMETER Invalid parameter=0D + @retval EFI_TIMEOUT Timeout while waiting for response= =0D +**/=0D +EFI_STATUS=0D +PchSbiExecution (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT64 Offset,=0D + IN PCH_SBI_OPCODE Opcode,=0D + IN BOOLEAN Posted,=0D + IN OUT UINT32 *Data32,=0D + OUT UINT8 *Response=0D + )=0D +{=0D + return PchSbiExecutionEx ( Pid,=0D + Offset,=0D + Opcode,=0D + Posted,=0D + 0x000F,=0D + 0x0000,=0D + 0x0000,=0D + Data32,=0D + Response=0D + );=0D +}=0D +=0D +/**=0D + Full function for executing PCH SBI message=0D + Take care of that there is no lock protection when using SBI programming= in both POST time and SMI.=0D + It will clash with POST time SBI programming when SMI happen.=0D + Programmer MUST do the save and restore opration while using the PchSbiE= xecution inside SMI=0D + to prevent from racing condition.=0D + This function will reveal P2SB and hide P2SB if it's originally hidden. = If more than one SBI access=0D + needed, it's better to unhide the P2SB before calling and hide it back a= fter done.=0D +=0D + When the return value is "EFI_SUCCESS", the "Response" do not need to be= checked as it would have been=0D + SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would = provide additional information=0D + when needed.=0D +=0D + @param[in] Pid Port ID of the SBI message=0D + @param[in] Offset Offset of the SBI message=0D + @param[in] Opcode Opcode=0D + @param[in] Posted Posted message=0D + @param[in] Fbe First byte enable=0D + @param[in] Bar Bar=0D + @param[in] Fid Function ID=0D + @param[in, out] Data32 Read/Write data=0D + @param[out] Response Response=0D +=0D + @retval EFI_SUCCESS Successfully completed.=0D + @retval EFI_DEVICE_ERROR Transaction fail=0D + @retval EFI_INVALID_PARAMETER Invalid parameter=0D + @retval EFI_TIMEOUT Timeout while waiting for response= =0D +**/=0D +EFI_STATUS=0D +PchSbiExecutionEx (=0D + IN PCH_SBI_PID Pid,=0D + IN UINT64 Offset,=0D + IN PCH_SBI_OPCODE Opcode,=0D + IN BOOLEAN Posted,=0D + IN UINT16 Fbe,=0D + IN UINT16 Bar,=0D + IN UINT16 Fid,=0D + IN OUT UINT32 *Data32,=0D + OUT UINT8 *Response=0D + )=0D +{=0D + UINT64 P2sbBase;=0D + UINTN Timeout;=0D + UINT16 SbiStat;=0D +=0D + //=0D + // Check opcode valid=0D + //=0D + switch (Opcode) {=0D + case MemoryRead:=0D + case MemoryWrite:=0D + case PciConfigRead:=0D + case PciConfigWrite:=0D + case PrivateControlRead:=0D + case PrivateControlWrite:=0D + case GpioLockUnlock:=0D + break;=0D + default:=0D + return EFI_INVALID_PARAMETER;=0D + break;=0D + }=0D +=0D + P2sbBase =3D P2sbPciCfgBase ();=0D + if (PciSegmentRead16 (P2sbBase + PCI_VENDOR_ID_OFFSET) =3D=3D 0xFFFF) {= =0D + ASSERT (FALSE);=0D + return EFI_DEVICE_ERROR;=0D + }=0D + ///=0D + /// BWG Section 2.2.1=0D + /// 1. Poll P2SB PCI offset D8h[0] =3D 0b=0D + /// Make sure the previous opeartion is completed.=0D + ///=0D + Timeout =3D 0xFFFFFFF;=0D + while (Timeout > 0) {=0D + SbiStat =3D PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT);=0D + if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) =3D=3D 0) {=0D + break;=0D + }=0D + Timeout--;=0D + }=0D + if (Timeout =3D=3D 0) {=0D + return EFI_TIMEOUT;=0D + }=0D + //=0D + // Initial Response status=0D + //=0D + *Response =3D SBI_INVALID_RESPONSE;=0D + SbiStat =3D 0;=0D + ///=0D + /// 2. Write P2SB PCI offset D0h[31:0] with Address and Destination Port= ID=0D + ///=0D + PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIADDR, (UINT32) ((Pid << 24) = | (UINT16) Offset));=0D + ///=0D + /// 3. Write P2SB PCI offset DCh[31:0] with extended address, which is e= xpected to be 0 in CNL PCH.=0D + ///=0D + PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIEXTADDR, (UINT32) RShiftU64 = (Offset, 16));=0D + ///=0D + /// 5. Set P2SB PCI offset D8h[15:8] =3D 00000110b for read=0D + /// Set P2SB PCI offset D8h[15:8] =3D 00000111b for write=0D + //=0D + // Set SBISTAT[15:8] to the opcode passed in=0D + // Set SBISTAT[7] to the posted passed in=0D + //=0D + PciSegmentAndThenOr16 (=0D + (P2sbBase + R_P2SB_CFG_SBISTAT),=0D + (UINT16) ~(B_P2SB_CFG_SBISTAT_OPCODE | B_P2SB_CFG_SBISTAT_POSTED),=0D + (UINT16) ((Opcode << 8) | (Posted << 7))=0D + );=0D + ///=0D + /// 6. Write P2SB PCI offset DAh[15:0] =3D F000h=0D + ///=0D + //=0D + // Set RID[15:0] =3D Fbe << 12 | Bar << 8 | Fid=0D + //=0D + PciSegmentWrite16 (=0D + (P2sbBase + R_P2SB_CFG_SBIRID),=0D + (((Fbe & 0x000F) << 12) | ((Bar & 0x0007) << 8) | (Fid & 0x00FF))=0D + );=0D +=0D + switch (Opcode) {=0D + case MemoryWrite:=0D + case PciConfigWrite:=0D + case PrivateControlWrite:=0D + case GpioLockUnlock:=0D + ///=0D + /// 4. Write P2SB PCI offset D4h[31:0] with the intended data accord= ingly=0D + ///=0D + PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), *Data32);=0D + break;=0D + default:=0D + ///=0D + /// 4. Write P2SB PCI offset D4h[31:0] with dummy data such as 0,=0D + /// because all D0-DFh register range must be touched in CNL PCH=0D + /// for a successful SBI transaction.=0D + ///=0D + PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), 0);=0D + break;=0D + }=0D + ///=0D + /// 7. Set P2SB PCI offset D8h[0] =3D 1b, Poll P2SB PCI offset D8h[0] = =3D 0b=0D + ///=0D + //=0D + // Set SBISTAT[0] =3D 1b, trigger the SBI operation=0D + //=0D + PciSegmentOr16 (P2sbBase + R_P2SB_CFG_SBISTAT, (UINT16) B_P2SB_CFG_SBIST= AT_INITRDY);=0D + //=0D + // Poll SBISTAT[0] =3D 0b, Polling for Busy bit=0D + //=0D + Timeout =3D 0xFFFFFFF;=0D + while (Timeout > 0) {=0D + SbiStat =3D PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT);=0D + if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) =3D=3D 0) {=0D + break;=0D + }=0D + Timeout--;=0D + }=0D + if (Timeout =3D=3D 0) {=0D + //=0D + // If timeout, it's fatal error.=0D + //=0D + return EFI_TIMEOUT;=0D + } else {=0D + ///=0D + /// 8. Check if P2SB PCI offset D8h[2:1] =3D 00b for successful transa= ction=0D + ///=0D + *Response =3D (UINT8) ((SbiStat & B_P2SB_CFG_SBISTAT_RESPONSE) >> N_P2= SB_CFG_SBISTAT_RESPONSE);=0D + if (*Response =3D=3D SBI_SUCCESSFUL) {=0D + switch (Opcode) {=0D + case MemoryRead:=0D + case PciConfigRead:=0D + case PrivateControlRead:=0D + ///=0D + /// 9. Read P2SB PCI offset D4h[31:0] for SBI data=0D + ///=0D + *Data32 =3D PciSegmentRead32 (P2sbBase + R_P2SB_CFG_SBIDATA);=0D + break;=0D + default:=0D + break;=0D + }=0D + return EFI_SUCCESS;=0D + } else if (*Response =3D=3D SBI_POWERDOWN) {=0D + return EFI_NO_RESPONSE;=0D + } else {=0D + return EFI_DEVICE_ERROR;=0D + }=0D + }=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/= PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf b/Silicon/Intel/Tiger= lakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeS= mmPchSbiAccessLib.inf new file mode 100644 index 0000000000..4199a0a6c7 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeS= mmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf @@ -0,0 +1,36 @@ +## @file=0D +# PCH SBI access library.=0D +#=0D +# All function in this library is available for PEI, DXE, and SMM,=0D +# But do not support UEFI RUNTIME environment call.=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 PeiDxeSmmPchSbiAccessLib=0D +FILE_GUID =3D 96ECB0FB-A975-4DC8-B88A-D90C3378CE87=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D PchSbiAccessLib=0D +=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +PciSegmentLib=0D +PchPciBdfLib=0D +=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +=0D +[Sources]=0D +PchSbiAccessLib.c=0D --=20 2.24.0.windows.2