]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Variable/Pei/Variable.c
1) Replace MACRO with C functions.
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
CommitLineData
8d3a5c82 1/*++\r
2\r
3Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11Module Name:\r
12\r
13 Variable.c\r
14\r
15Abstract:\r
16\r
d0738386 17 PEIM to provide the Variable functionality\r
8d3a5c82 18\r
19--*/\r
20\r
21\r
22#include "Variable.h"\r
23\r
24//\r
25// Module globals\r
26//\r
27static EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = {\r
28 PeiGetVariable,\r
29 PeiGetNextVariableName\r
30};\r
31\r
32static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {\r
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
34 &gEfiPeiReadOnlyVariable2PpiGuid,\r
35 &mVariablePpi\r
36};\r
37\r
38EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;\r
39\r
40EFI_STATUS\r
41EFIAPI\r
42PeimInitializeVariableServices (\r
43 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
44 IN EFI_PEI_SERVICES **PeiServices\r
45 )\r
46/*++\r
47\r
48Routine Description:\r
49\r
50 Provide the functionality of the variable services.\r
51\r
52Arguments:\r
53\r
54 FfsHeadher - The FFS file header\r
55 PeiServices - General purpose services available to every PEIM.\r
56\r
57Returns:\r
58\r
59 Status - EFI_SUCCESS if the interface could be successfully\r
60 installed\r
61\r
62--*/\r
63{\r
64 //\r
65 // Publish the variable capability to other modules\r
66 //\r
0c2b5da8 67 return (**PeiServices).InstallPpi ((CONST EFI_PEI_SERVICES **)PeiServices, &mPpiListVariable);\r
8d3a5c82 68\r
69}\r
70\r
9cad030b 71VARIABLE_HEADER *\r
72GetStartPointer (\r
73 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
74 )\r
75/*++\r
76\r
77Routine Description:\r
78\r
79 This code gets the pointer to the first variable memory pointer byte\r
80\r
81Arguments:\r
82\r
83 VarStoreHeader Pointer to the Variable Store Header.\r
84\r
85Returns:\r
86\r
87 VARIABLE_HEADER* Pointer to last unavailable Variable Header\r
88\r
89--*/\r
90{\r
91 //\r
92 // The end of variable store\r
93 //\r
94 return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
95}\r
96\r
97VARIABLE_HEADER *\r
98GetEndPointer (\r
99 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
100 )\r
101/*++\r
102\r
103Routine Description:\r
104\r
105 This code gets the pointer to the last variable memory pointer byte\r
106\r
107Arguments:\r
108\r
109 VarStoreHeader Pointer to the Variable Store Header.\r
110\r
111Returns:\r
112\r
113 VARIABLE_HEADER* Pointer to last unavailable Variable Header\r
114\r
115--*/\r
116{\r
117 //\r
118 // The end of variable store\r
119 //\r
120 return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
121}\r
122\r
8d3a5c82 123STATIC\r
130e2569 124BOOLEAN\r
125EFIAPI\r
126IsValidVariableHeader (\r
127 IN VARIABLE_HEADER *Variable\r
8d3a5c82 128 )\r
129/*++\r
130\r
131Routine Description:\r
132\r
133 This code checks if variable header is valid or not.\r
134\r
135Arguments:\r
130e2569 136 Variable Pointer to the Variable Header.\r
8d3a5c82 137\r
138Returns:\r
139 TRUE Variable header is valid.\r
140 FALSE Variable header is not valid.\r
141\r
142--*/\r
143{\r
130e2569 144 if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {\r
145 return FALSE;\r
146 }\r
147\r
148 return TRUE;\r
8d3a5c82 149}\r
150\r
130e2569 151\r
152UINTN\r
153NameSizeOfVariable (\r
8d3a5c82 154 IN VARIABLE_HEADER *Variable\r
155 )\r
156/*++\r
157\r
158Routine Description:\r
159\r
130e2569 160 This code gets the size of name of variable.\r
161\r
162Arguments:\r
163\r
164 Variable Pointer to the Variable Header.\r
165\r
166Returns:\r
167\r
168 UINTN Size of variable in bytes\r
169\r
170--*/\r
171{\r
172 if (Variable->State == (UINT8) (-1) ||\r
173 Variable->DataSize == (UINT32) -1 ||\r
174 Variable->NameSize == (UINT32) -1 ||\r
175 Variable->Attributes == (UINT32) -1) {\r
176 return 0;\r
177 }\r
178 return (UINTN) Variable->NameSize;\r
179}\r
180\r
181UINTN\r
182DataSizeOfVariable (\r
183 IN VARIABLE_HEADER *Variable\r
184 )\r
185/*++\r
186\r
187Routine Description:\r
188\r
189 This code gets the size of name of variable.\r
190\r
191Arguments:\r
192\r
193 Variable Pointer to the Variable Header.\r
194\r
195Returns:\r
196\r
197 UINTN Size of variable in bytes\r
198\r
199--*/\r
200{\r
201 if (Variable->State == (UINT8) -1 ||\r
202 Variable->DataSize == (UINT32) -1 ||\r
203 Variable->NameSize == (UINT32) -1 ||\r
204 Variable->Attributes == (UINT32) -1) {\r
205 return 0;\r
206 }\r
207 return (UINTN) Variable->DataSize;\r
208}\r
209\r
210CHAR16 *\r
211GetVariableNamePtr (\r
212 IN VARIABLE_HEADER *Variable\r
213 )\r
214/*++\r
215\r
216Routine Description:\r
217\r
218 This code gets the pointer to the variable name.\r
8d3a5c82 219\r
220Arguments:\r
130e2569 221\r
222 Variable Pointer to the Variable Header.\r
223\r
224Returns:\r
225\r
226 CHAR16* Pointer to Variable Name\r
227\r
228--*/\r
229{\r
230\r
231 return (CHAR16 *) (Variable + 1);\r
232}\r
233\r
234\r
235UINT8 *\r
236GetVariableDataPtr (\r
237 IN VARIABLE_HEADER *Variable\r
238 )\r
239/*++\r
240\r
241Routine Description:\r
242\r
243 This code gets the pointer to the variable data.\r
244\r
245Arguments:\r
246\r
247 Variable Pointer to the Variable Header.\r
248\r
249Returns:\r
250\r
251 UINT8* Pointer to Variable Data\r
252\r
253--*/\r
254{\r
255 UINTN Value;\r
256 \r
257 //\r
258 // Be careful about pad size for alignment\r
259 //\r
260 Value = (UINTN) GetVariableNamePtr (Variable);\r
261 Value += NameSizeOfVariable (Variable);\r
262 Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));\r
263\r
264 return (UINT8 *) Value;\r
265}\r
266\r
267VARIABLE_HEADER *\r
268GetNextVariablePtr (\r
269 IN VARIABLE_HEADER *Variable\r
270 )\r
271/*++\r
272\r
273Routine Description:\r
274\r
275 This code gets the pointer to the next variable header.\r
276\r
277Arguments:\r
278\r
8d3a5c82 279 Variable Pointer to the Variable Header.\r
280\r
281Returns:\r
130e2569 282\r
283 VARIABLE_HEADER* Pointer to next variable header.\r
8d3a5c82 284\r
285--*/\r
286{\r
130e2569 287 UINTN Value;\r
288\r
289 if (!IsValidVariableHeader (Variable)) {\r
290 return NULL;\r
8d3a5c82 291 }\r
292\r
130e2569 293 Value = (UINTN) GetVariableDataPtr (Variable);\r
294 Value += DataSizeOfVariable (Variable);\r
295 Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));\r
296\r
297 //\r
298 // Be careful about pad size for alignment\r
299 //\r
300 return (VARIABLE_HEADER *) HEADER_ALIGN (Value);\r
8d3a5c82 301}\r
302\r
130e2569 303\r
8d3a5c82 304STATIC\r
305VARIABLE_STORE_STATUS\r
306EFIAPI\r
307GetVariableStoreStatus (\r
308 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
309 )\r
310/*++\r
311\r
312Routine Description:\r
313\r
314 This code gets the pointer to the variable name.\r
315\r
316Arguments:\r
317\r
318 VarStoreHeader Pointer to the Variable Store Header.\r
319\r
320Returns:\r
321\r
322 EfiRaw Variable store is raw\r
323 EfiValid Variable store is valid\r
324 EfiInvalid Variable store is invalid\r
325\r
326--*/\r
327{\r
328 if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&\r
329 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&\r
330 VarStoreHeader->State == VARIABLE_STORE_HEALTHY\r
331 ) {\r
332\r
333 return EfiValid;\r
334 }\r
335\r
336 if (VarStoreHeader->Signature == 0xffffffff &&\r
337 VarStoreHeader->Size == 0xffffffff &&\r
338 VarStoreHeader->Format == 0xff &&\r
339 VarStoreHeader->State == 0xff\r
340 ) {\r
341\r
342 return EfiRaw;\r
343 } else {\r
344 return EfiInvalid;\r
345 }\r
346}\r
347\r
348STATIC\r
349EFI_STATUS\r
350CompareWithValidVariable (\r
351 IN VARIABLE_HEADER *Variable,\r
352 IN CONST CHAR16 *VariableName,\r
353 IN CONST EFI_GUID *VendorGuid,\r
354 OUT VARIABLE_POINTER_TRACK *PtrTrack\r
355 )\r
356/*++\r
357\r
358Routine Description:\r
359\r
360 This function compares a variable with variable entries in database\r
361\r
362Arguments:\r
363\r
364 Variable - Pointer to the variable in our database\r
365 VariableName - Name of the variable to compare to 'Variable'\r
366 VendorGuid - GUID of the variable to compare to 'Variable'\r
367 PtrTrack - Variable Track Pointer structure that contains\r
368 Variable Information.\r
369\r
370Returns:\r
371\r
372 EFI_SUCCESS - Found match variable\r
373 EFI_NOT_FOUND - Variable not found\r
374\r
375--*/\r
376{\r
130e2569 377 VOID *Point;\r
378\r
8d3a5c82 379 if (VariableName[0] == 0) {\r
380 PtrTrack->CurrPtr = Variable;\r
381 return EFI_SUCCESS;\r
382 } else {\r
383 //\r
384 // Don't use CompareGuid function here for performance reasons.\r
385 // Instead we compare the GUID a UINT32 at a time and branch\r
386 // on the first failed comparison.\r
387 //\r
388 if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&\r
389 (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&\r
390 (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&\r
391 (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])\r
392 ) {\r
130e2569 393 ASSERT (NameSizeOfVariable (Variable) != 0);\r
394 Point = (VOID *) GetVariableNamePtr (Variable);\r
395 if (!CompareMem (VariableName, Point, NameSizeOfVariable (Variable))) {\r
8d3a5c82 396 PtrTrack->CurrPtr = Variable;\r
397 return EFI_SUCCESS;\r
398 }\r
399 }\r
400 }\r
401\r
402 return EFI_NOT_FOUND;\r
403}\r
404\r
405STATIC\r
406EFI_STATUS\r
407EFIAPI\r
408FindVariable (\r
409 IN EFI_PEI_SERVICES **PeiServices,\r
410 IN CONST CHAR16 *VariableName,\r
411 IN CONST EFI_GUID *VendorGuid,\r
412 OUT VARIABLE_POINTER_TRACK *PtrTrack\r
413 )\r
414/*++\r
415\r
416Routine Description:\r
417\r
418 This code finds variable in storage blocks (Non-Volatile)\r
419\r
420Arguments:\r
421\r
422 PeiServices - General purpose services available to every PEIM.\r
423 VariableName - Name of the variable to be found\r
424 VendorGuid - Vendor GUID to be found.\r
425 PtrTrack - Variable Track Pointer structure that contains\r
426 Variable Information.\r
427\r
428Returns:\r
429\r
430 EFI_SUCCESS - Variable found successfully\r
431 EFI_NOT_FOUND - Variable not found\r
432 EFI_INVALID_PARAMETER - Invalid variable name\r
433\r
434--*/\r
435{\r
436 EFI_HOB_GUID_TYPE *GuidHob;\r
437 VARIABLE_STORE_HEADER *VariableStoreHeader;\r
438 VARIABLE_HEADER *Variable;\r
439 VARIABLE_HEADER *MaxIndex;\r
440 VARIABLE_INDEX_TABLE *IndexTable;\r
441 UINT32 Count;\r
442 UINT8 *VariableBase;\r
443\r
444 if (VariableName != 0 && VendorGuid == NULL) {\r
445 return EFI_INVALID_PARAMETER;\r
446 }\r
447 //\r
448 // No Variable Address equals zero, so 0 as initial value is safe.\r
449 //\r
450 MaxIndex = 0;\r
451\r
452 GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);\r
453 if (GuidHob == NULL) {\r
454 IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
455 IndexTable->Length = 0;\r
456 IndexTable->StartPtr = NULL;\r
457 IndexTable->EndPtr = NULL;\r
458 IndexTable->GoneThrough = 0;\r
459 } else {\r
460 IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
461 for (Count = 0; Count < IndexTable->Length; Count++)\r
462 {\r
463 MaxIndex = GetVariableByIndex (IndexTable, Count);\r
464\r
465 if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
466 PtrTrack->StartPtr = IndexTable->StartPtr;\r
467 PtrTrack->EndPtr = IndexTable->EndPtr;\r
468\r
469 return EFI_SUCCESS;\r
470 }\r
471 }\r
472\r
473 if (IndexTable->GoneThrough) {\r
474 return EFI_NOT_FOUND;\r
475 }\r
476 }\r
477 //\r
478 // If not found in HOB, then let's start from the MaxIndex we've found.\r
479 //\r
480 if (MaxIndex != NULL) {\r
481 Variable = GetNextVariablePtr (MaxIndex);\r
482 } else {\r
483 if (IndexTable->StartPtr || IndexTable->EndPtr) {\r
484 Variable = IndexTable->StartPtr;\r
485 } else {\r
486 VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);\r
487 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \\r
488 ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);\r
489\r
490 if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {\r
491 return EFI_UNSUPPORTED;\r
492 }\r
493\r
494 if (~VariableStoreHeader->Size == 0) {\r
495 return EFI_NOT_FOUND;\r
496 }\r
497 //\r
498 // Find the variable by walk through non-volatile variable store\r
499 //\r
9cad030b 500 IndexTable->StartPtr = GetStartPointer (VariableStoreHeader);\r
501 IndexTable->EndPtr = GetEndPointer (VariableStoreHeader);\r
8d3a5c82 502\r
503 //\r
504 // Start Pointers for the variable.\r
505 // Actual Data Pointer where data can be written.\r
506 //\r
507 Variable = IndexTable->StartPtr;\r
508 }\r
509 }\r
510 //\r
511 // Find the variable by walk through non-volatile variable store\r
512 //\r
513 PtrTrack->StartPtr = IndexTable->StartPtr;\r
514 PtrTrack->EndPtr = IndexTable->EndPtr;\r
515\r
516 while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {\r
517 if (Variable->State == VAR_ADDED) {\r
518 //\r
519 // Record Variable in VariableIndex HOB\r
520 //\r
521 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME)\r
522 {\r
523 VariableIndexTableUpdate (IndexTable, Variable);\r
524 }\r
525\r
526 if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
527 return EFI_SUCCESS;\r
528 }\r
529 }\r
530\r
531 Variable = GetNextVariablePtr (Variable);\r
532 }\r
533 //\r
534 // If gone through the VariableStore, that means we never find in Firmware any more.\r
535 //\r
536 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
537 IndexTable->GoneThrough = 1;\r
538 }\r
539\r
540 PtrTrack->CurrPtr = NULL;\r
541\r
542 return EFI_NOT_FOUND;\r
543}\r
544\r
545EFI_STATUS\r
546EFIAPI\r
547PeiGetVariable (\r
548 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,\r
549 IN CONST CHAR16 *VariableName,\r
550 IN CONST EFI_GUID *VariableGuid,\r
551 OUT UINT32 *Attributes,\r
552 IN OUT UINTN *DataSize,\r
553 OUT VOID *Data\r
554 )\r
555/*++\r
556\r
557Routine Description:\r
558\r
559 Provide the read variable functionality of the variable services.\r
560\r
561Arguments:\r
562\r
563 PeiServices - General purpose services available to every PEIM.\r
564\r
565 VariableName - The variable name\r
566\r
567 VendorGuid - The vendor's GUID\r
568\r
569 Attributes - Pointer to the attribute\r
570\r
571 DataSize - Size of data\r
572\r
573 Data - Pointer to data\r
574\r
575Returns:\r
576\r
577 EFI_SUCCESS - The interface could be successfully installed\r
578\r
579 EFI_NOT_FOUND - The variable could not be discovered\r
580\r
581 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough\r
582\r
583--*/\r
584{\r
585 VARIABLE_POINTER_TRACK Variable;\r
586 UINTN VarDataSize;\r
587 EFI_STATUS Status;\r
588 EFI_PEI_SERVICES **PeiServices;\r
589\r
590 PeiServices = GetPeiServicesTablePointer ();\r
591 if (VariableName == NULL || VariableGuid == NULL) {\r
592 return EFI_INVALID_PARAMETER;\r
593 }\r
594 //\r
595 // Find existing variable\r
596 //\r
597 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);\r
598 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {\r
599 return Status;\r
600 }\r
601 //\r
602 // Get data size\r
603 //\r
130e2569 604 VarDataSize = DataSizeOfVariable (Variable.CurrPtr);\r
8d3a5c82 605 if (*DataSize >= VarDataSize) {\r
130e2569 606 (*PeiServices)->CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);\r
8d3a5c82 607\r
608 if (Attributes != NULL) {\r
609 *Attributes = Variable.CurrPtr->Attributes;\r
610 }\r
611\r
612 *DataSize = VarDataSize;\r
613 return EFI_SUCCESS;\r
614 } else {\r
615 *DataSize = VarDataSize;\r
616 return EFI_BUFFER_TOO_SMALL;\r
617 }\r
618}\r
619\r
620EFI_STATUS\r
621EFIAPI\r
622PeiGetNextVariableName (\r
623 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,\r
624 IN OUT UINTN *VariableNameSize,\r
625 IN OUT CHAR16 *VariableName,\r
626 IN OUT EFI_GUID *VariableGuid\r
627 )\r
628/*++\r
629\r
630Routine Description:\r
631\r
632 Provide the get next variable functionality of the variable services.\r
633\r
634Arguments:\r
635\r
636 PeiServices - General purpose services available to every PEIM.\r
637 VariabvleNameSize - The variable name's size.\r
638 VariableName - A pointer to the variable's name.\r
639 VariableGuid - A pointer to the EFI_GUID structure.\r
640\r
641 VariableNameSize - Size of the variable name\r
642\r
643 VariableName - The variable name\r
644\r
645 VendorGuid - The vendor's GUID\r
646\r
647Returns:\r
648\r
649 EFI_SUCCESS - The interface could be successfully installed\r
650\r
651 EFI_NOT_FOUND - The variable could not be discovered\r
652\r
653--*/\r
654{\r
655 VARIABLE_POINTER_TRACK Variable;\r
656 UINTN VarNameSize;\r
657 EFI_STATUS Status;\r
658 EFI_PEI_SERVICES **PeiServices;\r
659\r
660 PeiServices = GetPeiServicesTablePointer ();\r
661 if (VariableName == NULL) {\r
662 return EFI_INVALID_PARAMETER;\r
663 }\r
664\r
665 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);\r
666 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {\r
667 return Status;\r
668 }\r
669\r
670 if (VariableName[0] != 0) {\r
671 //\r
672 // If variable name is not NULL, get next variable\r
673 //\r
674 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
675 }\r
676\r
677 while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {\r
678 if (IsValidVariableHeader (Variable.CurrPtr)) {\r
679 if (Variable.CurrPtr->State == VAR_ADDED) {\r
130e2569 680 ASSERT (NameSizeOfVariable (Variable.CurrPtr) != 0);\r
9cad030b 681\r
130e2569 682 VarNameSize = (UINTN) NameSizeOfVariable (Variable.CurrPtr);\r
8d3a5c82 683 if (VarNameSize <= *VariableNameSize) {\r
130e2569 684 (*PeiServices)->CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);\r
8d3a5c82 685\r
686 (*PeiServices)->CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));\r
687\r
688 Status = EFI_SUCCESS;\r
689 } else {\r
690 Status = EFI_BUFFER_TOO_SMALL;\r
691 }\r
692\r
693 *VariableNameSize = VarNameSize;\r
694 return Status;\r
695 //\r
696 // Variable is found\r
697 //\r
698 } else {\r
699 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
700 }\r
701 } else {\r
702 break;\r
703 }\r
704 }\r
705\r
706 return EFI_NOT_FOUND;\r
707}\r