Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>\r
Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
#include <Library/BaseLib.h>\r
#include <Library/DebugLib.h>\r
-#include <Library/EfiResetSystemLib.h>\r
+#include <Library/ResetSystemLib.h>\r
#include <Library/ArmSmcLib.h>\r
#include <Library/ArmHvcLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
\r
#include <IndustryStandard/ArmStdSmc.h>\r
\r
+#include <Protocol/FdtClient.h>\r
+\r
STATIC UINT32 mArmPsciMethod;\r
\r
RETURN_STATUS\r
VOID\r
)\r
{\r
- mArmPsciMethod = PcdGet32 (PcdArmPsciMethod);\r
- return RETURN_SUCCESS;\r
+ EFI_STATUS Status;\r
+ FDT_CLIENT_PROTOCOL *FdtClient;\r
+ CONST VOID *Prop;\r
+\r
+ Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
+ (VOID **)&FdtClient);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,psci-0.2",\r
+ "method", &Prop, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {\r
+ mArmPsciMethod = 1;\r
+ } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {\r
+ mArmPsciMethod = 2;\r
+ } else {\r
+ DEBUG ((DEBUG_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__,\r
+ Prop));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
- Resets the entire platform.\r
-\r
- @param ResetType The type of reset to perform.\r
- @param ResetStatus The status code for the reset.\r
- @param DataSize The size, in bytes, of WatchdogData.\r
- @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
- EfiResetShutdown the data buffer starts with a Null-terminated\r
- Unicode string, optionally followed by additional binary data.\r
+ This function causes a system-wide reset (cold reset), in which\r
+ all circuitry within the system returns to its initial state. This type of reset\r
+ is asynchronous to system operation and operates without regard to\r
+ cycle boundaries.\r
\r
+ If this function returns, it means that the system does not support cold reset.\r
**/\r
-EFI_STATUS\r
+VOID\r
EFIAPI\r
-LibResetSystem (\r
- IN EFI_RESET_TYPE ResetType,\r
- IN EFI_STATUS ResetStatus,\r
- IN UINTN DataSize,\r
- IN CHAR16 *ResetData OPTIONAL\r
+ResetCold (\r
+ VOID\r
)\r
{\r
ARM_SMC_ARGS ArmSmcArgs;\r
ARM_HVC_ARGS ArmHvcArgs;\r
\r
- switch (ResetType) {\r
+ // Send a PSCI 0.2 SYSTEM_RESET command\r
+ ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;\r
+ ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;\r
\r
- case EfiResetPlatformSpecific:\r
- // Map the platform specific reset as reboot\r
- case EfiResetWarm:\r
- // Map a warm reset into a cold reset\r
- case EfiResetCold:\r
- // Send a PSCI 0.2 SYSTEM_RESET command\r
- ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;\r
- ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;\r
+ switch (mArmPsciMethod) {\r
+ case 1:\r
+ ArmCallHvc (&ArmHvcArgs);\r
break;\r
- case EfiResetShutdown:\r
- // Send a PSCI 0.2 SYSTEM_OFF command\r
- ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;\r
- ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;\r
+\r
+ case 2:\r
+ ArmCallSmc (&ArmSmcArgs);\r
break;\r
+\r
default:\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
+ DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));\r
}\r
+}\r
+\r
+/**\r
+ This function causes a system-wide initialization (warm reset), in which all processors\r
+ are set to their initial state. Pending cycles are not corrupted.\r
+\r
+ If this function returns, it means that the system does not support warm reset.\r
+**/\r
+VOID\r
+EFIAPI\r
+ResetWarm (\r
+ VOID\r
+ )\r
+{\r
+ // Map a warm reset into a cold reset\r
+ ResetCold ();\r
+}\r
+\r
+/**\r
+ This function causes the system to enter a power state equivalent\r
+ to the ACPI G2/S5 or G3 states.\r
+\r
+ If this function returns, it means that the system does not support shutdown reset.\r
+**/\r
+VOID\r
+EFIAPI\r
+ResetShutdown (\r
+ VOID\r
+ )\r
+{\r
+ ARM_SMC_ARGS ArmSmcArgs;\r
+ ARM_HVC_ARGS ArmHvcArgs;\r
+\r
+ // Send a PSCI 0.2 SYSTEM_OFF command\r
+ ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;\r
+ ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;\r
\r
switch (mArmPsciMethod) {\r
case 1:\r
break;\r
\r
default:\r
- DEBUG ((EFI_D_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));\r
- return EFI_UNSUPPORTED;\r
+ DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));\r
}\r
-\r
- // We should never be here\r
- DEBUG ((EFI_D_ERROR, "%a: PSCI Reset failed\n", __FUNCTION__));\r
- CpuDeadLoop ();\r
- return EFI_UNSUPPORTED;\r
}\r
\r
/**\r
- Initialize any infrastructure required for LibResetSystem () to function.\r
-\r
- @param ImageHandle The firmware allocated handle for the EFI image.\r
- @param SystemTable A pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
+ This function causes a systemwide reset. The exact type of the reset is\r
+ defined by the EFI_GUID that follows the Null-terminated Unicode string passed\r
+ into ResetData. If the platform does not recognize the EFI_GUID in ResetData\r
+ the platform must pick a supported reset type to perform.The platform may\r
+ optionally log the parameters from any non-normal reset that occurs.\r
+\r
+ @param[in] DataSize The size, in bytes, of ResetData.\r
+ @param[in] ResetData The data buffer starts with a Null-terminated string,\r
+ followed by the EFI_GUID.\r
+**/\r
+VOID\r
+EFIAPI\r
+ResetPlatformSpecific (\r
+ IN UINTN DataSize,\r
+ IN VOID *ResetData\r
+ )\r
+{\r
+ // Map the platform specific reset as reboot\r
+ ResetCold ();\r
+}\r
\r
+/**\r
+ The ResetSystem function resets the entire platform.\r
+\r
+ @param[in] ResetType The type of reset to perform.\r
+ @param[in] ResetStatus The status code for the reset.\r
+ @param[in] DataSize The size, in bytes, of ResetData.\r
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown\r
+ the data buffer starts with a Null-terminated string, optionally\r
+ followed by additional binary data. The string is a description\r
+ that the caller may use to further indicate the reason for the\r
+ system reset.\r
**/\r
-EFI_STATUS\r
+VOID\r
EFIAPI\r
-LibInitializeResetSystem (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
+ResetSystem (\r
+ IN EFI_RESET_TYPE ResetType,\r
+ IN EFI_STATUS ResetStatus,\r
+ IN UINTN DataSize,\r
+ IN VOID *ResetData OPTIONAL\r
)\r
{\r
- return EFI_SUCCESS;\r
+ switch (ResetType) {\r
+ case EfiResetWarm:\r
+ ResetWarm ();\r
+ break;\r
+\r
+ case EfiResetCold:\r
+ ResetCold ();\r
+ break;\r
+\r
+ case EfiResetShutdown:\r
+ ResetShutdown ();\r
+ return;\r
+\r
+ case EfiResetPlatformSpecific:\r
+ ResetPlatformSpecific (DataSize, ResetData);\r
+ return;\r
+\r
+ default:\r
+ return;\r
+ }\r
}\r