[edk2-devel] [PATCH 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component

Heng Luo heng.luo at intel.com
Mon Feb 1 01:36:38 UTC 2021


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 at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Signed-off-by: Heng Luo <heng.luo at 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.
+
+ at param[in]  CpuSbDevice      CPU SB Device
+ at param[in]  Offset           Register offset of Port ID.
+ at param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+ at 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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#70971): https://edk2.groups.io/g/devel/message/70971
Mute This Topic: https://groups.io/mt/80274135/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list