ArmVirtPsciResetSystemLib.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. SPDX-License-Identifier: BSD-2-Clause-Patent
  10. **/
  11. #include <PiDxe.h>
  12. #include <Library/BaseLib.h>
  13. #include <Library/DebugLib.h>
  14. #include <Library/ResetSystemLib.h>
  15. #include <Library/ArmSmcLib.h>
  16. #include <Library/ArmHvcLib.h>
  17. #include <Library/UefiBootServicesTableLib.h>
  18. #include <IndustryStandard/ArmStdSmc.h>
  19. #include <Protocol/FdtClient.h>
  20. STATIC UINT32 mArmPsciMethod;
  21. RETURN_STATUS
  22. EFIAPI
  23. ArmPsciResetSystemLibConstructor (
  24. VOID
  25. )
  26. {
  27. EFI_STATUS Status;
  28. FDT_CLIENT_PROTOCOL *FdtClient;
  29. CONST VOID *Prop;
  30. Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
  31. (VOID **)&FdtClient);
  32. ASSERT_EFI_ERROR (Status);
  33. Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,psci-0.2",
  34. "method", &Prop, NULL);
  35. if (EFI_ERROR (Status)) {
  36. return Status;
  37. }
  38. if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
  39. mArmPsciMethod = 1;
  40. } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
  41. mArmPsciMethod = 2;
  42. } else {
  43. DEBUG ((EFI_D_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__,
  44. Prop));
  45. return EFI_NOT_FOUND;
  46. }
  47. return EFI_SUCCESS;
  48. }
  49. /**
  50. This function causes a system-wide reset (cold reset), in which
  51. all circuitry within the system returns to its initial state. This type of reset
  52. is asynchronous to system operation and operates without regard to
  53. cycle boundaries.
  54. If this function returns, it means that the system does not support cold reset.
  55. **/
  56. VOID
  57. EFIAPI
  58. ResetCold (
  59. VOID
  60. )
  61. {
  62. ARM_SMC_ARGS ArmSmcArgs;
  63. ARM_HVC_ARGS ArmHvcArgs;
  64. // Send a PSCI 0.2 SYSTEM_RESET command
  65. ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
  66. ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
  67. switch (mArmPsciMethod) {
  68. case 1:
  69. ArmCallHvc (&ArmHvcArgs);
  70. break;
  71. case 2:
  72. ArmCallSmc (&ArmSmcArgs);
  73. break;
  74. default:
  75. DEBUG ((EFI_D_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
  76. }
  77. }
  78. /**
  79. This function causes a system-wide initialization (warm reset), in which all processors
  80. are set to their initial state. Pending cycles are not corrupted.
  81. If this function returns, it means that the system does not support warm reset.
  82. **/
  83. VOID
  84. EFIAPI
  85. ResetWarm (
  86. VOID
  87. )
  88. {
  89. // Map a warm reset into a cold reset
  90. ResetCold ();
  91. }
  92. /**
  93. This function causes the system to enter a power state equivalent
  94. to the ACPI G2/S5 or G3 states.
  95. If this function returns, it means that the system does not support shutdown reset.
  96. **/
  97. VOID
  98. EFIAPI
  99. ResetShutdown (
  100. VOID
  101. )
  102. {
  103. ARM_SMC_ARGS ArmSmcArgs;
  104. ARM_HVC_ARGS ArmHvcArgs;
  105. // Send a PSCI 0.2 SYSTEM_OFF command
  106. ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
  107. ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
  108. switch (mArmPsciMethod) {
  109. case 1:
  110. ArmCallHvc (&ArmHvcArgs);
  111. break;
  112. case 2:
  113. ArmCallSmc (&ArmSmcArgs);
  114. break;
  115. default:
  116. DEBUG ((EFI_D_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
  117. }
  118. }
  119. /**
  120. This function causes the system to enter S3 and then wake up immediately.
  121. If this function returns, it means that the system does not support S3 feature.
  122. **/
  123. VOID
  124. EFIAPI
  125. EnterS3WithImmediateWake (
  126. VOID
  127. )
  128. {
  129. // not implemented
  130. }
  131. /**
  132. This function causes a systemwide reset. The exact type of the reset is
  133. defined by the EFI_GUID that follows the Null-terminated Unicode string passed
  134. into ResetData. If the platform does not recognize the EFI_GUID in ResetData
  135. the platform must pick a supported reset type to perform.The platform may
  136. optionally log the parameters from any non-normal reset that occurs.
  137. @param[in] DataSize The size, in bytes, of ResetData.
  138. @param[in] ResetData The data buffer starts with a Null-terminated string,
  139. followed by the EFI_GUID.
  140. **/
  141. VOID
  142. EFIAPI
  143. ResetPlatformSpecific (
  144. IN UINTN DataSize,
  145. IN VOID *ResetData
  146. )
  147. {
  148. // Map the platform specific reset as reboot
  149. ResetCold ();
  150. }