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