From: "Heng Luo" <heng.luo@intel.com>
To: devel@edk2.groups.io
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>,
Nate DeSimone <nathaniel.l.desimone@intel.com>
Subject: [Patch V3 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component
Date: Fri, 5 Feb 2021 15:40:26 +0800 [thread overview]
Message-ID: <20210205074045.3916-21-heng.luo@intel.com> (raw)
In-Reply-To: <20210205074045.3916-1-heng.luo@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
Adds the following files:
* IpBlock/P2sb/IncludePrivate
* IpBlock/P2sb/Library
* IpBlock/P2sb/LibraryPrivate
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchSbiAccessLib.h | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c | 494 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/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/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/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
+ Header file for PchSbiAccessLib.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SBI_ACCESS_LIB_H_
+#define _PCH_SBI_ACCESS_LIB_H_
+
+#include <Library/PchPcrLib.h>
+
+/**
+ PCH SBI opcode definitions
+**/
+typedef enum {
+ MemoryRead = 0x0,
+ MemoryWrite = 0x1,
+ PciConfigRead = 0x4,
+ PciConfigWrite = 0x5,
+ PrivateControlRead = 0x6,
+ PrivateControlWrite = 0x7,
+ GpioLockUnlock = 0x13
+} PCH_SBI_OPCODE;
+
+/**
+ PCH SBI response status definitions
+**/
+typedef enum {
+ SBI_SUCCESSFUL = 0,
+ SBI_UNSUCCESSFUL = 1,
+ SBI_POWERDOWN = 2,
+ SBI_MIXED = 3,
+ SBI_INVALID_RESPONSE
+} PCH_SBI_RESPONSE;
+
+/**
+ Execute PCH SBI message
+ Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+ It will clash with POST time SBI programming when SMI happen.
+ Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+ to prevent from racing condition.
+ This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+ needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+ When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+ SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+ when needed.
+
+ @param[in] Pid Port ID of the SBI message
+ @param[in] Offset Offset of the SBI message
+ @param[in] Opcode Opcode
+ @param[in] Posted Posted message
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_TIMEOUT Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecution (
+ IN PCH_SBI_PID Pid,
+ IN UINT64 Offset,
+ IN PCH_SBI_OPCODE Opcode,
+ IN BOOLEAN Posted,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ );
+
+/**
+ Full function for executing PCH SBI message
+ Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+ It will clash with POST time SBI programming when SMI happen.
+ Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+ to prevent from racing condition.
+ This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+ needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+ When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+ SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+ when needed.
+
+ @param[in] Pid Port ID of the SBI message
+ @param[in] Offset Offset of the SBI message
+ @param[in] Opcode Opcode
+ @param[in] Posted Posted message
+ @param[in] Fbe First byte enable
+ @param[in] Bar Bar
+ @param[in] Fid Function ID
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_TIMEOUT Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecutionEx (
+ IN PCH_SBI_PID Pid,
+ IN UINT64 Offset,
+ IN PCH_SBI_OPCODE Opcode,
+ IN BOOLEAN Posted,
+ IN UINT16 Fbe,
+ IN UINT16 Bar,
+ IN UINT16 Fid,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ );
+
+#endif // _PCH_SBI_ACCESS_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h
new file mode 100644
index 0000000000..44c71af719
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h
@@ -0,0 +1,65 @@
+/** @file
+ Register names for PCH P2SB device
+
+ Conventions:
+
+ - Register definition format:
+ Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+ - Prefix:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values within the bits
+ Definitions beginning with "S_" are register size
+ Definitions beginning with "N_" are the bit position
+ - [GenerationName]:
+ Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+ Register name without GenerationName applies to all generations.
+ - [ComponentName]:
+ This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+ Register name without ComponentName applies to all components.
+ Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+ - SubsystemName:
+ This field indicates the subsystem name of the component that the register belongs to
+ (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+ - RegisterSpace:
+ MEM - MMIO space register of subsystem.
+ IO - IO space register of subsystem.
+ PCR - Private configuration register of subsystem.
+ CFG - PCI configuration space register of subsystem.
+ - RegisterName:
+ Full register name.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _P2SB_REGS_H_
+#define _P2SB_REGS_H_
+
+//
+// PCI to P2SB Bridge Registers
+//
+
+#define R_IO_APIC_MEM_INDEX_OFFSET 0x00
+#define R_IO_APIC_MEM_DATA_OFFSET 0x10
+#define V_P2SB_CFG_IBDF_BUS 0
+#define V_P2SB_CFG_IBDF_DEV 30
+#define V_P2SB_CFG_IBDF_FUNC 7
+#define V_P2SB_CFG_HBDF_BUS 0
+#define V_P2SB_CFG_HBDF_DEV 30
+#define V_P2SB_CFG_HBDF_FUNC 6
+
+//
+// Definition for SBI
+//
+#define R_P2SB_CFG_SBIADDR 0xD0
+#define R_P2SB_CFG_SBIDATA 0xD4
+#define R_P2SB_CFG_SBISTAT 0xD8
+#define B_P2SB_CFG_SBISTAT_OPCODE 0xFF00
+#define B_P2SB_CFG_SBISTAT_POSTED BIT7
+#define B_P2SB_CFG_SBISTAT_RESPONSE 0x0006
+#define N_P2SB_CFG_SBISTAT_RESPONSE 1
+#define B_P2SB_CFG_SBISTAT_INITRDY BIT0
+#define R_P2SB_CFG_SBIRID 0xDA
+#define R_P2SB_CFG_SBIEXTADDR 0xDC
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c
new file mode 100644
index 0000000000..9d8851ac37
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c
@@ -0,0 +1,494 @@
+/** @file
+ CPU REGBAR ACCESS library.
+ All function in this library is available for PEI, DXE, and SMM,
+ But do not support UEFI RUNTIME environment call.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuRegbarAccessLib.h>
+
+/**
+ Definition for REGBAR address
+ The REGBAR address is used for the CPU IP's SB register access
+**/
+#define CPU_REGBAR_ADDRESS(Pid, Offset) (PcdGet32(PcdRegBarBaseAddress) | ((UINT8)(Pid) << 16) | (UINT16)(Offset))
+
+/**
+ Read REGBAR register.
+ It returns REGBAR register and size in 8bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT64 REGBAR register value.
+**/
+UINT64
+CpuRegbarRead64 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset
+ )
+{
+ UINT8 Pid;
+
+ Pid = CpuSbDevicePid;
+ if (Pid != INVALID_PID)
+ return ((UINT64) MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset)) + LShiftU64 ((UINT64) MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset+4)), 32));
+ else
+ return INVALID_DATA_64;
+}
+
+
+/**
+ Read REGBAR register.
+ It returns REGBAR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT32 REGBAR register value.
+**/
+UINT32
+CpuRegbarRead32 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset
+ )
+{
+ UINT8 Pid;
+
+ Pid = CpuSbDevicePid;
+ if (Pid != INVALID_PID)
+ return MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset));
+ else
+ return INVALID_DATA_32;
+}
+
+/**
+ Read REGBAR register.
+ It returns REGBAR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT16 REGBAR register value.
+**/
+UINT16
+CpuRegbarRead16 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset
+ )
+{
+ UINT16 DwOffset;
+ UINT32 Data32;
+ UINT16 Data16;
+
+ Data16 = 0;
+ Data32 = 0;
+ DwOffset = 0;
+
+ if (CpuSbDevicePid == INVALID_PID) {
+ return INVALID_DATA_16;
+ }
+ switch (Offset & 0x0003) {
+ case 0:
+ DwOffset = Offset;
+ break;
+ case 2:
+ DwOffset = Offset - 0x2;
+ break;
+ }
+ Data32 = MmioRead32 (CPU_REGBAR_ADDRESS (CpuSbDevicePid, DwOffset));
+ switch (Offset & 0x0003) {
+ case 0:
+ Data16 = (UINT16) Data32;
+ break;
+ case 2:
+ Data16 = (UINT16) (Data32 >> 16);
+ break;
+ }
+ return Data16;
+}
+
+/**
+ Read REGBAR register.
+ It returns REGBAR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT8 REGBAR regsiter value
+**/
+UINT8
+CpuRegbarRead8 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset
+ )
+{
+ UINT16 DwOffset;
+ UINT32 Data32;
+ UINT8 Data8;
+
+ DwOffset = 0;
+ Data32 = 0;
+ Data8 = 0;
+
+ if (CpuSbDevicePid == INVALID_PID)
+ return INVALID_DATA_8;
+ switch (Offset & 0x0003) {
+ case 0:
+ DwOffset = Offset;
+ break;
+ case 1:
+ DwOffset = Offset - 0x1;
+ break;
+ case 2:
+ DwOffset = Offset - 0x2;
+ break;
+ case 3:
+ DwOffset = Offset - 0x3;
+ break;
+ }
+ Data32 = MmioRead32 (CPU_REGBAR_ADDRESS (CpuSbDevicePid, DwOffset));
+ switch (Offset & 0x0003) {
+ case 0:
+ Data8 = (UINT8) Data32;
+ break;
+ case 1:
+ Data8 = (UINT8) (Data32 >> 8);
+ break;
+ case 2:
+ Data8 = (UINT8) (Data32 >> 16);
+ break;
+ case 3:
+ Data8 = (UINT8) (Data32 >> 24);
+ break;
+ }
+ return Data8;
+}
+
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 8bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT64 Value written to register
+**/
+UINT64
+CpuRegbarWrite64 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT64 Data
+ )
+{
+ UINT8 Pid;
+
+ Pid = CpuSbDevicePid;
+ if (Pid != INVALID_PID) {
+ MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset) + 4, (UINT32) RShiftU64 (Data, 32));
+ MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset), (UINT32) Data);
+ return Data;
+ }
+ else
+ return INVALID_DATA_64;
+}
+
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value written to register
+**/
+UINT32
+CpuRegbarWrite32 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT32 Data
+ )
+{
+ UINT8 Pid;
+
+ Pid = CpuSbDevicePid;
+ if (Pid != INVALID_PID)
+ return MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);
+ else
+ return INVALID_DATA_32;
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT16 Value written to register
+**/
+UINT16
+CpuRegbarWrite16 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT16 Data
+ )
+{
+ UINT8 Pid;
+
+ Pid = CpuSbDevicePid;
+ if (Pid != INVALID_PID)
+ return MmioWrite16 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);
+ else
+ return INVALID_DATA_16;
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT8 Value written to register
+**/
+UINT8
+CpuRegbarWrite8 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT8 Data
+ )
+{
+ UINT8 Pid;
+
+ Pid = CpuSbDevicePid;
+ if (Pid != INVALID_PID)
+ return MmioWrite8 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);
+ else
+ return INVALID_DATA_8;
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value written to register
+
+**/
+UINT32
+CpuRegbarOr32 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT32 OrData
+ )
+{
+ return CpuRegbarWrite32 (CpuSbDevicePid, Offset, CpuRegbarRead32(CpuSbDevicePid, Offset) | OrData);
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT16 Value written to register
+
+**/
+UINT16
+CpuRegbarOr16 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT16 OrData
+ )
+{
+ return CpuRegbarWrite16 (CpuSbDevicePid, Offset, CpuRegbarRead16(CpuSbDevicePid, Offset) | OrData);
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT8 Value written to register
+
+**/
+UINT8
+CpuRegbarOr8(
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT8 OrData
+ )
+{
+ return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8(CpuSbDevicePid, Offset) | OrData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit data.
+ It programs REGBAR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevice CPU SB Device
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData And Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value written to register
+
+**/
+UINT32
+CpuRegbarAnd32 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT32 AndData
+ )
+{
+ return CpuRegbarWrite32 (CpuSbDevicePid, Offset, CpuRegbarRead32 (CpuSbDevicePid, Offset) & AndData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit data.
+ It programs REGBAR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevice CPU SB Device
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData And Data. Must be the same size as Size parameter.
+
+ @retval UINT16 Value written to register
+
+**/
+UINT16
+CpuRegbarAnd16 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT16 AndData
+ )
+{
+ return CpuRegbarWrite16 (CpuSbDevicePid, Offset, CpuRegbarRead16 (CpuSbDevicePid, Offset) & AndData);
+}
+
+/**
+Performs a bitwise AND of a 8-bit data.
+It programs REGBAR register and size in 1byte.
+The Offset should not exceed 0xFFFF and must be aligned with size.
+
+@param[in] CpuSbDevice CPU SB Device
+@param[in] Offset Register offset of Port ID.
+@param[in] AndData And Data. Must be the same size as Size parameter.
+
+@retval UINT8 Value written to register
+
+**/
+UINT8
+CpuRegbarAnd8 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT8 AndData
+ )
+{
+ return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8 (CpuSbDevicePid, Offset) & AndData);
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value written to register
+
+**/
+UINT32
+CpuRegbarAndThenOr32 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return CpuRegbarWrite32 (CpuSbDevicePid, Offset, (CpuRegbarRead32 (CpuSbDevicePid, Offset) & AndData) | OrData);
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT16 Value written to register
+
+**/
+UINT16
+CpuRegbarAndThenOr16 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return CpuRegbarWrite16 (CpuSbDevicePid, Offset, (CpuRegbarRead16 (CpuSbDevicePid, Offset) & AndData) | OrData);
+}
+
+/**
+ Write REGBAR register.
+ It programs REGBAR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] CpuSbDevicePid CPU SB Device Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT8 Value written to register
+
+**/
+UINT8
+CpuRegbarAndThenOr8 (
+ IN CPU_SB_DEVICE_PID CpuSbDevicePid,
+ IN UINT16 Offset,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return CpuRegbarWrite8 (CpuSbDevicePid, Offset, (CpuRegbarRead8 (CpuSbDevicePid, Offset) & AndData) | OrData);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
new file mode 100644
index 0000000000..596543f34f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
@@ -0,0 +1,35 @@
+## @file
+# CPU REGBAR ACCESS Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmCpuRegbarAccessLib
+FILE_GUID = CA92B911-528D-4FBB-9A5A-7BC22AA1A6D0
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuRegbarAccessLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress
+
+[Sources]
+CpuRegbarAccessLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
new file mode 100644
index 0000000000..c4f3740c86
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
@@ -0,0 +1,313 @@
+/** @file
+ PCH PCR library.
+ All function in this library is available for PEI, DXE, and SMM,
+ But do not support UEFI RUNTIME environment call.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Register/PchPcrRegs.h>
+
+#ifndef MDEPKG_NDEBUG
+/**
+ Checks if the offset is valid for a given memory access width. Offset must align to width size.
+
+ @param[in] Offset Offset of a register
+ @param[in] Size Size of memory access in bytes
+
+ @retval FALSE Offset is not valid for a given memory access
+ @retval TRUE Offset is valid
+**/
+STATIC
+BOOLEAN
+PchIsPcrOffsetValid (
+ IN UINT32 Offset,
+ IN UINTN Size
+ )
+{
+ if (!IsP2sb20bPcrSupported ()) {
+ if (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFF)) {
+ DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x", Offset, Size));
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ } else {
+ if (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFFF)) {
+ DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x", Offset, Size));
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+}
+#endif
+
+/**
+ Read PCR register.
+ It returns PCR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT32 PCR register value.
+**/
+UINT32
+PchPcrRead32 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset
+ )
+{
+#ifndef MDEPKG_NDEBUG
+ ASSERT (PchIsPcrOffsetValid (Offset, 4));
+#endif
+ return MmioRead32 (PCH_PCR_ADDRESS (Pid, Offset));
+}
+
+/**
+ Read PCR register.
+ It returns PCR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT16 PCR register value.
+**/
+UINT16
+PchPcrRead16 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset
+ )
+{
+#ifndef MDEPKG_NDEBUG
+ ASSERT (PchIsPcrOffsetValid (Offset, 2));
+#endif
+ return MmioRead16 (PCH_PCR_ADDRESS (Pid, Offset));
+}
+
+/**
+ Read PCR register.
+ It returns PCR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of this Port ID
+
+ @retval UINT8 PCR register value
+**/
+UINT8
+PchPcrRead8 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset
+ )
+{
+ return MmioRead8 (PCH_PCR_ADDRESS (Pid, Offset));
+}
+
+/**
+ Write PCR register.
+ It programs PCR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value written to register
+**/
+UINT32
+PchPcrWrite32 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT32 Data
+ )
+{
+#ifndef MDEPKG_NDEBUG
+ ASSERT (PchIsPcrOffsetValid (Offset, 4));
+#endif
+ MmioWrite32 (PCH_PCR_ADDRESS (Pid, Offset), Data);
+
+ return Data;
+
+}
+
+/**
+ Write PCR register.
+ It programs PCR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT16 Value written to register
+**/
+UINT16
+PchPcrWrite16 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT16 Data
+ )
+{
+#ifndef MDEPKG_NDEBUG
+ ASSERT (PchIsPcrOffsetValid (Offset, 2));
+#endif
+ MmioWrite16 (PCH_PCR_ADDRESS (Pid, Offset), Data);
+
+ return Data;
+}
+
+/**
+ Write PCR register.
+ It programs PCR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] Data Input Data. Must be the same size as Size parameter.
+
+ @retval UINT8 Value written to register
+**/
+UINT8
+PchPcrWrite8 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT8 Data
+ )
+{
+
+ MmioWrite8 (PCH_PCR_ADDRESS (Pid, Offset), Data);
+
+ return Data;
+}
+
+/**
+ Write PCR register.
+ It programs PCR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value written to register
+
+**/
+UINT32
+PchPcrAndThenOr32 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData) | OrData);
+}
+
+/**
+ Write PCR register and read back.
+ The read back ensures the PCR cycle is completed before next operation.
+ It programs PCR register and size in 4bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT32 Value read back from the register
+**/
+UINT32
+PchPcrAndThenOr32WithReadback (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData) | OrData);
+ return PchPcrRead32 (Pid, Offset);
+}
+
+/**
+ Write PCR register.
+ It programs PCR register and size in 2bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT16 Value written to register
+
+**/
+UINT16
+PchPcrAndThenOr16 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return PchPcrWrite16 (Pid, Offset, (PchPcrRead16 (Pid, Offset) & AndData) | OrData);
+}
+
+/**
+ Write PCR register.
+ It programs PCR register and size in 1bytes.
+ The Offset should not exceed 0xFFFF and must be aligned with size.
+
+ @param[in] Pid Port ID
+ @param[in] Offset Register offset of Port ID.
+ @param[in] AndData AND Data. Must be the same size as Size parameter.
+ @param[in] OrData OR Data. Must be the same size as Size parameter.
+
+ @retval UINT8 Value written to register
+
+**/
+UINT8
+PchPcrAndThenOr8 (
+ IN PCH_SBI_PID Pid,
+ IN UINT32 Offset,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return PchPcrWrite8 (Pid, Offset, (PchPcrRead8 (Pid, Offset) & AndData) | OrData);
+}
+
+/**
+ Get PCH IP PID number
+
+ @param[in] IpEnum PCH IP in PCH_IP_PID_ENUM
+
+ @retval 0 PID of this IP is not supported
+ !0 PID of the IP.
+**/
+PCH_SBI_PID
+PchPcrGetPid (
+ PCH_IP_PID_ENUM IpEnum
+ )
+{
+ switch (IpEnum) {
+ case PchIpDmi:
+ return PID_DMI;
+ case PchIpIclk:
+ return PID_ICLK;
+ default:
+ ASSERT (FALSE);
+ return PCH_INVALID_PID;
+ }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
new file mode 100644
index 0000000000..2efeba374f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
@@ -0,0 +1,35 @@
+## @file
+# PCH PCR Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPcrLib
+FILE_GUID = 117C8D19-445B-46BF-B624-109F63709375
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPcrLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PchInfoLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcrLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
new file mode 100644
index 0000000000..8017dee3aa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
@@ -0,0 +1,253 @@
+/** @file
+ PCH SBI access library.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Register/PchRegs.h>
+#include <Register/P2sbRegs.h>
+
+/**
+ Execute PCH SBI message
+ Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+ It will clash with POST time SBI programming when SMI happen.
+ Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+ to prevent from racing condition.
+ This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+ needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+ When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+ SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+ when needed.
+
+ @param[in] Pid Port ID of the SBI message
+ @param[in] Offset Offset of the SBI message
+ @param[in] Opcode Opcode
+ @param[in] Posted Posted message
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_TIMEOUT Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecution (
+ IN PCH_SBI_PID Pid,
+ IN UINT64 Offset,
+ IN PCH_SBI_OPCODE Opcode,
+ IN BOOLEAN Posted,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ )
+{
+ return PchSbiExecutionEx ( Pid,
+ Offset,
+ Opcode,
+ Posted,
+ 0x000F,
+ 0x0000,
+ 0x0000,
+ Data32,
+ Response
+ );
+}
+
+/**
+ Full function for executing PCH SBI message
+ Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+ It will clash with POST time SBI programming when SMI happen.
+ Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+ to prevent from racing condition.
+ This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+ needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+ When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+ SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+ when needed.
+
+ @param[in] Pid Port ID of the SBI message
+ @param[in] Offset Offset of the SBI message
+ @param[in] Opcode Opcode
+ @param[in] Posted Posted message
+ @param[in] Fbe First byte enable
+ @param[in] Bar Bar
+ @param[in] Fid Function ID
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_TIMEOUT Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecutionEx (
+ IN PCH_SBI_PID Pid,
+ IN UINT64 Offset,
+ IN PCH_SBI_OPCODE Opcode,
+ IN BOOLEAN Posted,
+ IN UINT16 Fbe,
+ IN UINT16 Bar,
+ IN UINT16 Fid,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ )
+{
+ UINT64 P2sbBase;
+ UINTN Timeout;
+ UINT16 SbiStat;
+
+ //
+ // Check opcode valid
+ //
+ switch (Opcode) {
+ case MemoryRead:
+ case MemoryWrite:
+ case PciConfigRead:
+ case PciConfigWrite:
+ case PrivateControlRead:
+ case PrivateControlWrite:
+ case GpioLockUnlock:
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ P2sbBase = P2sbPciCfgBase ();
+ if (PciSegmentRead16 (P2sbBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ ASSERT (FALSE);
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// BWG Section 2.2.1
+ /// 1. Poll P2SB PCI offset D8h[0] = 0b
+ /// Make sure the previous opeartion is completed.
+ ///
+ Timeout = 0xFFFFFFF;
+ while (Timeout > 0) {
+ SbiStat = PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT);
+ if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) == 0) {
+ break;
+ }
+ Timeout--;
+ }
+ if (Timeout == 0) {
+ return EFI_TIMEOUT;
+ }
+ //
+ // Initial Response status
+ //
+ *Response = SBI_INVALID_RESPONSE;
+ SbiStat = 0;
+ ///
+ /// 2. Write P2SB PCI offset D0h[31:0] with Address and Destination Port ID
+ ///
+ PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIADDR, (UINT32) ((Pid << 24) | (UINT16) Offset));
+ ///
+ /// 3. Write P2SB PCI offset DCh[31:0] with extended address, which is expected to be 0 in CNL PCH.
+ ///
+ PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIEXTADDR, (UINT32) RShiftU64 (Offset, 16));
+ ///
+ /// 5. Set P2SB PCI offset D8h[15:8] = 00000110b for read
+ /// Set P2SB PCI offset D8h[15:8] = 00000111b for write
+ //
+ // Set SBISTAT[15:8] to the opcode passed in
+ // Set SBISTAT[7] to the posted passed in
+ //
+ PciSegmentAndThenOr16 (
+ (P2sbBase + R_P2SB_CFG_SBISTAT),
+ (UINT16) ~(B_P2SB_CFG_SBISTAT_OPCODE | B_P2SB_CFG_SBISTAT_POSTED),
+ (UINT16) ((Opcode << 8) | (Posted << 7))
+ );
+ ///
+ /// 6. Write P2SB PCI offset DAh[15:0] = F000h
+ ///
+ //
+ // Set RID[15:0] = Fbe << 12 | Bar << 8 | Fid
+ //
+ PciSegmentWrite16 (
+ (P2sbBase + R_P2SB_CFG_SBIRID),
+ (((Fbe & 0x000F) << 12) | ((Bar & 0x0007) << 8) | (Fid & 0x00FF))
+ );
+
+ switch (Opcode) {
+ case MemoryWrite:
+ case PciConfigWrite:
+ case PrivateControlWrite:
+ case GpioLockUnlock:
+ ///
+ /// 4. Write P2SB PCI offset D4h[31:0] with the intended data accordingly
+ ///
+ PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), *Data32);
+ break;
+ default:
+ ///
+ /// 4. Write P2SB PCI offset D4h[31:0] with dummy data such as 0,
+ /// because all D0-DFh register range must be touched in CNL PCH
+ /// for a successful SBI transaction.
+ ///
+ PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), 0);
+ break;
+ }
+ ///
+ /// 7. Set P2SB PCI offset D8h[0] = 1b, Poll P2SB PCI offset D8h[0] = 0b
+ ///
+ //
+ // Set SBISTAT[0] = 1b, trigger the SBI operation
+ //
+ PciSegmentOr16 (P2sbBase + R_P2SB_CFG_SBISTAT, (UINT16) B_P2SB_CFG_SBISTAT_INITRDY);
+ //
+ // Poll SBISTAT[0] = 0b, Polling for Busy bit
+ //
+ Timeout = 0xFFFFFFF;
+ while (Timeout > 0) {
+ SbiStat = PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT);
+ if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) == 0) {
+ break;
+ }
+ Timeout--;
+ }
+ if (Timeout == 0) {
+ //
+ // If timeout, it's fatal error.
+ //
+ return EFI_TIMEOUT;
+ } else {
+ ///
+ /// 8. Check if P2SB PCI offset D8h[2:1] = 00b for successful transaction
+ ///
+ *Response = (UINT8) ((SbiStat & B_P2SB_CFG_SBISTAT_RESPONSE) >> N_P2SB_CFG_SBISTAT_RESPONSE);
+ if (*Response == SBI_SUCCESSFUL) {
+ switch (Opcode) {
+ case MemoryRead:
+ case PciConfigRead:
+ case PrivateControlRead:
+ ///
+ /// 9. Read P2SB PCI offset D4h[31:0] for SBI data
+ ///
+ *Data32 = PciSegmentRead32 (P2sbBase + R_P2SB_CFG_SBIDATA);
+ break;
+ default:
+ break;
+ }
+ return EFI_SUCCESS;
+ } else if (*Response == SBI_POWERDOWN) {
+ return EFI_NO_RESPONSE;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
new file mode 100644
index 0000000000..4199a0a6c7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
@@ -0,0 +1,36 @@
+## @file
+# PCH SBI access library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSbiAccessLib
+FILE_GUID = 96ECB0FB-A975-4DC8-B88A-D90C3378CE87
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchSbiAccessLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchPciBdfLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSbiAccessLib.c
--
2.24.0.windows.2
next prev parent reply other threads:[~2021-02-05 7:41 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-05 7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
2021-02-05 7:40 ` [Patch V3 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers Heng Luo
2021-02-05 7:40 ` [Patch V3 03/40] TigerlakeSiliconPkg/Include: Add Pins, Register and other " Heng Luo
2021-02-05 7:40 ` [Patch V3 04/40] TigerlakeSiliconPkg/Cpu: Add Include headers Heng Luo
2021-02-05 7:40 ` [Patch V3 05/40] TigerlakeSiliconPkg/Pch: Add include headers Heng Luo
2021-02-05 7:40 ` [Patch V3 06/40] TigerlakeSiliconPkg/Pch: Add IncludePrivate headers Heng Luo
2021-02-05 7:40 ` [Patch V3 07/40] TigerlakeSiliconPkg/SystemAgent: Add include headers Heng Luo
2021-02-05 7:40 ` [Patch V3 08/40] TigerlakeSiliconPkg/SystemAgent: Add IncludePrivate headers Heng Luo
2021-02-05 7:40 ` [Patch V3 09/40] TigerlakeSiliconPkg/Fru: Add TglCpu/Include headers Heng Luo
2021-02-05 7:40 ` [Patch V3 10/40] TigerlakeSiliconPkg/Fru: Add TglCpu/IncludePrivate headers Heng Luo
2021-02-05 7:40 ` [Patch V3 11/40] TigerlakeSiliconPkg/Fru: Add TglPch/Include headers Heng Luo
2021-02-05 7:40 ` [Patch V3 12/40] TigerlakeSiliconPkg/Fru: Add TglPch/IncludePrivate headers Heng Luo
2021-02-05 7:40 ` [Patch V3 13/40] TigerlakeSiliconPkg/IpBlock: Add Cnvi component Heng Luo
2021-02-05 7:40 ` [Patch V3 14/40] TigerlakeSiliconPkg/IpBlock: Add CpuPcieRp component Heng Luo
2021-02-05 7:40 ` [Patch V3 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component Heng Luo
2021-02-05 7:40 ` [Patch V3 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component Heng Luo
2021-02-05 7:40 ` [Patch V3 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Heng Luo
2021-02-05 7:40 ` [Patch V3 18/40] TigerlakeSiliconPkg/IpBlock: Add Graphics component Heng Luo
2021-02-05 7:40 ` [Patch V3 19/40] TigerlakeSiliconPkg/IpBlock: Add Hda component Heng Luo
2021-02-05 7:40 ` [Patch V3 20/40] TigerlakeSiliconPkg/IpBlock: Add HostBridge component Heng Luo
2021-02-05 7:40 ` Heng Luo [this message]
2021-02-05 7:40 ` [Patch V3 22/40] TigerlakeSiliconPkg/IpBlock: Add PchDmi component Heng Luo
2021-02-05 7:40 ` [Patch V3 23/40] TigerlakeSiliconPkg/IpBlock: Add PcieRp component Heng Luo
2021-02-05 7:40 ` [Patch V3 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component Heng Luo
2021-02-05 7:40 ` [Patch V3 25/40] TigerlakeSiliconPkg/IpBlock: Add Psf component Heng Luo
2021-02-05 7:40 ` [Patch V3 26/40] TigerlakeSiliconPkg/IpBlock: Add Sata component Heng Luo
2021-02-05 7:40 ` [Patch V3 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component Heng Luo
2021-02-05 7:40 ` [Patch V3 28/40] TigerlakeSiliconPkg/IpBlock: Add Smbus component Heng Luo
2021-02-05 7:40 ` [Patch V3 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component Heng Luo
2021-02-05 7:40 ` [Patch V3 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component Heng Luo
2021-02-05 7:40 ` [Patch V3 31/40] TigerlakeSiliconPkg/Library: Add package common library instances Heng Luo
2021-02-05 7:40 ` [Patch V3 32/40] TigerlakeSiliconPkg/Pch: Add Pch " Heng Luo
2021-02-05 7:40 ` [Patch V3 33/40] TigerlakeSiliconPkg/Pch: Add Pch private " Heng Luo
2021-02-05 7:40 ` [Patch V3 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and " Heng Luo
2021-02-05 7:40 ` [Patch V3 35/40] TigerlakeSiliconPkg/Fru/TglCpu: Add CpuPcieRp and Vtd " Heng Luo
2021-02-05 7:40 ` [Patch V3 36/40] TigerlakeSiliconPkg/Pch: Add Pch modules Heng Luo
2021-02-05 7:40 ` [Patch V3 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules Heng Luo
2021-02-05 7:40 ` [Patch V3 38/40] TigerlakeSiliconPkg/Fru: Add Fru DSC files Heng Luo
2021-02-05 7:40 ` [Patch V3 39/40] TigerlakeSiliconPkg: Add package " Heng Luo
2021-02-05 7:40 ` [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers Heng Luo
2021-02-05 18:36 ` Nate DeSimone
2021-02-05 18:57 ` Chaganty, Rangasai V
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210205074045.3916-21-heng.luo@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox