public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Nate DeSimone" <nathaniel.l.desimone@intel.com>
To: devel@edk2.groups.io
Cc: Chasel Chiu <chasel.chiu@intel.com>,
	Mike Kinney <michael.d.kinney@intel.com>,
	Isaac Oram <isaac.w.oram@intel.com>,
	Mohamed Abbas <mohamed.abbas@intel.com>,
	Michael Kubacki <michael.kubacki@microsoft.com>,
	Zachary Bobroff <zacharyb@ami.com>,
	Harikrishna Doppalapudi <harikrishnad@ami.com>
Subject: [edk2-platforms] [PATCH V1 08/18] PurleyOpenBoardPkg: Add includes and libraries
Date: Tue, 11 May 2021 02:48:16 -0700	[thread overview]
Message-ID: <20210511094826.12495-9-nathaniel.l.desimone@intel.com> (raw)
In-Reply-To: <20210511094826.12495-1-nathaniel.l.desimone@intel.com>

Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Mike Kinney <michael.d.kinney@intel.com>
Cc: Isaac Oram <isaac.w.oram@intel.com>
Cc: Mohamed Abbas <mohamed.abbas@intel.com>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Cc: Zachary Bobroff <zacharyb@ami.com>
Cc: Harikrishna Doppalapudi <harikrishnad@ami.com>
Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
---
 .../Ipmi/Library/IpmiLibKcs/IpmiLibKcs.c      | 362 ++++++++++
 .../Ipmi/Library/IpmiLibKcs/IpmiLibKcs.inf    |  40 ++
 .../Features/Ipmi/Library/IpmiLibKcs/KcsBmc.c | 485 +++++++++++++
 .../Features/Ipmi/Library/IpmiLibKcs/KcsBmc.h | 208 ++++++
 .../IpmiPlatformHookLib/IpmiPlatformHookLib.c |  39 ++
 .../IpmiPlatformHookLib.inf                   |  28 +
 .../Include/Acpi/GlobalNvs.asi                | 282 ++++++++
 .../Include/Acpi/GlobalNvsAreaDef.h           | 128 ++++
 .../Include/Guid/PchRcVariable.h              | 414 +++++++++++
 .../Include/Guid/SetupVariable.h              | 539 ++++++++++++++
 .../Include/IioBifurcationSlotTable.h         | 100 +++
 .../PurleyOpenBoardPkg/Include/Platform.h     |  92 +++
 .../Include/Ppi/SystemBoard.h                 |  63 ++
 .../Include/Protocol/PciIovPlatform.h         |  70 ++
 .../PurleyOpenBoardPkg/Include/SetupTable.h   |  21 +
 .../PurleyOpenBoardPkg/Include/SioRegs.h      |  35 +
 .../Intel/PurleyOpenBoardPkg/OpenBoardPkg.dec | 141 ++++
 .../SiliconPolicyInitLib.c                    | 130 ++++
 .../SiliconPolicyInitLib.inf                  |  39 ++
 .../PchPolicyUpdateUsb.c                      |  99 +++
 .../SiliconPolicyUpdateLib.c                  | 659 ++++++++++++++++++
 .../SiliconPolicyUpdateLib.inf                |  54 ++
 22 files changed, 4028 insertions(+)
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.c
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.inf
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.c
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.c
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.inf
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvs.asi
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Guid/PchRcVariable.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Guid/SetupVariable.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/IioBifurcationSlotTable.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Platform.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Ppi/SystemBoard.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/Protocol/PciIovPlatform.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/SetupTable.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Include/SioRegs.h
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/OpenBoardPkg.dec
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/PchPolicyUpdateUsb.c
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf

