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