From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com []) by mx.groups.io with SMTP id smtpd.web08.10551.1620726526771786264 for ; Tue, 11 May 2021 02:48:53 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: nathaniel.l.desimone@intel.com) IronPort-SDR: SA5x8hvj7xQYrItKxyqrJEBRabfSbyxel/mTsixmzB1lkTuhSULq3PzecvB2IlAZvKFIvonyQn CPOYdGVlHOyA== X-IronPort-AV: E=McAfee;i="6200,9189,9980"; a="199469640" X-IronPort-AV: E=Sophos;i="5.82,290,1613462400"; d="scan'208";a="199469640" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 May 2021 02:48:50 -0700 IronPort-SDR: Q/zt1m50aHN1OLqdydI7l+XRapRrVO/FpaQLXOLU1dmhtyS3wcmIE9FxAFOpvOsVuxJCSnDgKk nzM96cexfz5Q== X-IronPort-AV: E=Sophos;i="5.82,290,1613462400"; d="scan'208";a="436573980" Received: from nldesimo-desk1.amr.corp.intel.com ([10.209.66.229]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 May 2021 02:48:48 -0700 From: "Nate DeSimone" To: devel@edk2.groups.io Cc: Chasel Chiu , Mike Kinney , Isaac Oram , Mohamed Abbas , Michael Kubacki , Zachary Bobroff , Harikrishna Doppalapudi Subject: [edk2-platforms] [PATCH V1 09/18] PurleyOpenBoardPkg: Add modules Date: Tue, 11 May 2021 02:48:17 -0700 Message-Id: <20210511094826.12495-10-nathaniel.l.desimone@intel.com> X-Mailer: git-send-email 2.27.0.windows.1 In-Reply-To: <20210511094826.12495-1-nathaniel.l.desimone@intel.com> References: <20210511094826.12495-1-nathaniel.l.desimone@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Cc: Chasel Chiu Cc: Mike Kinney Cc: Isaac Oram Cc: Mohamed Abbas Cc: Michael Kubacki Cc: Zachary Bobroff Cc: Harikrishna Doppalapudi Signed-off-by: Nate DeSimone --- .../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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "BdsPlatform.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _BDS_PLATFORM_H +#define _BDS_PLATFORM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/// +/// 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.
+# +# 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "BdsPlatform.h" +#include + +/** + 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "BdsPlatform.h" + +#include + +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.
+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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "PciPlatform.h" +#include + +#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.
+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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "PciPlatform.h" +#include +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCI_PLATFORM_H_ +#define PCI_PLATFORM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// 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.
+# +# 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +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.
+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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiDxe.h" +#include +#include +#include +#include +#include +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_PCI_SUPPORT_H_ +#define _EFI_PCI_SUPPORT_H_ + +#include + +#include + +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.
+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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PLATFORM_TYPES_H_ +#define _PLATFORM_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + + +#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.
+# +# 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "PlatformHost.h" +#include + +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.
+# +# 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "S3NvramSave.h" +#include +#include +#include + +/** + + 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +#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.
+# +# 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SystemBoardPei.h" + +#include +#include + +#include + +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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_SYSTEM_BOARD_PPI_H_ +#define _EFI_SYSTEM_BOARD_PPI_H_ + +#include +#include +#include + + +// GUID +#include +#include + +// PPI +#include +#include +#include +#include + + +// Library +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +// 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.
+# +# 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