diff --git a/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.c b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.c
new file mode 100644
index 0000000000..700e413aa6
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.c
@@ -0,0 +1,362 @@
+/** @file
+  IPMI library - KCS.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IpmiPlatformHookLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+
+#include "KcsBmc.h"
+
+#define MAX_TEMP_DATA     160
+
+//
+// Structure of IPMI Command buffer
+//
+#define EFI_IPMI_COMMAND_HEADER_SIZE  2
+
+typedef struct {
+  UINT8 Lun : 2;
+  UINT8 NetFunction : 6;
+  UINT8 Command;
+  UINT8 CommandData[MAX_TEMP_DATA - EFI_IPMI_COMMAND_HEADER_SIZE];
+} EFI_IPMI_COMMAND;
+
+//
+// Structure of IPMI Command response buffer
+//
+#define EFI_IPMI_RESPONSE_HEADER_SIZE 2
+
+typedef struct {
+  UINT8 Lun : 2;
+  UINT8 NetFunction : 6;
+  UINT8 Command;
+  UINT8 ResponseData[MAX_TEMP_DATA - EFI_IPMI_RESPONSE_HEADER_SIZE];
+} EFI_IPMI_RESPONSE;
+
+
+#define IPMI_INSTANCE_INFO_HOB_GUID { \
+  0x38ee71f, 0x1c78, 0x4874, { 0xba, 0xe3, 0xf8, 0xa2, 0x57, 0x75, 0x28, 0x52 } \
+  }
+
+EFI_GUID mIpmiInstanceGuid = IPMI_INSTANCE_INFO_HOB_GUID;
+
+#define SM_IPMI_BMC_SIGNATURE SIGNATURE_32 ('i', 'p', 'm', 'i')
+typedef UINT32  EFI_BMC_STATUS;
+typedef struct {
+  UINTN               Signature;
+  UINT64              KcsTimeoutPeriod;
+  UINT16              IpmiIoBase;
+  UINT8               SlaveAddress;
+  EFI_BMC_STATUS      BmcStatus;
+  UINT64              ErrorStatus;
+  UINT8               SoftErrorCount;
+  UINT8               TempData[MAX_TEMP_DATA];
+} IPMI_INSTANCE;
+
+#define EFI_BMC_OK        0
+#define EFI_BMC_SOFTFAIL  1
+#define EFI_BMC_HARDFAIL  2
+#define EFI_BMC_UPDATE_IN_PROGRESS  3
+#define EFI_BMC_NOTREADY  4
+
+EFI_STATUS
+UpdateErrorStatus (
+  IN UINT8                      BmcError,
+  IPMI_INSTANCE                 *IpmiInstance
+  )
+/*++
+
+Routine Description:
+
+  Check if the completion code is a Soft Error and increment the count.  The count
+  is not updated if the BMC is in Force Update Mode.
+
+Arguments:
+
+  BmcError      - Completion code to check
+  IpmiInstance  - BMC instance data
+
+Returns:
+
+  EFI_SUCCESS   - Status
+
+--*/
+{
+  UINT8   Errors[] = {
+    IPMI_COMP_CODE_NODE_BUSY, IPMI_COMP_CODE_TIMEOUT, IPMI_COMP_CODE_OUT_OF_SPACE, IPMI_COMP_CODE_OUT_OF_RANGE,
+    IPMI_COMP_CODE_CMD_RESP_NOT_PROVIDED, IPMI_COMP_CODE_FAIL_DUP_REQUEST, IPMI_COMP_CODE_SDR_REP_IN_UPDATE_MODE,
+    IPMI_COMP_CODE_DEV_IN_FW_UPDATE_MODE, IPMI_COMP_CODE_BMC_INIT_IN_PROGRESS, IPMI_COMP_CODE_UNSPECIFIED
+  };
+  UINT16  CodeCount;
+  UINT8   i;
+
+  CodeCount = sizeof (Errors) / sizeof (Errors[0]);
+  for (i = 0; i < CodeCount; i++) {
+    if (BmcError == Errors[i]) {
+      //
+      // Don't change Bmc Status flag if the BMC is in Force Update Mode.
+      //
+      if (IpmiInstance->BmcStatus != EFI_BMC_UPDATE_IN_PROGRESS) {
+        IpmiInstance->BmcStatus = EFI_BMC_SOFTFAIL;
+      }
+
+      IpmiInstance->SoftErrorCount++;
+      break;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+VOID
+UpdateBmcStatusOnResponse (
+  IN IPMI_INSTANCE               *IpmiInstance,
+  IN EFI_IPMI_COMMAND            *IpmiCommand,
+  IN EFI_STATUS                  EfiStatus,
+  IN EFI_IPMI_RESPONSE           *IpmiResponse
+  )
+{
+  IPMI_GET_DEVICE_ID_RESPONSE      *BmcInfo;
+  IPMI_SELF_TEST_RESULT_RESPONSE   *TestResult;
+
+  if ((IpmiCommand->NetFunction == IPMI_NETFN_APP) && (IpmiCommand->Command == IPMI_APP_GET_DEVICE_ID)) {
+    if (EFI_ERROR(EfiStatus)) {
+      IpmiInstance->BmcStatus = EFI_BMC_HARDFAIL;
+    } else {
+      BmcInfo = (VOID *)IpmiResponse->ResponseData;
+      if (BmcInfo->FirmwareRev1.Bits.UpdateMode) {
+        IpmiInstance->BmcStatus = EFI_BMC_UPDATE_IN_PROGRESS;
+      }
+    }
+  } else if ((IpmiCommand->NetFunction == IPMI_NETFN_APP) && (IpmiCommand->Command == IPMI_APP_GET_DEVICE_ID)) {
+    if (EFI_ERROR(EfiStatus)) {
+      IpmiInstance->BmcStatus = EFI_BMC_HARDFAIL;
+    } else {
+      TestResult = (VOID *)IpmiResponse->ResponseData;
+      switch (TestResult->Result) {
+      case IPMI_APP_SELFTEST_NO_ERROR:
+      case IPMI_APP_SELFTEST_NOT_IMPLEMENTED:
+        IpmiInstance->BmcStatus = EFI_BMC_OK;
+        break;
+      case IPMI_APP_SELFTEST_ERROR:
+        //
+        // Three of the possible errors result in BMC hard failure; FRU Corruption,
+        // BootBlock Firmware corruption, and Operational Firmware Corruption.  All
+        // other errors are BMC soft failures.
+        //
+        if ((TestResult->Param & (IPMI_APP_SELFTEST_FRU_CORRUPT | IPMI_APP_SELFTEST_FW_BOOTBLOCK_CORRUPT | IPMI_APP_SELFTEST_FW_CORRUPT)) != 0) {
+          IpmiInstance->BmcStatus = EFI_BMC_HARDFAIL;
+        } else {
+          IpmiInstance->BmcStatus = EFI_BMC_SOFTFAIL;
+        }
+        break;
+
+      case IPMI_APP_SELFTEST_FATAL_HW_ERROR:
+        IpmiInstance->BmcStatus = EFI_BMC_HARDFAIL;
+        break;
+
+      default:
+        break;
+      }
+    }
+  }
+}
+
+/**
+  This service enables submitting commands via Ipmi.
+
+  @param[in]         NetFunction       Net function of the command.
+  @param[in]         Command           IPMI Command.
+  @param[in]         RequestData       Command Request Data.
+  @param[in]         RequestDataSize   Size of Command Request Data.
+  @param[out]        ResponseData      Command Response Data. The completion code is the first byte of response data.
+  @param[in, out]    ResponseDataSize  Size of Command Response Data.
+
+  @retval EFI_SUCCESS            The command byte stream was successfully submit to the device and a response was successfully received.
+  @retval EFI_NOT_FOUND          The command was not successfully sent to the device or a response was not successfully received from the device.
+  @retval EFI_NOT_READY          Ipmi Device is not ready for Ipmi command access.
+  @retval EFI_DEVICE_ERROR       Ipmi Device hardware error.
+  @retval EFI_TIMEOUT            The command time out.
+  @retval EFI_UNSUPPORTED        The command was not successfully sent to the device.
+  @retval EFI_OUT_OF_RESOURCES   The resource allcation is out of resource or data size error.
+**/
+EFI_STATUS
+EFIAPI
+IpmiSubmitCommand (
+  IN     UINT8     NetFunction,
+  IN     UINT8     Command,
+  IN     UINT8     *RequestData,
+  IN     UINT32    RequestDataSize,
+     OUT UINT8     *ResponseData,
+  IN OUT UINT32    *ResponseDataSize
+  )
+{
+  UINT8                       DataSize;
+  EFI_STATUS                  Status;
+  EFI_IPMI_COMMAND            *IpmiCommand;
+  EFI_IPMI_RESPONSE           *IpmiResponse;
+  VOID                        *Hob;
+  IPMI_INSTANCE               *IpmiInstance;
+
+  DEBUG ((DEBUG_INFO, "IpmiSubmitCommand\n"));
+
+  Hob = GetFirstGuidHob (&mIpmiInstanceGuid);
+  if (Hob != NULL) {
+    IpmiInstance = GET_GUID_HOB_DATA(Hob);
+  } else {
+    IpmiInstance = BuildGuidHob (&mIpmiInstanceGuid, sizeof(IPMI_INSTANCE));
+    ASSERT(IpmiInstance != NULL);
+    if (IpmiInstance == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    IpmiInstance->Signature                      = SM_IPMI_BMC_SIGNATURE;
+    IpmiInstance->KcsTimeoutPeriod               = PcdGet64(PcdIpmiKcsTimeoutPeriod); 
+    IpmiInstance->SlaveAddress                   = PcdGet8(PcdIpmiBmcSlaveAddress);
+    IpmiInstance->IpmiIoBase                     = PcdGet16(PcdIpmiIoBaseAddress);
+    DEBUG((DEBUG_INFO,"IPMI KcsTimeoutPeriod=0x%x\n", IpmiInstance->KcsTimeoutPeriod));
+    DEBUG((DEBUG_INFO,"IPMI SlaveAddress=0x%x\n", IpmiInstance->SlaveAddress));
+    DEBUG((DEBUG_INFO,"IPMI IpmiIoBase=0x%x\n", IpmiInstance->IpmiIoBase));
+
+    IpmiInstance->BmcStatus                      = EFI_BMC_NOTREADY;
+    IpmiInstance->ErrorStatus                    = 0x00;
+    IpmiInstance->SoftErrorCount                 = 0x00;
+
+    MicroSecondDelay(10*1000);
+
+    Status = PlatformIpmiIoRangeSet (IpmiInstance->IpmiIoBase);
+    DEBUG ((DEBUG_INFO, "IPMI PlatformIpmiIoRangeSet - %r!\n", Status));
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+
+  IpmiCommand  = (VOID *)IpmiInstance->TempData;
+  IpmiResponse = (VOID *)IpmiInstance->TempData;
+
+  //
+  // Send IPMI command to BMC
+  //
+  IpmiCommand->Lun          = 0;
+  IpmiCommand->NetFunction  = NetFunction;
+  IpmiCommand->Command      = Command;
+
+  //
+  // Ensure that the buffer is valid before attempting to copy the command data
+  // buffer into the IpmiCommand structure.
+  //
+  if (RequestDataSize > 0) {
+    if (RequestData == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    CopyMem (
+      IpmiCommand->CommandData,
+      RequestData,
+      RequestDataSize
+      );
+  }
+
+  Status = SendDataToBmcPort (
+  	IpmiInstance->KcsTimeoutPeriod,
+    IpmiInstance->IpmiIoBase,
+    (UINT8 *)IpmiCommand,
+    (UINT8)(RequestDataSize + EFI_IPMI_COMMAND_HEADER_SIZE)
+    );
+
+  if (Status != EFI_SUCCESS) {
+    IpmiInstance->BmcStatus = EFI_BMC_SOFTFAIL;
+    IpmiInstance->SoftErrorCount++;
+    UpdateBmcStatusOnResponse (IpmiInstance, IpmiCommand, Status, NULL);
+    return Status;
+  }
+
+  //
+  // Get Response to IPMI Command from BMC.
+  //
+  DataSize = MAX_TEMP_DATA;
+  Status = ReceiveBmcDataFromPort (
+  	IpmiInstance->KcsTimeoutPeriod,
+    IpmiInstance->IpmiIoBase,
+    (UINT8 *)IpmiResponse,
+    &DataSize
+    );
+
+  if (Status != EFI_SUCCESS) {
+    IpmiInstance->BmcStatus = EFI_BMC_SOFTFAIL;
+    IpmiInstance->SoftErrorCount++;
+    UpdateBmcStatusOnResponse (IpmiInstance, IpmiCommand, Status, NULL);
+    return Status;
+  }
+
+  //
+  // If we got this far without any error codes, but the DataSize is 0 then the 
+  // command response failed, so do not continue.  
+  //
+  if (DataSize < 3) {
+    Status = EFI_DEVICE_ERROR;
+    IpmiInstance->BmcStatus = EFI_BMC_SOFTFAIL;
+    IpmiInstance->SoftErrorCount++;
+    UpdateBmcStatusOnResponse (IpmiInstance, IpmiCommand, Status, NULL);
+    return Status;
+  }
+
+  if ((IpmiResponse->ResponseData[0] != IPMI_COMP_CODE_NORMAL) &&
+      (IpmiInstance->BmcStatus == EFI_BMC_UPDATE_IN_PROGRESS)) {
+    //
+    // If the completion code is not normal and the BMC is in Force Update
+    // mode, then update the error status and return EFI_UNSUPPORTED.
+    //
+    UpdateErrorStatus (
+      IpmiResponse->ResponseData[0],
+      IpmiInstance
+      );
+    UpdateBmcStatusOnResponse (IpmiInstance, IpmiCommand, Status, IpmiResponse);
+    return EFI_UNSUPPORTED;
+  } else if (IpmiResponse->ResponseData[0] != IPMI_COMP_CODE_NORMAL) {
+    //
+    // Otherwise if the BMC is in normal mode, but the completion code
+    // is not normal, then update the error status and return device error.
+    //
+    UpdateErrorStatus (
+      IpmiResponse->ResponseData[0],
+      IpmiInstance
+      );
+    UpdateBmcStatusOnResponse (IpmiInstance, IpmiCommand, Status, IpmiResponse);
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Verify the response data buffer passed in is big enough.
+  //
+  if ((UINTN)(DataSize - EFI_IPMI_RESPONSE_HEADER_SIZE) > *ResponseDataSize) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  //
+  // Copy data over to the response data buffer.
+  //
+  if ((ResponseData != NULL) && (ResponseDataSize != NULL) && (*ResponseDataSize != 0)) {
+    *ResponseDataSize = DataSize - EFI_IPMI_RESPONSE_HEADER_SIZE;
+    CopyMem (
+      ResponseData,
+      IpmiResponse->ResponseData,
+      *ResponseDataSize
+      );
+  }
+  IpmiInstance->BmcStatus = EFI_BMC_OK;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.inf b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.inf
new file mode 100644
index 0000000000..239e115ad4
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/IpmiLibKcs.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for IPMI KCS Library.
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IpmiLibKcs
+  FILE_GUID                      = 9879DB3A-C2CD-4615-ACDA-95C1B2EC00B3
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = IpmiLib
+
+[sources]
+  IpmiLibKcs.c
+  KcsBmc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+  PurleyOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  PcdLib
+  TimerLib
+  IoLib
+  IpmiPlatformHookLib
+
+[Pcd]
+  gEfiIpmiPkgTokenSpaceGuid.PcdIpmiKcsTimeoutPeriod
+  gEfiIpmiPkgTokenSpaceGuid.PcdIpmiBmcSlaveAddress
+  gAdvancedFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress
\ No newline at end of file
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.c b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.c
new file mode 100644
index 0000000000..483843c6da
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.c
@@ -0,0 +1,485 @@
+/** @file
+    KCS Transport Hook.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "KcsBmc.h"
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+KcsErrorExit (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort
+  )
+/*++
+
+Routine Description:
+
+  Check the KCS error status
+
+Arguments:
+     
+  KcsPort          - The base port of KCS
+
+Returns:
+
+  EFI_DEVICE_ERROR - The device error happened
+  EFI_SUCCESS      - Successfully check the KCS error status
+
+--*/
+{
+  EFI_STATUS      Status;
+  UINT8           KcsData;
+  EFI_KCS_STATUS  KcsStatus;
+  UINT8           BmcStatus;
+  UINT8           RetryCount;
+  UINT64          TimeOut;
+
+  TimeOut     = 0;
+  RetryCount  = 0;
+  while (RetryCount < KCS_ABORT_RETRY_COUNT) {
+
+    do {
+      MicroSecondDelay(KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        RetryCount = KCS_ABORT_RETRY_COUNT;
+        break;
+      }
+      TimeOut++;
+    } while (KcsStatus.Status.Ibf);
+
+    if (RetryCount >= KCS_ABORT_RETRY_COUNT) {
+      break;
+    }
+
+    KcsData = KCS_ABORT;
+    IoWrite8 ((KcsPort + 1), KcsData);
+
+    TimeOut     = 0;
+    do {
+      MicroSecondDelay(KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        Status = EFI_DEVICE_ERROR;
+        goto LabelError;
+      }
+      TimeOut++;
+    } while (KcsStatus.Status.Ibf);
+
+    KcsData = IoRead8 (KcsPort);
+
+    KcsData = 0x0;
+    IoWrite8 (KcsPort, KcsData);
+
+    TimeOut     = 0;	
+    do {
+      MicroSecondDelay(KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        Status = EFI_DEVICE_ERROR;
+        goto LabelError;
+      }
+      TimeOut++;
+    } while (KcsStatus.Status.Ibf);
+
+    if (KcsStatus.Status.State == KcsReadState) {
+      TimeOut     = 0;	
+      do {
+        MicroSecondDelay(KCS_DELAY_UNIT);
+        KcsStatus.RawData = IoRead8 (KcsPort + 1);
+        if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+          Status = EFI_DEVICE_ERROR;
+          goto LabelError;
+        }
+        TimeOut++;
+      } while (!KcsStatus.Status.Obf);
+
+      BmcStatus = IoRead8 (KcsPort);
+
+      KcsData = KCS_READ;
+      IoWrite8 (KcsPort, KcsData);
+
+      TimeOut     = 0;
+      do {
+        MicroSecondDelay(KCS_DELAY_UNIT);
+        KcsStatus.RawData = IoRead8 (KcsPort + 1);
+        if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+          Status = EFI_DEVICE_ERROR;
+          goto LabelError;
+        }
+        TimeOut++;
+      } while (KcsStatus.Status.Ibf);
+
+      if (KcsStatus.Status.State == KcsIdleState) {
+        TimeOut     = 0;
+        do {
+          MicroSecondDelay(KCS_DELAY_UNIT);
+          KcsStatus.RawData = IoRead8 (KcsPort + 1);
+          if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+            Status = EFI_DEVICE_ERROR;
+            goto LabelError;
+          }
+          TimeOut++;
+        } while (!KcsStatus.Status.Obf);
+
+        KcsData = IoRead8 (KcsPort);
+        break;
+
+      } else {
+        RetryCount++;
+        continue;
+      }
+
+    } else {
+      RetryCount++;
+      continue;
+    }
+  }
+
+  if (RetryCount >= KCS_ABORT_RETRY_COUNT) {
+    Status = EFI_DEVICE_ERROR;
+    goto LabelError;
+  }
+
+  return EFI_SUCCESS;
+
+LabelError:
+
+  return Status;
+}
+
+EFI_STATUS
+KcsCheckStatus (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort,
+  KCS_STATE                         KcsState,
+  BOOLEAN                           *Idle
+  )
+/*++
+
+Routine Description:
+
+  Ckeck KCS status
+
+Arguments:
+
+  KcsPort       - The base port of KCS
+  KcsState      - The state of KCS to be checked
+  Idle          - If the KCS is idle
+
+Returns:
+
+  EFI_SUCCESS   - Checked the KCS status successfully
+
+--*/
+{
+  EFI_STATUS      Status = 0;
+  EFI_KCS_STATUS  KcsStatus = { 0 };
+  UINT8           KcsData = 0;
+  UINT64          TimeOut = 0;
+  
+  if(Idle == NULL ){ 
+       return EFI_INVALID_PARAMETER;
+  }
+	
+  *Idle   = FALSE;
+   
+  do {
+    MicroSecondDelay(KCS_DELAY_UNIT);
+    KcsStatus.RawData = IoRead8 (KcsPort + 1);
+    if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+      Status = EFI_DEVICE_ERROR;
+      goto LabelError;
+    }
+    TimeOut++;
+  } while (KcsStatus.Status.Ibf);
+
+  if (KcsState == KcsWriteState) {
+    KcsData = IoRead8 (KcsPort);
+  }
+
+  if (KcsStatus.Status.State != KcsState) {
+    if ((KcsStatus.Status.State == KcsIdleState) && (KcsState == KcsReadState)) {
+      *Idle = TRUE;
+    } else {
+      Status = KcsErrorExit (KcsTimeoutPeriod, KcsPort);
+      goto LabelError;
+    }
+  }
+
+  if (KcsState == KcsReadState) {
+    TimeOut     = 0;
+    do {
+      MicroSecondDelay(KCS_DELAY_UNIT);
+      KcsStatus.RawData = IoRead8 (KcsPort + 1);
+      if (KcsStatus.RawData == 0xFF || (TimeOut >= KcsTimeoutPeriod)) {
+        Status = EFI_DEVICE_ERROR;
+        goto LabelError;
+      }
+      TimeOut++;
+    } while (!KcsStatus.Status.Obf);
+  }
+
+  if (KcsState == KcsWriteState || Idle) {
+    KcsData = IoRead8 (KcsPort);
+  }
+
+  return EFI_SUCCESS;
+
+LabelError:
+
+  return Status;
+}
+
+EFI_STATUS
+SendDataToBmc (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+{
+  EFI_KCS_STATUS  KcsStatus;
+  UINT8           KcsData;
+  UINT16          KcsIoBase;
+  EFI_STATUS      Status;
+  UINT8           i;
+  BOOLEAN         Idle;
+  UINT64          TimeOut = 0;
+
+  DEBUG ((DEBUG_INFO, "SendDataToBmc (%ld, 0x%x) - ", KcsTimeoutPeriod, KcsPort));
+  for (i = 0; i < DataSize; i++) {
+    DEBUG ((DEBUG_INFO, "%02x ", Data[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  KcsIoBase = KcsPort;
+
+  do {
+    MicroSecondDelay(KCS_DELAY_UNIT);
+    KcsStatus.RawData = IoRead8 (KcsIoBase + 1);
+    if ((KcsStatus.RawData == 0xFF) || (TimeOut >= KcsTimeoutPeriod))
+    {
+      if ((Status = KcsErrorExit (KcsTimeoutPeriod, KcsIoBase)) != EFI_SUCCESS)
+      {
+        DEBUG ((DEBUG_INFO, "KcsErrorExit - %r\n", Status));
+        return Status;
+      }
+    }
+    TimeOut++;
+  } while (KcsStatus.Status.Ibf);
+
+  KcsData = KCS_WRITE_START;
+  IoWrite8 ((KcsIoBase + 1), KcsData);
+  if ((Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsWriteState, &Idle)) != EFI_SUCCESS) {
+    DEBUG ((DEBUG_INFO, "KcsCheckStatus 1 - %r\n", Status));
+    return Status;
+  }
+
+  for (i = 0; i < DataSize; i++) {
+    if (i == (DataSize - 1)) {
+      if ((Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsWriteState, &Idle)) != EFI_SUCCESS) {
+        DEBUG ((DEBUG_INFO, "KcsCheckStatus 2 - %r\n", Status));
+        return Status;
+      }
+
+      KcsData = KCS_WRITE_END;
+      IoWrite8 ((KcsIoBase + 1), KcsData);
+    }
+
+    Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsWriteState, &Idle);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "KcsCheckStatus 3 - %r\n", Status));
+      return Status;
+    }
+
+    IoWrite8 (KcsIoBase, Data[i]);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ReceiveBmcData (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  Data          - The buffer pointer
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received data successfully
+
+--*/
+{
+  UINT8       KcsData;
+  UINT16      KcsIoBase;
+  EFI_STATUS  Status;
+  BOOLEAN     Idle;
+  UINT8       Count;
+
+  Count     = 0;
+  KcsIoBase = KcsPort;
+
+  DEBUG ((DEBUG_INFO, "ReceiveBmcData (%ld, 0x%x)...\n", KcsTimeoutPeriod, KcsPort));
+
+  while (TRUE) {
+
+    if ((Status = KcsCheckStatus (KcsTimeoutPeriod, KcsIoBase, KcsReadState, &Idle)) != EFI_SUCCESS) {
+      DEBUG ((DEBUG_INFO, "KcsCheckStatus - %r\n", Status));
+      return Status;
+    }
+
+    if (Idle) {
+      DEBUG ((DEBUG_INFO, "DataSize - 0x%x\n", Count));
+      *DataSize = Count;
+      break;
+    }
+
+    if (Count > *DataSize) {
+      DEBUG ((DEBUG_INFO, "ERROR: Count(0x%x) > *DataSize(0x%x)\n", Count, *DataSize));
+      return EFI_DEVICE_ERROR;
+    }
+
+    Data[Count] = IoRead8 (KcsIoBase);
+
+    Count++;
+
+    KcsData = KCS_READ;
+    IoWrite8 (KcsIoBase, KcsData);
+  }
+
+  DEBUG ((DEBUG_INFO, "ReceiveBmcData (%ld, 0x%x) - ", KcsTimeoutPeriod, KcsPort));
+  for (Count = 0; Count < *DataSize; Count++) {
+    DEBUG ((DEBUG_INFO, "%02x ", Data[Count]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ReceiveBmcDataFromPort (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  Data          - The buffer pointer to receive data
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received the data successfully
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT16      KcsIoBase;
+  UINT8       i;
+  UINT8       MyDataSize;
+
+  MyDataSize  = *DataSize;
+
+  KcsIoBase   = KcsPort;
+
+  for (i = 0; i < KCS_ABORT_RETRY_COUNT; i++) {
+    Status = ReceiveBmcData (KcsTimeoutPeriod, KcsIoBase, Data, DataSize);
+    if (EFI_ERROR (Status)) {
+      if ((Status = KcsErrorExit (KcsTimeoutPeriod, KcsIoBase)) != EFI_SUCCESS) {
+        return Status;
+      }
+
+      *DataSize = MyDataSize;
+    } else {
+      return Status;
+    }
+  }
+
+  return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+SendDataToBmcPort (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+{
+  EFI_STATUS  Status;
+  UINT16      KcsIoBase;
+  UINT8       i;
+
+  KcsIoBase = KcsPort;
+
+  for (i = 0; i < KCS_ABORT_RETRY_COUNT; i++) {
+    Status = SendDataToBmc (KcsTimeoutPeriod, KcsIoBase, Data, DataSize);
+    if (EFI_ERROR (Status)) {
+      if ((Status = KcsErrorExit (KcsTimeoutPeriod, KcsIoBase)) != EFI_SUCCESS) {
+        return Status;
+      }
+    } else {
+      return Status;
+    }
+  }
+
+  return EFI_DEVICE_ERROR;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.h b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.h
new file mode 100644
index 0000000000..bf8ae6b63d
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiLibKcs/KcsBmc.h
@@ -0,0 +1,208 @@
+/** @file
+    KCS Transport Hook head file.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_KCS_BMC_H
+#define _EFI_KCS_BMC_H
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+
+#define KCS_WRITE_START       0x61
+#define KCS_WRITE_END         0x62
+#define KCS_READ              0x68
+#define KCS_GET_STATUS        0x60
+#define KCS_ABORT             0x60
+#define KCS_DELAY_UNIT 50  // [s] Each KSC IO delay
+
+#define KCS_ABORT_RETRY_COUNT 1
+
+typedef enum {
+  KcsIdleState,
+  KcsReadState,
+  KcsWriteState,
+  KcsErrorState
+} KCS_STATE;
+
+typedef union {
+  UINT8     RawData;
+  struct {
+  UINT8 Obf : 1;
+  UINT8 Ibf : 1;
+  UINT8 SmAtn : 1;
+  UINT8 CD : 1;
+  UINT8 Oem1 : 1;
+  UINT8 Oem2 : 1;
+  UINT8 State : 2;
+  } Status;
+} EFI_KCS_STATUS;
+
+
+//
+//External Fucntion List
+//
+EFI_STATUS
+SendDataToBmcPort (
+  UINT64                                    KcsTimeoutPeriod,
+  UINT16                                    KcsPort,
+  UINT8                                     *Data,
+  UINT8                                     DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+;
+
+EFI_STATUS
+ReceiveBmcDataFromPort (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  Data          - The buffer pointer
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received data successfully
+
+--*/
+;
+
+//
+//Internal Fucntion List
+//
+EFI_STATUS
+KcsErrorExit (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort
+  )
+/*++
+
+Routine Description:
+
+  Check the KCS error status
+
+Arguments:
+     
+  KcsPort          - The base port of KCS
+
+Returns:
+
+  EFI_DEVICE_ERROR - The device error happened
+  EFI_SUCCESS      - Successfully check the KCS error status
+
+--*/
+;
+
+EFI_STATUS
+KcsCheckStatus (
+  UINT64                            KcsTimeoutPeriod,
+  UINT16                            KcsPort,
+  KCS_STATE                         KcsState,
+  BOOLEAN                           *Idle
+  )
+/*++
+
+Routine Description:
+
+  Ckeck KCS status
+
+Arguments:
+
+  KcsPort       - The base port of KCS
+  KcsState      - The state of KCS to be checked
+  Idle          - If the KCS is idle
+  Context       - The context for this operation
+
+Returns:
+
+  EFI_SUCCESS   - Checked the KCS status successfully
+
+--*/
+;
+
+
+EFI_STATUS
+SendDataToBmc (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           DataSize
+  )
+/*++
+
+Routine Description:
+
+  Send data to BMC
+
+Arguments:
+
+  Data          - The data pointer to be sent
+  DataSize      - The data size
+
+Returns:
+
+  EFI_SUCCESS   - Send out the data successfully
+
+--*/
+;
+
+
+EFI_STATUS
+ReceiveBmcData (
+  UINT64                          KcsTimeoutPeriod,
+  UINT16                          KcsPort,
+  UINT8                           *Data,
+  UINT8                           *DataSize
+  )
+/*++
+
+Routine Description:
+
+  Routine Description:
+
+  Receive data from BMC
+
+Arguments:
+
+  Data          - The buffer pointer
+  DataSize      - The buffer size
+
+Returns:
+
+  EFI_SUCCESS   - Received data successfully
+
+--*/
+;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.c b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.c
new file mode 100644
index 0000000000..1cdd39c79a
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.c
@@ -0,0 +1,39 @@
+/** @file
+    IPMI platform hook.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/IpmiPlatformHookLib.h>
+
+#include <Library/PchCycleDecodingLib.h>
+#include <Register/PchRegsLpc.h>
+//
+// Prototype definitions for IPMI Platform Update Library
+//
+
+EFI_STATUS
+EFIAPI
+PlatformIpmiIoRangeSet(
+  UINT16 IpmiIoBase
+)
+/*++
+
+  Routine Description:
+
+  This function sets IPMI Io range
+
+  Arguments:
+
+   IpmiIoBase
+
+  Returns:
+
+    Status
+
+--*/
+{
+  return PchLpcGenIoRangeSet((IpmiIoBase & 0xFF0), 0x10, LPC_ESPI_FIRST_SLAVE);
+}
\ No newline at end of file
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.inf b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.inf
new file mode 100644
index 0000000000..94ab840a02
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Features/Ipmi/Library/IpmiPlatformHookLib/IpmiPlatformHookLib.inf
@@ -0,0 +1,28 @@
+## @file
+# Component description file for IPMI platform hook Library.
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = IpmiPlatformHookLib
+  FILE_GUID                      = E886B3EA-AAF3-4804-810C-C8F69897C580
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = IpmiPlatformHookLib
+
+[sources]
+  IpmiPlatformHookLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+  PurleyRefreshSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PchCycleDecodingLib
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvs.asi b/Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvs.asi
new file mode 100644
index 0000000000..3e049cca8e
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvs.asi
@@ -0,0 +1,282 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+  //
+  // BIOS parameter BIOS_ACPI_PARAM
+  //
+  OperationRegion (PSYS, SystemMemory, 0x30584946, 0x400) // (FIX0 - Patched by ACPI Platform Driver during POST)
+  Field (PSYS, ByteAcc, NoLock, Preserve) {
+    // IOAPIC Start
+    PLAT   ,  32,   // Platform ID
+    Offset (0x04),  // 
+#if MAX_SOCKET > 4
+    AP00   ,   1,   // PC00 IOAPIC Enable
+    AP01   ,   1,   // PC01 IOAPIC Enable
+    AP02   ,   1,   // PC02 IOAPIC Enable
+    AP03   ,   1,   // PC03 IOAPIC Enable
+    AP04   ,   1,   // PC04 IOAPIC Enable
+    AP05   ,   1,   // PC05 IOAPIC Enable
+    AP06   ,   1,   // PC06 IOAPIC Enable
+    AP07   ,   1,   // PC07 IOAPIC Enable
+    AP08   ,   1,   // PC08 IOAPIC Enable
+    AP09   ,   1,   // PC09 IOAPIC Enable
+    AP10   ,   1,   // PC10 IOAPIC Enable
+    AP11   ,   1,   // PC11 IOAPIC Enable
+    AP12   ,   1,   // PC12 IOAPIC Enable
+    AP13   ,   1,   // PC13 IOAPIC Enable
+    AP14   ,   1,   // PC14 IOAPIC Enable
+    AP15   ,   1,   // PC15 IOAPIC Enable
+    AP16   ,   1,   // PC16 IOAPIC Enable
+    AP17   ,   1,   // PC17 IOAPIC Enable
+    AP18   ,   1,   // PC18 IOAPIC Enable
+    AP19   ,   1,   // PC19 IOAPIC Enable
+    AP20   ,   1,   // PC20 IOAPIC Enable
+    AP21   ,   1,   // PC21 IOAPIC Enable
+    AP22   ,   1,   // PC22 IOAPIC Enable
+    AP23   ,   1,   // PC23 IOAPIC Enable
+    AP24   ,   1,   // PC24 IOAPIC Enable
+    AP25   ,   1,   // 8S PC25 IOAPIC Enable
+    AP26   ,   1,   // 8S PC26 IOAPIC Enable
+    AP27   ,   1,   // 8S PC27 IOAPIC Enable
+    AP28   ,   1,   // 8S PC28 IOAPIC Enable
+    AP29   ,   1,   // 8S PC29 IOAPIC Enable
+    AP30   ,   1,   // 8S PC30 IOAPIC Enable
+    AP31   ,   1,   // 8S PC31 IOAPIC Enable
+#else
+    APC0   ,   1,   // PCH IOAPIC Enable
+    AP00   ,   1,   // PC00 IOAPIC Enable
+    AP01   ,   1,   // PC01 IOAPIC Enable
+    AP02   ,   1,   // PC02 IOAPIC Enable
+    AP03   ,   1,   // PC03 IOAPIC Enable
+    AP04   ,   1,   // PC04 IOAPIC Enable
+    AP05   ,   1,   // PC05 IOAPIC Enable
+    AP06   ,   1,   // PC06 IOAPIC Enable
+    AP07   ,   1,   // PC07 IOAPIC Enable
+    AP08   ,   1,   // PC08 IOAPIC Enable
+    AP09   ,   1,   // PC09 IOAPIC Enable
+    AP10   ,   1,   // PC10 IOAPIC Enable
+    AP11   ,   1,   // PC11 IOAPIC Enable
+    AP12   ,   1,   // PC12 IOAPIC Enable
+    AP13   ,   1,   // PC13 IOAPIC Enable
+    AP14   ,   1,   // PC14 IOAPIC Enable
+    AP15   ,   1,   // PC15 IOAPIC Enable
+    AP16   ,   1,   // PC16 IOAPIC Enable
+    AP17   ,   1,   // PC17 IOAPIC Enable
+    AP18   ,   1,   // PC18 IOAPIC Enable
+    AP19   ,   1,   // PC19 IOAPIC Enable
+    AP20   ,   1,   // PC20 IOAPIC Enable
+    AP21   ,   1,   // PC21 IOAPIC Enable
+    AP22   ,   1,   // PC22 IOAPIC Enable
+    AP23   ,   1,   // PC23 IOAPIC Enable
+    RESA   ,   7,  // Unused
+#endif
+    Offset (0x08),
+    SKOV   ,   1,   // Override ApicId socket field
+           ,   7,   // Unused
+    // IOAPIC End
+
+    // Power Managment Start
+    Offset (0x09),
+           ,  1,    // 
+    CSEN   ,  1,    // C State Enable
+    C3EN   ,  1,    // OS C3 Report Enbale
+    C6EN   ,  1,    // C6 Enable
+    C7EN   ,  1,    // C7 Enable
+    MWOS   ,  1,    // MWAIT support Enable
+    PSEN   ,  1,    // P State Enable
+    EMCA   ,  1,    // EMCA Enable
+    Offset (0x0A),
+    HWAL   ,  2,    // PSD HW_ALL Enable
+    KPRS   ,  1,    // KB present Flag
+    MPRS   ,  1,    // Mouse present Flag
+    TSEN   ,  1,    // T State Enable Flag
+    FGTS   ,  1,    // Fine grained T state Flag
+    OSCX   ,  1,    // OS C States
+    RESX   ,  1,    // Unused
+    // Power Management End
+
+    // RAS Start
+    Offset (0x0B),
+    CPHP   ,  8,    // Bit field for determining CPU hotplug event is happening, Update every time CPU Hotpug event is registered as valid
+                    // Bit0 CPU0 O*L Request 
+                    // Bit1 CPU1 O*L Request
+                    // Bit2 CPU2 O*L Request
+                    // Bit3 CPU3 O*L Request
+                    // Bit4-7 Reserved
+    IIOP   ,  8,    // Bit field for determining IIO hotplug event is happening, Update every time IIO Hotpug event is registered as valid
+                    // Bit0 IIO1 O*L Request
+                    // Bit1 IIO2 O*L Request
+                    // Bit2 IIO3 O*L Request
+                    // Bit3-7 Reserved
+    IIOH   , 64,    // IIO bit Mask, what IIOs are present for STA method, Update every time IIO hotplug event happens and at boot time (Patched by ACPI Platform Driver during POST)
+    PRBM   , 32,    // Processor Bit mask, what sockets are present for STA method, Update every time hotplug event happen and at boot time (Patched by ACPI Platform Driver during POST)
+    P0ID   , 32,    // Processor 0 APIC ID base
+    P1ID   , 32,    // Processor 1 APIC ID base
+    P2ID   , 32,    // Processor 2 APIC ID base
+    P3ID   , 32,    // Processor 3 APIC ID base
+    P4ID   , 32,    // Processor 4 APIC ID base
+    P5ID   , 32,    // Processor 5 APIC ID base
+    P6ID   , 32,    // Processor 6 APIC ID base
+    P7ID   , 32,    // Processor 7 APIC ID base
+    P0BM   , 64,    // Processor 0 Bit mask, what cores are present for STA method 
+    P1BM   , 64,    // Processor 1 Bit mask, what cores are present for STA method 
+    P2BM   , 64,    // Processor 2 Bit mask, what cores are present for STA method 
+    P3BM   , 64,    // Processor 3 Bit mask, what cores are present for STA method 
+    P4BM   , 64,    // Processor 4 Bit mask, what cores are present for STA method 
+    P5BM   , 64,    // Processor 5 Bit mask, what cores are present for STA method 
+    P6BM   , 64,    // Processor 6 Bit mask, what cores are present for STA method 
+    P7BM   , 64,    // Processor 7 Bit mask, what cores are present for STA method 
+    MEBM   , 16,    // Memory controller bit mask what memory controllers are present, for STA Method
+    MEBC   , 16,    // Memory controller change event mask what memory controllers have been changed, for notify
+    CFMM   , 32,    // MMCFG Base
+    TSSZ   , 32,    // TSEG Size.
+    M0BS   , 64,    // Memory Controller Base 0
+    M1BS   , 64,    // Memory Controller Base 1
+    M2BS   , 64,    // Memory Controller Base 2
+    M3BS   , 64,    // Memory Controller Base 3
+    M4BS   , 64,    // Memory Controller Base 4
+    M5BS   , 64,    // Memory Controller Base 5
+    M6BS   , 64,    // Memory Controller Base 6
+    M7BS   , 64,    // Memory Controller Base 7
+    M0RN   , 64,    // Memory Controller Range 0
+    M1RN   , 64,    // Memory Controller Range 1
+    M2RN   , 64,    // Memory Controller Range 2
+    M3RN   , 64,    // Memory Controller Range 3
+    M4RN   , 64,    // Memory Controller Range 4
+    M5RN   , 64,    // Memory Controller Range 5
+    M6RN   , 64,    // Memory Controller Range 6
+    M7RN   , 64,    // Memory Controller Range 7
+    SMI0   , 32,    // Parameter0 used for faked SMI request
+    SMI1   , 32,    // Parameter1 used for faked SMI request
+    SMI2   , 32,    // Parameter2 used for faked SMI request
+    SMI3   , 32,    // Parameter3 used for faked SMI request
+    SCI0   , 32,    // Parameter0 used for faked SCI request
+    SCI1   , 32,    // Parameter1 used for faked SCI request
+    SCI2   , 32,    // Parameter2 used for faked SCI request
+    SCI3   , 32,    // Parameter3 used for faked SCI request
+    MADD   , 64,    // Migration ActionRegion GAS address. (Migration support written for 8 CPU socket system. In a 4 socket system, CPU4-7 and MEM8-15 are invalid.)
+    CUU0   , 128,   // CPU0 UUID
+    CUU1   , 128,   // CPU1 UUID
+    CUU2   , 128,   // CPU2 UUID
+    CUU3   , 128,   // CPU3 UUID
+    CUU4   , 128,   // CPU4 UUID
+    CUU5   , 128,   // CPU5 UUID
+    CUU6   , 128,   // CPU6 UUID
+    CUU7   , 128,   // CPU7 UUID
+    CPSP   , 8,     // CPU spare bitmap. 1 == IsSpare.
+    ME00   , 128,   // MEM0 UUID
+    ME01   , 128,   // MEM1 UUID
+    ME10   , 128,   // MEM2 UUID
+    ME11   , 128,   // MEM3 UUID
+    ME20   , 128,   // MEM4 UUID
+    ME21   , 128,   // MEM5 UUID
+    ME30   , 128,   // MEM6 UUID
+    ME31   , 128,   // MEM7 UUID
+    ME40   , 128,   // MEM8 UUID
+    ME41   , 128,   // MEM9 UUID
+    ME50   , 128,   // MEM10 UUID
+    ME51   , 128,   // MEM11 UUID
+    ME60   , 128,   // MEM12 UUID
+    ME61   , 128,   // MEM13 UUID
+    ME70   , 128,   // MEM14 UUID
+    ME71   , 128,   // MEM15 UUID
+    MESP   , 16,    // Memory module spare bitmap. 1 == IsSpare.
+    LDIR   , 64,    // L1 Directory Address
+    PRID   , 32,    // Processor ID
+    AHPE   , 8,     // ACPI PCIe hot plug enable.
+    // RAS End
+
+    // VTD Start
+    DHRD   , 192,   // DHRD
+    ATSR   , 192,   // ATSR
+    RHSA   , 192,   // RHSA
+    // VTD End
+
+    // BIOS Guard Start
+    CNBS   , 8,     // CPU SKU number bit shift
+    // BIOS Guard End
+
+    // USB3 Start
+    XHMD   , 8,     // copy of setup item PchUsb30Mode
+    SBV1   , 8,     // USB Sideband Deferring GPE Vector (HOST_ALERT#1)
+    SBV2   , 8,     // USB Sideband Deferring GPE Vector (HOST_ALERT#2)
+    // USB3 End    
+
+    // HWPM Start
+           ,  2,    // HWPM State Enable option from setup
+           ,  1,    // Aunomous C-state Enable option from setup
+    HWPI   ,  1,    // HWP Interrupt
+           ,  4,    // Reserved bits
+    // HWPM End
+
+    // PCIe Multi-Seg Start
+    BB00   , 8,     // Bus Base for PC00
+    BB01   , 8,     // Bus Base for PC01
+    BB02   , 8,     // Bus Base for PC02
+    BB03   , 8,     // Bus Base for PC03
+    BB04   , 8,     // Bus Base for PC04
+    BB05   , 8,     // Bus Base for PC05
+    BB06   , 8,     // Bus Base for PC06
+    BB07   , 8,     // Bus Base for PC07
+    BB08   , 8,     // Bus Base for PC08
+    BB09   , 8,     // Bus Base for PC09
+    BB10   , 8,     // Bus Base for PC10
+    BB11   , 8,     // Bus Base for PC11
+    BB12   , 8,     // Bus Base for PC12
+    BB13   , 8,     // Bus Base for PC13
+    BB14   , 8,     // Bus Base for PC14
+    BB15   , 8,     // Bus Base for PC15
+    BB16   , 8,     // Bus Base for PC16
+    BB17   , 8,     // Bus Base for PC17
+    BB18   , 8,     // Bus Base for PC18
+    BB19   , 8,     // Bus Base for PC19
+    BB20   , 8,     // Bus Base for PC20
+    BB21   , 8,     // Bus Base for PC21
+    BB22   , 8,     // Bus Base for PC22
+    BB23   , 8,     // Bus Base for PC23
+    BB24   , 8,     // Bus Base for PC24
+    BB25   , 8,     // Bus Base for PC25
+    BB26   , 8,     // Bus Base for PC26
+    BB27   , 8,     // Bus Base for PC27
+    BB28   , 8,     // Bus Base for PC28
+    BB29   , 8,     // Bus Base for PC29
+    BB30   , 8,     // Bus Base for PC30
+    BB31   , 8,     // Bus Base for PC31
+    BB32   , 8,     // Bus Base for PC32
+    BB33   , 8,     // Bus Base for PC33
+    BB34   , 8,     // Bus Base for PC34
+    BB35   , 8,     // Bus Base for PC35
+    BB36   , 8,     // Bus Base for PC36
+    BB37   , 8,     // Bus Base for PC37
+    BB38   , 8,     // Bus Base for PC38
+    BB39   , 8,     // Bus Base for PC39
+    BB40   , 8,     // Bus Base for PC40
+    BB41   , 8,     // Bus Base for PC41
+    BB42   , 8,     // Bus Base for PC42
+    BB43   , 8,     // Bus Base for PC43
+    BB44   , 8,     // Bus Base for PC44
+    BB45   , 8,     // Bus Base for PC45
+    BB46   , 8,     // Bus Base for PC46
+    BB47   , 8,     // Bus Base for PC47
+    SGEN   , 8,     // PCIe_MultiSeg_Support enable/disable
+    SG00   , 8,     // Segment ID for Segment Group 0
+    SG01   , 8,     // Segment ID for Segment Group 1
+    SG02   , 8,     // Segment ID for Segment Group 2
+    SG03   , 8,     // Segment ID for Segment Group 3
+    SG04   , 8,     // Segment ID for Segment Group 4
+    SG05   , 8,     // Segment ID for Segment Group 5
+    SG06   , 8,     // Segment ID for Segment Group 6
+    SG07   , 8,     // Segment ID for Segment Group 7
+    // PCIe Multi-Seg End
+
+    // Performance start  
+    CLOD   , 8,     // SncAnd2Cluster, i.e. 1=SNC enable and 2 Clusters, 0 otherwise    
+    // Performance End
+    
+  }
+
+  
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h b/Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
new file mode 100644
index 0000000000..8af401de99
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
@@ -0,0 +1,128 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_GLOBAL_NVS_AREA_H_
+#define _EFI_GLOBAL_NVS_AREA_H_
+
+//
+// Global NVS Area definition
+//
+#pragma pack (1)
+
+typedef struct {
+  // IOAPIC Start
+  UINT32 PlatformId;
+  UINT32 IoApicEnable;
+  UINT8  ApicIdOverrided  :1;
+  UINT8  RES0           :7;          
+  // IOAPIC End
+
+  // Power Management Start
+  UINT8  Rsvd_Pms_0     :1;
+  UINT8  CStateEnable   :1;
+  UINT8  C3Enable       :1;
+  UINT8  C6Enable       :1;
+  UINT8  C7Enable       :1;
+  UINT8  MonitorMwaitEnable :1;
+  UINT8  PStateEnable   :1;
+  UINT8  EmcaEn         :1;
+  UINT8  HWAllEnable    :2;
+  UINT8  KBPresent      :1;
+  UINT8  MousePresent   :1;
+  UINT8  TStateEnable   :1;
+  UINT8  TStateFineGrained: 1;
+  UINT8  OSCX           :1;
+  UINT8  RESX           :1;          
+  // Power Management End
+
+  // RAS Start
+  UINT8  CpuChangeMask;
+  UINT8  IioChangeMask;
+  UINT64 IioPresentBitMask;
+  UINT32 SocketBitMask;           //make sure this is at 4byte boundary
+  UINT32 ProcessorApicIdBase[8];
+  UINT64 ProcessorBitMask[8];
+  UINT16 MemoryBoardBitMask;
+  UINT16 MemoryBoardChgEvent;
+  UINT32 MmCfg;
+  UINT32 TsegSize;
+  UINT64 MemoryBoardBase[8];
+  UINT64 MemoryBoardRange[8];
+  UINT32 SmiRequestParam[4];
+  UINT32 SciRequestParam[4];
+  UINT64 MigrationActionRegionAddress;
+  UINT8  Cpu0Uuid[16];
+  UINT8  Cpu1Uuid[16]; 
+  UINT8  Cpu2Uuid[16]; 
+  UINT8  Cpu3Uuid[16]; 
+  UINT8  Cpu4Uuid[16];
+  UINT8  Cpu5Uuid[16]; 
+  UINT8  Cpu6Uuid[16]; 
+  UINT8  Cpu7Uuid[16]; 
+  UINT8  CpuSpareMask;   
+  UINT8  Mem0Uuid[16];  
+  UINT8  Mem1Uuid[16]; 
+  UINT8  Mem2Uuid[16]; 
+  UINT8  Mem3Uuid[16]; 
+  UINT8  Mem4Uuid[16];  
+  UINT8  Mem5Uuid[16]; 
+  UINT8  Mem6Uuid[16]; 
+  UINT8  Mem7Uuid[16]; 
+  UINT8  Mem8Uuid[16];  
+  UINT8  Mem9Uuid[16]; 
+  UINT8  Mem10Uuid[16]; 
+  UINT8  Mem11Uuid[16]; 
+  UINT8  Mem12Uuid[16];  
+  UINT8  Mem13Uuid[16]; 
+  UINT8  Mem14Uuid[16]; 
+  UINT8  Mem15Uuid[16]; 
+  UINT16 MemSpareMask;
+  UINT64 EmcaL1DirAddr;
+  UINT32 ProcessorId;
+  UINT8  PcieAcpiHotPlugEnable;
+  // RAS End
+
+  // VTD Start
+  UINT64 DrhdAddr[3];   
+  UINT64 AtsrAddr[3];   
+  UINT64 RhsaAddr[3];
+  // VTD End
+  
+  // BIOS Guard Start
+  UINT8   CpuSkuNumOfBitShift;
+  // BIOS Guard End
+  
+  // USB3 Start
+  UINT8   XhciMode;
+  UINT8   HostAlertVector1;
+  UINT8   HostAlertVector2;
+  // USB3 End
+  
+  // HWPM Start
+  UINT8   HWPMEnable:2; //HWPM
+  UINT8   AutoCstate:1; //HWPM
+  UINT8   HwpInterrupt:1; //HWP Interrupt
+  UINT8   RES1:4;       //reserved bits
+  // HWPM End
+
+  // PCIe Multi-Seg Start
+  // for 8S support needs max 32 IIO IOxAPIC being enabled!
+  UINT8   BusBase[48];		  // MAX_SOCKET * MAX_IIO_STACK. Note: hardcode due to ASL constraint. 
+  UINT8   PCIe_MultiSeg_Support;    // Enable /Disable switch
+  // for 8S support needs matching to MAX_SOCKET!
+  UINT8   PcieSegNum[8];	  // Segment number array. Must match MAX_SOCKET. Note: hardcode due to ASL constraint.
+  // PCIe Multi-seg end
+
+  // Performance Start
+  UINT8   SncAnd2Cluster;           //1=SncEn and NumCluster=2, otherwise 0     
+  // Performance End
+
+ } BIOS_ACPI_PARAM;
+
+#pragma pack ()
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Guid/PchRcVariable.h b/Platform/Intel/PurleyOpenBoardPkg/Include/Guid/PchRcVariable.h
new file mode 100644
index 0000000000..79b7429052
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Guid/PchRcVariable.h
@@ -0,0 +1,414 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef   __PCH_RC_CONFIG_DATA_H__
+#define   __PCH_RC_CONFIG_DATA_H__
+
+#include <PchLimits.h>
+#define HDAUDIO_FEATURES         3
+#define HDAUDIO_PP_MODULES       2
+
+
+/// sSATA max ports for Wellsburg
+#define PCH_SSATA_MAX_PORTS      6
+
+#pragma pack(1)
+typedef struct {
+
+  UINT8   BiosGuard;
+  UINT8   Dwr_Enable;
+  UINT8   Dwr_Stall;
+  UINT8   Dwr_BmcRootPort;
+
+  UINT8   DwrEn_PMCGBL;
+  UINT8   DwrEn_CPUTHRM;
+  UINT8   DwrEn_PCHTHRM;
+  UINT8   DwrEn_PBO;
+  UINT8   DwrEn_MEPBO;
+  UINT8   DwrEn_MEWDT;
+  UINT8   DwrEn_MEGBL;
+  UINT8   DwrEn_CTWDT;
+  UINT8   DwrEn_PMCWDT;
+  UINT8   DwrEn_ME_UERR;
+  UINT8   DwrEn_SYSPWR;
+  UINT8   DwrEn_OCWDT;
+  UINT8   DwrEn_IEPBO;
+  UINT8   DwrEn_IEWDT;
+  UINT8   DwrEn_IEGBLN;
+  UINT8   DwrEn_IE_UERRN;
+  UINT8   DwrEn_ACRU_ERR_2H_EN;
+
+  UINT8   DwrPmcEn_HOST_RESET_TIMEOUT;
+  UINT8   DwrPmcEn_SX_ENTRY_TIMEOUT;
+  UINT8   DwrPmcEn_HOST_RST_PROM;
+  UINT8   DwrPmcEn_HSMB_MSG;
+  UINT8   DwrPmcEn_IE_MTP_TIMEOUT;
+  UINT8   DwrPmcEn_MTP_TIMEOUT;
+  UINT8   DwrPmcEn_ESPI_ERROR_DETECT;
+
+  UINT8   Dwr_MeResetPrepDone;
+  UINT8   Dwr_IeResetPrepDone;
+
+  //
+  // PCH_DEVICE_ENABLES
+  //
+  UINT8   BoardCapability;
+  UINT8   DeepSxMode;
+  UINT8   Gp27WakeFromDeepSx;
+  UINT8   GbeRegionInvalid;
+  UINT8   LomLanSupported;
+  UINT8   PchWakeOnLan;
+  UINT8   PchSlpLanLowDc;
+  UINT8   PchSmbus;
+  UINT8   PchPciClockRun;
+  UINT8   PchDisplay;
+  UINT8   PchCrid;
+  UINT8   PchRtcLock;
+  UINT8   PchBiosLock;
+  UINT8   PchAllUnLock;
+  UINT8   PchThermalUnlock;
+  UINT8   PchSerm;
+  UINT8   PchGbeFlashLockDown;
+  UINT8   PchSmmBwp;
+
+  UINT8   Hpet;
+  UINT8   PchPort80Route;
+  UINT8   EnableClockSpreadSpec;
+  UINT8   IchPort80Route;
+  UINT8   PchSirqMode;
+
+  //
+  // Usb Config
+  //
+  UINT8   PchUsbManualMode;
+  UINT8   PchGpioLockDown;
+  UINT8   RouteUsb2PinsToWhichHc;
+  UINT8   RouteUsb2Pin0;
+  UINT8   RouteUsb2Pin1;
+  UINT8   RouteUsb2Pin2;
+  UINT8   RouteUsb2Pin3;
+  UINT8   RouteUsb2Pin4;
+  UINT8   RouteUsb2Pin5;
+  UINT8   RouteUsb2Pin6;
+  UINT8   RouteUsb2Pin7;
+  UINT8   RouteUsb2Pin8;
+  UINT8   RouteUsb2Pin9;
+  UINT8   RouteUsb2Pin10;
+  UINT8   RouteUsb2Pin11;
+  UINT8   RouteUsb2Pin12;
+  UINT8   RouteUsb2Pin13;
+  UINT8   Usb3PinsTermination;
+  UINT8   EnableUsb3Pin[10];
+  UINT8   PchUsbHsPort[16];
+  UINT8   PchUsbSsPort[10];
+  UINT8   PchUsbPortDisable;
+  UINT8   UsbSensorHub;
+  UINT8   UsbSsicSupport[2];
+  UINT8   XhciDisMSICapability;
+  UINT8   PchUsbPerPortCtl;
+  UINT8   PchUsb30Port[6];
+  UINT8   UsbPrecondition;
+  UINT8   XhciIdleL1;
+  UINT8   Btcg;
+  UINT8   PchUsbDegradeBar;
+  //
+  // XHCI OC Map
+  //
+  UINT8   XhciOcMapEnabled;
+  //
+  // xDCI Config
+  //
+  UINT8   PchXdciSupport;
+  //
+  // Sata CONFIG
+  //
+  UINT8   PchSata;
+  //
+  // Sata Interface Mode
+  // 0 - IDE  1 - RAID  2 - AHCI
+  //
+  UINT8   SataInterfaceMode;
+  UINT8   SataPort[PCH_MAX_SATA_PORTS];
+  UINT8   SataHotPlug[PCH_MAX_SATA_PORTS];
+  UINT8   SataMechanicalSw[PCH_MAX_SATA_PORTS];
+  UINT8   SataSpinUp[PCH_MAX_SATA_PORTS];
+  UINT8   SataExternal[PCH_MAX_SATA_PORTS];
+  UINT8   SataType[PCH_MAX_SATA_PORTS];
+  UINT8   SataRaidR0;
+  UINT8   SataRaidR1;
+  UINT8   SataRaidR10;
+  UINT8   SataRaidR5;
+  UINT8   SataRaidIrrt;
+  UINT8   SataRaidOub;
+  UINT8   SataHddlk;
+  UINT8   SataLedl;
+  UINT8   SataRaidIooe;
+  UINT8   SataRaidSrt;
+  UINT8   SataRaidLoadEfiDriver;
+  UINT8   SataRaidOromDelay;
+  UINT8   SataAlternateId;
+  UINT8   SataSalp;
+  UINT8   SataTestMode;
+  UINT8   PxDevSlp[PCH_MAX_SATA_PORTS];
+  UINT8   EnableDitoConfig[PCH_MAX_SATA_PORTS];
+  UINT16  DitoVal[PCH_MAX_SATA_PORTS];
+  UINT8   DmVal[PCH_MAX_SATA_PORTS];
+  UINT8   SataTopology[PCH_MAX_SATA_PORTS];  
+
+  //
+  // sSata CONFIG
+  //
+  UINT8   PchsSata;
+  //
+  // Sata Interface Mode
+  // 0 - IDE  1 - RAID  2 - AHCI
+  //
+  UINT8   sSataInterfaceMode;
+  UINT8   sSataPort[PCH_SSATA_MAX_PORTS];
+  UINT8   sSataHotPlug[PCH_SSATA_MAX_PORTS];
+  UINT8   sSataSpinUp[PCH_SSATA_MAX_PORTS];
+  UINT8   sSataExternal[PCH_SSATA_MAX_PORTS];
+  UINT8   sPxDevSlp[PCH_SSATA_MAX_PORTS];
+  UINT8   sSataType[PCH_SSATA_MAX_PORTS];
+  UINT8   sSataRaidR0;
+  UINT8   sSataRaidR1;
+  UINT8   sSataRaidR10;
+  UINT8   sSataRaidR5;
+  UINT8   sSataRaidIrrt;
+  UINT8   sSataRaidOub;
+  UINT8   sSataHddlk;
+  UINT8   sSataLedl;
+  UINT8   sSataRaidIooe;
+  UINT8   sSataRaidSrt;
+  UINT8   sSataRaidLoadEfiDriver;
+  UINT8   sSataRaidOromDelay;
+  UINT8   sSataAlternateId;
+  UINT8   sSataSalp;
+  UINT8   sSataTestMode;
+  UINT8   sEnableDitoConfig[PCH_SSATA_MAX_PORTS];
+  UINT8   sDmVal[PCH_SSATA_MAX_PORTS];
+  UINT8   sDitoVal[PCH_SSATA_MAX_PORTS];
+  UINT8   sSataTopology[PCH_SSATA_MAX_PORTS];  
+
+
+
+
+  //PCH THERMAL SENSOR
+  UINT8   ThermalDeviceEnable;
+  UINT8   PchCrossThrottling;
+
+  UINT8   PchDmiExtSync;
+  UINT8   PcieDmiExtSync;
+  // AcpiDebug Setup Options
+  UINT8   PciDelayOptimizationEcr;
+  UINT8   PchPcieGlobalAspm;
+
+  UINT8   PcieDmiStopAndScreamEnable;
+  UINT8   DmiLinkDownHangBypass;
+  UINT8   XTpmLen;
+  UINT8   PcieRootPort8xhDecode;
+  UINT8   Pcie8xhDecodePortIndex;
+  UINT8   PcieRootPortPeerMemoryWriteEnable;
+  UINT8   PcieComplianceTestMode;
+
+
+  UINT8   PcieRootPortSBDE;
+  UINT8   PcieSBDEPort;
+
+  UINT8   RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
+  UINT8   RstPcieStorageRemapPort[PCH_MAX_RST_PCIE_STORAGE_CR];
+  UINT8   PcieRootPortFunctionSwapping;
+  UINT8   PcieRootPortEn[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortAspm[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortURE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortFEE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortNFE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortCEE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortMSIE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortMaxPayLoadSize[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortAER[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieTopology[PCH_MAX_PCIE_ROOT_PORTS];   
+  
+  UINT8   PcieLaneCm[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieLaneCp[PCH_MAX_PCIE_ROOT_PORTS];
+
+  UINT8   PcieSwEqOverride;
+  UINT8   PcieSwEqCoeffCm[PCH_PCIE_SWEQ_COEFFS_MAX];
+  UINT8   PcieSwEqCoeffCp[PCH_PCIE_SWEQ_COEFFS_MAX];
+  UINT8   PchPcieUX8MaxPayloadSize;
+  UINT8   PchPcieUX16MaxPayloadSize;
+  UINT8   PcieRootPortCompletionTimeout[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieClockGatingDisabled;
+  UINT8   PcieUsbGlitchWa;
+  UINT8   PcieRootPortPIE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortACS[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortEqPh3Method[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortMaxReadRequestSize;
+  UINT8   PcieRootPortSFE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortSNE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortSCE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortPMCE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortHPE[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortSpeed[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PcieRootPortTHS[PCH_MAX_PCIE_ROOT_PORTS]; 
+
+  //
+  // PCI Bridge Resources
+  //
+  UINT8   PcieRootPortL1SubStates[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   MemoryThermalManagement;
+  UINT8   ExttsViaTsOnBoard;
+  UINT8   ExttsViaTsOnDimm;
+  UINT8   FixupPlatformSpecificSoftstraps;
+
+  //
+  // SMBUS Configuration
+  //
+  UINT8   TestSmbusSpdWriteDisable;
+
+
+  //
+  // HD-Audio Configuration
+  //
+  UINT8   PchHdAudio;
+  UINT8   PchHdAudioDsp;
+  UINT8   PchHdAudioPme;
+  UINT8   PchHdAudioIoBufferOwnership;
+  UINT8   PchHdAudioIoBufferVoltage;
+  UINT8   PchHdAudioCodecSelect;
+  UINT8   PchHdAudioFeature[HDAUDIO_FEATURES];
+  UINT8   PchHdAudioPostProcessingMod[HDAUDIO_PP_MODULES];
+
+  UINT8   RtoHdaVcType;
+  //
+  // DMI Configuration
+  //
+  UINT8   TestDmiAspmCtrl;
+
+
+  //
+  //
+  // PCIe LTR Configuration
+  //
+  UINT8   PchPcieLtrEnable[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PchPcieLtrConfigLock[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PchPcieSnoopLatencyOverrideMode[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PchPcieSnoopLatencyOverrideMultiplier[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PchPcieNonSnoopLatencyOverrideMode[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PchPcieNonSnoopLatencyOverrideMultiplier[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT16  PchPcieSnoopLatencyOverrideValue[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT16  PchPcieNonSnoopLatencyOverrideValue[PCH_MAX_PCIE_ROOT_PORTS];
+
+  UINT8   PchPcieForceLtrOverride[PCH_MAX_PCIE_ROOT_PORTS];
+  UINT8   PchSataLtrOverride;
+  UINT8   PchSataLtrEnable;
+  UINT16  PchSataSnoopLatencyOverrideValue;
+  UINT8   PchSataSnoopLatencyOverrideMultiplier;
+  UINT8   PchSataLtrConfigLock;
+
+  UINT8   PchSSataLtrOverride;
+  UINT16  PchSSataSnoopLatencyOverrideValue;
+  UINT8   PchSSataSnoopLatencyOverrideMultiplier;
+  UINT8   PchSSataLtrEnable;
+  UINT8   PchSSataLtrConfigLock;
+
+  UINT8   PchPcieUX16CompletionTimeout;
+  UINT8   PchPcieUX8CompletionTimeout;
+
+  //
+  // Interrupt Configuration
+  //
+  UINT8   PchIoApic24119Entries;
+
+  //
+  // DPTF SETUP items begin
+  //
+  UINT8   EnableDptf;
+  UINT8   EnablePchDevice;
+
+  //
+  // CPU
+  //
+  UINT8   DebugDciEnable;
+  UINT8   DebugInterfaceEnable;
+
+  //
+  // Miscellaneous options
+  //
+  UINT8   OsDebugPort;
+  UINT8   SlpLanLowDc;
+  UINT8   PchLanK1Off;
+  UINT8   PchWakeOnWlan;
+  UINT8   PchWakeOnWlanDeepSx;
+  UINT8   StateAfterG3;
+  UINT8   PciePllSsc;
+  UINT8   FirmwareConfiguration;
+  UINT8   PchDciEn;
+  UINT8   PchDciAutoDetect;
+
+  // Acpi.sd
+  UINT8   CSNotifyEC;
+  UINT8   EcLowPowerMode;
+
+  //
+  // TraceHub Setup Options
+  //
+  UINT8   TraceHubEnableMode;
+  UINT8   MemRegion0BufferSize;
+  UINT8   MemRegion1BufferSize;
+
+  //
+  // PCH P2SB hide and lock options
+  //
+  UINT8   PchP2sbDevReveal;
+  UINT8   PchP2sbUnlock;
+
+  //
+  // PCH SPI hide and lock options
+  //
+  UINT8   FlashLockDown;
+
+  //
+  // PCH PMC option
+  //
+  UINT8   PmcReadDisable;
+
+
+  //
+  // ADR Configuration
+  //
+  UINT8   PchAdrEn;
+  UINT8   AdrTimerEn;
+  UINT8   AdrTimerVal;
+  UINT8   AdrMultiplierVal;
+  UINT8   AdrGpioSel;
+  UINT8   AdrHostPartitionReset;
+
+  //
+  // Audio DSP Configuration
+  //
+  UINT8   PchAudioDsp;
+  UINT8   PchAudioDspD3PowerGating;
+  UINT8   PchAudioDspAcpiMode;
+  UINT8   PchAudioDspBluetooth;
+  UINT8   PchAudioDspAcpiInterruptMode;
+
+  //
+  // Miscellaneous options
+  //
+
+  UINT8   PchEvaMrom0HookEnable;
+  UINT8   PchEvaMrom1HookEnable;
+  UINT8   TestMctpBroadcastCycle;
+  UINT8   PchEvaLockDown;
+  UINT8   PchTraceHubHide;
+} PCH_RC_CONFIGURATION;
+#pragma pack()
+
+#endif
+
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Guid/SetupVariable.h b/Platform/Intel/PurleyOpenBoardPkg/Include/Guid/SetupVariable.h
new file mode 100644
index 0000000000..f8ea067b50
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Guid/SetupVariable.h
@@ -0,0 +1,539 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __SETUP_VARIABLE_H__
+#define __SETUP_VARIABLE_H__
+
+#include "UncoreCommonIncludes.h"
+// ---------------------------------------------------------------------------
+//
+// Driver Configuration
+//
+// ---------------------------------------------------------------------------
+//
+
+#define MAX_PCH_PCI_EXPRESS_ROOT_PORTS  8
+#define PASSWORD_MAX_SIZE              16
+#define SHA256_DIGEST_LENGTH           32
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+
+#pragma pack(1)
+
+typedef struct {
+
+  UINT8   UserPassword[SHA256_DIGEST_LENGTH];
+  UINT8   AdminPassword[SHA256_DIGEST_LENGTH];
+  UINT8   Access;
+
+  //
+  // Keyboard
+  //
+  UINT8   Numlock;
+  UINT8   Ps2PortSwap;
+
+  //
+  // TPM
+  //
+  UINT8         TpmEnable;
+  UINT8         TpmState;
+  UINT8         MorState;
+
+  //
+  // Breakpoints
+  //
+  UINT8   ValidationBreakpointType;
+  UINT16   bsdBreakpoint;
+
+  //
+  // Power State
+  //
+  UINT8   PowerState;
+
+  //
+  // Wake On Lan
+  //
+  UINT8   WakeOnLanS5;
+
+  //
+  // Boot from Network
+  //
+  UINT8   BootNetwork;
+
+  //
+  // Video
+  //
+  UINT8   VideoSelect;
+  UINT8   EfiWindowsInt10Workaround;
+  UINT8   UefiOptimizedBootToggle;
+
+  //
+  // Fan PWM Offset
+  //
+  UINT8    FanPwmOffset;
+
+  //
+  // PCI Minimum Secondary Bus Number
+  //
+  UINT8   PCIe_MultiSeg_Support;
+
+  //
+  UINT8   WakeOnLanSupport;
+  //
+  // Enable/disable for PCIe LOM by using GPO44/45
+  // NOT PCH LAN
+  //
+  UINT8   LomDisableByGpio;
+
+  UINT8   FpkPortConfig[4];
+  UINT8   FpkPortConfigPrev[4];
+  UINT8   FpkPortPresent[4];
+
+  // RTC WAKE
+  //
+  UINT8   WakeOnRTCS4S5;
+  UINT8   RTCWakeupTimeHour;
+  UINT8   RTCWakeupTimeMinute;
+  UINT8   RTCWakeupTimeSecond;
+  // PCI_EXPRESS_CONFIG, ROOT PORTS
+  //
+  // AJW: these cross the line, but depend on Platform Info
+  UINT8   PcieClockGating;
+  UINT8   PcieDmiAspm;
+  UINT8   PcieSBDE;
+  UINT8   GbePciePortNum;
+  UINT8   PciePortConfig1;
+  UINT8   PciePortConfig2;
+  UINT8   PciePortConfig3;
+  UINT8   PciePortConfig4;
+  UINT8   PciePortConfig5;
+
+  // GBE
+  UINT8 GbeEnabled;
+
+  // PCH Stepping
+  UINT8 PchStepping;
+
+  //
+  // XHCI Wake On USB
+  //
+  UINT8   XhciWakeOnUsbEnabled;
+
+  //
+  // EventLog
+  //
+//
+// SKX_TODO: add these for RAS, may be best to find new home for them in a new setup variable and setup page
+//
+  UINT8   SystemErrorEn;
+  //Viral, and IoMca are not supported in EP. Will need to wrap in an EX flag
+  //UINT8   ViralEn;
+  UINT8   PoisonEn;
+  UINT8   ViralEn;
+  UINT8   ClearViralStatus;
+  UINT8   CloakingEn;
+  UINT8   UboxToPcuMcaEn;
+  UINT8   FatalErrSpinLoopEn;
+
+  UINT8   EmcaEn;
+  UINT8   EmcaIgnOptin;
+  UINT8   EmcaCsmiEn;
+  UINT8   EmcaMsmiEn;
+  UINT8   ElogCorrErrEn;
+  UINT8   ElogMemErrEn;
+  UINT8   ElogProcErrEn;
+  UINT8   LmceEn;
+
+  UINT8   WheaSupportEn;
+  UINT8   WheaLogMemoryEn;
+  UINT8   WheaLogProcEn;
+
+  UINT8   WheaLogPciEn;
+
+  UINT8   WheaErrorInjSupportEn;
+  UINT8   McaBankErrInjEn;
+  UINT8   WheaErrInjEn;
+  UINT8   WheaPcieErrInjEn;
+  UINT8   MeSegErrorInjEn;
+  UINT8   PcieErrInjActionTable;
+  UINT8   ParityCheckEn;
+
+  UINT8   MemErrEn;
+  UINT8   CorrMemErrEn;
+  UINT32  LeakyBktHiLeakyBktLo;
+  UINT8   SpareIntSelect;
+  UINT8   FnvErrorEn;
+  UINT8   FnvErrorLowPrioritySignal;  // 0 - No Log, 1 - SMI, 2 - ERR0#, 3 - BOTH
+  UINT8   FnvErrorHighPrioritySignal; // 0 - No Log, 1 - SMI, 2 - ERR0#, 3 - BOTH
+  UINT8   Reserved_1;
+  UINT8   Reserved_2;
+  UINT8   Reserved_3;
+
+  UINT8   IioErrorEn;
+  UINT8   IoMcaEn;
+  UINT8   IioErrRegistersClearEn;
+  UINT8   IioErrorPinEn;
+  UINT8   LerEn;
+  UINT8   DisableMAerrorLoggingDueToLER;
+  UINT8   IioIrpErrorEn;
+  UINT8   IioMiscErrorEn;
+  UINT8   IioVtdErrorEn;
+  UINT8   IioDmaErrorEn;
+  UINT8   IioDmiErrorEn;
+  UINT8   IioPcieAddCorrErrorEn;
+  UINT8   IioPcieAddUnCorrEn;
+  UINT8   IioPcieAerSpecCompEn;
+
+  UINT8   PcieErrEn;
+  UINT8   PcieCorrErrEn;
+  UINT8   PcieUncorrErrEn;
+  UINT8   PcieFatalErrEn;
+  UINT8   PcieCorErrCntr;
+  UINT8   PcieCorErrMaskBitMap;
+  UINT16  PcieCorErrThres;
+  UINT8   PcieAerCorrErrEn;
+  UINT8   PcieAerAdNfatErrEn;
+  UINT8   PcieAerNfatErrEn;
+  UINT8   PcieAerFatErrEn;
+  UINT8   SerrPropEn;
+  UINT8   PerrPropEn;
+  UINT8   OsSigOnSerrEn;
+  UINT8   OsSigOnPerrEn;
+
+  UINT8   CaterrGpioSmiEn;
+
+// Endof RAS add
+  //Viral, and IoMca are not supported in EP. Will need to wrap in an EX flag
+  //UINT8   IoMcaEn;
+
+  UINT8   McBankWarmBootClearError;
+  UINT8   KTIFailoverSmiEn;
+
+  UINT8   irpp0_parityError;
+  UINT8   irpp0_qtOverflow;
+  UINT8   irpp0_unexprsp;
+  UINT8   irpp0_csraccunaligned;
+  UINT8   irpp0_unceccCs1;
+  UINT8   irpp0_unceccCs0;
+  UINT8   irpp0_rcvdpoison;
+  UINT8   irpp0_crreccCs1;
+  UINT8   irpp0_crreccCs0;
+
+  UINT8   PropagateSerr;
+  UINT8   PropagatePerr;
+
+  //
+  // Boot Options
+  //
+  UINT8   serialDebugMsgLvl;
+  UINT8   serialDebugTrace;
+  UINT8   serialDebugMsgLvlTrainResults;
+  UINT8   ResetOnMemMapChange;
+  UINT8   ForceSetup;
+  UINT8   BiosGuardEnabled;
+  UINT8   BiosGuardPlatformSupported;
+  UINT8   EnableAntiFlashWearout;
+  UINT8   AntiFlashWearoutSupported;
+  UINT8   RtoPopulateBGDirectory;
+
+  UINT8   Use1GPageTable;
+  //
+  // UINT8   QuietBoot;
+  //
+  UINT8   FastBoot;
+
+  //
+  // Reserve Memory that is hidden from the OS.
+  //
+  UINT8   ReserveMem;
+  UINT64  ReserveStartAddr;
+
+  //
+  // Reserve TAGEC Memory
+  //
+  UINT8  TagecMem;
+
+  //Usb Configdata
+  UINT8   UsbMassDevNum;
+  UINT8   UsbLegacySupport;
+  UINT8   UsbEmul6064;
+  UINT8   UsbMassResetDelay;
+  UINT8   UsbNonBoot;
+  UINT8   UsbEmu1;
+  UINT8   UsbEmu2;
+  UINT8   UsbEmu3;
+  UINT8   UsbEmu4;
+  UINT8   UsbEmu5;
+  UINT8   UsbEmu6;
+  UINT8   UsbEmu7;
+  UINT8   UsbEmu8;
+  UINT8   UsbEmu9;
+  UINT8   UsbEmu10;
+  UINT8   UsbEmu11;
+  UINT8   UsbEmu12;
+  UINT8   UsbEmu13;
+  UINT8   UsbEmu14;
+  UINT8   UsbEmu15;
+  UINT8   UsbEmu16;
+  UINT8   UsbStackSupport;
+
+  // Console Redirection
+  UINT8   ConsoleRedirection;
+  UINT8   FlowControl;
+  UINT64  BaudRate;
+  UINT8   TerminalType;
+  UINT8   LegacyOsRedirection;
+  UINT8   TerminalResolution;
+  UINT8   DataBits;
+  UINT8   Parity;
+  UINT8   StopBits;
+
+#ifdef EFI_PCI_IOV_SUPPORT
+  UINT8   SystemPageSize;
+  UINT8   ARIEnable;
+  UINT8   ARIForward;
+  UINT8   SRIOVEnable;
+  UINT8   MRIOVEnable;
+#endif
+  //
+  // RAS
+  //
+
+//
+// Network setup entries - start here <><><><><>
+//
+  UINT8  LegacyPxeRom;
+  UINT8  EfiNetworkSupport;
+//
+// Network setup entries - end here <><><><><>
+//
+
+//
+// SERIALPORT BAUD RATE: Begin
+//
+  UINT32        SerialBaudRate;
+//
+// SERIALPORT BAUD RATE: END
+//
+
+  UINT8         BootAllOptions;
+  UINT8         SetShellFirst;
+
+  //
+  // Overclocking related setup variables
+  //
+  UINT8  PlatformOCSupport;
+  UINT8  FilterPll;
+  UINT8  OverclockingSupport;
+
+  UINT8  CoreMaxOcRatio;
+  UINT8  CoreVoltageMode;
+  UINT16 CoreVoltageOverride;
+  UINT16 CoreVoltageOffset;
+  UINT8  CoreVoltageOffsetPrefix;
+  UINT16 CoreExtraTurboVoltage;
+
+  //
+  // OC related
+  //
+  UINT8  MemoryVoltage;
+  UINT8  MemoryVoltageDefault;
+  UINT8  tCL;
+
+  //
+  // CLR Related
+  //
+  UINT8   ClrMaxOcRatio;
+  UINT8   ClrVoltageMode;
+  UINT16  ClrVoltageOverride;
+  UINT16  ClrVoltageOffset;
+  UINT8   ClrVoltageOffsetPrefix;
+  UINT16  ClrExtraTurboVoltage;
+
+  //
+  // Uncore Related
+  //
+  UINT16   UncoreVoltageOffset;
+  UINT8    UncoreVoltageOffsetPrefix;
+  UINT16   IoaVoltageOffset;
+  UINT8    IoaVoltageOffsetPrefix;
+  UINT16   IodVoltageOffset;
+  UINT8    IodVoltageOffsetPrefix;
+
+  //
+  //  SVID and FIVR Related
+  //
+  UINT8   SvidEnable;
+  UINT16  SvidVoltageOverride;
+  UINT8   FivrFaultsEnable;
+  UINT8   FivrEfficiencyEnable;
+
+  UINT8 SataInterfaceRAIDMode;
+  UINT8 sSataInterfaceRAIDMode;
+
+  UINT16  C01MemoryVoltage;
+  UINT16  C23MemoryVoltage;
+
+  UINT16  CpuVccInVoltage;
+
+  UINT8   VccIoVoltage;
+
+  UINT8   CloudProfile;
+  UINT16  VariablePlatId;
+
+  //XTU 3.0
+
+  UINT8 FlexRatioOverrideDefault;
+  UINT8 RatioLimit1Default;
+  UINT8 RatioLimit2Default;
+  UINT8 RatioLimit3Default;
+  UINT8 RatioLimit4Default;
+  UINT8 OverclockingLockDefault;
+  UINT8 DdrRefClkDefault;
+  UINT8 DdrRatioDefault;
+  UINT8 tCLDefault;
+  UINT8 tCWLDefault;
+  UINT16 tFAWDefault;
+  UINT16 tRASDefault;
+  UINT16 tRCDefault;
+  UINT8 tRCDDefault;
+  UINT16 tREFIDefault;
+  UINT16 tRFCDefault;
+  UINT8 tRPDefault;
+  UINT8 tRPabDefault;
+  UINT8 tRRDDefault;
+  UINT8 tRTPDefault;
+  UINT8 tWRDefault;
+  UINT8 tWTRDefault;
+  UINT8 NModeDefault;
+  UINT8 CoreMaxOcRatioDefault;
+  UINT8 CoreVoltageModeDefault;
+  UINT16 CoreVoltageOverrideDefault;
+  UINT16 CoreVoltageOffsetDefault;
+  UINT8 CoreVoltageOffsetPrefixDefault;
+  UINT16 CoreExtraTurboVoltageDefault;
+  UINT8 GtOcSupportDefault;
+  UINT8 GtOcFrequencyDefault;
+  UINT16 GtExtraTurboVoltageDefault;
+  UINT16 GtOcVoltageDefault;
+  UINT8 GtVoltageModeDefault;
+  UINT16 GtVoltageOverrideDefault;
+  UINT16 GtVoltageOffsetDefault;
+  UINT8 GtVoltageOffsetPrefixDefault;
+  UINT8 ClrMaxOcRatioDefault;
+  UINT8 ClrVoltageModeDefault;
+  UINT16 ClrVoltageOverrideDefault;
+  UINT16 ClrVoltageOffsetDefault;
+  UINT8 ClrVoltageOffsetPrefixDefault;
+  UINT16 ClrExtraTurboVoltageDefault;
+  UINT16 UncoreVoltageOffsetDefault;
+  UINT8 UncoreVoltageOffsetPrefixDefault;
+  UINT16 IoaVoltageOffsetDefault;
+  UINT8 IoaVoltageOffsetPrefixDefault;
+  UINT16 IodVoltageOffsetDefault;
+  UINT8 IodVoltageOffsetPrefixDefault;
+  UINT8 SvidEnableDefault;
+  UINT16 SvidVoltageOverrideDefault;
+  UINT8 FivrFaultsEnableDefault;
+  UINT8 FivrEfficiencyEnableDefault;
+  UINT16 VrCurrentLimitDefault;
+  UINT8 EnableGvDefault;
+  UINT8 TurboModeDefault;
+  UINT8 PowerLimit1TimeDefault;
+  UINT16 PowerLimit1Default;
+  UINT16 PowerLimit2Default;
+
+
+  UINT8 RatioLimit1; //ratiolimit handling has changed in SKX. knobs might need to change too. Will have to revisit again.
+  UINT8 RatioLimit2;
+  UINT8 RatioLimit3;
+  UINT8 RatioLimit4;
+  UINT8 CpuRatio; // need to understand what is the difference between maxnonturboratio and cpuratio. if cpuratiooverride is 0, then cpuratio is same as maxnonturboratio. add this to platform cpu policy or socketsetup.
+  UINT8 CpuRatioOverride;
+  UINT8 IsTurboRatioDefaultsInitalized; // related to initializing all the vardefault. is this flow needed for HEDT/intended only for clients? no need for set up creation.
+
+
+  UINT8 DdrRefClk; //cant find any in purley. new one?
+  UINT8 PcieRatioDisabled;//need to check if this is applicable to HEDT. also no need to create a setup variable.
+  UINT8 NMode ;
+  UINT8 Pmtt;
+
+  UINT16 GtVoltageOffset; //existing but no set up option
+  UINT16 VrCurrentLimit;//done
+  //UINT8 SpdProfileSelected; same as XMPMode
+  UINT8 NModeSupport;
+  UINT8 WDTSupportforNextOSBoot; // no setup option needed
+  UINT16 TimeforNextOSBoot; // no setup optiom needed
+  UINT8 PlatformUnstable; // no set up option needed. this decides if all the vardefaults are needed.
+  UINT8 GtVoltageMode; //existing but no set up option
+  UINT8 DdrRatio;
+  UINT8 GtOcFrequency;
+  UINT16 GtExtraTurboVoltage; //existing but no set up option
+  UINT16 GtVoltageOverride; //existing but no set up option
+  UINT8 GtVoltageOffsetPrefix;
+  UINT8 GtOcSupport;
+  //
+  // CPU releated
+  //
+  UINT8 FlexOverrideEnable;
+  UINT8 FlexRatioOverride;
+  UINT8 PowerLimit3Override;
+  UINT32 PowerLimit3;
+  UINT8 PowerLimit3Time;
+  UINT8 PowerLimit3DutyCycle;
+  UINT8 PowerLimit3Lock;
+  UINT8 MemoryVoltageOverride;
+
+  //
+  // ICC Related
+  //
+  UINT8 BClkOverride;
+  UINT8 BclkAdjustable;
+  UINT8 DmiPegRatio;
+  UINT8 SkipXmlComprs;
+  UINT8 DfxAdvDebugJumper;
+  UINT8 DfxAltPostCode;
+
+  //
+  // Validation Related
+  //
+  UINT8   ValidationResetType;
+  UINT16  ValidationCountOuter;
+  UINT16  ValidationCountInner;
+  UINT8   ValidationStopOnError;
+  UINT8   ValidationBootWhenDone;
+  UINT8   ValidationSkxPciError;
+  UINT8   ValidationSkxPciLinkError;
+  UINT8   ValidationPchPciError;
+  UINT8   ValidationSkxPciLinkRecoveryCountError;
+  UINT16  ValidationSkxPciLinkRecoveryCountThreshold;
+  UINT8   ValidationKtiError;
+
+  UINT8 TraceHubDebugInterface;
+  UINT8 RamDebugInterface;
+  UINT8   StorageOpROMSuppression;
+//
+// PC_SIO_END
+//
+  UINT8   RsaSupport;
+
+} SYSTEM_CONFIGURATION;
+
+#pragma pack()
+
+#define EFI_HDD_PRESENT       0x01
+#define EFI_HDD_NOT_PRESENT   0x00
+#define EFI_CD_PRESENT        0x02
+#define EFI_CD_NOT_PRESENT    0x00
+
+#define EFI_HDD_WARNING_ON    0x01
+#define EFI_CD_WARNING_ON     0x02
+#define EFI_SMART_WARNING_ON  0x04
+#define EFI_HDD_WARNING_OFF   0x00
+#define EFI_CD_WARNING_OFF    0x00
+#define EFI_SMART_WARNING_OFF 0x00
+
+#endif // #ifndef _SETUP_VARIABLE
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/IioBifurcationSlotTable.h b/Platform/Intel/PurleyOpenBoardPkg/Include/IioBifurcationSlotTable.h
new file mode 100644
index 0000000000..76450ec21f
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/IioBifurcationSlotTable.h
@@ -0,0 +1,100 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef IIOBIFURCATIONSLOTTABLE_H
+#define IIOBIFURCATIONSLOTTABLE_H
+
+#include "IioPlatformData.h"
+
+#define QAT_ENABLED                0  // QAT is active-low
+#define RISER_PRESENT              0
+#define RISER_NOT_PRESENT          1
+#define RISER_HP_EN                1
+#define RISER_WINGED_IN            0
+#define RISER_SLOT9_DISABLE        1
+
+typedef struct {
+  UINT8 Socket;
+  UINT8 IouNumber;
+  UINT8 Bifurcation;
+} IIO_BIFURCATION_ENTRY;
+
+typedef union {
+  struct {
+    UINT8 PresentSignal:1;
+    UINT8 HPConf:1;
+    UINT8 WingConf:1;
+    UINT8 Slot9En:1;
+  } Bits;
+  UINT8 Data;
+} PCIE_RISER_ID;
+
+enum {
+  Iio_PortA = 0,
+  Iio_PortB = 1,
+  Iio_PortC = 2,
+  Iio_PortD = 3
+};
+typedef enum {
+ Iio_Iou0 =0,
+ Iio_Iou1,
+ Iio_Iou2,
+ Iio_Mcp0,
+ Iio_Mcp1,
+ Iio_IouMax
+} IIO_IOUS;
+
+typedef enum {
+  Iio_Socket0 = 0,
+  Iio_Socket1,
+  Iio_Socket2,
+  Iio_Socket3,
+  Iio_Socket4,
+  Iio_Socket5,
+  Iio_Socket6,
+  Iio_Socket7
+} IIO_SOCKETS;
+
+typedef enum {
+  VPP_PORT_0 = 0,
+  VPP_PORT_1,
+  VPP_PORT_2,
+  VPP_PORT_3
+} VPP_PORT;
+///
+/// Platform Port/Socket assignments.
+///
+
+#define ENABLE            1
+#define DISABLE           0
+#define NO_SLT_IMP        0xFF
+#define SLT_IMP           1
+#define HIDE              1
+#define NOT_HIDE          0
+#define VPP_PORT_0        0
+#define VPP_PORT_1        1
+#define VPP_PORT_MAX      0xFF
+#define VPP_ADDR_MAX      0xFF
+#define PWR_VAL_MAX       0xFF
+#define PWR_SCL_MAX       0xFF
+
+typedef struct {
+  UINT8   PortIndex;
+  UINT8   SlotNumber;     // 0xff if slot not implemented , Slot number if slot implemented
+  BOOLEAN InterLockPresent;
+  UINT8   SlotPowerLimitScale;
+  UINT8   SlotPowerLimitValue;
+  BOOLEAN HotPlugCapable;
+  UINT8   VppPort; // 0xff if Vpp not enabled
+  UINT8   VppAddress;
+  BOOLEAN PcieSSDCapable;
+  UINT8   PcieSSDVppPort; // 0xff if Vpp not enabled
+  UINT8   PcieSSDVppAddress;
+  BOOLEAN Hidden;
+} IIO_SLOT_CONFIG_ENTRY;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Platform.h b/Platform/Intel/PurleyOpenBoardPkg/Include/Platform.h
new file mode 100644
index 0000000000..160506039a
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Platform.h
@@ -0,0 +1,92 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Uefi.h"
+#include "Guid/SetupVariable.h"
+#include "UncoreCommonIncludes.h"
+#include <Library/PcdLib.h>
+
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+//
+// Assigning default ID and base addresses here, these definitions are used by ACPI tables
+// 
+
+#define PCH_INTERRUPT_BASE              0
+
+#if MAX_SOCKET > 4
+#define PCH_IOAPIC                      0
+#else
+#define PCH_IOAPIC                      (1 << 0)
+#endif
+
+//
+// This structure stores the base and size of the ACPI reserved memory used when
+// resuming from S3.  This region must be allocated by the platform code.
+//
+typedef struct {
+  UINT32  AcpiReservedMemoryBase;
+  UINT32  AcpiReservedMemorySize;
+  UINT32  SystemMemoryLength;
+} RESERVED_ACPI_S3_RANGE;
+
+#define RESERVED_ACPI_S3_RANGE_OFFSET (EFI_PAGE_SIZE - sizeof (RESERVED_ACPI_S3_RANGE))
+
+//
+// SMBUS Data
+//
+#define PCH_SMBUS_BASE_ADDRESS          0x0780
+
+//
+// CMOS usage
+//
+
+#define CMOS_WARM_RESET_COUNTER_OFFSET       0xBD    // 1 byte CMOS Space for passing warm reset counter to Dxe
+                                                     //   due to reset in MRC Dxe always thinks that warm reset occurs
+                                                     //   counter > 1 -> means WarmReset
+
+//
+// ACPI and legacy I/O register offsets from PMBASE
+//
+#define R_ACPI_PM1_STS                      0x00
+#define R_ACPI_PM1_EN                       0x02
+#define R_ACPI_PM1_CNT                      0x04
+#define R_ACPI_PM1_TMR                      0x08
+#define R_ACPI_PROC_CNT                     0x10
+#define R_ACPI_PM2_CNT                      0x50
+#define R_ACPI_GPE0_STS                     0x20
+#define R_ACPI_GPE0_EN                      0x28
+#define R_ACPI_SMI_EN                       0x30
+#define R_ACPI_SMI_STS                      0x34
+#define R_ACPI_ALT_GP_SMI_EN                0x38
+#define R_ACPI_ALT_GP_SMI_STS               0x3A
+
+#define R_ACPI_LV2                          0x14
+
+#define R_IOPORT_CMOS_STANDARD_INDEX            0x70
+#define R_IOPORT_CMOS_STANDARD_DATA             0x71
+
+#define R_IOPORT_CMOS_UPPER_INDEX               0x72
+#define R_IOPORT_CMOS_UPPER_DATA                0x73
+
+#define R_IOPORT_CMOS_IDX_DIAGNOSTIC_STATUS     0x0E
+
+//
+// Misc PCI register offsets and sizes
+//
+#define R_EFI_PCI_SVID                              0x2C
+#define   V_EFI_PCI_SVID_SIZE                         0x2
+#define R_EFI_PCI_SID                               0x2E
+#define   V_EFI_PCI_SID_SIZE                          0x2
+
+//
+// Need min. of 24 MB PEI phase
+//
+#define PEI_MIN_MEMORY_SIZE             (EFI_PHYSICAL_ADDRESS) ((320 * 0x100000))
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Ppi/SystemBoard.h b/Platform/Intel/PurleyOpenBoardPkg/Include/Ppi/SystemBoard.h
new file mode 100644
index 0000000000..ce0ebaf973
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Ppi/SystemBoard.h
@@ -0,0 +1,63 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PEI_SYSTEM_BOARD__H_
+#define _PEI_SYSTEM_BOARD__H_
+
+#include <Guid/SetupVariable.h>
+#include <Guid/PchRcVariable.h>
+#include <Pi/PiBootMode.h>
+#include <Platform.h>
+#include <SysHost.h>
+#include <Ppi/PchPolicy.h>
+#include <Library/GpioLib.h>
+
+///
+/// The forward declaration for SYSTEM_BOARD_INFO_PPI.
+///
+typedef struct _SYSTEM_BOARD_PPI  SYSTEM_BOARD_PPI;
+
+/**
+
+  SystemIioPortBifurcationInit is used to updating the IIO_GLOBALS Data Structure with IIO
+  SLOT config data
+  Bifurcation config data
+
+  @param *mSB - pointer to this protocol
+
+  @retval *IioUds updated with SLOT and Bifurcation information updated.
+
+**/
+typedef
+VOID
+  (EFIAPI *PEI_SYSTEM_IIO_PORT_BIF_INIT) (
+    IN IIO_GLOBALS *IioGlobalData
+  );
+/**
+
+  GetUplinkPortInformation is used to get board based uplink port information
+
+  @param IioIndex - Socket ID
+
+  @retval PortIndex for uplink.
+
+**/
+typedef
+UINT8
+  (EFIAPI *PEI_GET_UPLINK_PORT_INFORMATION) (
+    IN UINT8 IioIndex
+  );
+
+
+struct _SYSTEM_BOARD_PPI {
+  PEI_SYSTEM_IIO_PORT_BIF_INIT      SystemIioPortBifurcationInit; // Update OEM IIO Port Bifurcation based on PlatformConfiguration
+  PEI_GET_UPLINK_PORT_INFORMATION   GetUplinkPortInformation; // Get Uplink port information
+};
+
+extern EFI_GUID gEfiPeiSystemBoardPpiGuid;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/Protocol/PciIovPlatform.h b/Platform/Intel/PurleyOpenBoardPkg/Include/Protocol/PciIovPlatform.h
new file mode 100644
index 0000000000..43762cf9ee
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/Protocol/PciIovPlatform.h
@@ -0,0 +1,70 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCI_IOV_PLATFORM_H_
+#define _PCI_IOV_PLATFORM_H_
+
+
+//
+// Protocol for GUID.
+//
+
+typedef struct _EFI_PCI_IOV_PLATFORM_PROTOCOL EFI_PCI_IOV_PLATFORM_PROTOCOL;
+
+typedef    UINT32   EFI_PCI_IOV_PLATFORM_POLICY;
+ 
+#define     EFI_PCI_IOV_POLICY_ARI           0x0001
+#define     EFI_PCI_IOV_POLICY_SRIOV         0x0002
+#define     EFI_PCI_IOV_POLICY_MRIOV         0x0004
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_PCI_IOV_PLATFORM_GET_SYSTEM_LOWEST_PAGE_SIZE) (
+  IN  EFI_PCI_IOV_PLATFORM_PROTOCOL           *This,
+  OUT UINT32                                  *SystemLowestPageSize
+)
+/**
+
+    The GetSystemLowestPageSize() function retrieves the system lowest page size.
+    
+    @param This                 - Pointer to the EFI_PCI_IOV_PLATFORM_PROTOCOL instance.
+    @param SystemLowestPageSize - The system lowest page size. (This system supports a
+                                  page size of 2^(n+12) if bit n is set.)
+    
+    @retval EFI_SUCCESS           - The function completed successfully.
+    @retval EFI_INVALID_PARAMETER - SystemLowestPageSize is NULL.
+    
+**/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_PCI_IOV_PLATFORM_GET_PLATFORM_POLICY) (
+  IN  EFI_PCI_IOV_PLATFORM_PROTOCOL           *This,
+  OUT EFI_PCI_IOV_PLATFORM_POLICY             *PciIovPolicy
+)
+/**
+
+    The GetPlatformPolicy() function retrieves the platform policy regarding PCI IOV.
+    
+    @param This         - Pointer to the EFI_PCI_IOV_PLATFORM_PROTOCOL instance.
+    @param PciIovPolicy - The platform policy for PCI IOV configuration.
+    
+    @retval EFI_SUCCESS           - The function completed successfully.
+    @retval EFI_INVALID_PARAMETER - PciPolicy is NULL.
+    
+**/
+;
+
+typedef struct _EFI_PCI_IOV_PLATFORM_PROTOCOL {
+  EFI_PCI_IOV_PLATFORM_GET_SYSTEM_LOWEST_PAGE_SIZE          GetSystemLowestPageSize;
+  EFI_PCI_IOV_PLATFORM_GET_PLATFORM_POLICY                  GetPlatformPolicy;
+} EFI_PCI_IOV_PLATFORM_PROTOCOL;
+
+extern EFI_GUID   gEfiPciIovPlatformProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/SetupTable.h b/Platform/Intel/PurleyOpenBoardPkg/Include/SetupTable.h
new file mode 100644
index 0000000000..7d8742ad4d
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/SetupTable.h
@@ -0,0 +1,21 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SETUP_TABLE_H_
+#define _SETUP_TABLE_H_
+
+#include <Guid/SocketVariable.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PchRcVariable.h>
+
+typedef struct {
+  SOCKET_CONFIGURATION       SocketConfig;
+  SYSTEM_CONFIGURATION       SystemConfig;
+  PCH_RC_CONFIGURATION       PchRcConfig;
+} SETUP_DATA;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Include/SioRegs.h b/Platform/Intel/PurleyOpenBoardPkg/Include/SioRegs.h
new file mode 100644
index 0000000000..8b25ad3162
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Include/SioRegs.h
@@ -0,0 +1,35 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SIO_REG_H_
+#define _SIO_REG_H_
+
+typedef struct {
+  UINT8 Index;
+  UINT8 Value;
+} SIO_INDEX_DATA;
+
+#define REG_LOGICAL_DEVICE        0x07
+#define ACTIVATE                  0x30
+
+#define BASE_ADDRESS_HIGH0        0x60
+#define BASE_ADDRESS_LOW0         0x61
+#define INTERRUPT_TYPE            0x71
+
+#define SIO_INDEX_PORT  0x2E
+#define SIO_DATA_PORT   0x2F
+
+#define SIO_UART1       0x02
+#define SIO_SMI         0x0D
+#define SIO_MAILBOX     0x0E
+
+#define SIO_UNLOCK      0xA5
+#define SIO_LOCK        0xAA
+
+#define EXIST BIT4
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/PurleyOpenBoardPkg/OpenBoardPkg.dec
new file mode 100644
index 0000000000..96dd6b5b48
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/OpenBoardPkg.dec
@@ -0,0 +1,141 @@
+## @file
+# Declaration file for Purley based boards.
+#
+# The DEC files are used by the utilities that parse DSC and
+# INF files to generate AutoGen.c and AutoGen.h files
+# for the build infrastructure.
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = OpenBoardPkg
+  PACKAGE_GUID                   = 454FB726-6A01-49ce-B222-749CD093D3C5
+  PACKAGE_VERSION                = 0.91
+
+[Includes]
+  Include
+
+[Guids]
+  gEfiMemoryConfigDataGuid                            = { 0x80dbd530, 0xb74c, 0x4f11, { 0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 } }
+  gCpPlatFlashTokenSpaceGuid                          = { 0xc9c39664, 0x96dd, 0x4c5c, { 0xaf, 0xd7, 0xcd, 0x65, 0x76, 0x29, 0xcf, 0xb0 } }
+  gOemSkuTokenSpaceGuid                               = { 0x9e37d253, 0xabf8, 0x4985, { 0x8e, 0x23, 0xba, 0xca, 0x10, 0x39, 0x56, 0x13 } }
+  gEfiIpmiPkgTokenSpaceGuid                           = { 0xe96431d, 0xc68e, 0x4212, { 0xa1, 0x70, 0x16, 0xa6, 0x8, 0x55, 0x12, 0xc6 } }
+  gPlatformTokenSpaceGuid                             = { 0x07dfa0d2, 0x2ac5, 0x4cab, { 0xac, 0x14, 0x30, 0x5c, 0x62, 0x48, 0x87, 0xe4 } }
+
+[Ppis]
+  gEfiPeiSystemBoardPpiGuid                           = { 0xc8d85e8c, 0xdc1c, 0x4f8c, { 0xad, 0xa7, 0x58, 0xc1, 0xd1, 0x07, 0xa3, 0x04 } }
+  gEfiSiliconRcHobsReadyPpi                           = { 0xecf149b5, 0xbf4e, 0x4ac8, { 0x8a, 0x8c, 0xce, 0x87, 0xcb, 0xac, 0x93, 0xd3 } }
+
+[Protocols]
+  gEfiPciIovPlatformProtocolGuid                      = { 0xf3a4b484, 0x9b26, 0x4eea, { 0x90, 0xe5, 0xa2, 0x06, 0x54, 0x0c, 0xa5, 0x25 } }
+  gEfiDxeSystemBoardProtocolGuid                      = { 0xa57c1118, 0x6afc, 0x46d2, { 0xba, 0xe6, 0x92, 0x92, 0x62, 0xd3, 0xeb, 0x1e } }
+
+[PcdsFixedAtBuild]
+
+  gPlatformTokenSpaceGuid.PcdCmosDebugPrintLevelReg|0x4C|UINT8|0x30000032
+
+  # Choose the default serial debug message level when CMOS is bad; in the later BIOS phase, the setup default is applied
+  # 0 - Disable; 1 - Minimum; 2 - Normal; 3 - Max
+  gPlatformTokenSpaceGuid.PcdSerialDbgLvlAtBadCmos|0x1|UINT8|0x30000033
+
+[PcdsFeatureFlag]
+  gPlatformTokenSpaceGuid.PcdFastBoot|FALSE|BOOLEAN|0x30000034
+
+  gPlatformTokenSpaceGuid.PcdUpdateConsoleInBds|TRUE|BOOLEAN|0x30000035
+
+[PcdsDynamicEx]
+  gPlatformTokenSpaceGuid.PcdDfxAdvDebugJumper|FALSE|BOOLEAN|0x6000001D
+
+  ## This value is used to save memory address of MRC data structure.
+  gPlatformTokenSpaceGuid.PcdSyshostMemoryAddress|0x00000000|UINT64|0x30000040
+
+  gOemSkuTokenSpaceGuid.PcdForceTo1SConfigMode|FALSE|BOOLEAN|0x00000205
+
+  gOemSkuTokenSpaceGuid.PcdAcpiGnvsAddress|0|UINT64|0x00000206
+
+  gOemSkuTokenSpaceGuid.PcdOemSkuUplinkPortIndex|0xFF|UINT8|0x00000207
+
+  gOemSkuTokenSpaceGuid.PcdMemTsegSize|0x0|UINT32|0x00000208
+  gOemSkuTokenSpaceGuid.PcdMemIedSize|0x0|UINT32|0x00000209
+
+  gOemSkuTokenSpaceGuid.PcdUsb20OverCurrentMappings|0|UINT64|0x0000020A
+  gOemSkuTokenSpaceGuid.PcdUsb30OverCurrentMappings|0|UINT64|0x0000020B
+
+  gOemSkuTokenSpaceGuid.PcdIioBifurcationTable|0|UINT64|0x0000020C
+  gOemSkuTokenSpaceGuid.PcdIioBifurcationTableEntries|0|UINT8|0x0000020D
+  gOemSkuTokenSpaceGuid.PcdIioSlotTable|0|UINT64|0x0000020E
+  gOemSkuTokenSpaceGuid.PcdIioSlotTableEntries|0|UINT8|0x0000020F
+
+  gOemSkuTokenSpaceGuid.PcdAllLanesEparamTable|0|UINT64|0x00000210
+  gOemSkuTokenSpaceGuid.PcdAllLanesEparamTableSize|0|UINT32|0x00000211
+  gOemSkuTokenSpaceGuid.PcdPerLaneEparamTable|0|UINT64|0x00000212
+  gOemSkuTokenSpaceGuid.PcdPerLaneEparamTableSize|0|UINT32|0x00000213
+  gOemSkuTokenSpaceGuid.PcdBoardTypeBitmask|0|UINT32|0x00000214
+
+  gOemSkuTokenSpaceGuid.PcdSetupData|{0x0}|SYSTEM_CONFIGURATION|0x000F0001 {                       # SYSTEM_CONFIGURATION                 <== PLATFORM_SETUP_VARIABLE_NAME|gEfiSetupVariableGuid
+    <HeaderFiles>
+      Guid/SetupVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+      PurleyOpenBoardPkg/OpenBoardPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdPchRcConfigurationData|{0x0}|PCH_RC_CONFIGURATION|0x000F0002 {          # PCH_RC_CONFIGURATION                 <== PCH_RC_CONFIGURATION_NAME|gEfiPchRcVariableGuid
+    <HeaderFiles>
+      Guid/PchRcVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+      PurleyOpenBoardPkg/OpenBoardPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdSocketIioConfigData|{0x0}|SOCKET_IIO_CONFIGURATION|0x000F0003 {             # SOCKET_IIO_CONFIGURATION             <== SOCKET_IIO_CONFIGURATION_NAME|gEfiSocketIioVariableGuid
+    <HeaderFiles>
+      Guid/SocketIioVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdSocketCommonRcConfigData|{0x0}|SOCKET_COMMONRC_CONFIGURATION|0x000F0004 {        # SOCKET_COMMONRC_CONFIGURATION        <== SOCKET_COMMONRC_CONFIGURATION_NAME|gEfiSocketCommonRcVariableGuid
+    <HeaderFiles>
+      Guid/SocketCommonRcVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdSocketMpLinkConfigData|{0x0}|SOCKET_MP_LINK_CONFIGURATION|0x000F0005 {          # SOCKET_MP_LINK_CONFIGURATION         <== SOCKET_MP_LINK_CONFIGURATION_NAME|gEfiSocketMpLinkVariableGuid
+    <HeaderFiles>
+      Guid/SocketMpLinkVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdSocketMemoryConfigData|{0x0}|SOCKET_MEMORY_CONFIGURATION|0x000F0006 {          # SOCKET_MEMORY_CONFIGURATION          <== SOCKET_MEMORY_CONFIGURATION_NAME|gEfiSocketMemoryVariableGuid
+    <HeaderFiles>
+      Guid/SocketMemoryVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdSocketPowerManagementConfigData|{0x0}|SOCKET_POWERMANAGEMENT_CONFIGURATION|0x000F0007 { # SOCKET_POWERMANAGEMENT_CONFIGURATION <== SOCKET_POWERMANAGEMENT_CONFIGURATION_NAME|gEfiSocketPowermanagementVarGuid
+    <HeaderFiles>
+      Guid/SocketPowermanagementVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+  }
+  gOemSkuTokenSpaceGuid.PcdSocketProcessorCoreConfigData|{0x0}|SOCKET_PROCESSORCORE_CONFIGURATION|0x000F0008 {   # SOCKET_PROCESSORCORE_CONFIGURATION   <== SOCKET_PROCESSORCORE_CONFIGURATION_NAME|gEfiSocketProcessorCoreVarGuid
+    <HeaderFiles>
+      Guid/SocketProcessorCoreVariable.h
+    <Packages>
+      MdePkg/MdePkg.dec
+      PurleyRefreshSiliconPkg/SiPkg.dec
+  }
+
+[PcdsDynamic, PcdsDynamicEx]
+  gEfiIpmiPkgTokenSpaceGuid.PcdIpmiKcsTimeoutPeriod|5000|UINT64|0x90000020
+  gEfiIpmiPkgTokenSpaceGuid.PcdIpmiBmcSlaveAddress|0x20|UINT8|0x90000021
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
new file mode 100644
index 0000000000..ae7720cfb1
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
@@ -0,0 +1,130 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PchPolicyLib.h>
+
+/**
+  Performs silicon pre-mem policy initialization.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+
+  The returned data must be used as input data for SiliconPolicyDonePreMem(),
+  and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem().
+
+  1) In FSP path, the input Policy should be FspmUpd.
+  Value of FspmUpd has been initialized by FSP binary default value.
+  Only a subset of FspmUpd needs to be updated for different silicon sku.
+  The return data is same FspmUpd.
+
+  2) In non-FSP path, the input policy could be NULL.
+  The return data is the initialized policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPreMem (
+  IN OUT VOID *Policy OPTIONAL
+  )
+{
+  EFI_STATUS                    Status;
+  PCH_POLICY_PPI               *PchPolicyPpi;
+
+  //
+  // Call PchCreatePolicyDefaults to initialize platform policy structure
+  // and get all intel default policy settings.
+  //
+  Status = PchCreatePolicyDefaults (&PchPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  return PchPolicyPpi;
+}
+
+/*
+  The silicon pre-mem policy is finalized.
+  Silicon code can do initialization based upon the policy data.
+
+  The input Policy must be returned by SiliconPolicyInitPreMem().
+  
+  @param[in] Policy       Pointer to policy.
+
+  @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+*/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePreMem (
+  IN VOID *Policy
+  )
+{
+  EFI_STATUS                    Status;
+
+  //
+  // Install PchPolicyPpi.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = PchInstallPolicyPpi (Policy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Performs silicon post-mem policy initialization.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+
+  The returned data must be used as input data for SiliconPolicyDonePostMem(),
+  and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
+
+  1) In FSP path, the input Policy should be FspsUpd.
+  Value of FspsUpd has been initialized by FSP binary default value.
+  Only a subset of FspsUpd needs to be updated for different silicon sku.
+  The return data is same FspsUpd.
+
+  2) In non-FSP path, the input policy could be NULL.
+  The return data is the initialized policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPostMem (
+  IN OUT VOID *Policy OPTIONAL
+  )
+{
+  return Policy;
+}
+
+/*
+  The silicon post-mem policy is finalized.
+  Silicon code can do initialization based upon the policy data.
+
+  The input Policy must be returned by SiliconPolicyInitPostMem().
+  
+  @param[in] Policy       Pointer to policy.
+
+  @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+*/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePostMem (
+  IN VOID *Policy
+  )
+{
+  return RETURN_SUCCESS;
+}
\ No newline at end of file
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..3883e9e14c
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
@@ -0,0 +1,39 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION          = 0x00010005
+  BASE_NAME            = SiliconPolicyInitLib
+  FILE_GUID            = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
+  MODULE_TYPE          = PEIM
+  VERSION_STRING       = 1.0
+  LIBRARY_CLASS        = SiliconPolicyInitLib
+
+[Sources]
+  SiliconPolicyInitLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+[Packages]
+  MdePkg/MdePkg.dec
+  PurleyRefreshSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  BaseLib
+  DebugLib
+  DebugPrintErrorLevelLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  PeiServicesLib
+  PchPolicyLib
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/PchPolicyUpdateUsb.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/PchPolicyUpdateUsb.c
new file mode 100644
index 0000000000..73b90fd6d9
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/PchPolicyUpdateUsb.c
@@ -0,0 +1,99 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// EDK and EDKII have different GUID formats
+//
+#include <Uefi/UefiBaseType.h>
+#include <Ppi/PchPolicy.h>
+#include "PlatformHost.h"
+#include <Guid/SetupVariable.h>
+#include <Guid/PchRcVariable.h>
+#include <Library/PchInfoLib.h>
+
+
+VOID
+UpdatePchUsbConfig (
+  IN PCH_USB_CONFIG            *PchUsbConfig,
+  IN SYSTEM_CONFIGURATION      *SetupVariables,
+  IN PCH_RC_CONFIGURATION      *PchRcVariables,
+  IN VOID                      *Usb20OverCurrentMappings,
+  IN VOID                      *Usb30OverCurrentMappings
+  )
+/*++
+
+Routine Description:
+
+  This function performs PCH USB Platform Policy initialzation
+
+Arguments:
+  PchUsbConfig                    Pointer to PCH_USB_CONFIG data buffer
+  SetupVariables                  Pointer to Setup variable
+  PlatformType                    PlatformType specified
+  PlatformFlavor                  PlatformFlavor specified
+  BoardType                       BoardType specified
+
+Returns:
+
+--*/
+{
+  UINTN  PortIndex;
+
+  PchUsbConfig->UsbPrecondition = PchRcVariables->UsbPrecondition;
+
+    for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++) {
+      if (PchRcVariables->PchUsbHsPort[PortIndex] == 1) {
+      PchUsbConfig->PortUsb20[PortIndex].Enable = TRUE;
+    } else {
+        PchUsbConfig->PortUsb20[PortIndex].Enable = FALSE;
+      }
+    }
+    for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+      if (PchRcVariables->PchUsbSsPort[PortIndex] == 1) {
+      PchUsbConfig->PortUsb30[PortIndex].Enable = TRUE;
+    } else {
+        PchUsbConfig->PortUsb30[PortIndex].Enable = FALSE;
+    }
+  }
+
+  //
+  // xDCI (USB device) related settings from setup variable
+  //
+  if(PchRcVariables->PchXdciSupport == 1) {
+    PchUsbConfig->XdciConfig.Enable= TRUE;
+  } else {
+    PchUsbConfig->XdciConfig.Enable= FALSE;
+  }
+
+  //
+  // XHCI USB Over Current Pins disabled, update it based on setup option.
+  //
+  PchUsbConfig->XhciOcMapEnabled = PchRcVariables->XhciOcMapEnabled;
+
+  //
+  // XHCI Wake On USB configured based on user input through setup option
+  //
+  PchUsbConfig->XhciWakeOnUsb = SetupVariables->XhciWakeOnUsbEnabled;
+  //
+  // XHCI option to disable MSIs
+  //
+  PchUsbConfig->XhciDisMSICapability = PchRcVariables->XhciDisMSICapability;
+
+  //
+  // Platform Board programming per the layout of each port.
+  //
+  // OC Map for USB2 Ports
+  for (PortIndex=0;PortIndex<PCH_MAX_USB2_PORTS;PortIndex++) {
+    PchUsbConfig->PortUsb20[PortIndex].OverCurrentPin = (UINT8)((PCH_USB_OVERCURRENT_PIN *)Usb20OverCurrentMappings)[PortIndex];
+  }
+
+  // OC Map for USB3 Ports
+  for (PortIndex=0;PortIndex<PCH_MAX_USB3_PORTS;PortIndex++) {
+    PchUsbConfig->PortUsb30[PortIndex].OverCurrentPin = (UINT8)((PCH_USB_OVERCURRENT_PIN *)Usb30OverCurrentMappings)[PortIndex];
+  }
+
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
new file mode 100644
index 0000000000..cac6409719
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
@@ -0,0 +1,659 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include "Guid/SetupVariable.h"
+#include <Guid/PchRcVariable.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/PeiServicesLib.h>
+
+#include <PchAccess.h>
+#include <Ppi/PchPolicy.h>
+#include <Library/MmPciBaseLib.h>
+
+#include <Register/PchRegsSata.h>
+#include <Library/HobLib.h>
+#include <Platform.h>
+#include <Guid/PchRcVariable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/PchSerialIoLib.h>
+#include <Guid/SocketVariable.h>
+#include <Library/PcdLib.h>
+#include <Library/PchGbeLib.h>
+#include <Library/PchInfoLib.h>
+
+//
+// Haddock Creek
+//
+#define DIMM_SMB_SPD_P0C0D0_HC 0xA2
+#define DIMM_SMB_SPD_P0C0D1_HC 0xA0
+#define DIMM_SMB_SPD_P0C1D0_HC 0xA6
+#define DIMM_SMB_SPD_P0C1D1_HC 0xA4
+#define DIMM_SMB_SPD_P0C0D2_HC 0xAA
+#define DIMM_SMB_SPD_P0C1D2_HC 0xA8
+
+//
+// Sawtooth Peak
+// Single SPD EEPROM at 0xA2 serves both C0D0 and C1D0 (LPDDR is 1DPC only)
+//
+#define DIMM_SMB_SPD_P0C0D0_STP 0xA2
+#define DIMM_SMB_SPD_P0C0D1_STP 0xA0
+#define DIMM_SMB_SPD_P0C1D0_STP 0xA2
+#define DIMM_SMB_SPD_P0C1D1_STP 0xA0
+
+//
+// Aden Hills
+// DDR4 System (1DPC)
+//
+#define DIMM_SMB_SPD_P0C0D0_AH 0xA0
+#define DIMM_SMB_SPD_P0C0D1_AH 0xA4
+#define DIMM_SMB_SPD_P0C1D0_AH 0xA2
+#define DIMM_SMB_SPD_P0C1D1_AH 0xA6
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusHCRsvdAddresses[] = {
+  DIMM_SMB_SPD_P0C0D0_HC,
+  DIMM_SMB_SPD_P0C0D1_HC,
+  DIMM_SMB_SPD_P0C1D0_HC,
+  DIMM_SMB_SPD_P0C1D1_HC
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusSTPRsvdAddresses[] = {
+  DIMM_SMB_SPD_P0C0D0_STP,
+  DIMM_SMB_SPD_P0C0D1_STP,
+  DIMM_SMB_SPD_P0C1D0_STP,
+  DIMM_SMB_SPD_P0C1D1_STP
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusAHRsvdAddresses[] = {
+  DIMM_SMB_SPD_P0C0D0_AH,
+  DIMM_SMB_SPD_P0C0D1_AH,
+  DIMM_SMB_SPD_P0C1D0_AH,
+  DIMM_SMB_SPD_P0C1D1_AH
+};
+
+VOID
+UpdatePchUsbConfig (
+  IN PCH_USB_CONFIG            *PchUsbConfig,
+  IN SYSTEM_CONFIGURATION      *SetupVariables,
+  IN PCH_RC_CONFIGURATION      *PchRcVariables,
+  IN VOID                      *Usb20OverCurrentMappings,
+  IN VOID                      *Usb30OverCurrentMappings
+  );
+
+static
+VOID
+InstallPlatformVerbTables (
+    IN          UINTN                       CodecType
+  )
+{
+
+}
+
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicy (
+  IN OUT PCH_POLICY_PPI        *PchPolicy
+  )
+/*++
+
+Routine Description:
+
+  This function performs PCH PEI Policy initialzation.
+
+Arguments:
+
+  PchPolicy               The PCH Policy PPI instance
+
+Returns:
+
+  EFI_SUCCESS             The PPI is installed and initialized.
+  EFI ERRORS              The PPI is not successfully installed.
+  EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+
+--*/
+{
+  UINT8                           Index;
+  UINTN                           LpcBaseAddress;
+  UINT8                           MaxSataPorts;
+  UINT8                           *SmBusReservedTable;
+  UINT8                           SmBusReservedNum;
+  PCH_USB_OVERCURRENT_PIN        *Usb20OverCurrentMappings=NULL;
+  PCH_USB_OVERCURRENT_PIN        *Usb30OverCurrentMappings=NULL;
+  UINT8                          VTdSupport;
+  SYSTEM_CONFIGURATION           *SetupVariables;
+  PCH_RC_CONFIGURATION           *PchRcVariables;
+
+  DEBUG((EFI_D_ERROR, "platform common UpdatePeiPchPolicy entry\n"));
+
+  SetupVariables = PcdGetPtr(PcdSetupData);
+  PchRcVariables = PcdGetPtr(PcdPchRcConfigurationData);
+
+  LpcBaseAddress = MmPciBase (
+                    DEFAULT_PCI_BUS_NUMBER_PCH,
+                    PCI_DEVICE_NUMBER_PCH_LPC,
+                    PCI_FUNCTION_NUMBER_PCH_LPC
+                    );
+
+  PchPolicy->Port80Route          = PchRcVariables->IchPort80Route;
+
+  //
+  // DeviceEnables
+  //
+  if (PchIsGbeAvailable ()) {
+    PchPolicy->LanConfig.Enable         = TRUE;
+    PchPolicy->LanConfig.K1OffEnable    = PchRcVariables->PchLanK1Off;
+  } else {
+    PchPolicy->LanConfig.Enable         = FALSE;
+  }
+
+  PchPolicy->SataConfig.Enable          = PchRcVariables->PchSata;
+
+  PchPolicy->sSataConfig.Enable          = PchRcVariables->PchsSata;
+  PchPolicy->SmbusConfig.Enable         = TRUE;
+  //
+  // CLOCKRUN in LPC has to be disabled:
+  // - if a device is connected to LPC0
+  // - for LBG A0 stepping
+  //
+  PchPolicy->PmConfig.PciClockRun       = FALSE;
+  PchPolicy->PchConfig.Crid             = PchRcVariables->PchCrid;
+  PchPolicy->PchConfig.Serm             = PchRcVariables->PchSerm;
+
+
+  //
+  // SMBUS reserved addresses
+  //
+  SmBusReservedTable = NULL;
+  SmBusReservedNum   = 0;
+  PchPolicy->SmbusConfig.SmbusIoBase = PCH_SMBUS_BASE_ADDRESS;
+  SmBusReservedTable = mSmbusSTPRsvdAddresses;
+  SmBusReservedNum   = sizeof (mSmbusSTPRsvdAddresses);
+
+  if (SmBusReservedTable != NULL) {
+    PchPolicy->SmbusConfig.NumRsvdSmbusAddresses = SmBusReservedNum;
+    CopyMem (
+      PchPolicy->SmbusConfig.RsvdSmbusAddressTable,
+      SmBusReservedTable,
+      SmBusReservedNum
+      );
+  }
+
+  //
+  // SATA Config
+  //
+  PchPolicy->SataConfig.SataMode  = PchRcVariables->SataInterfaceMode;
+  MaxSataPorts = GetPchMaxSataPortNum ();
+
+  for (Index = 0; Index < MaxSataPorts; Index++) {
+    if (PchRcVariables->SataTestMode == TRUE)
+    {
+      PchPolicy->SataConfig.PortSettings[Index].Enable    = TRUE;
+    } else {
+      PchPolicy->SataConfig.PortSettings[Index].Enable = PchRcVariables->SataPort[Index];
+    }
+    PchPolicy->SataConfig.PortSettings[Index].HotPlug          = PchRcVariables->SataHotPlug[Index];
+    PchPolicy->SataConfig.PortSettings[Index].SpinUp           = PchRcVariables->SataSpinUp[Index];
+    PchPolicy->SataConfig.PortSettings[Index].External         = PchRcVariables->SataExternal[Index];
+    PchPolicy->SataConfig.PortSettings[Index].DevSlp           = PchRcVariables->PxDevSlp[Index];
+    PchPolicy->SataConfig.PortSettings[Index].EnableDitoConfig = PchRcVariables->EnableDitoConfig[Index];
+    PchPolicy->SataConfig.PortSettings[Index].DmVal            = PchRcVariables->DmVal[Index];
+    PchPolicy->SataConfig.PortSettings[Index].DitoVal          = PchRcVariables->DitoVal[Index];
+    PchPolicy->SataConfig.PortSettings[Index].SolidStateDrive  = PchRcVariables->SataType[Index];
+  }
+
+  if (PchPolicy->SataConfig.SataMode == PchSataModeRaid) {
+    PchPolicy->SataConfig.Rst.RaidAlternateId = PchRcVariables->SataAlternateId;
+    PchPolicy->SataConfig.Rst.EfiRaidDriverLoad = PchRcVariables->SataRaidLoadEfiDriver;
+  }
+  PchPolicy->SataConfig.Rst.Raid0           = PchRcVariables->SataRaidR0;
+  PchPolicy->SataConfig.Rst.Raid1           = PchRcVariables->SataRaidR1;
+  PchPolicy->SataConfig.Rst.Raid10          = PchRcVariables->SataRaidR10;
+  PchPolicy->SataConfig.Rst.Raid5           = PchRcVariables->SataRaidR5;
+  PchPolicy->SataConfig.Rst.Irrt            = PchRcVariables->SataRaidIrrt;
+  PchPolicy->SataConfig.Rst.OromUiBanner    = PchRcVariables->SataRaidOub;
+  PchPolicy->SataConfig.Rst.HddUnlock       = PchRcVariables->SataHddlk;
+  PchPolicy->SataConfig.Rst.LedLocate       = PchRcVariables->SataLedl;
+  PchPolicy->SataConfig.Rst.IrrtOnly        = PchRcVariables->SataRaidIooe;
+  PchPolicy->SataConfig.Rst.SmartStorage    = PchRcVariables->SataRaidSrt;
+  PchPolicy->SataConfig.Rst.OromUiDelay     = PchRcVariables->SataRaidOromDelay;
+
+  PchPolicy->SataConfig.EnclosureSupport    = TRUE;
+
+  PchPolicy->SataConfig.SalpSupport     = PchRcVariables->SataSalp;
+  PchPolicy->SataConfig.TestMode        = PchRcVariables->SataTestMode;
+
+  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+    if ((PchRcVariables->PchSata == TRUE) && (PchRcVariables->SataInterfaceMode == PchSataModeRaid)) {
+      PchPolicy->SataConfig.RstPcieStorageRemap[Index].Enable               = PchRcVariables->RstPcieStorageRemap[Index];
+      PchPolicy->SataConfig.RstPcieStorageRemap[Index].RstPcieStoragePort   = PchRcVariables->RstPcieStorageRemapPort[Index];
+    } else {
+      PchPolicy->SataConfig.RstPcieStorageRemap[Index].Enable               = FALSE;
+    }
+  }
+
+  //
+  // sSATA Config
+  //
+  PchPolicy->sSataConfig.SataMode  = PchRcVariables->sSataInterfaceMode;
+  MaxSataPorts = GetPchMaxsSataPortNum ();
+
+  for (Index = 0; Index < MaxSataPorts; Index++) {
+    if (PchRcVariables->sSataTestMode == TRUE)
+    {
+      PchPolicy->sSataConfig.PortSettings[Index].Enable    = TRUE;
+    } else {
+      PchPolicy->sSataConfig.PortSettings[Index].Enable = PchRcVariables->sSataPort[Index];
+    }
+    PchPolicy->sSataConfig.PortSettings[Index].HotPlug          = PchRcVariables->sSataHotPlug[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].SpinUp           = PchRcVariables->sSataSpinUp[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].External         = PchRcVariables->sSataExternal[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].DevSlp           = PchRcVariables->sPxDevSlp[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].EnableDitoConfig = PchRcVariables->sEnableDitoConfig[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].DmVal            = PchRcVariables->sDmVal[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].DitoVal          = PchRcVariables->sDitoVal[Index];
+    PchPolicy->sSataConfig.PortSettings[Index].SolidStateDrive  = PchRcVariables->sSataType[Index];
+  }
+
+  if (PchPolicy->sSataConfig.SataMode == PchSataModeRaid) {
+    PchPolicy->sSataConfig.Rst.RaidAlternateId = PchRcVariables->sSataAlternateId;
+    PchPolicy->sSataConfig.Rst.EfiRaidDriverLoad = PchRcVariables->sSataRaidLoadEfiDriver;
+  }
+  PchPolicy->sSataConfig.Rst.Raid0           = PchRcVariables->sSataRaidR0;
+  PchPolicy->sSataConfig.Rst.Raid1           = PchRcVariables->sSataRaidR1;
+  PchPolicy->sSataConfig.Rst.Raid10          = PchRcVariables->sSataRaidR10;
+  PchPolicy->sSataConfig.Rst.Raid5           = PchRcVariables->sSataRaidR5;
+  PchPolicy->sSataConfig.Rst.Irrt            = PchRcVariables->sSataRaidIrrt;
+  PchPolicy->sSataConfig.Rst.OromUiBanner    = PchRcVariables->sSataRaidOub;
+  PchPolicy->sSataConfig.Rst.HddUnlock       = PchRcVariables->sSataHddlk;
+  PchPolicy->sSataConfig.Rst.LedLocate       = PchRcVariables->sSataLedl;
+  PchPolicy->sSataConfig.Rst.IrrtOnly        = PchRcVariables->sSataRaidIooe;
+  PchPolicy->sSataConfig.Rst.SmartStorage    = PchRcVariables->sSataRaidSrt;
+  PchPolicy->sSataConfig.Rst.OromUiDelay     = PchRcVariables->sSataRaidOromDelay;
+
+  PchPolicy->sSataConfig.EnclosureSupport    = TRUE;
+
+  PchPolicy->sSataConfig.SalpSupport     = PchRcVariables->sSataSalp;
+  PchPolicy->sSataConfig.TestMode        = PchRcVariables->sSataTestMode;
+  //
+  // Initiate DMI Configuration
+  //
+  if (SetupVariables->PcieDmiAspm != PLATFORM_POR) {
+    if (SetupVariables->PcieDmiAspm != 0xFF) {
+      PchPolicy->DmiConfig.DmiAspm = TRUE;
+    } else {
+      PchPolicy->DmiConfig.DmiAspm = FALSE;
+    }
+  }
+  DEBUG((DEBUG_ERROR, "PchPolicy->DmiConfig.DmiAspm =%x\n", PchPolicy->DmiConfig.DmiAspm));
+  //
+  // PCI express config
+  //
+  PchPolicy->PcieConfig.DisableRootPortClockGating      = SetupVariables->PcieClockGating;
+  PchPolicy->PcieConfig.EnablePort8xhDecode           = PchRcVariables->PcieRootPort8xhDecode;
+  PchPolicy->PcieConfig.PchPciePort8xhDecodePortIndex = PchRcVariables->Pcie8xhDecodePortIndex;
+  PchPolicy->PcieConfig.EnablePeerMemoryWrite         = PchRcVariables->PcieRootPortPeerMemoryWriteEnable;
+  PchPolicy->PcieConfig.ComplianceTestMode            = PchRcVariables->PcieComplianceTestMode;
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    PchPolicy->PcieConfig.RootPort[Index].Enable                         = PchRcVariables->PcieRootPortEn[Index];
+    PchPolicy->PcieConfig.RootPort[Index].PhysicalSlotNumber             = (UINT8) Index;
+    if (PchRcVariables->PchPcieGlobalAspm > PchPcieAspmDisabled) {
+      // Disabled a.k.a. Per individual port
+      PchPolicy->PcieConfig.RootPort[Index].Aspm                         = PchRcVariables->PchPcieGlobalAspm;
+    } else {
+      PchPolicy->PcieConfig.RootPort[Index].Aspm                         = PchRcVariables->PcieRootPortAspm[Index];
+    }
+    PchPolicy->PcieConfig.RootPort[Index].L1Substates                    = PchRcVariables->PcieRootPortL1SubStates[Index];
+    PchPolicy->PcieConfig.RootPort[Index].AcsEnabled                     = PchRcVariables->PcieRootPortACS[Index];
+    PchPolicy->PcieConfig.RootPort[Index].PmSci                          = PchRcVariables->PcieRootPortPMCE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].HotPlug                        = PchRcVariables->PcieRootPortHPE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].AdvancedErrorReporting         = PchRcVariables->PcieRootPortAER[Index];
+    PchPolicy->PcieConfig.RootPort[Index].UnsupportedRequestReport       = PchRcVariables->PcieRootPortURE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].FatalErrorReport               = PchRcVariables->PcieRootPortFEE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].NoFatalErrorReport             = PchRcVariables->PcieRootPortNFE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].CorrectableErrorReport         = PchRcVariables->PcieRootPortCEE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].SystemErrorOnFatalError        = PchRcVariables->PcieRootPortSFE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].SystemErrorOnNonFatalError     = PchRcVariables->PcieRootPortSNE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].SystemErrorOnCorrectableError  = PchRcVariables->PcieRootPortSCE[Index];
+    PchPolicy->PcieConfig.RootPort[Index].TransmitterHalfSwing           = PchRcVariables->PcieRootPortTHS[Index];
+    PchPolicy->PcieConfig.RootPort[Index].CompletionTimeout              = PchRcVariables->PcieRootPortCompletionTimeout[Index];
+    PchPolicy->PcieConfig.RootPort[Index].PcieSpeed                      = PchRcVariables->PcieRootPortSpeed[Index];
+
+    PchPolicy->PcieConfig.RootPort[Index].MaxPayload                     = PchRcVariables->PcieRootPortMaxPayLoadSize[Index];
+    PchPolicy->PcieConfig.RootPort[Index].Gen3EqPh3Method                = PchRcVariables->PcieRootPortEqPh3Method[Index];
+  }
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); ++Index) {
+    PchPolicy->PcieConfig.EqPh3LaneParam[Index].Cm  = PchRcVariables->PcieLaneCm[Index];
+    PchPolicy->PcieConfig.EqPh3LaneParam[Index].Cp  = PchRcVariables->PcieLaneCp[Index];
+  }
+  if (PchRcVariables->PcieSwEqOverride) {
+    for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index++) {
+      PchPolicy->PcieConfig2.SwEqCoeffList[Index].Cm     = PchRcVariables->PcieSwEqCoeffCm[Index];
+      PchPolicy->PcieConfig2.SwEqCoeffList[Index].Cp     = PchRcVariables->PcieSwEqCoeffCp[Index];
+    }
+  }
+
+  PchPolicy->PcieConfig.MaxReadRequestSize                               = PchRcVariables->PcieRootPortMaxReadRequestSize;
+  ///
+  /// Update Competion Timeout settings for Upling ports for Server PCH
+  ///
+  PchPolicy->PcieConfig.PchPcieUX16CompletionTimeout                     = PchRcVariables->PchPcieUX16CompletionTimeout;
+  PchPolicy->PcieConfig.PchPcieUX8CompletionTimeout                      = PchRcVariables->PchPcieUX8CompletionTimeout;
+  ///
+  /// Update Max Payload Size settings for Upling ports for Server PCH
+  ///
+  PchPolicy->PcieConfig.PchPcieUX16MaxPayload                            = PchRcVariables->PchPcieUX16MaxPayloadSize;
+  PchPolicy->PcieConfig.PchPcieUX8MaxPayload                             = PchRcVariables->PchPcieUX8MaxPayloadSize;
+  CopyMem (&VTdSupport, (UINT8 *)PcdGetPtr(PcdSocketIioConfigData) + OFFSET_OF(SOCKET_IIO_CONFIGURATION, VTdSupport), sizeof(VTdSupport));
+  PchPolicy->PcieConfig.VTdSupport                                       = VTdSupport;
+
+  ///
+  /// Assign ClkReq signal to root port. (Base 0)
+  /// For LP, Set 0 - 5
+  /// For H,  Set 0 - 15
+  /// Note that if GbE is enabled, ClkReq assigned to GbE will not be available for Root Port. (TODO for Purley)
+  ///
+  //
+  // HdAudioConfig
+  //
+  PchPolicy->HdAudioConfig.Enable               = PchRcVariables->PchHdAudio;
+  PchPolicy->HdAudioConfig.DspEnable            = FALSE;
+  PchPolicy->HdAudioConfig.Pme                  = PchRcVariables->PchHdAudioPme;
+  PchPolicy->HdAudioConfig.IoBufferOwnership    = PchRcVariables->PchHdAudioIoBufferOwnership;
+  PchPolicy->HdAudioConfig.IoBufferVoltage      = PchRcVariables->PchHdAudioIoBufferVoltage;
+  PchPolicy->HdAudioConfig.ResetWaitTimer       = 300;
+  PchPolicy->HdAudioConfig.IDispCodecDisconnect = TRUE;  //iDisp is permanently disabled
+  for(Index = 0; Index < HDAUDIO_FEATURES; Index++) {
+    PchPolicy->HdAudioConfig.DspFeatureMask |= (UINT32)(PchRcVariables->PchHdAudioFeature[Index] ? (1 << Index) : 0);
+  }
+
+  for(Index = 0; Index < HDAUDIO_PP_MODULES; Index++) {
+    PchPolicy->HdAudioConfig.DspPpModuleMask |= (UINT32)(PchRcVariables->PchHdAudioPostProcessingMod[Index] ? (1 << Index) : 0);
+  }
+
+  if (PchPolicy->HdAudioConfig.Enable) {
+    InstallPlatformVerbTables (PchRcVariables->PchHdAudioCodecSelect);
+  }
+
+  PchPolicy->HdAudioConfig.VcType = PchRcVariables->RtoHdaVcType;
+  //
+  // LockDown
+  //
+
+
+    PchPolicy->LockDownConfig.RtcLock          = PchRcVariables->PchRtcLock;
+    PchPolicy->LockDownConfig.BiosLock         = PchRcVariables->PchBiosLock;
+    PchPolicy->LockDownConfig.SpiEiss          = TRUE;
+    PchPolicy->LockDownConfig.GlobalSmi        = TRUE;
+    PchPolicy->LockDownConfig.BiosInterface    = TRUE;
+    PchPolicy->LockDownConfig.EvaLockDown      = PchRcVariables->PchEvaLockDown;
+    PchPolicy->LockDownConfig.GpioLockDown     = PchRcVariables->PchGpioLockDown;
+    PchPolicy->LockDownConfig.TcoLock          = TRUE;
+
+  if(PchRcVariables->PchP2sbUnlock) {
+    PchPolicy->P2sbConfig.SbiUnlock = TRUE;
+    PchPolicy->P2sbConfig.PsfUnlock = TRUE;
+  } else {
+    PchPolicy->P2sbConfig.SbiUnlock = FALSE;
+    PchPolicy->P2sbConfig.PsfUnlock = FALSE;
+  }
+  PchPolicy->P2sbConfig.P2SbReveal = PchRcVariables->PchP2sbDevReveal;
+
+  //
+  // Update SPI policies
+  //
+  PchPolicy->SpiConfig.ShowSpiController = TRUE;
+
+  //
+  // PMC Policy
+  //
+  PchPolicy->PmConfig.PmcReadDisable = PchRcVariables->PmcReadDisable;
+
+
+  if (PchRcVariables->PchAdrEn != PLATFORM_POR) {
+    PchPolicy->AdrConfig.PchAdrEn = PchRcVariables->PchAdrEn;
+  }
+  PchPolicy->AdrConfig.AdrGpioSel = PchRcVariables->AdrGpioSel;
+  if (PchRcVariables->AdrHostPartitionReset != PLATFORM_POR) {
+    PchPolicy->AdrConfig.AdrHostPartitionReset = PchRcVariables->AdrHostPartitionReset;
+  }
+  if (PchRcVariables->AdrTimerEn != PLATFORM_POR) {
+    PchPolicy->AdrConfig.AdrTimerEn = PchRcVariables->AdrTimerEn;
+  }
+  if (PchRcVariables->AdrTimerVal != ADR_TMR_SETUP_DEFAULT_POR) {
+    PchPolicy->AdrConfig.AdrTimerVal = PchRcVariables->AdrTimerVal;
+  }
+  if (PchRcVariables->AdrMultiplierVal != ADR_MULT_SETUP_DEFAULT_POR) {
+    PchPolicy->AdrConfig.AdrMultiplierVal = PchRcVariables->AdrMultiplierVal;
+  }
+
+  //
+  // Thermal Config
+  //
+  if ((PchRcVariables->MemoryThermalManagement != FALSE) &&
+      ((PchRcVariables->ExttsViaTsOnBoard != FALSE) || (PchRcVariables->ExttsViaTsOnDimm != FALSE)))
+  {
+    PchPolicy->ThermalConfig.MemoryThrottling.Enable                                     = TRUE;
+    PchPolicy->ThermalConfig.MemoryThrottling.TsGpioPinSetting[TsGpioC].PmsyncEnable     = TRUE;
+    PchPolicy->ThermalConfig.MemoryThrottling.TsGpioPinSetting[TsGpioD].PmsyncEnable     = TRUE;
+    PchPolicy->ThermalConfig.MemoryThrottling.TsGpioPinSetting[TsGpioC].C0TransmitEnable = TRUE;
+    PchPolicy->ThermalConfig.MemoryThrottling.TsGpioPinSetting[TsGpioD].C0TransmitEnable = TRUE;
+    PchPolicy->ThermalConfig.MemoryThrottling.TsGpioPinSetting[TsGpioC].PinSelection     = 1;
+    PchPolicy->ThermalConfig.MemoryThrottling.TsGpioPinSetting[TsGpioD].PinSelection     = 0;
+  } else {
+    PchPolicy->ThermalConfig.MemoryThrottling.Enable = FALSE;
+  }
+
+  //
+  // IOAPIC Config
+  //
+  PchPolicy->IoApicConfig.IoApicEntry24_119 = PchRcVariables->PchIoApic24119Entries;
+  PchPolicy->IoApicConfig.BdfValid          = 1;
+  PchPolicy->IoApicConfig.BusNumber         = 0xF0;
+  PchPolicy->IoApicConfig.DeviceNumber      = 0x1F;
+  PchPolicy->IoApicConfig.FunctionNumber    = 0;
+
+
+  //
+  // Misc PM Config
+  //
+  PchPolicy->PmConfig.PchDeepSxPol                          = PchRcVariables->DeepSxMode;
+  PchPolicy->PmConfig.WakeConfig.WolEnableOverride          = PchRcVariables->PchWakeOnLan;
+  PchPolicy->PmConfig.WakeConfig.WoWlanEnable               = PchRcVariables->PchWakeOnWlan;
+  PchPolicy->PmConfig.WakeConfig.WoWlanDeepSxEnable         = PchRcVariables->PchWakeOnWlanDeepSx;
+  PchPolicy->PmConfig.WakeConfig.Gp27WakeFromDeepSx         = PchRcVariables->Gp27WakeFromDeepSx;
+  PchPolicy->PmConfig.SlpLanLowDc                           = PchRcVariables->PchSlpLanLowDc;
+  PchPolicy->PmConfig.PowerResetStatusClear.MeWakeSts       = TRUE;
+  PchPolicy->PmConfig.PowerResetStatusClear.MeHrstColdSts   = TRUE;
+  PchPolicy->PmConfig.PowerResetStatusClear.MeHrstWarmSts   = TRUE;
+  PchPolicy->PmConfig.PciePllSsc                            = PchRcVariables->PciePllSsc;
+
+  PchPolicy->PmConfig.DirtyWarmReset                        = PchRcVariables->Dwr_Enable;
+
+  PchPolicy->PmConfig.StallDirtyWarmReset                   = PchRcVariables->Dwr_Stall;
+  PchPolicy->PmConfig.Dwr_BmcRootPort                       = PchRcVariables->Dwr_BmcRootPort;
+
+  PchPolicy->PmConfig.PchGbl2HostEn.Bits.PMCGBL             = PchRcVariables->DwrEn_PMCGBL;
+  PchPolicy->PmConfig.PchGbl2HostEn.Bits.MEWDT              = PchRcVariables->DwrEn_MEWDT;
+  PchPolicy->PmConfig.PchGbl2HostEn.Bits.IEWDT              = PchRcVariables->DwrEn_IEWDT;
+
+  PchPolicy->PmConfig.Dwr_MeResetPrepDone                   = PchRcVariables->Dwr_MeResetPrepDone;
+  PchPolicy->PmConfig.Dwr_IeResetPrepDone                   = PchRcVariables->Dwr_IeResetPrepDone;
+
+  //
+  // DefaultSvidSid Config
+  //
+  PchPolicy->PchConfig.SubSystemVendorId     = V_PCH_INTEL_VENDOR_ID;
+  PchPolicy->PchConfig.SubSystemId           = V_PCH_DEFAULT_SID;
+  PchPolicy->PchConfig.EnableClockSpreadSpec =  PchRcVariables->EnableClockSpreadSpec;
+  //
+  // Thermal Config
+  //
+  PchPolicy->ThermalConfig.ThermalThrottling.TTLevels.PchCrossThrottling = PchRcVariables->PchCrossThrottling;
+  PchPolicy->ThermalConfig.ThermalThrottling.DmiHaAWC.SuggestedSetting   = TRUE;
+  if (PchRcVariables->ThermalDeviceEnable == PchThermalDeviceAuto) {
+    if (PchStepping () == LbgA0) {
+      PchPolicy->ThermalConfig.ThermalDeviceEnable = PchThermalDeviceDisabled;
+    } else {
+      PchPolicy->ThermalConfig.ThermalDeviceEnable = PchThermalDeviceEnabledPci;
+    }
+  } else {
+    PchPolicy->ThermalConfig.ThermalDeviceEnable = PchRcVariables->ThermalDeviceEnable;
+  }
+
+  PchPolicy->ThermalConfig.ThermalThrottling.TTLevels.SuggestedSetting   = TRUE;
+  PchPolicy->ThermalConfig.ThermalThrottling.SataTT.SuggestedSetting     = TRUE;
+  PchPolicy->ThermalConfig.ThermalThrottling.sSataTT.SuggestedSetting     = TRUE;
+
+  //
+  // DCI (EXI)
+  //
+  PchPolicy->DciConfig.DciEn         = PchRcVariables->PchDciEn;
+  PchPolicy->DciConfig.DciAutoDetect = PchRcVariables->PchDciAutoDetect;
+
+
+  //
+  // Initialize Serial IRQ Config
+  //
+  PchPolicy->SerialIrqConfig.SirqEnable       = TRUE;
+  PchPolicy->SerialIrqConfig.StartFramePulse  = PchSfpw4Clk;
+  if (PchRcVariables->PchSirqMode == 0) {
+    PchPolicy->SerialIrqConfig.SirqMode = PchQuietMode;
+  } else {
+    PchPolicy->SerialIrqConfig.SirqMode = PchContinuousMode;
+  }
+
+  //
+  // Port 61h emulation
+  //
+  PchPolicy->Port61hSmmConfig.Enable = TRUE;
+
+  //
+  // DMI configuration
+  //
+  PchPolicy->DmiConfig.DmiLinkDownHangBypass = PchRcVariables->DmiLinkDownHangBypass;
+  PchPolicy->DmiConfig.DmiStopAndScreamEnable = PchRcVariables->PcieDmiStopAndScreamEnable;
+
+  //
+  // Update Pch Usb Config
+  //
+  Usb20OverCurrentMappings = (PCH_USB_OVERCURRENT_PIN *)(UINTN)PcdGet64 (PcdUsb20OverCurrentMappings);
+  Usb30OverCurrentMappings = (PCH_USB_OVERCURRENT_PIN *)(UINTN)PcdGet64 (PcdUsb30OverCurrentMappings);
+  UpdatePchUsbConfig (
+    &PchPolicy->UsbConfig,
+    SetupVariables,
+    PchRcVariables,
+    Usb20OverCurrentMappings,
+    Usb30OverCurrentMappings
+    );
+                  
+  //
+  // Update TraceHub config based on setup options
+  //
+  PchPolicy->PchTraceHubConfig.EnableMode        = PchRcVariables->TraceHubEnableMode;
+
+  switch (PchRcVariables->MemRegion0BufferSize) {
+    case 0:
+       PchPolicy->PchTraceHubConfig.MemReg0Size = 0; // No memory
+       break;
+    case 1:
+       PchPolicy->PchTraceHubConfig.MemReg0Size = 0x100000;  // 1MB
+       break;
+    case 2:
+       PchPolicy->PchTraceHubConfig.MemReg0Size = 0x800000;  // 8MB
+       break;
+    case 3:
+       PchPolicy->PchTraceHubConfig.MemReg0Size = 0x4000000; // 64MB
+       break;
+  }
+
+  switch (PchRcVariables->MemRegion1BufferSize) {
+    case 0:
+       PchPolicy->PchTraceHubConfig.MemReg1Size = 0; // No memory
+       break;
+    case 1:
+       PchPolicy->PchTraceHubConfig.MemReg1Size = 0x100000;  // 1MB
+       break;
+    case 2:
+       PchPolicy->PchTraceHubConfig.MemReg1Size = 0x800000;  // 8MB
+       break;
+    case 3:
+       PchPolicy->PchTraceHubConfig.MemReg1Size = 0x4000000; // 64MB
+       break;
+  }
+
+  PchPolicy->PchTraceHubConfig.PchTraceHubHide  =  PchRcVariables->PchTraceHubHide;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs silicon pre-mem policy update.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+  
+  The input Policy must be returned by SiliconPolicyDonePreMem().
+  
+  1) In FSP path, the input Policy should be FspmUpd.
+  A platform may use this API to update the FSPM UPD policy initialized
+  by the silicon module or the default UPD data.
+  The output of FSPM UPD data from this API is the final UPD data.
+
+  2) In non-FSP path, the board may use additional way to get
+  the silicon policy data field based upon the input Policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePreMem (
+  IN OUT VOID *Policy
+  )
+{
+  UpdatePeiPchPolicy (Policy);
+  return Policy;
+}
+
+/**
+  Performs silicon post-mem policy update.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+  
+  The input Policy must be returned by SiliconPolicyDonePostMem().
+  
+  1) In FSP path, the input Policy should be FspsUpd.
+  A platform may use this API to update the FSPS UPD policy initialized
+  by the silicon module or the default UPD data.
+  The output of FSPS UPD data from this API is the final UPD data.
+
+  2) In non-FSP path, the board may use additional way to get
+  the silicon policy data field based upon the input Policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePostMem (
+  IN OUT VOID *Policy
+  )
+{
+  return Policy;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
new file mode 100644
index 0000000000..2df0ca977f
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
@@ -0,0 +1,54 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconPolicyUpdateLib
+  FILE_GUID                      = 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyUpdateLib
+
+[Sources]
+  SiliconPolicyUpdateLib.c
+  PchPolicyUpdateUsb.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  PurleyOpenBoardPkg/OpenBoardPkg.dec
+  PurleyRefreshSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  HobLib
+  MmPciLib
+  IoLib
+  PcdLib
+  PchGbeLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+  gOemSkuTokenSpaceGuid.PcdSocketIioConfigData
+  gOemSkuTokenSpaceGuid.PcdUsb20OverCurrentMappings
+  gOemSkuTokenSpaceGuid.PcdUsb30OverCurrentMappings
+
+  gOemSkuTokenSpaceGuid.PcdSetupData
+  gOemSkuTokenSpaceGuid.PcdPchRcConfigurationData
+
+[FixedPcd]
+
+[Ppis]
+
+[Guids]
+  gEfiAcpiVariableGuid
-- 
2.27.0.windows.1


  parent reply	other threads:[~2021-05-11  9:48 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-11  9:48 [edk2-platforms] [PATCH V1 00/18] Reinstate Purley MinPlatform Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 01/18] PurleyRefreshSiliconPkg: Add DEC and DSC files Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 02/18] PurleyRefreshSiliconPkg/Pch: Add Register Header Files Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 03/18] PurleyRefreshSiliconPkg/Pch: Add Public " Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 04/18] PurleyRefreshSiliconPkg/Pch: Add Private " Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 05/18] PurleyRefreshSiliconPkg/Pch: Add libraries Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 06/18] PurleyRefreshSiliconPkg/Pch: Add ACPI tables Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 07/18] PurleyRefreshSiliconPkg: Add Uncore files Nate DeSimone
2021-05-11  9:48 ` Nate DeSimone [this message]
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 09/18] PurleyOpenBoardPkg: Add modules Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 10/18] PurleyOpenBoardPkg/Acpi/BoardAcpiDxe: Add PlatformPciTree_WFP.asi Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 11/18] PurleyOpenBoardPkg/Acpi/BoardAcpiDxe: Add PCxx.asi files Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 12/18] PurleyOpenBoardPkg/Acpi/BoardAcpiDxe: Add ASL files Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 13/18] PurleyOpenBoardPkg/Acpi: Add BoardAcpiDxe Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 14/18] PurleyOpenBoardPkg: Add MtOlympus build files Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 15/18] PurleyOpenBoardPkg: Add StructureConfig.dsc Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 16/18] PurleyOpenBoardPkg: Add BoardMtOlympus Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 17/18] Readme.md: Add PurleyOpenBoardPkg Nate DeSimone
2021-05-11  9:48 ` [edk2-platforms] [PATCH V1 18/18] Maintainers.txt: Add PurleyOpenBoardPkg and PurleyRefreshSiliconPkg Nate DeSimone
2021-05-11 22:12 ` [edk2-platforms] [PATCH V1 00/18] Reinstate Purley MinPlatform Oram, Isaac W
2021-05-11 23:20   ` Nate DeSimone

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20210511094826.12495-9-nathaniel.l.desimone@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

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

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