[edk2-devel] [edk2-platforms] [PATCH V1 11/17] WhitleyOpenBoardPkg: Add Platform Modules

Nate DeSimone nathaniel.l.desimone at intel.com
Tue Jul 13 00:41:25 UTC 2021


Signed-off-by: Nate DeSimone <nathaniel.l.desimone at intel.com>
Co-authored-by: Isaac Oram <isaac.w.oram at intel.com>
Co-authored-by: Mohamed Abbas <mohamed.abbas at intel.com>
Cc: Chasel Chiu <chasel.chiu at intel.com>
Cc: Michael D Kinney <michael.d.kinney at intel.com>
Cc: Isaac Oram <isaac.w.oram at intel.com>
Cc: Mohamed Abbas <mohamed.abbas at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
Cc: Eric Dong <eric.dong at intel.com>
Cc: Michael Kubacki <Michael.Kubacki at microsoft.com>
---
 .../WhitleyOpenBoardPkg/BiosInfo/BiosInfo.c   | 104 +++
 .../WhitleyOpenBoardPkg/BiosInfo/BiosInfo.h   |  67 ++
 .../WhitleyOpenBoardPkg/BiosInfo/BiosInfo.inf |  70 ++
 .../Dxe/PlatformCpuPolicy/PlatformCpuPolicy.c | 704 ++++++++++++++++
 .../PlatformCpuPolicy/PlatformCpuPolicy.inf   |  81 ++
 .../Dxe/PlatformType/PlatformType.inf         |  58 ++
 .../Platform/Dxe/PlatformType/PlatformTypes.c | 364 +++++++++
 .../Platform/Dxe/PlatformType/PlatformTypes.h |  58 ++
 .../Platform/Dxe/S3NvramSave/S3NvramSave.c    | 157 ++++
 .../Platform/Dxe/S3NvramSave/S3NvramSave.h    |  40 +
 .../Platform/Dxe/S3NvramSave/S3NvramSave.inf  |  52 ++
 .../Platform/Pei/DummyPchSpi/DummyPchSpi.inf  |  43 +
 .../Platform/Pei/DummyPchSpi/PchSpi.c         | 383 +++++++++
 .../EmulationPlatformInit.c                   | 124 +++
 .../EmulationPlatformInit.inf                 |  46 ++
 .../Platform/Pei/PlatformInfo/PlatformInfo.c  | 761 ++++++++++++++++++
 .../Platform/Pei/PlatformInfo/PlatformInfo.h  |  89 ++
 .../Pei/PlatformInfo/PlatformInfo.inf         |  63 ++
 .../ExSerialStatusCodeWorker.c                | 194 +++++
 .../ExStatusCodeHandlerPei.c                  | 111 +++
 .../ExStatusCodeHandlerPei.h                  |  85 ++
 .../ExStatusCodeHandlerPei.inf                |  61 ++
 .../ExReportStatusCodeRouterPei.c             | 301 +++++++
 .../ExReportStatusCodeRouterPei.h             | 104 +++
 .../ExReportStatusCodeRouterPei.inf           |  51 ++
 .../PeiInterposerToSvidMap.c                  | 136 ++++
 .../PeiInterposerToSvidMap.inf                |  53 ++
 27 files changed, 4360 insertions(+)
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformType.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/DummyPchSpi.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/PchSpi.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExSerialStatusCodeWorker.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.h
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.inf
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.c
 create mode 100644 Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.inf

