ArmVirtPsciResetSystemLib.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /** @file
  2. Support ResetSystem Runtime call using PSCI calls
  3. Note: A similar library is implemented in
  4. ArmPkg/Library/ArmPsciResetSystemLib. Similar issues might
  5. exist in this implementation too.
  6. Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
  7. Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
  8. Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
  9. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  10. SPDX-License-Identifier: BSD-2-Clause-Patent
  11. **/
  12. #include <PiDxe.h>
  13. #include <Library/BaseLib.h>
  14. #include <Library/DebugLib.h>
  15. #include <Library/ResetSystemLib.h>
  16. #include <Library/ArmSmcLib.h>
  17. #include <Library/ArmHvcLib.h>
  18. #include <Library/UefiBootServicesTableLib.h>
  19. #include <IndustryStandard/ArmStdSmc.h>
  20. #include <Protocol/FdtClient.h>
  21. STATIC UINT32 mArmPsciMethod;
  22. RETURN_STATUS
  23. EFIAPI
  24. ArmPsciResetSystemLibConstructor (
  25. VOID
  26. )
  27. {
  28. EFI_STATUS Status;
  29. FDT_CLIENT_PROTOCOL *FdtClient;
  30. CONST VOID *Prop;
  31. Status = gBS->LocateProtocol (
  32. &gFdtClientProtocolGuid,
  33. NULL,
  34. (VOID **)&FdtClient
  35. );
  36. ASSERT_EFI_ERROR (Status);
  37. Status = FdtClient->FindCompatibleNodeProperty (
  38. FdtClient,
  39. "arm,psci-0.2",
  40. "method",
  41. &Prop,
  42. NULL
  43. );
  44. if (EFI_ERROR (Status)) {
  45. return Status;
  46. }
  47. if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
  48. mArmPsciMethod = 1;
  49. } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
  50. mArmPsciMethod = 2;
  51. } else {
  52. DEBUG ((
  53. DEBUG_ERROR,
  54. "%a: Unknown PSCI method \"%a\"\n",
  55. __FUNCTION__,
  56. Prop
  57. ));
  58. return EFI_NOT_FOUND;
  59. }
  60. return EFI_SUCCESS;
  61. }
  62. /**
  63. This function causes a system-wide reset (cold reset), in which
  64. all circuitry within the system returns to its initial state. This type of reset
  65. is asynchronous to system operation and operates without regard to
  66. cycle boundaries.
  67. If this function returns, it means that the system does not support cold reset.
  68. **/
  69. VOID
  70. EFIAPI
  71. ResetCold (
  72. VOID
  73. )
  74. {
  75. ARM_SMC_ARGS ArmSmcArgs;
  76. ARM_HVC_ARGS ArmHvcArgs;
  77. // Send a PSCI 0.2 SYSTEM_RESET command
  78. ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
  79. ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
  80. switch (mArmPsciMethod) {
  81. case 1:
  82. ArmCallHvc (&ArmHvcArgs);
  83. break;
  84. case 2:
  85. ArmCallSmc (&ArmSmcArgs);
  86. break;
  87. default:
  88. DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
  89. }
  90. }
  91. /**
  92. This function causes a system-wide initialization (warm reset), in which all processors
  93. are set to their initial state. Pending cycles are not corrupted.
  94. If this function returns, it means that the system does not support warm reset.
  95. **/
  96. VOID
  97. EFIAPI
  98. ResetWarm (
  99. VOID
  100. )
  101. {
  102. // Map a warm reset into a cold reset
  103. ResetCold ();
  104. }
  105. /**
  106. This function causes the system to enter a power state equivalent
  107. to the ACPI G2/S5 or G3 states.
  108. If this function returns, it means that the system does not support shutdown reset.
  109. **/
  110. VOID
  111. EFIAPI
  112. ResetShutdown (
  113. VOID
  114. )
  115. {
  116. ARM_SMC_ARGS ArmSmcArgs;
  117. ARM_HVC_ARGS ArmHvcArgs;
  118. // Send a PSCI 0.2 SYSTEM_OFF command
  119. ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
  120. ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
  121. switch (mArmPsciMethod) {
  122. case 1:
  123. ArmCallHvc (&ArmHvcArgs);
  124. break;
  125. case 2:
  126. ArmCallSmc (&ArmSmcArgs);
  127. break;
  128. default:
  129. DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
  130. }
  131. }
  132. /**
  133. This function causes a systemwide reset. The exact type of the reset is
  134. defined by the EFI_GUID that follows the Null-terminated Unicode string passed
  135. into ResetData. If the platform does not recognize the EFI_GUID in ResetData
  136. the platform must pick a supported reset type to perform.The platform may
  137. optionally log the parameters from any non-normal reset that occurs.
  138. @param[in] DataSize The size, in bytes, of ResetData.
  139. @param[in] ResetData The data buffer starts with a Null-terminated string,
  140. followed by the EFI_GUID.
  141. **/
  142. VOID
  143. EFIAPI
  144. ResetPlatformSpecific (
  145. IN UINTN DataSize,
  146. IN VOID *ResetData
  147. )
  148. {
  149. // Map the platform specific reset as reboot
  150. ResetCold ();
  151. }
  152. /**
  153. The ResetSystem function resets the entire platform.
  154. @param[in] ResetType The type of reset to perform.
  155. @param[in] ResetStatus The status code for the reset.
  156. @param[in] DataSize The size, in bytes, of ResetData.
  157. @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
  158. the data buffer starts with a Null-terminated string, optionally
  159. followed by additional binary data. The string is a description
  160. that the caller may use to further indicate the reason for the
  161. system reset.
  162. **/
  163. VOID
  164. EFIAPI
  165. ResetSystem (
  166. IN EFI_RESET_TYPE ResetType,
  167. IN EFI_STATUS ResetStatus,
  168. IN UINTN DataSize,
  169. IN VOID *ResetData OPTIONAL
  170. )
  171. {
  172. switch (ResetType) {
  173. case EfiResetWarm:
  174. ResetWarm ();
  175. break;
  176. case EfiResetCold:
  177. ResetCold ();
  178. break;
  179. case EfiResetShutdown:
  180. ResetShutdown ();
  181. return;
  182. case EfiResetPlatformSpecific:
  183. ResetPlatformSpecific (DataSize, ResetData);
  184. return;
  185. default:
  186. return;
  187. }
  188. }