TianoCore EDK2 master
Loading...
Searching...
No Matches
ResetSystem.c
Go to the documentation of this file.
1
10#include "ResetSystem.h"
11
12GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mResetTypeStr[] = {
13 L"Cold", L"Warm", L"Shutdown", L"PlatformSpecific"
14};
15
16//
17// The current ResetSystem() notification recursion depth
18//
19UINTN mResetNotifyDepth = 0;
20
43EFIAPI
46 IN EFI_RESET_SYSTEM ResetFunction
47 )
48{
50 LIST_ENTRY *Link;
51 RESET_NOTIFY_ENTRY *Entry;
52
53 if (ResetFunction == NULL) {
54 return EFI_INVALID_PARAMETER;
55 }
56
57 Instance = RESET_NOTIFICATION_INSTANCE_FROM_THIS (This);
58
59 for ( Link = GetFirstNode (&Instance->ResetNotifies)
60 ; !IsNull (&Instance->ResetNotifies, Link)
61 ; Link = GetNextNode (&Instance->ResetNotifies, Link)
62 )
63 {
64 Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
65 if (Entry->ResetNotify == ResetFunction) {
66 return EFI_ALREADY_STARTED;
67 }
68 }
69
70 ASSERT (IsNull (&Instance->ResetNotifies, Link));
71 Entry = AllocatePool (sizeof (*Entry));
72 if (Entry == NULL) {
73 return EFI_OUT_OF_RESOURCES;
74 }
75
76 Entry->Signature = RESET_NOTIFY_ENTRY_SIGNATURE;
77 Entry->ResetNotify = ResetFunction;
78 InsertTailList (&Instance->ResetNotifies, &Entry->Link);
79 return EFI_SUCCESS;
80}
81
98EFIAPI
101 IN EFI_RESET_SYSTEM ResetFunction
102 )
103{
105 LIST_ENTRY *Link;
106 RESET_NOTIFY_ENTRY *Entry;
107
108 if (ResetFunction == NULL) {
109 return EFI_INVALID_PARAMETER;
110 }
111
112 Instance = RESET_NOTIFICATION_INSTANCE_FROM_THIS (This);
113
114 for ( Link = GetFirstNode (&Instance->ResetNotifies)
115 ; !IsNull (&Instance->ResetNotifies, Link)
116 ; Link = GetNextNode (&Instance->ResetNotifies, Link)
117 )
118 {
119 Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
120 if (Entry->ResetNotify == ResetFunction) {
121 RemoveEntryList (&Entry->Link);
122 FreePool (Entry);
123 return EFI_SUCCESS;
124 }
125 }
126
127 return EFI_INVALID_PARAMETER;
128}
129
130RESET_NOTIFICATION_INSTANCE mResetNotification = {
131 RESET_NOTIFICATION_INSTANCE_SIGNATURE,
132 {
135 },
136 INITIALIZE_LIST_HEAD_VARIABLE (mResetNotification.ResetNotifies)
137};
138
139RESET_NOTIFICATION_INSTANCE mPlatformSpecificResetFilter = {
140 RESET_NOTIFICATION_INSTANCE_SIGNATURE,
141 {
144 },
145 INITIALIZE_LIST_HEAD_VARIABLE (mPlatformSpecificResetFilter.ResetNotifies)
146};
147
148RESET_NOTIFICATION_INSTANCE mPlatformSpecificResetHandler = {
149 RESET_NOTIFICATION_INSTANCE_SIGNATURE,
150 {
153 },
154 INITIALIZE_LIST_HEAD_VARIABLE (mPlatformSpecificResetHandler.ResetNotifies)
155};
156
170EFIAPI
172 IN EFI_HANDLE ImageHandle,
173 IN EFI_SYSTEM_TABLE *SystemTable
174 )
175{
176 EFI_STATUS Status;
177 EFI_HANDLE Handle;
178
179 //
180 // Make sure the Reset Architectural Protocol is not already installed in the system
181 //
182 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);
183
184 //
185 // Hook the runtime service table
186 //
187 gRT->ResetSystem = RuntimeServiceResetSystem;
188
189 //
190 // Now install the Reset RT AP on a new handle
191 //
192 Handle = NULL;
193 Status = gBS->InstallMultipleProtocolInterfaces (
194 &Handle,
195 &gEfiResetArchProtocolGuid,
196 NULL,
197 &gEfiResetNotificationProtocolGuid,
198 &mResetNotification.ResetNotification,
199 &gEdkiiPlatformSpecificResetFilterProtocolGuid,
200 &mPlatformSpecificResetFilter.ResetNotification,
201 &gEdkiiPlatformSpecificResetHandlerProtocolGuid,
202 &mPlatformSpecificResetHandler.ResetNotification,
203 NULL
204 );
205 ASSERT_EFI_ERROR (Status);
206
207 return Status;
208}
209
225VOID
226EFIAPI
228 IN EFI_RESET_TYPE ResetType,
229 IN EFI_STATUS ResetStatus,
230 IN UINTN DataSize,
231 IN VOID *ResetData OPTIONAL
232 )
233{
234 LIST_ENTRY *Link;
235 RESET_NOTIFY_ENTRY *Entry;
236
237 //
238 // Only do REPORT_STATUS_CODE() on first call to RuntimeServiceResetSystem()
239 //
240 if (mResetNotifyDepth == 0) {
241 //
242 // Indicate reset system runtime service is called.
243 //
244 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM));
245 }
246
247 mResetNotifyDepth++;
248 DEBUG ((
249 DEBUG_INFO,
250 "DXE ResetSystem2: ResetType %s, Call Depth = %d.\n",
251 mResetTypeStr[ResetType],
252 mResetNotifyDepth
253 ));
254
255 if ((ResetData != NULL) && (DataSize != 0)) {
256 DEBUG ((
257 DEBUG_INFO,
258 "DXE ResetSystem2: ResetData: %s\n",
259 ResetData
260 ));
261 }
262
263 if (mResetNotifyDepth <= MAX_RESET_NOTIFY_DEPTH) {
264 if (!EfiAtRuntime ()) {
265 //
266 // Call reset notification functions registered through the
267 // EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL.
268 //
269 for ( Link = GetFirstNode (&mPlatformSpecificResetFilter.ResetNotifies)
270 ; !IsNull (&mPlatformSpecificResetFilter.ResetNotifies, Link)
271 ; Link = GetNextNode (&mPlatformSpecificResetFilter.ResetNotifies, Link)
272 )
273 {
274 Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
275 Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
276 }
277
278 //
279 // Call reset notification functions registered through the
280 // EFI_RESET_NOTIFICATION_PROTOCOL.
281 //
282 for ( Link = GetFirstNode (&mResetNotification.ResetNotifies)
283 ; !IsNull (&mResetNotification.ResetNotifies, Link)
284 ; Link = GetNextNode (&mResetNotification.ResetNotifies, Link)
285 )
286 {
287 Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
288 Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
289 }
290
291 //
292 // call reset notification functions registered through the
293 // EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL.
294 //
295 for ( Link = GetFirstNode (&mPlatformSpecificResetHandler.ResetNotifies)
296 ; !IsNull (&mPlatformSpecificResetHandler.ResetNotifies, Link)
297 ; Link = GetNextNode (&mPlatformSpecificResetHandler.ResetNotifies, Link)
298 )
299 {
300 Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
301 Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
302 }
303 }
304 } else {
305 ASSERT (ResetType < ARRAY_SIZE (mResetTypeStr));
306 DEBUG ((DEBUG_ERROR, "DXE ResetSystem2: Maximum reset call depth is met. Use the current reset type: %s!\n", mResetTypeStr[ResetType]));
307 }
308
309 switch (ResetType) {
310 case EfiResetWarm:
311
312 ResetWarm ();
313 break;
314
315 case EfiResetCold:
316 ResetCold ();
317 break;
318
319 case EfiResetShutdown:
320 ResetShutdown ();
321 return;
322
324 ResetPlatformSpecific (DataSize, ResetData);
325 return;
326
327 default:
328 return;
329 }
330
331 //
332 // Given we should have reset getting here would be bad
333 //
334 ASSERT (FALSE);
335}
UINT64 UINTN
VOID EFIAPI ResetWarm(VOID)
VOID EFIAPI ResetShutdown(VOID)
VOID EFIAPI ResetPlatformSpecific(IN UINTN DataSize, IN VOID *ResetData)
VOID EFIAPI ResetCold(VOID)
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2904
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)
Definition: DebugLib.h:535
#define REPORT_STATUS_CODE(Type, Value)
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI RegisterResetNotify(IN EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI *This, IN EFI_RESET_SYSTEM ResetFunction)
Definition: ResetSystem.c:96
EFI_STATUS EFIAPI UnregisterResetNotify(IN EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI *This, IN EFI_RESET_SYSTEM ResetFunction)
Definition: ResetSystem.c:186
EFI_STATUS EFIAPI InitializeResetSystem(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: ResetSystem.c:243
VOID EFIAPI RuntimeServiceResetSystem(IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINTN DataSize, IN VOID *ResetData OPTIONAL)
Definition: ResetSystem.c:227
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_RESET_TYPE
@ EfiResetCold
@ EfiResetShutdown
@ EfiResetWarm
@ EfiResetPlatformSpecific
BOOLEAN EFIAPI EfiAtRuntime(VOID)
Definition: RuntimeLib.c:167
VOID(EFIAPI * EFI_RESET_SYSTEM)(IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINTN DataSize, IN VOID *ResetData OPTIONAL)
Definition: UefiSpec.h:1089