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 09/18] PurleyOpenBoardPkg: Add modules
Date: Tue, 11 May 2021 02:48:17 -0700 [thread overview]
Message-ID: <20210511094826.12495-10-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>
---
.../DxePlatformBootManagerLib/BdsPlatform.c | 1354 +++++++++++++++++
.../DxePlatformBootManagerLib/BdsPlatform.h | 184 +++
.../DxePlatformBootManagerLib.inf | 96 ++
.../DxePlatformBootManagerLib/MemoryTest.c | 85 ++
.../PlatformBootOption.c | 559 +++++++
.../Pci/PciPlatform/IoApic.h | 22 +
.../Pci/PciPlatform/PciIovPlatformPolicy.c | 96 ++
.../Pci/PciPlatform/PciIovPlatformPolicy.h | 51 +
.../Pci/PciPlatform/PciPlatform.c | 183 +++
.../Pci/PciPlatform/PciPlatform.h | 201 +++
.../Pci/PciPlatform/PciPlatform.inf | 70 +
.../Pci/PciPlatform/PciPlatformHooks.c | 527 +++++++
.../Pci/PciPlatform/PciPlatformHooks.h | 24 +
.../Pci/PciPlatform/PciSupportLib.c | 103 ++
.../Pci/PciPlatform/PciSupportLib.h | 44 +
.../Policy/IioUdsDataDxe/IioUdsDataDxe.c | 86 ++
.../Policy/IioUdsDataDxe/IioUdsDataDxe.h | 81 +
.../Policy/IioUdsDataDxe/IioUdsDataDxe.inf | 36 +
.../PlatformCpuPolicy/PlatformCpuPolicy.c | 654 ++++++++
.../PlatformCpuPolicy/PlatformCpuPolicy.inf | 80 +
.../Policy/S3NvramSave/S3NvramSave.c | 256 ++++
.../Policy/S3NvramSave/S3NvramSave.h | 31 +
.../Policy/S3NvramSave/S3NvramSave.inf | 59 +
.../Policy/SystemBoard/SystemBoardCommon.c | 625 ++++++++
.../Policy/SystemBoard/SystemBoardPei.c | 255 ++++
.../Policy/SystemBoard/SystemBoardPei.h | 182 +++
.../Policy/SystemBoard/SystemBoardPei.inf | 76 +
27 files changed, 6020 insertions(+)
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/MemoryTest.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/PlatformBootOption.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.inf
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.inf
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.inf
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.c
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.h
create mode 100644 Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.inf
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..b3b8ceba6f
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1354 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/EventGroup.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/PciIo.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Guid/EventGroup.h>
+
+#include <Library/Tcg2PhysicalPresenceLib.h>
+
+#include <Library/HobLib.h>
+#include <Protocol/UsbIo.h>
+
+#include <Library/UefiBootManagerLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE gBootMode;
+
+BOOLEAN gPPRequireUIConfirm;
+
+extern UINTN mBootMenuOptionNumber;
+
+GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
+ {
+ {
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ {
+ (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
+ (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0xffff, // VendorId
+ 0xffff, // ProductId
+ CLASS_HID, // DeviceClass
+ SUBCLASS_BOOT, // DeviceSubClass
+ PROTOCOL_KEYBOARD // DeviceProtocol
+ },
+ gEndEntire
+};
+
+//
+// Internal shell mode
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeColumn;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeRow;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellHorizontalResolution;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellVerticalResolution;
+//
+// BDS Platform Functions
+//
+
+BOOLEAN
+IsMorBitSet (
+ VOID
+ )
+{
+ UINTN MorControl;
+ EFI_STATUS Status;
+ UINTN DataSize;
+
+ //
+ // Check if the MOR bit is set.
+ //
+ DataSize = sizeof (MorControl);
+ Status = gRT->GetVariable (
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+ &gEfiMemoryOverwriteControlDataGuid,
+ NULL,
+ &DataSize,
+ &MorControl
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
+ MorControl = 0;
+ } else {
+ DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", MorControl));
+ }
+
+ return (BOOLEAN) (MorControl & 0x01);
+}
+
+VOID
+DumpDevicePath (
+ IN CHAR16 *Name,
+ IN EFI_DEVICE_PATH *DevicePath
+ )
+{
+ CHAR16 *Str;
+
+ Str = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
+ DEBUG ((DEBUG_INFO, "%s: %s\n", Name, Str));
+ if (Str != NULL) {
+ FreePool (Str);
+ }
+}
+
+/**
+ An empty function to pass error checking of CreateEventEx ().
+
+ This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
+ checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+**/
+VOID
+EFIAPI
+InternalBdsEmptyCallbackFuntion (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+
+VOID
+ExitPmAuth (
+ VOID
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ EFI_EVENT EndOfDxeEvent;
+
+ DEBUG((DEBUG_INFO,"ExitPmAuth ()- Start\n"));
+ //
+ // Prepare S3 information, this MUST be done before ExitPmAuth/EndOfDxe
+ //
+ //
+ // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ InternalBdsEmptyCallbackFuntion,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+ gBS->SignalEvent (EndOfDxeEvent);
+ gBS->CloseEvent (EndOfDxeEvent);
+ DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+ //
+ // NOTE: We need install DxeSmmReadyToLock directly here because many boot script is added via ExitPmAuth/EndOfDxe callback.
+ // If we install them at same callback, these boot script will be rejected because BootScript Driver runs first to lock them done.
+ // So we seperate them to be 2 different events, ExitPmAuth is last chance to let platform add boot script. DxeSmmReadyToLock will
+ // make boot script save driver lock down the interface.
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ DEBUG((DEBUG_INFO,"ExitPmAuth ()- End\n"));
+}
+
+VOID
+ConnectRootBridge (
+ BOOLEAN Recursive
+ )
+{
+ UINTN RootBridgeHandleCount;
+ EFI_HANDLE *RootBridgeHandleBuffer;
+ UINTN RootBridgeIndex;
+
+ RootBridgeHandleCount = 0;
+ gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &RootBridgeHandleCount,
+ &RootBridgeHandleBuffer
+ );
+ for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
+ gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, Recursive);
+ }
+}
+
+
+/**
+ Return whether the device is trusted console.
+
+ @param Device The device to be tested.
+
+ @retval TRUE The device can be trusted.
+ @retval FALSE The device cannot be trusted.
+**/
+BOOLEAN
+IsTrustedConsole (
+ IN CONSOLE_TYPE ConsoleType,
+ IN EFI_DEVICE_PATH_PROTOCOL *Device
+ )
+{
+ VOID *TrustedConsoleDevicepath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *Instance;
+ UINTN Size;
+ EFI_DEVICE_PATH_PROTOCOL *ConsoleDevice;
+
+ if (Device == NULL) {
+ return FALSE;
+ }
+
+ ConsoleDevice = DuplicateDevicePath(Device);
+
+ TrustedConsoleDevicepath = NULL;
+
+ switch (ConsoleType) {
+ case ConIn:
+ TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
+ break;
+ case ConOut:
+ //
+ // Check GOP and remove last node
+ //
+ TempDevicePath = ConsoleDevice;
+ while (!IsDevicePathEndType (TempDevicePath)) {
+ if (DevicePathType (TempDevicePath) == ACPI_DEVICE_PATH &&
+ DevicePathSubType (TempDevicePath) == ACPI_ADR_DP) {
+ SetDevicePathEndNode (TempDevicePath);
+ break;
+ }
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
+ break;
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+ TempDevicePath = TrustedConsoleDevicepath;
+ do {
+ Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+ if (Instance == NULL) {
+ break;
+ }
+
+ if (CompareMem (ConsoleDevice, Instance, Size - END_DEVICE_PATH_LENGTH) == 0) {
+ FreePool (Instance);
+ FreePool (ConsoleDevice);
+ return TRUE;
+ }
+
+ FreePool (Instance);
+ } while (TempDevicePath != NULL);
+
+ FreePool (ConsoleDevice);
+
+ return FALSE;
+}
+
+BOOLEAN
+IsUsbShortForm (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
+ ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) || (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)) ) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Connect the USB short form device path.
+
+ @param DevicePath USB short form device path
+
+ @retval EFI_SUCCESS Successfully connected the USB device
+ @retval EFI_NOT_FOUND Cannot connect the USB device
+ @retval EFI_INVALID_PARAMETER The device path is invalid.
+**/
+EFI_STATUS
+ConnectUsbShortFormDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handles;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 Class[3];
+ BOOLEAN AtLeastOneConnected;
+
+ //
+ // Check the passed in parameters
+ //
+ if (DevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsUsbShortForm (DevicePath)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Find the usb host controller firstly, then connect with the remaining device path
+ //
+ AtLeastOneConnected = FALSE;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &Handles
+ );
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ Handles[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Check whether the Pci device is the wanted usb host controller
+ //
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
+ if (!EFI_ERROR (Status) &&
+ ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1]))
+ ) {
+ Status = gBS->ConnectController (
+ Handles[Index],
+ NULL,
+ DevicePath,
+ FALSE
+ );
+ if (!EFI_ERROR(Status)) {
+ AtLeastOneConnected = TRUE;
+ }
+ }
+ }
+ }
+
+ return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND;
+}
+
+/**
+ Update the ConIn variable with USB Keyboard device path,if its not already exists in ConIn
+**/
+VOID
+EnumUsbKeyboard (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard]\n"));
+ EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, NULL);
+
+ //
+ // Append Usb Keyboard short form DevicePath into "ConInDev"
+ //
+ EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, NULL);
+}
+
+BOOLEAN
+IsVgaHandle (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (!EFI_ERROR (Status)) {
+ if (IS_PCI_VGA (&Pci) || IS_PCI_OLD_VGA (&Pci)) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+EFI_HANDLE
+IsVideoController (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_STATUS Status;
+ EFI_HANDLE DeviceHandle;
+
+ DupDevicePath = DuplicateDevicePath (DevicePath);
+ ASSERT (DupDevicePath != NULL);
+ if (DupDevicePath == NULL) {
+ return NULL;
+ }
+
+ TempDevicePath = DupDevicePath;
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TempDevicePath,
+ &DeviceHandle
+ );
+ FreePool (DupDevicePath);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ if (IsVgaHandle (DeviceHandle)) {
+ return DeviceHandle;
+ } else {
+ return NULL;
+ }
+}
+
+BOOLEAN
+IsGopDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ while (!IsDevicePathEndType (DevicePath)) {
+ if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH &&
+ DevicePathSubType (DevicePath) == ACPI_ADR_DP) {
+ return TRUE;
+ }
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+ return FALSE;
+}
+
+/**
+ Remove all GOP device path instance from DevicePath and add the Gop to the DevicePath.
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UpdateGopDevicePath (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ EFI_DEVICE_PATH_PROTOCOL *Gop
+ )
+{
+ UINTN Size;
+ UINTN GopSize;
+ EFI_DEVICE_PATH_PROTOCOL *Temp;
+ EFI_DEVICE_PATH_PROTOCOL *Return;
+ EFI_DEVICE_PATH_PROTOCOL *Instance;
+ BOOLEAN Exist;
+
+ Exist = FALSE;
+ Return = NULL;
+ GopSize = GetDevicePathSize (Gop);
+ do {
+ Instance = GetNextDevicePathInstance (&DevicePath, &Size);
+ if (Instance == NULL) {
+ break;
+ }
+ if (!IsGopDevicePath (Instance) ||
+ (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0)
+ ) {
+ if (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0) {
+ Exist = TRUE;
+ }
+ Temp = Return;
+ Return = AppendDevicePathInstance (Return, Instance);
+ if (Temp != NULL) {
+ FreePool (Temp);
+ }
+ }
+ FreePool (Instance);
+ } while (DevicePath != NULL);
+
+ if (!Exist) {
+ Temp = Return;
+ Return = AppendDevicePathInstance (Return, Gop);
+ if (Temp != NULL) {
+ FreePool (Temp);
+ }
+ }
+ return Return;
+}
+
+/**
+ Get Graphics Controller Handle.
+
+ @retval GraphicsController Successfully located
+ @retval NULL Failed to locate
+**/
+EFI_HANDLE
+EFIAPI
+GetGraphicsController (
+ IN BOOLEAN NeedTrustedConsole
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_HANDLE *PciHandles;
+ UINTN PciHandlesSize;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &PciHandlesSize,
+ &PciHandles
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ for (Index = 0; Index < PciHandlesSize; Index++) {
+ Status = gBS->HandleProtocol (
+ PciHandles[Index],
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+ if (!IsVgaHandle (PciHandles[Index])) {
+ continue;
+ }
+ if ((NeedTrustedConsole && IsTrustedConsole (ConOut, DevicePath)) ||
+ ((!NeedTrustedConsole) && (!IsTrustedConsole (ConOut, DevicePath)))) {
+ return PciHandles[Index];
+ }
+ }
+
+ return NULL;
+}
+
+VOID
+UpdateGraphicConOut (
+ IN BOOLEAN NeedTrustedConsole
+ )
+{
+ EFI_HANDLE GraphicsControllerHandle;
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *ConOutDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *UpdatedConOutDevicePath;
+
+ //
+ // Update ConOut variable
+ //
+ GraphicsControllerHandle = GetGraphicsController (NeedTrustedConsole);
+ if (GraphicsControllerHandle != NULL) {
+ //
+ // Connect the GOP driver
+ //
+ gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
+
+ //
+ // Get the GOP device path
+ // NOTE: We may get a device path that contains Controller node in it.
+ //
+ GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
+ if (GopDevicePath != NULL) {
+ GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
+ UpdatedConOutDevicePath = UpdateGopDevicePath (ConOutDevicePath, GopDevicePath);
+ if (ConOutDevicePath != NULL) {
+ FreePool (ConOutDevicePath);
+ }
+ FreePool (GopDevicePath);
+ gRT->SetVariable (
+ L"ConOut",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ GetDevicePathSize (UpdatedConOutDevicePath),
+ UpdatedConOutDevicePath
+ );
+ }
+ }
+}
+
+VOID
+AddConsoleVariable (
+ IN CONSOLE_TYPE ConsoleType,
+ IN EFI_DEVICE_PATH *ConsoleDevicePath
+ )
+{
+ EFI_DEVICE_PATH *TempDevicePath;
+ EFI_DEVICE_PATH *Instance;
+ UINTN Size;
+ EFI_HANDLE GraphicsControllerHandle;
+ EFI_DEVICE_PATH *GopDevicePath;
+
+ TempDevicePath = ConsoleDevicePath;
+ do {
+ Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+ if (Instance == NULL) {
+ break;
+ }
+
+ switch (ConsoleType) {
+ case ConIn:
+ if (IsUsbShortForm (Instance)) {
+ //
+ // Append Usb Keyboard short form DevicePath into "ConInDev"
+ //
+ EfiBootManagerUpdateConsoleVariable (ConInDev, Instance, NULL);
+ }
+ EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
+ break;
+ case ConOut:
+ GraphicsControllerHandle = IsVideoController (Instance);
+ if (GraphicsControllerHandle == NULL) {
+ EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
+ } else {
+ //
+ // Connect the GOP driver
+ //
+ gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
+ //
+ // Get the GOP device path
+ // NOTE: We may get a device path that contains Controller node in it.
+ //
+ GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
+ if (GopDevicePath != NULL) {
+ EfiBootManagerUpdateConsoleVariable (ConsoleType, GopDevicePath, NULL);
+ }
+ }
+ break;
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+ FreePool (Instance);
+ } while (TempDevicePath != NULL);
+}
+
+/**
+ The function connects the trusted consoles.
+**/
+VOID
+ConnectTrustedConsole (
+ VOID
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Consoles;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *Instance;
+ EFI_DEVICE_PATH_PROTOCOL *Next;
+ UINTN Size;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ CHAR16 *ConsoleVar[] = {L"ConIn", L"ConOut"};
+ VOID *TrustedConsoleDevicepath;
+
+ TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
+ DumpDevicePath (L"TrustedConsoleIn", TrustedConsoleDevicepath);
+ TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
+ DumpDevicePath (L"TrustedConsoleOut", TrustedConsoleDevicepath);
+
+ for (Index = 0; Index < sizeof (ConsoleVar) / sizeof (ConsoleVar[0]); Index++) {
+
+ GetEfiGlobalVariable2 (ConsoleVar[Index], (VOID **)&Consoles, NULL);
+
+ TempDevicePath = Consoles;
+ do {
+ Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+ if (Instance == NULL) {
+ break;
+ }
+ if (IsTrustedConsole (Index, Instance)) {
+ if (IsUsbShortForm (Instance)) {
+ ConnectUsbShortFormDevicePath (Instance);
+ } else {
+ for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
+ if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
+ break;
+ } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType (Next) == HW_CONTROLLER_DP &&
+ DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&
+ DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP
+ ) {
+ break;
+ }
+ }
+ if (!IsDevicePathEnd (Next)) {
+ SetDevicePathEndNode (Next);
+ Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
+ if (!EFI_ERROR (Status)) {
+ gBS->ConnectController (Handle, NULL, NULL, TRUE);
+ }
+ } else {
+ EfiBootManagerConnectDevicePath (Instance, NULL);
+ }
+ }
+ }
+ FreePool (Instance);
+ } while (TempDevicePath != NULL);
+
+ if (Consoles != NULL) {
+ FreePool (Consoles);
+ }
+ }
+}
+
+/**
+ The function connects the trusted Storages.
+**/
+VOID
+ConnectTrustedStorage (
+ VOID
+ )
+{
+ VOID *TrustedStorageDevicepath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *Instance;
+ UINTN Size;
+ EFI_DEVICE_PATH_PROTOCOL *TempStorageDevicePath;
+ EFI_STATUS Status;
+ EFI_HANDLE DeviceHandle;
+
+ TrustedStorageDevicepath = PcdGetPtr (PcdTrustedStorageDevicePath);
+ DumpDevicePath (L"TrustedStorage", TrustedStorageDevicepath);
+
+ TempDevicePath = TrustedStorageDevicepath;
+ do {
+ Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
+ if (Instance == NULL) {
+ break;
+ }
+
+ EfiBootManagerConnectDevicePath (Instance, NULL);
+
+ TempStorageDevicePath = Instance;
+
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TempStorageDevicePath,
+ &DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ gBS->ConnectController (DeviceHandle, NULL, NULL, FALSE);
+ }
+
+ FreePool (Instance);
+ } while (TempDevicePath != NULL);
+}
+
+/**
+ The function connects the trusted consoles and then call the PP processing library interface.
+**/
+VOID
+ProcessTcgPp (
+ VOID
+ )
+{
+ gPPRequireUIConfirm |= Tcg2PhysicalPresenceLibNeedUserConfirm();
+
+ if (gPPRequireUIConfirm) {
+ ConnectTrustedConsole ();
+ }
+
+ Tcg2PhysicalPresenceLibProcessRequest (NULL);
+}
+
+/**
+ The function connects the trusted storage to perform TPerReset.
+**/
+VOID
+ProcessTcgMor (
+ VOID
+ )
+{
+ if (IsMorBitSet ()) {
+ ConnectTrustedConsole();
+ ConnectTrustedStorage();
+ }
+}
+
+/**
+ Check if current BootCurrent variable is internal shell boot option.
+
+ @retval TRUE BootCurrent is internal shell.
+ @retval FALSE BootCurrent is not internal shell.
+**/
+BOOLEAN
+BootCurrentIsInternalShell (
+ VOID
+ )
+{
+ UINTN VarSize;
+ UINT16 BootCurrent;
+ CHAR16 BootOptionName[16];
+ UINT8 *BootOption;
+ UINT8 *Ptr;
+ BOOLEAN Result;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
+ EFI_GUID *GuidPoint;
+
+ BootOption = NULL;
+ Result = FALSE;
+
+ //
+ // Get BootCurrent variable
+ //
+ VarSize = sizeof (UINT16);
+ Status = gRT->GetVariable (
+ L"BootCurrent",
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &VarSize,
+ &BootCurrent
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ //
+ // Create boot option Bootxxxx from BootCurrent
+ //
+ UnicodeSPrint (BootOptionName, sizeof(BootOptionName), L"Boot%04X", BootCurrent);
+
+ GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize);
+ if (BootOption == NULL || VarSize == 0) {
+ return FALSE;
+ }
+
+ Ptr = BootOption;
+ Ptr += sizeof (UINT32);
+ Ptr += sizeof (UINT16);
+ Ptr += StrSize ((CHAR16 *) Ptr);
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ LastDeviceNode = TempDevicePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ LastDeviceNode = TempDevicePath;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+ GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+ (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+ );
+ if ((GuidPoint != NULL) &&
+ ((CompareGuid (GuidPoint, &gUefiShellFileGuid)))
+ ) {
+ //
+ // if this option is internal shell, return TRUE
+ //
+ Result = TRUE;
+ }
+
+ if (BootOption != NULL) {
+ FreePool (BootOption);
+ BootOption = NULL;
+ }
+
+ return Result;
+}
+
+/**
+ This function will change video resolution and text mode
+ for internl shell when internal shell is launched.
+
+ @param None.
+
+ @retval EFI_SUCCESS Mode is changed successfully.
+ @retval Others Mode failed to changed.
+**/
+EFI_STATUS
+EFIAPI
+ChangeModeForInternalShell (
+ VOID
+ )
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
+ UINTN SizeOfInfo;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINT32 MaxGopMode;
+ UINT32 MaxTextMode;
+ UINT32 ModeNumber;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN CurrentColumn;
+ UINTN CurrentRow;
+
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID**)&GraphicsOutput
+ );
+ if (EFI_ERROR (Status)) {
+ GraphicsOutput = NULL;
+ }
+
+ Status = gBS->HandleProtocol (
+ gST->ConsoleOutHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ (VOID**)&SimpleTextOut
+ );
+ if (EFI_ERROR (Status)) {
+ SimpleTextOut = NULL;
+ }
+
+ if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MaxGopMode = GraphicsOutput->Mode->MaxMode;
+ MaxTextMode = SimpleTextOut->Mode->MaxMode;
+
+ //
+ // 1. If current video resolution is same with new video resolution,
+ // video resolution need not be changed.
+ // 1.1. If current text mode is same with new text mode, text mode need not be change.
+ // 1.2. If current text mode is different with new text mode, text mode need be change to new text mode.
+ // 2. If current video resolution is different with new video resolution, we need restart whole console drivers.
+ //
+ for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
+ Status = GraphicsOutput->QueryMode (
+ GraphicsOutput,
+ ModeNumber,
+ &SizeOfInfo,
+ &Info
+ );
+ if (!EFI_ERROR (Status)) {
+ if ((Info->HorizontalResolution == mShellHorizontalResolution) &&
+ (Info->VerticalResolution == mShellVerticalResolution)) {
+ if ((GraphicsOutput->Mode->Info->HorizontalResolution == mShellHorizontalResolution) &&
+ (GraphicsOutput->Mode->Info->VerticalResolution == mShellVerticalResolution)) {
+ //
+ // If current video resolution is same with new resolution,
+ // then check if current text mode is same with new text mode.
+ //
+ Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
+ ASSERT_EFI_ERROR (Status);
+ if (CurrentColumn == mShellModeColumn && CurrentRow == mShellModeRow) {
+ //
+ // Current text mode is same with new text mode, text mode need not be change.
+ //
+ FreePool (Info);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Current text mode is different with new text mode, text mode need be change to new text mode.
+ //
+ for (Index = 0; Index < MaxTextMode; Index++) {
+ Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
+ if (!EFI_ERROR(Status)) {
+ if ((CurrentColumn == mShellModeColumn) && (CurrentRow == mShellModeRow)) {
+ //
+ // New text mode is supported, set it.
+ //
+ Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Update text mode PCD.
+ //
+ Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S (PcdConOutRow, mShellModeRow);
+ ASSERT_EFI_ERROR (Status);
+
+ FreePool (Info);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ if (Index == MaxTextMode) {
+ //
+ // If new text mode is not supported, return error.
+ //
+ FreePool (Info);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ } else {
+ FreePool (Info);
+ //
+ // If current video resolution is not same with the new one, set new video resolution.
+ // In this case, the driver which produces simple text out need be restarted.
+ //
+ Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Set PCD to restart GraphicsConsole and Consplitter to change video resolution
+ // and produce new text mode based on new resolution.
+ //
+ Status = PcdSet32S (PcdVideoHorizontalResolution, mShellHorizontalResolution);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S (PcdVideoVerticalResolution, mShellVerticalResolution);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PcdSet32S (PcdConOutRow, mShellModeRow);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleTextOutProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
+ }
+ for (Index = 0; Index < HandleCount; Index++) {
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+ break;
+ }
+ }
+ }
+ }
+ FreePool (Info);
+ }
+ }
+
+ if (ModeNumber == MaxGopMode) {
+ //
+ // If the new resolution is not supported, return error.
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ ReadyToBoot callback to set video and text mode for internal shell boot.
+ That will not connect USB controller while CSM and FastBoot are disabled, we need to connect them
+ before booting to Shell for showing USB devices in Shell.
+
+ When FastBoot is enabled and Windows Console is the chosen Console behavior, input devices will not be connected
+ by default. Hence, when booting to EFI shell, connecting input consoles are required.
+
+ @param Event Pointer to this event
+ @param Context Event hanlder private data
+
+ @retval None.
+**/
+VOID
+EFIAPI
+OnReadyToBootCallBack (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DEBUG ((EFI_D_INFO, "OnReadyToBootCallBack\n"));
+
+ if (BootCurrentIsInternalShell ()) {
+
+ ChangeModeForInternalShell ();
+ EfiBootManagerConnectAllDefaultConsoles();
+ gDS->Dispatch ();
+ }
+}
+
+/**
+ Platform Bds init. Incude the platform firmware vendor, revision
+ and so crc check.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *VarConOut;
+ EFI_DEVICE_PATH_PROTOCOL *VarConIn;
+ EFI_EVENT Event;
+
+ DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Get user defined text mode for internal shell only once.
+ //
+ mShellHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+ mShellVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
+ mShellModeColumn = PcdGet32 (PcdSetupConOutColumn);
+ mShellModeRow = PcdGet32 (PcdSetupConOutRow);
+
+ if (PcdGetBool (PcdUpdateConsoleInBds) == TRUE) {
+ //
+ // Create event to set proper video resolution and text mode for internal shell.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_CALLBACK,
+ OnReadyToBootCallBack,
+ NULL,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created
+ //
+ ConnectRootBridge (FALSE);
+
+ //
+ // Fill ConIn/ConOut in Full Configuration boot mode
+ //
+ DEBUG ((DEBUG_INFO, "PlatformBootManagerInit - %x\n", gBootMode));
+
+ if (gBootMode == BOOT_WITH_FULL_CONFIGURATION ||
+ gBootMode == BOOT_WITH_DEFAULT_SETTINGS ||
+ gBootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS ||
+ gBootMode == BOOT_IN_RECOVERY_MODE) {
+
+ GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL); if (VarConOut != NULL) { FreePool (VarConOut); }
+ GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL); if (VarConIn != NULL) { FreePool (VarConIn); }
+
+ //
+ // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may drop to Full Configuration boot mode in non-first boot
+ //
+ if (VarConOut == NULL || VarConIn == NULL) {
+ if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+ AddConsoleVariable (ConOut, PcdGetPtr (PcdTrustedConsoleOutputDevicePath));
+ }
+ if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+ AddConsoleVariable (ConIn, PcdGetPtr (PcdTrustedConsoleInputDevicePath));
+ }
+ }
+ }
+
+ EnumUsbKeyboard ();
+ //
+ // For trusted console it must be handled here.
+ //
+ UpdateGraphicConOut (TRUE);
+
+ //
+ // Dynamically register hot key: F2/F7/Enter
+ //
+ RegisterDefaultBootOption ();
+ RegisterStaticHotkey ();
+ }
+
+ PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7010);
+ if (PcdGetBool (PcdTpm2Enable)) {
+ ProcessTcgPp ();
+ ProcessTcgMor ();
+ }
+ PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7011);
+
+ //
+ // We should make all UEFI memory and GCD information populated before ExitPmAuth.
+ // SMM may consume these information.
+ //
+ MemoryTest((EXTENDMEM_COVERAGE_LEVEL) PcdGet32 (PcdPlatformMemoryCheckLevel));
+
+ PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7020);
+ ExitPmAuth ();
+ PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7021);
+
+ //
+ // Dispatch the deferred 3rd party images.
+ //
+ EfiBootManagerDispatchDeferredImages ();
+
+ //
+ // For non-trusted console it must be handled here.
+ //
+ if (PcdGetBool (PcdUpdateConsoleInBds) == TRUE) {
+ UpdateGraphicConOut (FALSE);
+ }
+}
+
+
+/**
+ Connect with predeined platform connect sequence,
+ the OEM/IBV can customize with their own connect sequence.
+
+ @param[in] BootMode Boot mode of this boot.
+**/
+VOID
+ConnectSequence (
+ IN EFI_BOOT_MODE BootMode
+ )
+{
+ EfiBootManagerConnectAll ();
+}
+
+/**
+ The function is to consider the boot order which is not in our expectation.
+ In the case that we need to re-sort the boot option.
+
+ @retval TRUE Need to sort Boot Option.
+ @retval FALSE Don't need to sort Boot Option.
+**/
+BOOLEAN
+IsNeedSortBootOption (
+ VOID
+ )
+{
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+ //
+ // If setup is the first priority in boot option, we need to sort boot option.
+ //
+ if ((BootOptionCount > 1) &&
+ (((StrnCmp (BootOptions->Description, L"Enter Setup", StrLen (L"Enter Setup"))) == 0) ||
+ ((StrnCmp (BootOptions->Description, L"BootManagerMenuApp", StrLen (L"BootManagerMenuApp"))) == 0))) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ The function will excute with as the platform policy, current policy
+ is driven by boot mode. IBV/OEM can customize this code for their specific
+ policy action.
+
+ @param DriverOptionList - The header of the driver option link list
+ @param BootOptionList - The header of the boot option link list
+ @param ProcessCapsules - A pointer to ProcessCapsules()
+ @param BaseMemoryTest - A pointer to BaseMemoryTest()
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+ VOID
+ )
+{
+ EFI_BOOT_MODE LocalBootMode;
+
+ DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
+
+ //
+ // Get current Boot Mode
+ //
+ LocalBootMode = gBootMode;
+ DEBUG ((DEBUG_INFO, "Current local bootmode - %x\n", LocalBootMode));
+
+ //
+ // Go the different platform policy with different boot mode
+ // Notes: this part code can be change with the table policy
+ //
+ switch (LocalBootMode) {
+
+ case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+ case BOOT_WITH_MINIMAL_CONFIGURATION:
+ case BOOT_ON_S4_RESUME:
+ //
+ // Perform some platform specific connect sequence
+ //
+ if (PcdGetBool (PcdFastBoot) == FALSE) {
+ PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7050);
+ ConnectSequence (LocalBootMode);
+ PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7051);
+ }
+
+ break;
+
+ case BOOT_WITH_FULL_CONFIGURATION:
+ case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+ case BOOT_WITH_DEFAULT_SETTINGS:
+ default:
+ //
+ // Perform some platform specific connect sequence
+ //
+ ConnectSequence (LocalBootMode);
+
+ //
+ // Only in Full Configuration boot mode we do the enumeration of boot device
+ //
+ //
+ // Dispatch all but Storage Oprom explicitly, because we assume Int13Thunk driver is there.
+ //
+ EfiBootManagerRefreshAllBootOption ();
+
+ if (IsNeedSortBootOption()) {
+ EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
+ }
+ //
+ // PXE boot option may appear after boot option enumeration
+ //
+
+ break;
+ }
+
+ if (PcdGetBool (PcdFastBoot) == FALSE) {
+ Print (L"Press F7 for BootMenu!\n");
+
+ EfiBootManagerRefreshAllBootOption ();
+ EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
+ }
+}
+
+/**
+ The function is called when no boot option could be launched,
+ including platform recovery options and options pointing to applications
+ built into firmware volumes.
+
+ If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootDeviceList;
+ CHAR16 OptionName[sizeof ("Boot####")];
+
+ if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
+ return;
+ }
+ UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", mBootMenuOptionNumber);
+ Status = EfiBootManagerVariableToLoadOption (OptionName, &BootDeviceList);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ for (;;) {
+ EfiBootManagerBoot (&BootDeviceList);
+ }
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..360a00d7d7
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,184 @@
+/** @file
+ Header file for BDS Platform specific code
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _BDS_PLATFORM_H
+#define _BDS_PLATFORM_H
+
+#include <PiDxe.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GenericMemoryTest.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Guid/CapsuleVendor.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Guid/FileInfo.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformBootManagerLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/PciCodeId.h>
+
+///
+/// ConnectType
+///
+#define CONSOLE_OUT 0x00000001
+#define STD_ERROR 0x00000002
+#define CONSOLE_IN 0x00000004
+#define CONSOLE_ALL (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
+
+extern EFI_GUID gUefiShellFileGuid;
+extern EFI_BOOT_MODE gBootMode;
+
+#define gPciRootBridge \
+ { \
+ { \
+ ACPI_DEVICE_PATH, \
+ ACPI_DP, \
+ { \
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+ }, \
+ }, \
+ EISA_PNP_ID (0x0A03), \
+ 0 \
+ }
+
+#define gEndEntire \
+ { \
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
+ }
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN ConnectType;
+} BDS_CONSOLE_CONNECT_ENTRY;
+
+//
+// Platform Root Bridge
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH Keyboard;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_KEYBOARD_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ONBOARD_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH Pci0Device;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_PEG_ROOT_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciBridge;
+ PCI_DEVICE_PATH PciDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_PCI_CONTROLLER_DEVICE_PATH;
+
+//
+// Below is the boot option device path
+//
+
+#define CLASS_HID 3
+#define SUBCLASS_BOOT 1
+#define PROTOCOL_KEYBOARD 1
+
+typedef struct {
+ USB_CLASS_DEVICE_PATH UsbClass;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+extern USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath;
+
+//
+// Platform BDS Functions
+//
+
+
+/**
+ Perform the memory test base on the memory test intensive level,
+ and update the memory resource.
+
+ @param Level The memory test intensive level.
+
+ @retval EFI_STATUS Success test all the system memory and update
+ the memory resource
+
+**/
+EFI_STATUS
+MemoryTest (
+ IN EXTENDMEM_COVERAGE_LEVEL Level
+ );
+
+VOID
+ConnectSequence (
+ IN EFI_BOOT_MODE BootMode
+ );
+
+
+INTN
+EFIAPI
+CompareBootOption (
+ CONST VOID *Left,
+ CONST VOID *Right
+ );
+
+
+VOID
+RegisterStaticHotkey (
+ VOID
+ );
+VOID
+RegisterDefaultBootOption (
+ VOID
+ );
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf
new file mode 100644
index 0000000000..5790743565
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf
@@ -0,0 +1,96 @@
+## @file
+# Component name for module DxePlatformBootManagerLib
+#
+# Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxePlatformBootManagerLib
+ FILE_GUID = A6BC385D-59E5-4B77-87D7-200ABAA83C15
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ UEFI_SPECIFICATION_VERSION = 2.10
+ LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ PrintLib
+ DevicePathLib
+ UefiLib
+ HobLib
+ DxeServicesLib
+ DxeServicesTableLib
+ HiiLib
+ UefiBootManagerLib
+ PerformanceLib
+ TimerLib
+ Tcg2PhysicalPresenceLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ PurleyOpenBoardPkg/OpenBoardPkg.dec
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut ## PRODUCES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution ## PRODUCES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution ## PRODUCES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow ## PRODUCES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn ## PRODUCES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand ## PRODUCES
+ gMinPlatformPkgTokenSpaceGuid.PcdPlatformMemoryCheckLevel ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleInputDevicePath ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleOutputDevicePath ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdTrustedStorageDevicePath ## CONSUMES
+ gPlatformTokenSpaceGuid.PcdUpdateConsoleInBds ## CONSUMES
+ gPlatformTokenSpaceGuid.PcdFastBoot ## CONSUMES
+
+[Sources]
+ BdsPlatform.c
+ BdsPlatform.h
+ PlatformBootOption.c
+ MemoryTest.c
+
+[Protocols]
+ gEfiPciRootBridgeIoProtocolGuid ## CONSUMES
+ gEfiPciIoProtocolGuid ## CONSUMES
+ gEfiCpuIo2ProtocolGuid ## CONSUMES
+ gEfiDxeSmmReadyToLockProtocolGuid ## PRODUCES
+ gEfiGenericMemTestProtocolGuid ## CONSUMES
+ gEfiDiskInfoProtocolGuid ## CONSUMES
+ gEfiDevicePathToTextProtocolGuid ## CONSUMES
+ gEfiSimpleTextInputExProtocolGuid ## CONSUMES
+ gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
+ gEfiFormBrowser2ProtocolGuid ## CONSUMES
+ gEfiGenericMemTestProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiGlobalVariableGuid ## PRODUCES
+ gEfiMemoryOverwriteControlDataGuid ## PRODUCES
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES
+
+[Depex.common.DXE_DRIVER]
+ gEfiVariableArchProtocolGuid
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/MemoryTest.c b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/MemoryTest.c
new file mode 100644
index 0000000000..e6445fecf8
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/MemoryTest.c
@@ -0,0 +1,85 @@
+/** @file
+ Perform the platform memory test
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BdsPlatform.h"
+#include <Protocol/GenericMemoryTest.h>
+
+/**
+ Perform the memory test base on the memory test intensive level,
+ and update the memory resource.
+
+ @param Level The memory test intensive level.
+
+ @retval EFI_STATUS Success test all the system memory and update
+ the memory resource
+
+**/
+EFI_STATUS
+MemoryTest (
+ IN EXTENDMEM_COVERAGE_LEVEL Level
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN RequireSoftECCInit;
+ EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;
+ UINT64 TestedMemorySize;
+ UINT64 TotalMemorySize;
+ BOOLEAN ErrorOut;
+ BOOLEAN TestAbort;
+
+ TestedMemorySize = 0;
+ TotalMemorySize = 0;
+ ErrorOut = FALSE;
+ TestAbort = FALSE;
+
+ RequireSoftECCInit = FALSE;
+
+ Status = gBS->LocateProtocol (
+ &gEfiGenericMemTestProtocolGuid,
+ NULL,
+ (VOID **) &GenMemoryTest
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ Status = GenMemoryTest->MemoryTestInit (
+ GenMemoryTest,
+ Level,
+ &RequireSoftECCInit
+ );
+ if (Status == EFI_NO_MEDIA) {
+ //
+ // The PEI codes also have the relevant memory test code to check the memory,
+ // it can select to test some range of the memory or all of them. If PEI code
+ // checks all the memory, this BDS memory test will has no not-test memory to
+ // do the test, and then the status of EFI_NO_MEDIA will be returned by
+ // "MemoryTestInit". So it does not need to test memory again, just return.
+ //
+ return EFI_SUCCESS;
+ }
+
+ if (PcdGetBool (PcdFastBoot) == FALSE) {
+ do {
+ Status = GenMemoryTest->PerformMemoryTest (
+ GenMemoryTest,
+ &TestedMemorySize,
+ &TotalMemorySize,
+ &ErrorOut,
+ TestAbort
+ );
+ if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
+ ASSERT (0);
+ }
+ } while (Status != EFI_NOT_FOUND);
+ }
+
+ Status = GenMemoryTest->Finished (GenMemoryTest);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/PlatformBootOption.c b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/PlatformBootOption.c
new file mode 100644
index 0000000000..84aa097d58
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Override/Platform/Intel/MinPlatformPkg/Bds/Library/DxePlatformBootManagerLib/PlatformBootOption.c
@@ -0,0 +1,559 @@
+/** @file
+ Driver for Platform Boot Options support.
+
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BdsPlatform.h"
+
+#include <Library/PcdLib.h>
+
+BOOLEAN mContinueBoot = FALSE;
+BOOLEAN mBootMenuBoot = FALSE;
+BOOLEAN mPxeBoot = FALSE;
+BOOLEAN mHotKeypressed = FALSE;
+EFI_EVENT HotKeyEvent = NULL;
+
+UINTN mBootMenuOptionNumber;
+
+EFI_DEVICE_PATH_PROTOCOL *
+BdsCreateShellDevicePath (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function will create a SHELL BootOption to boot.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ Shell Device path for booting.
+
+--*/
+{
+ UINTN FvHandleCount;
+ EFI_HANDLE *FvHandleBuffer;
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ UINTN Size;
+ UINT32 AuthenticationStatus;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ VOID *Buffer;
+
+ DevicePath = NULL;
+ Status = EFI_SUCCESS;
+
+ DEBUG ((DEBUG_INFO, "BdsCreateShellDevicePath\n"));
+ gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &FvHandleCount,
+ &FvHandleBuffer
+ );
+
+ for (Index = 0; Index < FvHandleCount; Index++) {
+ gBS->HandleProtocol (
+ FvHandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &Fv
+ );
+
+ Buffer = NULL;
+ Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ &gUefiShellFileGuid,
+ EFI_SECTION_PE32,
+ 0,
+ &Buffer,
+ &Size,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Skip if no shell file in the FV
+ //
+ continue;
+ } else {
+ //
+ // Found the shell
+ //
+ break;
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // No shell present
+ //
+ if (FvHandleCount) {
+ FreePool (FvHandleBuffer);
+ }
+ return NULL;
+ }
+ //
+ // Build the shell boot option
+ //
+ DevicePath = DevicePathFromHandle (FvHandleBuffer[Index]);
+
+ if (FvHandleCount) {
+ FreePool (FvHandleBuffer);
+ }
+
+ return DevicePath;
+}
+
+
+EFI_STATUS
+CreateFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOption,
+ UINT32 Attributes,
+ UINT8 *OptionalData, OPTIONAL
+ UINT32 OptionalDataSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ UINT32 AuthenticationStatus;
+ VOID *Buffer;
+ UINTN Size;
+
+ if ((BootOption == NULL) || (FileGuid == NULL) || (Description == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+
+ if (!CompareGuid (&gUefiShellFileGuid, FileGuid)) {
+ Status = gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->HandleProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &Fv
+ );
+ if (!EFI_ERROR (Status)) {
+ Buffer = NULL;
+ Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ FileGuid,
+ EFI_SECTION_PE32,
+ 0,
+ &Buffer,
+ &Size,
+ &AuthenticationStatus
+ );
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+ }
+ }
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ DevicePath = AppendDevicePathNode (
+ DevicePathFromHandle (LoadedImage->DeviceHandle),
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+ } else {
+ DevicePath = AppendDevicePathNode (
+ BdsCreateShellDevicePath (),
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+ }
+
+ Status = EfiBootManagerInitializeLoadOption (
+ BootOption,
+ LoadOptionNumberUnassigned,
+ LoadOptionTypeBoot,
+ Attributes,
+ Description,
+ DevicePath,
+ OptionalData,
+ OptionalDataSize
+ );
+ FreePool (DevicePath);
+ return Status;
+}
+
+EFI_GUID mUiFile = {
+ 0x462CAA21, 0x7614, 0x4503, { 0x83, 0x6E, 0x8A, 0xB6, 0xF4, 0x66, 0x23, 0x31 }
+};
+EFI_GUID mBootMenuFile = {
+ 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }
+};
+
+
+/**
+ Return the index of the load option in the load option array.
+
+ The function consider two load options are equal when the
+ OptionType, Attributes, Description, FilePath and OptionalData are equal.
+
+ @param Key Pointer to the load option to be found.
+ @param Array Pointer to the array of load options to be found.
+ @param Count Number of entries in the Array.
+
+ @retval -1 Key wasn't found in the Array.
+ @retval 0 ~ Count-1 The index of the Key in the Array.
+**/
+INTN
+PlatformFindLoadOption (
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
+ IN UINTN Count
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < Count; Index++) {
+ if ((Key->OptionType == Array[Index].OptionType) &&
+ (Key->Attributes == Array[Index].Attributes) &&
+ (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+ (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+ (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+ (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
+ return (INTN) Index;
+ }
+ }
+
+ return -1;
+}
+
+UINTN
+RegisterFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ UINTN Position,
+ UINT32 Attributes,
+ UINT8 *OptionalData, OPTIONAL
+ UINT32 OptionalDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN OptionIndex;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+
+ NewOption.OptionNumber = LoadOptionNumberUnassigned;
+ Status = CreateFvBootOption (FileGuid, Description, &NewOption, Attributes, OptionalData, OptionalDataSize);
+ if (!EFI_ERROR (Status)) {
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+ OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+ if (OptionIndex == -1) {
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position);
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ NewOption.OptionNumber = BootOptions[OptionIndex].OptionNumber;
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+ }
+
+ return NewOption.OptionNumber;
+}
+
+
+
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+ UINT16 TimeoutRemain
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TxtInEx;
+ EFI_KEY_DATA KeyData;
+ BOOLEAN PausePressed;
+
+ //
+ // Pause on PAUSE key
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
+ ASSERT_EFI_ERROR (Status);
+
+ PausePressed = FALSE;
+
+ while (TRUE) {
+ Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (KeyData.Key.ScanCode == SCAN_PAUSE) {
+ PausePressed = TRUE;
+ break;
+ }
+ }
+
+ //
+ // Loop until non-PAUSE key pressed
+ //
+ while (PausePressed) {
+ Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_INFO, "[PauseCallback] %x/%x %x/%x\n",
+ KeyData.Key.ScanCode, KeyData.Key.UnicodeChar,
+ KeyData.KeyState.KeyShiftState, KeyData.KeyState.KeyToggleState
+ ));
+ PausePressed = (BOOLEAN) (KeyData.Key.ScanCode == SCAN_PAUSE);
+ }
+ }
+}
+
+
+EFI_GUID gUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, { 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 } };
+
+#define INTERNAL_UEFI_SHELL_NAME L"Internal UEFI Shell 2.0"
+#define UEFI_HARD_DRIVE_NAME L"UEFI Hard Drive"
+
+VOID
+RegisterDefaultBootOption (
+ VOID
+ )
+{
+#if 0
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+#endif
+ UINT16 *ShellData;
+ UINT32 ShellDataSize;
+
+ ShellData = NULL;
+ ShellDataSize = 0;
+ RegisterFvBootOption (&gUefiShellFileGuid, INTERNAL_UEFI_SHELL_NAME, (UINTN) -1, LOAD_OPTION_ACTIVE, (UINT8 *)ShellData, ShellDataSize);
+
+ //
+ // Boot Menu
+ //
+ mBootMenuOptionNumber = RegisterFvBootOption (&mBootMenuFile, L"Boot Device List", (UINTN) -1, LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN, NULL, 0);
+
+ if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
+ DEBUG ((DEBUG_INFO, "BootMenuOptionNumber (%d) should not be same to LoadOptionNumberUnassigned(%d).\n", mBootMenuOptionNumber, LoadOptionNumberUnassigned));
+ }
+#if 0
+ //
+ // Boot Manager Menu
+ //
+ EfiInitializeFwVolDevicepathNode (&FileNode, &mUiFile);
+
+ gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ DevicePath = AppendDevicePathNode (DevicePathFromHandle (LoadedImage->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode);
+#endif
+
+}
+
+VOID
+RegisterBootOptionHotkey (
+ UINT16 OptionNumber,
+ EFI_INPUT_KEY *Key,
+ BOOLEAN Add
+ )
+{
+ EFI_STATUS Status;
+
+ if (!Add) {
+ //
+ // No enter hotkey when force to setup or there is no boot option
+ //
+ Status = EfiBootManagerDeleteKeyOptionVariable (NULL, 0, Key, NULL);
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);
+ } else {
+ //
+ // Register enter hotkey for the first boot option
+ //
+ Status = EfiBootManagerAddKeyOptionVariable (NULL, OptionNumber, 0, Key,NULL);
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+ }
+}
+
+EFI_STATUS
+EFIAPI
+DetectKeypressCallback (
+ IN EFI_KEY_DATA *KeyData
+)
+{
+ mHotKeypressed = TRUE;
+
+ if (HotKeyEvent != NULL) {
+ gBS->SignalEvent(HotKeyEvent);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called after all the boot options are enumerated and ordered properly.
+**/
+VOID
+RegisterStaticHotkey (
+ VOID
+ )
+{
+
+ EFI_INPUT_KEY Enter;
+ EFI_KEY_DATA F2;
+ EFI_KEY_DATA F7;
+ BOOLEAN EnterSetup;
+ EFI_STATUS Status;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+ EnterSetup = FALSE;
+
+ //
+ // [Enter]
+ //
+ mContinueBoot = !EnterSetup;
+ if (mContinueBoot) {
+ Enter.ScanCode = SCAN_NULL;
+ Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+ EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+ }
+
+
+ //
+ // [F2]/[F7]
+ //
+ F2.Key.ScanCode = SCAN_F2;
+ F2.Key.UnicodeChar = CHAR_NULL;
+ F2.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+ F2.KeyState.KeyToggleState = 0;
+ Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+ ASSERT_EFI_ERROR (Status);
+ RegisterBootOptionHotkey ((UINT16) BootOption.OptionNumber, &F2.Key, TRUE);
+ EfiBootManagerFreeLoadOption (&BootOption);
+
+ F7.Key.ScanCode = SCAN_F7;
+ F7.Key.UnicodeChar = CHAR_NULL;
+ F7.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+ F7.KeyState.KeyToggleState = 0;
+ mBootMenuBoot = !EnterSetup;
+ RegisterBootOptionHotkey ((UINT16) mBootMenuOptionNumber, &F7.Key, mBootMenuBoot);
+
+}
+
+UINT8
+BootOptionType (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+
+ for (Node = DevicePath; !IsDevicePathEndType (Node); Node = NextDevicePathNode (Node)) {
+ if (DevicePathType (Node) == MESSAGING_DEVICE_PATH) {
+ //
+ // Make sure the device path points to the driver device.
+ //
+ NextNode = NextDevicePathNode (Node);
+ if (DevicePathSubType(NextNode) == MSG_DEVICE_LOGICAL_UNIT_DP) {
+ //
+ // if the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN),
+ // skip it
+ //
+ NextNode = NextDevicePathNode (NextNode);
+ }
+ if (IsDevicePathEndType (NextNode)) {
+ if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH)) {
+ return DevicePathSubType (Node);
+ } else {
+ return MSG_SATA_DP;
+ }
+ }
+ }
+ }
+
+ return (UINT8) -1;
+}
+
+/**
+ Returns the priority number.
+ OptionType EFI
+ ------------------------------------
+ PXE 2
+ DVD 4
+ USB 6
+ NVME 7
+ HDD 8
+ EFI Shell 9
+ Others 100
+
+ @param BootOption
+**/
+UINTN
+BootOptionPriority (
+ CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
+ )
+{
+ //
+ // EFI boot options
+ //
+ switch (BootOptionType (BootOption->FilePath)) {
+ case MSG_MAC_ADDR_DP:
+ case MSG_VLAN_DP:
+ case MSG_IPv4_DP:
+ case MSG_IPv6_DP:
+ return 2;
+
+ case MSG_SATA_DP:
+ case MSG_ATAPI_DP:
+ case MSG_UFS_DP:
+ case MSG_NVME_NAMESPACE_DP:
+ return 4;
+
+ case MSG_USB_DP:
+ return 6;
+
+ }
+ if (StrCmp (BootOption->Description, INTERNAL_UEFI_SHELL_NAME) == 0) {
+ if (PcdGetBool (PcdBootToShellOnly)) {
+ return 0;
+ }
+ return 9;
+ }
+ if (StrCmp (BootOption->Description, UEFI_HARD_DRIVE_NAME) == 0) {
+ return 8;
+ }
+ return 100;
+}
+
+INTN
+EFIAPI
+CompareBootOption (
+ CONST VOID *Left,
+ CONST VOID *Right
+ )
+{
+ return BootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *) Left) -
+ BootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *) Right);
+}
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h
new file mode 100644
index 0000000000..3ec3baa207
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h
@@ -0,0 +1,22 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _IOAPIC_H_
+#define _IOAPIC_H_
+
+#define EFI_IO_APIC_INDEX_OFFSET 0x00
+#define EFI_IO_APIC_DATA_OFFSET 0x10
+#define EFI_IO_APIC_IRQ_ASSERTION_OFFSET 0x20
+#define EFI_IO_APIC_EOI_OFFSET 0x40
+
+#define EFI_IO_APIC_ID_REGISTER 0x0
+#define EFI_IO_APIC_ID_BITSHIFT 24
+#define EFI_IO_APIC_VER_REGISTER 0x1
+#define EFI_IO_APIC_BOOT_CONFIG_REGISTER 0x3
+#define EFI_IO_APIC_FSB_INT_DELIVERY 0x1
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c
new file mode 100644
index 0000000000..0b941ccb07
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c
@@ -0,0 +1,96 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include "PciPlatform.h"
+#include <Guid/SetupVariable.h>
+
+#ifdef EFI_PCI_IOV_SUPPORT
+
+/**
+
+ 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.
+
+**/
+EFI_STATUS
+EFIAPI
+GetSystemLowestPageSize (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT UINT32 *SystemLowestPageSize
+)
+{
+ UINT8 SystemPageSize;
+
+ CopyMem (&SystemPageSize, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, SystemPageSize), sizeof(UINT8));
+
+ if (SystemLowestPageSize != NULL) {
+ //
+ // Page size is 4K
+ //
+ //*SystemLowestPageSize = 1;
+ *SystemLowestPageSize = SystemPageSize;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+
+ The GetIovPlatformPolicy() 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.
+
+**/
+EFI_STATUS
+EFIAPI
+GetIovPlatformPolicy (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_IOV_PLATFORM_POLICY *PciIovPolicy
+)
+{
+ UINT8 PolicyEnable;
+ UINT8 ARIEnable;
+ UINT8 SRIOVEnable;
+ UINT8 MRIOVEnable;
+
+ PolicyEnable = 0;
+
+ CopyMem (&ARIEnable, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, ARIEnable), sizeof(UINT8));
+ CopyMem (&SRIOVEnable, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, SRIOVEnable), sizeof(UINT8));
+ CopyMem (&MRIOVEnable, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, MRIOVEnable), sizeof(UINT8));
+
+ if (ARIEnable == TRUE) {
+ PolicyEnable = PolicyEnable | EFI_PCI_IOV_POLICY_ARI;
+ }
+
+ if (SRIOVEnable == TRUE) {
+ PolicyEnable = PolicyEnable | EFI_PCI_IOV_POLICY_SRIOV;
+ }
+
+ if (MRIOVEnable == TRUE) {
+ PolicyEnable = PolicyEnable | EFI_PCI_IOV_POLICY_MRIOV;
+ }
+
+ if (PciIovPolicy != NULL) {
+ //*PciIovPolicy = EFI_PCI_IOV_POLICY_ARI | EFI_PCI_IOV_POLICY_SRIOV;
+ *PciIovPolicy = PolicyEnable;
+ }
+ return EFI_SUCCESS;
+}
+
+#endif
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h
new file mode 100644
index 0000000000..f7a8cb06a0
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h
@@ -0,0 +1,51 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCI_IOV_PLATFORM_POLICY_H_
+#define PCI_IOV_PLATFORM_POLICY_H_
+
+/**
+
+ 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.
+
+**/
+EFI_STATUS
+EFIAPI
+GetSystemLowestPageSize (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT UINT32 *SystemLowestPageSize
+)
+;
+
+
+/**
+
+ 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.
+
+**/
+EFI_STATUS
+EFIAPI
+GetIovPlatformPolicy (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_IOV_PLATFORM_POLICY *PciIovPolicy
+)
+;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c
new file mode 100644
index 0000000000..b479ec5992
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c
@@ -0,0 +1,183 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include "PciPlatform.h"
+#include <Library/PcdLib.h>
+#ifdef EFI_PCI_IOV_SUPPORT
+#include "PciIovPlatformPolicy.h"
+#endif
+
+PCI_PLATFORM_PRIVATE_DATA mPciPrivateData;
+
+BOOLEAN FirstCall = TRUE;
+UINT8 sSataRaidLoadEfiDriverOption;
+UINT8 SataRaidLoadEfiDriverOption;
+UINT8 BootNetworkOption;
+
+/**
+
+ Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
+
+ @param This - The pointer to the Protocol itself.
+ PciPolicy - the returned Policy.
+
+ @retval EFI_UNSUPPORTED - Function not supported.
+ @retval EFI_INVALID_PARAMETER - Invalid PciPolicy value.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
+ )
+{
+ if (PciPolicy == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+
+ Return a PCI ROM image for the onboard device represented by PciHandle.
+
+ @param This - Protocol instance pointer.
+ PciHandle - PCI device to return the ROM image for.
+ RomImage - PCI Rom Image for onboard device.
+ RomSize - Size of RomImage in bytes.
+
+ @retval EFI_SUCCESS - RomImage is valid.
+ @retval EFI_NOT_FOUND - No RomImage.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPciRom (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage,
+ OUT UINTN *RomSize
+ )
+{
+ return EFI_NOT_FOUND;
+}
+
+/**
+
+ GC_TODO: Add function description
+
+ @param This - GC_TODO: add argument description
+ @param Function - GC_TODO: add argument description
+ @param Phase - GC_TODO: add argument description
+
+ @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
+ @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
+ @retval EFI_UNSUPPORTED - GC_TODO: Add description for return value
+ @retval EFI_SUCCESS - GC_TODO: Add description for return value
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterPciCallback (
+ IN EFI_PCI_CALLBACK_PROTOCOL *This,
+ IN EFI_PCI_CALLBACK_FUNC Function,
+ IN EFI_PCI_ENUMERATION_PHASE Phase
+ )
+{
+ LIST_ENTRY *NodeEntry;
+ PCI_CALLBACK_DATA *PciCallbackData;
+
+ if (Function == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( (Phase & (EfiPciEnumerationDeviceScanning | EfiPciEnumerationBusNumberAssigned \
+ | EfiPciEnumerationResourceAssigned)) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Check if the node has been added
+ //
+ NodeEntry = GetFirstNode (&mPciPrivateData.PciCallbackList);
+ while (!IsNull (&mPciPrivateData.PciCallbackList, NodeEntry)) {
+ PciCallbackData = PCI_CALLBACK_DATA_FROM_LINK (NodeEntry);
+ if (PciCallbackData->Function == Function) {
+ return EFI_UNSUPPORTED;
+ }
+
+ NodeEntry = GetNextNode (&mPciPrivateData.PciCallbackList, NodeEntry);
+ }
+
+ PciCallbackData = NULL;
+ PciCallbackData = AllocateZeroPool (sizeof (PCI_CALLBACK_DATA));
+ ASSERT (PciCallbackData != NULL);
+
+ if(PciCallbackData != NULL){
+ PciCallbackData->Signature = PCI_CALLBACK_DATA_SIGNATURE;
+ PciCallbackData->Function = Function;
+ PciCallbackData->Phase = Phase;
+ InsertTailList (&mPciPrivateData.PciCallbackList, &PciCallbackData->Link);
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+
+/**
+
+ Main Entry point of the Pci Platform Driver.
+
+ @param ImageHandle - Handle to the image.
+ @param SystemTable - Handle to System Table.
+
+ @retval EFI_STATUS - Status of the function calling.
+
+**/
+EFI_STATUS
+EFIAPI
+PciPlatformDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&mPciPrivateData, sizeof (mPciPrivateData));
+ InitializeListHead (&mPciPrivateData.PciCallbackList);
+
+ mPciPrivateData.PciPlatform.PlatformNotify = PhaseNotify;
+ mPciPrivateData.PciPlatform.PlatformPrepController = PlatformPrepController;
+ mPciPrivateData.PciPlatform.GetPlatformPolicy = GetPlatformPolicy;
+ mPciPrivateData.PciPlatform.GetPciRom = GetPciRom;
+ mPciPrivateData.PciCallback.RegisterPciCallback = RegisterPciCallback;
+#ifdef EFI_PCI_IOV_SUPPORT
+ mPciPrivateData.PciIovPlatform.GetSystemLowestPageSize = GetSystemLowestPageSize;
+ mPciPrivateData.PciIovPlatform.GetPlatformPolicy = GetIovPlatformPolicy;
+#endif
+
+ //
+ // Install on a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPciPrivateData.PciPlatformHandle,
+ &gEfiPciPlatformProtocolGuid,
+ &mPciPrivateData.PciPlatform,
+ &gEfiPciCallbackProtocolGuid,
+ &mPciPrivateData.PciCallback,
+#ifdef EFI_PCI_IOV_SUPPORT
+ &gEfiPciIovPlatformProtocolGuid,
+ &mPciPrivateData.PciIovPlatform,
+#endif
+ NULL
+ );
+
+ return Status;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h
new file mode 100644
index 0000000000..353715688a
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h
@@ -0,0 +1,201 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCI_PLATFORM_H_
+#define PCI_PLATFORM_H_
+
+#include <PiDxe.h>
+#include <Register/PchRegsSata.h>
+#include <Register/PchRegsEva.h>
+#include <PchAccess.h>
+#include <Platform.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3PciLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/Runtime.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/PciCallback.h>
+#include <Protocol/PciPlatform.h>
+#include <Protocol/PciIovPlatform.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/SocketVariable.h>
+#include <IndustryStandard/Pci.h>
+
+//
+// Global variables for Option ROMs
+//
+
+#define INVALID 0xBD
+
+#define PCI_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('P', 'c', 'i', 'c')
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_PCI_CALLBACK_FUNC Function;
+ EFI_PCI_ENUMERATION_PHASE Phase;
+} PCI_CALLBACK_DATA;
+
+typedef struct {
+ EFI_HANDLE PciPlatformHandle;
+ EFI_HANDLE RootBridgeHandle;
+ EFI_PCI_PLATFORM_PROTOCOL PciPlatform;
+ EFI_PCI_CALLBACK_PROTOCOL PciCallback;
+#ifdef EFI_PCI_IOV_SUPPORT
+ EFI_PCI_IOV_PLATFORM_PROTOCOL PciIovPlatform;
+#endif
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ EFI_CPU_IO2_PROTOCOL *CpuIo;
+ EFI_LIST_ENTRY PciCallbackList;
+ EFI_PCI_CALLBACK_CONTEXT Context;
+ EFI_PCI_ENUMERATION_PHASE PciEnumerationPhase;
+ UINT8 BusAssignedTime;
+} PCI_PLATFORM_PRIVATE_DATA;
+
+#define PCI_CALLBACK_DATA_FROM_LINK(_node) \
+ CR ( \
+ _node, \
+ PCI_CALLBACK_DATA, \
+ Link, \
+ PCI_CALLBACK_DATA_SIGNATURE \
+ )
+
+extern PCI_PLATFORM_PRIVATE_DATA mPciPrivateData;
+extern EFI_GUID gPchSataEfiLoadProtocolGuid;
+
+/**
+
+ Perform initialization by the phase indicated.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - Must return with success.
+
+**/
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+;
+
+/**
+
+ The PlatformPrepController() function can be used to notify the platform driver so that
+ it can perform platform-specific actions. No specific actions are required.
+ Several notification points are defined at this time. More synchronization points may be
+ added as required in the future. The PCI bus driver calls the platform driver twice for
+ every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
+ is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
+ been notified.
+ This member function may not perform any error checking on the input parameters. It also
+ does not return any error codes. If this member function detects any error condition, it
+ needs to handle those errors on its own because there is no way to surface any errors to
+ the caller.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param RootBridge - The associated PCI root bridge handle.
+ @param PciAddress - The address of the PCI device on the PCI bus.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_HANDLE RootBridge,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+;
+
+/**
+
+ Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
+
+ @param This - The pointer to the Protocol itself.
+ PciPolicy - the returned Policy.
+
+ @retval EFI_UNSUPPORTED - Function not supported.
+ @retval EFI_INVALID_PARAMETER - Invalid PciPolicy value.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
+ )
+;
+
+/**
+
+ Return a PCI ROM image for the onboard device represented by PciHandle.
+
+ @param This - Protocol instance pointer.
+ PciHandle - PCI device to return the ROM image for.
+ RomImage - PCI Rom Image for onboard device.
+ RomSize - Size of RomImage in bytes.
+
+ @retval EFI_SUCCESS - RomImage is valid.
+ @retval EFI_NOT_FOUND - No RomImage.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPciRom (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage,
+ OUT UINTN *RomSize
+ )
+;
+
+/**
+
+ Register a callback during PCI bus enumeration
+
+ @param This - Protocol instance pointer.
+ @param Function - Callback function pointer.
+ @param Phase - PCI enumeration phase.
+
+ @retval EFI_SUCCESS - Function has registed successfully
+ @retval EFI_UNSUPPORTED - The function has been regisered
+ @retval EFI_InVALID_PARAMETER - The parameter is incorrect
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterPciCallback (
+ IN EFI_PCI_CALLBACK_PROTOCOL *This,
+ IN EFI_PCI_CALLBACK_FUNC Function,
+ IN EFI_PCI_ENUMERATION_PHASE Phase
+ )
+;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf
new file mode 100644
index 0000000000..884d151b49
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf
@@ -0,0 +1,70 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PciPlatform
+ FILE_GUID = E2441B64-7EF4-41fe-B3A3-8CAA7F8D3017
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PciPlatformDriverEntry
+
+[Sources]
+ PciPlatform.c
+ PciPlatform.h
+ PciPlatformHooks.c
+ PciPlatformHooks.h
+ PciIovPlatformPolicy.c
+ PciIovPlatformPolicy.h
+ PciSupportLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ PurleyOpenBoardPkg/OpenBoardPkg.dec
+ PurleyRefreshSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ IoLib
+ BaseMemoryLib
+ DebugLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ HobLib
+ S3PciLib
+ PcdLib
+
+[Protocols]
+ gEfiPciCallbackProtocolGuid
+ gEfiCpuIo2ProtocolGuid
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiPciIoProtocolGuid
+ gEfiPciPlatformProtocolGuid
+ gEfiIioUdsProtocolGuid
+ gEfiPciRootBridgeIoProtocolGuid
+ gEfiPciIovPlatformProtocolGuid
+ gEfiIioSystemProtocolGuid
+ gEfiPciHostBridgeResourceAllocationProtocolGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport
+ gOemSkuTokenSpaceGuid.PcdSetupData
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicIdBase
+
+[FixedPcd]
+ gEfiCpRcPkgTokenSpaceGuid.PcdMaxNestedLevel
+
+[Depex]
+ TRUE
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c
new file mode 100644
index 0000000000..2556d46407
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c
@@ -0,0 +1,527 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Protocol/IioUds.h>
+#include <PciPlatform.h>
+#include <PciPlatformHooks.h>
+#include <PciSupportLib.h>
+#include <IoApic.h>
+#include <Library/S3BootScriptLib.h>
+#include <Protocol/IioSystem.h>
+
+EFI_IIO_UDS_PROTOCOL *mIioUds = NULL;
+EFI_IIO_SYSTEM_PROTOCOL *IioSystemProtocol = NULL;
+IIO_GLOBALS *IioGlobalData = NULL;
+
+VOID
+ChipsetCallback (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_ENUMERATION_PHASE Phase,
+ EFI_PCI_CALLBACK_CONTEXT *Context
+ )
+{
+ EFI_LIST_ENTRY *NodeEntry;
+ PCI_CALLBACK_DATA *PciCallbackData;
+
+ //
+ // Check if the node has been added
+ //
+ // DEBUG ((DEBUG_ERROR, "PCI Callback (%d,%d,%d)\n",PciAddress.Bus, PciAddress.Device, PciAddress.Function ));
+ //
+ Context->PciRootBridgeIo = mPciPrivateData.PciRootBridgeIo;
+ NodeEntry = GetFirstNode (&mPciPrivateData.PciCallbackList);
+ while (!IsNull (&mPciPrivateData.PciCallbackList, NodeEntry)) {
+ PciCallbackData = PCI_CALLBACK_DATA_FROM_LINK (NodeEntry);
+ if (PciCallbackData->Phase & Phase) {
+ (PciCallbackData->Function) (RootBridgeHandle, PciAddress, Phase, Context);
+ }
+
+ NodeEntry = GetNextNode (&mPciPrivateData.PciCallbackList, NodeEntry);
+ }
+}
+
+/**
+
+ GC_TODO: add routine description
+
+ @param StartBus - GC_TODO: add arg description
+
+ @retval EFI_SUCCESS - GC_TODO: add retval description
+
+**/
+EFI_STATUS
+PciTreeTraverse (
+ IN UINT8 StartBus
+ )
+{
+ UINT64 PciAddress;
+ UINT8 Device;
+ UINT8 Func;
+ UINT8 SecondaryBus;
+ BOOLEAN MultiFunc;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+ MultiFunc = FALSE;
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+ if (IsPciDevicePresent (
+ mPciPrivateData.PciRootBridgeIo,
+ &mPciPrivateData.Context.PciHeader,
+ StartBus,
+ Device,
+ Func
+ )) {
+ if ((Func == 0) && IS_PCI_MULTI_FUNC(&(mPciPrivateData.Context.PciHeader))) {
+ MultiFunc = TRUE;
+ }
+ PciAddress = EFI_PCI_ADDRESS (StartBus, Device, Func, 0);
+ ChipsetCallback (
+ mPciPrivateData.RootBridgeHandle,
+ *(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &PciAddress,
+ mPciPrivateData.PciEnumerationPhase,
+ &(mPciPrivateData.Context)
+ );
+ if (IS_PCI_BRIDGE (&(mPciPrivateData.Context.PciHeader))) {
+ PciAddress = EFI_PCI_ADDRESS (StartBus, Device, Func, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ mPciPrivateData.PciRootBridgeIo->Pci.Read (
+ mPciPrivateData.PciRootBridgeIo,
+ EfiPciWidthUint8,
+ *(UINT64 *) &PciAddress,
+ 1,
+ &SecondaryBus
+ );
+ if ((SecondaryBus > 0) && (SecondaryBus < 0xFF)) {
+ PciTreeTraverse (SecondaryBus);
+ }
+ }
+ }
+
+ if (MultiFunc == FALSE) {
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+ Func = PCI_MAX_FUNC;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Program Io Apic Id
+
+ @param IoApicAddress and IoApicId
+
+ @retval None
+
+**/
+VOID
+ProgramIoApicId (
+ IN UINT32 IoApicAddress,
+ IN UINT8 IoApicId
+ )
+{
+
+ UINT32 Data;
+
+ mPciPrivateData.CpuIo->Mem.Read (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_INDEX_OFFSET,
+ 1,
+ &Data
+ );
+
+ //
+ // IOAPIC is not there
+ //
+ if (Data == (UINT32) -1) {
+ return ;
+ }
+ //
+ // Set up IO APIC ID and enable FSB delivery
+ // Use CPU IO protocol since the IO APIC ranges
+ // are not included in PCI apertures
+ //
+ Data = EFI_IO_APIC_ID_REGISTER;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_INDEX_OFFSET,
+ 1,
+ &Data
+ );
+
+ Data = IoApicId << EFI_IO_APIC_ID_BITSHIFT;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_DATA_OFFSET,
+ 1,
+ &Data
+ );
+
+ Data = EFI_IO_APIC_BOOT_CONFIG_REGISTER;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_INDEX_OFFSET,
+ 1,
+ &Data
+ );
+
+ Data = EFI_IO_APIC_FSB_INT_DELIVERY;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_DATA_OFFSET,
+ 1,
+ &Data
+ );
+}
+
+#ifdef EFI_PCI_IOV_SUPPORT
+/**
+
+ Initialize the Pci Iov Platform Data.
+
+ @param ImageHandle - Handle to the image.
+ @param SystemTable - Handle to System Table.
+
+ @retval EFI_STATUS - Status of the function calling.
+
+**/
+EFI_STATUS
+EFIAPI
+PciPlatformInitPciIovData (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IOV_PLATFORM_POLICY PciIovPolicy;
+ UINT32 SystemPageSize;
+ EFI_PCI_IOV_PLATFORM_PROTOCOL *gPciIovPlatformProtocol;
+
+ Status = gBS->LocateProtocol (
+ &gEfiPciIovPlatformProtocolGuid,
+ NULL,
+ &gPciIovPlatformProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gPciIovPlatformProtocol->GetSystemLowestPageSize (
+ gPciIovPlatformProtocol,
+ &SystemPageSize
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PcdSet32S (PcdSrIovSystemPageSize, (1 << SystemPageSize));
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ return Status;
+ }
+ Status = gPciIovPlatformProtocol->GetPlatformPolicy (
+ gPciIovPlatformProtocol,
+ &PciIovPolicy
+ );
+ if (!EFI_ERROR (Status)) {
+ if (PciIovPolicy & EFI_PCI_IOV_POLICY_ARI) {
+ Status = PcdSetBoolS (PcdAriSupport, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdAriSupport, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (PciIovPolicy & EFI_PCI_IOV_POLICY_SRIOV) {
+ Status = PcdSetBoolS (PcdSrIovSupport, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdSrIovSupport, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (PciIovPolicy & EFI_PCI_IOV_POLICY_MRIOV) {
+ Status = PcdSetBoolS (PcdMrIovSupport, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdMrIovSupport, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ } else {
+ return Status;
+ }
+ DEBUG ((
+ EFI_D_INFO,
+ " Initialized SR-IOV Platform Data: PCIIovPolicy = 0x%x; SystemPageSize = 0x%x;\n",
+ PciIovPolicy, SystemPageSize
+ ));
+ } else {
+ DEBUG ((
+ EFI_D_INFO,
+ " Using default values for SystemPageSize;\n"
+ ));
+ }
+ return Status;
+}
+#endif
+
+/**
+
+ Platform Pci Express init.
+
+ @param HostBridgeInstance - Pointer to Host Bridge private data
+ does not support 64 bit memory addresses.
+
+ @retval EFI_SUCCESS - Success.
+
+**/
+EFI_STATUS
+PciPlatformEarlyInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ //
+ // Locate the IIO Protocol Interface
+ //
+ Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid,NULL,&mIioUds);
+ ASSERT_EFI_ERROR (Status);
+ Status = gBS->LocateProtocol (&gEfiIioSystemProtocolGuid, NULL, &IioSystemProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ IioGlobalData = IioSystemProtocol->IioGlobalData;
+
+#ifdef EFI_PCI_IOV_SUPPORT
+ Status = PciPlatformInitPciIovData(); // Update IOV PCD values
+#endif
+ return EFI_SUCCESS;
+}
+
+
+/**
+
+ Init pci device registers after the device resources have been allocated, so
+ that devices behind a bus could be accessed.
+
+ @param HostBridgeInstance - PCI_HOST_BRIDGE_INSTANCE.
+
+ @retval EFI_SUCCESS - Function has completed successfully.
+
+**/
+EFI_STATUS
+PciPlatformPostInit (
+ VOID
+ )
+{
+ //
+ // Program all the IOAPIC in system
+ //
+ UINT8 Socket, Stack, IoApicId;
+ UINT8 Step;
+ UINT8 MaxSocket;
+
+#if MAX_SOCKET <= 4
+ Step = 6;
+ MaxSocket = 4;
+#else
+ Step = 4;
+ MaxSocket = 8;
+#endif
+
+ Stack = 0;
+ IoApicId = 0;
+ ProgramIoApicId (mIioUds->IioUdsPtr->PlatformData.IIO_resource[0].StackRes[0].IoApicBase, PcdGet8(PcdIoApicId));
+ for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+ if (!(mIioUds->IioUdsPtr->SystemStatus.socketPresentBitMap & (1 << Socket)))
+ continue;
+
+ for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+ if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack)))
+ continue;
+
+ if ((Socket < MaxSocket) && (Stack < Step)) {
+ IoApicId = PcdGet8(PcdPcIoApicIdBase) + Step * Socket + Stack;
+ }
+
+ if ((Socket == 0) && (Stack == 0)) {
+ ProgramIoApicId ((mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].IoApicBase + 0x1000), IoApicId);
+ } else {
+ ProgramIoApicId (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].IoApicBase, IoApicId);
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+
+ The PlatformPrepController() function can be used to notify the platform driver so that
+ it can perform platform-specific actions. No specific actions are required.
+ Several notification points are defined at this time. More synchronization points may be
+ added as required in the future. The PCI bus driver calls the platform driver twice for
+ every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
+ is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
+ been notified.
+ This member function may not perform any error checking on the input parameters. It also
+ does not return any error codes. If this member function detects any error condition, it
+ needs to handle those errors on its own because there is no way to surface any errors to
+ the caller.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param RootBridge - The associated PCI root bridge handle.
+ @param PciAddress - The address of the PCI device on the PCI bus.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_UNSUPPORTED - Not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_HANDLE RootBridge,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+{
+ if (mPciPrivateData.RootBridgeHandle == NULL) {
+ mPciPrivateData.RootBridgeHandle = RootBridge;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Perform initialization by the phase indicated.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - Must return with success.
+
+**/
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT8 Stack;
+
+ if (ChipsetPhase == ChipsetEntry) {
+ return EFI_SUCCESS;
+ }
+ //
+ // If for multiple host bridges, need special consideration
+ //
+ switch (Phase) {
+
+ case EfiPciHostBridgeBeginEnumeration:
+ //
+ // Pre-initialization before PCI bus enumeration
+ // No bus number and no PCI resource
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &(mPciPrivateData.PciRootBridgeIo)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiCpuIo2ProtocolGuid,
+ NULL,
+ &(mPciPrivateData.CpuIo)
+ );
+ ASSERT_EFI_ERROR (Status);
+ mPciPrivateData.Context.CpuIo = mPciPrivateData.CpuIo;
+
+ DEBUG ((DEBUG_ERROR, "PCI Platform Pre-Initialization (Before bus scanning)\n"));
+ PciPlatformEarlyInit ();
+ break;
+
+ case EfiPciHostBridgeEndBusAllocation:
+ //
+ // There are two rounds PCI bus scanning
+ // First round will initilize the PCI hotplug device
+ // Second round will be the final one
+ //
+ if (mPciPrivateData.BusAssignedTime == 0) {
+ mPciPrivateData.PciEnumerationPhase = EfiPciEnumerationDeviceScanning;
+ for (i = 0 ; i < MaxIIO ; i++) {
+ if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[i].Valid) {
+ for(Stack = 0; Stack < MAX_IIO_STACK; Stack ++) {
+ PciTreeTraverse (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[i].StackBus[Stack]);
+ }
+ }
+ }
+ mPciPrivateData.BusAssignedTime++;
+ DEBUG ((DEBUG_ERROR, "PCI Platform bus assigned\n"));
+ }
+ break;
+
+ case EfiPciHostBridgeBeginResourceAllocation:
+ //
+ // PCI bus number has been assigned, but resource is still empty
+ //
+ DEBUG ((DEBUG_ERROR, "PCI Platform Mid-Initialization (After bus number assignment)\n"));
+ mPciPrivateData.PciEnumerationPhase = EfiPciEnumerationBusNumberAssigned;
+ for (i = 0 ; i < MaxIIO ; i++) {
+ if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[i].Valid) {
+ for(Stack = 0; Stack < MAX_IIO_STACK; Stack ++) {
+ PciTreeTraverse (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[i].StackBus[Stack]);
+ }
+ }
+ }
+ //PciPlatformMidInit ();
+ break;
+
+ case EfiPciHostBridgeEndResourceAllocation:
+ //
+ // Resource enumeration is done.
+ // Both bus number and resource have been assigned
+ // Do any post initialization.
+ //
+ DEBUG ((DEBUG_ERROR, "PCI Platform Post-Initialization (After resource alloction)\n"));
+ mPciPrivateData.PciEnumerationPhase = EfiPciEnumerationResourceAssigned;
+ for (i = 0 ; i < MaxIIO ; i++) {
+ if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[i].Valid) {
+ for(Stack = 0; Stack < MAX_IIO_STACK; Stack ++) {
+ PciTreeTraverse (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[i].StackBus[Stack]);
+ }
+ }
+ }
+ PciPlatformPostInit ();
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h
new file mode 100644
index 0000000000..a5cee1b3a5
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h
@@ -0,0 +1,24 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCI_PLATFORM_HOOKS_H_
+#define PCI_PLATFORM_HOOKS_H_
+
+VOID
+ChipsetCallback (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_ENUMERATION_PHASE Phase,
+ EFI_PCI_CALLBACK_CONTEXT *Context
+ );
+
+EFI_STATUS
+PciTreeTraverse (
+ IN UINT8 StartBus
+ );
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c
new file mode 100644
index 0000000000..d8bf65439f
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c
@@ -0,0 +1,103 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiDxe.h"
+#include <Base.h>
+#include <Guid/SocketIioVariable.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include "IndustryStandard/Pci.h"
+#include "PciSupportLib.h"
+
+PCIE_STACK mPcieStack;
+
+
+/**
+
+ This routine is used to check whether the pci device is present
+
+ @retval None
+
+**/
+BOOLEAN
+IsPciDevicePresent (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+// TODO: PciRootBridgeIo - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ UINT64 Address;
+ UINT32 Dummy;
+ EFI_STATUS Status;
+
+ Dummy=0xFFFFFFFF;
+ //
+ // Create PCI address map in terms of Bus, Device and Func
+ //
+ Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
+
+ //
+ // Read the Vendor Id register
+ //
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ Pci
+ );
+ if ((Pci->Hdr).VendorId == 0xffff) {
+ /// PCIe card could have been assigned a temporary bus number.
+ /// An write cycle can be used to try to rewrite the Bus number in the card
+ /// Try to write the Vendor Id register, and recheck if the card is present.
+ Status = PciRootBridgeIo->Pci.Write(
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ &Dummy
+ );
+
+ // Retry the previous read after the PCI cycle has been tried.
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ Pci
+ );
+ }
+
+ if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {
+
+ //
+ // Read the entire config header for the device
+ //
+
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ sizeof (PCI_TYPE00) / sizeof (UINT32),
+ Pci
+ );
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h
new file mode 100644
index 0000000000..dc123b0d42
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h
@@ -0,0 +1,44 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_PCI_SUPPORT_H_
+#define _EFI_PCI_SUPPORT_H_
+
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Guid/SetupVariable.h>
+
+typedef struct {
+ UINT8 PcieCapPtr;
+ UINT8 Function;
+ UINT8 Device;
+ UINT8 Bus;
+ UINT16 PcieLnkCap;
+ UINT16 PcieDevCap;
+ //Added to Support AtomicOp Request-->Start
+ UINT16 PcieDevCap2;
+ //Added to Support AtomicOp Request-->End
+} PCIE_CAP_INFO;
+
+typedef struct {
+ INTN Top;
+ PCIE_CAP_INFO PcieCapInfo[FixedPcdGet32(PcdMaxNestedLevel)];
+} PCIE_STACK;
+
+extern PCIE_STACK mPcieStack;
+
+BOOLEAN
+IsPciDevicePresent (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ );
+
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.c
new file mode 100644
index 0000000000..6c626cf05d
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.c
@@ -0,0 +1,86 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// Statements that include other files
+//
+#include "IioUdsDataDxe.h"
+
+#define STRING_WIDTH_40 40
+
+//
+// Instantiation of Driver's private data.
+//
+EFI_IIO_UDS_DRIVER_PRIVATE mIioUdsPrivateData;
+IIO_UDS *IioUdsData; // Pointer to UDS in Allocated Memory Pool
+
+/**
+
+ Entry point for the driver.
+
+ @param ImageHandle - Image Handle.
+ @param SystemTable - EFI System Table.
+
+ @retval EFI_SUCCESS - Function has completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+IioUdsDataInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ IIO_UDS *UdsHobPtr;
+ EFI_GUID UniversalDataGuid = IIO_UNIVERSAL_DATA_GUID;
+
+ //
+ // Time to get the IIO_UDS HOB data stored in the PEI driver
+ //
+ GuidHob = GetFirstGuidHob (&UniversalDataGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ UdsHobPtr = GET_GUID_HOB_DATA(GuidHob);
+
+ //
+ // Allocate Memory Pool for Universal Data Storage so that protocol can expose it
+ //
+ Status = gBS->AllocatePool ( EfiReservedMemoryType, sizeof (IIO_UDS), (VOID **) &IioUdsData );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize the Pool Memory with the data from the Hand-Off-Block
+ //
+ CopyMem(IioUdsData, UdsHobPtr, sizeof(IIO_UDS));
+
+ //
+ // Build the IIO_UDS driver instance for protocol publishing
+ //
+ ZeroMem (&mIioUdsPrivateData, sizeof (mIioUdsPrivateData));
+
+ mIioUdsPrivateData.Signature = EFI_IIO_UDS_DRIVER_PRIVATE_SIGNATURE;
+ mIioUdsPrivateData.IioUds.IioUdsPtr = IioUdsData;
+ mIioUdsPrivateData.IioUds.EnableVc = NULL;
+
+ //
+ // Install the IioUds Protocol.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mIioUdsPrivateData.Handle,
+ &gEfiIioUdsProtocolGuid,
+ &mIioUdsPrivateData.IioUds,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.h b/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.h
new file mode 100644
index 0000000000..62da06d605
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.h
@@ -0,0 +1,81 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PLATFORM_TYPES_H_
+#define _PLATFORM_TYPES_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/VariableWrite.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/Spi.h>
+#include <Protocol/IioUds.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/HobList.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsLpc.h>
+#include <PchAccess.h>
+#include <Platform.h>
+
+
+
+
+#define EFI_PLATFORM_TYPE_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('T', 'Y', 'P', 'P')
+#define EFI_IIO_UDS_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('S', 'D', 'U', 'I')
+
+
+typedef unsigned char BYTE; //!< 8-bit quantities
+typedef unsigned short WORD; //!< 16-bit quantities
+typedef unsigned long DWORD; //!< 32-bit quantities
+
+typedef enum
+{
+#ifndef SUCCESS
+ SUCCESS = 0x00, //!< Packet it good! .data[] is valid
+#endif
+ DEFER = 0x01, //!< Packet is defered. .data[1] = BufID
+ W_EARLY_NACK = 0x02, //!< Packet mastered on the SMBus by the MCU was NACKed earlier than expected
+ NOT_RESP = 0x03, //!< Packet mastered on the SMBus by the MCU was NACKed during the address byte
+ BUFFER_OVERRUN = 0x04, //!< Too many BYTE s were stuffed into the buffer.
+ NO_BUFFER = 0x05, //!< All the buffers are used
+ INVALID_BUF = 0x06, //!< Command passed a buffer id that was not in range
+ BUF_NOT_IN_QUEUE = 0x07, //!< Command passed a buffer id is not being used.
+ ARBITRATION_LOST = 0x08, //!< While the MCU was mastering a packet on the SMBus it lost arbitration.
+ TIMEOUT = 0x0B, //!< SMBus timed out.
+ CHECKSUM_ERR = 0x0C, //!< Operation encountered a checksum mismatch
+ DATA_NACK = 0x0D, //!< Still don't know what these mean?
+ BUS_ERR = 0x0E, //!< ?
+ FAIL = 0x0F, //!< Generic error
+ BUSY = 0x10, //!< ?
+ R_EARLY_NACK = 0x11, //!< ?
+ INVALID_LCD_COL_OFF = 0x12, //!< The cursor on the LCD was set to a column that was out of range.
+ INVALID_LCD_ROW_OFF = 0x13, //!< The cursor on the LCD was set to a row that was out of range.
+ INVALID_CK410_SEL = 0x14, //!< ?
+ CMD_NOT_SUPPORTED = 0x15, //!< This command is not supported
+ MORE_DATA_AVAILABLE = 0x16, //!< Do the command again to get more data
+} STATUS;
+
+typedef struct {
+ BYTE byte_count;
+ STATUS status;
+ BYTE data[31];
+} BUFFER_RSLT;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle; // Handle for protocol this driver installs on
+ EFI_IIO_UDS_PROTOCOL IioUds; // Policy protocol this driver installs
+} EFI_IIO_UDS_DRIVER_PRIVATE;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.inf b/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.inf
new file mode 100644
index 0000000000..db425e3836
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/IioUdsDataDxe/IioUdsDataDxe.inf
@@ -0,0 +1,36 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IioUdsDataDxe
+ FILE_GUID = 036125ED-DD4C-4BF7-AC8D-83FE11CDD5DB
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = IioUdsDataInit
+
+[Sources]
+ IioUdsDataDxe.c
+ IioUdsDataDxe.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PurleyOpenBoardPkg/OpenBoardPkg.dec
+ PurleyRefreshSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+ HobLib
+ BaseMemoryLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiIioUdsProtocolGuid
+
+[Depex]
+ TRUE
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.c
new file mode 100644
index 0000000000..1cd8d657c1
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.c
@@ -0,0 +1,654 @@
+/** @file
+
+Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Protocol/IntelCpuPcdsSetDone.h>
+#include <Setup/IioUniversalData.h>
+#include <Guid/SetupVariable.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/CpuConfigLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/CpuPpmLib.h>
+#include <SetupTable.h>
+#include <Platform.h>
+#include "PlatformHost.h"
+#include <Register/Cpuid.h>
+
+CHAR16 mCpuSocketStr[8][5] = {L"CPU0", L"CPU1", L"CPU2", L"CPU3", L"CPU4", L"CPU5", L"CPU6", L"CPU7"};
+CHAR16 mCpuAssetTagStr[] = L"UNKNOWN";
+IIO_UDS *mIioUds;
+
+/**
+
+ GC_TODO: add routine description
+
+ @param None
+
+ @retval None
+
+**/
+VOID
+CheckAndReAssignSocketId(
+ VOID
+ )
+{
+#define APICID_MASK_BIT14_8 0x7F //current Si support programmable APICID up to 15bits
+ CPU_SOCKET_ID_INFO *pcdSktIdPtr;
+ UINT32 i, IntraPackageIdBits;
+ UINTN PcdSize;
+ EFI_STATUS Status;
+ UINT32 MaxSocketCount;
+
+ MaxSocketCount = FixedPcdGet32(PcdMaxCpuSocketCount);
+ DEBUG ((EFI_D_ERROR, "::SocketCount %08x\n", MaxSocketCount));
+ pcdSktIdPtr = (CPU_SOCKET_ID_INFO *)PcdGetPtr(PcdCpuSocketId);
+ PcdSize = PcdGetSize (PcdCpuSocketId); //MAX_SOCKET * sizeof(CPU_SOCKET_ID_INFO);
+ ASSERT(PcdSize == (MAX_SOCKET * sizeof(CPU_SOCKET_ID_INFO)));
+ Status = PcdSetPtrS (PcdCpuSocketId, &PcdSize, (VOID *)pcdSktIdPtr);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return;
+ DEBUG ((EFI_D_INFO, "::SockeId Pcd at %08x, size %x\n", PcdGetPtr(PcdCpuSocketId), PcdSize));
+
+ for(i = 0; i < MAX_SOCKET; i++) {
+ if(mIioUds->PlatformData.CpuQpiInfo[i].Valid) {
+ pcdSktIdPtr[i].DefaultSocketId = mIioUds->PlatformData.CpuQpiInfo[i].SocId;
+ pcdSktIdPtr[i].NewSocketId = mIioUds->PlatformData.CpuQpiInfo[i].SocId;
+ } else {
+ pcdSktIdPtr[i].DefaultSocketId = (UINT32)-1; //make sure Default and New are same
+ pcdSktIdPtr[i].NewSocketId = (UINT32)-1;
+ }
+ }
+
+ AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 1, &IntraPackageIdBits, NULL, NULL, NULL);
+ //assign new socketId
+ for(i = 0; i < MAX_SOCKET; i++) {
+
+ if(pcdSktIdPtr[i].DefaultSocketId == (UINT32)-1) continue;
+
+ switch(IntraPackageIdBits) {
+ case 4: //socket bit starts from bit4 of ApicId
+ case 5: //socket bit starts from bit5 of ApicId
+ if(MAX_SOCKET == 4) {
+ pcdSktIdPtr[i].NewSocketId |= (APICID_MASK_BIT14_8 << (8 - IntraPackageIdBits));
+ } else {
+ //3bit in lower 8bit as skt field, to avoid ApicID= FFs, leave bit8 untouched for 8S
+ pcdSktIdPtr[i].NewSocketId |= (0x7E << (8 - IntraPackageIdBits)); //leave bit8 to 0 so we don't have FFs in ApicId
+ }
+ break;
+
+ case 6: //socket bit starts from bit6 of ApicId
+ if(MAX_SOCKET == 4) {
+ //only 2bit in lower 8bit as skt field, to avoid ApicID= FFs, leave bit8 untouched for 4S
+ pcdSktIdPtr[i].NewSocketId |= (0x7E << (8 - IntraPackageIdBits));
+ } else {
+ //only 2bit in lower 8bit as skt field, to avoid ApicID= FFs, leave bit9 untouched for 8S
+ pcdSktIdPtr[i].NewSocketId |= (0x7C << (8 - IntraPackageIdBits));
+ }
+ break;
+
+ default:
+ DEBUG ((EFI_D_INFO, "::Need more info to make sure we can support!!!\n"));
+ break;
+
+ } //end switch
+ }
+}
+
+
+/**
+
+ This is the EFI driver entry point for the CpuPolicy Driver. This
+ driver is responsible for getting microcode patches from FV.
+
+ @param ImageHandle - Handle for the image of this driver.
+ @param SystemTable - Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS - Protocol installed sucessfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformCpuPolicyEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SETUP_DATA SetupData;
+ UINT32 CpuPolicy;
+ UINT32 CpuPolicyEx1;
+ EFI_HANDLE Handle;
+ UINT32 CsrSapmCtl = 0;
+ UINT32 CsrPerfPlimitCtl = 0;
+ UINT8 PCPSOptions = 0;
+ UINT32 AdvPwrMgtCtl;
+ UINT8 socket;
+ UINT32 *UpiInPkgCEntry = NULL;
+ UINT32 *PcieInPkgCEntry = NULL;
+ UINT32 MsrPowerCtlLow = 0;
+ UINT32 MsrTurboPowerLimitHigh = 0;
+ UINT32 MsrTurboPowerLimitLow = 0;
+ UINT32 MsrPriPlaneCurrentCfgCtlHigh = 0;
+ UINT32 MsrPriPlaneCurrentCfgCtlLow = 0;
+ UINT32 CsrDynamicPerfPowerCtl = 0;
+ UINT32 CsrPcieIltrOvrd = 0;
+ UINT32 MsrPerfBiasConfig = 0;
+ MSR_REGISTER *CStateLatencyCtrl = NULL;
+ UINT32 CpuFamilyModelStepping;
+ UINT64 i;
+ UINT64 *Addr;
+ EFI_PPM_STRUCT *ppm = NULL;
+ XE_STRUCT *XePtr = NULL;
+ TURBO_RATIO_LIMIT_RATIO_CORES *TurboRatioLimitRatioCores = NULL;
+ UINT8 PackageCStateSetting = 0;
+ UINT8 CpuCStateValue = 0;
+
+ EFI_GUID UniversalDataGuid = IIO_UNIVERSAL_DATA_GUID;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&UniversalDataGuid);
+ ASSERT (GuidHob != NULL);
+ if(GuidHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ mIioUds = GET_GUID_HOB_DATA(GuidHob);
+
+ AsmCpuid (1, &CpuFamilyModelStepping, NULL, NULL, NULL);
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(EFI_PPM_STRUCT),
+ (VOID **) &Addr
+ );
+ if(Status != EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "::Failed to allocate mem for PPM Struct\n"));
+ ASSERT_EFI_ERROR (Status); //may need to create a default
+ } else {
+ ZeroMem(Addr, sizeof(EFI_PPM_STRUCT));
+ i = (UINT32)(*(UINT64 *)(&Addr));
+ ppm = (EFI_PPM_STRUCT *)(Addr);
+ Status = PcdSet64S (PcdCpuPmStructAddr, i);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ DEBUG ((EFI_D_INFO, "::PPM mem allocate @ %x %X %X\n", i, PcdGet64(PcdCpuPmStructAddr), ppm));
+ UpiInPkgCEntry = (UINT32 *)(((EFI_PPM_STRUCT *)Addr)->Cst.PkgCstEntryCriteriaMaskKti);
+ PcieInPkgCEntry = (UINT32 *)(((EFI_PPM_STRUCT *)Addr)->Cst.PkgCstEntryCriteriaMaskPcie);
+ XePtr = (XE_STRUCT *)(&((EFI_PPM_STRUCT *)Addr)->Xe);
+ TurboRatioLimitRatioCores = (TURBO_RATIO_LIMIT_RATIO_CORES *)(&((EFI_PPM_STRUCT *)Addr)->TurboRatioLimitRatioCores);
+ DEBUG ((EFI_D_INFO, ":: XE @ %X\n", (UINTN) XePtr));
+
+ CStateLatencyCtrl = (MSR_REGISTER *)(ppm->Cst.LatencyCtrl);
+ DEBUG ((EFI_D_INFO, "CStateLatencyCtrl[%X]\n", (UINTN) CStateLatencyCtrl));
+ }
+
+ //
+ // Read the current system configuration variable store.
+ //
+ ZeroMem (&SetupData, sizeof(SETUP_DATA));
+ CopyMem (&SetupData.SocketConfig.IioConfig, PcdGetPtr(PcdSocketIioConfigData), sizeof(SOCKET_IIO_CONFIGURATION));
+ CopyMem (&SetupData.SocketConfig.CommonRcConfig, PcdGetPtr(PcdSocketCommonRcConfigData), sizeof(SOCKET_COMMONRC_CONFIGURATION));
+ CopyMem (&SetupData.SocketConfig.CsiConfig, PcdGetPtr(PcdSocketMpLinkConfigData), sizeof(SOCKET_MP_LINK_CONFIGURATION));
+ CopyMem (&SetupData.SocketConfig.MemoryConfig, PcdGetPtr(PcdSocketMemoryConfigData), sizeof(SOCKET_MEMORY_CONFIGURATION));
+ CopyMem (&SetupData.SocketConfig.PowerManagementConfig, PcdGetPtr(PcdSocketPowerManagementConfigData), sizeof(SOCKET_POWERMANAGEMENT_CONFIGURATION));
+ CopyMem (&SetupData.SocketConfig.SocketProcessorCoreConfiguration, PcdGetPtr(PcdSocketProcessorCoreConfigData), sizeof(SOCKET_PROCESSORCORE_CONFIGURATION));
+ CopyMem (&SetupData.SystemConfig, PcdGetPtr(PcdSetupData), sizeof(SYSTEM_CONFIGURATION));
+ CopyMem (&SetupData.PchRcConfig, PcdGetPtr(PcdPchRcConfigurationData), sizeof(PCH_RC_CONFIGURATION));
+
+ {
+
+ if (SetupData.SocketConfig.PowerManagementConfig.PackageCState == PPM_AUTO) {
+ PackageCStateSetting = 3; //POR Default = C6
+ } else {
+ PackageCStateSetting = SetupData.SocketConfig.PowerManagementConfig.PackageCState;
+ }
+
+ // Temporary override to prevent accidental enabling until CR dungeon approves
+ if (SetupData.SocketConfig.PowerManagementConfig.PackageCState != 0) {
+ DEBUG((EFI_D_ERROR, "Crystal Ridge Configuration Warning: Package c-states are not disabled\n"));
+ }
+
+ if ((SetupData.SocketConfig.PowerManagementConfig.C6Enable == PPM_AUTO) ||
+ SetupData.SocketConfig.PowerManagementConfig.ProcessorAutonomousCstateEnable) {
+ CpuCStateValue |= C6_ENABLE; //POR Default = Enabled
+ } else {
+ CpuCStateValue |= (SetupData.SocketConfig.PowerManagementConfig.C6Enable * C6_ENABLE);
+ }
+
+ Status = PcdSet8S (PcdCpuCoreCStateValue, CpuCStateValue);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // If ACC enabled, then override C1E to be enabled
+ //
+ if (SetupData.SocketConfig.PowerManagementConfig.ProcessorAutonomousCstateEnable) {
+ SetupData.SocketConfig.PowerManagementConfig.ProcessorC1eEnable = TRUE;
+ }
+
+ //
+ // Verify that the value being set is within the valid range 0 to MAX_SOCKET - 1
+ //
+ if (SetupData.SocketConfig.SocketProcessorCoreConfiguration.BspSelection > MAX_SOCKET)
+ SetupData.SocketConfig.SocketProcessorCoreConfiguration.BspSelection= 0xFF;
+ Status = PcdSet8S (PcdSbspSelection, SetupData.SocketConfig.SocketProcessorCoreConfiguration.BspSelection);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ //
+ // Map CPU setup options to PcdCpuProcessorFeatureUserConfiguration
+ //
+ CpuPolicy = (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorHyperThreadingDisable ? 0 : PCD_CPU_HT_BIT) |
+ (SetupData.SocketConfig.PowerManagementConfig.ProcessorEistEnable ? PCD_CPU_EIST_BIT : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.ProcessorC1eEnable ? PCD_CPU_C1E_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorVmxEnable ? PCD_CPU_VT_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorSmxEnable ? PCD_CPU_LT_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.FastStringEnable ? PCD_CPU_FAST_STRING_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.CpuidMaxValue ? PCD_CPU_MAX_CPUID_VALUE_LIMIT_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ExecuteDisableBit ? PCD_CPU_EXECUTE_DISABLE_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.MachineCheckEnable ? PCD_CPU_MACHINE_CHECK_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.DCUStreamerPrefetcherEnable ? PCD_CPU_DCU_PREFETCHER_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.DCUIPPrefetcherEnable ? PCD_CPU_IP_PREFETCHER_BIT : 0) |
+ PCD_CPU_MONITOR_MWAIT_BIT | //never disable Mwait
+ (SetupData.SocketConfig.PowerManagementConfig.TurboMode ? PCD_CPU_TURBO_MODE_BIT : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.EnableThermalMonitor ? PCD_CPU_THERMAL_MANAGEMENT_BIT : 0);
+
+ if (SetupData.SocketConfig.PowerManagementConfig.TStateEnable && (SetupData.SocketConfig.PowerManagementConfig.OnDieThermalThrottling > 0)) {
+ CpuPolicy |= (SetupData.SocketConfig.PowerManagementConfig.TStateEnable ? PCD_CPU_TSTATE_BIT : 0);
+ }
+
+ CpuPolicyEx1 = (SetupData.SocketConfig.SocketProcessorCoreConfiguration.MlcStreamerPrefetcherEnable ? PCD_CPU_MLC_STREAMER_PREFETCHER_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.MlcSpatialPrefetcherEnable ? PCD_CPU_MLC_SPATIAL_PREFETCHER_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ThreeStrikeTimer ? PCD_CPU_THREE_STRIKE_COUNTER_BIT : 0) |
+ PCD_CPU_ENERGY_PERFORMANCE_BIAS_BIT |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorX2apic ? PCD_CPU_X2APIC_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.AesEnable ? PCD_CPU_AES_BIT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.PCIeDownStreamPECIWrite ? PCD_CPU_PECI_DOWNSTREAM_WRITE_BIT : 0) |
+ PCD_CPU_C_STATE_BIT;
+
+
+ PCPSOptions = (SetupData.SocketConfig.PowerManagementConfig.ProcessorSinglePCTLEn ? PCD_CPU_PCPS_SINGLEPCTL : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.ProcessorSPD ? PCD_CPU_PCPS_SPD : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.PStateDomain ? PCD_CPU_PCPS_PSTATEDOMAIN : 0) |
+ (UINT8) SetupData.SocketConfig.PowerManagementConfig.ProcessorEistPsdFunc;
+
+ ppm->Pst.PcpsCtrl = PCPSOptions;
+ ppm->OverclockingLock = SetupData.SocketConfig.PowerManagementConfig.OverclockingLock;
+
+ ppm->FastRaplDutyCycle = SetupData.SocketConfig.PowerManagementConfig.FastRaplDutyCycle;
+
+ if(mIioUds->PlatformData.EVMode)
+ CpuPolicy &= ~PCD_CPU_LT_BIT;
+
+ if (SetupData.SocketConfig.PowerManagementConfig.ProcessorEistEnable) {
+ Status = PcdSetBoolS (PcdCpuHwCoordination, SetupData.SocketConfig.PowerManagementConfig.ProcessorEistPsdFunc ? FALSE : TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ Status = PcdSet16S (PcdCpuAcpiLvl2Addr, PcdGet16 (PcdPchAcpiIoPortBaseAddress) + R_ACPI_LV2);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet8S (PcdCpuPackageCStateLimit, PackageCStateSetting);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ if ((SetupData.SocketConfig.PowerManagementConfig.TStateEnable) && (SetupData.SocketConfig.PowerManagementConfig.OnDieThermalThrottling > 0)) {
+ Status = PcdSet8S (PcdCpuClockModulationDutyCycle, SetupData.SocketConfig.PowerManagementConfig.OnDieThermalThrottling);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ ppm->TCCActivationOffset = SetupData.SocketConfig.PowerManagementConfig.TCCActivationOffset;
+ }
+ Status = PcdSet8S (PcdCpuDcuMode, SetupData.SocketConfig.SocketProcessorCoreConfiguration.DCUModeSelection);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ if((CpuFamilyModelStepping >> 4) == CPU_FAMILY_SKX) {
+ Status = PcdSetBoolS (PcdCpuSmmRuntimeCtlHooks, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdCpuSmmRuntimeCtlHooks, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ DEBUG ((EFI_D_INFO, ":: PcdCpuSmmRuntimeCtlHooks= %x\n", PcdGetBool(PcdCpuSmmRuntimeCtlHooks)));
+
+ if(mIioUds->PlatformData.EVMode || SetupData.SystemConfig.LmceEn) {
+ Status = PcdSet8S (PcdCpuProcessorMsrLockCtrl, 0);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSet8S (PcdCpuProcessorMsrLockCtrl, SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorMsrLockControl);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ Status = PcdSet64S(PcdCpuIioLlcWaysBitMask, SetupData.SocketConfig.SocketProcessorCoreConfiguration.IioLlcWaysMask);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet64S(PcdCpuExpandedIioLlcWaysBitMask, SetupData.SocketConfig.SocketProcessorCoreConfiguration.ExpandedIioLlcWaysMask);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet64S(PcdCpuRemoteWaysBitMask, SetupData.SocketConfig.SocketProcessorCoreConfiguration.RemoteWaysMask);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet8S(PcdPchTraceHubEn, SetupData.SocketConfig.SocketProcessorCoreConfiguration.PchTraceHubEn);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet64S(PcdCpuQlruCfgBitMask, ((UINT64) SetupData.SocketConfig.SocketProcessorCoreConfiguration.QlruCfgMask_Hi << 32) | (UINT64)SetupData.SocketConfig.SocketProcessorCoreConfiguration.QlruCfgMask_Lo );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet64S(PcdCpuRRQCountThreshold, mIioUds->PlatformData.RemoteRequestThreshold);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ //CSR SAPM CTL
+ CsrSapmCtl = 0;
+
+ for( socket = 0; socket < MAX_SOCKET; socket++) {
+ CsrSapmCtl = (( SetupData.SocketConfig.PowerManagementConfig.Iio0PkgcClkGateDis[socket] << IIO012_PKGC_CLK_GATE_DISABLE_SHIFT) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Iio1PkgcClkGateDis[socket] << (IIO012_PKGC_CLK_GATE_DISABLE_SHIFT + 1)) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Iio2PkgcClkGateDis[socket] << (IIO012_PKGC_CLK_GATE_DISABLE_SHIFT + 2)) );
+
+ CsrSapmCtl |= (( SetupData.SocketConfig.PowerManagementConfig.Kti23PkgcClkGateDis[socket] << KTI23_PKGC_CLK_GATE_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Kti01PkgcClkGateDis[socket] << KTI01_PKGC_CLK_GATE_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Kti01pllOffEna[socket] << KTI_PLL_OFF_EN_SHIFT) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Kti23pllOffEna[socket] << (KTI_PLL_OFF_EN_SHIFT + 1) ) );
+
+ CsrSapmCtl |= (( SetupData.SocketConfig.PowerManagementConfig.Mc1PkgcClkGateDis[socket] << MC1_PKGC_CLK_GATE_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Mc0PkgcClkGateDis[socket] << MC0_PKGC_CLK_GATE_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Mc0pllOffEna[socket] << MEM_PLL_OFF_EN_SHIFT) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Mc1pllOffEna[socket] << (MEM_PLL_OFF_EN_SHIFT + 1) ));
+
+ if (SetupData.SocketConfig.MemoryConfig.OppSrefEn == 1) {
+ CsrSapmCtl |= ((1 << MC0_PKGC_IO_VOLTAGE_REDUCTION_DISABLE_SHIFT) | (1 << MC1_PKGC_IO_VOLTAGE_REDUCTION_DISABLE_SHIFT) |
+ (1 << MC0_PKGC_DIG_VOLTAGE_REDUCTION_DISABLE_SHIFT) | (1 << MC1_PKGC_DIG_VOLTAGE_REDUCTION_DISABLE_SHIFT)) ;
+ }
+
+ CsrSapmCtl |= (( SetupData.SocketConfig.PowerManagementConfig.P0pllOffEna[socket] << IIO_PLL_OFF_EN_SHIFT) |
+ ( SetupData.SocketConfig.PowerManagementConfig.P1pllOffEna[socket] << (IIO_PLL_OFF_EN_SHIFT + 1) ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.P2pllOffEna[socket] << (IIO_PLL_OFF_EN_SHIFT + 2) ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.SetvidDecayDisable[socket] << SETVID_DECAY_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.SapmCtlLock[socket] << SAPMCTL_LOCK_SHIFT) );
+
+ ppm->SapmCtl[socket] = CsrSapmCtl;
+ }
+
+ ppm->PmaxConfig = (SetupData.SocketConfig.PowerManagementConfig.UsePmaxOffsetTable ? USER_PMAX_USE_OFFSET_TABLE : 0 ) |
+ SetupData.SocketConfig.PowerManagementConfig.PmaxOffset |
+ (SetupData.SocketConfig.PowerManagementConfig.PmaxSign ? USER_PMAX_NEGATIVE_BIT : 0);
+
+ CsrPerfPlimitCtl = ( SetupData.SocketConfig.PowerManagementConfig.PerfPLmtThshld << PERF_PLIMIT_THRESHOLD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PerfPLimitClipC << PERF_PLIMIT_CLIP_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PerfPlimitDifferential << PERF_PLIMIT_DIFFERENTIAL_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PerfPLimitEn << REPERF_PLIMIT_EN_SHIFT );
+ ppm->PerPLimitCtl = CsrPerfPlimitCtl;
+
+ //
+ // IssConfigTdpLevelInfo Bit[23:16]: the currently active Config TDP Level
+ //
+ ppm->Pst.ConfigTdpLevel = (UINT8) ((mIioUds->SystemStatus.IssConfigTdpLevelInfo >> 16) & 0xFF);
+ ppm->Pst.CurrentPackageTdp = (mIioUds->SystemStatus.IssConfigTdpTdpInfo[0][ppm->Pst.ConfigTdpLevel] & 0x7FFF);
+
+ for( socket = 0; socket < MAX_SOCKET; socket++) {
+ UpiInPkgCEntry[socket] = (SetupData.SocketConfig.PowerManagementConfig.Kti0In[socket] |
+ (SetupData.SocketConfig.PowerManagementConfig.Kti1In[socket] << 1) |
+ (SetupData.SocketConfig.PowerManagementConfig.Kti2In[socket] << 2) );
+
+ if (SetupData.SocketConfig.PowerManagementConfig.PcieIio0In[socket]) {
+ PcieInPkgCEntry[socket] |= SET_PCIEx_MASK;
+ }
+ if (SetupData.SocketConfig.PowerManagementConfig.PcieIio1In[socket]) {
+ PcieInPkgCEntry[socket] |= (SET_PCIEx_MASK << 4);
+ }
+ if (SetupData.SocketConfig.PowerManagementConfig.PcieIio2In[socket]) {
+ PcieInPkgCEntry[socket] |= (SET_PCIEx_MASK << 8);
+ }
+ if (SetupData.SocketConfig.PowerManagementConfig.PcieIio3In[socket]) {
+ PcieInPkgCEntry[socket] |= (SET_PCIEx_MASK << 12);
+ }
+ if (SetupData.SocketConfig.PowerManagementConfig.PcieIio4In[socket]) {
+ PcieInPkgCEntry[socket] |= (SET_PCIEx_MASK << 16);
+ }
+ if (SetupData.SocketConfig.PowerManagementConfig.PcieIio5In[socket]) {
+ PcieInPkgCEntry[socket] |= (SET_PCIEx_MASK << 20);
+ }
+
+ }
+
+ AdvPwrMgtCtl = (SetupData.SocketConfig.PowerManagementConfig.SapmctlValCtl? PCD_CPU_SAPM_CTL_VAL_CTL : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.CurrentConfig? PCD_CPU_CURRENT_CONFIG : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.BootPState? PCU_CPU_EFFICIENT_BOOT : 0) |
+ (SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorMsrLockControl? CPU_MSR_LOCK : 0) |
+ (SetupData.SocketConfig.PowerManagementConfig.TurboPowerLimitCsrLock? TURBO_LIMIT_CSR_LOCK : 0);
+
+ AdvPwrMgtCtl |= SetupData.SocketConfig.PowerManagementConfig.PkgCstEntryValCtl; //PCD_CPU_PKG_CST_ENTRY_VAL_CTL
+
+ if (SetupData.SocketConfig.PowerManagementConfig.ProcessorEistEnable == 0) {
+ AdvPwrMgtCtl |= PCU_CPU_EFFICIENT_BOOT;
+ }
+
+ if (((CpuFamilyModelStepping >> 4) == CPU_FAMILY_HSX) && SetupData.SocketConfig.PowerManagementConfig.PriPlnCurCfgValCtl) {
+ AdvPwrMgtCtl |= PCD_CPU_PRI_PLN_CURR_CFG_CTL;
+ }
+
+ if ((PackageCStateSetting > 0) && SetupData.SocketConfig.PowerManagementConfig.DynamicL1) {
+ AdvPwrMgtCtl |= DYNAMIC_L1_DISABLE;
+ }
+
+ if (SetupData.SocketConfig.PowerManagementConfig.SPTWorkaround) {
+ AdvPwrMgtCtl |= SPT_PCH_WORKAROUND;
+ }
+
+ if (SetupData.SocketConfig.PowerManagementConfig.VccSAandVccIOdisable) {
+ AdvPwrMgtCtl |= VCCSA_VCCIO_DISABLE;
+ }
+ ppm->AdvPwrMgtCtlFlags = AdvPwrMgtCtl;
+
+ // MSR_POWER_CTL 0x1FC
+ MsrPowerCtlLow = ( SetupData.SocketConfig.PowerManagementConfig.PkgCLatNeg << PCH_NEG_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.LTRSwInput << LTR_SW_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PwrPerfTuning << PWR_PERF_TUNING_CFG_MODE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PwrPerfSwitch << PWR_PERF_TUNING_ENABLE_DYN_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.SAPMControl << PWR_PERF_TUNING_DISABLE_SAPM_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.EETurboDisable << EE_TURBO_DISABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.ProchotLock << PROCHOT_LOCK_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.ProcessorC1eEnable << C1E_ENABLE_SHIFT ) |
+ ( (SetupData.SocketConfig.PowerManagementConfig.EnableProcHot & 0x1) << DIS_PROCHOT_OUT_SHIFT ) |
+ ( (SetupData.SocketConfig.PowerManagementConfig.EnableProcHot & 0x2) >> 1 );
+
+ // 5332865 BIOS needs to set bit 25 in MSR 0x1FC when enabling HWP autonomous out of band mode
+ if (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 2) { //if HWPM = OOB Mode
+ MsrPowerCtlLow |= ( 1 << PWR_PERF_TUNING_CFG_MODE_SHIFT );
+ }
+
+ ppm->PowerCtl.Dwords.Low = MsrPowerCtlLow;
+
+ ppm->ProchotRatio = SetupData.SocketConfig.PowerManagementConfig.ProchotResponseRatio;
+
+ if ((CpuFamilyModelStepping >> 4) == CPU_FAMILY_HSX) {
+ // PRIMARY_PLANE_CURRENT_CONFIG_CONTROL 0x601
+ MsrPriPlaneCurrentCfgCtlHigh = ( SetupData.SocketConfig.PowerManagementConfig.Psi3Code << PSI3_CODE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Psi3Thshld << PSI3_THSHLD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Psi2Code << PSI2_CODE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Psi2Thshld << PSI2_THSHLD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Psi1Code << PSI1_CODE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.Psi1Thshld << PSI1_THSHLD_SHIFT );
+ }
+
+ MsrPriPlaneCurrentCfgCtlLow = ( SetupData.SocketConfig.PowerManagementConfig.PpcccLock << PPCCC_LOCK_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.CurrentLimit << CURRENT_LIMIT_SHIFT );
+
+ ppm->PP0CurrentCfg.Dwords.High = MsrPriPlaneCurrentCfgCtlHigh;
+ ppm->PP0CurrentCfg.Dwords.Low = MsrPriPlaneCurrentCfgCtlLow;
+
+ // MSR_TURBO_POWER_LIMIT 0x610
+ // CSR_TURBO_POWER_LIMIT 1:30:0:0xe8
+ MsrTurboPowerLimitHigh = ( SetupData.SocketConfig.PowerManagementConfig.TurboPowerLimitLock << POWER_LIMIT_LOCK_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PowerLimit2En << POWER_LIMIT_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PkgClmpLim2 << PKG_CLMP_LIM_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PowerLimit2Power );
+
+ MsrTurboPowerLimitLow = ( SetupData.SocketConfig.PowerManagementConfig.PowerLimit1Time << POWER_LIMIT_1_TIME_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PowerLimit1En << POWER_LIMIT_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.PowerLimit1Power );
+
+ if ((CpuFamilyModelStepping >> 4) == CPU_FAMILY_HSX) {
+ MsrTurboPowerLimitLow |= ( SetupData.SocketConfig.PowerManagementConfig.PkgClmpLim1 << PKG_CLMP_LIM_SHIFT );
+ MsrTurboPowerLimitHigh |= ( SetupData.SocketConfig.PowerManagementConfig.PkgClmpLim2 << PKG_CLMP_LIM_SHIFT );
+ }
+
+ if ((CpuFamilyModelStepping >> 4) == CPU_FAMILY_SKX) {
+ MsrTurboPowerLimitHigh |= ( SetupData.SocketConfig.PowerManagementConfig.PowerLimit2Time << POWER_LIMIT_1_TIME_SHIFT );
+ }
+
+ ppm->TurboPowerLimit.Dwords.Low = MsrTurboPowerLimitLow;
+ ppm->TurboPowerLimit.Dwords.High = MsrTurboPowerLimitHigh;
+
+ // DYNAMIC_PERF_POWER_CTL (CSR 1:30:2:0x64)
+ CsrDynamicPerfPowerCtl = ( SetupData.SocketConfig.PowerManagementConfig.UncrPerfPlmtOvrdEn << UNCORE_PERF_PLIMIT_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.EetOverrideEn << EET_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.IoBwPlmtOvrdEn << IO_BW_PLIMIT_OVERRIDE_ENABLE_SHIFT ) |
+ //( SetupData.SocketConfig.PowerManagementConfig.ImcApmOvrdEn << IMC_APM_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.IomApmOvrdEn << IOM_APM_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.QpiApmOvrdEn << QPI_APM_OVERRIDE_ENABLE_SHIFT ); //4986218: Remove both changes from 4168487
+
+ if((CpuFamilyModelStepping >> 4) == CPU_FAMILY_HSX) {
+ CsrDynamicPerfPowerCtl |= (( SetupData.SocketConfig.PowerManagementConfig.EepLOverride << EEP_L_OVERRIDE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.EepLOverrideEn << EEP_L_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.ITurboOvrdEn << I_TURBO_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.CstDemotOvrdEN << CST_DEMOTION_OVERRIDE_ENABLE_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.TrboDemotOvrdEn << TURBO_DEMOTION_OVERRIDE_ENABLE_SHIFT ));
+ }
+
+ ppm->DynamicPerPowerCtl = CsrDynamicPerfPowerCtl;
+
+ // CSR_PCIE_ILTR_OVRD (CSR 1:30:1:78)
+ // SW_LTR_OVRD (MSR 0xa02) -- not used
+ CsrPcieIltrOvrd = ( SetupData.SocketConfig.PowerManagementConfig.SnpLatVld << SNOOP_LATENCY_VLD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.SnpLatOvrd << FORCE_SNOOP_OVRD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.SnpLatMult << SNOOP_LATENCY_MUL_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.SnpLatVal << SNOOP_LATENCY_Value_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.NonSnpLatVld << NON_SNOOP_LATENCY_VLD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.NonSnpLatOvrd << FORCE_NON_SNOOP_OVRD_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.NonSnpLatMult << NON_SNOOP_LATENCY_MUL_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.NonSnpLatVal << NON_SNOOP_LATENCY_Value_SHIFT );
+
+ ppm-> PcieIltrOvrd = CsrPcieIltrOvrd;
+
+ if((CpuFamilyModelStepping >> 4) == CPU_FAMILY_SKX) { //Need to check if programming needs to be limited only if Turbo mode is enabled.
+ for(i = 0; i < 8; i++) {
+ TurboRatioLimitRatioCores->RatioLimitRatio[i] = SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitRatio[i];
+
+ TurboRatioLimitRatioCores->RatioLimitRatioMask[i] = 0xFF;
+ if (SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitRatio[i] > 0) {
+ TurboRatioLimitRatioCores->RatioLimitRatioMask[i] = 0;
+ }
+
+ TurboRatioLimitRatioCores->RatioLimitCoresMask[i] = 0xFF;
+ TurboRatioLimitRatioCores->RatioLimitCores[i] = 0;
+ if (SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitCores[i] != 0xFF) {
+ TurboRatioLimitRatioCores->RatioLimitCoresMask[i] = 0;
+ TurboRatioLimitRatioCores->RatioLimitCores[i] = SetupData.SocketConfig.PowerManagementConfig.TurboRatioLimitCores[i];
+ }
+ }
+ }
+
+ MsrPerfBiasConfig = ( SetupData.SocketConfig.PowerManagementConfig.EngAvgTimeWdw1 << AVG_TIME_Window_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.P0TtlTimeLow1 << PO_TOTAL_TIME_THSHLD_LOW_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.P0TtlTimeHigh1 << PO_TOTAL_TIME_THSHLD_HIGH_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.AltEngPerfBIAS << ALT_ENERGY_PERF_BIAS_SHIFT) |
+ ( SetupData.SocketConfig.PowerManagementConfig.WorkLdConfig << WORKLD_CONFIG_SHIFT );
+
+ ppm->PerfBiasConfig.Dwords.Low = MsrPerfBiasConfig;
+
+ //
+ //ProcessorHWPM-init as disabled.
+ //
+ ppm->Hwpm.HWPMNative = 0;
+ ppm->Hwpm.HWPMOOB = 0;
+ ppm->Hwpm.HWPMEnable = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable;
+ ppm->Hwpm.AutoCState = SetupData.SocketConfig.PowerManagementConfig.ProcessorAutonomousCstateEnable;
+ ppm->Hwpm.HWPMInterrupt = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMInterrupt;
+ ppm->Hwpm.EPPEnable = SetupData.SocketConfig.PowerManagementConfig.ProcessorEPPEnable;
+ ppm->Hwpm.EPPProfile = SetupData.SocketConfig.PowerManagementConfig.ProcessorEppProfile;
+
+ if ((SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 1) ||
+ (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 3)) {
+ ppm->Hwpm.HWPMNative = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable;
+ }else if (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 2){
+ ppm->Hwpm.HWPMOOB = SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable;
+ ppm->Hwpm.HWPMInterrupt = 0;
+ }else if (SetupData.SocketConfig.PowerManagementConfig.ProcessorHWPMEnable == 0){
+ ppm->Hwpm.HWPMNative = 0;
+ ppm->Hwpm.HWPMOOB = 0;
+ ppm->Hwpm.HWPMInterrupt = 0;
+ ppm->Hwpm.EPPEnable = 0;
+ }
+
+ ppm->Hwpm.APSrocketing = SetupData.SocketConfig.PowerManagementConfig.ProcessorAPSrocketing;
+ ppm->Hwpm.Scalability = SetupData.SocketConfig.PowerManagementConfig.ProcessorScalability;
+ ppm->Hwpm.OutofBandAlternateEPB = SetupData.SocketConfig.PowerManagementConfig.ProcessorOutofBandAlternateEPB;
+
+ if(SetupData.SocketConfig.SocketProcessorCoreConfiguration.ProcessorX2apic && SetupData.SocketConfig.SocketProcessorCoreConfiguration.ForceX2ApicIds &&
+ (CpuPolicyEx1 & PCD_CPU_X2APIC_BIT)) { //if user want to reprogram > 8bit ApicId (must be X2Apic too)
+ CheckAndReAssignSocketId();
+ }
+
+ for(i = 0; i < NUM_CST_LAT_MSR; i++) { //3 CStateLatencyCtrl CSRs
+ ppm->Cst.LatencyCtrl[i].Dwords.Low = ( SetupData.SocketConfig.PowerManagementConfig.CStateLatencyCtrlValid[i] << VALID_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.CStateLatencyCtrlMultiplier[i] << MULTIPLIER_SHIFT ) |
+ ( SetupData.SocketConfig.PowerManagementConfig.CStateLatencyCtrlValue[i] << VALUE_SHIFT );
+ }
+
+ if(SetupData.SocketConfig.PowerManagementConfig.C2C3TT) { //if option is not AUTO
+ ppm->C2C3TT = (UINT32)SetupData.SocketConfig.PowerManagementConfig.C2C3TT;
+ } else {
+ ppm->C2C3TT = 0x10;
+ }
+
+ } //end - else
+
+ CpuPolicy |= PCD_CPU_L3_CACHE_BIT;
+
+ Status = PcdSet32S (PcdCpuProcessorFeatureUserConfiguration, CpuPolicy);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = PcdSet32S (PcdCpuProcessorFeatureUserConfigurationEx1, CpuPolicyEx1);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ if (SetupData.SystemConfig.McBankWarmBootClearError == 1) {
+ Status = PcdSetBoolS (PcdIsPowerOnReset, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdIsPowerOnReset, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ //
+ // Cpu Driver could be dispatched after this protocol installed.
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gIntelCpuPcdsSetDoneProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.inf b/Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.inf
new file mode 100644
index 0000000000..dce03194e2
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/PlatformCpuPolicy/PlatformCpuPolicy.inf
@@ -0,0 +1,80 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformCpuPolicy
+ FILE_GUID = 76A7B4FC-C8D5-462d-A4D2-6E88338A772A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformCpuPolicyEntryPoint
+
+[Sources]
+ PlatformCpuPolicy.c
+
+[Packages]
+ UefiCpuPkg/UefiCpuPkg.dec
+ MdePkg/MdePkg.dec
+ PurleyOpenBoardPkg/OpenBoardPkg.dec
+ PurleyRefreshSiliconPkg/SiPkg.dec
+ PurleyRefreshSiliconPkg/Override/IA32FamilyCpuPkg/IA32FamilyCpuPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ PcdLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ HobLib
+ IoLib
+
+[Protocols]
+ gIntelCpuPcdsSetDoneProtocolGuid
+
+[Pcd]
+ gEfiCpuTokenSpaceGuid.PcdCpuProcessorFeatureUserConfiguration
+ gEfiCpuTokenSpaceGuid.PcdCpuProcessorFeatureUserConfigurationEx1
+ gEfiCpuTokenSpaceGuid.PcdCpuEnergyPolicy
+ gEfiCpuTokenSpaceGuid.PcdCpuAcpiLvl2Addr
+ gEfiCpuTokenSpaceGuid.PcdCpuPackageCStateLimit
+ gEfiCpuTokenSpaceGuid.PcdCpuCoreCStateValue
+ gEfiCpuTokenSpaceGuid.PcdCpuClockModulationDutyCycle
+ gEfiCpuTokenSpaceGuid.PcdCpuHwCoordination
+ gEfiCpuTokenSpaceGuid.PcdPlatformCpuSocketCount
+ gEfiCpuTokenSpaceGuid.PcdPlatformCpuSocketNames
+ gEfiCpuTokenSpaceGuid.PcdPlatformCpuAssetTags
+ gEfiCpuTokenSpaceGuid.PcdIsPowerOnReset
+ gEfiCpuTokenSpaceGuid.PcdCpuDcuMode
+ gEfiCpuTokenSpaceGuid.PcdCpuTurboOverride
+ gEfiCpuTokenSpaceGuid.PcdCpuProcessorMsrLockCtrl
+ gEfiCpuTokenSpaceGuid.PcdCpuIioLlcWaysBitMask
+ gEfiCpuTokenSpaceGuid.PcdCpuExpandedIioLlcWaysBitMask
+ gEfiCpuTokenSpaceGuid.PcdPchTraceHubEn
+ gEfiCpuTokenSpaceGuid.PcdCpuQlruCfgBitMask
+ gEfiCpuTokenSpaceGuid.PcdSbspSelection
+ gEfiCpuTokenSpaceGuid.PcdCpuPmStructAddr
+ gEfiCpuTokenSpaceGuid.PcdCpuSocketId
+ gEfiPchTokenSpaceGuid.PcdPchAcpiIoPortBaseAddress
+ gEfiCpuTokenSpaceGuid.PcdCpuRemoteWaysBitMask
+ gEfiCpuTokenSpaceGuid.PcdCpuRRQCountThreshold
+ gEfiCpuTokenSpaceGuid.PcdCpuSmmRuntimeCtlHooks
+ gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+ gOemSkuTokenSpaceGuid.PcdSetupData
+ gOemSkuTokenSpaceGuid.PcdPchRcConfigurationData
+ gOemSkuTokenSpaceGuid.PcdSocketIioConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketCommonRcConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketMpLinkConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketMemoryConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketPowerManagementConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketProcessorCoreConfigData
+
+[Depex]
+ gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.c
new file mode 100644
index 0000000000..158b19c169
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.c
@@ -0,0 +1,256 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "S3NvramSave.h"
+#include <Protocol/Decompress.h>
+#include <Library/CompressLib.h>
+#include <Protocol/VariableLock.h>
+
+/**
+
+ This function will retrieve the S3 data from HOBs produced by MRC
+ and will save it to NVRAM if the data is absent or different from
+ the previously saved data.
+
+ @param VOID
+
+ @retval VOID
+
+**/
+VOID
+SaveS3StructToNvram (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UINTN CurrentHobSize;
+ UINTN S3ChunkSize;
+ CHAR16 EfiMemoryConfigVariable[] = L"MemoryConfig0";
+ EFI_HOB_GUID_TYPE *GuidHob = NULL;
+ VOID *HobData = NULL;
+ VOID *VariableData = NULL;
+
+ UINTN CompressedDataSize;
+ UINT32 ScratchSize;
+ VOID *CompressedData = NULL;
+ VOID *Scratch = NULL;
+ EFI_DECOMPRESS_PROTOCOL *Decompress = NULL;
+ VOID *CompressedVariableData = NULL;
+ UINTN CompressedBufferSize;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock = NULL;
+
+ //
+ // Get first S3 data HOB
+ //
+ GuidHob = GetFirstGuidHob (&gEfiMemoryConfigDataHobGuid);
+
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
+ DEBUG((DEBUG_INFO, "[SaveMemoryConfigEntryPoint] Locate Decompress protocol - %r\n", Status));
+ if(EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return;
+ }
+
+ Status = gBS->LocateProtocol(&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);
+ DEBUG((DEBUG_INFO, "[SaveMemoryConfigEntryPoint] Locate Variable Lock protocol - %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ while (TRUE) {
+ if (GuidHob == NULL) {
+ break;
+ }
+ HobData = GET_GUID_HOB_DATA(GuidHob);
+ CurrentHobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
+
+ DEBUG((EFI_D_INFO, " Current Hob Size(bytes) is: %d\n", CurrentHobSize));
+ //
+ // Use the HOB data to save Memory Configuration Data
+ //
+ BufferSize = CurrentHobSize;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ BufferSize,
+ (VOID**)&VariableData
+ );
+
+ ASSERT (VariableData != NULL);
+ S3ChunkSize = MAX_HOB_ENTRY_SIZE / 8;
+ DEBUG((EFI_D_INFO, " S3ChunkSize Hob Size(bytes): %d\n", S3ChunkSize));
+
+ while (CurrentHobSize) {
+ if (S3ChunkSize > CurrentHobSize) {
+ S3ChunkSize = CurrentHobSize;
+ }
+ BufferSize = S3ChunkSize;
+ CompressedDataSize = 0;
+ ScratchSize = 0;
+ Status = gRT->GetVariable (
+ EfiMemoryConfigVariable,
+ &gEfiMemoryConfigDataGuid,
+ NULL,
+ &CompressedDataSize,
+ NULL
+ );
+
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ CompressedDataSize,
+ (VOID**)&CompressedData
+ );
+ ASSERT (Status == EFI_SUCCESS);
+ }
+
+ if(!EFI_ERROR (Status))
+ {
+ Status = gRT->GetVariable (
+ EfiMemoryConfigVariable,
+ &gEfiMemoryConfigDataGuid,
+ NULL,
+ &CompressedDataSize,
+ CompressedData
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = Decompress->GetInfo (
+ Decompress,
+ CompressedData,
+ (UINT32)CompressedDataSize,
+ (UINT32*)&BufferSize,
+ &ScratchSize
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ ScratchSize,
+ (VOID**)&Scratch
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = Decompress->Decompress (
+ Decompress,
+ CompressedData,
+ (UINT32)CompressedDataSize,
+ VariableData,
+ (UINT32)BufferSize,
+ Scratch,
+ ScratchSize
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "Getting variables error: 0x%x\n", Status));
+ ASSERT (Status == EFI_SUCCESS);
+ }
+
+ if(Scratch != NULL) {
+ gBS->FreePool (Scratch);
+ Scratch = NULL;
+ }
+ }
+
+ if(CompressedData != NULL) {
+ gBS->FreePool (CompressedData);
+ CompressedData = NULL;
+ }
+
+ if ( (EFI_ERROR(Status)) || (CompareMem (HobData, VariableData, S3ChunkSize) != 0) ) {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ BufferSize,
+ (VOID**)&CompressedVariableData
+ );
+ ASSERT (CompressedVariableData != NULL);
+ if (Status == EFI_SUCCESS) {
+ CompressedBufferSize = BufferSize;
+ Status = Compress(HobData, S3ChunkSize, CompressedVariableData, &CompressedBufferSize);
+ if (Status == EFI_BUFFER_TOO_SMALL){
+ gBS->FreePool(CompressedVariableData);
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ CompressedBufferSize,
+ (VOID**)&CompressedVariableData
+ );
+ ASSERT (CompressedVariableData != NULL);
+ Status = Compress(HobData, S3ChunkSize, CompressedVariableData, &CompressedBufferSize);
+ }
+ if(Status == EFI_SUCCESS) {
+ Status = gRT->SetVariable (
+ EfiMemoryConfigVariable,
+ &gEfiMemoryConfigDataGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ CompressedBufferSize,
+ CompressedVariableData
+ );
+ }
+ if(CompressedVariableData != NULL) {
+ gBS->FreePool(CompressedVariableData);
+ CompressedVariableData = NULL;
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "Set variable error. Status: 0x%x\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ //
+ // Lock the Memory Config Variable
+ //
+ Status = VariableLock->RequestToLock(VariableLock, EfiMemoryConfigVariable, &gEfiMemoryConfigDataGuid);
+ ASSERT_EFI_ERROR(Status);
+ HobData = (UINT8 *) (HobData) + S3ChunkSize;
+
+ CurrentHobSize -= S3ChunkSize;
+ EfiMemoryConfigVariable[12]++; // Increment number in the string
+ }
+ //
+ // Get next S3 Config data hob, if none left, results NULL
+ //
+ GuidHob = GET_NEXT_HOB (GuidHob); // Increment to next HOB
+ GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataHobGuid, GuidHob); // Now search for next MemConfig HOB
+
+ if(VariableData != NULL) {
+ gBS->FreePool(VariableData);
+ VariableData = NULL;
+ }
+ }
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+S3NvramSaveEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/**
+
+ This is the main entry point of the S3 NVRAM Save module.
+
+ @param ImageHandle - Handle for the image of this driver.
+ @param SystemTable - Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS - Module launched successfully.
+
+**/
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ //
+ // Save the s3 strututre from MRC into NVRAM if needed
+ //
+ SaveS3StructToNvram();
+
+ return Status;
+
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.h b/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.h
new file mode 100644
index 0000000000..ad8efe572a
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.h
@@ -0,0 +1,31 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include "SysHost.h"
+
+extern EFI_GUID gEfiMemoryConfigDataHobGuid;
+extern EFI_GUID gEfiMemoryConfigDataGuid;
+
+#define MAX_HOB_ENTRY_SIZE 60*1024
+
+EFI_STATUS
+EFIAPI
+S3NvramSaveEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+VOID
+SaveS3StructToNvram (
+ VOID
+);
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.inf b/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.inf
new file mode 100644
index 0000000000..0376b38bb1
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/S3NvramSave/S3NvramSave.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = S3NvramSave
+ FILE_GUID = 62DC08AC-A651-4EE9-AF81-EAA9261E9780
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = S3NvramSaveEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ S3NvramSave.h
+ S3NvramSave.c
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ MemoryAllocationLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ HobLib
+ BaseMemoryLib
+ CompressLib
+
+[Protocols]
+ gEfiDecompressProtocolGuid
+ gEdkiiVariableLockProtocolGuid
+
+[Guids]
+ gEfiMemoryConfigDataGuid
+ gEfiMemoryConfigDataHobGuid
+
+[FixedPcd]
+ gEfiCpRcPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ PurleyOpenBoardPkg/OpenBoardPkg.dec
+ PurleyRefreshSiliconPkg/SiPkg.dec
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiDecompressProtocolGuid AND
+ gEdkiiVariableLockProtocolGuid
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c
new file mode 100644
index 0000000000..6b9efae0f6
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardCommon.c
@@ -0,0 +1,625 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Platform.h>
+#include <Register/PchRegsUsb.h>
+#include <PchLimits.h>
+#include <PchPolicyCommon.h>
+#include <IioBifurcationSlotTable.h>
+
+VOID
+SetBifurcations(
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_BIFURCATION_ENTRY *BifurcationTable,
+ IN UINT8 BifurcationEntries
+)
+{
+ UINT8 Socket;
+ UINT8 Iou;
+ UINT8 Index;
+
+ for (Index = 0; Index < BifurcationEntries ; Index++) {
+ Socket = BifurcationTable[Index].Socket;
+ Iou = BifurcationTable[Index].IouNumber;
+ switch (Iou) {
+ case Iio_Iou0:
+ if (IioGlobalData->SetupData.ConfigIOU0[Socket]==IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigIOU0[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Iou1:
+ if (IioGlobalData->SetupData.ConfigIOU1[Socket] == IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigIOU1[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Iou2:
+ if (IioGlobalData->SetupData.ConfigIOU2[Socket]==IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigIOU2[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Mcp0:
+ if (IioGlobalData->SetupData.ConfigMCP0[Socket] == IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigMCP0[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ case Iio_Mcp1:
+ if (IioGlobalData->SetupData.ConfigMCP1[Socket] == IIO_BIFURCATE_AUTO) {
+ IioGlobalData->SetupData.ConfigMCP1[Socket] = BifurcationTable[Index].Bifurcation;
+ }
+ break;
+ default:
+ DEBUG((EFI_D_ERROR, "Invalid bifurcation table: Bad Iou (%d)", Iou));
+ ASSERT(Iou);
+ break;
+ }
+ }
+}
+
+VOID
+EnableHotPlug (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN UINT8 Port,
+ IN UINT8 VppPort,
+ IN UINT8 VppAddress,
+ IN UINT8 PortOwnership
+ )
+{
+ IioGlobalData->SetupData.SLOTHPCAP[Port]= ENABLE;
+ IioGlobalData->SetupData.SLOTAIP[Port] = ENABLE; // Attention Indicator Present
+ IioGlobalData->SetupData.SLOTPIP[Port] = ENABLE; // Power Indicator Present
+ IioGlobalData->SetupData.SLOTMRLSP[Port]= ENABLE; // MRL Sensor Present
+ IioGlobalData->SetupData.SLOTABP[Port] = ENABLE; // Attention Button Present
+ IioGlobalData->SetupData.SLOTPCP[Port] = ENABLE; // Power Controlled Present
+
+ if (PortOwnership == PCIEAIC_OCL_OWNERSHIP){
+ IioGlobalData->SetupData.SLOTAIP[Port] = DISABLE; // Attention Indicator Present
+ IioGlobalData->SetupData.SLOTPIP[Port] = DISABLE; // Power Indicator Present
+ }
+ if (PortOwnership == VMD_OWNERSHIP){
+ IioGlobalData->SetupData.SLOTABP[Port] = DISABLE;
+ IioGlobalData->SetupData.SLOTPCP[Port] = DISABLE;
+ IioGlobalData->SetupData.SLOTMRLSP[Port]= DISABLE;
+ }
+ //
+ // Set SLTCAP settings based on VMD/PCIe SSD Ownership
+ //
+ if ((PortOwnership == PCIEAIC_OCL_OWNERSHIP) ||
+ (PortOwnership == VMD_OWNERSHIP)){
+ IioGlobalData->SetupData.SLOTHPSUP[Port]= ENABLE; // HotPlug Surprise
+ }
+
+ if (VppPort!= VPP_PORT_MAX) {
+ IioGlobalData->SetupData.VppEnable[Port]= ENABLE;
+ IioGlobalData->SetupData.VppPort[Port]= VppPort;
+ IioGlobalData->SetupData.VppAddress[Port] = VppAddress;
+ } else {
+ DEBUG((EFI_D_ERROR, "PCIE HOT Plug. Missing VPP values on slot table\n"));
+ }
+}
+
+VOID
+ConfigSlots (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_SLOT_CONFIG_ENTRY *Slot,
+ IN UINT8 SlotEntries
+ )
+{
+ UINT8 Index;
+ UINT8 Port;
+
+ for (Index =0; Index < SlotEntries; Index ++) {
+ Port=Slot[Index].PortIndex;
+ if (Slot[Index].Hidden != NOT_HIDE) {
+ IioGlobalData->SetupData.HidePEXPMenu[Port] = HIDE;
+ IioGlobalData->SetupData.PEXPHIDE[Port]= HIDE;
+ }
+ /// Check if slot is assigned.
+ if (Slot[Index].SlotNumber!= NO_SLT_IMP){
+ IioGlobalData->SetupData.SLOTIMP[Port]= SLT_IMP;
+ IioGlobalData->SetupData.SLOTPSP[Port]=Slot[Index].SlotNumber;
+ IioGlobalData->SetupData.SLOTEIP[Port]=Slot[Index].InterLockPresent;
+ if (Slot[Index].SlotPowerLimitScale!= PWR_SCL_MAX) {
+ IioGlobalData->SetupData.SLOTSPLS[Port] = Slot[Index].SlotPowerLimitScale;
+ IioGlobalData->SetupData.SLOTSPLV[Port] = Slot[Index].SlotPowerLimitValue;
+ }
+ if (Slot[Index].HotPlugCapable != DISABLE) {
+ EnableHotPlug(IioGlobalData, Port, Slot[Index].VppPort, Slot[Index].VppAddress, REGULAR_PCIE_OWNERSHIP);
+ }
+ }
+ }
+}
+
+/**
+ Verify if and Slot should be implemented based on IOUX bifurcation settings.
+
+ @param IioGlobalData Pointer to Iio Globals.
+ @param Port - Port Index
+
+ @retval TRUE/FALSE to determine if an slot shoudl be implemented or not
+ based on the IOUX bifurcation settings in case user want to do an
+ override and VMD is enabled.
+
+**/
+BOOLEAN
+SlotImplemented(
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN UINT8 Port
+ ){
+ UINT8 IioIndex;
+ UINT8 PortIndex;
+ UINT8 Stack;
+ BOOLEAN SlotImp = FALSE;
+
+ IioIndex = Port/NUMBER_PORTS_PER_SOCKET;
+ PortIndex = (Port - (NUMBER_PORTS_PER_SOCKET * IioIndex));
+ // Stack = (((PortIndex + 3)/4) - 1) + (IioIndex*VMD_STACK_PER_SOCKET);
+ Stack = IioGlobalData->IioVar.IioVData.StackPerPort[IioIndex][PortIndex];
+ DEBUG((DEBUG_INFO, "SlotImplemented:IioIndex = %x, Stack = %x, Port = %x, PortIndex =%x\n", IioIndex, Stack, Port, PortIndex));
+
+ switch(Stack){
+ case IIO_PSTACK0:
+ if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_x4x4x4x4){
+ SlotImp = TRUE;
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_x4x4xxx8){
+ if ((PortIndex == PORT_1D_INDEX) || (PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_xxx8x4x4){
+ if ((PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1B_INDEX) || (PortIndex == PORT_1A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_xxx8xxx8){
+ if ((PortIndex == PORT_1C_INDEX) || (PortIndex == PORT_1A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU0[IioIndex] == IIO_BIFURCATE_xxxxxx16){
+ if (PortIndex == PORT_1A_INDEX){
+ SlotImp = TRUE;
+ }
+ }
+ break;
+ case IIO_PSTACK1:
+ if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_x4x4x4x4){
+ SlotImp = TRUE;
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_x4x4xxx8){
+ if ((PortIndex == PORT_2D_INDEX) || (PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_xxx8x4x4){
+ if ((PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2B_INDEX) || (PortIndex == PORT_2A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_xxx8xxx8){
+ if ((PortIndex == PORT_2C_INDEX) || (PortIndex == PORT_2A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU1[IioIndex] == IIO_BIFURCATE_xxxxxx16){
+ if (PortIndex == PORT_2A_INDEX){
+ SlotImp = TRUE;
+ }
+ }
+ break;
+ case IIO_PSTACK2:
+ if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_x4x4x4x4){
+ SlotImp = TRUE;
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_x4x4xxx8){
+ if ((PortIndex == PORT_3D_INDEX) || (PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_xxx8x4x4){
+ if ((PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3B_INDEX) || (PortIndex == PORT_3A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_xxx8xxx8){
+ if ((PortIndex == PORT_3C_INDEX) || (PortIndex == PORT_3A_INDEX)){
+ SlotImp = TRUE;
+ }
+ } else if (IioGlobalData->SetupData.ConfigIOU2[IioIndex] == IIO_BIFURCATE_xxxxxx16){
+ if (PortIndex == PORT_3A_INDEX){
+ SlotImp = TRUE;
+ }
+ }
+ break;
+ }
+ DEBUG((DEBUG_INFO, "SlotImplemented: = %x\n", SlotImp));
+ return SlotImp;
+}
+
+/**
+ Verify if VMD is enabled and override Slot conofgiration
+ based on the VMD settings
+
+ @param IioGlobalData Pointer to Iio Globals.
+ @param Slot - Slot configuarion settings
+ @param SlotEntries - Number of slot entries
+
+ @retval None
+
+**/
+VOID
+OverrideConfigSlots (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_SLOT_CONFIG_ENTRY *Slot,
+ IN UINT8 SlotEntries
+ )
+{
+ UINT8 Index;
+ UINT8 Port;
+ UINT8 IioIndex;
+ UINT8 VmdPort;
+ UINT8 Stack;
+
+ for (Index =0; Index < SlotEntries; Index ++) {
+ Port = Slot[Index].PortIndex;
+ //
+ // Check if Slot is capable of PcieSSD Solution and override the SLOT Config values
+ //
+ if (Slot[Index].PcieSSDCapable){
+ IioIndex = Port/NUMBER_PORTS_PER_SOCKET;
+ Stack = ((((Port - (NUMBER_PORTS_PER_SOCKET * IioIndex))+ 3)/4) - 1) + (IioIndex*VMD_STACK_PER_SOCKET);
+ DEBUG((DEBUG_INFO, "Stack = %x, Port = %x\n", Stack, Port));
+
+ //
+ // check if VMD will own Pcie Root Port
+ //
+ if(IioGlobalData->SetupData.VMDEnabled[Stack]){
+ VmdPort = ((IioIndex * VMD_PORTS_PER_SOCKET) + (Port - (NUMBER_PORTS_PER_SOCKET * IioIndex))) - 1;
+ if (IioGlobalData->SetupData.VMDPortEnable[VmdPort]){
+ IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] = VMD_OWNERSHIP;
+ }
+ } else {
+
+ DEBUG((DEBUG_INFO, "IioGlobalData->SetupData.PcieAICEnabled[%x] = %x\n",Stack, IioGlobalData->SetupData.PcieAICEnabled[Stack]));
+ //
+ // Check if Pcie AIC Card will be present on Pcie Root Port
+ //
+ if(IioGlobalData->SetupData.PcieAICEnabled[Stack]){
+ //
+ // Force to have this port enabled by default for hot-plug.
+ //
+ IioGlobalData->SetupData.PciePortDisable[(IioIndex * NUMBER_PORTS_PER_SOCKET) + Port] = ENABLE;
+ IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] = PCIEAIC_OCL_OWNERSHIP;
+ DEBUG((DEBUG_ERROR, "Port = %x, PciePortDisable = %x\n",Port,IioGlobalData->SetupData.PciePortDisable[(IioIndex * NUMBER_PORTS_PER_SOCKET) + Port]));
+ }
+ } // No _VMD Ownership
+
+ DEBUG((DEBUG_INFO, "PciePortOwnerShip[%x] = %x\n",Port, IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port]));
+
+ // if PcieSSDSupport required do slot override settings accordingly
+ if((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] != REGULAR_PCIE_OWNERSHIP) &&
+ (SlotImplemented(IioGlobalData, Port) == TRUE)){
+ IioGlobalData->SetupData.SLOTIMP[Port]= SLT_IMP;
+ IioGlobalData->SetupData.SLOTPSP[Port]= 0x50 + Port; // Just program a value for PCIEACI_OCL/VMD
+ IioGlobalData->SetupData.SLOTEIP[Port]= DISABLE;
+
+ if (Slot[Index].SlotPowerLimitScale!= PWR_SCL_MAX) {
+ IioGlobalData->SetupData.SLOTSPLS[Port] = Slot[Index].SlotPowerLimitScale;
+ IioGlobalData->SetupData.SLOTSPLV[Port] = Slot[Index].SlotPowerLimitValue;
+ }
+ DEBUG((DEBUG_INFO,"Slot[Index].PcieSSDVppPort = %x\n", Slot[Index].PcieSSDVppPort));
+ // Enable hot-plug if slot/port supports it
+ if (Slot[Index].PcieSSDVppPort != VPP_PORT_MAX) {
+ DEBUG((DEBUG_INFO, "IioGlobalData->SetupData.VMDHotPlugEnable[%x] = %x\n",Stack,IioGlobalData->SetupData.VMDHotPlugEnable[Stack]));
+ DEBUG((DEBUG_INFO, "IioGlobalData->SetupData.PcieAICHotPlugEnable[%x] = %x\n",Stack,IioGlobalData->SetupData.PcieAICHotPlugEnable[Stack]));
+ // Check if hot-plug is enabled for VMD or PCIeAIC case.
+ if (((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] == VMD_OWNERSHIP) && (IioGlobalData->SetupData.VMDHotPlugEnable[Stack])) ||
+ ((IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port] == PCIEAIC_OCL_OWNERSHIP) && (IioGlobalData->SetupData.PcieAICHotPlugEnable[Stack]))) {
+ EnableHotPlug(IioGlobalData, Port, Slot[Index].PcieSSDVppPort, Slot[Index].PcieSSDVppAddress, IioGlobalData->IioVar.IioOutData.PciePortOwnership[Port]);
+ DEBUG((DEBUG_INFO,"Enable HotPlug Done\n"));
+ }
+ }
+ //
+ // Unhide the port in order to get configured and it will be hide later for VMDLateSetup if VMD own the Pcie Root Port
+ //
+ IioGlobalData->SetupData.PEXPHIDE[Port]= NOT_HIDE;
+ }// PcieSSDSupport
+ }// PcieSSDCapable
+ }// Per Slot
+}
+
+
+/**
+ Auto determine which PCIe Root port to be hidden if its
+ lanes are assigned to its preceding root port...use the
+ Setup option variable of ConfigIOU to determine which ports
+ are to be hidden on each IOU for corresponding IIO
+
+ @param IOUx - IOUx Index
+ @param IioIndex - Index to Iio
+ @param IioGlobalData Pointer to Iio Globals.
+
+ @retval None
+
+**/
+VOID
+CalculatePEXPHideFromIouBif (
+ IN UINT8 Iou,
+ IN UINT8 IioIndex,
+ IN OUT IIO_GLOBALS *IioGlobalData
+)
+{
+
+ UINT8 *PXPHide, *HidePEXPMenu;
+ UINT8 CurrentIOUConfigValue;
+ UINT8 PXPOffset;
+ PXPHide = IioGlobalData->SetupData.PEXPHIDE;
+ HidePEXPMenu = IioGlobalData->SetupData.HidePEXPMenu;
+ CurrentIOUConfigValue =0;
+
+ PXPOffset=IioIndex * NUMBER_PORTS_PER_SOCKET;
+
+ switch (Iou) {
+ case Iio_Iou0:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU0[IioIndex];
+ PXPOffset+= PORT_1A_INDEX;
+ break;
+ case Iio_Iou1:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU1[IioIndex];
+ PXPOffset+= PORT_2A_INDEX;
+ break;
+ case Iio_Iou2:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigIOU2[IioIndex];
+ PXPOffset+= PORT_3A_INDEX;
+ break;
+ case Iio_Mcp0:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigMCP0[IioIndex];
+ PXPOffset+= PORT_4A_INDEX;
+ break;
+ case Iio_Mcp1:
+ CurrentIOUConfigValue = IioGlobalData->SetupData.ConfigMCP1[IioIndex];
+ PXPOffset += PORT_5A_INDEX;
+ break;
+ }
+
+ switch(CurrentIOUConfigValue){
+ case IIO_BIFURCATE_xxxxxxxx:
+ PXPHide[PXPOffset + Iio_PortA] = HIDE; // hide A
+ PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B
+ PXPHide[PXPOffset + Iio_PortC] = HIDE; // hide C
+ PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide D
+ HidePEXPMenu[PXPOffset + Iio_PortA] = HIDE; // hide the Setup menu for A
+ HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortC] = HIDE; // hide the Setup menu for C
+ HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D
+ break;
+ case IIO_BIFURCATE_x4x4xxx8:
+ PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A
+ PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B
+ PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C
+ PXPHide[PXPOffset + Iio_PortD] = NOT_HIDE; // show D
+ HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for D
+ HidePEXPMenu[PXPOffset + Iio_PortD] = NOT_HIDE; // show the Setup menu for B
+ break;
+ case IIO_BIFURCATE_xxx8x4x4:
+ PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A
+ PXPHide[PXPOffset + Iio_PortB] = NOT_HIDE; // show B
+ PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C
+ PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide port D
+ HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A
+ HidePEXPMenu[PXPOffset + Iio_PortB] = NOT_HIDE; // show the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for C
+ HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D
+ break;
+ case IIO_BIFURCATE_xxx8xxx8:
+ PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A
+ PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B
+ PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C
+ PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide D
+ HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A
+ HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for C
+ HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D
+ break;
+ case IIO_BIFURCATE_xxxxxx16:
+ PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A
+ PXPHide[PXPOffset + Iio_PortB] = HIDE; // hide B
+ PXPHide[PXPOffset + Iio_PortC] = HIDE; // hide C
+ PXPHide[PXPOffset + Iio_PortD] = HIDE; // hide D
+ HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A
+ HidePEXPMenu[PXPOffset + Iio_PortB] = HIDE; // hide the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortC] = HIDE; // hide the Setup menu for C
+ HidePEXPMenu[PXPOffset + Iio_PortD] = HIDE; // hide the Setup menu for D
+ break;
+ default:
+ PXPHide[PXPOffset + Iio_PortA] = NOT_HIDE; // show A
+ PXPHide[PXPOffset + Iio_PortB] = NOT_HIDE; // show B
+ PXPHide[PXPOffset + Iio_PortC] = NOT_HIDE; // show C
+ PXPHide[PXPOffset + Iio_PortD] = NOT_HIDE; // show port D
+ HidePEXPMenu[PXPOffset + Iio_PortA] = NOT_HIDE; // show the Setup menu for A
+ HidePEXPMenu[PXPOffset + Iio_PortB] = NOT_HIDE; // show the Setup menu for B
+ HidePEXPMenu[PXPOffset + Iio_PortC] = NOT_HIDE; // show the Setup menu for C
+ HidePEXPMenu[PXPOffset + Iio_PortD] = NOT_HIDE; // show the Setup menu for D
+ break;
+ }
+
+ //
+ // Change PEXPHIDE setting to hide all PCIe port of a IOU if IIO_BIFURCATE_xxxxxxxx is set.
+ // And set ConfigIOUx/ConfigMCPx to default bifucation control value
+ // Bifurcation_Control[2:0] in IOU Bifurcation Control (PCIE_IOU_BIF_CTRL) register should be 000b ~ 100b.
+ //
+ if (CurrentIOUConfigValue == IIO_BIFURCATE_xxxxxxxx) {
+ switch (Iou) {
+ case Iio_Iou0:
+ IioGlobalData->SetupData.ConfigIOU0[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Iou1:
+ IioGlobalData->SetupData.ConfigIOU1[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Iou2:
+ IioGlobalData->SetupData.ConfigIOU2[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Mcp0:
+ IioGlobalData->SetupData.ConfigMCP0[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ case Iio_Mcp1:
+ IioGlobalData->SetupData.ConfigMCP1[IioIndex] = IIO_BIFURCATE_x4x4x4x4;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+VOID
+DumpPort(
+ IIO_GLOBALS *IioGlobalData,
+ UINT8 Port,
+ UINT8 NumberOfPorts
+)
+{
+ UINT8 Index;
+ DEBUG((EFI_D_INFO, "IDX, Port Hide, Slot Impl, Slot Number, HotPlug, PcieSSD, VppPort, VppAddress, Interlock\n"));
+ for (Index = Port; Index < (Port + NumberOfPorts); Index++ ) {
+ DEBUG((EFI_D_INFO, "%3d| %2d | %2d | %3d | %3d | %3d | 0x%02x | 0x%02x | %2d \n", \
+ Index, \
+ IioGlobalData->SetupData.PEXPHIDE[Index], \
+ IioGlobalData->SetupData.SLOTIMP[Index], \
+ IioGlobalData->SetupData.SLOTPSP[Index], \
+ IioGlobalData->SetupData.SLOTHPCAP[Index], \
+ IioGlobalData->IioVar.IioOutData.PciePortOwnership[Index], \
+ IioGlobalData->SetupData.VppPort[Index], \
+ IioGlobalData->SetupData.VppAddress[Index],\
+ IioGlobalData->SetupData.SLOTEIP[Index]));
+ }
+ }
+/// Dump iio configuration. Dump the current IIO configuration to the serial
+/// log.
+VOID
+DumpIioConfiguration(
+ IN UINT8 iio,
+ IN IIO_GLOBALS *IioGlobalData
+)
+{
+ UINT8 Iou;
+ UINT8 PortIndex;
+ UINT8 Bifurcation;
+ UINT8 IouPorts;
+ PortIndex = iio * NUMBER_PORTS_PER_SOCKET;
+ /// First dump the socket number;
+ DEBUG((EFI_D_INFO, "Socket number: %d \n", iio));
+
+ /// Dump DMI configuration:
+ if ((iio == 0) && (PortIndex == 0)){
+ DEBUG((EFI_D_INFO, "PORT 0: DMI Port\n"));
+ } else {
+ DEBUG((EFI_D_INFO, "PORT 0: DMI Port working as PCIE\n"));
+ DumpPort(IioGlobalData, PortIndex, 1);
+ }
+ IouPorts=4;
+ /// Dump IOU bifurcations:
+ for (Iou = Iio_Iou0; Iou< Iio_IouMax; Iou ++) {
+ /// Reset port index.
+ PortIndex = iio * NUMBER_PORTS_PER_SOCKET;
+ // Get the bifurcation
+ switch (Iou) {
+ case Iio_Iou0:
+ Bifurcation = IioGlobalData->SetupData.ConfigIOU0[iio];
+ PortIndex += PORT_1A_INDEX;
+ DEBUG((EFI_D_INFO, "IUO0: Root Port 1, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Iou1:
+ Bifurcation = IioGlobalData->SetupData.ConfigIOU1[iio];
+ PortIndex += PORT_2A_INDEX;
+ DEBUG((EFI_D_INFO, "IUO1: Root Port 2, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Iou2:
+ Bifurcation = IioGlobalData->SetupData.ConfigIOU2[iio];
+ PortIndex += PORT_3A_INDEX;
+ DEBUG((EFI_D_INFO, "IUO2: Root Port 3, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Mcp0:
+ Bifurcation = IioGlobalData->SetupData.ConfigMCP0[iio];
+ PortIndex += PORT_4A_INDEX;
+ DEBUG((EFI_D_INFO, "MCP0, Bifurcation: %d\n", Bifurcation));
+ break;
+ case Iio_Mcp1:
+ Bifurcation = IioGlobalData->SetupData.ConfigMCP1[iio];
+ PortIndex += PORT_5A_INDEX;
+ DEBUG((EFI_D_INFO, "MCP1, Bifurcation: %d\n", Bifurcation));
+ break;
+ default:
+ DEBUG((EFI_D_INFO, "Iou no detected = %d",Iou));
+ break;
+ }
+ DumpPort(IioGlobalData, PortIndex, IouPorts);
+ }
+
+}
+
+UINT8
+GetUplinkPortInformationCommon (
+ IN UINT8 IioIndex
+)
+{
+ UINT8 UplinkPortIndex = 0xFF;
+
+ if (IioIndex == 0) {
+ UplinkPortIndex = PcdGet8(PcdOemSkuUplinkPortIndex);
+ }
+
+ return UplinkPortIndex;
+}
+/**
+
+ SystemIioPortBifurcationInit - Program the UDS data structure with OEM IIO init values
+ for SLOTs and Bifurcation.
+
+ @param mSB - pointer to this protocol
+ @param IioUds - Pointer to the IIO UDS datastructure.
+
+ @retval EFI_SUCCESS
+
+**/
+VOID
+SystemIioPortBifurcationInitCommon (
+ IIO_GLOBALS *IioGlobalData,
+ IIO_BIFURCATION_ENTRY **BifurcationTable,
+ UINT8 *BifurcationEntries,
+ IIO_SLOT_CONFIG_ENTRY **SlotTable,
+ UINT8 *SlotEntries
+)
+{
+
+ UINT8 PortIndex;//, iio;
+
+ /// This function outline:
+ //// 1 Based on platform apply the default bifurcation and slot configuration.
+ //// 2 Apply dynamic overrides based on GPIO and other configurations.
+ //// 3 Hide unused ports due bifurcation.
+
+ for (PortIndex = 0; PortIndex < MAX_SOCKET*NUMBER_PORTS_PER_SOCKET; PortIndex++) {
+ IioGlobalData->SetupData.PEXPHIDE[PortIndex] = 0;
+ IioGlobalData->SetupData.HidePEXPMenu[PortIndex] = 0;
+ }
+
+ *BifurcationEntries = 0;
+ *SlotEntries = 0;
+
+ *BifurcationTable = (IIO_BIFURCATION_ENTRY *)(UINTN)PcdGet64 (PcdIioBifurcationTable);
+ *BifurcationEntries = PcdGet8 (PcdIioBifurcationTableEntries);
+ *SlotTable = (IIO_SLOT_CONFIG_ENTRY *)(UINTN)PcdGet64 (PcdIioSlotTable);
+ *SlotEntries = PcdGet8 (PcdIioSlotTableEntries);
+}
+
+VOID
+SystemHideIioPortsCommon(
+ IIO_GLOBALS *IioGlobalData,
+ UINT8 IioIndex
+)
+{
+ CalculatePEXPHideFromIouBif(Iio_Iou0, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Iou1, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Iou2, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Mcp0, IioIndex, IioGlobalData);
+ CalculatePEXPHideFromIouBif(Iio_Mcp1, IioIndex, IioGlobalData);
+ DumpIioConfiguration(IioIndex, IioGlobalData);
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.c b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.c
new file mode 100644
index 0000000000..9d05a39c68
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.c
@@ -0,0 +1,255 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SystemBoardPei.h"
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <IioBifurcationSlotTable.h>
+
+extern IIO_BIFURCATION_ENTRY mIioBifurcationTable[];
+extern UINT8 mIioBifurcationTableEntries;
+extern IIO_SLOT_CONFIG_ENTRY mIioSlotTable[];
+extern UINT8 mIioSlotTableEntries;
+
+//
+// System board PPI structure
+//
+static SYSTEM_BOARD_PPI mSystemBoardPpi = {
+ SystemIioPortBifurcationInit, // Set IIO Bifurcation ports configuration
+ GetUplinkPortInformation,
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mSystemBoardPpiDesc = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiSystemBoardPpiGuid,
+ &mSystemBoardPpi
+};
+
+/**
+
+ GetUplinkPortInformation - Get uplink port information
+
+ @param IioIndex - socket ID.
+
+ @retval PortIndex for uplink port
+
+**/
+UINT8
+EFIAPI
+GetUplinkPortInformation (
+ IN UINT8 IioIndex
+)
+{
+ UINT8 UplinkPortIndex;
+
+ UplinkPortIndex = GetUplinkPortInformationCommon(IioIndex);
+ return UplinkPortIndex;
+}
+
+/**
+
+ SystemIioPortBifurcationInit - Program the UDS data structure with OEM IIO init values
+ for SLOTs and Bifurcation.
+
+ @param mSB - pointer to this protocol
+ @param IioUds - Pointer to the IIO UDS datastructure.
+
+ @retval EFI_SUCCESS
+
+**/
+VOID
+InternalSystemIioPortBifurcationInitCommon (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN OUT IIO_BIFURCATION_ENTRY **BifurcationTable,
+ IN OUT UINT8 *BifurcationEntries,
+ IN OUT IIO_SLOT_CONFIG_ENTRY **SlotTable,
+ IN OUT UINT8 *SlotEntries
+)
+{
+
+ UINT8 PortIndex;//, iio;
+
+ /// This function outline:
+ //// 1 Based on platform apply the default bifurcation and slot configuration.
+ //// 2 Apply dynamic overrides based on GPIO and other configurations.
+ //// 3 Hide unused ports due bifurcation.
+
+ for (PortIndex = 0; PortIndex < MAX_SOCKET*NUMBER_PORTS_PER_SOCKET; PortIndex++) {
+ IioGlobalData->SetupData.PEXPHIDE[PortIndex] = 0;
+ IioGlobalData->SetupData.HidePEXPMenu[PortIndex] = 0;
+ }
+
+ *BifurcationEntries = 0;
+ *SlotEntries = 0;
+
+ // Purley Intel boards are not Multi-PCH
+ IioGlobalData->IioVar.IioVData.MultiPch = 0;
+
+ *BifurcationTable = (IIO_BIFURCATION_ENTRY *)(UINTN)PcdGet64 (PcdIioBifurcationTable);
+ *BifurcationEntries = PcdGet8 (PcdIioBifurcationTableEntries);
+ *SlotTable = (IIO_SLOT_CONFIG_ENTRY *)(UINTN)PcdGet64 (PcdIioSlotTable);
+ *SlotEntries = PcdGet8 (PcdIioSlotTableEntries);
+}
+
+/**
+
+ SystemIioPortBifurcationInit - Program the IIO_GLOBALS data structure with OEM IIO init values
+ for SLOTs and Bifurcation.
+
+ @param mSB - pointer to this protocol
+ @param IioUds - Pointer to the IIO UDS datastructure.
+
+ @retval EFI_SUCCESS
+
+**/
+VOID
+SystemIioPortBifurcationInit (
+ IN IIO_GLOBALS *IioGlobalData
+)
+{
+
+ UINT8 IioIndex;
+ IIO_BIFURCATION_ENTRY *BifurcationTable = NULL;
+ UINT8 BifurcationEntries;
+ IIO_SLOT_CONFIG_ENTRY *SlotTable = NULL;
+ UINT8 SlotEntries;
+
+ // This function outline:
+ // 1. Based on platform apply the default bifurcation and slot configuration.
+ // 2. Apply dynamic overrides based on GPIO and other configurations.
+ // 3. Hide unused ports due bifurcation.
+
+ SystemIioPortBifurcationInitCommon(IioGlobalData, &BifurcationTable, &BifurcationEntries, &SlotTable, &SlotEntries);
+ /// Set the default bifurcations for this platform.
+ SetBifurcations(IioGlobalData, BifurcationTable, BifurcationEntries);
+ ConfigSlots(IioGlobalData, SlotTable, SlotEntries);
+ OverrideConfigSlots(IioGlobalData, SlotTable, SlotEntries);
+
+ // All overrides have been applied now.
+ // Hide root ports whose lanes are assigned preceding ports.
+ for (IioIndex = Iio_Socket0; IioIndex < MaxIIO; IioIndex++) {
+ if (IioGlobalData->IioVar.IioVData.SocketPresent[IioIndex]) {
+ SystemHideIioPortsCommon(IioGlobalData, IioIndex);
+ }
+ }
+}
+
+
+/**
+
+ This function dump raw data.
+
+ @param Data raw data
+ @param Size raw data size
+
+**/
+VOID
+InternalDumpData (
+ IN UINT8 *Data,
+ IN UINTN Size
+ )
+{
+ UINTN Index;
+ for (Index = 0; Index < Size; Index++) {
+ DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));
+ }
+}
+
+/**
+
+ This function dump raw data with colume format.
+
+ @param Data raw data
+ @param Size raw data size
+
+**/
+VOID
+InternalDumpHex (
+ IN UINT8 *Data,
+ IN UINTN Size
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ UINTN Left;
+
+#define COLUME_SIZE (16 * 2)
+
+ Count = Size / COLUME_SIZE;
+ Left = Size % COLUME_SIZE;
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));
+ InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
+ DEBUG ((EFI_D_INFO, "\n"));
+ }
+
+ if (Left != 0) {
+ DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));
+ InternalDumpData (Data + Index * COLUME_SIZE, Left);
+ DEBUG ((EFI_D_INFO, "\n"));
+ }
+}
+
+VOID
+DumpConfig (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_INFO, "PcdSetupData - 0x%x\n", PcdGetSize (PcdSetupData)));
+ InternalDumpHex (PcdGetPtr (PcdSetupData), PcdGetSize (PcdSetupData));
+ DEBUG ((DEBUG_INFO, "PcdPchRcConfigurationData - 0x%x\n", PcdGetSize (PcdPchRcConfigurationData)));
+ InternalDumpHex (PcdGetPtr (PcdPchRcConfigurationData), PcdGetSize (PcdPchRcConfigurationData));
+ DEBUG ((DEBUG_INFO, "PcdSocketIioConfigData - 0x%x\n", PcdGetSize (PcdSocketIioConfigData)));
+ InternalDumpHex (PcdGetPtr (PcdSocketIioConfigData), PcdGetSize (PcdSocketIioConfigData));
+ DEBUG ((DEBUG_INFO, "PcdSocketCommonRcConfigData - 0x%x\n", PcdGetSize (PcdSocketCommonRcConfigData)));
+ InternalDumpHex (PcdGetPtr (PcdSocketCommonRcConfigData), PcdGetSize (PcdSocketCommonRcConfigData));
+ DEBUG ((DEBUG_INFO, "PcdSocketMpLinkConfigData - 0x%x\n", PcdGetSize (PcdSocketMpLinkConfigData)));
+ InternalDumpHex (PcdGetPtr (PcdSocketMpLinkConfigData), PcdGetSize (PcdSocketMpLinkConfigData));
+ DEBUG ((DEBUG_INFO, "PcdSocketMemoryConfigData - 0x%x\n", PcdGetSize (PcdSocketMemoryConfigData)));
+ InternalDumpHex (PcdGetPtr (PcdSocketMemoryConfigData), PcdGetSize (PcdSocketMemoryConfigData));
+ DEBUG ((DEBUG_INFO, "PcdSocketPowerManagementConfigData - 0x%x\n", PcdGetSize (PcdSocketPowerManagementConfigData)));
+ InternalDumpHex (PcdGetPtr (PcdSocketPowerManagementConfigData), PcdGetSize (PcdSocketPowerManagementConfigData));
+ DEBUG ((DEBUG_INFO, "PcdSocketProcessorCoreConfigData - 0x%x\n", PcdGetSize (PcdSocketProcessorCoreConfigData)));
+ InternalDumpHex (PcdGetPtr (PcdSocketProcessorCoreConfigData), PcdGetSize (PcdSocketProcessorCoreConfigData));
+}
+
+//
+// PEI entry point - SystemBoardPpi entry point
+//
+/**
+
+ PEI system board PPI intialization main entry point. This will setup up a PPI that will handle providing system board level
+ configuration for the platform.
+
+ @param FileHandle Pointer to the PEIM FFS file header.
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval Otherwise System board initialization failed.
+**/
+EFI_STATUS
+EFIAPI
+SystemBoardPeiEntry (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_ERROR, "--> SystemBoard PEI BoardDetection\n"));
+
+ //DumpConfig ();
+
+ //
+ // Initialize system board information PPI
+ //
+ Status = PeiServicesInstallPpi(&mSystemBoardPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.h b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.h
new file mode 100644
index 0000000000..1adc59cb3d
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.h
@@ -0,0 +1,182 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_SYSTEM_BOARD_PPI_H_
+#define _EFI_SYSTEM_BOARD_PPI_H_
+
+#include <Platform.h>
+#include <Library/MmPciBaseLib.h>
+#include <Pi/PiHob.h>
+
+
+// GUID
+#include <Guid/SetupVariable.h>
+#include <Guid/SocketIioVariable.h>
+
+// PPI
+#include <Ppi/PchPolicy.h>
+#include <Ppi/SystemBoard.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/Smbus2.h>
+
+
+// Library
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciExpressLib.h>
+
+#include <Library/GpioLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PchInfoLib.h>
+#include <Platform.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioLib.h>
+
+#include <IioBifurcationSlotTable.h>
+
+// CMOS access Port address
+#define LAST_CMOS_BYTE 0x7F
+#define NMI_OFF 0x80
+#define B_PCH_RTC_REGB_SRBRST 0x02 // Value to be reset to during POST
+#define R_PCH_RTC_REGD 0x0D // CMOS Register D Status
+#define R_PCH_RTC_REGE 0x0E // CMOS Register E Status
+#define B_PCH_RTC_REGE_INVTIM 0x04 // CMOS invalid time found
+
+#define TIMER1_CONTROL_PORT 0x43
+#define TIMER1_COUNT_PORT 0x41
+#define LOAD_COUNTER1_LSB 0x54
+#define COUNTER1_COUNT 0x12
+//
+// Reset Generator I/O Port
+//
+#define RESET_GENERATOR_PORT 0xCF9
+
+//-----------------------------------------------------------------------;
+// PCH: Chipset Configuration Register Equates
+//-----------------------------------------------------------------------;
+#define ICH_RCRB_IRQ0 0
+#define ICH_RCRB_IRQA 1
+#define ICH_RCRB_IRQB 2
+#define ICH_RCRB_IRQC 3
+#define ICH_RCRB_IRQD 4
+#define ICH_RCRB_PIRQA 0
+#define ICH_RCRB_PIRQB 1
+#define ICH_RCRB_PIRQC 2
+#define ICH_RCRB_PIRQD 3
+#define ICH_RCRB_PIRQE 4
+#define ICH_RCRB_PIRQF 5
+#define ICH_RCRB_PIRQG 6
+#define ICH_RCRB_PIRQH 7
+
+//
+// From WBG Soft Straps WIP.xlsx
+//
+#define WBG_DOWNSKU_STRAP_DSKU 0x80046000
+#define WBG_DOWNSKU_STRAP_BSKU 0x8004E003
+#define WBG_DOWNSKU_STRAP_TSKU 0x00044000
+
+#define PCHSTRAP_9 9
+#define PCHSTRAP_10 10
+#define PCHSTRAP_16 16
+#define PCHSTRAP_17 17
+
+#define RESET_PORT 0x0CF9
+#define CLEAR_RESET_BITS 0x0F1
+#define COLD_RESET 0x02 // Set bit 1 for cold reset
+#define RST_CPU 0x04 // Setting this bit triggers a reset of the CPU
+#define FULL_RESET 0x08 // Set bit 4 with bit 1 for full reset
+
+//
+// PPI functions
+//
+
+VOID
+SetBifurcations(
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_BIFURCATION_ENTRY *BifurcationTable,
+ IN UINT8 BifurcationEntries
+);
+
+VOID
+EnableHotPlug (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN UINT8 Port,
+ IN UINT8 VppPort,
+ IN UINT8 VppAddress,
+ IN UINT8 PortOwnership
+ );
+
+
+VOID
+ConfigSlots (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_SLOT_CONFIG_ENTRY *Slot,
+ IN UINT8 SlotEntries
+ );
+
+VOID
+OverrideConfigSlots (
+ IN OUT IIO_GLOBALS *IioGlobalData,
+ IN IIO_SLOT_CONFIG_ENTRY *Slot,
+ IN UINT8 SlotEntries
+ );
+
+VOID
+CalculatePEXPHideFromIouBif (
+ IN UINT8 Iou,
+ IN UINT8 IioIndex,
+ IN OUT IIO_GLOBALS *IioGlobalData
+);
+
+VOID
+DumpIioConfiguration(
+ IN UINT8 iio,
+ IN IIO_GLOBALS *IioGlobalData
+);
+
+VOID
+OverrideDefaultBifSlots(
+ IN IIO_GLOBALS *IioGlobalData
+);
+
+UINT8
+GetUplinkPortInformationCommon (
+ IN UINT8 IioIndex
+);
+
+VOID
+SystemIioPortBifurcationInitCommon (
+ IIO_GLOBALS *IioGlobalData,
+ IIO_BIFURCATION_ENTRY **BifurcationTable,
+ UINT8 *BifurcationEntries,
+ IIO_SLOT_CONFIG_ENTRY **SlotTable,
+ UINT8 *SlotEntries
+);
+
+VOID
+SystemHideIioPortsCommon(
+ IIO_GLOBALS *IioGlobalData,
+ UINT8 IioIndex
+);
+
+UINT8
+GetUplinkPortInformation (
+ IN UINT8 IioIndex
+);
+
+VOID
+SystemIioPortBifurcationInit (
+ IN IIO_GLOBALS *IioGlobalData
+ );
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.inf b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.inf
new file mode 100644
index 0000000000..9bd2dfbb59
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Policy/SystemBoard/SystemBoardPei.inf
@@ -0,0 +1,76 @@
+## @file
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SystemBoardPei
+ FILE_GUID = C0989520-2F0D-470a-9BE4-2969E0EC5641
+ MODULE_TYPE = PEIM
+ ENTRY_POINT = SystemBoardPeiEntry
+
+[Sources]
+ SystemBoardPei.c
+ SystemBoardCommon.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ PurleyOpenBoardPkg/OpenBoardPkg.dec
+ PurleyRefreshSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ PeiServicesLib
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ IoLib
+ PciLib
+ PcdLib
+ PeiServicesTablePointerLib
+ PciExpressLib
+ PchInfoLib
+ GpioLib
+ TimerLib
+ PchCycleDecodingLib
+ PchSbiAccessLib
+ PchInfoLib
+ PchP2sbLib
+ PchPcrLib
+ MmPciLib
+ PcdLib
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gOemSkuTokenSpaceGuid.PcdIioBifurcationTable
+ gOemSkuTokenSpaceGuid.PcdIioBifurcationTableEntries
+ gOemSkuTokenSpaceGuid.PcdIioSlotTable
+ gOemSkuTokenSpaceGuid.PcdIioSlotTableEntries
+ gOemSkuTokenSpaceGuid.PcdOemSkuUplinkPortIndex
+
+ gOemSkuTokenSpaceGuid.PcdSetupData
+ gOemSkuTokenSpaceGuid.PcdPchRcConfigurationData
+ gOemSkuTokenSpaceGuid.PcdSocketIioConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketCommonRcConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketMpLinkConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketMemoryConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketPowerManagementConfigData
+ gOemSkuTokenSpaceGuid.PcdSocketProcessorCoreConfigData
+
+
+[Ppis]
+ gEfiPeiSystemBoardPpiGuid ## PRODUCES
+ gEfiPeiSmbus2PpiGuid
+ gPchPlatformPolicyPpiGuid
+
+[Depex]
+ gEfiPeiPcdPpiGuid AND
+ gEfiPeiReadOnlyVariable2PpiGuid
+
--
2.27.0.windows.1
next prev 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 ` [edk2-platforms] [PATCH V1 08/18] PurleyOpenBoardPkg: Add includes and libraries Nate DeSimone
2021-05-11 9:48 ` Nate DeSimone [this message]
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-10-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