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

Nate DeSimone nathaniel.l.desimone at intel.com
Thu Feb 4 03:54:47 UTC 2021


Reviewed-by: Nate DeSimone <nathaniel.l.desimone at intel.com>

> -----Original Message-----
> From: Luo, Heng <heng.luo at intel.com>
> Sent: Sunday, January 31, 2021 5:37 PM
> To: devel at edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty at intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone at intel.com>
> Subject: [PATCH 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component
> 
> 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/PchSbi
> AccessLib.h                             | 112
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sb
> Regs.h                                   |  65
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegba
> rAccessLib/CpuRegbarAccessLib.c             | 494
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegba
> rAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf  |  35
> +++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/
> PchPcrLib.c                               | 313
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/
> PeiDxeSmmPchPcrLib.inf                    |  35
> +++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPch
> SbiAccessLib/PchSbiAccessLib.c            | 253
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPch
> SbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf |  36
> ++++++++++++++++++++++++++++++++++++
>  8 files changed, 1343 insertions(+)
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchS
> biAccessLib.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchS
> biAccessLib.h
> new file mode 100644
> index 0000000000..3fab933bbd
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchS
> biAccessLib.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/P2s
> bRegs.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2s
> bRegs.h
> new file mode 100644
> index 0000000000..44c71af719
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2s
> bRegs.h
> @@ -0,0 +1,65 @@
> +/** @file
> 
> +  Register names for PCH P2SB device
> 
> +
> 
> +  Conventions:
> 
> +
> 
> +  - Register definition format:
> 
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterS
> pace_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/PeiDxeSmmCpuReg
> barAccessLib/CpuRegbarAccessLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuReg
> barAccessLib/CpuRegbarAccessLib.c
> new file mode 100644
> index 0000000000..9d8851ac37
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuReg
> barAccessLib/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/PeiDxeSmmCpuReg
> barAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuReg
> barAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
> new file mode 100644
> index 0000000000..596543f34f
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuReg
> barAccessLib/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/PeiDxeSmmPchPcrLi
> b/PchPcrLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLi
> b/PchPcrLib.c
> new file mode 100644
> index 0000000000..c4f3740c86
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLi
> b/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/PeiDxeSmmPchPcrLi
> b/PeiDxeSmmPchPcrLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLi
> b/PeiDxeSmmPchPcrLib.inf
> new file mode 100644
> index 0000000000..2efeba374f
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLi
> b/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/PeiDxeSmmP
> chSbiAccessLib/PchSbiAccessLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmP
> chSbiAccessLib/PchSbiAccessLib.c
> new file mode 100644
> index 0000000000..8017dee3aa
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmP
> chSbiAccessLib/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/PeiDxeSmmP
> chSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmP
> chSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
> new file mode 100644
> index 0000000000..4199a0a6c7
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmP
> chSbiAccessLib/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 (#71156): https://edk2.groups.io/g/devel/message/71156
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