]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/S3SaveStateDxe/AcpiS3ContextSave.c
MdeModulePkg: Refine casting expression result to bigger size
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / S3SaveStateDxe / AcpiS3ContextSave.c
CommitLineData
bd890a73
SZ
1/** @file\r
2 This is the implementation to save ACPI S3 Context.\r
3\r
16f69227 4Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
bd890a73
SZ
5\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions\r
8of the BSD License which accompanies this distribution. The\r
9full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <PiDxe.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/HobLib.h>\r
22#include <Library/LockBoxLib.h>\r
23#include <Library/PcdLib.h>\r
24#include <Library/DebugLib.h>\r
25#include <Guid/AcpiS3Context.h>\r
26#include <Guid/Acpi.h>\r
27#include <IndustryStandard/Acpi.h>\r
28#include <Protocol/LockBox.h>\r
29\r
30//\r
31// 8 extra pages for PF handler.\r
32//\r
33#define EXTRA_PAGE_TABLE_PAGES 8\r
34\r
35EFI_GUID mAcpiS3IdtrProfileGuid = {\r
36 0xdea652b0, 0xd587, 0x4c54, { 0xb5, 0xb4, 0xc6, 0x82, 0xe7, 0xa0, 0xaa, 0x3d }\r
37};\r
38\r
39/**\r
40 Allocate memory below 4G memory address.\r
41\r
42 This function allocates memory below 4G memory address.\r
43\r
44 @param MemoryType Memory type of memory to allocate.\r
45 @param Size Size of memory to allocate.\r
46 \r
47 @return Allocated address for output.\r
48\r
49**/\r
50VOID*\r
51AllocateMemoryBelow4G (\r
52 IN EFI_MEMORY_TYPE MemoryType,\r
53 IN UINTN Size\r
54 )\r
55{\r
56 UINTN Pages;\r
57 EFI_PHYSICAL_ADDRESS Address;\r
58 EFI_STATUS Status;\r
59 VOID* Buffer;\r
60\r
61 Pages = EFI_SIZE_TO_PAGES (Size);\r
62 Address = 0xffffffff;\r
63\r
64 Status = gBS->AllocatePages (\r
65 AllocateMaxAddress,\r
66 MemoryType,\r
67 Pages,\r
68 &Address\r
69 );\r
70 ASSERT_EFI_ERROR (Status);\r
71\r
72 Buffer = (VOID *) (UINTN) Address;\r
73 ZeroMem (Buffer, Size);\r
74\r
75 return Buffer;\r
76}\r
77\r
78/**\r
79\r
80 This function scan ACPI table in RSDT.\r
81\r
82 @param Rsdt ACPI RSDT\r
83 @param Signature ACPI table signature\r
84\r
85 @return ACPI table\r
86\r
87**/\r
88VOID *\r
89ScanTableInRSDT (\r
90 IN EFI_ACPI_DESCRIPTION_HEADER *Rsdt,\r
91 IN UINT32 Signature\r
92 )\r
93{\r
94 UINTN Index;\r
95 UINT32 EntryCount;\r
96 UINT32 *EntryPtr;\r
97 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
98\r
99 if (Rsdt == NULL) {\r
100 return NULL;\r
101 }\r
102\r
103 EntryCount = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);\r
104 \r
105 EntryPtr = (UINT32 *)(Rsdt + 1);\r
106 for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {\r
107 Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));\r
108 if (Table->Signature == Signature) {\r
109 return Table;\r
110 }\r
111 }\r
112 \r
113 return NULL;\r
114}\r
115\r
116/**\r
117\r
118 This function scan ACPI table in XSDT.\r
119\r
120 @param Xsdt ACPI XSDT\r
121 @param Signature ACPI table signature\r
122\r
123 @return ACPI table\r
124\r
125**/\r
126VOID *\r
127ScanTableInXSDT (\r
128 IN EFI_ACPI_DESCRIPTION_HEADER *Xsdt,\r
129 IN UINT32 Signature\r
130 )\r
131{\r
132 UINTN Index;\r
133 UINT32 EntryCount;\r
134 UINT64 EntryPtr;\r
135 UINTN BasePtr;\r
136 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
137\r
138 if (Xsdt == NULL) {\r
139 return NULL;\r
140 }\r
141\r
142 EntryCount = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);\r
143 \r
144 BasePtr = (UINTN)(Xsdt + 1);\r
145 for (Index = 0; Index < EntryCount; Index ++) {\r
146 CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));\r
147 Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(EntryPtr));\r
148 if (Table->Signature == Signature) {\r
149 return Table;\r
150 }\r
151 }\r
152 \r
153 return NULL;\r
154}\r
155\r
156/**\r
157 To find Facs in FADT.\r
158\r
159 @param Fadt FADT table pointer\r
160 \r
161 @return Facs table pointer.\r
162**/\r
163EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *\r
164FindAcpiFacsFromFadt (\r
165 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
166 )\r
167{\r
168 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
169 UINT64 Data64;\r
170\r
171 if (Fadt == NULL) {\r
172 return NULL;\r
173 }\r
174\r
175 if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
176 Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;\r
177 } else {\r
178 if (Fadt->FirmwareCtrl != 0) {\r
179 Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;\r
180 } else {\r
181 CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof(UINT64));\r
182 Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Data64;\r
183 }\r
184 }\r
185 return Facs;\r
186}\r
187\r
188/**\r
189 To find Facs in Acpi tables.\r
190 \r
191 To find Firmware ACPI control strutcure in Acpi Tables since the S3 waking vector is stored \r
192 in the table.\r
193\r
194 @param AcpiTableGuid The guid used to find ACPI table in UEFI ConfigurationTable.\r
195 \r
196 @return Facs table pointer.\r
197**/\r
198EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *\r
199FindAcpiFacsTableByAcpiGuid (\r
200 IN EFI_GUID *AcpiTableGuid\r
201 )\r
202{\r
203 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
204 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
205 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
206 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
207 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
208 UINTN Index;\r
209\r
210 Rsdp = NULL;\r
211 //\r
212 // found ACPI table RSD_PTR from system table\r
213 //\r
214 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {\r
215 if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), AcpiTableGuid)) {\r
216 //\r
217 // A match was found.\r
218 //\r
219 Rsdp = gST->ConfigurationTable[Index].VendorTable;\r
220 break;\r
221 }\r
222 }\r
223\r
224 if (Rsdp == NULL) {\r
225 return NULL;\r
226 }\r
227\r
228 //\r
229 // Search XSDT\r
230 //\r
231 if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {\r
232 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress;\r
233 Fadt = ScanTableInXSDT (Xsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);\r
234 if (Fadt != NULL) {\r
235 Facs = FindAcpiFacsFromFadt (Fadt);\r
236 if (Facs != NULL) {\r
237 return Facs;\r
238 }\r
239 }\r
240 }\r
241\r
242 //\r
243 // Search RSDT\r
244 //\r
245 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;\r
246 Fadt = ScanTableInRSDT (Rsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);\r
247 if (Fadt != NULL) {\r
248 Facs = FindAcpiFacsFromFadt (Fadt);\r
249 if (Facs != NULL) {\r
250 return Facs;\r
251 }\r
252 }\r
253\r
254 return NULL;\r
255}\r
256\r
257/**\r
258 To find Facs in Acpi tables.\r
259 \r
260 To find Firmware ACPI control strutcure in Acpi Tables since the S3 waking vector is stored \r
261 in the table.\r
262 \r
263 @return Facs table pointer.\r
264**/\r
265EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *\r
266FindAcpiFacsTable (\r
267 VOID\r
268 )\r
269{\r
270 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
271\r
272 Facs = FindAcpiFacsTableByAcpiGuid (&gEfiAcpi20TableGuid);\r
273 if (Facs != NULL) {\r
274 return Facs;\r
275 }\r
276\r
277 return FindAcpiFacsTableByAcpiGuid (&gEfiAcpi10TableGuid);\r
278}\r
279\r
280/**\r
281 The function will check if long mode waking vector is supported.\r
282\r
283 @param[in] Facs Pointer to FACS table.\r
284\r
285 @retval TRUE Long mode waking vector is supported.\r
286 @retval FALSE Long mode waking vector is not supported.\r
287\r
288**/\r
289BOOLEAN\r
290IsLongModeWakingVectorSupport (\r
291 IN EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs\r
292 )\r
293{\r
294 if ((Facs == NULL) ||\r
295 (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ) {\r
296 //\r
297 // Something wrong with FACS.\r
298 //\r
299 return FALSE;\r
300 }\r
301 if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
302 ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0)) {\r
303 //\r
304 // BIOS supports 64bit waking vector.\r
305 //\r
306 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
307 return TRUE;\r
308 }\r
309 }\r
310 return FALSE;\r
311}\r
312\r
313/**\r
314 Allocates page table buffer.\r
315\r
316 @param[in] LongModeWakingVectorSupport Support long mode waking vector or not.\r
317\r
318 If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1 \r
319 virtual to physical mapping page table when long mode waking vector is supported, otherwise\r
320 create 4G page table when long mode waking vector is not supported and let PF handler to\r
321 handle > 4G request.\r
322 If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. \r
323 \r
324 @return Page table base address. \r
325\r
326**/\r
327EFI_PHYSICAL_ADDRESS\r
328S3AllocatePageTablesBuffer (\r
329 IN BOOLEAN LongModeWakingVectorSupport\r
330 )\r
331{ \r
332 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
333 UINTN ExtraPageTablePages;\r
334 UINT32 RegEax;\r
335 UINT32 RegEdx;\r
336 UINT8 PhysicalAddressBits;\r
337 UINT32 NumberOfPml4EntriesNeeded;\r
338 UINT32 NumberOfPdpEntriesNeeded;\r
339 EFI_PHYSICAL_ADDRESS S3NvsPageTableAddress;\r
340 UINTN TotalPageTableSize;\r
341 VOID *Hob;\r
342 BOOLEAN Page1GSupport;\r
343\r
344 Page1GSupport = FALSE;\r
345 if (PcdGetBool(PcdUse1GPageTable)) {\r
346 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
347 if (RegEax >= 0x80000001) {\r
348 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
349 if ((RegEdx & BIT26) != 0) {\r
350 Page1GSupport = TRUE;\r
351 }\r
352 }\r
353 }\r
354\r
355 //\r
356 // Get physical address bits supported.\r
357 //\r
358 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);\r
359 if (Hob != NULL) {\r
360 PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;\r
361 } else {\r
362 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
363 if (RegEax >= 0x80000008) {\r
364 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
365 PhysicalAddressBits = (UINT8) RegEax;\r
366 } else {\r
367 PhysicalAddressBits = 36;\r
368 }\r
369 }\r
370\r
371 //\r
372 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
373 //\r
374 ASSERT (PhysicalAddressBits <= 52);\r
375 if (PhysicalAddressBits > 48) {\r
376 PhysicalAddressBits = 48;\r
377 }\r
378\r
379 ExtraPageTablePages = 0;\r
380 if (!LongModeWakingVectorSupport) {\r
381 //\r
382 // Create 4G page table when BIOS does not support long mode waking vector,\r
383 // and let PF handler to handle > 4G request.\r
384 //\r
385 PhysicalAddressBits = 32;\r
386 ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;\r
387 }\r
388\r
389 //\r
390 // Calculate the table entries needed.\r
391 //\r
392 if (PhysicalAddressBits <= 39 ) {\r
393 NumberOfPml4EntriesNeeded = 1;\r
394 NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));\r
395 } else {\r
396 NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));\r
397 NumberOfPdpEntriesNeeded = 512;\r
398 }\r
399\r
400 //\r
401 // We need calculate whole page size then allocate once, because S3 restore page table does not know each page in Nvs.\r
402 //\r
403 if (!Page1GSupport) {\r
16f69227 404 TotalPageTableSize = 1 + NumberOfPml4EntriesNeeded + NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded;\r
bd890a73 405 } else {\r
16f69227 406 TotalPageTableSize = 1 + NumberOfPml4EntriesNeeded;\r
bd890a73
SZ
407 }\r
408\r
409 TotalPageTableSize += ExtraPageTablePages;\r
410 DEBUG ((EFI_D_ERROR, "AcpiS3ContextSave TotalPageTableSize - 0x%x pages\n", TotalPageTableSize));\r
411\r
412 //\r
413 // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.\r
414 //\r
415 S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize));\r
416 ASSERT (S3NvsPageTableAddress != 0);\r
417 return S3NvsPageTableAddress;\r
418 } else {\r
419 //\r
420 // If DXE is running 32-bit mode, no need to establish page table.\r
421 //\r
422 return (EFI_PHYSICAL_ADDRESS) 0; \r
423 }\r
424}\r
425\r
426/**\r
427 Callback function executed when the EndOfDxe event group is signaled.\r
428\r
429 @param[in] Event Event whose notification function is being invoked.\r
430 @param[in] Context The pointer to the notification function's context, which\r
431 is implementation-dependent.\r
432**/\r
433VOID\r
434EFIAPI\r
435AcpiS3ContextSaveOnEndOfDxe (\r
436 IN EFI_EVENT Event,\r
437 IN VOID *Context\r
438 )\r
439{\r
440 EFI_STATUS Status;\r
441 EFI_PHYSICAL_ADDRESS AcpiS3ContextBuffer;\r
442 ACPI_S3_CONTEXT *AcpiS3Context;\r
443 IA32_DESCRIPTOR *Idtr;\r
444 IA32_IDT_GATE_DESCRIPTOR *IdtGate;\r
445 EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
446 VOID *Interface;\r
447\r
448 DEBUG ((EFI_D_INFO, "AcpiS3ContextSave!\n"));\r
449\r
450 Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface);\r
451 if (EFI_ERROR (Status)) {\r
452 DEBUG ((EFI_D_INFO | EFI_D_WARN, "ACPI S3 context can't be saved without LockBox!\n"));\r
453 goto Done;\r
454 }\r
455\r
456 AcpiS3Context = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(*AcpiS3Context));\r
457 ASSERT (AcpiS3Context != NULL);\r
458 AcpiS3ContextBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context;\r
459\r
460 //\r
461 // Get ACPI Table because we will save its position to variable\r
462 //\r
463 Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) FindAcpiFacsTable ();\r
464 AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS) (UINTN) Facs;\r
465 ASSERT (AcpiS3Context->AcpiFacsTable != 0);\r
466\r
467 IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR));\r
468 Idtr = (IA32_DESCRIPTOR *)(IdtGate + 0x100);\r
469 Idtr->Base = (UINTN)IdtGate;\r
470 Idtr->Limit = (UINT16)(sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 - 1);\r
471 AcpiS3Context->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)Idtr;\r
472\r
473 Status = SaveLockBox (\r
474 &mAcpiS3IdtrProfileGuid,\r
475 (VOID *)(UINTN)Idtr,\r
476 (UINTN)sizeof(IA32_DESCRIPTOR)\r
477 );\r
478 ASSERT_EFI_ERROR (Status);\r
479\r
480 Status = SetLockBoxAttributes (&mAcpiS3IdtrProfileGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
481 ASSERT_EFI_ERROR (Status);\r
482\r
483 //\r
484 // Allocate page table\r
485 //\r
486 AcpiS3Context->S3NvsPageTableAddress = S3AllocatePageTablesBuffer (IsLongModeWakingVectorSupport (Facs));\r
487\r
488 //\r
489 // Allocate stack\r
490 //\r
491 AcpiS3Context->BootScriptStackSize = PcdGet32 (PcdS3BootScriptStackSize);\r
492 AcpiS3Context->BootScriptStackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3BootScriptStackSize));\r
493 ASSERT (AcpiS3Context->BootScriptStackBase != 0);\r
494\r
495 //\r
496 // Allocate a code buffer < 4G for S3 debug to load external code, set invalid code instructions in it.\r
497 //\r
498 AcpiS3Context->S3DebugBufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGE_SIZE);\r
499 SetMem ((VOID *)(UINTN)AcpiS3Context->S3DebugBufferAddress, EFI_PAGE_SIZE, 0xff);\r
500\r
501 DEBUG((EFI_D_INFO, "AcpiS3Context: AcpiFacsTable is 0x%8x\n", AcpiS3Context->AcpiFacsTable));\r
502 DEBUG((EFI_D_INFO, "AcpiS3Context: IdtrProfile is 0x%8x\n", AcpiS3Context->IdtrProfile));\r
503 DEBUG((EFI_D_INFO, "AcpiS3Context: S3NvsPageTableAddress is 0x%8x\n", AcpiS3Context->S3NvsPageTableAddress));\r
504 DEBUG((EFI_D_INFO, "AcpiS3Context: S3DebugBufferAddress is 0x%8x\n", AcpiS3Context->S3DebugBufferAddress));\r
505 DEBUG((EFI_D_INFO, "AcpiS3Context: BootScriptStackBase is 0x%8x\n", AcpiS3Context->BootScriptStackBase));\r
506 DEBUG((EFI_D_INFO, "AcpiS3Context: BootScriptStackSize is 0x%8x\n", AcpiS3Context->BootScriptStackSize));\r
507\r
508 Status = SaveLockBox (\r
509 &gEfiAcpiVariableGuid,\r
510 &AcpiS3ContextBuffer,\r
511 sizeof(AcpiS3ContextBuffer)\r
512 );\r
513 ASSERT_EFI_ERROR (Status);\r
514\r
515 Status = SaveLockBox (\r
516 &gEfiAcpiS3ContextGuid,\r
517 (VOID *)(UINTN)AcpiS3Context,\r
518 (UINTN)sizeof(*AcpiS3Context)\r
519 );\r
520 ASSERT_EFI_ERROR (Status);\r
521\r
522 Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
523 ASSERT_EFI_ERROR (Status);\r
524\r
525Done:\r
526 //\r
527 // Close the event, deregistering the callback and freeing resources.\r
528 //\r
529 Status = gBS->CloseEvent (Event);\r
530 ASSERT_EFI_ERROR (Status);\r
531}\r
532\r