diff --git a/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.c b/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.c
new file mode 100644
index 0000000000..718bc14ffc
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.c
@@ -0,0 +1,104 @@
+/** @file
+  Driver for BIOS Info support.
+
+ at copyright
+  Copyright 2011 - 2021 Intel Corporation.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <BiosInfo.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/FirmwareInterfaceTable.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED BIOS_INFO  mBiosInfo = {
+  {
+    BIOS_INFO_SIGNATURE,
+    BIOS_INFO_STRUCT_SIZE,
+    0,
+  },
+  {
+    {
+      FIT_TYPE_07_BIOS_STARTUP_MODULE,
+      BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT,
+      0x0100,
+      FixedPcdGet32 (PcdFlashNvStorageVariableSize) + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize),
+      FixedPcdGet32 (PcdFlashNvStorageVariableBase)
+    },
+    {
+      FIT_TYPE_07_BIOS_STARTUP_MODULE,
+      0,
+      0x0100,
+      FixedPcdGet32 (PcdFlashFvPreMemorySize),
+      FixedPcdGet32 (PcdFlashFvPreMemoryBase)
+    },
+    {
+      FIT_TYPE_07_BIOS_STARTUP_MODULE,
+      0,
+      0x0100,
+      FixedPcdGet32 (PcdFlashFvFspMSize),
+      FixedPcdGet32 (PcdFlashFvFspMBase)
+    },
+    {
+      FIT_TYPE_01_MICROCODE,
+      BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION,
+      0x0100,
+      FixedPcdGet32 (PcdFlashNvStorageMicrocodeSize),
+      FixedPcdGet32 (PcdFlashNvStorageMicrocodeBase)
+    },
+
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR  mBiosInfoPpiList = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gBiosInfoGuid,
+  &mBiosInfo
+};
+
+/**
+  Installs BiosInfo Ppi.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS   Install the BiosInfo Ppi successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosInfoEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+  VOID        *HobData;
+
+  //
+  // Install PPI, so that other PEI module can add dependency.
+  //
+  Status = PeiServicesInstallPpi (&mBiosInfoPpiList);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Build hob, so that DXE module can also get the data.
+  //
+  HobData = BuildGuidHob (&gBiosInfoGuid, sizeof (BIOS_INFO));
+  ASSERT (HobData != NULL);
+
+  if (HobData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem (HobData, &mBiosInfo, sizeof (BIOS_INFO));
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.h b/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.h
new file mode 100644
index 0000000000..b849663766
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.h
@@ -0,0 +1,67 @@
+/** @file
+
+ @copyright
+  Copyright 2011 - 2021 Intel Corporation.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BIOS_INFO_H_
+#define _BIOS_INFO_H_
+
+#undef BIOS_INFO_STRUCT_SIZE
+#define BIOS_INFO_STRUCT_SIZE 4
+//
+// BIOS INFO data structure
+// This is self contained data structure for BIOS info for TXT
+//
+#pragma pack (1)
+
+#define BIOS_INFO_SIGNATURE  SIGNATURE_64 ('$', 'B', 'I', 'O', 'S', 'I', 'F', '$')
+typedef struct {
+  UINT64            Signature;
+  UINT32            EntryCount;
+  UINT32            Reserved;
+} BIOS_INFO_HEADER;
+
+//
+// BIOS_INFO_STRUCT attributes
+// bits[0:3] means general attributes
+// bits[4:7] means type specific attributes
+//
+#define BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT  0x01
+#define BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION    0x10
+#define BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB             0x10
+#define BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_NON_IBB              0x20
+
+typedef struct {
+  //
+  // FitTable entry type
+  //
+  UINT8    Type;
+  //
+  // BIOS_INFO_STRUCT attributes
+  //
+  UINT8    Attributes;
+  //
+  // FitTable entry version
+  //
+  UINT16   Version;
+  //
+  // FitTable entry real size
+  //
+  UINT32   Size;
+  //
+  // FitTable entry address
+  //
+  UINT64   Address;
+} BIOS_INFO_STRUCT;
+
+typedef struct {
+  BIOS_INFO_HEADER  Header;
+  BIOS_INFO_STRUCT  Entry[BIOS_INFO_STRUCT_SIZE];
+} BIOS_INFO;
+
+#pragma pack ()
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.inf b/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.inf
new file mode 100644
index 0000000000..b758e8d4e5
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/BiosInfo/BiosInfo.inf
@@ -0,0 +1,70 @@
+### @file
+# Module Information description file for BIOS Info Driver
+#
+#@copyright
+#  Copyright 2011 - 2021 Intel Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# @par Specification Reference:
+#
+# @par Glossary:
+###
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BiosInfo
+  FILE_GUID                      = 4A4CA1C6-871C-45BB-8801-6910A7AA5807
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = BiosInfoEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES IA32 X64
+#
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  HobLib
+  BaseMemoryLib
+  DebugLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+
+[Pcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase           ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           ## CONSUMES
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize    ## CONSUMES
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize    ## CONSUMES
+
+  gCpPlatFlashTokenSpaceGuid.PcdFlashFvAcmBase                    ## CONSUMES
+  gCpPlatFlashTokenSpaceGuid.PcdFlashFvAcmSize                    ## CONSUMES
+
+  gCpuUncoreTokenSpaceGuid.PcdFlashNvStorageMicrocodeBase         ## CONSUMES
+  gCpuUncoreTokenSpaceGuid.PcdFlashNvStorageMicrocodeSize         ## CONSUMES
+
+[Sources]
+  BiosInfo.c
+
+[Guids]
+  gBiosInfoGuid                                                   ## PRODUCES
+
+[Depex]
+  gEfiPeiMasterBootModePpiGuid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.c b/Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.c
new file mode 100644
index 0000000000..556dc1b0bf
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.c
@@ -0,0 +1,704 @@
+/** @file
+  CPU Policy Platform DXE Driver implementation.
+
+  @copyright
+  Copyright 2015 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Protocol/CpuPolicyProtocol.h>
+#include <Protocol/PpmPolicyProtocol.h>
+#include <IioUniversalData.h>
+#include <Protocol/PlatformType.h>
+#include <SetupTable.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/CpuConfigLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/CpuPpmLib.h>
+#include <Platform.h>
+#include <Cpu/CpuIds.h>
+#include <CpuAndRevisionDefines.h>
+#include <ScratchpadList.h>
+#include <Register/Cpuid.h>
+#include <ProcessorPpmSetup.h>
+#include <Protocol/DynamicSiLibraryProtocol.h>
+
+CHAR16 mCpuSocketStr[8][5] = {L"CPU0", L"CPU1", L"CPU2", L"CPU3", L"CPU4", L"CPU5", L"CPU6", L"CPU7"};
+CHAR16 mCpuAssetTagStr[] = L"UNKNOWN";
+IIO_UDS                     *mIioUds;
+CPU_POLICY_CONFIGURATION    mCpuPolicyConfiguration;
+PPM_POLICY_CONFIGURATION    mPpmPolicyConfiguration;
+
+/**
+  Set platform CPU data that related to SMBIOS.
+**/
+VOID
+PlatformCpuSmbiosData (
+  VOID
+  )
+{
+  UINT32                        CpuSocketCount;
+  UINTN                         Index;
+  CHAR16                        **CpuSocketNames;
+  CHAR16                        **CpuAssetTags;
+  EFI_STATUS                    Status = EFI_SUCCESS;
+
+  //
+  // Set the count of CPU sockets on the board.
+  //
+  CpuSocketCount = PcdGet32(PcdOemSkuBoardSocketCount);
+
+  Status = PcdSet32S (PcdPlatformCpuSocketCount, CpuSocketCount);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return;
+  }
+
+  CpuSocketNames = AllocatePool (CpuSocketCount * sizeof (UINTN));
+
+  if (CpuSocketNames == NULL) {
+    DEBUG ((EFI_D_ERROR, "\nEFI_OUT_OF_RESOURCES!!! AllocatePool() returned NULL pointer.\n"));
+    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+    return;
+  }
+
+  CpuAssetTags = AllocatePool (CpuSocketCount * sizeof (UINTN));
+  if (CpuAssetTags == NULL) {
+    DEBUG ((EFI_D_ERROR, "\nEFI_OUT_OF_RESOURCES!!! AllocatePool() returned NULL pointer.\n"));
+    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+    gBS->FreePool (CpuSocketNames);
+    return;
+  }
+
+  for (Index = 0; Index < CpuSocketCount; Index++) {
+    CpuSocketNames[Index] = mCpuSocketStr[Index];
+    CpuAssetTags[Index] = mCpuAssetTagStr;
+  }
+
+  mCpuPolicyConfiguration.PlatformCpuSocketNames = (UINT64) (UINTN) CpuSocketNames;
+
+  mCpuPolicyConfiguration.PlatformCpuAssetTags = (UINT64) (UINTN) CpuAssetTags;
+}
+
+
+
+/**
+
+    Re-assign socket id when both X2APIC and ForceX2Apic are enabled.
+
+    @param None
+
+    @retval None
+
+**/
+VOID
+CheckAndReAssignSocketId(
+  VOID
+  )
+{
+  CPU_SOCKET_ID_INFO    *pcdSktIdPtr;
+  UINT32                i, IntraPackageIdBits;
+  UINTN                 PcdSize;
+  EFI_STATUS            Status;
+  UINT32                MaxSocketCount;
+
+  MaxSocketCount = FixedPcdGet32(PcdMaxCpuSocketCount);
+  DEBUG ((DEBUG_INFO, "::SocketCount %08x\n", MaxSocketCount));
+  pcdSktIdPtr = (CPU_SOCKET_ID_INFO *)PcdGetPtr(PcdCpuSocketId);
+  PcdSize = LibPcdGetSize (PcdToken (PcdCpuSocketId)); //MAX_SOCKET * sizeof(CPU_SOCKET_ID_INFO);
+  ASSERT(PcdSize == (MAX_SOCKET * sizeof(CPU_SOCKET_ID_INFO)));
+  Status = PcdSetPtrS (PcdCpuSocketId, &PcdSize, (VOID *)pcdSktIdPtr);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return;
+  }
+  DEBUG ((EFI_D_INFO, "::SockeId Pcd at %08x, size %x\n", PcdGetPtr(PcdCpuSocketId), PcdSize));
+
+  for(i = 0; i < MAX_SOCKET; i++) {
+    if (mIioUds->PlatformData.CpuQpiInfo[i].Valid) {
+      pcdSktIdPtr[i].DefaultSocketId = mIioUds->PlatformData.CpuQpiInfo[i].SocId;
+      pcdSktIdPtr[i].NewSocketId     = mIioUds->PlatformData.CpuQpiInfo[i].SocId;
+    } else {
+      pcdSktIdPtr[i].DefaultSocketId = (UINT32)-1;   //make sure Default and New are same
+      pcdSktIdPtr[i].NewSocketId     = (UINT32)-1;
+    }
+  }
+
+  AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, &IntraPackageIdBits, NULL, NULL, NULL);
+  //assign new socketId
+  for(i = 0; i < MAX_SOCKET; i++) {
+
+    if (pcdSktIdPtr[i].DefaultSocketId == (UINT32)-1) {
+      continue;
+    }
+
+    switch(IntraPackageIdBits) {
+      case 4: //socket bit starts from bit4 of ApicId
+      case 5: //socket bit starts from bit5 of ApicId
+        if (MAX_SOCKET == 4) {
+          pcdSktIdPtr[i].NewSocketId |= (APICID_MASK_BIT14_8 << (8 - IntraPackageIdBits));
+        } else {
+          //3bit in lower 8bit as skt field, to avoid ApicID= FFs, leave bit8 untouched for 8S
+          pcdSktIdPtr[i].NewSocketId |= (0x7E << (8 - IntraPackageIdBits));      //leave bit8 to 0 so we don't have FFs in ApicId
+        }
+        break;
+
+     case 6: //socket bit starts from bit6 of ApicId
+        if (MAX_SOCKET == 4) {
+          //only 2bit in lower 8bit as skt field, to avoid ApicID= FFs, leave bit8 untouched for 4S
+          pcdSktIdPtr[i].NewSocketId |= (0x7E << (8 - IntraPackageIdBits));
+        } else {
+          //only 2bit in lower 8bit as skt field, to avoid ApicID= FFs, leave bit9 untouched for 8S
+          pcdSktIdPtr[i].NewSocketId |= (0x7C << (8 - IntraPackageIdBits));
+        }
+        break;
+
+     default:
+        DEBUG ((EFI_D_INFO, "::Need more info to make sure we can support!!!\n"));
+        break;
+
+    } //end switch
+  }
+}
+
+/**
+
+  This is the EFI driver entry point for the CpuPolicy Driver. This
+  driver is responsible for getting microcode patches from FV.
+
+  @param ImageHandle     - Handle for the image of this driver.
+  @param SystemTable     - Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS     - Protocol installed sucessfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformCpuPolicyEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                       Status;
+  SETUP_DATA                       SetupData;
+  EFI_HANDLE                       Handle;
+  UINT8                            socket;
+  TURBO_POWRER_LIMIT               *TurboPowerLimit;
+  EFI_PLATFORM_TYPE_PROTOCOL       *PlatformType;
+  UINT32                           CpuFamilyModelStepping;
+  BIOS_SCRATCHPAD7_STRUCT          Sp7;
+  UINT64                           i;
+  UINT8                            PackageCStateSetting = 0;
+  UINT8                            CpuCStateValue = 0;
+  EFI_GUID                         UniversalDataGuid = IIO_UNIVERSAL_DATA_GUID;
+  EFI_HOB_GUID_TYPE                *GuidHob;
+  SYSTEM_MEMORY_MAP_HOB            *SystemMemoryMap;
+  CPU_VAR_DATA                     *CpuVarDataPtr = NULL;
+  DYNAMIC_SI_LIBARY_PROTOCOL       *DynamicSiLibraryProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  CpuVarDataPtr = DynamicSiLibraryProtocol->GetCpuVarData ();
+
+  GuidHob   = GetFirstGuidHob (&UniversalDataGuid);
+  ASSERT (GuidHob != NULL);
+  if (GuidHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  mIioUds   = GET_GUID_HOB_DATA(GuidHob);
+
+  SystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
+  if (SystemMemoryMap == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  SetMem (&mCpuPolicyConfiguration, sizeof (CPU_POLICY_CONFIGURATION), 0x00);
+  SetMem (&mPpmPolicyConfiguration, sizeof (PPM_POLICY_CONFIGURATION), 0x00);
+
+  AsmCpuid (1, &CpuFamilyModelStepping, NULL, NULL, NULL);
+
+  PlatformCpuSmbiosData ();
+
+  //
+  // Read the current system configuration variable store.
+  //
+  ZeroMem(&SetupData, sizeof(SETUP_DATA));
+  CopyMem (&SetupData.SocketConfig.IioConfig, PcdGetPtr(PcdSocketIioConfig), sizeof(SOCKET_IIO_CONFIGURATION));
+  CopyMem (&SetupData.SocketConfig.CommonRcConfig, PcdGetPtr(PcdSocketCommonRcConfig), sizeof(SOCKET_COMMONRC_CONFIGURATION));
+  CopyMem (&SetupData.SocketConfig.UpiConfig, PcdGetPtr(PcdSocketMpLinkConfig), sizeof(SOCKET_MP_LINK_CONFIGURATION));
+  CopyMem (&SetupData.SocketConfig.MemoryConfig, PcdGetPtr(PcdSocketMemoryConfig), sizeof(SOCKET_MEMORY_CONFIGURATION));
+  CopyMem (&SetupData.SocketConfig.PowerManagementConfig, PcdGetPtr(PcdSocketPowerManagementConfig), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION));
+  CopyMem (&SetupData.SocketConfig.SocketProcessorCoreConfiguration, PcdGetPtr(PcdSocketProcessorCoreConfig), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
+  CopyMem (&SetupData.SystemConfig, PcdGetPtr(PcdSetup), sizeof(SYSTEM_CONFIGURATION));
+  CopyMem (&SetupData.PchSetup, PcdGetPtr(PcdPchSetup), sizeof(PCH_SETUP));
+
+  Sp7.Data = DynamicSiLibraryProtocol->ReadScratchpad7 ();
+  DEBUG ((EFI_D_INFO, "AYP Debug scratchpad7: %x Stepping %x\n", Sp7.Bits.AepDimmPresent, CpuFamilyModelStepping & 0x0f));
+  if ((Sp7.Bits.AepDimmPresent == 1) && ((CpuFamilyModelStepping & 0x0f) < 0x04) && ((CpuFamilyModelStepping >> 4) == CPU_FAMILY_SKX)) {
+    SetupData.SocketConfig.PowerManagementConfig.PackageCState = 0;
+  }
+
+  if (SetupData.SocketConfig.PowerManagementConfig.PackageCState == PPM_AUTO) {
+      PackageCStateSetting = C6_ENABLE;  //POR Default = C6
+  } else {
+      PackageCStateSetting = SetupData.SocketConfig.PowerManagementConfig.PackageCState;
+  }
+
+  if (SetupData.SocketConfig.PowerManagementConfig.C6Enable == PPM_AUTO) {
+      CpuCStateValue |= C6_ENABLE;   //POR Default = Enabled
+  } else {
+      CpuCStateValue |= (SetupData.SocketConfig.PowerManagementConfig.C6Enable * C6_ENABLE);
+  }
+
+  mCpuPolicyConfiguration.Policy.CpuCoreCStateValue = CpuCStateValue;
+
+  //
+  //  Update CpuMtoIWa from StructurePcd
+  //
+  if (DynamicSiLibraryProtocol->IsCpuAndRevision (CPU_ICXSP, REV_R0) || DynamicSiLibraryProtocol->IsCpuAndRevision (CPU_ICXSP, REV_L0) || DynamicSiLibraryProtocol->IsCpuAndRevision (CPU_ICXSP, REV_C0)) {
+    mCpuPolicyConfiguration.Policy.CpuMtoIWa = SetupData.SocketConfig.SocketProcessorCoreConfiguration.CpuMtoIWa;
+  }
+  //
+  // Verify that the value being set is within the valid range 0 to MAX_SOCKET - 1
+  //
+  if (SetupData.SocketConfig.SocketProcessorCoreConfiguration.BspSelection > MAX_SOCKET) {
+    SetupData.SocketConfig.SocketProcessorCoreConfiguration.BspSelection= 0xFF;
+  }
+  mCpuPolicyConfiguration.SbspSelection = SetupData.SocketConfig.SocketProcessorCoreConfiguration.BspSelection;
+  //
+  // Map CPU setup options to mCpuPolicyConfiguration
+  //
+  mCpuPolicyConfiguration.Policy.CpuEistEnable           = SetupData.SocketConfig.PowerManagementConfig.ProcessorEistEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuVtEnable             = SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorVmxEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuLtEnable             = SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorSmxEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuFastStringEnable     = SetupData.SocketConfig.SocketProcessorCoreConfiguration.FastStringEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuMaxCpuidValueLimitEnable = SetupData.SocketConfig.SocketProcessorCoreConfiguration.CpuidMaxValue ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuMachineCheckEnable   = SetupData.SocketConfig.SocketProcessorCoreConfiguration.MachineCheckEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuDcuPrefetcherEnable  = SetupData.SocketConfig.SocketProcessorCoreConfiguration.DCUStreamerPrefetcherEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuIpPrefetcherEnable   = SetupData.SocketConfig.SocketProcessorCoreConfiguration.DCUIPPrefetcherEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuMonitorMwaitEnable   = SetupData.SocketConfig.PowerManagementConfig.MonitorMWait ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuTurboModeEnable      = SetupData.SocketConfig.PowerManagementConfig.TurboMode ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuThermalManagementEnable = SetupData.SocketConfig.PowerManagementConfig.EnableThermalMonitor ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuTccActivationOffset = SetupData.SocketConfig.PowerManagementConfig.TCCActivationOffset;
+  mCpuPolicyConfiguration.Policy.CpuL1NextPagePrefetcherDisable  = SetupData.SocketConfig.SocketProcessorCoreConfiguration.CpuL1NextPagePrefetcherDisable ? TRUE : FALSE;
+
+  if (SetupData.SocketConfig.PowerManagementConfig.TStateEnable && (SetupData.SocketConfig.PowerManagementConfig.OnDieThermalThrottling > 0)) {
+    mCpuPolicyConfiguration.Policy.CpuTStateEnable = SetupData.SocketConfig.PowerManagementConfig.TStateEnable ? TRUE : FALSE;
+  }
+
+  mCpuPolicyConfiguration.Policy.CpuMlcStreamerPrefetecherEnable  = SetupData.SocketConfig.SocketProcessorCoreConfiguration.MlcStreamerPrefetcherEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuMlcSpatialPrefetcherEnable  = SetupData.SocketConfig.SocketProcessorCoreConfiguration.MlcSpatialPrefetcherEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuThreeStrikeCounterEnable    = SetupData.SocketConfig.SocketProcessorCoreConfiguration.ThreeStrikeTimer ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuEnergyPerformanceBiasEnable = TRUE;
+  mCpuPolicyConfiguration.Policy.CpuX2ApicEnable                = (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorX2apic || DynamicSiLibraryProtocol->X2ApicIdDetect (NULL)) ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuAesEnable                   = SetupData.SocketConfig.SocketProcessorCoreConfiguration.AesEnable ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuPpinControlEnable           = SetupData.SocketConfig.SocketProcessorCoreConfiguration.PpinControl ? TRUE : FALSE;
+  mCpuPolicyConfiguration.Policy.CpuPeciDownstreamWriteEnable   = SetupData.SocketConfig.SocketProcessorCoreConfiguration.PCIeDownStreamPECIWrite ? TRUE : FALSE;
+  if ((CpuFamilyModelStepping >> 4) == CPU_FAMILY_ICX) {
+    mCpuPolicyConfiguration.Policy.CpuC1AutoDemotionEnable        = SetupData.SocketConfig.PowerManagementConfig.C1AutoDemotion ? TRUE : FALSE;
+    mCpuPolicyConfiguration.Policy.CpuC1AutoUndemotionEnable      = SetupData.SocketConfig.PowerManagementConfig.C1AutoUnDemotion ? TRUE : FALSE;
+  }
+  mCpuPolicyConfiguration.Policy.CpuCStateEnable                = TRUE;
+
+  mPpmPolicyConfiguration.OverclockingLock  = SetupData.SocketConfig.PowerManagementConfig.OverclockingLock;
+  mPpmPolicyConfiguration.AvxSupport        = SetupData.SocketConfig.PowerManagementConfig.AvxSupport;
+  mPpmPolicyConfiguration.AvxIccpLevel      = SetupData.SocketConfig.PowerManagementConfig.AvxIccpLevel;
+  mPpmPolicyConfiguration.GpssTimer         = SetupData.SocketConfig.PowerManagementConfig.GpssTimer;
+
+  mPpmPolicyConfiguration.FastRaplDutyCycle = SetupData.SocketConfig.PowerManagementConfig.FastRaplDutyCycle;
+
+  if (mIioUds->PlatformData.EVMode) {
+    mCpuPolicyConfiguration.Policy.CpuLtEnable = FALSE;
+  }
+
+  if (SetupData.SocketConfig.PowerManagementConfig.ProcessorEistEnable) {
+    mCpuPolicyConfiguration.Policy.CpuHwCoordinationEnable = SetupData.SocketConfig.PowerManagementConfig.ProcessorEistPsdFunc ? FALSE : TRUE;
+    mCpuPolicyConfiguration.Policy.CpuBootPState = SetupData.SocketConfig.PowerManagementConfig.BootPState;
+  } else {
+    mCpuPolicyConfiguration.Policy.CpuTurboModeEnable = FALSE;
+  }
+
+  mCpuPolicyConfiguration.Policy.CpuAcpiLvl2Addr = PCH_ACPI_BASE_ADDRESS + R_ACPI_LV2;
+  mCpuPolicyConfiguration.Policy.CpuPackageCStateLimit = PackageCStateSetting;
+
+  if ((SetupData.SocketConfig.PowerManagementConfig.TStateEnable) && (SetupData.SocketConfig.PowerManagementConfig.OnDieThermalThrottling > 0)) {
+    mCpuPolicyConfiguration.Policy.CpuClockModulationDutyCycle = SetupData.SocketConfig.PowerManagementConfig.OnDieThermalThrottling;
+  }
+
+  Status = PcdSetBoolS (PcdCpuSmmMsrSaveStateEnable, SetupData.SocketConfig.SocketProcessorCoreConfiguration.eSmmSaveState? TRUE : FALSE);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  if (SetupData.SystemConfig.EmcaMsmiEn != 0) {
+    Status = PcdSetBoolS (PcdCpuSmmProtectedModeEnable, TRUE);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  } else {
+    Status = PcdSetBoolS (PcdCpuSmmProtectedModeEnable, FALSE);
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+
+
+  mCpuPolicyConfiguration.Policy.CpuIioLlcWaysBitMask         = SetupData.SocketConfig.SocketProcessorCoreConfiguration.IioLlcWaysMask;
+  mCpuPolicyConfiguration.Policy.CpuExpandedIioLlcWaysBitMask = SetupData.SocketConfig.SocketProcessorCoreConfiguration.ExpandedIioLlcWaysMask;
+  mCpuPolicyConfiguration.Policy.CpuRemoteWaysBitMask         = SetupData.SocketConfig.SocketProcessorCoreConfiguration.RemoteWaysMask;
+  mCpuPolicyConfiguration.Policy.CpuRrqCountThreshold         = mIioUds->PlatformData.RemoteRequestThreshold;
+  mCpuPolicyConfiguration.Policy.CpuCrashLogGprs = (SetupData.SocketConfig.SocketProcessorCoreConfiguration.CpuCrashLogGprs > 0) ? TRUE : FALSE;
+
+  //CSR SAPM CTL
+  for( socket = 0; socket < MAX_SOCKET; socket++) {
+    mPpmPolicyConfiguration.SapmCtl[socket].Iio0PkgcClkGateDis  = SetupData.SocketConfig.PowerManagementConfig.Iio0PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Iio1PkgcClkGateDis  = SetupData.SocketConfig.PowerManagementConfig.Iio1PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Iio2PkgcClkGateDis  = SetupData.SocketConfig.PowerManagementConfig.Iio2PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Kti01PkgcClkGateDis = SetupData.SocketConfig.PowerManagementConfig.Kti01PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Kti23PkgcClkGateDis = SetupData.SocketConfig.PowerManagementConfig.Kti23PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Mc0PkgcClkGateDis   = SetupData.SocketConfig.PowerManagementConfig.Mc0PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Mc1PkgcClkGateDis   = SetupData.SocketConfig.PowerManagementConfig.Mc1PkgcClkGateDis[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].P0pllOffEna         = SetupData.SocketConfig.PowerManagementConfig.P0pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].P1pllOffEna         = SetupData.SocketConfig.PowerManagementConfig.P1pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].P2pllOffEna         = SetupData.SocketConfig.PowerManagementConfig.P2pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Kti01pllOffEna      = SetupData.SocketConfig.PowerManagementConfig.Kti01pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Kti23pllOffEna      = SetupData.SocketConfig.PowerManagementConfig.Kti23pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Mc0pllOffEna        = SetupData.SocketConfig.PowerManagementConfig.Mc0pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].Mc1pllOffEna        = SetupData.SocketConfig.PowerManagementConfig.Mc1pllOffEna[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].SetvidDecayDisable  = SetupData.SocketConfig.PowerManagementConfig.SetvidDecayDisable[socket];
+    mPpmPolicyConfiguration.SapmCtl[socket].SapmCtlLock         = SetupData.SocketConfig.PowerManagementConfig.SapmCtlLock[socket];
+
+    if (SetupData.SocketConfig.MemoryConfig.OppSrefEn == 1) {
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc0PkgcIoVolRedDis  = 1;
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc1PkgcIoVolRedDis  = 1;
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc0PkgcDigVolRedDis = 1;
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc1PkgcDigVolRedDis = 1;
+    }
+
+    if (Sp7.Bits.AepDimmPresent == 1) {
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc0pllOffEna        = 0;
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc1pllOffEna        = 0;
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc0PkgcClkGateDis   = 1;
+      mPpmPolicyConfiguration.SapmCtl[socket].Mc1PkgcClkGateDis   = 1;
+    }
+  }
+
+  //
+  // PMAX Detector Config
+  //
+  mPpmPolicyConfiguration.PmaxConfig.PmaxDetector       = SetupData.SocketConfig.PowerManagementConfig.PmaxDetector;
+  mPpmPolicyConfiguration.PmaxConfig.PmaxAutoAdjustment = SetupData.SocketConfig.PowerManagementConfig.PmaxAutoAdjustment;
+  mPpmPolicyConfiguration.PmaxConfig.PmaxLoadLine       = SetupData.SocketConfig.PowerManagementConfig.PmaxLoadLine;
+  mPpmPolicyConfiguration.PmaxConfig.PmaxSign           = SetupData.SocketConfig.PowerManagementConfig.PmaxSign;
+  mPpmPolicyConfiguration.PmaxConfig.PmaxOffset         = SetupData.SocketConfig.PowerManagementConfig.PmaxOffset;
+  mPpmPolicyConfiguration.PmaxConfig.PmaxTriggerSetup   = SetupData.SocketConfig.PowerManagementConfig.PmaxTriggerSetup;
+
+  //
+  // PERF_P_LIMIT_CONTROL (CSR 1:30:2:0xE4)
+  //
+  mPpmPolicyConfiguration.PerPLimitCtl.PerfPLmtThshld         = SetupData.SocketConfig.PowerManagementConfig.PerfPLmtThshld;
+  mPpmPolicyConfiguration.PerPLimitCtl.PerfPLimitClipC        = SetupData.SocketConfig.PowerManagementConfig.PerfPLimitClipC;
+  mPpmPolicyConfiguration.PerPLimitCtl.PerfPlimitDifferential = SetupData.SocketConfig.PowerManagementConfig.PerfPlimitDifferential;
+  mPpmPolicyConfiguration.PerPLimitCtl.PerfPLimitEn           = SetupData.SocketConfig.PowerManagementConfig.PerfPLimitEn;
+
+    mPpmPolicyConfiguration.DynamicIss = SetupData.SocketConfig.PowerManagementConfig.DynamicIss;
+    mPpmPolicyConfiguration.IssCapableSystem = CpuVarDataPtr->IssCapableSystem;
+    mPpmPolicyConfiguration.ConfigTDPLevel = CpuVarDataPtr->IssConfigTdpCurrentLevel;
+    mPpmPolicyConfiguration.ConfigTDPLock = SetupData.SocketConfig.PowerManagementConfig.ConfigTdpLock;
+
+  for (socket = 0; socket < MAX_SOCKET; socket++) {
+      mPpmPolicyConfiguration.PmaxConfig.BasePackageTdp[socket] = CpuVarDataPtr->IssConfigTdpPower[socket][0];
+      mPpmPolicyConfiguration.CurrentPackageTdp[socket] = CpuVarDataPtr->IssConfigTdpPower[socket][mPpmPolicyConfiguration.ConfigTDPLevel];
+
+    if ((CpuFamilyModelStepping >> 4) != CPU_FAMILY_SKX) {
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaKti[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaKti[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaRlink[socket]        = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaRlink[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaFxr[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaFxr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaMcddr[socket]        = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaMcddr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaHbm[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaHbm[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaIio[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaIio[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaHqm[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaHqm[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaNac[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaNac[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaTip[socket]          = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaTip[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnablePkgCCriteriaMdfs[socket]         = SetupData.SocketConfig.PowerManagementConfig.EnablePkgCCriteriaMdfs[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaLogicalIpType[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaLogicalIpType[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaLogicalIpTypeMcddr[socket] = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaLogicalIpTypeMcddr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaLogicalIpTypeIio[socket]   = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaLogicalIpTypeIio[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoKti[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoKti[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnableLinkInL1Kti[socket]              = SetupData.SocketConfig.PowerManagementConfig.EnableLinkInL1Kti[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoRlink[socket]    = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoRlink[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnableLinkInL1Rlink[socket]            = SetupData.SocketConfig.PowerManagementConfig.EnableLinkInL1Rlink[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoFxr[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoFxr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgcCriteraPsMaskFxr[socket]           = SetupData.SocketConfig.PowerManagementConfig.PkgcCriteraPsMaskFxr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaAllowedPsMaskFxr[socket]   = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaAllowedPsMaskFxr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoMcddr[socket]    = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoMcddr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgcCriteriaPsOptionMcddr[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgcCriteriaPsOptionMcddr[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoHbm[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoHbm[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgcCriteriaPsOptionHbm[socket]        = SetupData.SocketConfig.PowerManagementConfig.PkgcCriteriaPsOptionHbm[socket];
+
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoIio[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoIio[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.EnableLinkInL1Iio[socket]              = SetupData.SocketConfig.PowerManagementConfig.EnableLinkInL1Iio[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoHqm[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoHqm[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgcCriteraPsMaskHqm[socket]           = SetupData.SocketConfig.PowerManagementConfig.PkgcCriteraPsMaskHqm[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaAllowedPsMaskHqm[socket]   = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaAllowedPsMaskHqm[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoNac[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoNac[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgcCriteraPsMaskNac[socket]           = SetupData.SocketConfig.PowerManagementConfig.PkgcCriteraPsMaskNac[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaAllowedPsMaskNac[socket]   = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaAllowedPsMaskNac[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoTip[socket]      = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoTip[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgcCriteraPsMaskTip[socket]           = SetupData.SocketConfig.PowerManagementConfig.PkgcCriteraPsMaskTip[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaAllowedPsMaskTip[socket]   = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaAllowedPsMaskTip[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.PkgCCriteriaInstanceNoMdfs[socket]     = SetupData.SocketConfig.PowerManagementConfig.PkgCCriteriaInstanceNoMdfs[socket];
+      mPpmPolicyConfiguration.PkgcCriteria.AllowLpStateMdfs[socket]               = SetupData.SocketConfig.PowerManagementConfig.AllowLpStateMdfs[socket];
+    }
+
+    if ((CpuFamilyModelStepping >> 4) == CPU_FAMILY_SKX) {
+      mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskKti[socket] = (SetupData.SocketConfig.PowerManagementConfig.Kti0In[socket] |
+                               (SetupData.SocketConfig.PowerManagementConfig.Kti1In[socket] << 1) |
+                               (SetupData.SocketConfig.PowerManagementConfig.Kti2In[socket] << 2) );
+
+      if (SetupData.SocketConfig.PowerManagementConfig.PcieIio0In[socket]) {
+        mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskPcie[socket] |= SET_PCIEx_MASK;
+      }
+      if (SetupData.SocketConfig.PowerManagementConfig.PcieIio1In[socket]) {
+        mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskPcie[socket] |= (SET_PCIEx_MASK << 4);
+      }
+      if (SetupData.SocketConfig.PowerManagementConfig.PcieIio2In[socket]) {
+        mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskPcie[socket] |= (SET_PCIEx_MASK << 8);
+      }
+      if (SetupData.SocketConfig.PowerManagementConfig.PcieIio3In[socket]) {
+        mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskPcie[socket] |= (SET_PCIEx_MASK << 12);
+      }
+      if (SetupData.SocketConfig.PowerManagementConfig.PcieIio4In[socket]) {
+        mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskPcie[socket] |= (SET_PCIEx_MASK << 16);
+      }
+      if (SetupData.SocketConfig.PowerManagementConfig.PcieIio5In[socket]) {
+        mPpmPolicyConfiguration.PpmCst.PkgCstEntryCriteriaMaskPcie[socket] |= (SET_PCIEx_MASK << 20);
+      }
+    }
+  }
+
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.SapmctlValCtl = SetupData.SocketConfig.PowerManagementConfig.SapmctlValCtl;
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.MsrLock       = 1;
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.PkgCstEntryValCtl    = SetupData.SocketConfig.PowerManagementConfig.PkgCstEntryValCtl;
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.CurrentConfig        = SetupData.SocketConfig.PowerManagementConfig.CurrentConfig;
+  mPpmPolicyConfiguration.TurboPowerLimit.TurboLimitCsrLock = 1;
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.MsrPkgCstConfigControlLock = SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorMsrPkgCstConfigControlLock ? 1 : 0;
+
+  if ((PackageCStateSetting > 0) && SetupData.SocketConfig.PowerManagementConfig.DynamicL1) {
+    mPpmPolicyConfiguration.AdvPwrMgtCtl.DynamicL1Disable = 1;
+  }
+
+  if (SetupData.SocketConfig.PowerManagementConfig.VccSAandVccIOdisable) {
+    mPpmPolicyConfiguration.AdvPwrMgtCtl.VccsaVccioDisable = 1;
+  }
+
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.SwLtrOvrdCtl = SetupData.SocketConfig.PowerManagementConfig.SwLtrOvrdCtl;
+  mPpmPolicyConfiguration.AdvPwrMgtCtl.EnableLowerLatencyMode = SetupData.SocketConfig.PowerManagementConfig.EnableLowerLatencyMode;
+
+  if (SetupData.SocketConfig.PowerManagementConfig.ProcessorEistEnable == 0) {
+    mPpmPolicyConfiguration.PowerCtl.EeTurboDisable = 1;
+  }
+
+  mPpmPolicyConfiguration.PowerCtl.PkgCLatNeg     = SetupData.SocketConfig.PowerManagementConfig.PkgCLatNeg;
+  mPpmPolicyConfiguration.PowerCtl.LtrSwInput     = SetupData.SocketConfig.PowerManagementConfig.LTRSwInput;
+  mPpmPolicyConfiguration.PowerCtl.PwrPerfSwitch  = SetupData.SocketConfig.PowerManagementConfig.PwrPerfSwitch;
+  mPpmPolicyConfiguration.PowerCtl.SapmControl    = SetupData.SocketConfig.PowerManagementConfig.SAPMControl;
+  mPpmPolicyConfiguration.PowerCtl.EeTurboDisable = SetupData.SocketConfig.PowerManagementConfig.EETurboDisable;
+  mPpmPolicyConfiguration.PowerCtl.ProchotLock    = 1;
+  mPpmPolicyConfiguration.PowerCtl.C1eEnable      = SetupData.SocketConfig.PowerManagementConfig.ProcessorC1eEnable;
+  mPpmPolicyConfiguration.PowerCtl.SetvidDecayDisable = SetupData.SocketConfig.PowerManagementConfig.SetvidDecayDisable[0];
+
+  if ((SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 3) && !SetupData.SocketConfig.PowerManagementConfig.PwrPerfTuning) {
+    // If hwp native w/o legacy then default value is "BIOS Controls EPB". OS Control of EPB should not be allowed
+    mPpmPolicyConfiguration.PowerCtl.PwrPerfTuning  = 1;
+  } else if ((SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 2) && !SetupData.SocketConfig.PowerManagementConfig.PwrPerfTuning) {
+    // if hwp oob mode then default value is "PECI Controls EPB". OS Control of EPB should not be allowed
+    mPpmPolicyConfiguration.PowerCtl.PwrPerfTuning  = 2;
+  } else {
+    mPpmPolicyConfiguration.PowerCtl.PwrPerfTuning  = SetupData.SocketConfig.PowerManagementConfig.PwrPerfTuning;
+  }
+
+  //  From Setup:
+  //    0: Output only
+  //    1: Disable
+  //    2: Bi-Directional
+  //    3: Input Only
+  //
+  if ((SetupData.SocketConfig.PowerManagementConfig.EnableProcHot & 1) == 0) {
+    mPpmPolicyConfiguration.PowerCtl.ProchotOutputDisable = 0;
+  } else {
+    mPpmPolicyConfiguration.PowerCtl.ProchotOutputDisable = 1;
+  }
+
+  if ((SetupData.SocketConfig.PowerManagementConfig.EnableProcHot & 2) == 0) {
+    mPpmPolicyConfiguration.PowerCtl.BidirProchotEnable = 0;
+  } else {
+    mPpmPolicyConfiguration.PowerCtl.BidirProchotEnable = 1;
+  }
+
+  //
+  // PROCHOT_RESPONSE_RATIO (CSR 1:30:2:0xB0)
+  //
+  mPpmPolicyConfiguration.ProchotRatio = SetupData.SocketConfig.PowerManagementConfig.ProchotResponseRatio;
+
+  mPpmPolicyConfiguration.PpoCurrentCfg.PpcccLock = SetupData.SocketConfig.PowerManagementConfig.PpcccLock;
+  mPpmPolicyConfiguration.PpoCurrentCfg.CurrentLimit = SetupData.SocketConfig.PowerManagementConfig.CurrentLimit;
+
+  // MSR_PACKAGE_POWER_LIMIT 0x610
+  // CSR_TURBO_POWER_LIMIT 1:30:0:0xe8
+  TurboPowerLimit = &mPpmPolicyConfiguration.TurboPowerLimit;
+  TurboPowerLimit->TurboPowerLimitLock  = SetupData.SocketConfig.PowerManagementConfig.TurboPowerLimitLock;
+  TurboPowerLimit->PowerLimit1Power     = SetupData.SocketConfig.PowerManagementConfig.PowerLimit1Power;
+  TurboPowerLimit->PowerLimit1Time      = SetupData.SocketConfig.PowerManagementConfig.PowerLimit1Time;
+  TurboPowerLimit->PowerLimit1En        = SetupData.SocketConfig.PowerManagementConfig.PowerLimit1En;
+  TurboPowerLimit->PowerLimit2Power     = SetupData.SocketConfig.PowerManagementConfig.PowerLimit2Power;
+  TurboPowerLimit->PowerLimit2Time      = SetupData.SocketConfig.PowerManagementConfig.PowerLimit2Time;
+  TurboPowerLimit->PowerLimit2En        = SetupData.SocketConfig.PowerManagementConfig.PowerLimit2En;
+  TurboPowerLimit->PkgClmpLim1          = 1;
+  TurboPowerLimit->PkgClmpLim2          = 1;
+
+  // DYNAMIC_PERF_POWER_CTL (CSR 1:30:2:0x64)
+  mPpmPolicyConfiguration.DynamicPerPowerCtl.UncrPerfPlmtOvrdEn   = SetupData.SocketConfig.PowerManagementConfig.UncrPerfPlmtOvrdEn;
+  mPpmPolicyConfiguration.DynamicPerPowerCtl.EetOverrideEn        = SetupData.SocketConfig.PowerManagementConfig.EetOverrideEn;
+  mPpmPolicyConfiguration.DynamicPerPowerCtl.IoBwPlmtOvrdEn       = SetupData.SocketConfig.PowerManagementConfig.IoBwPlmtOvrdEn;
+  mPpmPolicyConfiguration.DynamicPerPowerCtl.IomApmOvrdEn         = SetupData.SocketConfig.PowerManagementConfig.IomApmOvrdEn;
+  mPpmPolicyConfiguration.DynamicPerPowerCtl.KtiApmOvrdEn         = SetupData.SocketConfig.PowerManagementConfig.KtiApmOvrdEn;
+
+  //
+  // CSR_PCIE_ILTR_OVRD (CSR 1:30:1:0xFC)
+  // SW_LTR_OVRD (MSR 0xa02) -- not used
+  //
+  mPpmPolicyConfiguration.PcieIltrOvrd.SnpLatVld     = SetupData.SocketConfig.PowerManagementConfig.SnpLatVld;
+  mPpmPolicyConfiguration.PcieIltrOvrd.SnpLatOvrd    = SetupData.SocketConfig.PowerManagementConfig.SnpLatOvrd;
+  mPpmPolicyConfiguration.PcieIltrOvrd.SnpLatMult    = SetupData.SocketConfig.PowerManagementConfig.SnpLatMult;
+  mPpmPolicyConfiguration.PcieIltrOvrd.SnpLatVal     = SetupData.SocketConfig.PowerManagementConfig.SnpLatVal;
+  mPpmPolicyConfiguration.PcieIltrOvrd.NonSnpLatVld  = SetupData.SocketConfig.PowerManagementConfig.NonSnpLatVld;
+  mPpmPolicyConfiguration.PcieIltrOvrd.NonSnpLatOvrd = SetupData.SocketConfig.PowerManagementConfig.NonSnpLatOvrd;
+  mPpmPolicyConfiguration.PcieIltrOvrd.NonSnpLatMult = SetupData.SocketConfig.PowerManagementConfig.NonSnpLatMult;
+  mPpmPolicyConfiguration.PcieIltrOvrd.NonSnpLatVal  = SetupData.SocketConfig.PowerManagementConfig.NonSnpLatVal;
+
+  for(i = 0; i < 8; i++) {
+    mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitRatio[i] = SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitRatio[i];
+
+    mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitRatioMask[i] = 0xFF;
+    if (SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitRatio[i] > 0) {
+      mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitRatioMask[i] = 0;
+    }
+
+    mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitCoresMask[i] = 0xFF;
+    mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitCores[i] = 0;
+    if (SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitCores[i] != 0xFF) {
+      mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitCoresMask[i] = 0;
+      mPpmPolicyConfiguration.TurboRatioLimit.RatioLimitCores[i] = SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitCores[i];
+    }
+  }
+
+  //
+  // ENERGY_PERF_BIAS_CONFIG (MSR 0xA01)
+  //
+  mPpmPolicyConfiguration.PerfBiasConfig.EngAvgTimeWdw1 = SetupData.SocketConfig.PowerManagementConfig.EngAvgTimeWdw1;
+  mPpmPolicyConfiguration.PerfBiasConfig.P0TtlTimeLow1  = SetupData.SocketConfig.PowerManagementConfig.P0TtlTimeLow1;
+  mPpmPolicyConfiguration.PerfBiasConfig.P0TtlTimeHigh1 = SetupData.SocketConfig.PowerManagementConfig.P0TtlTimeHigh1;
+  mPpmPolicyConfiguration.PerfBiasConfig.AltEngPerfBIAS = SetupData.SocketConfig.PowerManagementConfig.AltEngPerfBIAS;
+  mPpmPolicyConfiguration.PerfBiasConfig.WorkLdConfig   = SetupData.SocketConfig.PowerManagementConfig.WorkLdConfig;
+
+  //
+  //ProcessorHWPM-init as disabled.
+  //
+  mPpmPolicyConfiguration.Hwpm.HWPMNative    = 0;
+  mPpmPolicyConfiguration.Hwpm.HWPMOOB       = 0;
+  mPpmPolicyConfiguration.Hwpm.HWPMEnable    = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable;
+  mPpmPolicyConfiguration.Hwpm.HWPMInterrupt = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMInterrupt;
+  mPpmPolicyConfiguration.Hwpm.EPPEnable     = SetupData.SocketConfig.PowerManagementConfig.ProcessorEPPEnable;
+  mPpmPolicyConfiguration.Hwpm.EPPProfile    = SetupData.SocketConfig.PowerManagementConfig.ProcessorEppProfile;
+
+  if ((SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 1) ||
+     (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 3)) {
+    mPpmPolicyConfiguration.Hwpm.HWPMNative  = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable;
+  }else if (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 2){
+    mPpmPolicyConfiguration.Hwpm.HWPMOOB     = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable;
+    mPpmPolicyConfiguration.Hwpm.HWPMInterrupt = 0;
+  }else if (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 0){
+    mPpmPolicyConfiguration.Hwpm.HWPMNative    = 0;
+    mPpmPolicyConfiguration.Hwpm.HWPMOOB       = 0;
+    mPpmPolicyConfiguration.Hwpm.HWPMInterrupt = 0;
+    mPpmPolicyConfiguration.Hwpm.EPPEnable     = 0;
+  }
+
+  mPpmPolicyConfiguration.Hwpm.APSrocketing          = SetupData.SocketConfig.PowerManagementConfig.ProcessorAPSrocketing;
+  mPpmPolicyConfiguration.Hwpm.Scalability           = SetupData.SocketConfig.PowerManagementConfig.ProcessorScalability;
+  mPpmPolicyConfiguration.Hwpm.RaplPrioritization             = SetupData.SocketConfig.PowerManagementConfig.ProcessorRaplPrioritization;
+  mPpmPolicyConfiguration.Hwpm.OutofBandAlternateEPB = SetupData.SocketConfig.PowerManagementConfig.ProcessorOutofBandAlternateEPB;
+
+  for (i = 0; i < NUM_CST_LAT_MSR; i++) {    // CStateLatencyCtrl CSRs
+    mPpmPolicyConfiguration.PpmCst.LatencyCtrl[i].Valid      = SetupData.SocketConfig.PowerManagementConfig.CStateLatencyCtrlValid[i];
+    mPpmPolicyConfiguration.PpmCst.LatencyCtrl[i].Multiplier = SetupData.SocketConfig.PowerManagementConfig.CStateLatencyCtrlMultiplier[i];
+    mPpmPolicyConfiguration.PpmCst.LatencyCtrl[i].Value      = SetupData.SocketConfig.PowerManagementConfig.CStateLatencyCtrlValue[i];
+  }
+
+  if (SetupData.SocketConfig.PowerManagementConfig.C2C3TT) { //if option is not AUTO
+    mPpmPolicyConfiguration.C2C3TT = SetupData.SocketConfig.PowerManagementConfig.C2C3TT;
+  } else {
+    mPpmPolicyConfiguration.C2C3TT = 0x10;
+  }
+
+  //
+  // If Emulation flag set by InitializeDefaultData in MemoryQpiInit.c
+  //  force X2APIC
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiPlatformTypeProtocolGuid,
+                  NULL,
+                  &PlatformType
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  // allocate memory for IedTrace
+  if ((SetupData.SocketConfig.SocketProcessorCoreConfiguration.IedTraceSize != 0) && (PcdGet32 (PcdCpuIEDRamSize) != 0)) {
+    DynamicSiLibraryProtocol->CheckAndPopulateIedTraceMemory(0x400000 << (SetupData.SocketConfig.SocketProcessorCoreConfiguration.IedTraceSize - 1), mIioUds);
+  }
+
+  //
+  // Install CPU PPM Policy Protocol for platform PPM configuration
+  //
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gPpmPolicyProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mPpmPolicyConfiguration
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install CPU Policy Protocol for platform configuration
+  // Cpu Driver could be dispatched after this protocol installed.
+  //
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiCpuPolicyProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mCpuPolicyConfiguration
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.inf b/Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.inf
new file mode 100644
index 0000000000..e125017e1d
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Cpu/Dxe/PlatformCpuPolicy/PlatformCpuPolicy.inf
@@ -0,0 +1,81 @@
+## @file
+# Component description file for Platform CPU Policy DXE Driver.
+#
+# @copyright
+# Copyright 2015 - 2021 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                   = 0x00010005
+  BASE_NAME                     = PlatformCpuPolicy
+  FILE_GUID                     = 76A7B4FC-C8D5-462d-A4D2-6E88338A772A
+  MODULE_TYPE                   = DXE_DRIVER
+  VERSION_STRING                = 1.0
+  ENTRY_POINT                   = PlatformCpuPolicyEntryPoint
+
+[Sources]
+  PlatformCpuPolicy.c
+
+[Packages]
+  UefiCpuPkg/UefiCpuPkg.dec
+  MdePkg/MdePkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleySiliconPkg/Cpu/CpuRcPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  HobLib
+  IoLib
+
+[Protocols]
+  gEfiPlatformTypeProtocolGuid
+  gEfiCpuPolicyProtocolGuid
+  gPpmPolicyProtocolGuid
+  gDynamicSiLibraryProtocolGuid                 ## CONSUMES
+
+[Guids]
+  gEfiSetupVariableGuid
+  gEfiSocketMemoryVariableGuid
+  gEfiSocketPowermanagementVarGuid
+  gEfiSocketProcessorCoreVarGuid
+  gEfiEndOfDxeEventGroupGuid
+
+[Pcd]
+  gCpuPkgTokenSpaceGuid.PcdPlatformCpuSocketCount
+  gCpuPkgTokenSpaceGuid.PcdCpuSocketId
+  gCpuPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable
+  gCpuPkgTokenSpaceGuid.PcdCpuSmmProtectedModeEnable
+  gCpuPkgTokenSpaceGuid.PcdCpuSmmRuntimeCtlHooks
+  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+  gOemSkuTokenSpaceGuid.PcdOemSkuBoardSocketCount
+  gCpuPkgTokenSpaceGuid.PcdCpuIEDRamSize
+
+  gStructPcdTokenSpaceGuid.PcdSocketIioConfig
+  gStructPcdTokenSpaceGuid.PcdSocketCommonRcConfig
+  gStructPcdTokenSpaceGuid.PcdSocketMpLinkConfig
+  gStructPcdTokenSpaceGuid.PcdSocketMemoryConfig
+  gStructPcdTokenSpaceGuid.PcdSocketPowerManagementConfig
+  gStructPcdTokenSpaceGuid.PcdSocketProcessorCoreConfig
+  gStructPcdTokenSpaceGuid.PcdSetup
+  gStructPcdTokenSpaceGuid.PcdPchSetup
+  gStructPcdTokenSpaceGuid.PcdFpgaSocketConfig
+
+  gOemSkuTokenSpaceGuid.PcdTurboPowerLimitLock
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND gEfiPlatformTypeProtocolGuid AND gDynamicSiLibraryProtocolGuid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformType.inf b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformType.inf
new file mode 100644
index 0000000000..a3ab0ecbe6
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformType.inf
@@ -0,0 +1,58 @@
+## @file
+#
+# @copyright
+# Copyright 2009 - 2021 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformType
+  FILE_GUID                      = 2E6A521C-F697-402d-9774-98B2B7E140F3
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformTypeInit
+
+[Sources]
+  PlatformTypes.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/Cpu/CpuRcPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  BaseLib
+  HobLib
+  DebugLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+
+ [Protocols]
+  gEfiPlatformTypeProtocolGuid     ## PRODUCES
+  gEfiIioUdsProtocolGuid
+  gDynamicSiLibraryProtocolGuid    ## CONSUMES
+
+[Guids]
+  gEfiPlatformInfoGuid
+  gEfiSetupVariableGuid
+
+[Pcd]
+  gOemSkuTokenSpaceGuid.PcdOemSkuPlatformName
+  gOemSkuTokenSpaceGuid.PcdOemSkuPlatformNameSize
+  gOemSkuTokenSpaceGuid.PcdOemSkuAssertPostGPIO
+  gOemSkuTokenSpaceGuid.PcdOemSkuAssertPostGPIOValue
+
+[FixedPcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+  gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+
+[Depex]
+  gDynamicSiLibraryProtocolGuid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.c b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.c
new file mode 100644
index 0000000000..08396c3b7a
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.c
@@ -0,0 +1,364 @@
+/** @file
+  Platform type driver to identify different platform.
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "PlatformTypes.h"
+#include <Library/SerialPortLib/Ns16550.h>
+#include <Library/IoLib.h>
+#include <Protocol/SmbusHc.h>
+#include <Protocol/MpService.h>
+#include <Library/SetupLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Protocol/DynamicSiLibraryProtocol.h>
+
+#define STRING_WIDTH_40    40
+
+CHAR16                              PchName[STRING_WIDTH_40];
+CHAR16                              IioName[STRING_WIDTH_40];
+CHAR16                              *PlatformName;
+
+//
+// Instantiation of Driver's private data.
+//
+EFI_PLATFORM_DATA_DRIVER_PRIVATE    mPrivatePlatformData;
+EFI_IIO_UDS_DRIVER_PRIVATE          mIioUdsPrivateData;
+IIO_UDS                             *IioUdsData;          // Pointer to UDS in Allocated Memory Pool
+
+EFI_GUID gEfiSmbusHcProtocolGuid = EFI_SMBUS_HC_PROTOCOL_GUID;
+EFI_GUID gEfiMpServiceProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+EFI_GUID mSystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
+
+
+/**
+  Get the PCH name.
+
+  Concatenate the series, stepping, and SKU strings to initialize the module
+  global variable "PchName".
+
+  @param[in]  PlatformInfoHobData   Pointer to the platform info HOB.
+
+  @retval EFI_INVALID_PARAMETER     Pointer parameter was null on entry.
+  @retval EFI_SUCCESS               PchName was initialized successfully.
+**/
+EFI_STATUS
+EFIAPI
+GetPchName (
+  IN EFI_PLATFORM_INFO *PlatformInfoHobData
+  )
+{
+  CHAR8                             AsciiBuffer[STRING_WIDTH_40];
+  CHAR16                            UnicodeBuffer[STRING_WIDTH_40];
+  UINT32                            BufferAsciiSize;
+  DYNAMIC_SI_LIBARY_PROTOCOL        *DynamicSiLibraryProtocol = NULL;
+  EFI_STATUS                        Status;
+
+  ASSERT (PlatformInfoHobData != NULL);
+  if (PlatformInfoHobData == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BufferAsciiSize = sizeof (AsciiBuffer);
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  AsciiStrCpyS (AsciiBuffer, BufferAsciiSize, DynamicSiLibraryProtocol->PchGetSeriesStr ());
+  AsciiStrToUnicodeStrS (AsciiBuffer, UnicodeBuffer, STRING_WIDTH_40);
+  ZeroMem (AsciiBuffer, BufferAsciiSize);
+  StrCpyS (PchName, STRING_WIDTH_40, UnicodeBuffer);
+
+  StrCatS (PchName, STRING_WIDTH_40, L" ");
+
+  DynamicSiLibraryProtocol->PchGetSteppingStr (AsciiBuffer, BufferAsciiSize);
+  AsciiStrToUnicodeStrS (AsciiBuffer, UnicodeBuffer, STRING_WIDTH_40);
+  ZeroMem (AsciiBuffer, BufferAsciiSize);
+  StrCatS (PchName, STRING_WIDTH_40, UnicodeBuffer);
+
+  StrCatS (PchName, STRING_WIDTH_40, L" - ");
+
+  AsciiStrCpyS (AsciiBuffer, BufferAsciiSize, DynamicSiLibraryProtocol->PchGetSkuStr ());
+  AsciiStrToUnicodeStrS (AsciiBuffer, UnicodeBuffer, STRING_WIDTH_40);
+  ZeroMem (AsciiBuffer, BufferAsciiSize);
+  StrCatS (PchName, STRING_WIDTH_40, UnicodeBuffer);
+
+  mPrivatePlatformData.PlatformType.PchStringPtr = (UINT64)PchName;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+    GC_TODO: add routine description
+
+    @param None
+
+    @retval None
+
+**/
+VOID
+EFIAPI
+GetIioName (
+  VOID
+  )
+{
+
+  StrCpyS(IioName, STRING_WIDTH_40, L"Unknown");
+
+  mPrivatePlatformData.PlatformType.IioStringPtr = (UINT64)IioName;
+  return ;
+}
+
+
+/**
+
+  Assert the POST complete GPIO
+
+  @param Event         Pointer to the event that triggered this Ccllback Function
+  @param Context       VOID Pointer required for Ccllback functio
+
+  @retval EFI_SUCCESS         - Assertion successfully
+
+
+**/
+VOID
+EFIAPI
+AssertPostGpio (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+{
+  UINT32                      GPIO_B20;
+  UINT32                      Data32;
+  DYNAMIC_SI_LIBARY_PROTOCOL  *DynamicSiLibraryProtocol = NULL;
+  EFI_STATUS                  Status;
+
+  Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  GPIO_B20 = PcdGet32 (PcdOemSkuAssertPostGPIO);
+  Data32 = PcdGet32(PcdOemSkuAssertPostGPIOValue);
+  if (GPIO_B20 == 0xFFFFFFFF) {
+    DEBUG ((EFI_D_ERROR, "GPIO Pcd is invalid, so abort the GPIO Set and just return! \n"));
+    return;
+  }
+  DynamicSiLibraryProtocol->GpioSetOutputValue (GPIO_B20, Data32);
+  DEBUG ((EFI_D_INFO, "System Post Complete GPIO has been set ! \n"));
+}
+
+/**
+
+  Gets the CpuId and fills in the pointer with the value.
+  Needed for executing CpuId on other APs.
+
+  @param RegEax - Pointer to be used to pass the CpuId value
+
+  @retval None
+
+**/
+VOID
+EFIAPI
+PlatformGetProcessorID (
+  IN OUT UINT32  *RegEax
+  )
+{
+
+  AsmCpuid (CPUID_VERSION_INFO, RegEax, NULL, NULL, NULL);
+}
+
+//
+// Define platform type check
+//
+/**
+
+  Entry point for the driver.
+
+  This routine reads the PlatformType GPI on FWH and produces a protocol
+  to be consumed by the chipset driver to effect those settings.
+
+  @param ImageHandle  -  Image Handle.
+  @param SystemTable  -  EFI System Table.
+
+  @retval EFI_SUCCESS  -  Function has completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformTypeInit (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HOB_GUID_TYPE               *GuidHob;
+  EFI_PLATFORM_INFO               *PlatformInfoHobData = NULL;
+  IIO_UDS                         *UdsHobPtr;
+  EFI_GUID                        UniversalDataGuid = IIO_UNIVERSAL_DATA_GUID;
+  EFI_EVENT                       ReadyToBootEvent;
+  CHAR16                          *PcdPlatformName = NULL;
+  UINT32                          PcdPlatformNameSize = 0;
+  UINT32                          PlatformNameSize;
+
+  //
+  // Initialize driver private data.
+  // Only one instance exists
+  //
+  ZeroMem (&mPrivatePlatformData, sizeof (mPrivatePlatformData));
+  mPrivatePlatformData.Signature            = EFI_PLATFORM_TYPE_DRIVER_PRIVATE_SIGNATURE;
+
+  PlatformNameSize = (STRING_WIDTH_40) * sizeof (CHAR16);
+  PlatformName = AllocateZeroPool (PlatformNameSize);
+  ASSERT (PlatformName != NULL);
+  if (PlatformName == NULL) {
+    DEBUG ((EFI_D_ERROR, "Failed to allocate memory\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Search for the Platform Info PEIM GUID HOB.
+  //
+  GuidHob       = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  ASSERT (GuidHob != NULL);
+  if (GuidHob == NULL) {
+    DEBUG ((EFI_D_ERROR, "gEfiPlatformInfoGuid not found\n"));
+    return EFI_NOT_FOUND;
+  }
+  PlatformInfoHobData  = GET_GUID_HOB_DATA(GuidHob);
+
+  CopyMem(&(mPrivatePlatformData.PlatformType.SystemUuid[0]), &PlatformInfoHobData->SystemUuid[0], 16);
+  mPrivatePlatformData.PlatformType.Signature = PlatformInfoHobData->Signature;
+  mPrivatePlatformData.PlatformType.Size = PlatformInfoHobData->Size;
+  mPrivatePlatformData.PlatformType.Revision = PlatformInfoHobData->Revision;
+  mPrivatePlatformData.PlatformType.TypeRevisionId = PlatformInfoHobData->TypeRevisionId;
+  mPrivatePlatformData.PlatformType.ExtendedInfoValid = PlatformInfoHobData->ExtendedInfoValid;
+  mPrivatePlatformData.PlatformType.Checksum = PlatformInfoHobData->Checksum;
+
+  CopyMem(&(mPrivatePlatformData.PlatformType.PciData), &PlatformInfoHobData->PciData, sizeof(EFI_PLATFORM_PCI_DATA));
+  CopyMem(&(mPrivatePlatformData.PlatformType.CpuData), &PlatformInfoHobData->CpuData, sizeof(EFI_PLATFORM_CPU_DATA));
+  CopyMem(&(mPrivatePlatformData.PlatformType.MemData), &PlatformInfoHobData->MemData, sizeof(EFI_PLATFORM_MEM_DATA));
+  CopyMem(&(mPrivatePlatformData.PlatformType.SysData), &PlatformInfoHobData->SysData, sizeof(EFI_PLATFORM_SYS_DATA));
+  CopyMem(&(mPrivatePlatformData.PlatformType.PchData), &PlatformInfoHobData->PchData, sizeof(EFI_PLATFORM_PCH_DATA));
+
+  mPrivatePlatformData.PlatformType.BoardId     = PlatformInfoHobData->BoardId;
+  mPrivatePlatformData.PlatformType.Type        = mPrivatePlatformData.PlatformType.BoardId;
+  mPrivatePlatformData.PlatformType.IioSku      = PlatformInfoHobData->IioSku;
+  mPrivatePlatformData.PlatformType.IioRevision = PlatformInfoHobData->IioRevision;
+  mPrivatePlatformData.PlatformType.PchSku      = PlatformInfoHobData->PchSku;
+  mPrivatePlatformData.PlatformType.PchRevision = PlatformInfoHobData->PchRevision;
+  mPrivatePlatformData.PlatformType.PchType     = PlatformInfoHobData->PchType;  //Include PCH SKU type
+  mPrivatePlatformData.PlatformType.CpuType     = PlatformInfoHobData->CpuType;
+  mPrivatePlatformData.PlatformType.CpuStepping = PlatformInfoHobData->CpuStepping;
+
+  mPrivatePlatformData.PlatformType.IioRiserId = PlatformInfoHobData->IioRiserId;
+  mPrivatePlatformData.PlatformType.PcieRiser1Type = PlatformInfoHobData->PcieRiser1Type;
+  mPrivatePlatformData.PlatformType.PcieRiser2Type = PlatformInfoHobData->PcieRiser2Type;
+  mPrivatePlatformData.PlatformType.Emulation = 0x4;                 // default is Simics
+
+  PcdPlatformNameSize = PcdGet32(PcdOemSkuPlatformNameSize);
+  PcdPlatformName = PcdGetPtr (PcdOemSkuPlatformName);
+  ASSERT(PlatformNameSize >= PcdPlatformNameSize);
+  if (PlatformNameSize < PcdPlatformNameSize) {
+    DEBUG ((EFI_D_ERROR, "Invalid buffer size\n"));
+    return EFI_BUFFER_TOO_SMALL;
+  }
+  ASSERT(PcdPlatformName != NULL);
+  if (PcdPlatformName == NULL) {
+    DEBUG ((EFI_D_ERROR, "Invalid PCD detected\n"));
+    return EFI_NOT_FOUND;
+  }
+  CopyMem (PlatformName, PcdPlatformName, PcdPlatformNameSize);
+
+  mPrivatePlatformData.PlatformType.TypeStringPtr = (UINT64)PlatformName;
+
+  Status = GetPchName (PlatformInfoHobData);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Failed to get PCH name: %r\n", Status));
+    return Status;
+  }
+
+  GetIioName();
+
+  //
+  // Install the PlatformType policy.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mPrivatePlatformData.Handle,
+                  &gEfiPlatformTypeProtocolGuid,
+                  &mPrivatePlatformData.PlatformType,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "%s platform is detected!\n", PlatformName));
+
+  //
+  // Time to get the IIO_UDS HOB data stored in the PEI driver
+  //
+  GuidHob    = GetFirstGuidHob (&UniversalDataGuid);
+  ASSERT (GuidHob != NULL);
+  if (GuidHob == NULL) {
+    DEBUG ((EFI_D_ERROR, "UniversalDataGuid not found\n"));
+    return EFI_NOT_FOUND;
+  }
+  UdsHobPtr = GET_GUID_HOB_DATA(GuidHob);
+
+  //
+  // Allocate Memory Pool for Universal Data Storage so that protocol can expose it
+  //
+  Status = gBS->AllocatePool ( EfiReservedMemoryType, sizeof (IIO_UDS), (VOID **) &IioUdsData );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize the Pool Memory with the data from the Hand-Off-Block
+  //
+  CopyMem(IioUdsData, UdsHobPtr, sizeof(IIO_UDS));
+
+  //
+  // Build the IIO_UDS driver instance for protocol publishing
+  //
+  ZeroMem (&mIioUdsPrivateData, sizeof (mIioUdsPrivateData));
+
+  mIioUdsPrivateData.Signature            = EFI_IIO_UDS_DRIVER_PRIVATE_SIGNATURE;
+  mIioUdsPrivateData.IioUds.IioUdsPtr     = IioUdsData;
+  mIioUdsPrivateData.IioUds.EnableVc      = NULL;
+
+  //
+  // Install the IioUds Protocol.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mIioUdsPrivateData.Handle,
+                  &gEfiIioUdsProtocolGuid,
+                  &mIioUdsPrivateData.IioUds,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Set up callback to assert the POST Complete GPIO to the iBMC
+  //
+  Status = EfiCreateEventReadyToBootEx(
+             TPL_CALLBACK,
+             AssertPostGpio,
+             NULL,
+             &ReadyToBootEvent
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.h b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.h
new file mode 100644
index 0000000000..a6dbe19c40
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/PlatformType/PlatformTypes.h
@@ -0,0 +1,58 @@
+/** @file
+  Platform Type Driver for Harwich.
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_TYPES_H_
+#define _PLATFORM_TYPES_H_
+
+#include <PiDxe.h>
+#include <Protocol/PlatformType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/VariableWrite.h>
+#include <Protocol/Spi.h>
+#include <Protocol/IioUds.h>
+#include <SystemBoard.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/HobList.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsLpc.h>
+#include <PchAccess.h>
+#include <Platform.h>
+#include <Register/Cpuid.h>
+
+
+
+
+#define EFI_PLATFORM_TYPE_DRIVER_PRIVATE_SIGNATURE  SIGNATURE_32 ('T', 'Y', 'P', 'P')
+#define EFI_IIO_UDS_DRIVER_PRIVATE_SIGNATURE  SIGNATURE_32 ('S', 'D', 'U', 'I')
+
+
+typedef unsigned char BYTE;     //!<  8-bit quantities
+typedef unsigned short WORD;    //!< 16-bit quantities
+typedef unsigned long DWORD;    //!< 32-bit quantities
+
+typedef struct {
+  UINTN                               Signature;
+  EFI_HANDLE                          Handle;               // Handle for protocol this driver installs on
+  EFI_PLATFORM_TYPE_PROTOCOL          PlatformType;         // Policy protocol this driver installs
+} EFI_PLATFORM_DATA_DRIVER_PRIVATE;
+
+typedef struct {
+  UINTN                               Signature;
+  EFI_HANDLE                          Handle;         // Handle for protocol this driver installs on
+  EFI_IIO_UDS_PROTOCOL                IioUds;         // Policy protocol this driver installs
+} EFI_IIO_UDS_DRIVER_PRIVATE;
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.c b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.c
new file mode 100644
index 0000000000..709c7ad479
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.c
@@ -0,0 +1,157 @@
+/** @file
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "S3NvramSave.h"
+#include <Library/MemoryAllocationLib.h>
+#include <Library/LargeVariableReadLib.h>
+#include <Library/LargeVariableWriteLib.h>
+
+/**
+  Verify the SysHost structure size.
+
+  Verifies that the size of the SysHost structure in PEI is
+  the same as the size of the SysHost structure and DXE and
+  ASSERT's is the size is not the same.
+
+  This is typically caused by the use of pointers or UINTNs
+  in the SysHost structure, neither of those datatypes are
+  allowed in SysHost.
+
+  @param  None
+
+  @retval None
+
+**/
+
+VOID
+VerifySysHostStructureSize (
+  VOID
+  )
+{
+
+  if (PcdGet32 (PcdPeiSyshostMemorySize) != sizeof (SYSHOST)) {
+
+    DEBUG ((EFI_D_ERROR, "ERROR: In DXE sizeof SysHost = %d, in PEI sizeof SysHost = %d\n",
+      sizeof (SYSHOST),
+      PcdGet32 (PcdPeiSyshostMemorySize)
+      ));
+
+    DEBUG ((EFI_D_ERROR, "Size of SysHost must match in PEI and DXE\n"));
+    ASSERT (FALSE);
+
+  }
+
+  return;
+
+} // VerifySysHostStructureSize
+
+/**
+  Saves the FSP Non-Volatile Storage HOB to the UEFI Variable Services
+
+  @param      None
+
+  @retval     EFI_SUCCESS  The FSP Non-Volatile Storage HOB was successfully saved.
+  @retval     EFI_ERROR    The FSP Non-Volatile Storage HOB was not successfully saved.
+**/
+EFI_STATUS
+SaveFspNonVolatileStorageHob (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_HOB_GUID_TYPE                   *GuidHob;
+  VOID                                *HobData;
+  VOID                                *VariableData;
+  UINTN                               DataSize;
+  UINTN                               FspNvsBufferSize;
+  BOOLEAN                             DataIsIdentical;
+
+  FspNvsBufferSize  = 0;
+  DataSize          = 0;
+  VariableData      = NULL;
+  GuidHob           = NULL;
+  HobData           = NULL;
+  DataIsIdentical   = FALSE;
+  Status            = EFI_SUCCESS;
+
+  DEBUG ((DEBUG_INFO, "Saving FSP / MRC Training Data\n"));
+  GuidHob = GetFirstGuidHob (&gFspNonVolatileStorageHobGuid);
+  if (GuidHob != NULL) {
+    HobData  = GET_GUID_HOB_DATA (GuidHob);
+    DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+    if (DataSize > 0) {
+
+      //
+      // Check if the presently saved data is identical to the data given by MRC/FSP
+      //
+      Status = GetLargeVariable (L"FspNvsBuffer", &gFspNonVolatileStorageHobGuid, &FspNvsBufferSize, NULL);
+      if (Status == EFI_BUFFER_TOO_SMALL) {
+        if (FspNvsBufferSize == DataSize) {
+          VariableData = AllocatePool (FspNvsBufferSize);
+          if (VariableData != NULL) {
+            Status = GetLargeVariable (L"FspNvsBuffer", &gFspNonVolatileStorageHobGuid, &FspNvsBufferSize, VariableData);
+            if (!EFI_ERROR (Status) && (FspNvsBufferSize == DataSize) && (0 == CompareMem (HobData, VariableData, DataSize))) {
+              DataIsIdentical = TRUE;
+            }
+            FreePool (VariableData);
+          }
+        }
+      }
+      Status = EFI_SUCCESS;
+
+      if (!DataIsIdentical) {
+        Status = SetLargeVariable (L"FspNvsBuffer", &gFspNonVolatileStorageHobGuid, TRUE, DataSize, HobData);
+        ASSERT_EFI_ERROR (Status);
+        DEBUG ((DEBUG_INFO, "Saved size of FSP / MRC Training Data: 0x%x\n", DataSize));
+      } else {
+        DEBUG ((DEBUG_INFO, "FSP / MRC Training Data is identical to data from last boot, no need to save.\n"));
+      }
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+S3NvramSaveEntry (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+/**
+
+  This is the main entry point of the S3 NVRAM Save module.
+
+  @param ImageHandle  -  Handle for the image of this driver.
+  @param SystemTable  -  Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS  -  Module launched successfully.
+
+**/
+{
+  EFI_STATUS                       Status = EFI_SUCCESS;
+
+  //
+  // Check that SysHost size in DXE is the same as PEI.
+  //
+
+#ifndef FSP_API_MODE
+  VerifySysHostStructureSize ();
+#endif
+
+  //
+  // Save structures into NVRAM if needed
+  //
+  Status = SaveFspNonVolatileStorageHob ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Error: FSP NVRAM Data NOT Saved! Status: %r\n", Status));
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.h b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.h
new file mode 100644
index 0000000000..8b106a3445
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.h
@@ -0,0 +1,40 @@
+/** @file
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "SysHost.h"
+
+extern EFI_GUID gEfiMemoryConfigDataHobGuid;
+extern EFI_GUID gEfiMemoryConfigDataGuid;
+
+#define MAX_HOB_ENTRY_SIZE  60*1024
+
+EFI_STATUS
+EFIAPI
+S3NvramSaveEntry (
+  IN EFI_HANDLE             ImageHandle,
+  IN EFI_SYSTEM_TABLE       *SystemTable
+  );
+
+/**
+  Saves the FSP Non-Volatile Storage HOB to the UEFI Variable Services
+
+  @param      None
+
+  @retval     EFI_SUCCESS  The FSP Non-Volatile Storage HOB was successfully saved.
+  @retval     EFI_ERROR    The FSP Non-Volatile Storage HOB was not successfully saved.
+**/
+EFI_STATUS
+SaveFspNonVolatileStorageHob (
+  VOID
+  );
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.inf b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.inf
new file mode 100644
index 0000000000..e62baa24c4
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Dxe/S3NvramSave/S3NvramSave.inf
@@ -0,0 +1,52 @@
+## @file
+#
+# @copyright
+# Copyright 2009 - 2021 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = S3NvramSave
+  FILE_GUID                      = 62DC08AC-A651-4EE9-AF81-EAA9261E9780
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = S3NvramSaveEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+
+[Sources]
+  S3NvramSave.h
+  S3NvramSave.c
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  HobLib
+  BaseMemoryLib
+  LargeVariableReadLib
+  LargeVariableWriteLib
+
+[Guids]
+  gFspNonVolatileStorageHobGuid # CONSUMES
+
+[Pcd]
+  gEfiCpRcPkgTokenSpaceGuid.PcdPeiSyshostMemorySize
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/DummyPchSpi.inf b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/DummyPchSpi.inf
new file mode 100644
index 0000000000..6d0486fda7
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/DummyPchSpi.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for PCH Reset Lib Pei Phase
+#
+# @copyright
+#  Copyright 2016 - 2021 Intel Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PchSpiPei
+  FILE_GUID                      = FEB73B42-2B02-4D2E-B9E3-77015AF91879
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = DummySpiPpiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+  DebugLib
+  PeiServicesLib
+  PeiServicesTablePointerLib
+  MemoryAllocationLib
+  PciSegmentLib
+  PeimEntryPoint
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+
+[Sources]
+  PchSpi.c
+
+[Ppis]
+  gPchSpiPpiGuid ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/PchSpi.c b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/PchSpi.c
new file mode 100644
index 0000000000..0d63044416
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/DummyPchSpi/PchSpi.c
@@ -0,0 +1,383 @@
+/** @file
+  PCH SPI PEI Library implements the SPI Host Controller Compatibility Interface.
+
+  @copyright
+  Copyright 2004 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/Spi.h>
+#include <Ppi/PchPolicy.h>
+#include <Private/Library/PchSpiCommonLib.h>
+#include <Library/PchMultiPchBase.h>
+
+typedef struct {
+  EFI_PEI_PPI_DESCRIPTOR  PpiDescriptor;
+  SPI_INSTANCE            SpiInstance;
+} PEI_SPI_INSTANCE;
+
+
+/**
+  Read data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[out] Buffer              The Pointer to caller-allocated buffer containing the dada received.
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *Buffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Write data to the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[in] Buffer               Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *Buffer
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Erase some area on the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Read SFDP data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] Address              The starting byte address for SFDP data read.
+  @param[in] ByteCount            Number of bytes in SFDP data portion of the SPI cycle
+  @param[out] SfdpData            The Pointer to caller-allocated buffer containing the SFDP data received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *SfdpData
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Read Jedec Id from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] ByteCount            Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+  @param[out] JedecId             The Pointer to caller-allocated buffer containing JEDEC ID received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *JedecId
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Write the status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[in] StatusValue          The Pointer to caller-allocated buffer containing the value of Status register writing
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Read status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[out] StatusValue         The Pointer to caller-allocated buffer containing the value of Status register received.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get the SPI region base and size, based on the enum type
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for for the base address which is listed in the Descriptor.
+  @param[out] BaseAddress         The Flash Linear Address for the Region 'n' Base
+  @param[out] RegionSize          The size for the Region 'n'
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid region type given
+  @retval EFI_DEVICE_ERROR        The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+   IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  OUT    UINT32             *BaseAddress,
+  OUT    UINT32             *RegionSize
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Read PCH Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        PCH Soft Strap address offset from FPSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Read CPU Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        CPU Soft Strap address offset from FCPUSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle.
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Initialize an SPI protocol instance.
+
+  @param[in] PchId                The PCH Id (0 - Legacy PCH, 1 ... n - Non-Legacy PCH)
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval EFI_SUCCESS             The protocol instance was properly initialized
+  @exception EFI_UNSUPPORTED      The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+  IN     UINT8              PchId,
+  IN     SPI_INSTANCE       *SpiInstance
+  )
+{
+  //
+  // Initialize the SPI protocol instance
+  //
+  SpiInstance->Signature                    = PCH_SPI_PRIVATE_DATA_SIGNATURE;
+  SpiInstance->Handle                       = NULL;
+  SpiInstance->SpiProtocol.Revision         = PCH_SPI_SERVICES_REVISION;
+  SpiInstance->SpiProtocol.FlashRead        = SpiProtocolFlashRead;
+  SpiInstance->SpiProtocol.FlashWrite       = SpiProtocolFlashWrite;
+  SpiInstance->SpiProtocol.FlashErase       = SpiProtocolFlashErase;
+  SpiInstance->SpiProtocol.FlashReadSfdp    = SpiProtocolFlashReadSfdp;
+  SpiInstance->SpiProtocol.FlashReadJedecId = SpiProtocolFlashReadJedecId;
+  SpiInstance->SpiProtocol.FlashWriteStatus = SpiProtocolFlashWriteStatus;
+  SpiInstance->SpiProtocol.FlashReadStatus  = SpiProtocolFlashReadStatus;
+  SpiInstance->SpiProtocol.GetRegionAddress = SpiProtocolGetRegionAddress;
+  SpiInstance->SpiProtocol.ReadPchSoftStrap = SpiProtocolReadPchSoftStrap;
+  SpiInstance->SpiProtocol.ReadCpuSoftStrap = SpiProtocolReadCpuSoftStrap;
+  return EFI_SUCCESS;
+}
+
+/**
+  Installs PCH SPI PPI
+
+  @retval EFI_SUCCESS             PCH SPI PPI is installed successfully
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+  VOID
+  )
+{
+  EFI_STATUS        Status;
+  PEI_SPI_INSTANCE  *PeiSpiInstance;
+  SPI_INSTANCE      *SpiInstance;
+
+  DEBUG ((DEBUG_INFO, "InstallPchSpi() Start\n"));
+
+  //
+  // PCI Enumeratuion is not done till later in DXE
+  // Initlialize SPI BAR0 to a default value till enumeration is done
+  // also enable memory space decoding for SPI
+  //
+
+
+  PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof (PEI_SPI_INSTANCE));
+  if (NULL == PeiSpiInstance) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SpiInstance = &(PeiSpiInstance->SpiInstance);
+  SpiProtocolConstructor (PCH_LEGACY_ID, SpiInstance);
+
+  PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  PeiSpiInstance->PpiDescriptor.Guid  = &gPchSpiPpiGuid;
+  PeiSpiInstance->PpiDescriptor.Ppi   = &(SpiInstance->SpiProtocol);
+
+
+
+  ///
+  /// Install the SPI PPI
+  ///
+  Status = PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "SPI PPI Installed\n"));
+
+  DEBUG ((DEBUG_INFO, "InstallPchSpi() End\n"));
+
+  return Status;
+}
+
+/**
+  Board Install Dummy SPI Ppi entry point.
+
+  @param  FileHandle   Handle of the file being invoked.
+                       Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
+  @param  PeiServices  General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+DummySpiPpiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE       FileHandle,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+
+  InstallPchSpi ();
+
+  return EFI_SUCCESS;
+
+}
\ No newline at end of file
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.c b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.c
new file mode 100644
index 0000000000..d065225a92
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.c
@@ -0,0 +1,124 @@
+/** @file
+  EFI PEIM for Emulation Platform Initial
+
+  @copyright
+  Copyright 2017 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/EmulationConfigurationLib.h>
+#include <EmulationConfiguration.h>
+#include <Guid/EmulationDfxVariable.h>
+#include <PlatformHost.h>
+#include <Cpu/CpuIds.h>
+
+EFI_PEI_PPI_DESCRIPTOR     mPpiListEmulation = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEmulationHobGuid,
+  NULL
+};
+
+#define CSR_EMULATION_FLAG_OFFSET  0xFC
+
+EFI_STATUS
+EFIAPI
+EmulationPlatformInitEntry (
+  IN EFI_PEI_FILE_HANDLE             FileHandle,
+  IN CONST EFI_PEI_SERVICES          **PeiServices
+  )
+{
+
+  EFI_STATUS                           Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI      *PeiVariable;
+  EMULATION_DFX_CONFIGURATION          EmulationVariable;
+  UINTN                                BufferSize = sizeof(EMULATION_DFX_CONFIGURATION);
+  EMULATION_SETTING                    *EmulationSetting;
+  UINT32                               RegEax;
+  UINT16                               CpuFamily;
+  UINTN                                PciLibAddress;
+  UINT32                               EmulationType;
+
+  //
+  // Build the Emulation Hob
+  //
+  EmulationSetting = BuildGuidHob (&gEmulationHobGuid, sizeof (EMULATION_SETTING));
+  if (EmulationSetting == NULL) {
+    DEBUG((EFI_D_ERROR, "Emulation BuildGuidDataHob fail!\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  EmulationSetting->UbiosGenerationSetting = EMULATION_DISABLE;
+  EmulationSetting->HybridSystemLevelEmulationSetting = EMULATION_DISABLE;
+  EmulationSetting->UbiosOutputMode = ASM_OUTPUT_ENABLE;
+  EmulationSetting->LoopBackLabelNumber = 0;
+  EmulationSetting->FnvAccessValue = FNV_ACCESS_DISABLE;
+  EmulationSetting->MsrTraceEnable = MSR_OUTPUT_DISABLE;
+
+  //
+  // Store variable into the hob.
+  //
+  (*PeiServices)->LocatePpi (
+                  PeiServices,
+                  &gEfiPeiReadOnlyVariable2PpiGuid,
+                  0,
+                  NULL,
+                  &PeiVariable
+                  );
+
+  Status = PeiVariable->GetVariable (PeiVariable, EMULATION_DFX_CONFIGURATION_NAME, &gEmulationDfxVariableGuid, NULL, &BufferSize, &EmulationVariable);
+  DEBUG ((DEBUG_INFO, "Emulation GetVariable status = %r !\n", Status));
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  EmulationSetting->UbiosGenerationSetting = EmulationVariable.DfxUbiosGeneration;
+  EmulationSetting->HybridSystemLevelEmulationSetting = EmulationVariable.DfxHybridSystemLevelEmulation;
+  EmulationSetting->MsrTraceEnable = EmulationVariable.DfxPmMsrTrace;
+
+  //
+  // Check the override value
+  //
+  AsmCpuid (1, &RegEax, NULL, NULL, NULL);
+  CpuFamily = (UINT16) (RegEax >> 4);
+
+  if (CpuFamily == CPU_FAMILY_SKX) {
+    //
+    // Simics flag is at B0:D0:F0 offset 0xFC for SKX.
+    //
+    PciLibAddress = PCI_LIB_ADDRESS(0, 0, 0, CSR_EMULATION_FLAG_OFFSET);
+  } else {
+    //
+    // Simics flag is at B0:D3:F0 offset 0xFC for 10nm.
+    //
+    PciLibAddress = PCI_LIB_ADDRESS(0, 3, 0, CSR_EMULATION_FLAG_OFFSET);
+  }
+
+  EmulationType = PciRead32 (PciLibAddress);
+
+  if (EmulationType != 0xFFFFFFFF) {
+    if ((EmulationType & UBIOS_GENERATION_EN) != 0) {
+      EmulationSetting->UbiosGenerationSetting = EMULATION_ENABLE;
+      DEBUG ((DEBUG_INFO, "EmulationVariable.DfxUbiosGeneration = %d\n", EmulationSetting->UbiosGenerationSetting));
+    }
+
+    if ((EmulationType & HYBRID_SYSTEM_LEVEL_EMULATION_EN) != 0) {
+      EmulationSetting->HybridSystemLevelEmulationSetting = EMULATION_ENABLE;
+      DEBUG ((DEBUG_INFO, "EmulationSetting->HybridSystemLevelEmulationSetting = %d\n", EmulationSetting->HybridSystemLevelEmulationSetting));
+    }
+  }
+  //
+  // Install gEmulationHobGuid PPI to inform the Emulation Hob is ready.
+  //
+  Status = PeiServicesInstallPpi (&mPpiListEmulation);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.inf b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.inf
new file mode 100644
index 0000000000..ca22383a96
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/EmulationPlatformInit/EmulationPlatformInit.inf
@@ -0,0 +1,46 @@
+## @file
+# Emulation PEIM
+#
+# @copyright
+# Copyright 2017 - 2021 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = EmulationPlatformInit
+  FILE_GUID                      = BD446386-7F8A-4ee1-A014-8D3BAB92B4E9
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = EmulationPlatformInitEntry
+
+[Sources]
+  EmulationPlatformInit.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+
+[LibraryClasses]
+  PeiServicesLib
+  PeimEntryPoint
+  DebugLib
+  HobLib
+  PciLib
+  BaseMemoryLib
+
+[Guids]
+  gEmulationHobGuid
+  gEmulationDfxVariableGuid
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid
+
+[Depex]
+  gEfiPeiReadOnlyVariable2PpiGuid AND
+  gPlatformVariableInitPpiGuid
+
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.c b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.c
new file mode 100644
index 0000000000..3652695fba
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.c
@@ -0,0 +1,761 @@
+/** @file
+  Platform Info PEIM.
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInfo.h"
+#include <GpioPinsSklH.h>
+#include <Library/GpioLib.h>
+#include <Library/PchInfoLib.h>
+
+#include <Ppi/DynamicSiLibraryPpi.h>
+
+#include <Library/UbaGpioPlatformConfig.h>
+#include <UncoreCommonIncludes.h>
+#include <PlatformInfoTypes.h>
+
+#include <Library/PeiServicesLib.h>
+
+#define  TEMP_BUS_NUMBER    (0x3F)
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR       mPlatformInfoPpi = {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPlatformInfoGuid,
+    NULL
+  };
+
+#define  BOARD_ID_GPIO_PADS_NUMBER 6
+#define  BOARD_REV_ID_GPIO_PADS_NUMBER 3
+
+//
+// These pads shall not be board specific as these are used for Board ID and Rev ID detection
+// Therefore can not be moved to UBA and are common for all Purley boards
+//
+GPIO_PAD                 mBoardId [BOARD_ID_GPIO_PADS_NUMBER] = {
+  // BoardId pads - PADCFG register  for GPIO G12
+  // WARNING: The pad number must be obtained from board schematics
+  GPIO_SKL_H_GPP_G12,
+  GPIO_SKL_H_GPP_G13,
+  GPIO_SKL_H_GPP_G14,
+  GPIO_SKL_H_GPP_G15,
+  GPIO_SKL_H_GPP_G16,
+  GPIO_SKL_H_GPP_B19
+};
+
+GPIO_PAD                 mBoardRevId [BOARD_REV_ID_GPIO_PADS_NUMBER] = {
+  // Board RevId pads - Start from pad C12
+  // WARNING: This should be obtained from board schematics
+  GPIO_SKL_H_GPP_C12,
+  GPIO_SKL_H_GPP_C13,
+  GPIO_SKL_H_GPP_B9
+};
+
+GPIO_CONFIG              mBoardAndRevIdConfig = {
+  // Board and Revision ID pads configuration required for proper reading the values
+  GpioPadModeGpio, GpioHostOwnDefault, GpioDirIn, GpioOutDefault, GpioIntDefault,
+    GpioPlatformReset, GpioTermDefault, GpioLockDefault, GpioRxRaw1Default
+};
+
+
+VOID
+GpioConfigForBoardId (
+  VOID
+  )
+{
+  UINT8                   i;
+  EFI_STATUS              Status;
+  GPIO_CONFIG             PadConfig;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+  PadConfig.PadMode          = mBoardAndRevIdConfig.PadMode;
+  PadConfig.HostSoftPadOwn   = mBoardAndRevIdConfig.HostSoftPadOwn;
+  PadConfig.Direction        = mBoardAndRevIdConfig.Direction;
+  PadConfig.OutputState      = mBoardAndRevIdConfig.OutputState;
+  PadConfig.InterruptConfig  = mBoardAndRevIdConfig.InterruptConfig;
+  PadConfig.PowerConfig      = mBoardAndRevIdConfig.PowerConfig;
+  PadConfig.ElectricalConfig = mBoardAndRevIdConfig.ElectricalConfig;
+  PadConfig.LockConfig       = mBoardAndRevIdConfig.LockConfig;
+  PadConfig.OtherSettings    = mBoardAndRevIdConfig.OtherSettings;
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  for (i = 0; i < BOARD_ID_GPIO_PADS_NUMBER; i++) {
+    Status = DynamicSiLibraryPpi->GpioSetPadConfig (mBoardId[i], &PadConfig);
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+
+VOID
+GpioConfigForBoardRevId (
+  VOID
+  )
+{
+  UINT8                   i;
+  EFI_STATUS              Status;
+  GPIO_CONFIG             PadConfig;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+  PadConfig.PadMode          = mBoardAndRevIdConfig.PadMode;
+  PadConfig.HostSoftPadOwn   = mBoardAndRevIdConfig.HostSoftPadOwn;
+  PadConfig.Direction        = mBoardAndRevIdConfig.Direction;
+  PadConfig.OutputState      = mBoardAndRevIdConfig.OutputState;
+  PadConfig.InterruptConfig  = mBoardAndRevIdConfig.InterruptConfig;
+  PadConfig.PowerConfig      = mBoardAndRevIdConfig.PowerConfig;
+  PadConfig.ElectricalConfig = mBoardAndRevIdConfig.ElectricalConfig;
+  PadConfig.LockConfig       = mBoardAndRevIdConfig.LockConfig;
+  PadConfig.OtherSettings    = mBoardAndRevIdConfig.OtherSettings;
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  for (i = 0; i < BOARD_REV_ID_GPIO_PADS_NUMBER; i++) {
+    Status = DynamicSiLibraryPpi->GpioSetPadConfig (mBoardRevId[i], &PadConfig);
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+/**
+
+    Reads GPIO pins to get Board ID value
+
+    @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetBoardId (
+  OUT UINT32 *BoardId
+  )
+{
+  EFI_STATUS              Status = EFI_DEVICE_ERROR;
+  UINT32                  Data32;
+  UINT8                   i;
+  UINT32                  BdId;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+  if (BoardId == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  BdId = 0;
+
+  GpioConfigForBoardId ();
+
+  for (i = 0; i < BOARD_ID_GPIO_PADS_NUMBER; i++) {
+    Status = DynamicSiLibraryPpi->GpioGetInputValue (mBoardId[i], &Data32);
+    if (EFI_ERROR(Status)) {
+      break;
+    }
+    if (Data32) {
+      BdId = BdId | (1 << i);
+    }
+  }
+  if (Status != EFI_SUCCESS) {
+    return Status;
+  }
+  *BoardId = BdId;
+  return EFI_SUCCESS;
+}
+
+/**
+
+    Reads GPIO pins to get Board Revision ID value
+
+    @retval Status - Success if GPIO's are read properly
+
+**/
+EFI_STATUS
+GpioGetBoardRevId (
+  OUT UINT32 *BoardRevId
+  )
+{
+  EFI_STATUS              Status = EFI_DEVICE_ERROR;
+  UINT32                  Data32;
+  UINT8                   i;
+  UINT32                  RevId;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+  if (BoardRevId == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  RevId = 0;
+
+  GpioConfigForBoardRevId ();
+
+  for (i = 0; i < BOARD_REV_ID_GPIO_PADS_NUMBER; i++){
+    Status =  DynamicSiLibraryPpi->GpioGetInputValue (mBoardRevId[i], &Data32);
+    if (EFI_ERROR(Status)) {
+      break;
+    }
+    if (Data32) {
+      RevId = RevId | (1 << i);
+    }
+  }
+  if (Status != EFI_SUCCESS) {
+    return Status;
+  }
+  *BoardRevId = RevId;
+  return EFI_SUCCESS;
+
+}
+
+/**
+
+   Returns the Model ID of the CPU.
+   Model ID = EAX[7:4]
+
+**/
+VOID
+GetCpuInfo (
+  UINT32    *CpuType,
+  UINT8     *CpuStepping
+  )
+
+{
+  UINT32                    RegEax=0;
+
+  AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
+
+  *CpuStepping = (UINT8) (RegEax & 0x0F);
+  *CpuType     = (UINT32) (RegEax >> 4);
+}
+
+
+/**
+
+    GC_TODO: add routine description
+
+    @param BAR         - GC_TODO: add arg description
+    @param PeiServices - GC_TODO: add arg description
+
+    @retval None
+
+**/
+VOID
+InitGSX(
+  UINT32                *BAR,
+  IN EFI_PEI_SERVICES  **PeiServices
+)
+{
+}
+
+/**
+
+    GC_TODO: add routine description
+
+    @param Data        - GC_TODO: add arg description
+    @param PeiServices - GC_TODO: add arg description
+
+    @retval EFI_SUCCESS     - GC_TODO: add retval description
+    @retval EFI_UNSUPPORTED - GC_TODO: add retval description
+
+**/
+EFI_STATUS
+GsxRead(
+   UINT32                *Data,
+   IN EFI_PEI_SERVICES  **PeiServices
+)
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+    GC_TODO: add routine description
+
+    @param Data        - GC_TODO: add arg description
+    @param PeiServices - GC_TODO: add arg description
+
+    @retval None
+
+**/
+VOID
+GetGsxBoardID(
+   BOARD_ID             *Data,
+   IN EFI_PEI_SERVICES  **PeiServices
+)
+{
+
+  EFI_STATUS                Status;
+  UINT32                    GSXIN[2];
+  UINT32                    RetryCount;
+
+  RetryCount = 0;
+  GSXIN[0]   = 0;
+  GSXIN[1]   = 0;
+
+  do {
+    Status     = GsxRead(GSXIN, PeiServices);
+
+    if(Status){
+      // if EFI_SUCCESS != Success then retry one more time
+      RetryCount ++;
+    }else{
+      // if EFI_SUCCESS read Board ID and exit
+      RetryCount = 0xFFFFFFFF;
+    }
+
+    if (GSXIN[0] & BIT0) {
+      Data->BoardID.BoardID0 = 1;
+    }
+
+    if (GSXIN[0] & BIT1) {
+      Data->BoardID.BoardID1 = 1;
+    }
+
+    if (GSXIN[0] & BIT2) {
+      Data->BoardID.BoardID2 = 1;
+    }
+
+    if (GSXIN[0] & BIT3) {
+      Data->BoardID.BoardID3 = 1;
+    }
+
+    if (GSXIN[0] & BIT4) {
+      Data->BoardID.BoardID4 = 1;
+    }
+
+    if (GSXIN[0] & BIT5) {
+      Data->BoardID.BoardRev0 = 1;
+    }
+
+    if (GSXIN[0] & BIT6) {
+      Data->BoardID.BoardRev1 = 1;
+    }
+
+  } while(RetryCount < 1);
+
+  if(Status){
+    //
+    // Unhable to read GSX HW error Hang the system
+    //
+    DEBUG ((EFI_D_ERROR, "ERROR: GSX HW is unavailable, SYSTEM HANG\n"));
+    CpuDeadLoop ();
+  }
+}
+
+/**
+    Get Platform Type by read Platform Data Region in SPI flash.
+    SPI Descriptor Mode Routines for Accessing Platform Info from Platform Data Region (PDR)
+
+    @param PeiServices  -  General purpose services available to every PEIM.
+    @param PlatformInfoHob - Platform Type is returned in PlatformInfoHob->BoardId
+
+    @retval Status EFI_SUCCESS - PDR read success
+    @retval Status EFI_INCOMPATIBLE_VERSION - PDR read but it is not valid Platform Type
+
+**/
+EFI_STATUS
+PdrGetPlatformInfo (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  OUT EFI_PLATFORM_INFO         *PlatformInfoHob
+  )
+{
+  EFI_STATUS              Status;
+  PCH_SPI_PROTOCOL        *SpiPpi;
+  UINTN                   Size;
+
+  //
+  // Locate the SPI PPI Interface
+  //
+  Status = (*PeiServices)->LocatePpi (
+                    PeiServices,
+                    &gPchSpiPpiGuid,
+                    0,
+                    NULL,
+                    &SpiPpi
+                    );
+
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // Read the PIT (Platform Info Table) from the SPI Flash Platform Data Region
+  //
+  Size = sizeof (EFI_PLATFORM_INFO);
+  Status = SpiPpi->FlashRead (
+                              SpiPpi,
+                              FlashRegionPlatformData,
+                              PDR_REGION_START_OFFSET,
+                              (UINT32) Size,
+                              (UINT8 *) PlatformInfoHob
+                             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  if ((PlatformInfoHob->BoardId >= TypePlatformMin) && (PlatformInfoHob->BoardId <= TypePlatformMax)) {
+    //
+    // Valid Platform Identified
+    //
+    DEBUG ((DEBUG_INFO, "Platform Info from PDR: Type = %x\n",PlatformInfoHob->BoardId));
+  } else {
+    //
+    // Reading PIT from SPI PDR Failed or a unknown platform identified
+    //
+    DEBUG ((EFI_D_ERROR, "PIT from SPI PDR reports Platform ID as %x. This is unknown ID. Assuming Greencity Platform!\n", PlatformInfoHob->BoardId));
+    PlatformInfoHob->BoardId = TypePlatformUnknown;
+    Status = EFI_INCOMPATIBLE_VERSION;
+  }
+  return Status;
+}
+
+VOID
+GatherQATInfo(OUT EFI_PLATFORM_INFO   *PlatformInfoHob)
+/**
+
+    GC_TODO: add routine description
+
+    @param None
+
+    @ret None
+**/
+{
+  EFI_STATUS              Status;
+  GPIO_CONFIG             PadConfig;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+    // Gpio programming to QAT board detection
+  PadConfig.PadMode          = GpioPadModeGpio;
+  PadConfig.HostSoftPadOwn   = GpioHostOwnDefault;
+  PadConfig.Direction        = GpioDirIn;
+  PadConfig.OutputState      = GpioOutLow;
+  PadConfig.InterruptConfig  = GpioIntDis;
+  PadConfig.PowerConfig      = GpioResetPwrGood;
+  PadConfig.ElectricalConfig = GpioTermNone;
+  PadConfig.LockConfig       = GpioPadConfigLock;
+  PadConfig.OtherSettings    = 00;
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return;
+  }
+
+  Status = DynamicSiLibraryPpi->GpioSetPadConfig (GPIO_SKL_H_GPP_B3, &PadConfig);
+  Status = DynamicSiLibraryPpi->GpioGetInputValue (GPIO_SKL_H_GPP_B3, &PlatformInfoHob->QATDis);
+  Status = DynamicSiLibraryPpi->GpioSetPadConfig (GPIO_SKL_H_GPP_B4, &PadConfig);
+  Status = DynamicSiLibraryPpi->GpioGetInputValue (GPIO_SKL_H_GPP_B4, &PlatformInfoHob->QATSel);
+}
+
+EFI_STATUS
+GetPlatformInfo (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  OUT EFI_PLATFORM_INFO   *PlatformInfoHob
+  )
+/**
+
+    GC_TODO: add routine description
+
+    @param PeiServices     - GC_TODO: add arg description
+    @param PlatformInfoHob - GC_TODO: add arg description
+
+    @retval EFI_UNSUPPORTED - GC_TODO: add retval description
+    @retval EFI_SUCCESS     - GC_TODO: add retval description
+
+**/
+{
+
+
+  UINT32                  BoardId;
+  UINT32                  BoardRev;
+  EFI_PEI_PCI_CFG2_PPI    *PciCfgPpi;
+  EFI_STATUS              Status;
+
+  PciCfgPpi = (**PeiServices).PciCfg;
+  ASSERT (PciCfgPpi != NULL);
+
+  PlatformInfoHob->BoardId = TypeNeonCityEPRP;
+  DEBUG ((DEBUG_INFO, "Use GPIO to read Board ID\n"));
+
+  Status = GpioGetBoardId (&BoardId);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Error: Can't read GPIO to get Board ID!\n"));
+    return Status;
+  }
+  Status = GpioGetBoardRevId (&BoardRev);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "Error: Can't read GPIO to get Board ID!\n"));
+    return Status;
+  }
+  PlatformInfoHob->TypeRevisionId = BoardRev;
+
+  switch (BoardId) {
+    case 0x00:  // for Simics
+      PlatformInfoHob->BoardId = TypeWilsonCityRP;
+    break;
+    case 0x01:
+      PlatformInfoHob->BoardId = TypeWilsonCityRP;
+      DEBUG ((DEBUG_INFO, "Board ID = TypeWilsonCityRP\n"));
+      break;
+    case 0x12:
+      PlatformInfoHob->BoardId = TypeWilsonCityRP;
+      DEBUG((DEBUG_INFO, "Board ID = TypeWilsonCityRP\n"));
+      break;
+    case 0x15:
+      PlatformInfoHob->BoardId = TypeWilsonCitySMT;
+      DEBUG((DEBUG_INFO, "Board ID = TypeWilsonCitySMT\n"));
+      break;
+    case 0x17:
+    case 0x18:
+      PlatformInfoHob->BoardId = TypeCooperCityRP;
+      DEBUG((DEBUG_INFO, "Board ID = TypeCooperCityRP\n"));
+      break;
+    default:
+      PlatformInfoHob->BoardId = TypePlatformDefault;
+      DEBUG ((DEBUG_INFO, "Board ID = %2X Default set to TypePlatformDefault\n",BoardId));
+      break;
+  }
+
+  GatherQATInfo(PlatformInfoHob);
+
+  DEBUG ((DEBUG_INFO, "Board Rev.: %d\n", BoardRev));
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function initializes the board related flag to indicates if
+  PCH and Lan-On-Motherboard (LOM) devices is supported.
+
+**/
+VOID
+GetPchLanSupportInfo(
+  IN EFI_PLATFORM_INFO   *PlatformInfoHob
+  )
+{
+  PlatformInfoHob->PchData.LomLanSupported  = 0;
+}
+
+/**
+
+    GC_TODO: add routine description
+
+    @param PeiVariable     - GC_TODO: add arg description
+    @param PlatformInfoHob - GC_TODO: add arg description
+
+    @retval EFI_SUCCESS - GC_TODO: add retval description
+
+**/
+EFI_STATUS
+EFIAPI
+GetIioCommonRcPlatformSetupPolicy(
+  OUT EFI_PLATFORM_INFO                     *PlatformInfoHob
+  )
+  {
+  UINT8                                 IsocEn;
+
+  CopyMem (&IsocEn, (UINT8 *)PcdGetPtr(PcdSocketCommonRcConfig) + OFFSET_OF(SOCKET_COMMONRC_CONFIGURATION, IsocEn), sizeof(UINT8));
+
+  PlatformInfoHob->SysData.IsocEn    = IsocEn;       // ISOC enabled
+
+  return EFI_SUCCESS;
+}
+/**
+
+    GC_TODO: add routine description
+
+    @param PeiVariable     - GC_TODO: add arg description
+    @param PlatformInfoHob - GC_TODO: add arg description
+
+    @retval EFI_SUCCESS - GC_TODO: add retval description
+
+**/
+EFI_STATUS
+EFIAPI
+GetIioPlatformSetupPolicy(
+  OUT EFI_PLATFORM_INFO                     *PlatformInfoHob
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Platform Type detection. Because the PEI globle variable
+  is in the flash, it could not change directly.So use
+  2 PPIs to distinguish the platform type.
+
+  @param FfsHeader    -  Pointer to Firmware File System file header.
+  @param PeiServices  -  General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS  -  Memory initialization completed successfully.
+  @retval Others       -  All other error conditions encountered result in an ASSERT.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInfoInit (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PEI_PCI_CFG2_PPI    *PciCfgPpi;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI       *PeiVariable;
+  EFI_PLATFORM_INFO       PlatformInfoHob;
+  EFI_PLATFORM_INFO       tempPlatformInfoHob;
+  UINT8                   ChipId;
+  UINT32                  Delay;
+  UINT32                  CpuType;
+  UINT8                   CpuStepping;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+  PciCfgPpi = (**PeiServices).PciCfg;
+  if (PciCfgPpi == NULL) {
+    DEBUG ((EFI_D_ERROR, "\nError! PlatformInfoInit() - PeiServices is a NULL Pointer!!!\n"));
+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Locate Variable PPI
+  //
+  Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, &PeiVariable);
+
+  (*PeiServices)->SetMem (&PlatformInfoHob, sizeof (PlatformInfoHob), 0);
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // --------------------------------------------------
+  //
+  // Detect the iBMC SIO for CV/CRB Platforms
+  // 0x2E/0x2F decoding has been enabled in MonoStatusCode PEIM.
+  //
+  IoWrite8 (PILOTIV_SIO_INDEX_PORT, PILOTIV_SIO_UNLOCK);
+  for (Delay = 0; Delay < 40; Delay++) IoRead8  (0x61);
+  IoWrite8 (PILOTIV_SIO_INDEX_PORT, PILOTIV_CHIP_ID_REG);
+  for (Delay = 0; Delay < 40; Delay++) IoRead8  (0x61);
+  ChipId = IoRead8  (PILOTIV_SIO_DATA_PORT);
+  for (Delay = 0; Delay < 40; Delay++) IoRead8  (0x61);
+  IoWrite8 (PILOTIV_SIO_INDEX_PORT, PILOTIV_SIO_LOCK);
+  for (Delay = 0; Delay < 40; Delay++) IoRead8  (0x61);
+
+  if (EFI_ERROR (Status))
+  {
+        DEBUG((EFI_D_ERROR, "LocatePpi Error in PlatformInfo.c !\n"));
+  }
+
+  Status = GetIioPlatformSetupPolicy (&PlatformInfoHob);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetIioCommonRcPlatformSetupPolicy (&PlatformInfoHob);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update PCH Type
+  //
+  PlatformInfoHob.PchType = DynamicSiLibraryPpi->GetPchSeries ();
+  PlatformInfoHob.PchSku = DynamicSiLibraryPpi->GetPchLpcDeviceId ();
+  PlatformInfoHob.PchRevision = (UINT8) DynamicSiLibraryPpi->PchStepping ();
+  PlatformInfoHob.MaxNumOfPchs = 1;
+  Status = EFI_SUCCESS;
+
+    if(!EFI_ERROR(Status)) {
+      Status = GetPlatformInfo (PeiServices, &PlatformInfoHob);
+      if(EFI_ERROR (Status)) {
+        Status = PdrGetPlatformInfo (PeiServices, &tempPlatformInfoHob);
+        PlatformInfoHob.BoardId = tempPlatformInfoHob.BoardId;
+        PlatformInfoHob.TypeRevisionId = tempPlatformInfoHob.TypeRevisionId;
+        if (EFI_ERROR(Status)) {
+          PlatformInfoHob.BoardId = TypePlatformUnknown;
+        }
+      }
+    } else {
+      PlatformInfoHob.BoardId = TypePlatformUnknown;
+    }
+
+  //
+  // Update IIO Type
+  //
+  PlatformInfoHob.IioRevision = 0;
+
+
+  //
+  // Get Subtractive decode enable bit from descriptor
+  //
+
+  if (DynamicSiLibraryPpi->PchIsGbeRegionValid () == FALSE) {
+    PlatformInfoHob.PchData.GbeRegionInvalid = 1;
+  } else {
+    PlatformInfoHob.PchData.GbeRegionInvalid = 0;
+  }
+  GetPchLanSupportInfo (&PlatformInfoHob);
+  PlatformInfoHob.PchData.GbePciePortNum = 0xFF;
+  PlatformInfoHob.PchData.GbePciePortNum = (UINT8) DynamicSiLibraryPpi->PchGetGbePortNumber ();
+  PlatformInfoHob.PchData.GbeEnabled  = DynamicSiLibraryPpi->PchIsGbePresent ();
+  PlatformInfoHob.PchData.PchStepping = (UINT8) DynamicSiLibraryPpi->PchStepping ();
+
+  PlatformInfoHob.SysData.SysSioExist = (UINT8)IsSioExist();
+
+  GetCpuInfo (&CpuType, &CpuStepping);
+  PlatformInfoHob.CpuType     = CpuType;
+  PlatformInfoHob.CpuStepping = CpuStepping;
+
+  //
+  // Set default memory topology to DaisyChainTopology. This should be modified in UBA board
+  // specific file.
+  //
+  (*PeiServices)->SetMem (&PlatformInfoHob.MemoryTopology, sizeof (PlatformInfoHob.MemoryTopology), DaisyChainTopology);
+
+  //
+  // Set default memory type connector to DimmConnectorPth. This should be modified in UBA board
+  // specific file.
+  //
+  (*PeiServices)->SetMem (&PlatformInfoHob.MemoryConnectorType, sizeof (PlatformInfoHob.MemoryConnectorType), DimmConnectorPth);
+
+  //
+  // Build HOB for setup memory information
+  //
+  BuildGuidDataHob (
+      &gEfiPlatformInfoGuid,
+      &(PlatformInfoHob),
+      sizeof (EFI_PLATFORM_INFO)
+      );
+
+  Status = (**PeiServices).InstallPpi (PeiServices, &mPlatformInfoPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Save PlatformInfoHob.BoardId in CMOS
+  //
+  IoWrite8 (R_IOPORT_CMOS_UPPER_INDEX, CMOS_PLATFORM_ID_LO);
+  IoWrite8 (R_IOPORT_CMOS_UPPER_DATA, (UINT8)PlatformInfoHob.BoardId);
+
+  IoWrite8 (R_IOPORT_CMOS_UPPER_INDEX, CMOS_PLATFORM_ID_HI);
+  IoWrite8 (R_IOPORT_CMOS_UPPER_DATA, (UINT8)((PlatformInfoHob.PcieRiser2Type << 4) + (PlatformInfoHob.PcieRiser1Type)));
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.h b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.h
new file mode 100644
index 0000000000..5e46db8f0f
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.h
@@ -0,0 +1,89 @@
+/** @file
+  Platform Info Driver.
+
+  @copyright
+  Copyright 1999 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_INFO_INTERNAL_H_
+#define _PLATFORM_INFO_INTERNAL_H_
+
+#include <PiPei.h>
+#include <Ppi/CpuIo.h>
+#include <Ppi/Spi.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PlatformHooksLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/SocketVariable.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PlatformInfo.h>
+#include <IndustryStandard/Pci22.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioLib.h>
+#include <Platform.h>
+#include "SioRegs.h"
+#include <Register/PchRegsSpi.h>
+#include <PchAccess.h>
+#include <Register/PchRegsLpc.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Register/Cpuid.h>
+
+#define EFI_PLATFORMINFO_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('P', 'I', 'N', 'F')
+
+//
+// CPU Model
+//
+#define  INVALID_MODEL             0x0
+
+#define R_SB_SPI_FDOC         0xB0
+#define R_SB_SPI_FDOD         0xB4
+#define SPI_OPCODE_READ_INDEX            4
+#define PDR_REGION_START_OFFSET    0x0
+
+typedef union BOARD_ID
+{
+   struct{
+      UINT8  BoardID0            :1;
+      UINT8  BoardID1            :1;
+      UINT8  BoardID2            :1;
+      UINT8  BoardID3            :1;
+      UINT8  BoardID4            :1;
+      UINT8  BoardRev0           :1;
+      UINT8  BoardRev1           :1;
+      UINT8  Rsvd                :1;
+   }BoardID;
+}BOARD_ID;
+
+typedef union RISER_ID
+{
+   struct{
+      UINT8  RiserID0            :1;
+      UINT8  RiserID1            :1;
+      UINT8  RiserID2            :1;
+      UINT8  RiserID3            :1;
+      UINT8  Rsvd                :4;
+   }RiserID;
+}RISER_ID;
+
+
+
+EFI_STATUS
+PdrGetPlatformInfo (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  OUT EFI_PLATFORM_INFO   *PlatformInfoHob
+  );
+
+EFI_STATUS
+GPIOGetPlatformInfo (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  OUT EFI_PLATFORM_INFO   *PlatformInfoHob
+);
+
+#endif
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.inf b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.inf
new file mode 100644
index 0000000000..69d926004d
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Platform/Pei/PlatformInfo/PlatformInfo.inf
@@ -0,0 +1,63 @@
+## @file
+# PlatformInfo PEIM
+#
+# @copyright
+# Copyright 2009 - 2021 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformInfo
+  FILE_GUID                      = 34CC6167-7AE7-403e-8AB2-23837F398A30
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformInfoInit
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  PlatformInfo.c
+  PlatformInfo.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PcdLib
+  DebugLib
+  HobLib
+  IoLib
+  PlatformHooksLib
+  PeiServicesLib
+
+[Pcd]
+  gStructPcdTokenSpaceGuid.PcdSocketCommonRcConfig
+
+[Guids]
+  gEfiPlatformInfoGuid
+  gEfiSetupVariableGuid
+
+[Ppis]
+  gPchSpiPpiGuid
+  gEfiPeiReadOnlyVariable2PpiGuid
+  gDynamicSiLibraryPpiGuid                 ## CONSUMES
+
+[Depex]
+  gPchSpiPpiGuid AND
+  gEfiPeiReadOnlyVariable2PpiGuid AND
+  gDynamicSiLibraryPpiGuid
+
+
+
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExSerialStatusCodeWorker.c b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExSerialStatusCodeWorker.c
new file mode 100644
index 0000000000..4336f330e3
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExSerialStatusCodeWorker.c
@@ -0,0 +1,194 @@
+/** @file
+
+  @copyright
+  Copyright 2017 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "ExStatusCodeHandlerPei.h"
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ExSerialStatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[MAX_EX_DEBUG_STR_LEN];
+  CHAR8           *BufferPtr;
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+  EX_DEBUG_INFO   *ExDebugInfo = NULL;
+
+  Buffer[0] = '\0';
+  CharCount = 0;
+
+  if (Data != NULL &&
+      CompareGuid (&Data->Type, &gStatusCodeDataTypeExDebugGuid)) {
+    ExDebugInfo = (EX_DEBUG_INFO*)(Data + 1);
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rPEI_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  Format,
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "ERROR: C%08x:V%08x I%x",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+
+    ASSERT(CharCount > 0);
+
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "PROGRESS CODE: V%08x I%x\n\r",
+                  Value,
+                  Instance
+                  );
+  } else if (Data != NULL &&
+             CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
+             ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
+    //
+    // EFI_STATUS_CODE_STRING_DATA
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "%a\n\r",
+                  ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "Undefined: C%08x:V%08x I%x\n\r",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+  }
+
+  //
+  // No EX info, just print and exit.
+  //
+  if (ExDebugInfo == NULL) {
+    SerialPortWrite ((UINT8*)Buffer, CharCount);
+    return EFI_SUCCESS;
+  }
+
+  //
+  // EX handling here - point at correct string and then take action.
+  // Acquire print, process buffer, write to serial, release print.
+  // Skip any if not requested.
+  //
+  CharCount = ExDebugInfo->DebugStringLen;
+  BufferPtr = ExDebugInfo->DebugString;
+  if (ExDebugInfo->PrintSyncAcquire != NULL) {
+    ExDebugInfo->PrintSyncAcquire ();
+  }
+  if (ExDebugInfo->ProcessBuffer != NULL) {
+    BufferPtr = ExDebugInfo->ProcessBuffer (
+                               ExDebugInfo->ProcessDataPtr,
+                               Buffer,
+                               &CharCount
+                               );
+  }
+  if (BufferPtr != NULL) {
+    SerialPortWrite ((UINT8*)BufferPtr, CharCount);
+  }
+  if (ExDebugInfo != NULL && ExDebugInfo->PrintSyncRelease != NULL) {
+    ExDebugInfo->PrintSyncRelease ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.c b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.c
new file mode 100644
index 0000000000..5fe58d5d00
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.c
@@ -0,0 +1,111 @@
+/** @file
+
+  @copyright
+  Copyright 2017 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "ExStatusCodeHandlerPei.h"
+
+EFI_PEI_EX_RSC_HANDLER_PPI  mExStatusCodeHandlerPpi = {
+  RegisterExStatusCodeHandler
+  };
+
+EFI_PEI_PPI_DESCRIPTOR   mExStatusCodeHandlerPpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiExStatusCodeHandlerPpiGuid,
+    &mExStatusCodeHandlerPpi
+  }
+};
+
+/**
+  Registers ExSerialStatusCodeReportWorker as callback function for ReportStatusCode() notification.
+
+
+  @param[in] PeiServices        Pointer to PEI Services Table.
+
+  @retval EFI_SUCCESS           Function was successfully registered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_OUT_OF_RESOURCES  The internal buffer ran out of space. No more functions can be
+                                registered.
+  @retval EFI_ALREADY_STARTED   The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterExStatusCodeHandler (
+  IN CONST  EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PEI_RSC_HANDLER_PPI     *RscHandlerPpi;
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiRscHandlerPpiGuid,
+             0,
+             NULL,
+             (VOID **) &RscHandlerPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  if (PcdGetBool (PcdStatusCodeUseSerial)) {
+    Status = RscHandlerPpi->Register (ExSerialStatusCodeReportWorker);
+    if (Status != EFI_ALREADY_STARTED) {
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+  return Status;
+}
+
+/**
+  Entry point of EX Status Code PEIM.
+
+  This function is the entry point of this EX Status Code PEIM.
+  It initializes serial port status code handler with policy features.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCESS  The entry point of PEIM executes successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ExStatusCodeHandlerPeiEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+  UINT32                      DebugPrintErrorLevel;
+
+  //
+  // Dispatch initialization request to sub-statuscode-devices.
+  //
+  Status = SerialPortInitialize();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // If serial logging is disabled. set PcdStatusCodeUseSerial to FALSE.
+  //
+
+  DebugPrintErrorLevel = GetDebugPrintErrorLevel ();
+  if (DebugPrintErrorLevel == 0) {
+    Status = PcdSetBoolS (PcdStatusCodeUseSerial, FALSE);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = RegisterExStatusCodeHandler (PeiServices);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install Report Status Code Handler PPI
+  //
+  Status = PeiServicesInstallPpi (mExStatusCodeHandlerPpiList);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.h b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.h
new file mode 100644
index 0000000000..4d101a0c2d
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.h
@@ -0,0 +1,85 @@
+/** @file
+
+  @copyright
+  Copyright 2017 - 2021 Intel Corporation. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __EX_STATUS_CODE_HANDLER_PEI_H__
+#define __EX_STATUS_CODE_HANDLER_PEI_H__
+
+
+#include <Ppi/ReportStatusCodeHandler.h>
+#include <Ppi/ExReportStatusCodeHandler.h>
+
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+#include <Guid/StatusCodeDataTypeExDebug.h>
+
+#include <Library/DebugLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SemaphoreLib.h>
+
+/**
+  Registers ExSerialStatusCodeReportWorker as callback function for ReportStatusCode() notification.
+
+
+  @param[in] PeiServices        Pointer to PEI Services Table.
+
+  @retval EFI_SUCCESS           Function was successfully registered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_OUT_OF_RESOURCES  The internal buffer ran out of space. No more functions can be
+                                registered.
+  @retval EFI_ALREADY_STARTED   The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterExStatusCodeHandler (
+  IN CONST  EFI_PEI_SERVICES           **PeiServices
+  );
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ExSerialStatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  );
+
+#endif // __EX_STATUS_CODE_HANDLER_PEI_H__
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.inf b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.inf
new file mode 100644
index 0000000000..083de9850f
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeHandler/ExStatusCodeHandlerPei.inf
@@ -0,0 +1,61 @@
+## @file
+#  Report Status Code Handler PEIM which produces general handlers and hook them onto the PEI status code router.
+#
+#  @copyright
+#  Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ExStatusCodeHandlerPei
+  FILE_GUID                      = 75E78806-C68F-4839-8A68-B29084820659
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ExStatusCodeHandlerPeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC (EBC is only for build)
+#
+
+[Sources]
+  ExStatusCodeHandlerPei.c
+  ExStatusCodeHandlerPei.h
+  ExSerialStatusCodeWorker.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  PcdLib
+  HobLib
+  SerialPortLib
+  ReportStatusCodeLib
+  PrintLib
+  DebugLib
+  DebugPrintErrorLevelLib
+  BaseMemoryLib
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial     ## CONSUMES
+
+[Guids]
+  gEfiStatusCodeDataTypeStringGuid              ## SOMETIMES_CONSUMES
+  gStatusCodeDataTypeExDebugGuid                ## SOMETIMES_CONSUMES
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
+  gEfiPeiExStatusCodeHandlerPpiGuid             ## PRODUCES
+
+[Depex]
+  gEfiPeiRscHandlerPpiGuid
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.c b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.c
new file mode 100644
index 0000000000..99dd891ccd
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.c
@@ -0,0 +1,301 @@
+/** @file
+  Report Status Code Router PEIM which produces Report Stataus Code Handler PPI and Status Code PPI.
+
+  @copyright
+  Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "ExReportStatusCodeRouterPei.h"
+
+EFI_PEI_RSC_HANDLER_PPI     mRscHandlerPpi = {
+  Register,
+  Unregister
+  };
+
+EFI_PEI_PROGRESS_CODE_PPI     mStatusCodePpi = {
+  ReportDispatcher
+  };
+
+EFI_PEI_PPI_DESCRIPTOR   mRscHandlerPpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiRscHandlerPpiGuid,
+    &mRscHandlerPpi
+  }
+};
+
+EFI_PEI_PPI_DESCRIPTOR   mStatusCodePpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiStatusCodePpiGuid,
+    &mStatusCodePpi
+  }
+};
+
+/**
+  Worker function to create one memory status code GUID'ed HOB,
+  using PacketIndex to identify the packet.
+
+  @param   PacketIndex    Index of records packet.
+
+  @return  Pointer to the memory status code packet.
+
+**/
+UINTN *
+CreateRscHandlerCallbackPacket (
+  VOID
+  )
+{
+  UINTN                         *NumberOfEntries;
+  EFI_PEI_RSC_HANDLER_CALLBACK  *CallbackEntry;
+  UINT16                        Index;
+
+  //
+  // Build GUID'ed HOB with PCD defined size.
+  //
+  NumberOfEntries = BuildGuidHob (
+                      &gStatusCodeCallbackGuid,
+                      sizeof (EFI_PEI_RSC_HANDLER_CALLBACK) * 64 + sizeof (UINTN)
+                      );
+  ASSERT (NumberOfEntries != NULL);
+  if (NumberOfEntries == NULL) {
+    return NumberOfEntries;
+  }
+
+  *NumberOfEntries = 0;
+  CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+
+  for (Index = 0; Index < 64; Index++) {
+    CallbackEntry[Index] = NULL;
+  }
+
+  return NumberOfEntries;
+}
+
+/**
+  Register the callback function for ReportStatusCode() notification.
+
+  When this function is called the function pointer is added to an internal list and any future calls to
+  ReportStatusCode() will be forwarded to the Callback function.
+
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is called
+                                when a call to ReportStatusCode() occurs.
+
+  @retval EFI_SUCCESS           Function was successfully registered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_OUT_OF_RESOURCES  The internal buffer ran out of space. No more functions can be
+                                registered.
+  @retval EFI_ALREADY_STARTED   The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+Register (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  )
+{
+  EFI_PEI_HOB_POINTERS          Hob;
+  EFI_PEI_RSC_HANDLER_CALLBACK  *CallbackEntry;
+  UINTN                         *NumberOfEntries;
+  UINTN                         Index;
+
+  if (Callback == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Hob.Raw        = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+  if (Hob.Raw != NULL) {
+    NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+    CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+    if (*NumberOfEntries >= 64) {
+      //
+      // If current total number of handlers does exceed 64, bail
+      //
+      return EFI_OUT_OF_RESOURCES;
+    }
+    for (Index = 0; Index <= *NumberOfEntries; Index++) {
+      if (CallbackEntry[Index] == Callback) {
+        //
+        // If the function was already registered. It can't be registered again.
+        //
+        return EFI_ALREADY_STARTED;
+      }
+      if (CallbackEntry[Index] == NULL) {
+        //
+        // If the total number of handlers in current packet is max value 64,
+        // search an entry with NULL pointer and fill new handler into this entry.
+        //
+        *NumberOfEntries += 1;
+        CallbackEntry[Index] = Callback;
+
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Remove a previously registered callback function from the notification list.
+
+  ReportStatusCode() messages will no longer be forwarded to the Callback function.
+
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is to be
+                                unregistered.
+
+  @retval EFI_SUCCESS           The function was successfully unregistered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_NOT_FOUND         The callback function was not found to be unregistered.
+
+**/
+EFI_STATUS
+EFIAPI
+Unregister (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  )
+{
+  EFI_PEI_HOB_POINTERS            Hob;
+  EFI_PEI_RSC_HANDLER_CALLBACK    *CallbackEntry;
+  UINTN                           *NumberOfEntries;
+  UINTN                           Index;
+
+  if (Callback == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Hob.Raw  = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+  if (Hob.Raw != NULL) {
+    NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+    CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+    for (Index = 0; Index < *NumberOfEntries; Index++) {
+      if (CallbackEntry[Index] == Callback) {
+        //
+        // Set removed entry as NULL.
+        //
+        CallbackEntry[Index] = NULL;
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Publishes an interface that allows PEIMs to report status codes.
+
+  This function implements EFI_PEI_PROGRESS_CODE_PPI.ReportStatusCode().
+  It publishes an interface that allows PEIMs to report status codes.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId OPTIONAL,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  EFI_PEI_HOB_POINTERS            Hob;
+  EFI_PEI_RSC_HANDLER_CALLBACK    *CallbackEntry;
+  UINTN                           *NumberOfEntries;
+  UINTN                           Index;
+
+  Hob.Raw  = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+  if (Hob.Raw != NULL) {
+    NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+    CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+    for (Index = 0; Index < *NumberOfEntries; Index++) {
+      if (CallbackEntry[Index] != NULL) {
+      CallbackEntry[Index](
+        PeiServices,
+        CodeType,
+        Value,
+        Instance,
+        CallerId,
+        Data
+        );
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Entry point of Status Code PEIM.
+
+  This function is the entry point of this Status Code Router PEIM.
+  It produces Report Stataus Code Handler PPI and Status Code PPI.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GenericStatusCodePeiEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS                 Status;
+  EFI_PEI_PPI_DESCRIPTOR     *OldDescriptor;
+  EFI_PEI_PROGRESS_CODE_PPI  *OldStatusCodePpi;
+
+  CreateRscHandlerCallbackPacket ();
+
+  //
+  // Install Report Status Code Handler PPI
+  //
+  Status = PeiServicesInstallPpi (mRscHandlerPpiList);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install Status Code PPI. PI spec specifies that there can be only one instance
+  // of this PPI in system. So first check if other instance already exists.
+  // If no other instance exists, then just install the PPI.
+  // If other instance already exists, then reinstall it.
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiStatusCodePpiGuid,
+             0,
+             &OldDescriptor,
+             (VOID **) &OldStatusCodePpi
+             );
+  if (!EFI_ERROR (Status)) {
+    Status = PeiServicesReInstallPpi (OldDescriptor, mStatusCodePpiList);
+  } else {
+    Status = PeiServicesInstallPpi (mStatusCodePpiList);
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.h b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.h
new file mode 100644
index 0000000000..32b709ca15
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.h
@@ -0,0 +1,104 @@
+/** @file
+  Internal include file for Report Status Code Router PEIM.
+
+  @copyright
+  Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PEI_REPORT_STATUS_CODE_ROUTER_H__
+#define __PEI_REPORT_STATUS_CODE_ROUTER_H__
+
+
+#include <Ppi/ReportStatusCodeHandler.h>
+#include <Ppi/StatusCode.h>
+
+#include <Guid/StatusCodeCallbackGuid.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+
+/**
+  Register the callback function for ReportStatusCode() notification.
+
+  When this function is called the function pointer is added to an internal list and any future calls to
+  ReportStatusCode() will be forwarded to the Callback function.
+
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is called
+                                when a call to ReportStatusCode() occurs.
+
+  @retval EFI_SUCCESS           Function was successfully registered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_OUT_OF_RESOURCES  The internal buffer ran out of space. No more functions can be
+                                registered.
+  @retval EFI_ALREADY_STARTED   The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+Register (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  );
+
+/**
+  Remove a previously registered callback function from the notification list.
+
+  ReportStatusCode() messages will no longer be forwarded to the Callback function.
+
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is to be
+                                unregistered.
+
+  @retval EFI_SUCCESS           The function was successfully unregistered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_NOT_FOUND         The callback function was not found to be unregistered.
+
+**/
+EFI_STATUS
+EFIAPI
+Unregister (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  );
+
+/**
+  Publishes an interface that allows PEIMs to report status codes.
+
+  This function implements EFI_PEI_PROGRESS_CODE_PPI.ReportStatusCode().
+  It publishes an interface that allows PEIMs to report status codes.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId OPTIONAL,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  );
+
+#endif
+
+
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.inf b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.inf
new file mode 100644
index 0000000000..b46775ab55
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiExStatusCodeRouter/ExReportStatusCodeRouterPei.inf
@@ -0,0 +1,51 @@
+## @file
+#  Report Status Code Router PEIM which produces Report Stataus Code Handler PPI and Status Code PPI.
+#
+#  @copyright
+#  Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ExReportStatusCodeRouterPei
+  FILE_GUID                      = 1DDA5978-B29A-4EA7-AEFB-8B0BAA982E22
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = GenericStatusCodePeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is only for build)
+#
+
+[Sources]
+  ExReportStatusCodeRouterPei.c
+  ExReportStatusCodeRouterPei.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  DebugLib
+  HobLib
+
+[Guids]
+  ## PRODUCES ## HOB
+  ## CONSUMES ## HOB
+  gStatusCodeCallbackGuid
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## PRODUCES
+  gEfiPeiStatusCodePpiGuid                      ## PRODUCES
+
+
+[Depex]
+  TRUE
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.c b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.c
new file mode 100644
index 0000000000..1fdefe9ef6
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.c
@@ -0,0 +1,136 @@
+/** @file
+  File to update SVID values from Interposer mapping.
+
+ at copyright
+  Copyright 2018 - 2021 Intel Corporation.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Guid/PlatformInfo.h>
+#include <Library/HobLib.h>
+#include <Library/MemVrSvidMapLib.h>
+#include <Ppi/DynamicSiLibraryPpi.h>
+
+/**
+  After Memory policy installation need to map SVID in case of an Interposer is present.
+
+  @param[in]  PeiServices       General purpose services available to every PEIM.
+  @param[in]  NotifyDescriptor  Notify that this module published.
+  @param[in]  Ppi               PPI that was installed.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+MapInterposerToSvid (
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  INTERPOSER_TYPE         InterposerType;
+  EFI_PLATFORM_INFO       *PlatformInfo;
+  EFI_HOB_GUID_TYPE       *GuidHob;
+  UINT8                   OriginalMcId = 0;
+  UINT8                   CurrentMcId = 0;
+  UINT8                   Socket = 0;
+  UINT8                   SvidValue = 0;
+  MEM_SVID_MAP            *MemSvidMap;
+  UINTN                   Size;
+  EFI_STATUS              Status;
+  INTERPOSER_MAP          *MemInterposerMap = NULL;
+  BOOLEAN                 InterposerPresent = FALSE;
+  DYNAMIC_SI_LIBARY_PPI   *DynamicSiLibraryPpi = NULL;
+
+  DEBUG ((EFI_D_INFO, "MapInterposerToSvid   Entry\n"));
+
+  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
+  if (GuidHob == NULL) {
+    DEBUG ((EFI_D_INFO, "No Platform Info HOB Detected Exiting...\n"));
+    return EFI_SUCCESS;
+  } else {
+    MemInterposerMap = (INTERPOSER_MAP *) PcdGetPtr (PcdMemInterposerMap);
+    if (MemInterposerMap == NULL) {
+      return EFI_SUCCESS;
+    }
+    Size = sizeof (MEM_SVID_MAP);
+    DEBUG ((EFI_D_INFO, "Allocate memory for MemSvidMap PCD\n"));
+    Status = (*PeiServices)->AllocatePool (PeiServices, Size, &MemSvidMap);
+    ASSERT_EFI_ERROR (Status);
+    ZeroMem (MemSvidMap, Size);
+
+    PlatformInfo = GET_GUID_HOB_DATA (GuidHob);
+    for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+      InterposerType = PlatformInfo->InterposerType[Socket];
+      for (CurrentMcId =0; CurrentMcId < MAX_IMC; CurrentMcId++) {
+        if (InterposerType != InterposerUnknown) {
+          OriginalMcId = MemInterposerMap->Interposer[InterposerType].MappedMcId[CurrentMcId];
+          if (OriginalMcId < MAX_IMC) {
+            Status = DynamicSiLibraryPpi->GetSvidMap (Socket, OriginalMcId, &SvidValue);
+
+            if(Status == EFI_NOT_FOUND) {
+              DEBUG ((DEBUG_ERROR, "PcdMemSrVidMap = NULL\n"));
+            } else {
+              DEBUG ((DEBUG_ERROR, "SocketId = %d, McId = %d, SvidValue = %d\n", Socket, OriginalMcId, SvidValue));
+            }
+
+            MemSvidMap->Socket[Socket].Mc[CurrentMcId] = SvidValue;
+            InterposerPresent = TRUE;
+          }
+          DEBUG ((EFI_D_INFO, "Current MC id = %d, Original MC id = %d, SVID = %d\n", CurrentMcId, OriginalMcId, SvidValue));
+        }
+      }
+    }
+  }
+  if (InterposerPresent) {
+    PcdSetPtrS (PcdMemSrvidMap, &Size, (VOID *) MemSvidMap);
+  } else {
+    DEBUG ((EFI_D_INFO, "No Interposer Present....\n"));
+  }
+
+  DEBUG ((EFI_D_INFO, "MapInterposerToSvid   Exit\n"));
+  return EFI_SUCCESS;
+}
+
+EFI_PEI_NOTIFY_DESCRIPTOR mMapInterposerToSvidNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gMemoryPolicyPpiGuid,
+  MapInterposerToSvid
+};
+
+/**
+  Initialize SVID PCD with Interposer mapping
+
+  @param[in]  FileHandle           Not used.
+  @param[in]  PeiServices          General purpose services available to every PEIM.
+
+  @retval     EFI_SUCCESS          The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InterposerToSvidMapEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  DEBUG ((EFI_D_INFO, "InterposerToSvidMap   Entry\n"));
+
+  Status = PeiServicesNotifyPpi (&mMapInterposerToSvidNotifyList);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_INFO, "InterposerToSvidMap   Exit\n"));
+  return EFI_SUCCESS;;
+}
\ No newline at end of file
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.inf b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.inf
new file mode 100644
index 0000000000..c311425846
--- /dev/null
+++ b/Platform/Intel/WhitleyOpenBoardPkg/Universal/PeiInterposerToSvidMap/PeiInterposerToSvidMap.inf
@@ -0,0 +1,53 @@
+## @file
+# Component description file for PeiInterposerToSvidMap
+#
+# @copyright
+# Copyright 2018 - 2021 Intel Corporation. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiInterposerToSvidMap
+  FILE_GUID                      = DF11893B-FAC7-4812-8DD7-F5DD56889040
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InterposerToSvidMapEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+
+  PeiInterposerToSvidMap.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhitleyOpenBoardPkg/PlatformPkg.dec
+  WhitleySiliconPkg/CpRcPkg.dec
+  WhitleySiliconPkg/WhitleySiliconPkg.dec
+  WhitleySiliconPkg/SiliconPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PeimEntryPoint
+  PcdLib
+  BaseMemoryLib
+
+[Ppis]
+  gMemoryPolicyPpiGuid                     ## CONSUMES
+  gDynamicSiLibraryPpiGuid                 ## CONSUMES
+
+[Guids]
+  gEfiPlatformInfoGuid
+
+[Pcd]
+  gPlatformTokenSpaceGuid.PcdMemInterposerMap
+  gEfiCpRcPkgTokenSpaceGuid.PcdMemSrvidMap
+
+[Depex]
+  gDynamicSiLibraryPpiGuid
-- 
2.27.0.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#77715): https://edk2.groups.io/g/devel/message/77715
Mute This Topic: https://groups.io/mt/84168629/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