Reviewed-by: Nate DeSimone <nathaniel.l.desim...@intel.com> > -----Original Message----- > From: Luo, Heng <heng....@intel.com> > Sent: Sunday, January 31, 2021 5:37 PM > To: devel@edk2.groups.io > Cc: Chaganty, Rangasai V <rangasai.v.chaga...@intel.com>; Desimone, > Nathaniel L <nathaniel.l.desim...@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.chaga...@intel.com> > Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> > Signed-off-by: Heng Luo <heng....@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. > > + > > +@param[in] CpuSbDevice CPU SB Device > > +@param[in] Offset Register offset of Port ID. > > +@param[in] AndData And Data. Must be the same size as Size > parameter. > > + > > +@retval UINT8 Value written to register > > + > > +**/ > > +UINT8 > > +CpuRegbarAnd8 ( > > + IN CPU_SB_DEVICE_PID CpuSbDevicePid, > > + IN UINT16 Offset, > > + IN UINT8 AndData > > + ) > > +{ > > + return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8 > (CpuSbDevicePid, Offset) & AndData); > > +} > > + > > +/** > > + Write REGBAR register. > > + It programs REGBAR register and size in 4bytes. > > + The Offset should not exceed 0xFFFF and must be aligned with size. > > + > > + @param[in] CpuSbDevicePid CPU SB Device Port ID > > + @param[in] Offset Register offset of Port ID. > > + @param[in] AndData AND Data. Must be the same size as Size > parameter. > > + @param[in] OrData OR Data. Must be the same size as Size > parameter. > > + > > + @retval UINT32 Value written to register > > + > > +**/ > > +UINT32 > > +CpuRegbarAndThenOr32 ( > > + IN CPU_SB_DEVICE_PID CpuSbDevicePid, > > + IN UINT16 Offset, > > + IN UINT32 AndData, > > + IN UINT32 OrData > > + ) > > +{ > > + return CpuRegbarWrite32 (CpuSbDevicePid, Offset, (CpuRegbarRead32 > (CpuSbDevicePid, Offset) & AndData) | OrData); > > +} > > + > > +/** > > + Write REGBAR register. > > + It programs REGBAR register and size in 2bytes. > > + The Offset should not exceed 0xFFFF and must be aligned with size. > > + > > + @param[in] CpuSbDevicePid CPU SB Device Port ID > > + @param[in] Offset Register offset of Port ID. > > + @param[in] AndData AND Data. Must be the same size as Size > parameter. > > + @param[in] OrData OR Data. Must be the same size as Size > parameter. > > + > > + @retval UINT16 Value written to register > > + > > +**/ > > +UINT16 > > +CpuRegbarAndThenOr16 ( > > + IN CPU_SB_DEVICE_PID CpuSbDevicePid, > > + IN UINT16 Offset, > > + IN UINT16 AndData, > > + IN UINT16 OrData > > + ) > > +{ > > + return CpuRegbarWrite16 (CpuSbDevicePid, Offset, (CpuRegbarRead16 > (CpuSbDevicePid, Offset) & AndData) | OrData); > > +} > > + > > +/** > > + Write REGBAR register. > > + It programs REGBAR register and size in 1bytes. > > + The Offset should not exceed 0xFFFF and must be aligned with size. > > + > > + @param[in] CpuSbDevicePid CPU SB Device Port ID > > + @param[in] Offset Register offset of Port ID. > > + @param[in] AndData AND Data. Must be the same size as Size > parameter. > > + @param[in] OrData OR Data. Must be the same size as Size > parameter. > > + > > + @retval UINT8 Value written to register > > + > > +**/ > > +UINT8 > > +CpuRegbarAndThenOr8 ( > > + IN CPU_SB_DEVICE_PID CpuSbDevicePid, > > + IN UINT16 Offset, > > + IN UINT8 AndData, > > + IN UINT8 OrData > > + ) > > +{ > > + return CpuRegbarWrite8 (CpuSbDevicePid, Offset, (CpuRegbarRead8 > (CpuSbDevicePid, Offset) & AndData) | OrData); > > +} > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/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/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-