3 Read and edit the EFI variable.
5 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 extern LIST_ENTRY mAllVarListEntry
;
14 extern MULTI_PLATFORM_PARAMETERS mMultiPlatformParam
;
15 extern G_EFI_FD_INFO gEfiFdInfo
;
17 EFI_GUID gEfiVariableGuid
= EFI_VARIABLE_GUID
;
20 Gets the pointer to the first variable header in given variable store area.
22 @param VarStoreHeader Pointer to the Variable Store Header.
24 @return Pointer to the first variable header.
30 IN VARIABLE_STORE_HEADER
*VarStoreHeader
34 // The end of variable store.
36 return (VARIABLE_HEADER
*) HEADER_ALIGN (VarStoreHeader
+ 1);
41 Gets the pointer to the end of the variable storage area.
43 This function gets pointer to the end of the variable storage
44 area, according to the input variable store header.
46 @param VarStoreHeader Pointer to the Variable Store Header.
48 @return Pointer to the end of the variable storage area.
54 IN VARIABLE_STORE_HEADER
*VarStoreHeader
58 // The end of variable store
60 return (VARIABLE_HEADER
*) HEADER_ALIGN ((UINTN
) VarStoreHeader
+ VarStoreHeader
->Size
);
66 This code checks if variable header is valid or not.
68 @param Variable Pointer to the Variable Header.
70 @retval TRUE Variable header is valid.
71 @retval FALSE Variable header is not valid.
76 IsValidVariableHeader (
77 IN VARIABLE_HEADER
*Variable
80 if ((Variable
== NULL
) || (Variable
->StartId
!= VARIABLE_DATA
)) {
89 This code gets the size of name of variable.
91 @param Variable Pointer to the Variable Header.
93 @return UINTN Size of variable in bytes.
99 IN VARIABLE_HEADER
*Variable
102 if ((Variable
->State
== (UINT8
) (-1)) ||
103 (Variable
->DataSize
== (UINT32
) (-1)) ||
104 (Variable
->NameSize
== (UINT32
) (-1)) ||
105 (Variable
->Attributes
== (UINT32
) (-1))
109 return (UINTN
) Variable
->NameSize
;
114 This code gets the size of variable data.
116 @param Variable Pointer to the Variable Header.
118 @return Size of variable in bytes.
124 IN VARIABLE_HEADER
*Variable
127 if ((Variable
->State
== (UINT8
) (-1)) ||
128 (Variable
->DataSize
== (UINT32
) (-1)) ||
129 (Variable
->NameSize
== (UINT32
) (-1)) ||
130 (Variable
->Attributes
== (UINT32
) (-1))
134 return (UINTN
) Variable
->DataSize
;
139 This code gets the pointer to the variable name.
141 @param Variable Pointer to the Variable Header.
143 @return Pointer to Variable Name which is Unicode encoding.
149 IN VARIABLE_HEADER
*Variable
153 return (CHAR16
*) (Variable
+ 1);
158 This code gets the pointer to the variable data.
160 @param Variable Pointer to the Variable Header.
162 @return Pointer to Variable Data.
168 IN VARIABLE_HEADER
*Variable
174 // Be careful about pad size for alignment.
176 Value
= (UINTN
) GetVariableNamePtr (Variable
);
177 Value
+= NameSizeOfVariable (Variable
);
178 Value
+= GET_PAD_SIZE (NameSizeOfVariable (Variable
));
180 return (UINT8
*) Value
;
185 This code gets the pointer to the next variable header.
187 @param Variable Pointer to the Variable Header.
189 @return Pointer to next variable header.
195 IN VARIABLE_HEADER
*Variable
200 if (!IsValidVariableHeader (Variable
)) {
204 Value
= (UINTN
) GetVariableDataPtr (Variable
);
205 Value
+= DataSizeOfVariable (Variable
);
206 Value
+= GET_PAD_SIZE (DataSizeOfVariable (Variable
));
209 // Be careful about pad size for alignment.
211 return (VARIABLE_HEADER
*) HEADER_ALIGN (Value
);
215 Search and get a free space in the EFI variable zone
217 @param VariableStoreHeader The start of a EFI variable zone.
218 @param VarListSize The size of a variables needs to be allocated.
219 @param FreeBeginVar The dual pointer to the free NV space.
221 @retval EFI_SUCCESS Return the beginning of a free variable space.
222 @retval RETURN_BUFFER_TOO_SMALL Failed.
227 IN VARIABLE_STORE_HEADER
*VariableStoreHeader
,
228 IN UINT32 VarListSize
,
229 IN OUT CHAR8
**FreeBeginVar
233 VARIABLE_HEADER
*Variable
;
234 VARIABLE_HEADER
*EndOfVariable
;
240 EndOfVariable
= NULL
;
241 *FreeBeginVar
= NULL
;
243 if (VariableStoreHeader
== NULL
) {
244 *FreeBeginVar
= NULL
;
245 return RETURN_INVALID_PARAMETER
;
247 Variable
= GetStartPointer (VariableStoreHeader
);
248 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
250 //Search the beginning of free NV
252 while (Variable
!= EndOfVariable
) {
253 BeginVar
= (CHAR8
*)Variable
;
254 Variable
= GetNextVariablePtr (Variable
);
255 if (Variable
== NULL
) {
261 // Check whether the free space is more than what we want
263 if ((CHAR8
*)BeginVar
+ VarListSize
> (CHAR8
*)EndOfVariable
) {
264 return RETURN_BUFFER_TOO_SMALL
;
267 // If not find the available space, return NULL
270 return RETURN_BUFFER_TOO_SMALL
;
272 *FreeBeginVar
= BeginVar
;
278 Search whether the variable in VarList has existed in current NV.
280 Parse the FFS or Fd image, and find the valid variable pointer.
282 @param VariableStoreHeader The start of a EFI variable zone.
283 @param VarList The pointer to the VarList
285 @retval address If the variable existed in current NV, return address
286 @return NULL Otherwise, return NULL
291 IN VARIABLE_STORE_HEADER
*VariableStoreHeader
,
292 IN FORMSET_STORAGE
*Storage
296 VARIABLE_HEADER
*Variable
;
297 VARIABLE_HEADER
*EndOfVariable
;
298 CHAR16
*VariableName
;
302 EndOfVariable
= NULL
;
305 if ((VariableStoreHeader
== NULL
) || (Storage
== NULL
) || (Storage
->Name
== NULL
)) {
308 Variable
= GetStartPointer (VariableStoreHeader
);
309 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
311 // Parse and compare the variable in the NV space one by one
313 while ((Variable
!= EndOfVariable
) && (Variable
!= NULL
)) {
314 VariableName
= (CHAR16
*)((CHAR8
*)Variable
+ sizeof (VARIABLE_HEADER
));
315 if (!CompareGuid (&Variable
->VendorGuid
, &Storage
->Guid
) \
316 && !FceStrCmp (Storage
->Name
, VariableName
) \
317 && (Variable
->State
== VAR_ADDED
)) {
321 Variable
= GetNextVariablePtr (Variable
);
329 Exchange the data between Efi variable and the data of VarList when the
330 variable use the authenticated variable header
332 If VarToList is TRUE, copy the efi variable data to the VarList; Otherwise,
333 update the data from varlist to efi variable.
335 @param VarToList The flag to control the direction of exchange.
336 @param StorageListHead Decide which variale list be updated
338 @retval EFI_SUCCESS Get the address successfully.
339 @retval EFI_OUT_OF_RESOURCES No available in the EFI variable zone.
344 IN BOOLEAN VarToList
,
345 IN LIST_ENTRY
*StorageListHead
348 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
349 LIST_ENTRY
*StorageLink
;
350 FORMSET_STORAGE
*Storage
;
352 CHAR8
*NewAvailableAddr
;
354 VARIABLE_HEADER
*VariableHeader
;
355 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
358 Status
= EFI_SUCCESS
;
360 NewAvailableAddr
= NULL
;
362 VariableHeader
= NULL
;
363 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
364 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
366 //Parse the variable range, and check whether there is some existed ones.
368 StorageLink
= GetFirstNode (StorageListHead
);
369 while (!IsNull (StorageListHead
, StorageLink
)) {
370 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
372 // Ignore the invalid varlist node
374 if (Storage
->Buffer
== NULL
) {
375 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
379 // Report error, if the variable name is invalid.
381 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
382 printf ("Error. One variable name is NULL. Its GUID is: ");
383 PrintGuid(&(Storage
->Guid
));
384 return EFI_INVALID_PARAMETER
;
386 VariableHeader
= FindVariableInNv (
393 //Copy the data from NV to the VarList.
395 if (VariableHeader
!= NULL
) {
396 if (Storage
->Buffer
== NULL
) {
397 Storage
->Buffer
= calloc (Storage
->Size
, sizeof (CHAR8
));
398 ASSERT (Storage
->Buffer
!= NULL
);
400 DataBase
= (CHAR8
*)GetVariableDataPtr (VariableHeader
);
409 //If existed, copy the List data to the variable in NV directly. If not found, create a new one.
411 VarNameSize
= 2 * (FceStrLen (Storage
->Name
) + 1);
413 //If this variable has existed in current FD, the data in VarList has
414 // been updated, and this variable is not authenticated type, then
415 // update it from VarList to the FD.
417 if ((VariableHeader
!= NULL
) \
418 && (Storage
->Buffer
!= NULL
)
420 DataBase
= (CHAR8
*)GetVariableDataPtr (VariableHeader
);
426 } else if ((VariableHeader
== NULL
) && (Storage
->Buffer
!= NULL
)){
428 //If EfiVarstore is not EFI_VARIABLE_NON_VOLATILE, only skip it.
430 if (Storage
->NewEfiVarstore
431 && ((Storage
->Attributes
& EFI_VARIABLE_NON_VOLATILE
) == 0)
433 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
437 // Try to get the available zone from the efi variables
439 Status
= GetVariableVar (
441 Storage
->Size
+ sizeof (VARIABLE_HEADER
),
445 if (!EFI_ERROR (Status
)) {
447 // Create the variable header
449 VariableHeader
= (VARIABLE_HEADER
*) NewAvailableAddr
;
450 VariableHeader
->StartId
= VARIABLE_DATA
;
451 VariableHeader
->State
= VAR_ADDED
;
452 VariableHeader
->Reserved
= 0x0;
453 if (Storage
->NewEfiVarstore
) {
454 VariableHeader
->Attributes
= Storage
->Attributes
;
456 VariableHeader
->Attributes
= EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
;
458 VariableHeader
->NameSize
= VarNameSize
;
459 VariableHeader
->DataSize
= Storage
->Size
;
461 //Copy the Guid, variable name, and data in sequence.
464 (VOID
*)&(VariableHeader
->VendorGuid
),
468 NewAvailableAddr
= NewAvailableAddr
+ sizeof (VARIABLE_HEADER
);
470 (VOID
*) NewAvailableAddr
,
475 NewAvailableAddr
= NewAvailableAddr
+ VarNameSize
+ GET_PAD_SIZE (VarNameSize
);
477 (VOID
*) NewAvailableAddr
,
479 Storage
->Size
* sizeof (CHAR8
)
482 printf ("Error. No available space in NV ram.\n");
483 return EFI_OUT_OF_RESOURCES
;
487 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
493 Remove the variable from Efi variable
495 Found the variable with the same name in StorageListHead and remove it.
497 @param StorageListHead Decide which variale list be removed.
499 @retval EFI_SUCCESS Remove the variables successfully.
502 RemoveNormalEfiVariable (
503 IN LIST_ENTRY
*StorageListHead
506 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
507 LIST_ENTRY
*StorageLink
;
508 FORMSET_STORAGE
*Storage
;
509 VARIABLE_HEADER
*VariableHeader
;
510 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
512 VariableHeader
= NULL
;
513 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
514 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
516 //Parse the variable range, and check whether there is some existed ones.
518 StorageLink
= GetFirstNode (StorageListHead
);
519 while (!IsNull (StorageListHead
, StorageLink
)) {
520 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
522 // Ignore the invalid varlist node
524 if (Storage
->Buffer
== NULL
) {
525 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
529 // Report error, if the variable name is invalid.
531 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
532 printf ("Error. One variable name is NULL. Its GUID is: ");
533 PrintGuid(&(Storage
->Guid
));
534 return EFI_INVALID_PARAMETER
;
536 VariableHeader
= FindVariableInNv (
540 if (VariableHeader
!= NULL
) {
541 VariableHeader
->State
= VAR_DELETED
;
543 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
549 Check the store variable is no-authenticated or not
551 @param VarToList The pointer to the header of Variable Store.
553 @retval TRUE If no-authenticated, return TRUE.
554 @retval FALSE Otherwise, return FALSE.
558 CheckNormalVarStoreOrNot (
559 IN VOID
*VariableStoreHeader
564 &((VARIABLE_STORE_HEADER
*)VariableStoreHeader
)->Signature
)
573 Copy variable to binary in multi-platform mode
575 @param Storage The pointer to a storage in storage list.
576 @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
577 @param Index The number of the storage. If the Index is 0, record the variable header to
578 the binary. Or else, only record the storage.
580 @return length The length of storage
583 CopyVariableToBinary (
584 IN FORMSET_STORAGE
*Storage
,
585 IN OUT UINT8
*StorageBeginning
,
590 CHAR8
*NewAvailableAddr
;
591 VARIABLE_HEADER
*VariableHeader
;
592 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
596 Status
= EFI_SUCCESS
;
597 NewAvailableAddr
= NULL
;
600 VariableHeader
= NULL
;
601 VariableStoreHeader
= NULL
;
603 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
604 printf ("Error. One variable name is NULL. Its GUID is: ");
605 PrintGuid(&(Storage
->Guid
));
609 // If the first storage under one specified platformId and defaultId, create the variable header
612 HeaderLength
= WriteDefaultAndPlatformId (StorageBeginning
, Storage
);
613 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (StorageBeginning
+ HeaderLength
);
615 //Create the Variable Storage header
617 memcpy (&(VariableStoreHeader
->Signature
), &gEfiVariableGuid
, sizeof (EFI_GUID
));
618 VariableStoreHeader
->Format
= 0x5A;
619 VariableStoreHeader
->State
= 0xFE;
621 //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.
623 VariableStoreHeader
->Size
= gEfiFdInfo
.FdSize
;
626 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (StorageBeginning
+ *(UINT16
*)StorageBeginning
);
628 Status
= GetVariableVar (
630 Storage
->Size
+ sizeof (VARIABLE_HEADER
),
633 if (EFI_ERROR (Status
)) {
637 // Create the variable header
639 VarNameSize
= 2 * (FceStrLen (Storage
->Name
) + 1);
640 VariableHeader
= (VARIABLE_HEADER
*) NewAvailableAddr
;
641 VariableHeader
->StartId
= VARIABLE_DATA
;
642 VariableHeader
->State
= VAR_ADDED
;
643 VariableHeader
->Reserved
= 0x0;
644 if (Storage
->NewEfiVarstore
) {
645 VariableHeader
->Attributes
= Storage
->Attributes
;
647 VariableHeader
->Attributes
= EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
;
649 VariableHeader
->NameSize
= VarNameSize
;
650 VariableHeader
->DataSize
= Storage
->Size
;
652 //Copy the Guid, variable name, and data in sequence.
655 (VOID
*)&(VariableHeader
->VendorGuid
),
659 NewAvailableAddr
= NewAvailableAddr
+ sizeof (VARIABLE_HEADER
);
661 (VOID
*) NewAvailableAddr
,
666 NewAvailableAddr
= NewAvailableAddr
+ VarNameSize
+ GET_PAD_SIZE (VarNameSize
);
668 (VOID
*) NewAvailableAddr
,
670 Storage
->Size
* sizeof (CHAR8
)
673 // Return the length which is from the beginning of Binary
675 return ((UINT32
) ((UINT8
*)NewAvailableAddr
- StorageBeginning
) + Storage
->Size
);
678 Copy variable to binary in multi-platform mode
680 @param Storage The pointer to a storage in storage list.
681 @param StorageBeginning The pointer to the beginning of storage under specifed platformId and defaultId
682 @param Index The number of the storage. If the Index is 0, record the variable header to
683 the binary. Or else, only record the storage.
685 @return length The length of storage
688 CopyVariableToNvStoreBinary (
689 IN FORMSET_STORAGE
*Storage
,
690 IN OUT UINT8
*StorageBeginning
,
695 CHAR8
*NewAvailableAddr
;
696 VARIABLE_HEADER
*VariableHeader
;
697 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
700 PCD_DEFAULT_DATA
*PcdDefaultDataHeader
;
702 Status
= EFI_SUCCESS
;
703 NewAvailableAddr
= NULL
;
706 VariableHeader
= NULL
;
707 VariableStoreHeader
= NULL
;
709 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
710 printf ("Error. One variable name is NULL. Its GUID is: ");
711 PrintGuid(&(Storage
->Guid
));
715 // If the first storage under one specified platformId and defaultId, create the variable header
718 HeaderLength
= WriteNvStoreDefaultAndPlatformId (StorageBeginning
, Storage
);
719 PcdDefaultDataHeader
= (PCD_DEFAULT_DATA
*)StorageBeginning
;
720 PcdDefaultDataHeader
->HeaderSize
= HeaderLength
;
721 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (StorageBeginning
+ HeaderLength
+ 4);
723 //Create the Variable Storage header
725 memcpy (&(VariableStoreHeader
->Signature
), &gEfiVariableGuid
, sizeof (EFI_GUID
));
726 VariableStoreHeader
->Format
= 0x5A;
727 VariableStoreHeader
->State
= 0xFE;
729 //Assign a big size here. It will be fixed after the storage under a specifed platformId and defaultId are all written.
731 VariableStoreHeader
->Size
= gEfiFdInfo
.FdSize
;
733 PcdDefaultDataHeader
= (PCD_DEFAULT_DATA
*)StorageBeginning
;
734 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (StorageBeginning
+ PcdDefaultDataHeader
->HeaderSize
+ 4);
735 Status
= GetVariableVar (
737 Storage
->Size
+ sizeof (VARIABLE_HEADER
),
740 if (EFI_ERROR (Status
)) {
744 // Create the variable header
746 VarNameSize
= 2 * (FceStrLen (Storage
->Name
) + 1);
747 VariableHeader
= (VARIABLE_HEADER
*) NewAvailableAddr
;
748 VariableHeader
->StartId
= VARIABLE_DATA
;
749 VariableHeader
->State
= VAR_ADDED
;
750 VariableHeader
->Reserved
= 0x0;
751 if (Storage
->NewEfiVarstore
) {
752 VariableHeader
->Attributes
= Storage
->Attributes
;
754 VariableHeader
->Attributes
= EFI_VARIABLE_NON_VOLATILE
|EFI_VARIABLE_BOOTSERVICE_ACCESS
|EFI_VARIABLE_RUNTIME_ACCESS
;
756 VariableHeader
->NameSize
= VarNameSize
;
757 VariableHeader
->DataSize
= Storage
->Size
;
759 //Copy the Guid, variable name, and data in sequence.
762 (VOID
*)&(VariableHeader
->VendorGuid
),
767 NewAvailableAddr
= NewAvailableAddr
+ sizeof (VARIABLE_HEADER
);
769 (VOID
*) NewAvailableAddr
,
774 NewAvailableAddr
= NewAvailableAddr
+ VarNameSize
+ GET_PAD_SIZE (VarNameSize
);
776 (VOID
*) NewAvailableAddr
,
778 Storage
->Size
* sizeof (CHAR8
)
781 // Return the length which is from the beginning of Binary
783 return ((UINT32
) ((UINT8
*)NewAvailableAddr
- StorageBeginning
- PcdDefaultDataHeader
->HeaderSize
- 4) + Storage
->Size
);
786 Read variable to storage list in multi-platform mode
788 @param Binary The pointer to the header of storage under specifed platformId and defaultId
789 @param StorageListEntry The pointer to the storage list.
791 @return length The length of storage
794 ReadNvStoreVariableToList (
796 IN LIST_ENTRY
*StorageListEntry
799 VARIABLE_HEADER
*EndOfVariable
;
800 VARIABLE_HEADER
*Variable
;
801 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
802 FORMSET_STORAGE
*Storage
;
804 PCD_DEFAULT_DATA
*PcdDefaultData
;
806 static UINT16 PreDefaultId
;
807 static UINT64 PrePlatformId
;
809 VariableStoreHeader
= NULL
;
814 PcdDefaultData
= (PCD_DEFAULT_DATA
*)DataBase
;
815 PrePlatformId
= PcdDefaultData
->DefaultInfo
[0].SkuId
;
816 PreDefaultId
= PcdDefaultData
->DefaultInfo
[0].DefaultId
;
817 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (DataBase
+ PcdDefaultData
->HeaderSize
+ 4);
818 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
820 for (Variable
= GetStartPointer (VariableStoreHeader
);
821 Length
< VariableStoreHeader
->Size
;
822 Length
+= sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ Variable
->DataSize
825 // Create the storage
828 Storage
= calloc (sizeof (FORMSET_STORAGE
), sizeof (CHAR8
));
829 if (Storage
== NULL
) {
830 printf ("Allocate memory failed.\n");
834 // Store the DefaultId and PlatformId collected from the header to Storage.
836 Storage
->DefaultId
[0] = PreDefaultId
;
837 Storage
->PlatformId
[0] = PrePlatformId
;
838 Storage
->DefaultPlatformIdNum
= 0;
840 Storage
->Attributes
= Variable
->Attributes
;
841 Storage
->Size
= (UINT16
)Variable
->DataSize
;
842 Storage
->Name
= calloc (Variable
->NameSize
, sizeof (UINT8
));
843 ASSERT (Storage
->Name
!= NULL
);
844 Storage
->Buffer
= calloc (Variable
->DataSize
, sizeof (UINT8
));
845 ASSERT (Storage
->Buffer
!= NULL
);
848 &(Variable
->VendorGuid
),
853 (UINT8
*)Variable
+ sizeof (VARIABLE_HEADER
),
858 (UINT8
*)Variable
+ sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ GET_PAD_SIZE (Variable
->NameSize
),
859 Storage
->Size
* sizeof (CHAR8
)
862 // Assigned the value for comparison in verify mode
864 Storage
->Type
= EFI_IFR_VARSTORE_EFI_OP
;
865 Storage
->NewEfiVarstore
= TRUE
;
866 InitializeListHead (&Storage
->NameValueListHead
);
868 InsertTailList(StorageListEntry
, &Storage
->Link
);
870 // If the last variable, exit.
872 if (Variable
== EndOfVariable
) {
876 Variable
= GetNextVariablePtr (Variable
);
877 assert (Variable
!= NULL
);
878 if (!IsValidVariableHeader(Variable
)) {
886 Read variable to storage list in multi-platform mode
888 @param Binary The pointer to the header of storage under specifed platformId and defaultId
889 @param StorageListEntry The pointer to the storage list.
891 @return length The length of storage
896 IN LIST_ENTRY
*StorageListEntry
899 VARIABLE_HEADER
*EndOfVariable
;
900 VARIABLE_HEADER
*Variable
;
901 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
902 FORMSET_STORAGE
*Storage
;
903 BOOLEAN ReadIdHeaderFlag
;
905 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
907 static UINT16 PreDefaultId
[MAX_PLATFORM_DEFAULT_ID_NUM
];
908 static UINT64 PrePlatformId
[MAX_PLATFORM_DEFAULT_ID_NUM
];
910 VariableStoreHeader
= NULL
;
912 ReadIdHeaderFlag
= TRUE
;
914 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)Binary
;
915 DataBase
= Binary
+ sizeof (EFI_COMMON_SECTION_HEADER
);
916 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (DataBase
+ *(UINT16
*)DataBase
);
917 EndOfVariable
= GetEndPointer(VariableStoreHeader
);
919 for (Variable
= GetStartPointer (VariableStoreHeader
);
920 Length
< VariableStoreHeader
->Size
;
921 Length
+= sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ Variable
->DataSize
924 // Create the storage
927 Storage
= calloc (sizeof (FORMSET_STORAGE
), sizeof (CHAR8
));
928 if (Storage
== NULL
) {
929 printf ("Allocate memory failed.\n");
933 // If access the first storage, read the platformId and defaultId
935 if (ReadIdHeaderFlag
) {
936 ReadDefaultAndPlatformIdFromBfv (DataBase
, Storage
);
937 Length
+= sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ Variable
->DataSize
;
938 ReadIdHeaderFlag
= FALSE
;
939 memcpy (PreDefaultId
, Storage
->DefaultId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT16
));
940 memcpy (PrePlatformId
, Storage
->PlatformId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT64
));
943 // Store the DefaultId and PlatformId collected from the header to Storage.
945 memcpy (Storage
->DefaultId
, PreDefaultId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT16
));
946 memcpy (Storage
->PlatformId
, PrePlatformId
, MAX_PLATFORM_DEFAULT_ID_NUM
* sizeof (UINT64
));
948 Storage
->Attributes
= Variable
->Attributes
;
949 Storage
->Size
= (UINT16
)Variable
->DataSize
;
950 Storage
->Name
= calloc (Variable
->NameSize
, sizeof (UINT8
));
951 ASSERT (Storage
->Name
!= NULL
);
952 Storage
->Buffer
= calloc (Variable
->DataSize
, sizeof (UINT8
));
953 ASSERT (Storage
->Buffer
!= NULL
);
956 &(Variable
->VendorGuid
),
961 (UINT8
*)Variable
+ sizeof (VARIABLE_HEADER
),
966 (UINT8
*)Variable
+ sizeof (VARIABLE_HEADER
) + Variable
->NameSize
+ GET_PAD_SIZE (Variable
->NameSize
),
967 Storage
->Size
* sizeof (CHAR8
)
970 // Assigned the value for comparison in verify mode
972 Storage
->Type
= EFI_IFR_VARSTORE_EFI_OP
;
973 Storage
->NewEfiVarstore
= TRUE
;
974 InitializeListHead (&Storage
->NameValueListHead
);
976 InsertTailList(StorageListEntry
, &Storage
->Link
);
978 // If the last variable, exit.
980 if (Variable
== EndOfVariable
) {
984 Variable
= GetNextVariablePtr (Variable
);
985 assert (Variable
!= NULL
);
988 // Return the length which is from the beginning of Binary
990 Length
= FvBufExpand3ByteSize (SectionHeader
->Size
);
996 Check whether exists the valid normal variables in NvStorage or not.
998 @retval TRUE If existed, return TRUE.
1002 ExistNormalEfiVarOrNot (
1003 IN LIST_ENTRY
*StorageListHead
1006 EFI_FIRMWARE_VOLUME_HEADER
*VarAddr
;
1007 LIST_ENTRY
*StorageLink
;
1008 FORMSET_STORAGE
*Storage
;
1009 VARIABLE_HEADER
*VariableHeader
;
1010 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
1012 VariableHeader
= NULL
;
1013 VarAddr
= (EFI_FIRMWARE_VOLUME_HEADER
*) gEfiFdInfo
.EfiVariableAddr
;
1014 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*)((CHAR8
*)VarAddr
+ VarAddr
->HeaderLength
);
1016 //Parse the variable range, and check whether there is some existed ones.
1018 StorageLink
= GetFirstNode (StorageListHead
);
1019 while (!IsNull (StorageListHead
, StorageLink
)) {
1020 Storage
= FORMSET_STORAGE_FROM_LINK (StorageLink
);
1022 // Ignore the invalid varlist node
1024 if ((Storage
->Buffer
== NULL
)
1025 || (Storage
->Name
== NULL
)
1026 || (FceStrLen(Storage
->Name
) == 0)
1028 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
1032 // Report error, if the variable name is invalid.
1034 if ((Storage
->Name
== NULL
) || (FceStrLen(Storage
->Name
) == 0)) {
1035 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
1038 VariableHeader
= FindVariableInNv (
1039 VariableStoreHeader
,
1043 if ((VariableHeader
!= NULL
)) {
1046 StorageLink
= GetNextNode (StorageListHead
, StorageLink
);
1052 Fix the size of variable header.
1054 @param Binary The pointer to the header of storage under specifed platformId and defaultId
1055 @param Length The length of binary.
1059 FixVariableHeaderSize (
1060 IN UINT8
*BinaryBeginning
,
1064 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
1066 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (BinaryBeginning
+ *(UINT16
*)BinaryBeginning
);
1067 VariableStoreHeader
->Size
= Length
- *(UINT16
*)BinaryBeginning
;
1071 Fix the size of variable header.
1073 @param Binary The pointer to the header of storage under specifed platformId and defaultId
1074 @param Length The length of binary.
1078 FixNvStoreVariableHeaderSize (
1079 IN UINT8
*BinaryBeginning
,
1083 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
1084 PCD_DEFAULT_DATA
*PcdDefaultDataHeader
;
1086 PcdDefaultDataHeader
= (PCD_DEFAULT_DATA
*)(BinaryBeginning
);
1087 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (BinaryBeginning
+ PcdDefaultDataHeader
->HeaderSize
+ 4);
1088 VariableStoreHeader
->Size
= Length
;
1089 PcdDefaultDataHeader
->DataSize
= VariableStoreHeader
->Size
+ PcdDefaultDataHeader
->HeaderSize
+ 4;