[edk2-devel] [PATCH v2 01/10] AlderlakeSiliconPkg/IpBlock: Add CpuPcieRp, Espi, Gpio components

Nate DeSimone nathaniel.l.desimone at intel.com
Sat Sep 16 00:26:07 UTC 2023


The series has been pushed as 9c77b37~..6382836

-----Original Message-----
From: Kasbekar, Saloni <saloni.kasbekar at intel.com> 
Sent: Thursday, September 14, 2023 9:46 PM
To: devel at edk2.groups.io
Cc: Kasbekar, Saloni <saloni.kasbekar at intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty at intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone at intel.com>; Chuang, Rosen <rosen.chuang at intel.com>
Subject: [PATCH v2 01/10] AlderlakeSiliconPkg/IpBlock: Add CpuPcieRp, Espi, Gpio components

Adds the following modules:
  - IpBlock/CpuPcieRp/Include
  - IpBlock/Espi/Library
  - IpBlock/Gpio/IncludePrivate
  - IpBlock/Gpio/Library
  - IpBlock/Gpio/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Cc: Rosen Chuang <rosen.chuang at intel.com>
Signed-off-by: Saloni Kasbekar <saloni.kasbekar at intel.com>
---
 .../IpBlock/CpuPcieRp/Include/CpuPcieInfo.h   |  25 +
 .../Espi/Library/PeiDxeSmmEspiLib/EspiLib.c   |  58 ++
 .../PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf     |  38 ++
 .../IncludePrivate/Library/GpioHelpersLib.h   |  50 ++
 .../IncludePrivate/Library/GpioNativePads.h   | 245 ++++++++
 .../IncludePrivate/Library/GpioPrivateLib.h   | 350 +++++++++++
 .../Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c  | 546 ++++++++++++++++++
 .../Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c   | 522 +++++++++++++++++
 .../Library/PeiDxeSmmGpioLib/GpioLibrary.h    |  29 +
 .../Library/PeiDxeSmmGpioLib/GpioNativeLib.c  | 177 ++++++
 .../PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf     |  44 ++
 .../BaseGpioHelpersLibNull.c                  |  51 ++
 .../BaseGpioHelpersLibNull.inf                |  25 +
 .../GpioNativePrivateLibInternal.h            |  48 ++
 .../PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c  | 267 +++++++++
 .../GpioPrivateLibPch.c                       | 172 ++++++
 .../GpioPrivateLibVer2.c                      |  81 +++
 .../PeiDxeSmmGpioPrivateLibVer2.inf           |  40 ++
 .../PeiGpioHelpersLib/PeiGpioHelpersLib.c     | 218 +++++++
 .../PeiGpioHelpersLib/PeiGpioHelpersLib.inf   |  46 ++
 20 files changed, 3032 insertions(+)
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c
 create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf

diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h
new file mode 100644
index 0000000000..a6f8b16d10
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h
@@ -0,0 +1,25 @@
+/** @file
+  This file contains definitions of PCIe controller information
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PCIE_INFO_H_
+#define _CPU_PCIE_INFO_H_
+
+#define PCIE_HWEQ_COEFFS_MAX    5
+
+
+//
+// SA PCI Express* Port configuration
+//
+
+#define CPU_PCIE_MAX_ROOT_PORTS            4
+#define CPU_PCIE_MAX_CONTROLLERS           3
+
+#define SA_PEG_MAX_FUN           0x04
+#define SA_PEG_MAX_LANE          0x14
+
+
+
+#endif
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c
new file mode 100644
index 0000000000..2e4d1375ca
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c
@@ -0,0 +1,58 @@
+/** @file
+  This file contains routines for eSPI
+
+   Copyright (c) 2022, 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/BaseMemoryLib.h>
+#include <Library/EspiLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/TimerLib.h>
+#include <PchLimits.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchRegsLpc.h>
+
+
+/**
+  Checks if second device capability is enabled
+
+  @retval TRUE      There's second device
+  @retval FALSE     There's no second device
+**/
+BOOLEAN
+IsEspiSecondSlaveSupported (
+  VOID
+  )
+{
+  return ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAPS) & B_ESPI_PCR_SOFTSTRAPS_CS1_EN) != 0);
+}
+
+
+/**
+  Is eSPI enabled in strap.
+
+  @retval TRUE          Espi is enabled in strap
+  @retval FALSE         Espi is disabled in strap
+**/
+BOOLEAN
+IsEspiEnabled (
+  VOID
+  )
+{
+  return (PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_CFG_VAL) & B_ESPI_PCR_CFG_VAL_ESPI_EN) != 0;
+}
+
+typedef enum {
+  EspiSlaveOperationConfigRead,
+  EspiSlaveOperationConfigWrite,
+  EspiSlaveOperationStatusRead,
+  EspiSlaveOperationInBandReset
+} ESPI_SLAVE_OPERATION;
+
+
+
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf
new file mode 100644
index 0000000000..e8db1e4e8d
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for the PeiDxeSmmPchEspiLib
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmEspiLib
+FILE_GUID = 7F25F990-7989-4413-B414-1EDE557E9389
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = EspiLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PchPcrLib
+TimerLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+EspiLib.c
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h
new file mode 100644
index 0000000000..cf67c81ed0
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h
@@ -0,0 +1,50 @@
+/** @file
+  Header file for GPIO Helpers Lib implementation.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_HELPERS_LIB_H_
+#define _GPIO_HELPERS_LIB_H_
+
+#include <Library/GpioConfig.h>
+
+/**
+  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]  PadsToLock          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
+  );
+
+/**
+  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]  PadsToLock          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
+  );
+
+#endif // _GPIO_HELPERS_LIB_H_
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h
new file mode 100644
index 0000000000..dbd13963fa
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h
@@ -0,0 +1,245 @@
+/** @file
+  Header file for GPIO Native pads support
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_NATIVE_PADS_H_
+#define _GPIO_NATIVE_PADS_H_
+
+//
+// GpioPad can contain additional information used to provide data on
+// native functions. Please refer to description of GPIO_NATIVE_PAD
+//
+// FFFF CCCC TTTG GGGG TTTT TTTP PPPP PPPP
+//
+// F - 2^4 = 16,  native function number
+// C - 2^4 = 16,  chipset ID
+// T - 2^10 = 1024 , abstract type representing native mode of a pad (e.g. SERIALIO_UART2_TX)
+// G - 2^5 = 32,  group
+// P - 2^9 = 512, pad number
+//
+// F & T contain additional optional settings used for native pads
+//
+#define GPIO_NATIVE_PAD_DEF(GpioNativePad, NativeMode, NativeFunction) \
+  (GpioNativePad | (NativeMode << 28) | ((NativeFunction & 0x7F) << 9) | ((NativeFunction & 0x380) << 14))
+
+#define GPIO_NATIVE_GET_FUNCTION(GpioNativePad) ((((GpioNativePad) & 0xFE00) >> 9) | (((GpioNativePad) & 0xE00000) >> 14))
+#define GPIO_NATIVE_GET_PAD_FN(GpioNativePad)   (((GpioNativePad) >> 28) & 0xF)
+#define GPIO_NATIVE_GET_PAD_MODE(GpioNativePad) ((GPIO_NATIVE_GET_PAD_FN(GpioNativePad) << 1) | 1)
+#define GPIO_NATIVE_TO_GPIO_PAD(GpioNativePad)  (GpioNativePad & 0xF1F01FF)
+
+//
+// Below defines and macros are used to build abstract type
+// to help encode native pin information in GPIO_PAD
+//
+
+//
+// Macro used to define GPIO native function.
+// <Min,Max> defines range that can be used to encode given native signal.
+// Numbering must be unique and cannot overlap.
+// If there are many instances of similar signal (e.g. per controller) the lower
+// word will store value for a given instance in the form: Min + Instance
+// Upper word (Max) is left untouched and later used for verification
+//
+#define GPIO_NATIVE_FUNCTION_DEF(Min, Max)              (((Max) << 16) + (Min))
+#define GPIO_NATIVE_FUNCTION_GET_MAX(NativeFunction)    (((NativeFunction) >> 16) & 0xFFFF)
+#define GPIO_NATIVE_FUNCTION_GET_VALUE(NativeFunction)  ((NativeFunction) & 0xFFFF)
+
+//
+// Macro GPIO_NATIVE_FUNCTION_GET_SIGNAL is created as synonym to macro GPIO_NATIVE_FUNCTION_GET_MAX
+// GPIO_NATIVE_FUNCTION_GET_SIGNAL used with below defines is more descriptive and easier to read
+// ex.
+//  - GPIO_NATIVE_FUNCTION_GET_SIGNAL(GPIO_SERIAL_IO_UART_RX)
+//  - GPIO_NATIVE_FUNCTION_GET_SIGNAL(GPIO_ISH_GP)
+//  - ...
+//
+#define GPIO_NATIVE_FUNCTION_GET_SIGNAL(NativeFunction) (GPIO_NATIVE_FUNCTION_GET_MAX(NativeFunction))
+
+//
+// GPIO native modes
+// Those defines are internal to this header.
+// GPIO_FUNCTION_<IP>_<signal>(index) defines should be used by other modules instead.
+//
+#define GPIO_SERIAL_IO_UART_RX     GPIO_NATIVE_FUNCTION_DEF(1,8)
+#define GPIO_SERIAL_IO_UART_TX     GPIO_NATIVE_FUNCTION_DEF(9,16)
+#define GPIO_SERIAL_IO_UART_RTS    GPIO_NATIVE_FUNCTION_DEF(17,24)
+#define GPIO_SERIAL_IO_UART_CTS    GPIO_NATIVE_FUNCTION_DEF(25,31)
+#define GPIO_SERIAL_IO_SPI_MOSI    GPIO_NATIVE_FUNCTION_DEF(32,39)
+#define GPIO_SERIAL_IO_SPI_MISO    GPIO_NATIVE_FUNCTION_DEF(40,47)
+#define GPIO_SERIAL_IO_SPI_CLK     GPIO_NATIVE_FUNCTION_DEF(48,55)
+#define GPIO_SERIAL_IO_SPI_CS      GPIO_NATIVE_FUNCTION_DEF(56,71)
+#define GPIO_ISH_GP                GPIO_NATIVE_FUNCTION_DEF(80,143)
+#define GPIO_ISH_UART_RX           GPIO_NATIVE_FUNCTION_DEF(144,151)
+#define GPIO_ISH_UART_TX           GPIO_NATIVE_FUNCTION_DEF(152,159)
+#define GPIO_ISH_UART_RTS          GPIO_NATIVE_FUNCTION_DEF(160,167)
+#define GPIO_ISH_UART_CTS          GPIO_NATIVE_FUNCTION_DEF(168,175)
+#define GPIO_ISH_SPI_MOSI          GPIO_NATIVE_FUNCTION_DEF(184,191)
+#define GPIO_ISH_SPI_MISO          GPIO_NATIVE_FUNCTION_DEF(192,199)
+#define GPIO_ISH_SPI_CLK           GPIO_NATIVE_FUNCTION_DEF(200,207)
+#define GPIO_ISH_SPI_CS            GPIO_NATIVE_FUNCTION_DEF(208,223)
+#define GPIO_ISH_I2C_SCL           GPIO_NATIVE_FUNCTION_DEF(232,239)
+#define GPIO_ISH_I2C_SDA           GPIO_NATIVE_FUNCTION_DEF(240,247)
+#define GPIO_THC_SPI_INT           GPIO_NATIVE_FUNCTION_DEF(248,251)
+#define GPIO_DMIC_DATA             GPIO_NATIVE_FUNCTION_DEF(258,261)
+#define GPIO_DMIC_CLKA             GPIO_NATIVE_FUNCTION_DEF(262,265)
+#define GPIO_DMIC_CLKB             GPIO_NATIVE_FUNCTION_DEF(266,269)
+#define GPIO_DDSP_HPD0             GPIO_NATIVE_FUNCTION_DEF(270,285)
+#define GPIO_PANEL_AVDD_EN         GPIO_NATIVE_FUNCTION_DEF(286,289)
+#define GPIO_PANEL_BKLTEN          GPIO_NATIVE_FUNCTION_DEF(290,293)
+#define GPIO_PANEL_BKLTCTL         GPIO_NATIVE_FUNCTION_DEF(294,297)
+#define GPIO_PANEL_RESET           GPIO_NATIVE_FUNCTION_DEF(298,301)
+#define GPIO_PANEL_AVEE_EN         GPIO_NATIVE_FUNCTION_DEF(302,305)
+#define GPIO_PANEL_VIO_EN          GPIO_NATIVE_FUNCTION_DEF(306,309)
+#define GPIO_PANEL_HPD             GPIO_NATIVE_FUNCTION_DEF(310,313)
+#define GPIO_PANEL_TE_EN           GPIO_NATIVE_FUNCTION_DEF(314,317)
+#define GPIO_HDMI_GMBUS_SCL        GPIO_NATIVE_FUNCTION_DEF(318,325)
+#define GPIO_HDMI_GMBUS_SDA        GPIO_NATIVE_FUNCTION_DEF(326,333)
+#define GPIO_SERIAL_IO_I2C_SCL     GPIO_NATIVE_FUNCTION_DEF(338,353)
+#define GPIO_SERIAL_IO_I2C_SDA     GPIO_NATIVE_FUNCTION_DEF(354,369)
+#define GPIO_SD_DATA               GPIO_NATIVE_FUNCTION_DEF(374,377)
+#define GPIO_EMMC_DATA             GPIO_NATIVE_FUNCTION_DEF(384,391)
+#define GPIO_THC_CLK_LOOPBACK      GPIO_NATIVE_FUNCTION_DEF(395,396)
+#define GPIO_MIPI_PANEL_RESET      GPIO_NATIVE_FUNCTION_DEF(401,404)
+#define GPIO_MIPI_SEC_POW_EN_AVEE  GPIO_NATIVE_FUNCTION_DEF(405,408)
+#define GPIO_MIPI_SEC_POW_EN_AVDD  GPIO_NATIVE_FUNCTION_DEF(409,412)
+#define GPIO_THC_WOT               GPIO_NATIVE_FUNCTION_DEF(413,414)
+#define GPIO_SATA_DEVSLP           GPIO_NATIVE_FUNCTION_DEF(415,446)
+#define GPIO_PCIE_CLKREQ           GPIO_NATIVE_FUNCTION_DEF(447,478)
+
+//
+// Serial IO UART
+//
+
+#define GPIO_FUNCTION_SERIAL_IO_UART_RX(UartDev)  (GPIO_SERIAL_IO_UART_RX + ((UINT32)UartDev))
+#define GPIO_FUNCTION_SERIAL_IO_UART_TX(UartDev)  (GPIO_SERIAL_IO_UART_TX + ((UINT32)UartDev))
+#define GPIO_FUNCTION_SERIAL_IO_UART_RTS(UartDev) (GPIO_SERIAL_IO_UART_RTS + ((UINT32)UartDev))
+#define GPIO_FUNCTION_SERIAL_IO_UART_CTS(UartDev) (GPIO_SERIAL_IO_UART_CTS + ((UINT32)UartDev))
+
+//
+// Serial IO SPI
+//
+#define GPIO_SERIAL_IO_SPI_RANGE  8  // Number of SerialIo SPIx controllers supported in GPIO_NATIVE_PAD encoding
+
+#define GPIO_FUNCTION_SERIAL_IO_SPI_MOSI(SpiDev)      (GPIO_SERIAL_IO_SPI_MOSI + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_SERIAL_IO_SPI_MISO(SpiDev)      (GPIO_SERIAL_IO_SPI_MISO + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_SERIAL_IO_SPI_CLK(SpiDev)       (GPIO_SERIAL_IO_SPI_CLK + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_SERIAL_IO_SPI_CS(SpiDev, CsNum) (GPIO_SERIAL_IO_SPI_CS + ((UINT32)SpiDev) + ((UINT32)CsNum) * GPIO_SERIAL_IO_SPI_RANGE)
+
+//
+// Serial IO I2C
+//
+
+#define GPIO_FUNCTION_SERIAL_IO_I2C_SCL(I2cDev) (GPIO_SERIAL_IO_I2C_SCL + ((UINT32)I2cDev))
+#define GPIO_FUNCTION_SERIAL_IO_I2C_SDA(I2cDev) (GPIO_SERIAL_IO_I2C_SDA + ((UINT32)I2cDev))
+
+//
+// ISH GP
+//
+
+#define GPIO_FUNCTION_ISH_GP(GpNum) (GPIO_ISH_GP + ((UINT32)GpNum))
+
+//
+// ISH UART
+//
+
+#define GPIO_FUNCTION_ISH_UART_RX(UartDev)  (GPIO_ISH_UART_RX + ((UINT32)UartDev))
+#define GPIO_FUNCTION_ISH_UART_TX(UartDev)  (GPIO_ISH_UART_TX + ((UINT32)UartDev))
+#define GPIO_FUNCTION_ISH_UART_RTS(UartDev) (GPIO_ISH_UART_RTS + ((UINT32)UartDev))
+#define GPIO_FUNCTION_ISH_UART_CTS(UartDev) (GPIO_ISH_UART_CTS + ((UINT32)UartDev))
+
+//
+// ISH SPI
+//
+#define GPIO_ISH_SPI_RANGE  8  // Number of ISH SPI controllers supported in GPIO_NATIVE_PAD encoding
+
+#define GPIO_FUNCTION_ISH_SPI_MOSI(SpiDev)      (GPIO_ISH_SPI_MOSI + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_ISH_SPI_MISO(SpiDev)      (GPIO_ISH_SPI_MISO + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_ISH_SPI_CLK(SpiDev)       (GPIO_ISH_SPI_CLK + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_ISH_SPI_CS(SpiDev, CsNum) (GPIO_ISH_SPI_CS + ((UINT32)SpiDev) + ((UINT32)CsNum) * GPIO_ISH_SPI_RANGE)
+
+//
+// ISH I2C
+//
+
+#define GPIO_FUNCTION_ISH_I2C_SCL(I2cDev) (GPIO_ISH_I2C_SCL + ((UINT32)I2cDev))
+#define GPIO_FUNCTION_ISH_I2C_SDA(I2cDev) (GPIO_ISH_I2C_SDA + ((UINT32)I2cDev))
+
+//
+// SD Card
+//
+#define GPIO_FUNCTION_SD_DATA(Index)        (GPIO_SD_DATA + ((UINT32)Index))
+
+//
+// EMMC
+//
+#define GPIO_FUNCTION_EMMC_DATA(Index)      (GPIO_EMMC_DATA + ((UINT32)Index))
+
+//
+// THC SPI
+//
+
+#define GPIO_FUNCTION_THC_SPI_INT(SpiDev) (GPIO_THC_SPI_INT + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_THC_CLK_LOOPBACK(SpiDev) (GPIO_THC_CLK_LOOPBACK + ((UINT32)SpiDev))
+#define GPIO_FUNCTION_THC_WOT(SpiDev) (GPIO_THC_WOT + ((UINT32)SpiDev))
+
+
+//
+// DMIC
+//
+
+#define GPIO_FUNCTION_DMIC_DATA(DmicDev) (GPIO_DMIC_DATA  + ((UINT32)DmicDev))
+#define GPIO_FUNCTION_DMIC_CLKA(DmicDev) (GPIO_DMIC_CLKA  + ((UINT32)DmicDev))
+#define GPIO_FUNCTION_DMIC_CLKB(DmicDev) (GPIO_DMIC_CLKB  + ((UINT32)DmicDev))
+#define GPIO_FUNCTION_DMIC_CLK(DmicDev)  (GPIO_DMIC_CLKA  + ((UINT32)DmicDev)) // If there is no split between channel A/B use A range for such Clocks
+
+
+//
+// DDSP HPD
+//
+
+#define GPIO_FUNCTION_DDSP_HPD(HpdIndex) \
+  (HpdIndex > 7) ? GPIO_DDSP_HPD0 + 8 + (HpdIndex) - 'A' : GPIO_DDSP_HPD0 + HpdIndex
+
+//
+// HDMI_GMBUS
+//
+
+#define GPIO_FUNCTION_HDMI_SCL(DdiPort) (GPIO_HDMI_GMBUS_SCL + ((UINT32)DdiPort))
+#define GPIO_FUNCTION_HDMI_SDA(DdiPort) (GPIO_HDMI_GMBUS_SDA + ((UINT32)DdiPort))
+
+//
+// Panel
+//
+
+#define GPIO_FUNCTION_PANEL_AVDD_EN(PanelDev)         (GPIO_PANEL_AVDD_EN + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_BKLTEN(PanelDev)          (GPIO_PANEL_BKLTEN + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_BKLTCTL(PanelDev)         (GPIO_PANEL_BKLTCTL + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_RESET(PanelDev)           (GPIO_PANEL_RESET + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_AVEE_EN(PanelDev)         (GPIO_PANEL_AVEE_EN + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_VIO_EN(PanelDev)          (GPIO_PANEL_VIO_EN + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_HPD(PanelDev)             (GPIO_PANEL_HPD + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_PANEL_TE_EN(PanelDev)           (GPIO_PANEL_TE_EN + ((UINT32)PanelDev))
+
+//
+// MIPI
+//
+#define GPIO_FUNCTION_MIPI_PANEL_RESET(PanelDev)      (GPIO_MIPI_PANEL_RESET + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_MIPI_SEC_POW_EN_AVEE(PanelDev)  (GPIO_MIPI_SEC_POW_EN_AVEE + ((UINT32)PanelDev))
+#define GPIO_FUNCTION_MIPI_SEC_POW_EN_AVDD(PanelDev)  (GPIO_MIPI_SEC_POW_EN_AVDD + ((UINT32)PanelDev))
+
+
+//
+// SATA DevSlp
+//
+#define GPIO_SATA_DEVSLP_RANGE 32   // Number of SATA DevSlp instances per controller supported in GPIO_NATIVE_PAD encoding
+
+#define GPIO_FUNCTION_SATA_DEVSLP(CsNum, SataDevSlpIndex)      (GPIO_SATA_DEVSLP + ((UINT32)SataDevSlpIndex) + ((UINT32)CsNum) * GPIO_SATA_DEVSLP_RANGE)
+
+//
+// SRC CLKREQ
+//
+
+#define GPIO_FUNCTION_PCIE_CLKREQ(ClkReqIndex)      (GPIO_PCIE_CLKREQ + ((UINT32)ClkReqIndex))
+
+#endif // _GPIO_NATIVE_PADS_H_
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h
new file mode 100644
index 0000000000..a757a4b057
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h
@@ -0,0 +1,350 @@
+/** @file
+  Header file for GpioPrivateLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_PRIVATE_LIB_H_
+#define _GPIO_PRIVATE_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/GpioConfig.h>
+#include <Library/PchPcrLib.h>
+
+/**
+  GPIO Standby State configuration
+  Standby State options for GPIO Pads
+**/
+typedef enum {
+  GpioIosStateDefault         = 0x0,
+  GpioIosStateLatchLastValue  = (0x0 << 1) | 0x01,  ///< Latch last value driven on TX, TX Enable and RX Enable
+  GpioIosStateTx0Rx0RxDis     = (0x1 << 1) | 0x01,  ///< TX: 0, RX: 0 (internally), RX disabled
+  GpioIosStateTx0Rx1RxDis     = (0x2 << 1) | 0x01,  ///< TX: 0, RX: 1 (internally), RX disabled
+  GpioIosStateTx1Rx0RxDis     = (0x3 << 1) | 0x01,  ///< TX: 1, RX: 0 (internally), RX disabled
+  GpioIosStateTx1Rx1RxDis     = (0x4 << 1) | 0x01,  ///< TX: 1, RX: 1 (internally), RX disabled
+  GpioIosStateTx0RxEn         = (0x5 << 1) | 0x01,  ///< TX: 0, RX enabled
+  GpioIosStateTx1RxEn         = (0x6 << 1) | 0x01,  ///< TX: 1, RX enabled
+  GpioIosStateHizRx0          = (0x7 << 1) | 0x01,  ///< Hi-Z, RX: 0 (internally)
+  GpioIosStateHizRx1          = (0x8 << 1) | 0x01,  ///< Hi-Z, RX: 1 (internally)
+  GpioIosStateTxDisRxEn       = (0x9 << 1) | 0x01,  ///< TX Disabled and RX Enabled (i.e. wake or interrupt)
+  GpioIosStateMasked          = (0xF << 1) | 0x01   ///< IO Standby signal is masked for this pad. In this mode, a pad operates as if IOStandby has not been asserted.
+} GPIO_IOSTANDBY_STATE;
+
+/**
+  GPIO Standby Term configuration
+  Standby Termination options for GPIO Pads
+**/
+typedef enum {
+  GpioIosTermDefault         = 0x00,
+  GpioIosTermSame            = (0x00 << 1) | 0x01, ///< Same as state specified in Term
+  GpioIosTermPuDisPdDis      = (0x01 << 1) | 0x01, ///< Disable Pullup and Pulldown
+  GpioIosTermPuDisPdEn       = (0x02 << 1) | 0x01, ///< Enable Pulldown
+  GpioIosTermPuEnPdDis       = (0x03 << 1) | 0x01  ///< Enable Pullup
+} GPIO_IOSTANDBY_TERM;
+
+//
+// Structure for native pin data
+//
+typedef struct {
+  GPIO_PAD              Pad;
+  GPIO_PAD_MODE         Mode;
+  GPIO_IOSTANDBY_STATE  IosState;
+  GPIO_IOSTANDBY_TERM   IosTerm;
+} GPIO_PAD_NATIVE_FUNCTION;
+
+//
+// Structure for Serial GPIO pin definition
+//
+typedef struct {
+  GPIO_PAD_NATIVE_FUNCTION  Sclock;
+  GPIO_PAD_NATIVE_FUNCTION  Sload;
+  GPIO_PAD_NATIVE_FUNCTION  Sdataout;
+} SGPIO_PINS;
+
+//
+// Structure for USB Virtual Wire OverCurrent Pad Mode group
+//
+typedef struct {
+  GPIO_PAD       OcRxPad;
+  GPIO_PAD       OcTxPad;
+} GPIO_VWOC_FUNCTION;
+
+//
+// Below defines are based on GPIO_CONFIG structure fields
+//
+#define B_GPIO_PAD_MODE_MASK                            0xF
+#define N_GPIO_PAD_MODE_BIT_POS                         0
+#define B_GPIO_DIRECTION_DIR_MASK                       0x7
+#define N_GPIO_DIRECTION_DIR_BIT_POS                    0
+#define B_GPIO_DIRECTION_INV_MASK                       0x18
+#define N_GPIO_DIRECTION_INV_BIT_POS                    3
+#define B_GPIO_OUTPUT_MASK                              0x3
+#define N_GPIO_OUTPUT_BIT_POS                           0
+#define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS            0
+#define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS              5
+#define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS    0
+#define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS               0
+
+//
+// Structure for storing information about registers offset, community,
+// maximal pad number for available groups
+//
+typedef struct {
+  PCH_SBI_PID  Community;
+  UINT16       PadOwnOffset;
+  UINT16       HostOwnOffset;
+  UINT16       GpiIsOffset;
+  UINT16       GpiIeOffset;
+  UINT16       GpiGpeStsOffset;
+  UINT16       GpiGpeEnOffset;
+  UINT16       SmiStsOffset;
+  UINT16       SmiEnOffset;
+  UINT16       NmiStsOffset;
+  UINT16       NmiEnOffset;
+  UINT16       PadCfgLockOffset;
+  UINT16       PadCfgLockTxOffset;
+  UINT16       PadCfgOffset;
+  UINT16       PadPerGroup;
+} GPIO_GROUP_INFO;
+
+//
+// If in GPIO_GROUP_INFO structure certain register doesn't exist
+// it will have value equal to NO_REGISTER_FOR_PROPERTY
+//
+#define NO_REGISTER_FOR_PROPERTY 0xFFFF
+
+#define GPIO_PAD_DEF(Group,Pad)                (UINT32)(((Group) << 16) + (Pad))
+#define GPIO_GROUP_DEF(GroupIndex,ChipsetId)   ((GroupIndex) | ((ChipsetId) << 8))
+#define GPIO_GET_GROUP_INDEX(Group)            ((Group) & 0x1F)
+#define GPIO_GET_GROUP_FROM_PAD(GpioPad)       (((GpioPad) & 0x0F1F0000) >> 16)
+#define GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad) GPIO_GET_GROUP_INDEX (GPIO_GET_GROUP_FROM_PAD(GpioPad))
+#define GPIO_GET_PAD_NUMBER(GpioPad)           ((GpioPad) & 0x1FF)
+#define GPIO_GET_CHIPSET_ID(GpioPad)           (((GpioPad) >> 24) & 0xF)
+
+#define GPIO_GET_PAD_POSITION(PadNumber)       ((PadNumber) % 32)
+#define GPIO_GET_DW_NUM(PadNumber)             ((PadNumber) / 32u)
+
+/**
+  This procedure will retrieve address and length of GPIO info table
+
+  @param[out]  GpioGroupInfoTableLength   Length of GPIO group table
+
+  @retval Pointer to GPIO group table
+**/
+CONST GPIO_GROUP_INFO*
+GpioGetGroupInfoTable (
+  OUT UINT32              *GpioGroupInfoTableLength
+  );
+
+typedef struct {
+  CONST CHAR8*    GpioGroupPrefix;
+  CONST GPIO_PAD  FirstUniqueGpio;
+  CONST CHAR8**   GroupUniqueNames;
+  CONST UINT32    UniqueNamesTableSize;
+} GPIO_GROUP_NAME_INFO;
+
+//
+// Helper macros for initializing GPIO_GROUP_NAME_INFO structures
+//
+#define GPIO_GROUP_NAME(GroupName,FirstUniqueGpio,GroupUniqueNamesTable) \
+  {GroupName, FirstUniqueGpio, GroupUniqueNamesTable, ARRAY_SIZE (GroupUniqueNamesTable)}
+
+#define GPIO_GROUP_NAME_BASIC(GroupName) \
+  {GroupName, 0, NULL, 0}
+
+/**
+  Get GPIO Chipset ID specific to PCH generation and series
+**/
+UINT32
+GpioGetThisChipsetId (
+  VOID
+  );
+
+/**
+  This procedure is used to check if GpioPad is valid for certain chipset
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval TRUE                    This pin is valid on this chipset
+          FALSE                   Incorrect pin
+**/
+BOOLEAN
+GpioIsCorrectPadForThisChipset (
+  IN  GPIO_PAD        GpioPad
+  );
+
+
+/**
+  This procedure is used by PchSmiDispatcher and will return information
+  needed to register GPI SMI.
+
+  @param[in]  Index                   GPI SMI number
+  @param[out] GpioPin                 GPIO pin
+  @param[out] GpiSmiBitOffset         GPI SMI bit position within GpiSmi Registers
+  @param[out] GpiHostSwOwnRegAddress  Address of HOSTSW_OWN register
+  @param[out] GpiSmiStsRegAddress     Address of GPI SMI status register
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadAndSmiRegs (
+  IN UINT32            Index,
+  OUT GPIO_PAD         *GpioPin,
+  OUT UINT8            *GpiSmiBitOffset,
+  OUT UINT32           *GpiHostSwOwnRegAddress,
+  OUT UINT32           *GpiSmiStsRegAddress
+  );
+
+/**
+  This procedure calculates Pad Configuration Register DW offset
+
+  @param[in] GpioPad                 GPIO pad
+  @param[in] DwReg                   Index of the configuration register
+
+  @retval DW Register offset
+**/
+UINT32
+GpioGetGpioPadCfgAddressFromGpioPad (
+  IN  GPIO_PAD                GpioPad,
+  IN  UINT32                  DwReg
+  );
+
+
+/**
+  This procedure will check if GpioPad argument is valid.
+  Function will check below conditions:
+   - GpioPad represents a pad for current PCH
+   - GpioPad belongs to valid GpioGroup
+   - GPIO PadNumber is not greater than number of pads for this group
+
+  @param[in] GpioPad       GPIO pad
+
+  @retval TRUE             GPIO pad is valid and can be used with GPIO lib API
+  @retval FALSE            GPIO pad is invalid and cannot be used with GPIO lib API
+**/
+BOOLEAN
+GpioIsPadValid (
+  IN GPIO_PAD             GpioPad
+  );
+
+/**
+  This procedure will read GPIO Pad Configuration register
+
+  @param[in] GpioPad          GPIO pad
+  @param[in] DwReg            Choose PADCFG register: 0:DW0, 1:DW1
+
+  @retval PadCfgRegValue      PADCFG_DWx value
+**/
+UINT32
+GpioReadPadCfgReg (
+  IN GPIO_PAD             GpioPad,
+  IN UINT8                DwReg
+  );
+
+/**
+  Check if 0x13 opcode supported for writing to GPIO lock unlock register
+
+  @retval TRUE                It's supported
+  @retval FALSE               It's not supported
+**/
+BOOLEAN
+IsGpioLockOpcodeSupported (
+  VOID
+  );
+
+/**
+  Gpio Minimum Set
+
+  Set of Gpio Minimum function to use in Pre Mem phase.
+  To optimise execution and reduce memory footprint thse minimum version
+  of 'full' functions are stripped from:
+    - GpioPad PCH validation
+    - GpioPad Group belonging validation
+    - GpioPad Host ownership validation
+    - IoStandbyState configuration
+  The use of below functions has to be careful and with full
+  understanding of all pros and cons. Please refer to GpioPrivateLib.c
+  to familiarize with details of implementation.
+**/
+
+/**
+  This procedure reads GPIO register
+
+  @param[in] GpioGroupInfo           Pointer to GPIO group table info
+  @param[in] Register                Register offset
+
+  @retval Register value or "F"s in case of errors
+**/
+UINT32
+GpioRegisterAccessRead32 (
+  IN  CONST GPIO_GROUP_INFO   *GpioGroupInfo,
+  IN  UINT32                  Register
+  );
+
+/**
+  This procedure writes GPIO register
+
+  @param[in] GpioGroupInfo           Pointer to GPIO group table info
+  @param[in] Register                Register offset
+  @param[in] AndValue                And value
+  @param[in] OrValue                 Or value
+
+  @retval EFI_DEVICE_ERROR           vGPIO BAR not programmed
+          EFI_SUCCESS                Operation completed successfully
+**/
+EFI_STATUS
+GpioRegisterAccessAndThenOr32 (
+  IN  CONST GPIO_GROUP_INFO   *GpioGroupInfo,
+  IN  UINT32                  Register,
+  IN  UINT32                  AndValue,
+  IN  UINT32                  OrValue
+  );
+
+/**
+  This procedure will calculate PADCFG register value based on GpioConfig data
+  The procedure can be various depending on chipset generation.
+  Available configuration options and corresponding registers fields
+  can distributed in different way in configuration registers.
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioConfig                GPIO Configuration data
+  @param[out] PadCfgDwReg               PADCFG DWx register value
+  @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
+
+  @retval Status
+**/
+EFI_STATUS
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  );
+
+/**
+  This procedure will write GPIO Lock/LockTx register
+  - For PCH SBI message is used.
+  - For IBL MMIO access is used.
+
+  @param[in] RegValue             GPIO register (Lock or LockTx) value
+  @param[in] RegOffset            GPIO register (Lock or LockTx) base offset
+  @param[in] DwNum                Register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in] GpioGroupInfo        Pointer to GPIO group table info
+  @param[in] GroupIndex           GPIO group index in the GpioGroupInfo table
+
+  @retval EFI_SUCCESS             The function completed successfully
+          EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+EFI_STATUS
+GpioInternalWriteLockRegister (
+  IN UINT32                 RegValue,
+  IN UINT32                 RegOffset,
+  IN UINT32                 DwNum,
+  IN CONST GPIO_GROUP_INFO  *GpioGroupInfo,
+  IN UINT32                 GroupIndex
+  );
+
+#endif // _GPIO_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c
new file mode 100644
index 0000000000..cf6f92a50d
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c
@@ -0,0 +1,546 @@
+/** @file
+  This file contains routines for GPIO initialization
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "GpioLibrary.h"
+
+//
+// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch function
+// to cache values which will be programmed into respective GPIO registers
+// after all GpioPads are processed. This way MMIO accesses are decreased
+// and instead of doing one programming for one GpioPad there is only
+// one access for whole register.
+//
+typedef struct {
+  UINT32             HostSoftOwnReg;
+  UINT32             HostSoftOwnRegMask;
+  UINT32             GpiGpeEnReg;
+  UINT32             GpiGpeEnRegMask;
+  UINT32             GpiNmiEnReg;
+  UINT32             GpiNmiEnRegMask;
+  UINT32             GpiSmiEnReg;
+  UINT32             GpiSmiEnRegMask;
+  UINT32             ConfigUnlockMask;
+  UINT32             OutputUnlockMask;
+} GPIO_GROUP_DW_DATA;
+
+//
+// GPIO_GROUP_DW_NUMBER contains number of DWords required to
+// store Pad data for all groups. Each pad uses one bit.
+//
+// For Cannonlake only vGPIO group has >32 pads but those pads
+// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be 1
+//
+#define GPIO_GROUP_DW_NUMBER  1
+
+/**
+  Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock).
+
+  @param[in]     PadNumber      GPIO pad number
+  @param[in]     GpioConfig     GPIO Config data
+  @param[in out] DwRegsValues   Values for GPIO DW Registers
+
+  @retval None
+**/
+STATIC
+VOID
+GpioDwRegValueFromGpioConfig (
+  IN UINT32                 PadNumber,
+  IN CONST GPIO_CONFIG      *GpioConfig,
+  IN OUT GPIO_GROUP_DW_DATA *GroupDwData
+  )
+{
+  UINT32  PadBitPosition;
+  UINT32  DwNum;
+
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+
+  if (DwNum >= GPIO_GROUP_DW_NUMBER) {
+    ASSERT (FALSE);
+    return;
+  }
+  //
+  // Update value to be programmed in HOSTSW_OWN register
+  //
+  GroupDwData[DwNum].HostSoftOwnRegMask |= (GpioConfig->HostSoftPadOwn & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].HostSoftOwnReg |= (GpioConfig->HostSoftPadOwn >> 0x1) << PadBitPosition;
+
+  //
+  // Update value to be programmed in GPI_GPE_EN register
+  //
+  GroupDwData[DwNum].GpiGpeEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].GpiGpeEnReg |= ((GpioConfig->InterruptConfig & GpioIntSci) >> 3) << PadBitPosition;
+
+  //
+  // Update value to be programmed in GPI_NMI_EN register
+  //
+  GroupDwData[DwNum].GpiNmiEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].GpiNmiEnReg |= ((GpioConfig->InterruptConfig & GpioIntNmi) >> 1) << PadBitPosition;
+
+  //
+  // Update value to be programmed in GPI_SMI_EN register
+  GroupDwData[DwNum].GpiSmiEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].GpiSmiEnReg |= ((GpioConfig->InterruptConfig & GpioIntSmi) >> 2) << PadBitPosition;
+  if ((GpioConfig->InterruptConfig & GpioIntSmi) == GpioIntSmi) {
+    GroupDwData[DwNum].HostSoftOwnRegMask |= 1 << PadBitPosition;
+    GroupDwData[DwNum].HostSoftOwnReg |= 1 << PadBitPosition;
+  }
+
+  //
+  // Update information on Pad Configuration Lock
+  //
+  GroupDwData[DwNum].ConfigUnlockMask |= ((GpioConfig->LockConfig >> 1) & 0x1) << PadBitPosition;
+
+  //
+  // Update information on Pad Configuration Lock Tx
+  //
+  GroupDwData[DwNum].OutputUnlockMask |= ((GpioConfig->LockConfig >> 3) & 0x1) << PadBitPosition;
+
+  //
+  // if pad in GpioMode is an output default action should be to leave output unlocked
+  //
+  if ((GpioConfig->PadMode == GpioPadModeGpio) &&
+      (GpioConfig->Direction == GpioDirOut) &&
+      ((GpioConfig->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) == GpioLockDefault)) {
+    GroupDwData[DwNum].OutputUnlockMask |= 0x1 << PadBitPosition;
+  }
+}
+
+/**
+  This internal procedure will scan GPIO initialization table and unlock
+  all pads present in it
+
+  @param[in] NumberOfItem               Number of GPIO pad records in table
+  @param[in] GpioInitTableAddress       GPIO initialization table
+  @param[in] Index                      Index of GPIO Initialization table record
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+STATIC
+EFI_STATUS
+GpioUnlockPadsForAGroup (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress,
+  IN UINT32                    Index
+  )
+{
+  UINT32                 PadsToUnlock[GPIO_GROUP_DW_NUMBER];
+  UINT32                 DwNum;
+  UINT32                 PadBitPosition;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  CONST GPIO_INIT_CONFIG *GpioData;
+  GPIO_GROUP             Group;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  GpioData   = &GpioInitTableAddress[Index];
+  Group      = GpioGetGroupFromGpioPad (GpioData->GpioPad);
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioData->GpioPad);
+
+  ZeroMem (PadsToUnlock, sizeof (PadsToUnlock));
+  //
+  // Loop through pads for one group. If pad belongs to a different group then
+  // break and move to register programming.
+  //
+  while (Index < NumberOfItems) {
+
+    GpioData   = &GpioInitTableAddress[Index];
+    if (GroupIndex != GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) {
+      //if next pad is from different group then break loop
+      break;
+    }
+
+    PadNumber  = GpioGetPadNumberFromGpioPad (GpioData->GpioPad);
+    //
+    // Check if legal pin number
+    //
+    if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+      DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for group %d\n", PadNumber, GroupIndex));
+      return EFI_INVALID_PARAMETER;
+    }
+
+    PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+    DwNum = GPIO_GET_DW_NUM (PadNumber);
+
+    if (DwNum >= GPIO_GROUP_DW_NUMBER) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    //
+    // Update pads which need to be unlocked
+    //
+    PadsToUnlock[DwNum] |= 0x1 << PadBitPosition;
+
+    //Move to next item
+    Index++;
+  }
+
+  for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1); DwNum++) {
+    //
+    // Unlock pads
+    //
+    if (PadsToUnlock[DwNum] != 0) {
+      GpioUnlockPadCfgForGroupDw (Group, DwNum, PadsToUnlock[DwNum]);
+      GpioUnlockPadCfgTxForGroupDw (Group, DwNum, PadsToUnlock[DwNum]);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will initialize multiple PCH GPIO pins
+
+  @param[in] NumberofItem               Number of GPIO pads to be updated
+  @param[in] GpioInitTableAddress       GPIO initialization table
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+STATIC
+EFI_STATUS
+GpioConfigurePch (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress
+  )
+{
+  UINT32                 Index;
+  UINT32                 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32                 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32                 PadCfgReg;
+  GPIO_GROUP_DW_DATA     GroupDwData[GPIO_GROUP_DW_NUMBER];
+  UINT32                 DwNum;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  GPIO_PAD_OWN           PadOwnVal;
+  CONST GPIO_INIT_CONFIG *GpioData;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  UINT32                 DwRegIndex;
+
+  PadOwnVal = GpioPadOwnHost;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  Index = 0;
+  while (Index < NumberOfItems) {
+
+    GpioData   = &GpioInitTableAddress[Index];
+    GroupIndex = GpioGetGroupIndexFromGpioPad (GpioData->GpioPad);
+
+    DEBUG_CODE_BEGIN();
+    if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) {
+      DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on this chipset!\n", GpioData->GpioPad));
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    DEBUG_CODE_END ();
+
+    //
+    // Unlock pads for a given group which are going to be reconfigured
+    //
+    //
+    // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, lock settings
+    // will get back to default only after G3 or DeepSx transition. On the other hand GpioPads
+    // configuration is controlled by a configurable type of reset - PadRstCfg. This means that if
+    // PadRstCfg != Powergood GpioPad will have its configuration locked despite it being not the
+    // one desired by BIOS. Before reconfiguring all pads they will get unlocked.
+    //
+    GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, Index);
+
+    ZeroMem (GroupDwData, sizeof (GroupDwData));
+    //
+    // Loop through pads for one group. If pad belongs to a different group then
+    // break and move to register programming.
+    //
+    while (Index < NumberOfItems) {
+
+      GpioData   = &GpioInitTableAddress[Index];
+      if (GroupIndex != GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) {
+        //if next pad is from different group then break loop
+        break;
+      }
+
+      PadNumber  = GpioGetPadNumberFromGpioPad (GpioData->GpioPad);
+
+      DEBUG_CODE_BEGIN ();
+      //
+      // Check if legal pin number
+      //
+      if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for group %d\n", PadNumber, GroupIndex));
+        return EFI_INVALID_PARAMETER;
+      }
+
+      //
+      // Check if selected GPIO Pad is not owned by CSME/ISH
+      //
+      GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal);
+
+      if (PadOwnVal != GpioPadOwnHost) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by host (Group=%d, Pad=%d)!\n", GroupIndex, PadNumber));
+        DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync between CSME and BIOS configuration. \n"));
+        DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should not do any configuration by BIOS.\n"));
+        //Move to next item
+        goto move_to_next_index;
+      }
+
+      //
+      // Check if Pad enabled for SCI is to be in unlocked state
+      //
+      if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) == GpioIntSci) &&
+          ((GpioData->GpioConfig.LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) != GpioPadConfigUnlock)){
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: GPIO used for SCI is not unlocked!\n"));
+        ASSERT (FALSE);
+        return EFI_INVALID_PARAMETER;
+      }
+      DEBUG_CODE_END ();
+
+      ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg));
+      ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask));
+      //
+      // Get GPIO PADCFG register value from GPIO config data
+      //
+      GpioPadCfgRegValueFromGpioConfig (
+        GpioData->GpioPad,
+        &GpioData->GpioConfig,
+        PadCfgDwReg,
+        PadCfgDwRegMask
+        );
+
+      //
+      // Write PADCFG DW0, DW1, DW2 registers
+      //
+      for (DwRegIndex = 0; DwRegIndex <= 2; DwRegIndex++) {
+        PadCfgReg = GpioGetGpioPadCfgAddressFromGpioPad (GpioData->GpioPad, DwRegIndex);
+        if (PadCfgReg != 0) {
+          GpioRegisterAccessAndThenOr32 (&GpioGroupInfo[GroupIndex], PadCfgReg, ~PadCfgDwRegMask[DwRegIndex], PadCfgDwReg[DwRegIndex]);
+        }
+      }
+
+      //
+      // Get GPIO DW register values from GPIO config data
+      //
+      GpioDwRegValueFromGpioConfig (
+        PadNumber,
+        &GpioData->GpioConfig,
+        GroupDwData
+        );
+
+    move_to_next_index:
+      //Move to next item
+      Index++;
+    }
+
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+      //
+      // Write HOSTSW_OWN registers
+      //
+      if (GpioGroupInfo[GroupIndex].HostOwnOffset != NO_REGISTER_FOR_PROPERTY) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].HostOwnOffset + DwNum * 0x4,
+          ~GroupDwData[DwNum].HostSoftOwnRegMask,
+          GroupDwData[DwNum].HostSoftOwnReg
+          );
+      }
+
+      //
+      // Write GPI_GPE_EN registers
+      //
+      if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset != NO_REGISTER_FOR_PROPERTY) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].GpiGpeEnOffset + DwNum * 0x4,
+          ~GroupDwData[DwNum].GpiGpeEnRegMask,
+          GroupDwData[DwNum].GpiGpeEnReg
+          );
+      }
+
+      //
+      // Write GPI_NMI_EN registers
+      //
+      if (GpioGroupInfo[GroupIndex].NmiEnOffset != NO_REGISTER_FOR_PROPERTY) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].NmiEnOffset + DwNum * 0x4,
+          ~GroupDwData[DwNum].GpiNmiEnRegMask,
+          GroupDwData[DwNum].GpiNmiEnReg
+          );
+      } else if (GroupDwData[DwNum].GpiNmiEnReg != 0x0) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting NMI\n", GroupIndex));
+        ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+      }
+
+      //
+      // Write GPI_SMI_EN registers
+      //
+      if (GpioGroupInfo[GroupIndex].SmiEnOffset != NO_REGISTER_FOR_PROPERTY) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].SmiEnOffset + DwNum * 0x4,
+          ~GroupDwData[DwNum].GpiSmiEnRegMask,
+          GroupDwData[DwNum].GpiSmiEnReg
+          );
+      } else if (GroupDwData[DwNum].GpiSmiEnReg != 0x0) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting SMI\n", GroupIndex));
+        ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+      }
+
+      //
+      // Update Pad Configuration unlock data
+      //
+      if (GroupDwData[DwNum].ConfigUnlockMask) {
+        GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, GroupDwData[DwNum].ConfigUnlockMask);
+      }
+
+      //
+      // Update Pad Output unlock data
+      //
+      if (GroupDwData[DwNum].OutputUnlockMask) {
+        GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, GroupDwData[DwNum].OutputUnlockMask);
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will clear all status bits of any GPIO interrupts.
+
+  @param[in] none
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+STATIC
+EFI_STATUS
+GpioClearAllGpioInterrupts (
+  VOID
+  )
+{
+  GPIO_GROUP             Group;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  GPIO_GROUP             GpioGroupLowest;
+  GPIO_GROUP             GpioGroupHighest;
+  UINT32                 GroupIndex;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 DwNum;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  GpioGroupLowest = GpioGetLowestGroup ();
+  GpioGroupHighest = GpioGetHighestGroup ();
+
+  for (Group = GpioGroupLowest; Group <= GpioGroupHighest; Group++) {
+    GroupIndex = GpioGetGroupIndexFromGroup (Group);
+    //
+    // Check if group has GPI IS register
+    //
+    if (GpioGroupInfo[GroupIndex].GpiIsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all GPI_IS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].GpiIsOffset + DwNum * 0x4,
+          ~(UINT32)0,
+          0xFFFFFFFF
+          );
+      }
+    }
+
+    //
+    // Check if group has GPI_GPE_STS register
+    //
+    if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all GPI_GPE_STS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4,
+          ~(UINT32)0,
+          0xFFFFFFFF
+          );
+      }
+    }
+
+    //
+    // Check if group has SMI_STS register
+    //
+    if (GpioGroupInfo[GroupIndex].SmiStsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all SMI_STS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].SmiStsOffset + DwNum * 4,
+          ~(UINT32)0,
+          0xFFFFFFFF
+          );
+      }
+    }
+
+    //
+    // Check if group has NMI_STS register
+    //
+    if (GpioGroupInfo[GroupIndex].NmiStsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all NMI_STS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        GpioRegisterAccessAndThenOr32 (
+          &GpioGroupInfo[GroupIndex],
+          GpioGroupInfo[GroupIndex].NmiStsOffset + DwNum * 4,
+          ~(UINT32)0,
+          0xFFFFFFFF
+          );
+      }
+    }
+
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFIG structure.
+  Structure contains fields that can be used to configure each pad.
+  Pad not configured using GPIO_INIT_CONFIG will be left with hardware default values.
+  Separate fields could be set to hardware default if it does not matter, except
+  GpioPad and PadMode.
+  Function will work in most efficient way if pads which belong to the same group are
+  placed in adjacent records of the table.
+  Although function can enable pads for Native mode, such programming is done
+  by reference code when enabling related silicon feature.
+
+  @param[in] NumberofItem               Number of GPIO pads to be updated
+  @param[in] GpioInitTableAddress       GPIO initialization table
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+EFI_STATUS
+GpioConfigurePads (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress
+  )
+{
+  EFI_STATUS   Status;
+
+  Status =  GpioConfigurePch (NumberOfItems, GpioInitTableAddress);
+
+  GpioClearAllGpioInterrupts ();
+  return Status;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c
new file mode 100644
index 0000000000..19daed97c0
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c
@@ -0,0 +1,522 @@
+/** @file
+  This file contains routines for GPIO
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "GpioLibrary.h"
+#include <Register/PchPcrRegs.h>
+
+/**
+  This procedure will check if GpioGroup argument is correct and
+  supplied DW reg number can be used for this group to access DW registers.
+  Function will check below conditions:
+   - Valid GpioGroup
+   - DwNum is has valid value for this group
+
+  @param[in] Group        GPIO group
+  @param[in] DwNum        Register number for current group (parameter applicable in accessing whole register).
+                          For group which has less then 32 pads per group DwNum must be 0.
+
+  @retval TRUE             DW Reg number and GpioGroup is valid
+  @retval FALSE            DW Reg number and GpioGroup is invalid
+**/
+STATIC
+BOOLEAN
+GpioIsGroupAndDwNumValid (
+  IN GPIO_GROUP             Group,
+  IN UINT32                 DwNum
+  )
+{
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup ()) || (GroupIndex >= GpioGroupInfoLength)) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not within range of possible groups for this PCH\n", GroupIndex));
+    goto Error;
+  }
+
+  //
+  // Check if DwNum argument does not exceed number of DWord registers
+  // resulting from available pads for certain group
+  //
+  if (DwNum > GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1)){
+    goto Error;
+  }
+
+  return TRUE;
+Error:
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+//
+// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() functions
+//
+typedef enum {
+  GpioHostOwnershipRegister = 0,
+  GpioGpeEnableRegister,
+  GpioGpeStatusRegister,
+  GpioSmiEnableRegister,
+  GpioSmiStatusRegister,
+  GpioNmiEnableRegister,
+  GpioPadConfigLockRegister,
+  GpioPadLockOutputRegister
+} GPIO_REG;
+
+/**
+  This procedure will read GPIO register
+
+  @param[in] RegType              GPIO register type
+  @param[in] Group                GPIO group
+  @param[in] DwNum                Register number for current group (parameter applicable in accessing whole register).
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] ReadVal             Read data
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+STATIC
+EFI_STATUS
+GpioReadReg (
+  IN GPIO_REG               RegType,
+  IN GPIO_GROUP             Group,
+  IN UINT32                 DwNum,
+  OUT UINT32                *ReadVal
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  RegOffset = NO_REGISTER_FOR_PROPERTY;
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  switch (RegType) {
+    case GpioHostOwnershipRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset;
+      break;
+    case GpioGpeEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeEnOffset;
+      break;
+    case GpioGpeStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeStsOffset;
+      break;
+    case GpioSmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiEnOffset;
+      break;
+    case GpioSmiStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
+      break;
+    case GpioNmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
+      break;
+    case GpioPadConfigLockRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockOffset;
+      break;
+    case GpioPadLockOutputRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockTxOffset;
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // If there are more then 32 pads per group then certain
+  // group information would be split into more then one DWord register.
+  //
+  if ((RegType == GpioPadConfigLockRegister) || (RegType == GpioPadLockOutputRegister)) {
+    //
+    // PadConfigLock and OutputLock registers when used for group containing more than 32 pads
+    // are not placed in a continuous way, e.g:
+    // 0x0 - PadConfigLock_DW0
+    // 0x4 - OutputLock_DW0
+    // 0x8 - PadConfigLock_DW1
+    // 0xC - OutputLock_DW1
+    //
+    RegOffset += DwNum * 0x8;
+  } else {
+    RegOffset += DwNum * 0x4;
+  }
+
+  *ReadVal = GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], RegOffset);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will write GPIO register
+
+  @param[in] RegType              GPIO register type
+  @param[in] Group                GPIO group
+  @param[in] DwNum                Register number for current group (parameter applicable in accessing whole register).
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in] RegAndMask           Mask which will be AND'ed with register value
+  @param[in] RegOrMask            Mask which will be OR'ed with register value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+STATIC
+EFI_STATUS
+GpioWriteReg (
+  IN GPIO_REG               RegType,
+  IN GPIO_GROUP             Group,
+  IN UINT32                 DwNum,
+  IN UINT32                 RegAndMask,
+  IN UINT32                 RegOrMask
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 PadCfgLock;
+  BOOLEAN                Lockable;
+
+  Lockable = FALSE;
+  PadCfgLock = 0;
+  RegOffset = NO_REGISTER_FOR_PROPERTY;
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  switch (RegType) {
+    case GpioHostOwnershipRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset;
+      break;
+    case GpioGpeEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeEnOffset;
+      Lockable = TRUE;
+      break;
+    case GpioGpeStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeStsOffset;
+      break;
+    case GpioSmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiEnOffset;
+      Lockable = TRUE;
+      break;
+    case GpioSmiStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
+      break;
+    case GpioNmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
+      Lockable = TRUE;
+      break;
+    case GpioPadConfigLockRegister:
+    case GpioPadLockOutputRegister:
+    default:
+      break;
+  }
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Lockable) {
+    GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock);
+    if (PadCfgLock) {
+      //
+      // Check if for pads which are going to be reconfigured lock is set.
+      //
+      if ((~RegAndMask | RegOrMask) & PadCfgLock) {
+        //
+        // Unlock all pads for this Group DW reg for simplicity
+        // even if not all of those pads will have their settings reprogrammed
+        //
+        GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+      } else {
+        //
+        // No need to perform an unlock as pads which are going to be reconfigured
+        // are not in locked state
+        //
+        PadCfgLock = 0;
+      }
+    }
+  }
+
+  //
+  // If there are more then 32 pads per group then certain
+  // group information would be split into more then one DWord register.
+  //
+  RegOffset += DwNum * 0x4;
+
+  GpioRegisterAccessAndThenOr32 (&GpioGroupInfo[GroupIndex], RegOffset, RegAndMask,RegOrMask);
+
+  if (Lockable && PadCfgLock) {
+    //
+    // Lock previously unlocked pads
+    //
+    GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will write GPIO Lock/LockTx register using SBI.
+
+  @param[in] RegType              GPIO register (Lock or LockTx)
+  @param[in] Group                GPIO group number
+  @param[in] DwNum                Register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in] LockRegAndMask       Mask which will be AND'ed with Lock register value
+  @param[in] LockRegOrMask        Mask which will be Or'ed with Lock register value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+STATIC
+EFI_STATUS
+GpioWriteLockReg (
+  IN GPIO_REG                  RegType,
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    LockRegAndMask,
+  IN UINT32                    LockRegOrMask
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 RegOffset;
+  UINT32                 OldLockVal;
+  UINT32                 NewLockVal;
+  UINT32                 GroupIndex;
+
+  OldLockVal = 0;
+  NewLockVal = 0;
+
+  RegOffset = NO_REGISTER_FOR_PROPERTY;
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  switch (RegType) {
+    case GpioPadConfigLockRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockOffset;
+      GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal);
+      break;
+    case GpioPadLockOutputRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockTxOffset;
+      GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_UNSUPPORTED;
+  }
+
+  NewLockVal = (OldLockVal & LockRegAndMask) | LockRegOrMask;
+
+  return GpioInternalWriteLockRegister (NewLockVal, RegOffset, DwNum, GpioGroupInfo, GroupIndex);
+}
+
+/**
+  This procedure will get Gpio Pad Ownership
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] PadOwnVal           Value of Pad Ownership
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadOwnership (
+  IN  GPIO_PAD                GpioPad,
+  OUT GPIO_PAD_OWN            *PadOwnVal
+  )
+{
+  UINT32                 Mask;
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 PadOwnRegValue;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Check if selected register exists
+  //
+  if (GpioGroupInfo[GroupIndex].PadOwnOffset == NO_REGISTER_FOR_PROPERTY) {
+    *PadOwnVal = GpioPadOwnHost;
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Calculate RegOffset using Pad Ownership offset and GPIO Pad number.
+  // One DWord register contains information for 8 pads.
+  //
+  RegOffset = GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4;
+
+  //
+  // Calculate pad bit position within DWord register
+  //
+  PadNumber %= 8;
+  Mask = (BIT1 | BIT0) << (PadNumber * 4);
+
+  PadOwnRegValue = GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], RegOffset);
+
+  *PadOwnVal = (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> (PadNumber * 4));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will check state of Pad Config Lock for pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] PadCfgLockRegVal    Value of PadCfgLock register
+                                  Bit position - PadNumber
+                                  Bit value - 0: NotLocked, 1: Locked
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetPadCfgLockForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *PadCfgLockRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioReadReg (
+           GpioPadConfigLockRegister,
+           Group,
+           DwNum,
+           PadCfgLockRegVal
+           );
+}
+/**
+  This procedure will check state of Pad Config Tx Lock for pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLockTx register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] PadCfgLockTxRegVal  Value of PadCfgLockTx register
+                                  Bit position - PadNumber
+                                  Bit value - 0: NotLockedTx, 1: LockedTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetPadCfgLockTxForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *PadCfgLockTxRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioReadReg (
+           GpioPadLockOutputRegister,
+           Group,
+           DwNum,
+           PadCfgLockTxRegVal
+           );
+}
+/**
+  This procedure will clear PadCfgLock for selected pads within one group.
+  This function should be used only inside SMI.
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToUnlock        Bitmask for pads which are going to be unlocked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotUnlock, 1: Unlock
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgForGroupDw (
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    PadsToUnlock
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioWriteLockReg (
+           GpioPadConfigLockRegister,
+           Group,
+           DwNum,
+           ~PadsToUnlock,
+           0
+           );
+}
+/**
+  This procedure will clear PadCfgLockTx for selected pads within one group.
+  This function should be used only inside SMI.
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLockTx register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToUnlockTx      Bitmask for pads which are going to be unlocked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotUnLockTx, 1: LockTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgTxForGroupDw (
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    PadsToUnlockTx
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioWriteLockReg (
+           GpioPadLockOutputRegister,
+           Group,
+           DwNum,
+           ~PadsToUnlockTx,
+           0
+           );
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h
new file mode 100644
index 0000000000..2c2b4ee75c
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h
@@ -0,0 +1,29 @@
+/** @file
+  Header file for GPIO Lib implementation.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_LIBRARY_H_
+#define _GPIO_LIBRARY_H_
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcPrivateLib.h>
+#include <Library/GpioHelpersLib.h>
+#include <Register/GpioRegs.h>
+
+//
+// Number of PADCFG_DW registers
+//
+#define GPIO_PADCFG_DW_REG_NUMBER  4
+
+#endif // _GPIO_LIBRARY_H_
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
new file mode 100644
index 0000000000..4e4c53e588
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
@@ -0,0 +1,177 @@
+/** @file
+  This file contains routines for GPIO native and chipset specific usage
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "GpioLibrary.h"
+
+/**
+  This procedure will get number of pads for certain GPIO group
+
+  @param[in] Group            GPIO group number
+
+  @retval Value               Pad number for group
+                              If illegal group number then return 0
+**/
+UINT32
+GpioGetPadPerGroup (
+  IN GPIO_GROUP      Group
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+  //
+  // Check if group argument exceeds GPIO GROUP INFO array
+  //
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
+    return 0;
+  } else {
+    return GpioGroupInfo[GroupIndex].PadPerGroup;
+  }
+}
+
+/**
+  This procedure will get number of groups
+
+  @param[in] none
+
+  @retval Value               Group number
+**/
+UINT32
+GpioGetNumberOfGroups (
+  VOID
+  )
+{
+  UINT32                 GpioGroupInfoLength;
+
+  GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  return GpioGroupInfoLength;
+}
+/**
+  This procedure will get lowest group
+
+  @param[in] none
+
+  @retval Value               Lowest Group
+**/
+GPIO_GROUP
+GpioGetLowestGroup (
+  VOID
+  )
+{
+  return GpioGetGroupFromGroupIndex (0);
+}
+/**
+  This procedure will get highest group
+
+  @param[in] none
+
+  @retval Value               Highest Group
+**/
+GPIO_GROUP
+GpioGetHighestGroup (
+  VOID
+  )
+{
+  return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1);
+}
+
+/**
+  This procedure will get group number
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Group number
+**/
+GPIO_GROUP
+GpioGetGroupFromGpioPad (
+  IN GPIO_PAD         GpioPad
+  )
+{
+  return GPIO_GET_GROUP_FROM_PAD (GpioPad);
+}
+
+/**
+  This procedure will get group index (0 based)
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Group Index
+**/
+UINT32
+GpioGetGroupIndexFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  )
+{
+  return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad);
+}
+
+/**
+  This procedure will get group index (0 based) from group
+
+  @param[in] GpioGroup        Gpio Group
+
+  @retval Value               Group Index
+**/
+UINT32
+GpioGetGroupIndexFromGroup (
+  IN GPIO_GROUP        GpioGroup
+  )
+{
+  return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup);
+}
+
+/**
+  This procedure will get group from group index (0 based)
+
+  @param[in] GroupIndex        Group Index
+
+  @retval GpioGroup            Gpio Group
+**/
+GPIO_GROUP
+GpioGetGroupFromGroupIndex (
+  IN UINT32        GroupIndex
+  )
+{
+  return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ());
+}
+
+/**
+  This procedure will get pad number (0 based) from Gpio Pad
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Pad Number
+**/
+UINT32
+GpioGetPadNumberFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  )
+{
+  return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad);
+}
+/**
+  This procedure will return GpioPad from Group and PadNumber
+
+  @param[in] Group              GPIO group
+  @param[in] PadNumber          GPIO PadNumber
+
+  @retval GpioPad               GpioPad
+**/
+GPIO_PAD
+GpioGetGpioPadFromGroupAndPadNumber (
+  IN GPIO_GROUP      Group,
+  IN UINT32          PadNumber
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_PAD_DEF (Group,PadNumber);
+  } else {
+    return GPIO_PAD_DEF (Group,PadNumber);
+  }
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
new file mode 100644
index 0000000000..21fb4417c1
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for the PeiDxeSmmGpioLib
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmGpioLib
+FILE_GUID = 16EC5CA8-8195-4847-B6CB-662BD7B763F2
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GpioLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PrintLib
+PchCycleDecodingLib
+PchSbiAccessLib
+PmcPrivateLib
+GpioPrivateLib
+GpioHelpersLib
+
+[Packages]
+MdePkg/MdePkg.dec
+AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+GpioLib.c
+GpioNativeLib.c
+GpioInit.c
+GpioLibrary.h
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
new file mode 100644
index 0000000000..b4b6c14329
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
@@ -0,0 +1,51 @@
+/** @file
+  This file contains NULL implementation for GPIO Helpers Lib
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/GpioConfig.h>
+
+/**
+  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;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
new file mode 100644
index 0000000000..91d81af4b9
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
@@ -0,0 +1,25 @@
+## @file
+# Component description file for the NULL GpioHelpersLib
+#
+#   Copyright (c) 2022, 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
+AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseGpioHelpersLibNull.c
+
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
new file mode 100644
index 0000000000..480990cb62
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
@@ -0,0 +1,48 @@
+/** @file
+  Header file for GPIO Private Lib Internal functions.
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
+#define _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
+
+#include <Library/GpioPrivateLib.h>
+
+
+/**
+  This function provides recommended GPIO IO Standby configuration for a given native function
+
+  @param[in]  PadFunction            PadFunction for a specific native signal. Please refer to GpioNativePads.h
+  @param[out] StandbyState           IO Standby State for specified native function
+  @param[out] StandbyTerm            IO Standby Termination for specified native function
+
+  @retval Status
+**/
+EFI_STATUS
+GpioGetFunctionIoStandbyConfig (
+  IN  UINT32                PadFunction,
+  OUT GPIO_IOSTANDBY_STATE  *StandbyState,
+  OUT GPIO_IOSTANDBY_TERM   *StandbyTerm
+  );
+
+/**
+  This procedure will calculate PADCFG register value based on GpioConfig data
+  For physical/local/hard (not virtual) GPIO pads
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioConfig                GPIO Configuration data
+  @param[out] PadCfgDwReg               PADCFG DWx register value
+  @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
+
+  @retval Status
+**/
+EFI_STATUS
+GpioPadCfgRegValueFromGpioConfigHardGpio (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  );
+
+#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
new file mode 100644
index 0000000000..7d5fa9fafd
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
@@ -0,0 +1,267 @@
+/** @file
+  This file contains GPIO routines for RC usage
+
+   Copyright (c) 2022, 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/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioNativePads.h>
+#include <Register/GpioRegs.h>
+#include "GpioNativePrivateLibInternal.h"
+
+/**
+  This procedure is used to check if GpioPad is valid for certain chipset
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval TRUE                    This pin is valid on this chipset
+          FALSE                   Incorrect pin
+**/
+BOOLEAN
+GpioIsCorrectPadForThisChipset (
+  IN  GPIO_PAD        GpioPad
+  )
+{
+  return ((GPIO_GET_CHIPSET_ID (GpioPad) == GpioGetThisChipsetId ()) &&
+         (GpioGetGroupIndexFromGpioPad (GpioPad) < GpioGetNumberOfGroups ()));
+}
+
+/**
+  This procedure is used by PchSmiDispatcher and will return information
+  needed to register GPI SMI.
+
+  @param[in]  Index                   GPI SMI number
+  @param[out] GpioPin                 GPIO pin
+  @param[out] GpiSmiBitOffset         GPI SMI bit position within GpiSmi Registers
+  @param[out] GpiHostSwOwnRegAddress  Address of HOSTSW_OWN register
+  @param[out] GpiSmiStsRegAddress     Address of GPI SMI status register
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadAndSmiRegs (
+  IN UINT32            Index,
+  OUT GPIO_PAD         *GpioPin,
+  OUT UINT8            *GpiSmiBitOffset,
+  OUT UINT32           *GpiHostSwOwnRegAddress,
+  OUT UINT32           *GpiSmiStsRegAddress
+  )
+{
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  GPIO_GROUP             GpioGroup;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 SmiStsRegOffset;
+  UINT32                 HostSwOwnRegOffset;
+  GPIO_PAD_OWN           PadOwnVal;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  PadNumber = 0;
+  GroupIndex = 0;
+  for (GroupIndex = 0; GroupIndex < GpioGroupInfoLength; GroupIndex++) {
+    PadNumber = Index;
+    if (PadNumber < GpioGroupInfo[GroupIndex].PadPerGroup) {
+      //
+      // Found group and pad number
+      //
+      break;
+    }
+    Index = Index - GpioGroupInfo[GroupIndex].PadPerGroup;
+  }
+
+  //
+  // Check if legal pad number
+  //
+  if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check if selected group has GPI SMI Enable and Status registers
+  //
+  if (GpioGroupInfo[GroupIndex].SmiEnOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioGroup = GpioGetGroupFromGroupIndex (GroupIndex);
+  *GpioPin = GpioGetGpioPadFromGroupAndPadNumber (GpioGroup, PadNumber);
+
+  DEBUG_CODE_BEGIN ();
+  //
+  // Check if selected GPIO Pad is not owned by CSME/ISH/IE
+  //
+  GpioGetPadOwnership (*GpioPin, &PadOwnVal);
+  if (PadOwnVal != GpioPadOwnHost) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: GPIO not owned by host!\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  DEBUG_CODE_END ();
+
+  *GpiSmiBitOffset = (UINT8)(PadNumber % 32);
+
+  HostSwOwnRegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset + (PadNumber / 32) * 0x4;
+  *GpiHostSwOwnRegAddress = PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, HostSwOwnRegOffset);
+
+  SmiStsRegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset + (PadNumber / 32) * 0x4;
+  *GpiSmiStsRegAddress = PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, SmiStsRegOffset);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will check if GpioPad argument is valid.
+  Function will check below conditions:
+   - GpioPad represents a pad for current PCH
+   - GpioPad belongs to valid GpioGroup
+   - GPIO PadNumber is not greater than number of pads for this group
+
+  @param[in] GpioPad       GPIO pad
+
+  @retval TRUE             GPIO pad is valid and can be used with GPIO lib API
+  @retval FALSE            GPIO pad is invalid and cannot be used with GPIO lib API
+**/
+BOOLEAN
+GpioIsPadValid (
+  IN GPIO_PAD             GpioPad
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 PadNumber;
+  UINT32                 GroupIndex;
+
+  if (!GpioIsCorrectPadForThisChipset (GpioPad)) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on this chipset!\n", GpioPad));
+    goto Error;
+  }
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Check if legal pin number
+  //
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds range of group (max: %d)\n",
+                                                                                   PadNumber,
+                                                                                   GpioGroupInfo[GroupIndex].PadPerGroup));
+    goto Error;
+  }
+
+  return TRUE;
+Error:
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  This procedure will read GPIO Pad Configuration register
+
+  @param[in] GpioPad          GPIO pad
+  @param[in] DwReg            Choose PADCFG register: 0:DW0, 1:DW1
+
+  @retval PadCfgRegValue      PADCFG_DWx value
+**/
+UINT32
+GpioReadPadCfgReg (
+  IN GPIO_PAD             GpioPad,
+  IN UINT8                DwReg
+  )
+{
+  UINT32                 PadCfgReg;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Create Pad Configuration register offset
+  //
+  PadCfgReg = GpioGetGpioPadCfgAddressFromGpioPad (GpioPad, DwReg);
+  return GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], PadCfgReg);
+}
+
+
+/**
+  This procedure will calculate PADCFG register value based on GpioConfig data
+  For physical/local/hard (not virtual) GPIO pads
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioConfig                GPIO Configuration data
+  @param[out] PadCfgDwReg               PADCFG DWx register value
+  @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
+
+  @retval Status
+**/
+EFI_STATUS
+GpioPadCfgRegValueFromGpioConfigHardGpio (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  )
+{
+  //
+  // Configure how interrupt is triggered (RxEvCfg)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RX_LVL_EDG);
+  PadCfgDwReg[0] |= (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG);
+
+  //
+  // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) == GpioHardwareDefault)  ? 0x0 : (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE));
+  PadCfgDwReg[0] |= (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PCR_RX_NMI_ROUTE);
+
+  //
+  // Configure GPIO direction (GPIORxDis and GPIOTxDis)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK) >> N_GPIO_DIRECTION_DIR_BIT_POS) == GpioHardwareDefault) ? 0x0 : (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS));
+  PadCfgDwReg[0] |= (((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK) >> (N_GPIO_DIRECTION_DIR_BIT_POS + 1)) << N_GPIO_PCR_TXDIS);
+
+  //
+  // Configure GPIO input inversion (RXINV)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) == GpioHardwareDefault) ?  0x0 : B_GPIO_PCR_RXINV);
+  PadCfgDwReg[0] |= (((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK) >> (N_GPIO_DIRECTION_INV_BIT_POS + 1)) << N_GPIO_PCR_RXINV);
+
+  //
+  // Configure GPIO output state (GPIOTxState)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> N_GPIO_OUTPUT_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TX_STATE);
+  PadCfgDwReg[0] |= (((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> (N_GPIO_OUTPUT_BIT_POS + 1)) << N_GPIO_PCR_TX_STATE);
+
+  //
+  // Configure GPIO RX raw override to '1' (RXRAW1)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RX_RAW1);
+  PadCfgDwReg[0] |= (((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << N_GPIO_PCR_RX_RAW1);
+
+  //
+  // Configure GPIO Pad Mode (PMode)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> N_GPIO_PAD_MODE_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_PAD_MODE);
+  PadCfgDwReg[0] |= (((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE);
+
+  //
+  // Configure GPIO termination (Term)
+  //
+  PadCfgDwRegMask[1] |= ((((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM);
+  PadCfgDwReg[1] |= (((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << N_GPIO_PCR_TERM);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c
new file mode 100644
index 0000000000..3d16fd2acd
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c
@@ -0,0 +1,172 @@
+/** @file
+  This file contains hard/physical/local (not virtual) GPIO information
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Register/GpioRegs.h>
+#include "GpioNativePrivateLibInternal.h"
+
+/**
+  This procedure calculates Pad Configuration Register DW offset
+
+  @param[in] GpioPad                 GPIO pad
+  @param[in] DwReg                   Index of the configuration register
+
+  @retval DW Register offset
+**/
+UINT32
+GpioGetGpioPadCfgAddressFromGpioPad (
+  IN  GPIO_PAD                GpioPad,
+  IN  UINT32                  DwReg
+  )
+{
+  UINT32                 PadCfgRegAddress;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Create Pad Configuration register offset
+  //
+  PadCfgRegAddress = GpioGroupInfo[GroupIndex].PadCfgOffset + DwReg * 4 + S_GPIO_PCR_PADCFG * PadNumber;
+
+  return PadCfgRegAddress;
+}
+
+/**
+  This procedure reads GPIO register
+
+  @param[in] GpioGroupInfo           Pointer to GPIO group table info
+  @param[in] Register                Register offset
+
+  @retval Register value or "F"s in case of errors
+**/
+UINT32
+GpioRegisterAccessRead32 (
+  IN  CONST GPIO_GROUP_INFO   *GpioGroupInfo,
+  IN  UINT32                  Register
+  )
+{
+  return MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo->Community, Register));
+}
+
+/**
+  This procedure writes GPIO register
+
+  @param[in] GpioGroupInfo           Pointer to GPIO group table info
+  @param[in] Register                Register offset
+  @param[in] AndValue                And value
+  @param[in] OrValue                 Or value
+
+  @retval EFI_SUCCESS                Operation completed successfully
+**/
+EFI_STATUS
+GpioRegisterAccessAndThenOr32 (
+  IN  CONST GPIO_GROUP_INFO   *GpioGroupInfo,
+  IN  UINT32                  Register,
+  IN  UINT32                  AndValue,
+  IN  UINT32                  OrValue
+  )
+{
+  MmioAndThenOr32 (
+    PCH_PCR_ADDRESS (GpioGroupInfo->Community, Register),
+    AndValue,
+    OrValue
+    );
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will calculate PADCFG register value based on GpioConfig data
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioConfig                GPIO Configuration data
+  @param[out] PadCfgDwReg               PADCFG DWx register value
+  @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
+
+  @retval Status
+**/
+EFI_STATUS
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  )
+{
+  return GpioPadCfgRegValueFromGpioConfigHardGpio (GpioPad, GpioConfig, PadCfgDwReg, PadCfgDwRegMask);
+}
+
+/**
+  This procedure will write GPIO Lock/LockTx register
+  - For PCH SBI message is used.
+
+  @param[in] RegValue             GPIO register (Lock or LockTx) value
+  @param[in] RegOffset            GPIO register (Lock or LockTx) base offset
+  @param[in] DwNum                Register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in] GpioGroupInfo        Pointer to GPIO group table info
+  @param[in] GroupIndex           GPIO group index in the GpioGroupInfo table
+
+  @retval EFI_SUCCESS             The function completed successfully
+          EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+EFI_STATUS
+GpioInternalWriteLockRegister (
+  IN UINT32                 RegValue,
+  IN UINT32                 RegOffset,
+  IN UINT32                 DwNum,
+  IN CONST GPIO_GROUP_INFO  *GpioGroupInfo,
+  IN UINT32                 GroupIndex
+  )
+{
+  EFI_STATUS             Status;
+  PCH_SBI_OPCODE         Opcode;
+  UINT8                  Response;
+
+  //
+  // If there are more then 32 pads per group then certain
+  // group information would be split into more then one DWord register.
+  // PadConfigLock and OutputLock registers when used for group containing more than 32 pads
+  // are not placed in a continuous way, e.g:
+  // 0x0 - PadConfigLock_DW0
+  // 0x4 - OutputLock_DW0
+  // 0x8 - PadConfigLock_DW1
+  // 0xC - OutputLock_DW1
+  //
+  RegOffset += DwNum * 0x8;
+
+  if (IsGpioLockOpcodeSupported ()) {
+    Opcode = GpioLockUnlock;
+  } else {
+    Opcode = PrivateControlWrite;
+  }
+
+  Status = PchSbiExecutionEx (
+             GpioGroupInfo[GroupIndex].Community,
+             RegOffset,
+             Opcode,
+             FALSE,
+             0x000F,
+             0x0000,
+             0x0000,
+             &RegValue,
+             &Response
+             );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c
new file mode 100644
index 0000000000..1348643553
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c
@@ -0,0 +1,81 @@
+/** @file
+  This file contains VER2 specific GPIO information
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioNativePads.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioHelpersLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Register/GpioRegsVer2.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/GpioRegs.h>
+#include <Pins/GpioPinsVer2Lp.h>
+#include <GpioNativePrivateLibInternal.h>
+#include <Library/PcdLib.h>
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] = {
+  {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_B_PAD_MAX}, //TGL PCH-LP GPP_B
+  {PID_GPIOCOM0, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_A_PAD_MAX}, //TGL PCH-LP GPP_A
+  {PID_GPIOCOM5, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_R_PAD_MAX}, //TGL PCH-LP GPP_R
+  {PID_GPIOCOM5, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM2, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN,    R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN,    R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IS,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IE,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK,    R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX,     R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET,    GPIO_VER2_PCH_LP_GPIO_GPD_PAD_MAX},   //TGL PCH-LP GPD
+  {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_S_PAD_MAX}, //TGL PCH-LP GPP_S
+  {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,            R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_H_PAD_MAX}, //TGL PCH-LP GPP_H
+  {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_D_PAD_MAX}, //TGL PCH-LP GPP_D
+  {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_C_PAD_MAX}, //TGL PCH-LP GPP_C
+  {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_F_PAD_MAX}, //TGL PCH-LP GPP_F
+  {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_E_PAD_MAX}, //TGL PCH-LP GPP_E
+};
+
+/**
+  This procedure will retrieve address and length of GPIO info table
+
+  @param[out]  GpioGroupInfoTableLength   Length of GPIO group table
+
+  @retval Pointer to GPIO group table
+
+**/
+CONST GPIO_GROUP_INFO*
+GpioGetGroupInfoTable (
+  OUT UINT32              *GpioGroupInfoTableLength
+  )
+{
+  *GpioGroupInfoTableLength = ARRAY_SIZE (mPchLpGpioGroupInfo);
+  return mPchLpGpioGroupInfo;
+}
+
+/**
+  Get GPIO Chipset ID specific to PCH generation and series
+**/
+UINT32
+GpioGetThisChipsetId (
+  VOID
+  )
+{
+    return GPIO_VER2_LP_CHIPSET_ID;
+}
+
+/**
+  Check if 0x13 opcode supported for writing to GPIO lock unlock register
+
+  @retval TRUE                It's supported
+  @retval FALSE               It's not supported
+**/
+BOOLEAN
+IsGpioLockOpcodeSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
new file mode 100644
index 0000000000..2e9a6b7336
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
@@ -0,0 +1,40 @@
+## @file
+#  Component description file for the PeiDxeSmmGpioPrivateLib
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmGpioPrivateLibVer2
+FILE_GUID                      = 680A81B0-A087-4687-B5B4-146DA30042D6
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = GpioPrivateLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  PmcLib
+  PchInfoLib
+  GpioLib
+  GpioHelpersLib
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  GpioPrivateLib.c
+  GpioPrivateLibVer2.c
+  GpioPrivateLibPch.c
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c
new file mode 100644
index 0000000000..9d47e6bfd5
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c
@@ -0,0 +1,218 @@
+/** @file
+  This file contains routines for PEI GPIO Helpers Lib
+
+   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/HobLib.h>
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioHelpersLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+
+extern EFI_GUID gGpioLibUnlockHobGuid;
+
+//
+//  GPIO Lock HOB
+//  Stores information on GPIO pads that should be left unlocked
+//
+typedef struct {
+  //
+  // GPIO PadConfig unlock data
+  //
+  UINT32  PadConfig;
+  //
+  // GPIO Output unlock data
+  //
+  UINT32  OutputState;
+} GPIO_UNLOCK_HOB_DATA;
+
+/**
+  This procedure will get index of GPIO Unlock HOB structure for selected GroupIndex and DwNum.
+
+  @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 GpioUnlockHobIndex
+**/
+STATIC
+UINT32
+GpioUnlockDataIndex (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  )
+{
+  UINT32         GpioUnlockDataIndex;
+  UINT32         Index;
+
+  GpioUnlockDataIndex = 0;
+
+  for (Index = 0; Index < GroupIndex; Index++) {
+    GpioUnlockDataIndex += GPIO_GET_DW_NUM (GpioGetPadPerGroup (GpioGetGroupFromGroupIndex (Index))) + 1;
+  }
+
+  GpioUnlockDataIndex += DwNum;
+  return GpioUnlockDataIndex;
+}
+
+/**
+  This procedure will create GPIO HOB for storing unlock data
+
+  @retval Pointer to GPIO Unlock data structure
+**/
+STATIC
+GPIO_UNLOCK_HOB_DATA*
+GpioCreateUnlockData (
+  VOID
+  )
+{
+  VOID           *HobData;
+  GPIO_GROUP     Group;
+  GPIO_GROUP     GroupMin;
+  GPIO_GROUP     GroupMax;
+  UINT32         GpioUnlockDataRecords;
+
+  GroupMin = GpioGetLowestGroup ();
+  GroupMax = GpioGetHighestGroup ();
+  GpioUnlockDataRecords = 0;
+
+  for (Group = GroupMin; Group <= GroupMax; Group++) {
+    GpioUnlockDataRecords += GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)) + 1;
+  }
+
+  HobData = BuildGuidHob (&gGpioLibUnlockHobGuid, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA));
+  if (HobData == NULL) {
+    return NULL;
+  }
+
+  ZeroMem (HobData, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA));
+
+  return (GPIO_UNLOCK_HOB_DATA*)HobData;
+}
+
+/**
+  This procedure will Get GPIO Unlock data structure for storing unlock data.
+  If HOB doesn't exist it will be created.
+
+  @param[out] GpioUnlockData          pointer to GPIO Unlock data structure
+
+  @retval Length                      number of GPIO unlock data records
+**/
+STATIC
+UINT32
+GpioGetUnlockData (
+  GPIO_UNLOCK_HOB_DATA  **GpioUnlockData
+  )
+{
+  VOID  *Hob;
+
+  Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid);
+  if (Hob == NULL) {
+    //
+    // It is the first time this function is used so create the HOB
+    //
+    *GpioUnlockData = GpioCreateUnlockData ();
+    if (*GpioUnlockData == NULL) {
+      return 0;
+    }
+    Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid);
+  } else {
+    *GpioUnlockData = (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA (Hob);
+  }
+  return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (GPIO_UNLOCK_HOB_DATA);
+}
+
+/**
+  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
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               Index;
+
+  if (UnlockedPads == 0) {
+    //
+    // No pads to be left unlocked
+    //
+    return EFI_SUCCESS;
+  }
+
+  Length = GpioGetUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = GpioUnlockDataIndex (GroupIndex, DwNum);
+  if (Index >= Length) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioUnlockData[Index].PadConfig |= 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
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               Index;
+
+  if (UnlockedPads == 0) {
+    //
+    // No pads to be left unlocked
+    //
+    return EFI_SUCCESS;
+  }
+
+  Length = GpioGetUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = GpioUnlockDataIndex (GroupIndex, DwNum);
+  if (Index >= Length) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioUnlockData[Index].OutputState |= UnlockedPads;
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
new file mode 100644
index 0000000000..c1886b22f9
--- /dev/null
+++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Component description file for the PeiGpioHelpersLib
+#
+#   Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+#   SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiGpioHelpersLib
+FILE_GUID = 1838E1E7-3CC4-4A74-90D9-B421EF2A579F
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = GpioHelpersLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+HobLib
+GpioLib
+ConfigBlockLib
+PeiServicesLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+AlderlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiGpioHelpersLib.c
+
+
+[Guids]
+gGpioLibUnlockHobGuid
+
+[Ppis]
+gSiPreMemPolicyPpiGuid
-- 
2.36.1.windows.1



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




More information about the edk2-devel-archive mailing list