3 Copyright (c) 2006 - 2007 Intel Corporation. <BR>
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 Framework PEIM to provide the Variable functionality
27 static EFI_PEI_READ_ONLY_VARIABLE_PPI mVariablePpi
= {
29 PeiGetNextVariableName
32 static EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariable2Ppi
= {
34 PeiGetNextVariableName2
37 static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable
[] = {
39 (EFI_PEI_PPI_DESCRIPTOR_PPI
),
40 &gEfiPeiReadOnlyVariable2PpiGuid
,
44 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
45 &gEfiPeiReadOnlyVariablePpiGuid
,
50 EFI_GUID mEfiVariableIndexTableGuid
= EFI_VARIABLE_INDEX_TABLE_GUID
;
54 PeimInitializeVariableServices (
55 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
56 IN EFI_PEI_SERVICES
**PeiServices
62 Provide the functionality of the variable services.
66 FfsHeadher - The FFS file header
67 PeiServices - General purpose services available to every PEIM.
71 Status - EFI_SUCCESS if the interface could be successfully
77 // Publish the variable capability to other modules
79 return (**PeiServices
).InstallPpi ((CONST EFI_PEI_SERVICES
**) PeiServices
, &mPpiListVariable
[0]);
85 IN VARIABLE_STORE_HEADER
*VarStoreHeader
91 This code gets the pointer to the first variable memory pointer byte
95 VarStoreHeader Pointer to the Variable Store Header.
99 VARIABLE_HEADER* Pointer to last unavailable Variable Header
104 // The end of variable store
106 return (VARIABLE_HEADER
*) HEADER_ALIGN (VarStoreHeader
+ 1);
111 IN VARIABLE_STORE_HEADER
*VarStoreHeader
117 This code gets the pointer to the last variable memory pointer byte
121 VarStoreHeader Pointer to the Variable Store Header.
125 VARIABLE_HEADER* Pointer to last unavailable Variable Header
130 // The end of variable store
132 return (VARIABLE_HEADER
*) HEADER_ALIGN ((UINTN
) VarStoreHeader
+ VarStoreHeader
->Size
);
138 IsValidVariableHeader (
139 IN VARIABLE_HEADER
*Variable
145 This code checks if variable header is valid or not.
148 Variable Pointer to the Variable Header.
151 TRUE Variable header is valid.
152 FALSE Variable header is not valid.
156 if (Variable
== NULL
|| Variable
->StartId
!= VARIABLE_DATA
) {
166 IN VARIABLE_HEADER
*Variable
172 This code gets the size of name of variable.
176 Variable Pointer to the Variable Header.
180 UINTN Size of variable in bytes
184 if (Variable
->State
== (UINT8
) (-1) ||
185 Variable
->DataSize
== (UINT32
) -1 ||
186 Variable
->NameSize
== (UINT32
) -1 ||
187 Variable
->Attributes
== (UINT32
) -1) {
190 return (UINTN
) Variable
->NameSize
;
195 IN VARIABLE_HEADER
*Variable
201 This code gets the size of name of variable.
205 Variable Pointer to the Variable Header.
209 UINTN Size of variable in bytes
213 if (Variable
->State
== (UINT8
) -1 ||
214 Variable
->DataSize
== (UINT32
) -1 ||
215 Variable
->NameSize
== (UINT32
) -1 ||
216 Variable
->Attributes
== (UINT32
) -1) {
219 return (UINTN
) Variable
->DataSize
;
224 IN VARIABLE_HEADER
*Variable
230 This code gets the pointer to the variable name.
234 Variable Pointer to the Variable Header.
238 CHAR16* Pointer to Variable Name
243 return (CHAR16
*) (Variable
+ 1);
249 IN VARIABLE_HEADER
*Variable
255 This code gets the pointer to the variable data.
259 Variable Pointer to the Variable Header.
263 UINT8* Pointer to Variable Data
270 // Be careful about pad size for alignment
272 Value
= (UINTN
) GetVariableNamePtr (Variable
);
273 Value
+= NameSizeOfVariable (Variable
);
274 Value
+= GET_PAD_SIZE (NameSizeOfVariable (Variable
));
276 return (UINT8
*) Value
;
281 IN VARIABLE_HEADER
*Variable
287 This code gets the pointer to the next variable header.
291 Variable Pointer to the Variable Header.
295 VARIABLE_HEADER* Pointer to next variable header.
301 if (!IsValidVariableHeader (Variable
)) {
305 Value
= (UINTN
) GetVariableDataPtr (Variable
);
306 Value
+= DataSizeOfVariable (Variable
);
307 Value
+= GET_PAD_SIZE (DataSizeOfVariable (Variable
));
310 // Be careful about pad size for alignment
312 return (VARIABLE_HEADER
*) HEADER_ALIGN (Value
);
317 VARIABLE_STORE_STATUS
319 GetVariableStoreStatus (
320 IN VARIABLE_STORE_HEADER
*VarStoreHeader
326 This code gets the pointer to the variable name.
330 VarStoreHeader Pointer to the Variable Store Header.
334 EfiRaw Variable store is raw
335 EfiValid Variable store is valid
336 EfiInvalid Variable store is invalid
340 if (VarStoreHeader
->Signature
== VARIABLE_STORE_SIGNATURE
&&
341 VarStoreHeader
->Format
== VARIABLE_STORE_FORMATTED
&&
342 VarStoreHeader
->State
== VARIABLE_STORE_HEALTHY
348 if (VarStoreHeader
->Signature
== 0xffffffff &&
349 VarStoreHeader
->Size
== 0xffffffff &&
350 VarStoreHeader
->Format
== 0xff &&
351 VarStoreHeader
->State
== 0xff
362 CompareWithValidVariable (
363 IN VARIABLE_HEADER
*Variable
,
364 IN CONST CHAR16
*VariableName
,
365 IN CONST EFI_GUID
*VendorGuid
,
366 OUT VARIABLE_POINTER_TRACK
*PtrTrack
372 This function compares a variable with variable entries in database
376 Variable - Pointer to the variable in our database
377 VariableName - Name of the variable to compare to 'Variable'
378 VendorGuid - GUID of the variable to compare to 'Variable'
379 PtrTrack - Variable Track Pointer structure that contains
380 Variable Information.
384 EFI_SUCCESS - Found match variable
385 EFI_NOT_FOUND - Variable not found
391 if (VariableName
[0] == 0) {
392 PtrTrack
->CurrPtr
= Variable
;
396 // Don't use CompareGuid function here for performance reasons.
397 // Instead we compare the GUID a UINT32 at a time and branch
398 // on the first failed comparison.
400 if ((((INT32
*) VendorGuid
)[0] == ((INT32
*) &Variable
->VendorGuid
)[0]) &&
401 (((INT32
*) VendorGuid
)[1] == ((INT32
*) &Variable
->VendorGuid
)[1]) &&
402 (((INT32
*) VendorGuid
)[2] == ((INT32
*) &Variable
->VendorGuid
)[2]) &&
403 (((INT32
*) VendorGuid
)[3] == ((INT32
*) &Variable
->VendorGuid
)[3])
405 ASSERT (NameSizeOfVariable (Variable
) != 0);
406 Point
= (VOID
*) GetVariableNamePtr (Variable
);
407 if (!CompareMem (VariableName
, Point
, NameSizeOfVariable (Variable
))) {
408 PtrTrack
->CurrPtr
= Variable
;
414 return EFI_NOT_FOUND
;
421 IN EFI_PEI_SERVICES
**PeiServices
,
422 IN CONST CHAR16
*VariableName
,
423 IN CONST EFI_GUID
*VendorGuid
,
424 OUT VARIABLE_POINTER_TRACK
*PtrTrack
430 This code finds variable in storage blocks (Non-Volatile)
434 PeiServices - General purpose services available to every PEIM.
435 VariableName - Name of the variable to be found
436 VendorGuid - Vendor GUID to be found.
437 PtrTrack - Variable Track Pointer structure that contains
438 Variable Information.
442 EFI_SUCCESS - Variable found successfully
443 EFI_NOT_FOUND - Variable not found
444 EFI_INVALID_PARAMETER - Invalid variable name
448 EFI_HOB_GUID_TYPE
*GuidHob
;
449 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
450 VARIABLE_HEADER
*Variable
;
451 VARIABLE_HEADER
*MaxIndex
;
452 VARIABLE_INDEX_TABLE
*IndexTable
;
456 if (VariableName
!= 0 && VendorGuid
== NULL
) {
457 return EFI_INVALID_PARAMETER
;
460 // No Variable Address equals zero, so 0 as initial value is safe.
464 GuidHob
= GetFirstGuidHob (&mEfiVariableIndexTableGuid
);
465 if (GuidHob
== NULL
) {
466 IndexTable
= BuildGuidHob (&mEfiVariableIndexTableGuid
, sizeof (VARIABLE_INDEX_TABLE
));
467 IndexTable
->Length
= 0;
468 IndexTable
->StartPtr
= NULL
;
469 IndexTable
->EndPtr
= NULL
;
470 IndexTable
->GoneThrough
= 0;
472 IndexTable
= GET_GUID_HOB_DATA (GuidHob
);
473 for (Count
= 0; Count
< IndexTable
->Length
; Count
++)
475 MaxIndex
= GetVariableByIndex (IndexTable
, Count
);
477 if (CompareWithValidVariable (MaxIndex
, VariableName
, VendorGuid
, PtrTrack
) == EFI_SUCCESS
) {
478 PtrTrack
->StartPtr
= IndexTable
->StartPtr
;
479 PtrTrack
->EndPtr
= IndexTable
->EndPtr
;
485 if (IndexTable
->GoneThrough
) {
486 return EFI_NOT_FOUND
;
490 // If not found in HOB, then let's start from the MaxIndex we've found.
492 if (MaxIndex
!= NULL
) {
493 Variable
= GetNextVariablePtr (MaxIndex
);
495 if (IndexTable
->StartPtr
|| IndexTable
->EndPtr
) {
496 Variable
= IndexTable
->StartPtr
;
498 VariableBase
= (UINT8
*) (UINTN
) PcdGet32 (PcdFlashNvStorageVariableBase
);
499 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (VariableBase
+ \
500 ((EFI_FIRMWARE_VOLUME_HEADER
*) (VariableBase
)) -> HeaderLength
);
502 if (GetVariableStoreStatus (VariableStoreHeader
) != EfiValid
) {
503 return EFI_UNSUPPORTED
;
506 if (~VariableStoreHeader
->Size
== 0) {
507 return EFI_NOT_FOUND
;
510 // Find the variable by walk through non-volatile variable store
512 IndexTable
->StartPtr
= GetStartPointer (VariableStoreHeader
);
513 IndexTable
->EndPtr
= GetEndPointer (VariableStoreHeader
);
516 // Start Pointers for the variable.
517 // Actual Data Pointer where data can be written.
519 Variable
= IndexTable
->StartPtr
;
523 // Find the variable by walk through non-volatile variable store
525 PtrTrack
->StartPtr
= IndexTable
->StartPtr
;
526 PtrTrack
->EndPtr
= IndexTable
->EndPtr
;
528 while (IsValidVariableHeader (Variable
) && (Variable
<= IndexTable
->EndPtr
)) {
529 if (Variable
->State
== VAR_ADDED
) {
531 // Record Variable in VariableIndex HOB
533 if (IndexTable
->Length
< VARIABLE_INDEX_TABLE_VOLUME
)
535 VariableIndexTableUpdate (IndexTable
, Variable
);
538 if (CompareWithValidVariable (Variable
, VariableName
, VendorGuid
, PtrTrack
) == EFI_SUCCESS
) {
543 Variable
= GetNextVariablePtr (Variable
);
546 // If gone through the VariableStore, that means we never find in Firmware any more.
548 if (IndexTable
->Length
< VARIABLE_INDEX_TABLE_VOLUME
) {
549 IndexTable
->GoneThrough
= 1;
552 PtrTrack
->CurrPtr
= NULL
;
554 return EFI_NOT_FOUND
;
560 IN EFI_PEI_SERVICES
**PeiServices
,
561 IN CHAR16
*VariableName
,
562 IN EFI_GUID
* VendorGuid
,
563 OUT UINT32
*Attributes OPTIONAL
,
564 IN OUT UINTN
*DataSize
,
571 Provide the read variable functionality of the variable services.
575 PeiServices - General purpose services available to every PEIM.
577 VariableName - The variable name
579 VendorGuid - The vendor's GUID
581 Attributes - Pointer to the attribute
583 DataSize - Size of data
585 Data - Pointer to data
589 EFI_SUCCESS - The interface could be successfully installed
591 EFI_NOT_FOUND - The variable could not be discovered
593 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
597 VARIABLE_POINTER_TRACK Variable
;
601 if (VariableName
== NULL
|| VendorGuid
== NULL
) {
602 return EFI_INVALID_PARAMETER
;
605 // Find existing variable
607 Status
= FindVariable (PeiServices
, VariableName
, VendorGuid
, &Variable
);
609 if (Variable
.CurrPtr
== NULL
|| Status
!= EFI_SUCCESS
) {
615 VarDataSize
= DataSizeOfVariable (Variable
.CurrPtr
);
616 if (*DataSize
>= VarDataSize
) {
617 (*PeiServices
)->CopyMem (Data
, GetVariableDataPtr (Variable
.CurrPtr
), VarDataSize
);
619 if (Attributes
!= NULL
) {
620 *Attributes
= Variable
.CurrPtr
->Attributes
;
623 *DataSize
= VarDataSize
;
626 *DataSize
= VarDataSize
;
627 return EFI_BUFFER_TOO_SMALL
;
635 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI
*This
,
636 IN CONST CHAR16
*VariableName
,
637 IN CONST EFI_GUID
*VariableGuid
,
638 OUT UINT32
*Attributes
,
639 IN OUT UINTN
*DataSize
,
646 Provide the read variable functionality of the variable services.
650 PeiServices - General purpose services available to every PEIM.
652 VariableName - The variable name
654 VendorGuid - The vendor's GUID
656 Attributes - Pointer to the attribute
658 DataSize - Size of data
660 Data - Pointer to data
664 EFI_SUCCESS - The interface could be successfully installed
666 EFI_NOT_FOUND - The variable could not be discovered
668 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
672 return PeiGetVariable (
673 GetPeiServicesTablePointer (),
674 (CHAR16
*)VariableName
,
675 (EFI_GUID
*)VariableGuid
,
684 PeiGetNextVariableName (
685 IN EFI_PEI_SERVICES
**PeiServices
,
686 IN OUT UINTN
*VariableNameSize
,
687 IN OUT CHAR16
*VariableName
,
688 IN OUT EFI_GUID
*VendorGuid
694 Provide the get next variable functionality of the variable services.
698 PeiServices - General purpose services available to every PEIM.
699 VariabvleNameSize - The variable name's size.
700 VariableName - A pointer to the variable's name.
701 VendorGuid - A pointer to the EFI_GUID structure.
703 VariableNameSize - Size of the variable name
705 VariableName - The variable name
707 VendorGuid - The vendor's GUID
711 EFI_SUCCESS - The interface could be successfully installed
713 EFI_NOT_FOUND - The variable could not be discovered
717 VARIABLE_POINTER_TRACK Variable
;
721 if (VariableName
== NULL
) {
722 return EFI_INVALID_PARAMETER
;
725 Status
= FindVariable (PeiServices
, VariableName
, VendorGuid
, &Variable
);
727 if (Variable
.CurrPtr
== NULL
|| Status
!= EFI_SUCCESS
) {
731 if (VariableName
[0] != 0) {
733 // If variable name is not NULL, get next variable
735 Variable
.CurrPtr
= GetNextVariablePtr (Variable
.CurrPtr
);
738 while (!(Variable
.CurrPtr
>= Variable
.EndPtr
|| Variable
.CurrPtr
== NULL
)) {
739 if (IsValidVariableHeader (Variable
.CurrPtr
)) {
740 if (Variable
.CurrPtr
->State
== VAR_ADDED
) {
741 ASSERT (NameSizeOfVariable (Variable
.CurrPtr
) != 0);
743 VarNameSize
= (UINTN
) NameSizeOfVariable (Variable
.CurrPtr
);
744 if (VarNameSize
<= *VariableNameSize
) {
745 (*PeiServices
)->CopyMem (VariableName
, GetVariableNamePtr (Variable
.CurrPtr
), VarNameSize
);
747 (*PeiServices
)->CopyMem (VendorGuid
, &Variable
.CurrPtr
->VendorGuid
, sizeof (EFI_GUID
));
749 Status
= EFI_SUCCESS
;
751 Status
= EFI_BUFFER_TOO_SMALL
;
754 *VariableNameSize
= VarNameSize
;
760 Variable
.CurrPtr
= GetNextVariablePtr (Variable
.CurrPtr
);
767 return EFI_NOT_FOUND
;
772 PeiGetNextVariableName2 (
773 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI
*This
,
774 IN OUT UINTN
*VariableNameSize
,
775 IN OUT CHAR16
*VariableName
,
776 IN OUT EFI_GUID
*VariableGuid
782 Provide the get next variable functionality of the variable services.
786 PeiServices - General purpose services available to every PEIM.
787 VariabvleNameSize - The variable name's size.
788 VariableName - A pointer to the variable's name.
789 VariableGuid - A pointer to the EFI_GUID structure.
791 VariableNameSize - Size of the variable name
793 VariableName - The variable name
795 VendorGuid - The vendor's GUID
799 EFI_SUCCESS - The interface could be successfully installed
801 EFI_NOT_FOUND - The variable could not be discovered
805 return PeiGetNextVariableName (
806 GetPeiServicesTablePointer (),