public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
	"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
	"Gao, Liming" <liming.gao@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>,
	"Sinha, Ankit" <ankit.sinha@intel.com>
Subject: Re: [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
Date: Sat, 17 Aug 2019 01:13:41 +0000	[thread overview]
Message-ID: <3C3EFB470A303B4AB093197B6777CCEC50462360@PGSMSX111.gar.corp.intel.com> (raw)
In-Reply-To: <20190817001603.30632-22-michael.a.kubacki@intel.com>

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add
> Base library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds Pch/Library/Private Base library class instances.
> 
> * BaseGpioHelpersLibNull
> * BasePchSpiCommonlib
> * BaseSiScheduleResetLib
> * BaseSiScheduleResetLibFsp
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibN
> ull/BaseGpioHelpersLibNull.inf     |   26 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLi
> b/BasePchSpiCommonLib.inf           |   28 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLib.inf     |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLibFsp.inf  |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibN
> ull/BaseGpioHelpersLibNull.c       |  108 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLi
> b/SpiCommon.c                       | 1081 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLib.c       |   70 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLibCommon.c |  125 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLibFsp.c    |   61 ++
>  9 files changed, 1579 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.inf
> new file mode 100644
> index 0000000000..5502af824f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.inf
> @@ -0,0 +1,26 @@
> +## @file
> +# Component description file for the NULL GpioHelpersLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseGpioHelpersLib
> +FILE_GUID = AB282608-2A50-4AE3-9242-64064ECF40D4
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = GpioHelpersLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +BaseGpioHelpersLibNull.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommon
> Lib/BasePchSpiCommonLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/BasePchSpiCommonLib.inf
> new file mode 100644
> index 0000000000..ea23e628c8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/BasePchSpiCommonLib.inf
> @@ -0,0 +1,28 @@
> +## @file
> +#  Component description file for the PchSpiCommonLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BasePchSpiCommonLib
> +  FILE_GUID                      = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PchSpiCommonLib
> +
> +[Sources]
> +  SpiCommon.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  IoLib
> +  DebugLib
> +  PmcLib
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.inf
> new file mode 100644
> index 0000000000..de7f6eeb73
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Component description file for Si Reset Schedule Library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseSiScheduleResetLib
> +FILE_GUID = E6F3D551-36C0-4737-80C7-47FC57593163
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = SiScheduleResetLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +HobLib
> +ResetSystemLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Guids]
> +gSiScheduleResetHobGuid
> +gPchConfigHobGuid
> +
> +[Sources]
> +BaseSiScheduleResetLibCommon.c
> +BaseSiScheduleResetLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.inf
> new file mode 100644
> index 0000000000..c8fe9e6079
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Component description file for Si Reset Schedule Library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseSiScheduleResetLibFsp
> +FILE_GUID = 1478D005-8DEC-4A6E-9619-309C6A7F313A
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = SiScheduleResetLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +HobLib
> +PeiServicesTablePointerLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Guids]
> +gSiScheduleResetHobGuid
> +gPchConfigHobGuid
> +
> +[Sources]
> +BaseSiScheduleResetLibCommon.c
> +BaseSiScheduleResetLibFsp.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.c
> new file mode 100644
> index 0000000000..46390eeca1
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.c
> @@ -0,0 +1,108 @@
> +/** @file
> +  This file contains NULL implementation for GPIO Helpers Lib
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <GpioConfig.h>
> +
> +/**
> +  This procedure stores GPIO pad unlock information
> +
> +  @param[in] GpioPad         GPIO pad
> +  @param[in] GpioLockConfig  GPIO Lock Configuration
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioStoreUnlockData (
> +  IN GPIO_PAD             GpioPad,
> +  IN GPIO_LOCK_CONFIG     GpioLockConfig
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This procedure stores GPIO group data about pads which PadConfig needs
> to be unlocked.
> +
> +  @param[in]  GroupIndex          GPIO group index
> +  @param[in]  DwNum               DWORD index for a group.
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @param[in]  UnlockedPads        DWORD bitmask for pads which are going
> to be left unlocked
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: Skip, 1: Leave unlocked
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioStoreGroupDwUnlockPadConfigData (
> +  IN UINT32                       GroupIndex,
> +  IN UINT32                       DwNum,
> +  IN UINT32                       UnlockedPads
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This procedure stores GPIO group data about pads which Output state
> needs to be unlocked.
> +
> +  @param[in]  GroupIndex          GPIO group index
> +  @param[in]  DwNum               DWORD index for a group.
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @param[in]  UnlockedPads        DWORD bitmask for pads which are going
> to be left unlocked
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: Skip, 1: Leave unlocked
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioStoreGroupDwUnlockOutputData (
> +  IN UINT32                       GroupIndex,
> +  IN UINT32                       DwNum,
> +  IN UINT32                       UnlockedPads
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This procedure will get GPIO group data with pads, which PadConfig is
> supposed to be left unlock
> +
> +  @param[in]  GroupIndex          GPIO group index
> +  @param[in]  DwNum               DWORD index for a group.
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @retval     UnlockedPads        DWORD bitmask for pads which are going to
> be left unlocked
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: to be locked, 1: Leave unlocked
> +**/
> +UINT32
> +GpioGetGroupDwUnlockPadConfigMask (
> +  IN UINT32                       GroupIndex,
> +  IN UINT32                       DwNum
> +  )
> +{
> +  return 0;
> +}
> +
> +/**
> +  This procedure will get GPIO group data with pads, which Output is
> supposed to be left unlock
> +
> +  @param[in]  GroupIndex          GPIO group index
> +  @param[in]  DwNum               DWORD index for a group.
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @retval     UnlockedPads        DWORD bitmask for pads which are going to
> be left unlocked
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: to be locked, 1: Leave unlocked
> +**/
> +UINT32
> +GpioGetGroupDwUnlockOutputMask (
> +  IN UINT32                       GroupIndex,
> +  IN UINT32                       DwNum
> +  )
> +{
> +  return 0;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommon
> Lib/SpiCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/SpiCommon.c
> new file mode 100644
> index 0000000000..bc84a4f27f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/SpiCommon.c
> @@ -0,0 +1,1081 @@
> +/** @file
> +  PCH SPI Common Driver implements the SPI Host Controller Compatibility
> Interface.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Protocol/Spi.h>
> +#include <Private/Library/PchSpiCommonLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsSpi.h>
> +#include <Register/PchRegsPmc.h>
> +
> +/**
> +  Initialize an SPI protocol instance.
> +
> +  @param[in] SpiInstance          Pointer to SpiInstance to initialize
> +
> +  @retval EFI_SUCCESS             The protocol instance was properly
> initialized
> +  @exception EFI_UNSUPPORTED      The PCH is not supported by this
> module
> +**/
> +EFI_STATUS
> +SpiProtocolConstructor (
> +  IN     SPI_INSTANCE       *SpiInstance
> +  )
> +{
> +  UINTN           PchSpiBar0;
> +  UINT32          Data32;
> +
> +  //
> +  // Initialize the SPI protocol instance
> +  //
> +  SpiInstance->Signature                    =
> PCH_SPI_PRIVATE_DATA_SIGNATURE;
> +  SpiInstance->Handle                       = NULL;
> +  SpiInstance->SpiProtocol.Revision         = PCH_SPI_SERVICES_REVISION;
> +  SpiInstance->SpiProtocol.FlashRead        = SpiProtocolFlashRead;
> +  SpiInstance->SpiProtocol.FlashWrite       = SpiProtocolFlashWrite;
> +  SpiInstance->SpiProtocol.FlashErase       = SpiProtocolFlashErase;
> +  SpiInstance->SpiProtocol.FlashReadSfdp    = SpiProtocolFlashReadSfdp;
> +  SpiInstance->SpiProtocol.FlashReadJedecId = SpiProtocolFlashReadJedecId;
> +  SpiInstance->SpiProtocol.FlashWriteStatus = SpiProtocolFlashWriteStatus;
> +  SpiInstance->SpiProtocol.FlashReadStatus  = SpiProtocolFlashReadStatus;
> +  SpiInstance->SpiProtocol.GetRegionAddress =
> SpiProtocolGetRegionAddress;
> +  SpiInstance->SpiProtocol.ReadPchSoftStrap =
> SpiProtocolReadPchSoftStrap;
> +  SpiInstance->SpiProtocol.ReadCpuSoftStrap =
> SpiProtocolReadCpuSoftStrap;
> +
> +  SpiInstance->PchSpiBase = PCI_SEGMENT_LIB_ADDRESS (
> +                              DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                              DEFAULT_PCI_BUS_NUMBER_PCH,
> +                              PCI_DEVICE_NUMBER_PCH_SPI,
> +                              PCI_FUNCTION_NUMBER_PCH_SPI,
> +                              0
> +                              );
> +
> +  SpiInstance->PchAcpiBase = PmcGetAcpiBase ();
> +  ASSERT (SpiInstance->PchAcpiBase != 0);
> +
> +  PchSpiBar0 = PciSegmentRead32 (SpiInstance->PchSpiBase +
> R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
> +  if (PchSpiBar0 == 0) {
> +    DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
> +    ASSERT (FALSE);
> +  }
> +
> +  if ((MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC) &
> B_SPI_MEM_HSFSC_FDV) == 0) {
> +    DEBUG ((DEBUG_ERROR, "ERROR : SPI Flash Signature invalid, cannot use
> the Hardware Sequencing registers!\n"));
> +    ASSERT (FALSE);
> +  }
> +
> +  //
> +  // Get Region 0 - 7 read Permission bits, region 8 and above are not
> permitted.
> +  //
> +  SpiInstance->ReadPermission = MmioRead8 (PchSpiBar0 +
> R_SPI_MEM_FRAP) & B_SPI_MEM_FRAP_BRRA_MASK;
> +  DEBUG ((DEBUG_INFO, "Flash Region read Permission : %0x\n",
> SpiInstance->ReadPermission));
> +  //
> +  // Get Region 0 - 7 write Permission bits, region 8 and above are not
> permitted.
> +  //
> +  SpiInstance->WritePermission = (UINT8) ((MmioRead16 (PchSpiBar0 +
> R_SPI_MEM_FRAP) &
> +                                           B_SPI_MEM_FRAP_BRWA_MASK) >>
> N_SPI_MEM_FRAP_BRWA);
> +  DEBUG ((DEBUG_INFO, "Flash Region write Permission : %0x\n",
> SpiInstance->WritePermission));
> +
> +  SpiInstance->SfdpVscc0Value = MmioRead32 (PchSpiBar0 +
> R_SPI_MEM_SFDP0_VSCC0);
> +  DEBUG ((DEBUG_INFO, "Component 0 SFDP VSCC value : %0x\n",
> SpiInstance->SfdpVscc0Value));
> +  SpiInstance->SfdpVscc1Value = MmioRead32 (PchSpiBar0 +
> R_SPI_MEM_SFDP1_VSCC1);
> +  DEBUG ((DEBUG_INFO, "Component 1 SFDP VSCC value : %0x\n",
> SpiInstance->SfdpVscc1Value));
> +
> +  //
> +  // Select to Flash Map 0 Register to get the number of flash Component
> +  //
> +  MmioAndThenOr32 (
> +    PchSpiBar0 + R_SPI_MEM_FDOC,
> +    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
> +    (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM |
> R_SPI_FLASH_FDBAR_FLASH_MAP0)
> +    );
> +
> +  //
> +  // Copy Zero based Number Of Components
> +  //
> +  SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16 (PchSpiBar0
> + R_SPI_MEM_FDOD) & B_SPI_FLASH_FDBAR_NC) >>
> N_SPI_FLASH_FDBAR_NC);
> +  DEBUG ((DEBUG_INFO, "Component Number : %0x\n",
> SpiInstance->NumberOfComponents + 1));
> +
> +  MmioAndThenOr32 (
> +    PchSpiBar0 + R_SPI_MEM_FDOC,
> +    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
> +    (UINT32) (V_SPI_MEM_FDOC_FDSS_COMP | R_SPI_FLASH_FCBA_FLCOMP)
> +    );
> +
> +  //
> +  // Copy Component 0 Density
> +  //
> +  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
> +  if (SpiInstance->NumberOfComponents > 0) {
> +    SpiInstance->Component1StartAddr =
> V_SPI_FLASH_FLCOMP_COMP_512KB <<
> +      (Data32 & B_SPI_FLASH_FLCOMP_COMP0_MASK);
> +    DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n",
> SpiInstance->Component1StartAddr));
> +    SpiInstance->TotalFlashSize = SpiInstance->Component1StartAddr +
> +      (V_SPI_FLASH_FLCOMP_COMP_512KB <<
> +      ((Data32 & B_SPI_FLASH_FLCOMP_COMP1_MASK) >>
> +      N_SPI_FLASH_FLCOMP_COMP1));
> +  } else {
> +    SpiInstance->TotalFlashSize = V_SPI_FLASH_FLCOMP_COMP_512KB <<
> +      (Data32 & B_SPI_FLASH_FLCOMP_COMP0_MASK);
> +  }
> +  DEBUG ((DEBUG_INFO, "Total Flash Size : %0x\n",
> SpiInstance->TotalFlashSize));
> +
> +  //
> +  // Select FLASH_MAP1 to get Flash PCH Strap Base Address
> +  //
> +  MmioAndThenOr32 (
> +    (PchSpiBar0 + R_SPI_MEM_FDOC),
> +    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
> +    (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM |
> R_SPI_FLASH_FDBAR_FLASH_MAP1)
> +    );
> +  //
> +  // Align FPSBA with address bits for the PCH Strap portion of flash descriptor
> +  //
> +  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
> +  SpiInstance->PchStrapBaseAddr = (UINT16) (((Data32 &
> B_SPI_FLASH_FDBAR_FPSBA)
> +                                             >> N_SPI_FLASH_FDBAR_FPSBA)
> +                                            << N_SPI_FLASH_FDBAR_FPSBA_REPR);
> +  DEBUG ((DEBUG_INFO, "PchStrapBaseAddr : %0x\n",
> SpiInstance->PchStrapBaseAddr));
> +  ASSERT (SpiInstance->PchStrapBaseAddr != 0);
> +  //
> +  // PCH Strap Length, [31:24] represents number of Dwords
> +  //
> +  SpiInstance->PchStrapSize = (UINT16) (((Data32 &
> B_SPI_FLASH_FDBAR_PCHSL)
> +                                         >> N_SPI_FLASH_FDBAR_PCHSL)
> +                                        * sizeof (UINT32));
> +  DEBUG ((DEBUG_INFO, "PchStrapSize : %0x\n", SpiInstance->PchStrapSize));
> +
> +  //
> +  // Select FLASH_MAP2 to get Flash CPU Strap Base Address
> +  //
> +  MmioAndThenOr32 (
> +    (PchSpiBar0 + R_SPI_MEM_FDOC),
> +    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK |
> B_SPI_MEM_FDOC_FDSI_MASK)),
> +    (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM |
> R_SPI_FLASH_FDBAR_FLASH_MAP2)
> +    );
> +  //
> +  // Align FPSBA with address bits for the PCH Strap portion of flash descriptor
> +  //
> +  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
> +  SpiInstance->CpuStrapBaseAddr = (UINT16) (((Data32 &
> B_SPI_FLASH_FDBAR_FCPUSBA)
> +                                             >> N_SPI_FLASH_FDBAR_FCPUSBA)
> +                                            << N_SPI_FLASH_FDBAR_FCPUSBA_REPR);
> +  DEBUG ((DEBUG_INFO, "CpuStrapBaseAddr : %0x\n",
> SpiInstance->CpuStrapBaseAddr));
> +  ASSERT (SpiInstance->CpuStrapBaseAddr != 0);
> +  //
> +  // CPU Strap Length, [15:8] represents number of Dwords
> +  //
> +  SpiInstance->CpuStrapSize = (UINT16) (((Data32 &
> B_SPI_FLASH_FDBAR_CPUSL)
> +                                         >> N_SPI_FLASH_FDBAR_CPUSL)
> +                                        * sizeof (UINT32));
> +  DEBUG ((DEBUG_INFO, "CpuStrapSize : %0x\n",
> SpiInstance->CpuStrapSize));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Delay for at least the request number of microseconds for Runtime usage.
> +
> +  @param[in] ABase                Acpi base address
> +  @param[in] Microseconds         Number of microseconds to delay.
> +
> +**/
> +VOID
> +EFIAPI
> +PchPmTimerStallRuntimeSafe (
> +  IN  UINT16  ABase,
> +  IN  UINTN   Microseconds
> +  )
> +{
> +  UINTN   Ticks;
> +  UINTN   Counts;
> +  UINTN   CurrentTick;
> +  UINTN   OriginalTick;
> +  UINTN   RemainingTick;
> +
> +  if (Microseconds == 0) {
> +    return;
> +  }
> +
> +  OriginalTick   = IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_TMR)) &
> B_ACPI_IO_PM1_TMR_VAL;
> +  CurrentTick    = OriginalTick;
> +
> +  //
> +  // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
> +  //
> +  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
> +
> +  //
> +  // The loops needed by timer overflow
> +  //
> +  Counts = Ticks / V_ACPI_IO_PM1_TMR_MAX_VAL;
> +
> +  //
> +  // Remaining clocks within one loop
> +  //
> +  RemainingTick = Ticks % V_ACPI_IO_PM1_TMR_MAX_VAL;
> +
> +  //
> +  // not intend to use TMROF_STS bit of register PM1_STS, because this adds
> extra
> +  // one I/O operation, and maybe generate SMI
> +  //
> +  while ((Counts != 0) || (RemainingTick > CurrentTick)) {
> +    CurrentTick = IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_TMR)) &
> B_ACPI_IO_PM1_TMR_VAL;
> +    //
> +    // Check if timer overflow
> +    //
> +    if ((CurrentTick < OriginalTick)) {
> +      if (Counts != 0) {
> +        Counts--;
> +      } else {
> +        //
> +        // If timer overflow and Counts equ to 0, that means we already stalled
> more than
> +        // RemainingTick, break the loop here
> +        //
> +        break;
> +      }
> +    }
> +
> +    OriginalTick = CurrentTick;
> +  }
> +}
> +
> +/**
> +  Wait execution cycle to complete on the SPI interface.
> +
> +  @param[in] This                 The SPI protocol instance
> +  @param[in] PchSpiBar0           Spi MMIO base address
> +  @param[in] ErrorCheck           TRUE if the SpiCycle needs to do the error
> check
> +
> +  @retval TRUE                    SPI cycle completed on the interface.
> +  @retval FALSE                   Time out while waiting the SPI cycle to
> complete.
> +                                  It's not safe to program the next command on the
> SPI interface.
> +**/
> +STATIC
> +BOOLEAN
> +WaitForSpiCycleComplete (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINTN              PchSpiBar0,
> +  IN     BOOLEAN            ErrorCheck
> +  )
> +{
> +  UINT64        WaitTicks;
> +  UINT64        WaitCount;
> +  UINT32        Data32;
> +  SPI_INSTANCE  *SpiInstance;
> +
> +  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +
> +  //
> +  // Convert the wait period allowed into to tick count
> +  //
> +  WaitCount = SPI_WAIT_TIME / SPI_WAIT_PERIOD;
> +  //
> +  // Wait for the SPI cycle to complete.
> +  //
> +  for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
> +    Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC);
> +    if ((Data32 & B_SPI_MEM_HSFSC_SCIP) == 0) {
> +      MmioWrite32 (PchSpiBar0 + R_SPI_MEM_HSFSC,
> B_SPI_MEM_HSFSC_FCERR | B_SPI_MEM_HSFSC_FDONE);
> +      if (((Data32 & B_SPI_MEM_HSFSC_FCERR) != 0) && (ErrorCheck == TRUE))
> {
> +        return FALSE;
> +      } else {
> +        return TRUE;
> +      }
> +    }
> +    PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase,
> SPI_WAIT_PERIOD);
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  This function sends the programmed SPI command to the slave device.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] SpiRegionType        The SPI Region type for flash cycle which is
> listed in the Descriptor
> +  @param[in] FlashCycleType       The Flash SPI cycle type list in HSFC
> (Hardware Sequencing Flash Control Register) register
> +  @param[in] Address              The Flash Linear Address must fall within a
> region for which BIOS has access permissions.
> +  @param[in] ByteCount            Number of bytes in the data portion of the
> SPI cycle.
> +  @param[in,out] Buffer           Pointer to caller-allocated buffer containing
> the dada received or sent during the SPI cycle.
> +
> +  @retval EFI_SUCCESS             SPI command completes successfully.
> +  @retval EFI_DEVICE_ERROR        Device error, the command aborts
> abnormally.
> +  @retval EFI_ACCESS_DENIED       Some unrecognized or blocked command
> encountered in hardware sequencing mode
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +**/
> +STATIC
> +EFI_STATUS
> +SendSpiCmd (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     FLASH_REGION_TYPE  FlashRegionType,
> +  IN     FLASH_CYCLE_TYPE   FlashCycleType,
> +  IN     UINT32             Address,
> +  IN     UINT32             ByteCount,
> +  IN OUT UINT8              *Buffer
> +  )
> +{
> +  EFI_STATUS      Status;
> +  UINT32          Index;
> +  SPI_INSTANCE    *SpiInstance;
> +  UINT64          SpiBaseAddress;
> +  UINTN           PchSpiBar0;
> +  UINT32          HardwareSpiAddr;
> +  UINT32          FlashRegionSize;
> +  UINT32          SpiDataCount;
> +  UINT32          FlashCycle;
> +  UINT8           BiosCtlSave;
> +  UINT32          SmiEnSave;
> +  UINT16          ABase;
> +  UINT32          HsfstsCtl;
> +
> +  //
> +  // For flash write, there is a requirement that all CPU threads are in SMM
> +  // before the flash protection is disabled.
> +  //
> +  if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType ==
> FlashCycleErase)) {
> +    if (!IsSpiFlashWriteGranted ()) {
> +      return EFI_ACCESS_DENIED;
> +    }
> +  }
> +
> +  Status            = EFI_SUCCESS;
> +  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +  SpiBaseAddress    = SpiInstance->PchSpiBase;
> +  PchSpiBar0        = AcquireSpiBar0 (SpiInstance);
> +  ABase             = SpiInstance->PchAcpiBase;
> +
> +  //
> +  // Disable SMIs to make sure normal mode flash access is not interrupted by
> an SMI
> +  // whose SMI handler accesses flash (e.g. for error logging)
> +  //
> +  // *** NOTE: if the SMI_LOCK bit is set (i.e., PMC PCI Offset A0h [4]='1'),
> +  // clearing B_GBL_SMI_EN will not have effect. In this situation, some other
> +  // synchronization methods must be applied here or in the consumer of the
> +  // SendSpiCmd. An example method is disabling the specific SMI sources
> +  // whose SMI handlers access flash before flash cycle and re-enabling the
> SMI
> +  // sources after the flash cycle .
> +  //
> +  SmiEnSave   = IoRead32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN));
> +  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN), SmiEnSave & (UINT32)
> (~B_ACPI_IO_SMI_EN_GBL_SMI));
> +  BiosCtlSave = PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_SRC;
> +
> +  //
> +  // If it's write cycle, disable Prefetching, Caching and disable BIOS Write
> Protect
> +  //
> +  if ((FlashCycleType == FlashCycleWrite) ||
> +      (FlashCycleType == FlashCycleErase)) {
> +    Status = DisableBiosWriteProtect ();
> +    if (EFI_ERROR (Status)) {
> +      goto SendSpiCmdEnd;
> +    }
> +    PciSegmentAndThenOr8 (
> +      SpiBaseAddress + R_SPI_CFG_BC,
> +      (UINT8) (~B_SPI_CFG_BC_SRC),
> +      (UINT8) (V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS <<
> N_SPI_CFG_BC_SRC)
> +      );
> +  }
> +  //
> +  // Make sure it's safe to program the command.
> +  //
> +  if (!WaitForSpiCycleComplete (This, PchSpiBar0, FALSE)) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto SendSpiCmdEnd;
> +  }
> +
> +  //
> +  // Check if Write Status isn't disabled in HW Sequencing
> +  //
> +  if (FlashCycleType == FlashCycleWriteStatus) {
> +    HsfstsCtl = MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC);
> +    if ((HsfstsCtl & B_SPI_MEM_HSFSC_WRSDIS) != 0) {
> +      Status = EFI_ACCESS_DENIED;
> +      goto SendSpiCmdEnd;
> +    }
> +  }
> +
> +  Status = SpiProtocolGetRegionAddress (This, FlashRegionType,
> &HardwareSpiAddr, &FlashRegionSize);
> +  if (EFI_ERROR (Status)) {
> +    goto SendSpiCmdEnd;
> +  }
> +  HardwareSpiAddr += Address;
> +  if ((Address + ByteCount) > FlashRegionSize) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto SendSpiCmdEnd;
> +  }
> +
> +  //
> +  // Check for PCH SPI hardware sequencing required commands
> +  //
> +  FlashCycle = 0;
> +  switch (FlashCycleType) {
> +    case FlashCycleRead:
> +      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      break;
> +    case FlashCycleWrite:
> +      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_WRITE <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      break;
> +    case FlashCycleErase:
> +      if (((ByteCount % SIZE_4KB) != 0) ||
> +          ((HardwareSpiAddr % SIZE_4KB) != 0)) {
> +        ASSERT (FALSE);
> +        Status = EFI_INVALID_PARAMETER;
> +        goto SendSpiCmdEnd;
> +      }
> +      break;
> +    case FlashCycleReadSfdp:
> +      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_SFDP <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      break;
> +    case FlashCycleReadJedecId:
> +      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_JEDEC_ID <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      break;
> +    case FlashCycleWriteStatus:
> +      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_WRITE_STATUS <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      break;
> +    case FlashCycleReadStatus:
> +      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_STATUS <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      break;
> +    default:
> +      //
> +      // Unrecognized Operation
> +      //
> +      ASSERT (FALSE);
> +      Status = EFI_INVALID_PARAMETER;
> +      goto SendSpiCmdEnd;
> +      break;
> +  }
> +
> +  do {
> +    SpiDataCount = ByteCount;
> +    if ((FlashCycleType == FlashCycleRead) ||
> +        (FlashCycleType == FlashCycleWrite) ||
> +        (FlashCycleType == FlashCycleReadSfdp)) {
> +      //
> +      // Trim at 256 byte boundary per operation,
> +      // - PCH SPI controller requires trimming at 4KB boundary
> +      // - Some SPI chips require trimming at 256 byte boundary for write
> operation
> +      // - Trimming has limited performance impact as we can read / write
> atmost 64 byte
> +      //   per operation
> +      //
> +      if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 -
> 1))) {
> +        SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) -
> (UINT32) (HardwareSpiAddr);
> +      }
> +      //
> +      // Calculate the number of bytes to shift in/out during the SPI data cycle.
> +      // Valid settings for the number of bytes duing each data portion of the
> +      // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
> +      //
> +      if (SpiDataCount >= 64) {
> +        SpiDataCount = 64;
> +      } else if ((SpiDataCount &~0x07) != 0) {
> +        SpiDataCount = SpiDataCount &~0x07;
> +      }
> +    }
> +    if (FlashCycleType == FlashCycleErase) {
> +      if (((ByteCount / SIZE_64KB) != 0) &&
> +          ((ByteCount % SIZE_64KB) == 0) &&
> +          ((HardwareSpiAddr % SIZE_64KB) == 0)) {
> +        if (HardwareSpiAddr < SpiInstance->Component1StartAddr) {
> +          //
> +          // Check whether Component0 support 64k Erase
> +          //
> +          if ((SpiInstance->SfdpVscc0Value &
> B_SPI_MEM_SFDPX_VSCCX_EO_64K) != 0) {
> +            SpiDataCount = SIZE_64KB;
> +          } else {
> +            SpiDataCount = SIZE_4KB;
> +          }
> +        } else {
> +          //
> +          // Check whether Component1 support 64k Erase
> +          //
> +          if ((SpiInstance->SfdpVscc1Value &
> B_SPI_MEM_SFDPX_VSCCX_EO_64K) != 0) {
> +            SpiDataCount = SIZE_64KB;
> +          } else {
> +            SpiDataCount = SIZE_4KB;
> +          }
> +        }
> +      } else {
> +        SpiDataCount = SIZE_4KB;
> +      }
> +      if (SpiDataCount == SIZE_4KB) {
> +        FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_4K_ERASE <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      } else {
> +        FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_64K_ERASE <<
> N_SPI_MEM_HSFSC_CYCLE);
> +      }
> +    }
> +    //
> +    // If it's write cycle, load data into the SPI data buffer.
> +    //
> +    if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType ==
> FlashCycleWriteStatus)) {
> +      if ((SpiDataCount & 0x07) != 0) {
> +        //
> +        // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
> +        //
> +        for (Index = 0; Index < SpiDataCount; Index++) {
> +          MmioWrite8 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index,
> Buffer[Index]);
> +        }
> +      } else {
> +        //
> +        // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
> +        //
> +        for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
> +          MmioWrite32 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index, *(UINT32
> *) (Buffer + Index));
> +        }
> +      }
> +    }
> +
> +    //
> +    // Set the Flash Address
> +    //
> +    MmioWrite32 (
> +      (PchSpiBar0 + R_SPI_MEM_FADDR),
> +      (UINT32) (HardwareSpiAddr & B_SPI_MEM_FADDR_MASK)
> +      );
> +
> +    //
> +    // Set Data count, Flash cycle, and Set Go bit to start a cycle
> +    //
> +    MmioAndThenOr32 (
> +      PchSpiBar0 + R_SPI_MEM_HSFSC,
> +      (UINT32) (~(B_SPI_MEM_HSFSC_FDBC_MASK |
> B_SPI_MEM_HSFSC_CYCLE_MASK)),
> +      (UINT32) ((((SpiDataCount - 1) << N_SPI_MEM_HSFSC_FDBC) &
> B_SPI_MEM_HSFSC_FDBC_MASK) | FlashCycle |
> B_SPI_MEM_HSFSC_CYCLE_FGO)
> +      );
> +    //
> +    // end of command execution
> +    //
> +    // Wait the SPI cycle to complete.
> +    //
> +    if (!WaitForSpiCycleComplete (This, PchSpiBar0, TRUE)) {
> +      ASSERT (FALSE);
> +      Status = EFI_DEVICE_ERROR;
> +      goto SendSpiCmdEnd;
> +    }
> +    //
> +    // If it's read cycle, load data into the call's buffer.
> +    //
> +    if ((FlashCycleType == FlashCycleRead) ||
> +        (FlashCycleType == FlashCycleReadSfdp) ||
> +        (FlashCycleType == FlashCycleReadJedecId) ||
> +        (FlashCycleType == FlashCycleReadStatus)) {
> +      if ((SpiDataCount & 0x07) != 0) {
> +        //
> +        // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
> +        //
> +        for (Index = 0; Index < SpiDataCount; Index++) {
> +          Buffer[Index] = MmioRead8 (PchSpiBar0 + R_SPI_MEM_FDATA00 +
> Index);
> +        }
> +      } else {
> +        //
> +        // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
> +        //
> +        for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
> +          *(UINT32 *) (Buffer + Index) = MmioRead32 (PchSpiBar0 +
> R_SPI_MEM_FDATA00 + Index);
> +        }
> +      }
> +    }
> +
> +    HardwareSpiAddr += SpiDataCount;
> +    Buffer += SpiDataCount;
> +    ByteCount -= SpiDataCount;
> +  } while (ByteCount > 0);
> +
> +SendSpiCmdEnd:
> +  //
> +  // Restore the settings for SPI Prefetching and Caching and enable BIOS
> Write Protect
> +  //
> +  if ((FlashCycleType == FlashCycleWrite) ||
> +      (FlashCycleType == FlashCycleErase)) {
> +    EnableBiosWriteProtect ();
> +    PciSegmentAndThenOr8 (
> +      SpiBaseAddress + R_SPI_CFG_BC,
> +      (UINT8) ~B_SPI_CFG_BC_SRC,
> +      BiosCtlSave
> +      );
> +  }
> +  //
> +  // Restore SMIs.
> +  //
> +  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN), SmiEnSave);
> +
> +  ReleaseSpiBar0 (SpiInstance);
> +
> +  return Status;
> +}
> +
> +/**
> +  Read data from the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] FlashRegionType      The Flash Region type for flash cycle
> which is listed in the Descriptor.
> +  @param[in] Address              The Flash Linear Address must fall within a
> region for which BIOS has access permissions.
> +  @param[in] ByteCount            Number of bytes in the data portion of the
> SPI cycle.
> +  @param[out] Buffer              The Pointer to caller-allocated buffer
> containing the dada received.
> +                                  It is the caller's responsibility to make sure Buffer is
> large enough for the total number of bytes read.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashRead (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     FLASH_REGION_TYPE  FlashRegionType,
> +  IN     UINT32             Address,
> +  IN     UINT32             ByteCount,
> +  OUT    UINT8              *Buffer
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionType,
> +             FlashCycleRead,
> +             Address,
> +             ByteCount,
> +             Buffer
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Write data to the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] FlashRegionType      The Flash Region type for flash cycle
> which is listed in the Descriptor.
> +  @param[in] Address              The Flash Linear Address must fall within a
> region for which BIOS has access permissions.
> +  @param[in] ByteCount            Number of bytes in the data portion of the
> SPI cycle.
> +  @param[in] Buffer               Pointer to caller-allocated buffer containing
> the data sent during the SPI cycle.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashWrite (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     FLASH_REGION_TYPE  FlashRegionType,
> +  IN     UINT32             Address,
> +  IN     UINT32             ByteCount,
> +  IN     UINT8              *Buffer
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionType,
> +             FlashCycleWrite,
> +             Address,
> +             ByteCount,
> +             Buffer
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Erase some area on the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] FlashRegionType      The Flash Region type for flash cycle
> which is listed in the Descriptor.
> +  @param[in] Address              The Flash Linear Address must fall within a
> region for which BIOS has access permissions.
> +  @param[in] ByteCount            Number of bytes in the data portion of the
> SPI cycle.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashErase (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     FLASH_REGION_TYPE  FlashRegionType,
> +  IN     UINT32             Address,
> +  IN     UINT32             ByteCount
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionType,
> +             FlashCycleErase,
> +             Address,
> +             ByteCount,
> +             NULL
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Read SFDP data from the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] ComponentNumber      The Componen Number for chip select
> +  @param[in] Address              The starting byte address for SFDP data read.
> +  @param[in] ByteCount            Number of bytes in SFDP data portion of the
> SPI cycle
> +  @param[out] SfdpData            The Pointer to caller-allocated buffer
> containing the SFDP data received
> +                                  It is the caller's responsibility to make sure Buffer is
> large enough for the total number of bytes read
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashReadSfdp (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT8              ComponentNumber,
> +  IN     UINT32             Address,
> +  IN     UINT32             ByteCount,
> +  OUT    UINT8              *SfdpData
> +  )
> +{
> +  SPI_INSTANCE      *SpiInstance;
> +  EFI_STATUS        Status;
> +  UINT32            FlashAddress;
> +
> +  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +  Status            = EFI_SUCCESS;
> +
> +  if (ComponentNumber > SpiInstance->NumberOfComponents) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  FlashAddress = 0;
> +  if (ComponentNumber == FlashComponent1) {
> +    FlashAddress = SpiInstance->Component1StartAddr;
> +  }
> +  FlashAddress += Address;
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionAll,
> +             FlashCycleReadSfdp,
> +             FlashAddress,
> +             ByteCount,
> +             SfdpData
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Read Jedec Id from the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] ComponentNumber      The Componen Number for chip select
> +  @param[in] ByteCount            Number of bytes in JedecId data portion of
> the SPI cycle, the data size is 3 typically
> +  @param[out] JedecId             The Pointer to caller-allocated buffer
> containing JEDEC ID received
> +                                  It is the caller's responsibility to make sure Buffer is
> large enough for the total number of bytes read.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashReadJedecId (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT8              ComponentNumber,
> +  IN     UINT32             ByteCount,
> +  OUT    UINT8              *JedecId
> +  )
> +{
> +  SPI_INSTANCE      *SpiInstance;
> +  EFI_STATUS        Status;
> +  UINT32            Address;
> +
> +  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +  Status            = EFI_SUCCESS;
> +
> +  if (ComponentNumber > SpiInstance->NumberOfComponents) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Address = 0;
> +  if (ComponentNumber == FlashComponent1) {
> +    Address = SpiInstance->Component1StartAddr;
> +  }
> +
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionAll,
> +             FlashCycleReadJedecId,
> +             Address,
> +             ByteCount,
> +             JedecId
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Write the status register in the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] ByteCount            Number of bytes in Status data portion of
> the SPI cycle, the data size is 1 typically
> +  @param[in] StatusValue          The Pointer to caller-allocated buffer
> containing the value of Status register writing
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashWriteStatus (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT32             ByteCount,
> +  IN     UINT8              *StatusValue
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionAll,
> +             FlashCycleWriteStatus,
> +             0,
> +             ByteCount,
> +             StatusValue
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Read status register in the flash part.
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] ByteCount            Number of bytes in Status data portion of
> the SPI cycle, the data size is 1 typically
> +  @param[out] StatusValue         The Pointer to caller-allocated buffer
> containing the value of Status register received.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashReadStatus (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT32             ByteCount,
> +  OUT    UINT8              *StatusValue
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // Sends the command to the SPI interface to execute.
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionAll,
> +             FlashCycleReadStatus,
> +             0,
> +             ByteCount,
> +             StatusValue
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Get the SPI region base and size, based on the enum type
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] FlashRegionType      The Flash Region type for for the base
> address which is listed in the Descriptor.
> +  @param[out] BaseAddress         The Flash Linear Address for the Region 'n'
> Base
> +  @param[out] RegionSize          The size for the Region 'n'
> +
> +  @retval EFI_SUCCESS             Read success
> +  @retval EFI_INVALID_PARAMETER   Invalid region type given
> +  @retval EFI_DEVICE_ERROR        The region is not used
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolGetRegionAddress (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     FLASH_REGION_TYPE  FlashRegionType,
> +  OUT    UINT32             *BaseAddress,
> +  OUT    UINT32             *RegionSize
> +  )
> +{
> +  SPI_INSTANCE    *SpiInstance;
> +  UINTN           PchSpiBar0;
> +  UINT32          ReadValue;
> +
> +  SpiInstance     = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +
> +  if (FlashRegionType >= FlashRegionMax) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (FlashRegionType == FlashRegionAll) {
> +    *BaseAddress  = 0;
> +    *RegionSize   = SpiInstance->TotalFlashSize;
> +    return EFI_SUCCESS;
> +  }
> +
> +  PchSpiBar0      = AcquireSpiBar0 (SpiInstance);
> +  ReadValue = MmioRead32 (PchSpiBar0 + (R_SPI_MEM_FREG0_FLASHD +
> (S_SPI_MEM_FREGX * ((UINT32) FlashRegionType))));
> +  ReleaseSpiBar0 (SpiInstance);
> +
> +  //
> +  // If the region is not used, the Region Base is 7FFFh and Region Limit is
> 0000h
> +  //
> +  if (ReadValue == B_SPI_MEM_FREGX_BASE_MASK) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  *BaseAddress = ((ReadValue & B_SPI_MEM_FREGX_BASE_MASK) >>
> N_SPI_MEM_FREGX_BASE) <<
> +    N_SPI_MEM_FREGX_BASE_REPR;
> +  //
> +  // Region limit address Bits[11:0] are assumed to be FFFh
> +  //
> +  *RegionSize = ((((ReadValue & B_SPI_MEM_FREGX_LIMIT_MASK) >>
> N_SPI_MEM_FREGX_LIMIT) + 1) <<
> +                 N_SPI_MEM_FREGX_LIMIT_REPR) - *BaseAddress;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Read PCH Soft Strap Values
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] SoftStrapAddr        PCH Soft Strap address offset from FPSBA.
> +  @param[in] ByteCount            Number of bytes in SoftStrap data portion
> of the SPI cycle
> +  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer
> containing PCH Soft Strap Value.
> +                                  If the value of ByteCount is 0, the data type of
> SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap
> Length
> +                                  It is the caller's responsibility to make sure Buffer is
> large enough for the total number of bytes read.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolReadPchSoftStrap (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT32             SoftStrapAddr,
> +  IN     UINT32             ByteCount,
> +  OUT    VOID               *SoftStrapValue
> +  )
> +{
> +  SPI_INSTANCE      *SpiInstance;
> +  UINT32            StrapFlashAddr;
> +  EFI_STATUS        Status;
> +
> +  SpiInstance     = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +
> +  if (ByteCount == 0) {
> +    *(UINT16 *) SoftStrapValue = SpiInstance->PchStrapSize;
> +    return EFI_SUCCESS;
> +  }
> +
> +  if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->PchStrapSize) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // PCH Strap Flash Address = FPSBA + RamAddr
> +  //
> +  StrapFlashAddr = SpiInstance->PchStrapBaseAddr + SoftStrapAddr;
> +
> +  //
> +  // Read PCH Soft straps from using execute command
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionDescriptor,
> +             FlashCycleRead,
> +             StrapFlashAddr,
> +             ByteCount,
> +             SoftStrapValue
> +             );
> +  return Status;
> +}
> +
> +/**
> +  Read CPU Soft Strap Values
> +
> +  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
> +  @param[in] SoftStrapAddr        CPU Soft Strap address offset from
> FCPUSBA.
> +  @param[in] ByteCount            Number of bytes in SoftStrap data portion
> of the SPI cycle.
> +  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer
> containing CPU Soft Strap Value.
> +                                  If the value of ByteCount is 0, the data type of
> SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap
> Length
> +                                  It is the caller's responsibility to make sure Buffer is
> large enough for the total number of bytes read.
> +
> +  @retval EFI_SUCCESS             Command succeed.
> +  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
> +  @retval EFI_DEVICE_ERROR        Device error, command aborts
> abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolReadCpuSoftStrap (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT32             SoftStrapAddr,
> +  IN     UINT32             ByteCount,
> +  OUT    VOID               *SoftStrapValue
> +  )
> +{
> +  SPI_INSTANCE      *SpiInstance;
> +  UINT32            StrapFlashAddr;
> +  EFI_STATUS        Status;
> +
> +  SpiInstance     = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
> +
> +  if (ByteCount == 0) {
> +    *(UINT16 *) SoftStrapValue = SpiInstance->CpuStrapSize;
> +    return EFI_SUCCESS;
> +  }
> +
> +  if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->CpuStrapSize) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // CPU Strap Flash Address = FCPUSBA + RamAddr
> +  //
> +  StrapFlashAddr = SpiInstance->CpuStrapBaseAddr + SoftStrapAddr;
> +
> +  //
> +  // Read Cpu Soft straps from using execute command
> +  //
> +  Status = SendSpiCmd (
> +             This,
> +             FlashRegionDescriptor,
> +             FlashCycleRead,
> +             StrapFlashAddr,
> +             ByteCount,
> +             SoftStrapValue
> +             );
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.c
> new file mode 100644
> index 0000000000..dfc49d9bf6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/ResetSystemLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi.h>
> +#include <Pi/PiMultiPhase.h>
> +#include <Library/HobLib.h>
> +#include <Private/Library/SiScheduleResetLib.h>
> +#include <Private/SiScheduleResetHob.h>
> +
> +/**
> +  This function returns SiScheduleResetHob for library use
> +**/
> +SI_SCHEDULE_RESET_HOB *
> +SiScheduleGetResetData (
> +  VOID
> +  );
> +
> +/**
> +  This function performs reset based on SiScheduleResetHob
> +
> +  @retval     BOOLEAN       The function returns FALSE if no reset is required
> +**/
> +BOOLEAN
> +SiScheduleResetPerformReset (
> +  VOID
> +  )
> +{
> +  UINTN                 DataSize;
> +  SI_SCHEDULE_RESET_HOB *SiScheduleResetHob;
> +
> +  if (!SiScheduleResetIsRequired ()) {
> +    return FALSE;
> +  }
> +  SiScheduleResetHob = SiScheduleGetResetData ();
> +
> +  if (SiScheduleResetHob == NULL) {
> +    return TRUE;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "SiScheduleResetPerformReset : Reset Type =
> 0x%x\n", SiScheduleResetHob->ResetType));
> +  switch (SiScheduleResetHob->ResetType) {
> +  case EfiResetWarm:
> +    ResetWarm ();
> +    break;
> +
> +  case EfiResetCold:
> +    ResetCold ();
> +    break;
> +
> +  case EfiResetShutdown:
> +    ResetShutdown ();
> +    break;
> +
> +  case EfiResetPlatformSpecific:
> +    DataSize = sizeof (PCH_RESET_DATA);
> +    ResetPlatformSpecific (DataSize, &SiScheduleResetHob->ResetData);
> +    break;
> +  }
> +  // Code should never reach here
> +  ASSERT (FALSE);
> +  return TRUE;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibCommon.c
> new file mode 100644
> index 0000000000..e1d783b2e2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibCommon.c
> @@ -0,0 +1,125 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi.h>
> +#include <Pi/PiMultiPhase.h>
> +#include <Library/HobLib.h>
> +#include <Private/SiScheduleResetHob.h>
> +
> +/**
> +  This function returns SiScheduleResetHob for library use
> +**/
> +SI_SCHEDULE_RESET_HOB *
> +SiScheduleGetResetData (
> +  VOID
> +  )
> +{
> +  STATIC SI_SCHEDULE_RESET_HOB *SiScheduleResetHob = NULL;
> +  SI_SCHEDULE_RESET_HOB        *SiScheduleResetHobTemp;
> +  VOID                         *HobPtr;
> +
> +  if (SiScheduleResetHob != NULL) {
> +    return SiScheduleResetHob;
> +  }
> +
> +  HobPtr = GetFirstGuidHob (&gSiScheduleResetHobGuid);
> +  if (HobPtr == NULL) {
> +    SiScheduleResetHobTemp = BuildGuidHob (&gSiScheduleResetHobGuid,
> sizeof (SI_SCHEDULE_RESET_HOB));
> +    if (SiScheduleResetHobTemp == NULL) {
> +      ASSERT (FALSE);
> +      return SiScheduleResetHobTemp;
> +    }
> +    SiScheduleResetHobTemp->ResetType = 0xFF;
> +    DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : Init
> SiScheduleResetHob\n"));
> +  } else {
> +    SiScheduleResetHobTemp = (SI_SCHEDULE_RESET_HOB*)
> GET_GUID_HOB_DATA (HobPtr);
> +  }
> +  SiScheduleResetHob = SiScheduleResetHobTemp;
> +  return SiScheduleResetHobTemp;
> +}
> +
> +/**
> +  This function updates the reset information in SiScheduleResetHob
> +  @param[in] ResetType        UEFI defined reset type.
> +  @param[in] ResetData        Optional element used to introduce a platform
> specific reset.
> +                               The exact type of the reset is defined by the EFI_GUID
> that follows
> +                               the Null-terminated Unicode string.
> +**/
> +VOID
> +SiScheduleResetSetType (
> +  IN EFI_RESET_TYPE     ResetType,
> +  IN PCH_RESET_DATA     *ResetData OPTIONAL
> +  )
> +{
> +  SI_SCHEDULE_RESET_HOB *SiScheduleResetHob;
> +  if (ResetType > EfiResetPlatformSpecific) {
> +    DEBUG ((DEBUG_INFO, "Unsupported Reset Type Requested\n"));
> +    return;
> +  }
> +  SiScheduleResetHob = SiScheduleGetResetData ();
> +  if (SiScheduleResetHob == NULL) {
> +    return;
> +  }
> +  DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : Current Reset Type =
> 0x%x\n", SiScheduleResetHob->ResetType));
> +  if (SiScheduleResetHob->ResetType == ResetType) {
> +    DEBUG ((DEBUG_INFO, "Current Reset Type is same as requested Reset
> Type\n"));
> +    return;
> +  }
> +  if (SiScheduleResetHob->ResetType == 0xFF) {
> +    //
> +    // Init Reset Type to lowest ResetType
> +  //
> +    SiScheduleResetHob->ResetType = EfiResetWarm;
> +  }
> +  //
> +  // ResetType Priority set as : ResetPlatformSpecific(3) > ResetShutdown(2) >
> ResetCold(0) > ResetWarm(1)
> +  //
> +  switch (ResetType) {
> +    case EfiResetWarm:
> +      break;
> +
> +    case EfiResetCold:
> +      if (SiScheduleResetHob->ResetType == EfiResetWarm) {
> +        SiScheduleResetHob->ResetType = ResetType;
> +      }
> +      break;
> +
> +    case EfiResetShutdown:
> +      if (SiScheduleResetHob->ResetType < ResetType)
> +      SiScheduleResetHob->ResetType = ResetType;
> +      break;
> +
> +    case EfiResetPlatformSpecific:
> +      SiScheduleResetHob->ResetType = ResetType;
> +      SiScheduleResetHob->ResetData = *ResetData;
> +      break;
> +  }
> +  DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : New Reset Type =
> 0x%x\n", SiScheduleResetHob->ResetType));
> +}
> +
> +/**
> +  This function returns TRUE or FALSE depending on whether a reset is
> required based on SiScheduleResetHob
> +
> +  @retval     BOOLEAN       The function returns FALSE if no reset is required
> +**/
> +BOOLEAN
> +SiScheduleResetIsRequired (
> +  VOID
> +  )
> +{
> +  VOID                  *HobPtr;
> +
> +  HobPtr = NULL;
> +  HobPtr = GetFirstGuidHob (&gSiScheduleResetHobGuid);
> +  if (HobPtr == NULL) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.c
> new file mode 100644
> index 0000000000..15ac61a21b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.c
> @@ -0,0 +1,61 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi.h>
> +#include <Pi/PiMultiPhase.h>
> +#include <Pi/PiPeiCis.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Library/HobLib.h>
> +#include <Private/Library/SiScheduleResetLib.h>
> +#include <Private/SiScheduleResetHob.h>
> +
> +/**
> +  This function returns SiScheduleResetHob for library use
> +**/
> +SI_SCHEDULE_RESET_HOB *
> +SiScheduleGetResetData (
> +  VOID
> +  );
> +
> +/**
> +  This function performs reset based on SiScheduleResetHob
> +
> +  @retval     BOOLEAN       The function returns FALSE if no reset is required
> +**/
> +BOOLEAN
> +SiScheduleResetPerformReset (
> +  VOID
> +  )
> +{
> +  UINTN                 DataSize;
> +  SI_SCHEDULE_RESET_HOB *SiScheduleResetHob;
> +
> +  if (!SiScheduleResetIsRequired ()) {
> +    return FALSE;
> +  }
> +  SiScheduleResetHob = SiScheduleGetResetData ();
> +
> +  if (SiScheduleResetHob == NULL) {
> +    return TRUE;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "SiScheduleResetPerformReset : Reset Type =
> 0x%x\n", SiScheduleResetHob->ResetType));
> +  if (SiScheduleResetHob->ResetType == EfiResetPlatformSpecific) {
> +    DataSize = sizeof (PCH_RESET_DATA);
> +    (*GetPeiServicesTablePointer ())->ResetSystem2
> (SiScheduleResetHob->ResetType, EFI_SUCCESS, DataSize,
> &SiScheduleResetHob->ResetData);
> +  } else {
> +    (*GetPeiServicesTablePointer ())->ResetSystem2
> (SiScheduleResetHob->ResetType, EFI_SUCCESS, 0, NULL);
> +  }
> +  //
> +  // Code should never reach here
> +  //
> +  ASSERT (FALSE);
> +  return TRUE;
> +}
> --
> 2.16.2.windows.1


  parent reply	other threads:[~2019-08-17  1:13 UTC|newest]

Thread overview: 121+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  1:18   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  6:58   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  7:04   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:10   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel [this message]
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-19 18:09   ` Sinha, Ankit
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:08   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17  7:50   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17 20:11   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:00   ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C3EFB470A303B4AB093197B6777CCEC50462360@PGSMSX111.gar.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox