MdeModulePkg: Fix potential integer overflow issue
[mirror_edk2.git] / MdeModulePkg / Library / SmmLockBoxLib / SmmLockBoxSmmLib.c
CommitLineData
1c837cd5 1/** @file\r
2\r
579b5ef2 3Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
1c837cd5 4\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions\r
7of the BSD License which accompanies this distribution. The\r
8full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PiSmm.h>\r
17#include <Library/SmmServicesTableLib.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/LockBoxLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Guid/SmmLockBox.h>\r
23\r
24#include "SmmLockBoxLibPrivate.h"\r
25\r
26/**\r
27 We need handle this library carefully. Only one library instance will construct the environment.\r
28 Below 2 global variable can only be used in constructor. They should NOT be used in any other library functions.\r
29**/\r
30SMM_LOCK_BOX_CONTEXT mSmmLockBoxContext;\r
31LIST_ENTRY mLockBoxQueue = INITIALIZE_LIST_HEAD_VARIABLE (mLockBoxQueue);\r
32\r
33/**\r
34 This function return SmmLockBox context from SMST.\r
35\r
36 @return SmmLockBox context from SMST.\r
37**/\r
38SMM_LOCK_BOX_CONTEXT *\r
39InternalGetSmmLockBoxContext (\r
40 VOID\r
41 )\r
42{\r
43 UINTN Index;\r
44\r
45 //\r
46 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone\r
47 //\r
48 for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) {\r
49 if (CompareGuid (&gSmst->SmmConfigurationTable[Index].VendorGuid, &gEfiSmmLockBoxCommunicationGuid)) {\r
50 //\r
51 // Found. That means some other library instance is already run.\r
52 // No need to install again, just return.\r
53 //\r
54 return (SMM_LOCK_BOX_CONTEXT *)gSmst->SmmConfigurationTable[Index].VendorTable;\r
55 }\r
56 }\r
57\r
58 //\r
59 // Not found.\r
60 //\r
61 return NULL;\r
62}\r
63\r
64/**\r
65 Constructor for SmmLockBox library.\r
66 This is used to set SmmLockBox context, which will be used in PEI phase in S3 boot path later.\r
67\r
68 @param[in] ImageHandle Image handle of this driver.\r
69 @param[in] SystemTable A Pointer to the EFI System Table.\r
70\r
71 @retval EFI_SUCEESS \r
72 @return Others Some error occurs.\r
73**/\r
74EFI_STATUS\r
75EFIAPI\r
76SmmLockBoxSmmConstructuor (\r
77 IN EFI_HANDLE ImageHandle,\r
78 IN EFI_SYSTEM_TABLE *SystemTable\r
79 )\r
80{\r
81 EFI_STATUS Status;\r
82 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
83\r
84 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Enter\n"));\r
85\r
86 //\r
87 // Check if gEfiSmmLockBoxCommunicationGuid is installed by someone\r
88 //\r
89 SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
90 if (SmmLockBoxContext != NULL) {\r
91 //\r
92 // Find it. That means some other library instance is already run.\r
93 // No need to install again, just return.\r
94 //\r
95 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - already installed\n"));\r
96 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Exit\n"));\r
97 return EFI_SUCCESS;\r
98 }\r
99\r
100 //\r
101 // If no one install this, it means this is first instance. Install it.\r
102 //\r
103 if (sizeof(UINTN) == sizeof(UINT64)) {\r
104 mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_64;\r
105 } else {\r
106 mSmmLockBoxContext.Signature = SMM_LOCK_BOX_SIGNATURE_32;\r
107 }\r
108 mSmmLockBoxContext.LockBoxDataAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)&mLockBoxQueue;\r
109\r
110 Status = gSmst->SmmInstallConfigurationTable (\r
111 gSmst,\r
112 &gEfiSmmLockBoxCommunicationGuid,\r
113 &mSmmLockBoxContext,\r
114 sizeof(mSmmLockBoxContext)\r
115 );\r
116 ASSERT_EFI_ERROR (Status);\r
117\r
118 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxContext - %x\n", (UINTN)&mSmmLockBoxContext));\r
119 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib LockBoxDataAddress - %x\n", (UINTN)&mLockBoxQueue));\r
120 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SmmLockBoxSmmConstructuor - Exit\n"));\r
121\r
122 return Status;\r
123}\r
124\r
125/**\r
126 This function return SmmLockBox queue address.\r
127\r
128 @return SmmLockBox queue address.\r
129**/\r
130LIST_ENTRY *\r
131InternalGetLockBoxQueue (\r
132 VOID\r
133 )\r
134{\r
135 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
136\r
137 SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
138 ASSERT (SmmLockBoxContext != NULL);\r
139 if (SmmLockBoxContext == NULL) {\r
140 return NULL;\r
141 }\r
142 return (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
143}\r
144\r
145/**\r
146 This function find LockBox by GUID.\r
147\r
148 @param Guid The guid to indentify the LockBox\r
149\r
150 @return LockBoxData\r
151**/\r
152SMM_LOCK_BOX_DATA *\r
153InternalFindLockBoxByGuid (\r
154 IN EFI_GUID *Guid\r
155 )\r
156{\r
157 LIST_ENTRY *Link;\r
158 SMM_LOCK_BOX_DATA *LockBox;\r
159 LIST_ENTRY *LockBoxQueue;\r
160\r
161 LockBoxQueue = InternalGetLockBoxQueue ();\r
162 ASSERT (LockBoxQueue != NULL);\r
163\r
164 for (Link = LockBoxQueue->ForwardLink;\r
165 Link != LockBoxQueue;\r
166 Link = Link->ForwardLink) {\r
167 LockBox = BASE_CR (\r
168 Link,\r
169 SMM_LOCK_BOX_DATA,\r
170 Link\r
171 );\r
172 if (CompareGuid (&LockBox->Guid, Guid)) {\r
173 return LockBox;\r
174 }\r
175 }\r
176 return NULL;\r
177}\r
178\r
179/**\r
180 This function will save confidential information to lockbox.\r
181\r
182 @param Guid the guid to identify the confidential information\r
183 @param Buffer the address of the confidential information\r
184 @param Length the length of the confidential information\r
185\r
186 @retval RETURN_SUCCESS the information is saved successfully.\r
187 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0\r
188 @retval RETURN_ALREADY_STARTED the requested GUID already exist.\r
189 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.\r
190 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
191 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
192 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
193**/\r
194RETURN_STATUS\r
195EFIAPI\r
196SaveLockBox (\r
197 IN GUID *Guid,\r
198 IN VOID *Buffer,\r
199 IN UINTN Length\r
200 )\r
201{\r
202 SMM_LOCK_BOX_DATA *LockBox;\r
203 EFI_PHYSICAL_ADDRESS SmramBuffer;\r
204 EFI_STATUS Status;\r
205 LIST_ENTRY *LockBoxQueue;\r
206\r
207 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Enter\n"));\r
208\r
209 //\r
210 // Basic check\r
211 //\r
212 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {\r
213 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
214 return EFI_INVALID_PARAMETER;\r
215 }\r
216\r
217 //\r
218 // Find LockBox\r
219 //\r
220 LockBox = InternalFindLockBoxByGuid (Guid);\r
221 if (LockBox != NULL) {\r
222 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_ALREADY_STARTED));\r
223 return EFI_ALREADY_STARTED;\r
224 }\r
225\r
226 //\r
227 // Allocate SMRAM buffer\r
228 //\r
229 Status = gSmst->SmmAllocatePages (\r
230 AllocateAnyPages,\r
231 EfiRuntimeServicesData,\r
232 EFI_SIZE_TO_PAGES (Length),\r
233 &SmramBuffer\r
234 );\r
235 ASSERT_EFI_ERROR (Status);\r
236 if (EFI_ERROR (Status)) {\r
237 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
238 return EFI_OUT_OF_RESOURCES;\r
239 }\r
240\r
241 //\r
242 // Allocate LockBox\r
243 //\r
244 Status = gSmst->SmmAllocatePool (\r
245 EfiRuntimeServicesData,\r
246 sizeof(*LockBox),\r
247 (VOID **)&LockBox\r
248 );\r
249 ASSERT_EFI_ERROR (Status);\r
250 if (EFI_ERROR (Status)) {\r
251 gSmst->SmmFreePages (SmramBuffer, EFI_SIZE_TO_PAGES (Length));\r
252 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_OUT_OF_RESOURCES));\r
253 return EFI_OUT_OF_RESOURCES;\r
254 }\r
255\r
256 //\r
257 // Save data\r
258 //\r
259 CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)Buffer, Length);\r
260\r
261 //\r
262 // Insert LockBox to queue\r
263 //\r
264 LockBox->Signature = SMM_LOCK_BOX_DATA_SIGNATURE;\r
265 CopyMem (&LockBox->Guid, Guid, sizeof(EFI_GUID));\r
266 LockBox->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
267 LockBox->Length = (UINT64)Length;\r
05ca95e2 268 LockBox->Attributes = 0;\r
1c837cd5 269 LockBox->SmramBuffer = SmramBuffer;\r
ef96ba3c
SZ
270\r
271 DEBUG ((\r
272 EFI_D_INFO,\r
273 "LockBoxGuid - %g, SmramBuffer - 0x%lx, Length - 0x%lx\n",\r
274 &LockBox->Guid,\r
275 LockBox->SmramBuffer,\r
276 LockBox->Length\r
277 ));\r
278\r
1c837cd5 279 LockBoxQueue = InternalGetLockBoxQueue ();\r
280 ASSERT (LockBoxQueue != NULL);\r
281 InsertTailList (LockBoxQueue, &LockBox->Link);\r
282\r
283 //\r
284 // Done\r
285 //\r
286 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SaveLockBox - Exit (%r)\n", EFI_SUCCESS));\r
287 return EFI_SUCCESS;\r
288}\r
289\r
290/**\r
291 This function will set lockbox attributes.\r
292\r
293 @param Guid the guid to identify the confidential information\r
294 @param Attributes the attributes of the lockbox\r
295\r
296 @retval RETURN_SUCCESS the information is saved successfully.\r
297 @retval RETURN_INVALID_PARAMETER attributes is invalid.\r
298 @retval RETURN_NOT_FOUND the requested GUID not found.\r
299 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
300 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
301 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
302**/\r
303RETURN_STATUS\r
304EFIAPI\r
305SetLockBoxAttributes (\r
306 IN GUID *Guid,\r
307 IN UINT64 Attributes\r
308 )\r
309{\r
310 SMM_LOCK_BOX_DATA *LockBox;\r
311\r
312 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Enter\n"));\r
313\r
314 //\r
315 // Basic check\r
316 //\r
317 if ((Guid == NULL) ||\r
318 ((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) {\r
319 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
320 return EFI_INVALID_PARAMETER;\r
321 }\r
322\r
323 //\r
324 // Find LockBox\r
325 //\r
326 LockBox = InternalFindLockBoxByGuid (Guid);\r
327 if (LockBox == NULL) {\r
328 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_NOT_FOUND));\r
329 return EFI_NOT_FOUND;\r
330 }\r
331\r
332 //\r
333 // Update data\r
334 //\r
335 LockBox->Attributes = Attributes;\r
336\r
337 //\r
338 // Done\r
339 //\r
340 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib SetLockBoxAttributes - Exit (%r)\n", EFI_SUCCESS));\r
341 return EFI_SUCCESS;\r
342}\r
343\r
344/**\r
345 This function will update confidential information to lockbox.\r
346\r
347 @param Guid the guid to identify the original confidential information\r
348 @param Offset the offset of the original confidential information\r
349 @param Buffer the address of the updated confidential information\r
350 @param Length the length of the updated confidential information\r
351\r
352 @retval RETURN_SUCCESS the information is saved successfully.\r
353 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.\r
354 @retval RETURN_NOT_FOUND the requested GUID not found.\r
355 @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold new information.\r
356 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
357 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
358 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
359**/\r
360RETURN_STATUS\r
361EFIAPI\r
362UpdateLockBox (\r
363 IN GUID *Guid,\r
364 IN UINTN Offset,\r
365 IN VOID *Buffer,\r
366 IN UINTN Length\r
367 )\r
368{\r
369 SMM_LOCK_BOX_DATA *LockBox;\r
370\r
371 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));\r
372\r
373 //\r
374 // Basic check\r
375 //\r
376 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {\r
377 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
378 return EFI_INVALID_PARAMETER;\r
379 }\r
380\r
381 //\r
382 // Find LockBox\r
383 //\r
384 LockBox = InternalFindLockBoxByGuid (Guid);\r
385 if (LockBox == NULL) {\r
386 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_NOT_FOUND));\r
387 return EFI_NOT_FOUND;\r
388 }\r
389\r
390 //\r
391 // Update data\r
392 //\r
393 if (LockBox->Length < Offset + Length) {\r
394 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));\r
395 return EFI_BUFFER_TOO_SMALL;\r
396 }\r
579b5ef2 397 ASSERT ((UINTN)LockBox->SmramBuffer <= (MAX_ADDRESS - Offset));\r
1c837cd5 398 CopyMem ((VOID *)((UINTN)LockBox->SmramBuffer + Offset), Buffer, Length);\r
399\r
400 //\r
401 // Done\r
402 //\r
403 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n", EFI_SUCCESS));\r
404 return EFI_SUCCESS;\r
405}\r
406\r
407/**\r
408 This function will restore confidential information from lockbox.\r
409\r
410 @param Guid the guid to identify the confidential information\r
411 @param Buffer the address of the restored confidential information\r
412 NULL means restored to original address, Length MUST be NULL at same time.\r
413 @param Length the length of the restored confidential information\r
414\r
415 @retval RETURN_SUCCESS the information is restored successfully.\r
416 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.\r
417 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no \r
418 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
419 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.\r
420 @retval RETURN_NOT_FOUND the requested GUID not found.\r
421 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
422 @retval RETURN_ACCESS_DENIED not allow to restore to the address\r
423 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
424**/\r
425RETURN_STATUS\r
426EFIAPI\r
427RestoreLockBox (\r
428 IN GUID *Guid,\r
429 IN VOID *Buffer, OPTIONAL\r
430 IN OUT UINTN *Length OPTIONAL\r
431 )\r
432{\r
433 SMM_LOCK_BOX_DATA *LockBox;\r
434 VOID *RestoreBuffer;\r
435\r
436 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Enter\n"));\r
437\r
438 //\r
439 // Restore this, Buffer and Length MUST be both NULL or both non-NULL\r
440 //\r
441 if ((Guid == NULL) ||\r
442 ((Buffer == NULL) && (Length != NULL)) ||\r
443 ((Buffer != NULL) && (Length == NULL))) {\r
444 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_INVALID_PARAMETER));\r
445 return EFI_INVALID_PARAMETER;\r
446 }\r
447\r
448 //\r
449 // Find LockBox\r
450 //\r
451 LockBox = InternalFindLockBoxByGuid (Guid);\r
452 if (LockBox == NULL) {\r
453 //\r
454 // Not found\r
455 //\r
456 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_NOT_FOUND));\r
457 return EFI_NOT_FOUND;\r
458 }\r
459\r
460 //\r
461 // Set RestoreBuffer\r
462 //\r
463 if (Buffer != NULL) {\r
464 //\r
465 // restore to new buffer\r
466 //\r
467 RestoreBuffer = Buffer;\r
468 } else {\r
469 //\r
470 // restore to original buffer\r
471 //\r
472 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {\r
473 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_WRITE_PROTECTED));\r
474 return EFI_WRITE_PROTECTED;\r
475 }\r
476 RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;\r
477 }\r
478\r
479 //\r
480 // Set RestoreLength\r
481 //\r
482 if (Length != NULL) {\r
483 if (*Length < (UINTN)LockBox->Length) {\r
484 //\r
485 // Input buffer is too small to hold all data.\r
486 //\r
487 *Length = (UINTN)LockBox->Length;\r
488 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_BUFFER_TOO_SMALL));\r
489 return EFI_BUFFER_TOO_SMALL;\r
490 }\r
491 *Length = (UINTN)LockBox->Length;\r
492 }\r
493\r
494 //\r
495 // Restore data\r
496 //\r
497 CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
498\r
499 //\r
500 // Done\r
501 //\r
502 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreLockBox - Exit (%r)\n", EFI_SUCCESS));\r
503 return EFI_SUCCESS;\r
504}\r
505\r
506/**\r
507 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
508\r
509 @retval RETURN_SUCCESS the information is restored successfully.\r
510 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
511 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
512**/\r
513RETURN_STATUS\r
514EFIAPI\r
515RestoreAllLockBoxInPlace (\r
516 VOID\r
517 )\r
518{\r
519 SMM_LOCK_BOX_DATA *LockBox;\r
520 LIST_ENTRY *Link;\r
521 LIST_ENTRY *LockBoxQueue;\r
522\r
523 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Enter\n"));\r
524\r
525 LockBoxQueue = InternalGetLockBoxQueue ();\r
526 ASSERT (LockBoxQueue != NULL);\r
527\r
528 //\r
529 // Restore all, Buffer and Length MUST be NULL\r
530 //\r
531 for (Link = LockBoxQueue->ForwardLink;\r
532 Link != LockBoxQueue;\r
533 Link = Link->ForwardLink) {\r
534 LockBox = BASE_CR (\r
535 Link,\r
536 SMM_LOCK_BOX_DATA,\r
537 Link\r
538 );\r
539 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {\r
540 //\r
541 // Restore data\r
542 //\r
543 CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
544 }\r
545 }\r
546 //\r
547 // Done\r
548 //\r
549 DEBUG ((EFI_D_INFO, "SmmLockBoxSmmLib RestoreAllLockBoxInPlace - Exit (%r)\n", EFI_SUCCESS));\r
550 return EFI_SUCCESS;\r
551}\r
552\r