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
16EFI_PEI_RESET2_PPI mPpiReset2 = {
18};
19
20EFI_GUID *mProcessingOrder[] = {
21 &gEdkiiPlatformSpecificResetFilterPpiGuid,
22 &gEdkiiPlatformSpecificResetNotificationPpiGuid,
23 &gEdkiiPlatformSpecificResetHandlerPpiGuid
24};
25
26RESET_FILTER_INSTANCE mResetFilter = {
27 {
30 },
31 &gEdkiiPlatformSpecificResetFilterPpiGuid
32};
33
34RESET_FILTER_INSTANCE mResetNotification = {
35 {
38 },
39 &gEdkiiPlatformSpecificResetNotificationPpiGuid
40};
41
42RESET_FILTER_INSTANCE mResetHandler = {
43 {
46 },
47 &gEdkiiPlatformSpecificResetHandlerPpiGuid
48};
49
50EFI_PEI_PPI_DESCRIPTOR mPpiListReset[] = {
51 {
52 EFI_PEI_PPI_DESCRIPTOR_PPI,
53 &gEfiPeiReset2PpiGuid,
54 &mPpiReset2
55 },
56 {
57 EFI_PEI_PPI_DESCRIPTOR_PPI,
58 &gEdkiiPlatformSpecificResetFilterPpiGuid,
59 &mResetFilter.ResetFilter
60 },
61 {
62 EFI_PEI_PPI_DESCRIPTOR_PPI,
63 &gEdkiiPlatformSpecificResetNotificationPpiGuid,
64 &mResetNotification.ResetFilter
65 },
66 {
67 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
68 &gEdkiiPlatformSpecificResetHandlerPpiGuid,
69 &mResetHandler.ResetFilter
70 }
71};
72
95EFIAPI
98 IN EFI_RESET_SYSTEM ResetFunction
99 )
100{
101 RESET_FILTER_INSTANCE *ResetFilter;
102 RESET_FILTER_LIST *List;
103 VOID *Hob;
104 UINTN Index;
105
106 if (ResetFunction == NULL) {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 ResetFilter = (RESET_FILTER_INSTANCE *)This;
111 ASSERT (
112 CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetFilterPpiGuid) ||
113 CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetNotificationPpiGuid) ||
114 CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetHandlerPpiGuid)
115 );
116
117 Hob = GetFirstGuidHob (ResetFilter->Guid);
118 if (Hob == NULL) {
119 //
120 // When the GUIDed HOB doesn't exist, create it.
121 //
123 ResetFilter->Guid,
124 sizeof (RESET_FILTER_LIST) + sizeof (EFI_RESET_SYSTEM) * PcdGet32 (PcdMaximumPeiResetNotifies)
125 );
126 if (List == NULL) {
127 return EFI_OUT_OF_RESOURCES;
128 }
129
130 List->Signature = RESET_FILTER_LIST_SIGNATURE;
131 List->Count = PcdGet32 (PcdMaximumPeiResetNotifies);
132 ZeroMem (List->ResetFilters, sizeof (EFI_RESET_SYSTEM) * List->Count);
133 List->ResetFilters[0] = ResetFunction;
134 return EFI_SUCCESS;
135 } else {
136 List = (RESET_FILTER_LIST *)GET_GUID_HOB_DATA (Hob);
137 ASSERT (List->Signature == RESET_FILTER_LIST_SIGNATURE);
138 //
139 // Firstly check whether the ResetFunction is already registerred.
140 //
141 for (Index = 0; Index < List->Count; Index++) {
142 if (List->ResetFilters[Index] == ResetFunction) {
143 break;
144 }
145 }
146
147 if (Index != List->Count) {
148 return EFI_ALREADY_STARTED;
149 }
150
151 //
152 // Secondly find the first free slot.
153 //
154 for (Index = 0; Index < List->Count; Index++) {
155 if (List->ResetFilters[Index] == NULL) {
156 break;
157 }
158 }
159
160 if (Index == List->Count) {
161 return EFI_OUT_OF_RESOURCES;
162 }
163
164 List->ResetFilters[Index] = ResetFunction;
165 return EFI_SUCCESS;
166 }
167}
168
185EFIAPI
188 IN EFI_RESET_SYSTEM ResetFunction
189 )
190{
191 RESET_FILTER_INSTANCE *ResetFilter;
192 RESET_FILTER_LIST *List;
193 VOID *Hob;
194 UINTN Index;
195
196 if (ResetFunction == NULL) {
197 return EFI_INVALID_PARAMETER;
198 }
199
200 ResetFilter = (RESET_FILTER_INSTANCE *)This;
201 ASSERT (
202 CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetFilterPpiGuid) ||
203 CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetNotificationPpiGuid) ||
204 CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetHandlerPpiGuid)
205 );
206
207 Hob = GetFirstGuidHob (ResetFilter->Guid);
208 if (Hob == NULL) {
209 return EFI_INVALID_PARAMETER;
210 }
211
212 List = (RESET_FILTER_LIST *)GET_GUID_HOB_DATA (Hob);
213 ASSERT (List->Signature == RESET_FILTER_LIST_SIGNATURE);
214 for (Index = 0; Index < List->Count; Index++) {
215 if (List->ResetFilters[Index] == ResetFunction) {
216 break;
217 }
218 }
219
220 if (Index == List->Count) {
221 return EFI_INVALID_PARAMETER;
222 }
223
224 List->ResetFilters[Index] = NULL;
225 return EFI_SUCCESS;
226}
227
242EFIAPI
244 IN EFI_PEI_FILE_HANDLE FileHandle,
245 IN CONST EFI_PEI_SERVICES **PeiServices
246 )
247{
248 EFI_STATUS Status;
249 VOID *Ppi;
250
251 Status = PeiServicesLocatePpi (&gEfiPeiReset2PpiGuid, 0, NULL, (VOID **)&Ppi);
252 if (Status != EFI_NOT_FOUND) {
253 return EFI_ALREADY_STARTED;
254 }
255
256 PeiServicesInstallPpi (mPpiListReset);
257
258 return Status;
259}
260
276VOID
277EFIAPI
279 IN EFI_RESET_TYPE ResetType,
280 IN EFI_STATUS ResetStatus,
281 IN UINTN DataSize,
282 IN VOID *ResetData OPTIONAL
283 )
284{
285 VOID *Hob;
286 UINTN Index;
287 RESET_FILTER_LIST *List;
288 UINTN OrderIndex;
289 UINT8 RecursionDepth;
290 UINT8 *RecursionDepthPointer;
291
292 //
293 // The recursion depth is stored in GUIDed HOB using gEfiCallerIdGuid.
294 //
295 Hob = GetFirstGuidHob (&gEfiCallerIdGuid);
296 if (Hob == NULL) {
297 RecursionDepth = 0;
298 RecursionDepthPointer = BuildGuidDataHob (&gEfiCallerIdGuid, &RecursionDepth, sizeof (RecursionDepth));
299 } else {
300 RecursionDepthPointer = (UINT8 *)GET_GUID_HOB_DATA (Hob);
301 }
302
303 //
304 // Only do REPORT_STATUS_CODE() on first call to ResetSystem()
305 //
306 if (*RecursionDepthPointer == 0) {
307 //
308 // Indicate reset system PEI service is called.
309 //
310 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_RESET_SYSTEM));
311 }
312
313 //
314 // Increase the call depth
315 //
316 (*RecursionDepthPointer)++;
317 DEBUG ((DEBUG_INFO, "PEI ResetSystem2: Reset call depth = %d.\n", *RecursionDepthPointer));
318
319 if (*RecursionDepthPointer <= MAX_RESET_NOTIFY_DEPTH) {
320 //
321 // Iteratively call Reset Filters and Reset Handlers.
322 //
323 for (OrderIndex = 0; OrderIndex < ARRAY_SIZE (mProcessingOrder); OrderIndex++) {
324 Hob = GetFirstGuidHob (mProcessingOrder[OrderIndex]);
325 if (Hob != NULL) {
326 List = (RESET_FILTER_LIST *)GET_GUID_HOB_DATA (Hob);
327 ASSERT (List->Signature == RESET_FILTER_LIST_SIGNATURE);
328
329 for (Index = 0; Index < List->Count; Index++) {
330 if (List->ResetFilters[Index] != NULL) {
331 List->ResetFilters[Index](ResetType, ResetStatus, DataSize, ResetData);
332 }
333 }
334 }
335 }
336 } else {
337 ASSERT (ResetType < ARRAY_SIZE (mResetTypeStr));
338 DEBUG ((DEBUG_ERROR, "PEI ResetSystem2: Maximum reset call depth is met. Use the current reset type: %s!\n", mResetTypeStr[ResetType]));
339 }
340
341 switch (ResetType) {
342 case EfiResetWarm:
343 ResetWarm ();
344 break;
345
346 case EfiResetCold:
347 ResetCold ();
348 break;
349
350 case EfiResetShutdown:
351 ResetShutdown ();
352 return;
353
355 ResetPlatformSpecific (DataSize, ResetData);
356 return;
357
358 default:
359 return;
360 }
361
362 //
363 // Given we should have reset getting here would be bad
364 //
365 ASSERT (FALSE);
366}
UINT64 UINTN
VOID EFIAPI ResetWarm(VOID)
VOID EFIAPI ResetShutdown(VOID)
VOID EFIAPI ResetPlatformSpecific(IN UINTN DataSize, IN VOID *ResetData)
VOID EFIAPI ResetCold(VOID)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
Definition: HobLib.c:375
VOID *EFIAPI BuildGuidHob(IN CONST EFI_GUID *Guid, IN UINTN DataLength)
Definition: HobLib.c:336
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#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 DEBUG(Expression)
Definition: DebugLib.h:434
#define REPORT_STATUS_CODE(Type, Value)
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
EFI_STATUS EFIAPI RegisterResetNotify(IN EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI *This, IN EFI_RESET_SYSTEM ResetFunction)
Definition: ResetSystem.c:96
VOID EFIAPI ResetSystem2(IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINTN DataSize, IN VOID *ResetData OPTIONAL)
Definition: ResetSystem.c:278
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
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_RESET_TYPE
@ EfiResetCold
@ EfiResetShutdown
@ EfiResetWarm
@ EfiResetPlatformSpecific
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
Definition: Base.h:213