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