diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index f4ffc71d7165..09037c59b531 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -109,6 +109,7 @@ [Components.common] ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf + ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c new file mode 100644 index 000000000000..4134c8bfda41 --- /dev/null +++ b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c @@ -0,0 +1,176 @@ +/** @file + Support ResetSystem Runtime call using PSCI calls + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2014, Linaro Ltd. All rights reserved.
+ Copyright (c) 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2024, Google Llc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include + +/** + Library constructor. This function does nothing, but this library may depend + on other libraries that do have a non-trivial constructor, which the + BaseToools fail to account for if a library has no constructor at all. + **/ +RETURN_STATUS +EFIAPI +ArmPsciResetSystemLibConstructor ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + This function causes a system-wide reset (cold reset), in which + all circuitry within the system returns to its initial state. This type of reset + is asynchronous to system operation and operates without regard to + cycle boundaries. + + If this function returns, it means that the system does not support cold reset. +**/ +VOID +EFIAPI +ResetCold ( + VOID + ) +{ + ARM_MONITOR_ARGS Args; + + // Send a PSCI 0.2 SYSTEM_RESET command + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET; + + ArmMonitorCall (&Args); +} + +/** + This function causes a system-wide initialization (warm reset), in which all processors + are set to their initial state. Pending cycles are not corrupted. + + If this function returns, it means that the system does not support warm reset. +**/ +VOID +EFIAPI +ResetWarm ( + VOID + ) +{ + ARM_MONITOR_ARGS Args; + + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64; + + // Is SYSTEM_RESET2 supported? + ArmMonitorCall (&Args); + if (Args.Arg0 == ARM_SMC_PSCI_RET_SUCCESS) { + // Send PSCI SYSTEM_RESET2 command + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64; + + ArmMonitorCall (&Args); + } else { + // Map a warm reset into a cold reset + DEBUG (( + DEBUG_INFO, + "Warm reboot not supported by platform, issuing cold reboot\n" + )); + ResetCold (); + } +} + +/** + This function causes the system to enter a power state equivalent + to the ACPI G2/S5 or G3 states. + + If this function returns, it means that the system does not support shutdown reset. +**/ +VOID +EFIAPI +ResetShutdown ( + VOID + ) +{ + ARM_MONITOR_ARGS Args; + + // Send a PSCI 0.2 SYSTEM_RESET command + Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF; + + ArmMonitorCall (&Args); +} + +/** + This function causes a systemwide reset. The exact type of the reset is + defined by the EFI_GUID that follows the Null-terminated Unicode string passed + into ResetData. If the platform does not recognize the EFI_GUID in ResetData + the platform must pick a supported reset type to perform.The platform may + optionally log the parameters from any non-normal reset that occurs. + + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData The data buffer starts with a Null-terminated string, + followed by the EFI_GUID. +**/ +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + // Map the platform specific reset as reboot + ResetCold (); +} + +/** + The ResetSystem function resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown + the data buffer starts with a Null-terminated string, optionally + followed by additional binary data. The string is a description + that the caller may use to further indicate the reason for the + system reset. +**/ +VOID +EFIAPI +ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + switch (ResetType) { + case EfiResetWarm: + ResetWarm (); + break; + + case EfiResetCold: + ResetCold (); + break; + + case EfiResetShutdown: + ResetShutdown (); + return; + + case EfiResetPlatformSpecific: + ResetPlatformSpecific (DataSize, ResetData); + return; + + default: + return; + } +} diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf new file mode 100644 index 000000000000..c98f60df78a8 --- /dev/null +++ b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf @@ -0,0 +1,32 @@ +## @file +# Reset System lib using PSCI hypervisor or secure monitor calls +# +# Copyright (c) 2008, Apple Inc. All rights reserved.
+# Copyright (c) 2014, Linaro Ltd. All rights reserved.
+# Copyright (c) 2024, Google Llc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ArmPsciResetSystemLib + FILE_GUID = 31db596f-cc80-47fd-849f-e6be5e9f7560 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib + CONSTRUCTOR = ArmPsciResetSystemLibConstructor + +[Sources] + ArmPsciResetSystemLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmMonitorLib + BaseLib + DebugLib