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]);
86 IN VARIABLE_HEADER
*Variable
92 This code checks if variable header is valid or not.
95 Variable Pointer to the Variable Header.
98 TRUE Variable header is valid.
99 FALSE Variable header is not valid.
103 return (VARIABLE_HEADER
*) HEADER_ALIGN ((UINTN
) GET_VARIABLE_DATA_PTR (Variable
) + DATASIZE_OF_VARIABLE (Variable
) + GET_PAD_SIZE (DATASIZE_OF_VARIABLE (Variable
)));
109 IsValidVariableHeader (
110 IN VARIABLE_HEADER
*Variable
116 This code checks if variable header is valid or not.
119 Variable Pointer to the Variable Header.
122 TRUE Variable header is valid.
123 FALSE Variable header is not valid.
127 if (Variable
== NULL
|| Variable
->StartId
!= VARIABLE_DATA
) {
135 VARIABLE_STORE_STATUS
137 GetVariableStoreStatus (
138 IN VARIABLE_STORE_HEADER
*VarStoreHeader
144 This code gets the pointer to the variable name.
148 VarStoreHeader Pointer to the Variable Store Header.
152 EfiRaw Variable store is raw
153 EfiValid Variable store is valid
154 EfiInvalid Variable store is invalid
158 if (VarStoreHeader
->Signature
== VARIABLE_STORE_SIGNATURE
&&
159 VarStoreHeader
->Format
== VARIABLE_STORE_FORMATTED
&&
160 VarStoreHeader
->State
== VARIABLE_STORE_HEALTHY
166 if (VarStoreHeader
->Signature
== 0xffffffff &&
167 VarStoreHeader
->Size
== 0xffffffff &&
168 VarStoreHeader
->Format
== 0xff &&
169 VarStoreHeader
->State
== 0xff
180 CompareWithValidVariable (
181 IN VARIABLE_HEADER
*Variable
,
182 IN CONST CHAR16
*VariableName
,
183 IN CONST EFI_GUID
*VendorGuid
,
184 OUT VARIABLE_POINTER_TRACK
*PtrTrack
190 This function compares a variable with variable entries in database
194 Variable - Pointer to the variable in our database
195 VariableName - Name of the variable to compare to 'Variable'
196 VendorGuid - GUID of the variable to compare to 'Variable'
197 PtrTrack - Variable Track Pointer structure that contains
198 Variable Information.
202 EFI_SUCCESS - Found match variable
203 EFI_NOT_FOUND - Variable not found
207 if (VariableName
[0] == 0) {
208 PtrTrack
->CurrPtr
= Variable
;
212 // Don't use CompareGuid function here for performance reasons.
213 // Instead we compare the GUID a UINT32 at a time and branch
214 // on the first failed comparison.
216 if ((((INT32
*) VendorGuid
)[0] == ((INT32
*) &Variable
->VendorGuid
)[0]) &&
217 (((INT32
*) VendorGuid
)[1] == ((INT32
*) &Variable
->VendorGuid
)[1]) &&
218 (((INT32
*) VendorGuid
)[2] == ((INT32
*) &Variable
->VendorGuid
)[2]) &&
219 (((INT32
*) VendorGuid
)[3] == ((INT32
*) &Variable
->VendorGuid
)[3])
221 ASSERT (NAMESIZE_OF_VARIABLE (Variable
) != 0);
222 if (!CompareMem (VariableName
, GET_VARIABLE_NAME_PTR (Variable
), NAMESIZE_OF_VARIABLE (Variable
))) {
223 PtrTrack
->CurrPtr
= Variable
;
229 return EFI_NOT_FOUND
;
236 IN EFI_PEI_SERVICES
**PeiServices
,
237 IN CONST CHAR16
*VariableName
,
238 IN CONST EFI_GUID
*VendorGuid
,
239 OUT VARIABLE_POINTER_TRACK
*PtrTrack
245 This code finds variable in storage blocks (Non-Volatile)
249 PeiServices - General purpose services available to every PEIM.
250 VariableName - Name of the variable to be found
251 VendorGuid - Vendor GUID to be found.
252 PtrTrack - Variable Track Pointer structure that contains
253 Variable Information.
257 EFI_SUCCESS - Variable found successfully
258 EFI_NOT_FOUND - Variable not found
259 EFI_INVALID_PARAMETER - Invalid variable name
263 EFI_HOB_GUID_TYPE
*GuidHob
;
264 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
265 VARIABLE_HEADER
*Variable
;
266 VARIABLE_HEADER
*MaxIndex
;
267 VARIABLE_INDEX_TABLE
*IndexTable
;
271 if (VariableName
!= 0 && VendorGuid
== NULL
) {
272 return EFI_INVALID_PARAMETER
;
275 // No Variable Address equals zero, so 0 as initial value is safe.
279 GuidHob
= GetFirstGuidHob (&mEfiVariableIndexTableGuid
);
280 if (GuidHob
== NULL
) {
281 IndexTable
= BuildGuidHob (&mEfiVariableIndexTableGuid
, sizeof (VARIABLE_INDEX_TABLE
));
282 IndexTable
->Length
= 0;
283 IndexTable
->StartPtr
= NULL
;
284 IndexTable
->EndPtr
= NULL
;
285 IndexTable
->GoneThrough
= 0;
287 IndexTable
= GET_GUID_HOB_DATA (GuidHob
);
288 for (Count
= 0; Count
< IndexTable
->Length
; Count
++)
290 MaxIndex
= GetVariableByIndex (IndexTable
, Count
);
291 if (CompareWithValidVariable (MaxIndex
, VariableName
, VendorGuid
, PtrTrack
) == EFI_SUCCESS
) {
292 PtrTrack
->StartPtr
= IndexTable
->StartPtr
;
293 PtrTrack
->EndPtr
= IndexTable
->EndPtr
;
299 if (IndexTable
->GoneThrough
) {
300 return EFI_NOT_FOUND
;
304 // If not found in HOB, then let's start from the MaxIndex we've found.
306 if (MaxIndex
!= NULL
) {
307 Variable
= GetNextVariablePtr (MaxIndex
);
309 if (IndexTable
->StartPtr
|| IndexTable
->EndPtr
) {
310 Variable
= IndexTable
->StartPtr
;
312 VariableBase
= (UINT8
*) (UINTN
) PcdGet32 (PcdFlashNvStorageVariableBase
);
313 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (VariableBase
+ \
314 ((EFI_FIRMWARE_VOLUME_HEADER
*) (VariableBase
)) -> HeaderLength
);
316 if (GetVariableStoreStatus (VariableStoreHeader
) != EfiValid
) {
317 return EFI_UNSUPPORTED
;
320 if (~VariableStoreHeader
->Size
== 0) {
321 return EFI_NOT_FOUND
;
324 // Find the variable by walk through non-volatile variable store
326 IndexTable
->StartPtr
= (VARIABLE_HEADER
*) (VariableStoreHeader
+ 1);
327 IndexTable
->EndPtr
= (VARIABLE_HEADER
*) ((UINTN
) VariableStoreHeader
+ VariableStoreHeader
->Size
);
330 // Start Pointers for the variable.
331 // Actual Data Pointer where data can be written.
333 Variable
= IndexTable
->StartPtr
;
337 // Find the variable by walk through non-volatile variable store
339 PtrTrack
->StartPtr
= IndexTable
->StartPtr
;
340 PtrTrack
->EndPtr
= IndexTable
->EndPtr
;
342 while (IsValidVariableHeader (Variable
) && (Variable
<= IndexTable
->EndPtr
)) {
343 if (Variable
->State
== VAR_ADDED
) {
345 // Record Variable in VariableIndex HOB
347 if (IndexTable
->Length
< VARIABLE_INDEX_TABLE_VOLUME
)
349 VariableIndexTableUpdate (IndexTable
, Variable
);
352 if (CompareWithValidVariable (Variable
, VariableName
, VendorGuid
, PtrTrack
) == EFI_SUCCESS
) {
357 Variable
= GetNextVariablePtr (Variable
);
360 // If gone through the VariableStore, that means we never find in Firmware any more.
362 if (IndexTable
->Length
< VARIABLE_INDEX_TABLE_VOLUME
) {
363 IndexTable
->GoneThrough
= 1;
366 PtrTrack
->CurrPtr
= NULL
;
368 return EFI_NOT_FOUND
;
374 IN EFI_PEI_SERVICES
**PeiServices
,
375 IN CHAR16
*VariableName
,
376 IN EFI_GUID
* VendorGuid
,
377 OUT UINT32
*Attributes OPTIONAL
,
378 IN OUT UINTN
*DataSize
,
385 Provide the read variable functionality of the variable services.
389 PeiServices - General purpose services available to every PEIM.
391 VariableName - The variable name
393 VendorGuid - The vendor's GUID
395 Attributes - Pointer to the attribute
397 DataSize - Size of data
399 Data - Pointer to data
403 EFI_SUCCESS - The interface could be successfully installed
405 EFI_NOT_FOUND - The variable could not be discovered
407 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
411 VARIABLE_POINTER_TRACK Variable
;
415 if (VariableName
== NULL
|| VendorGuid
== NULL
) {
416 return EFI_INVALID_PARAMETER
;
419 // Find existing variable
421 Status
= FindVariable (PeiServices
, VariableName
, VendorGuid
, &Variable
);
423 if (Variable
.CurrPtr
== NULL
|| Status
!= EFI_SUCCESS
) {
429 VarDataSize
= DATASIZE_OF_VARIABLE (Variable
.CurrPtr
);
430 if (*DataSize
>= VarDataSize
) {
431 (*PeiServices
)->CopyMem (Data
, GET_VARIABLE_DATA_PTR (Variable
.CurrPtr
), VarDataSize
);
433 if (Attributes
!= NULL
) {
434 *Attributes
= Variable
.CurrPtr
->Attributes
;
437 *DataSize
= VarDataSize
;
440 *DataSize
= VarDataSize
;
441 return EFI_BUFFER_TOO_SMALL
;
449 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI
*This
,
450 IN CONST CHAR16
*VariableName
,
451 IN CONST EFI_GUID
*VariableGuid
,
452 OUT UINT32
*Attributes
,
453 IN OUT UINTN
*DataSize
,
460 Provide the read variable functionality of the variable services.
464 PeiServices - General purpose services available to every PEIM.
466 VariableName - The variable name
468 VendorGuid - The vendor's GUID
470 Attributes - Pointer to the attribute
472 DataSize - Size of data
474 Data - Pointer to data
478 EFI_SUCCESS - The interface could be successfully installed
480 EFI_NOT_FOUND - The variable could not be discovered
482 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
486 return PeiGetVariable (
487 GetPeiServicesTablePointer (),
488 (CHAR16
*)VariableName
,
489 (EFI_GUID
*)VariableGuid
,
498 PeiGetNextVariableName (
499 IN EFI_PEI_SERVICES
**PeiServices
,
500 IN OUT UINTN
*VariableNameSize
,
501 IN OUT CHAR16
*VariableName
,
502 IN OUT EFI_GUID
*VendorGuid
508 Provide the get next variable functionality of the variable services.
512 PeiServices - General purpose services available to every PEIM.
513 VariabvleNameSize - The variable name's size.
514 VariableName - A pointer to the variable's name.
515 VendorGuid - A pointer to the EFI_GUID structure.
517 VariableNameSize - Size of the variable name
519 VariableName - The variable name
521 VendorGuid - The vendor's GUID
525 EFI_SUCCESS - The interface could be successfully installed
527 EFI_NOT_FOUND - The variable could not be discovered
531 VARIABLE_POINTER_TRACK Variable
;
535 if (VariableName
== NULL
) {
536 return EFI_INVALID_PARAMETER
;
539 Status
= FindVariable (PeiServices
, VariableName
, VendorGuid
, &Variable
);
541 if (Variable
.CurrPtr
== NULL
|| Status
!= EFI_SUCCESS
) {
545 if (VariableName
[0] != 0) {
547 // If variable name is not NULL, get next variable
549 Variable
.CurrPtr
= GetNextVariablePtr (Variable
.CurrPtr
);
552 while (!(Variable
.CurrPtr
>= Variable
.EndPtr
|| Variable
.CurrPtr
== NULL
)) {
553 if (IsValidVariableHeader (Variable
.CurrPtr
)) {
554 if (Variable
.CurrPtr
->State
== VAR_ADDED
) {
555 ASSERT (NAMESIZE_OF_VARIABLE (Variable
.CurrPtr
) != 0);
557 VarNameSize
= (UINTN
) NAMESIZE_OF_VARIABLE (Variable
.CurrPtr
);
558 if (VarNameSize
<= *VariableNameSize
) {
559 (*PeiServices
)->CopyMem (VariableName
, GET_VARIABLE_NAME_PTR (Variable
.CurrPtr
), VarNameSize
);
561 (*PeiServices
)->CopyMem (VendorGuid
, &Variable
.CurrPtr
->VendorGuid
, sizeof (EFI_GUID
));
563 Status
= EFI_SUCCESS
;
565 Status
= EFI_BUFFER_TOO_SMALL
;
568 *VariableNameSize
= VarNameSize
;
574 Variable
.CurrPtr
= GetNextVariablePtr (Variable
.CurrPtr
);
581 return EFI_NOT_FOUND
;
586 PeiGetNextVariableName2 (
587 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI
*This
,
588 IN OUT UINTN
*VariableNameSize
,
589 IN OUT CHAR16
*VariableName
,
590 IN OUT EFI_GUID
*VariableGuid
596 Provide the get next variable functionality of the variable services.
600 PeiServices - General purpose services available to every PEIM.
601 VariabvleNameSize - The variable name's size.
602 VariableName - A pointer to the variable's name.
603 VariableGuid - A pointer to the EFI_GUID structure.
605 VariableNameSize - Size of the variable name
607 VariableName - The variable name
609 VendorGuid - The vendor's GUID
613 EFI_SUCCESS - The interface could be successfully installed
615 EFI_NOT_FOUND - The variable could not be discovered
619 return PeiGetNextVariableName (
620 GetPeiServicesTablePointer (),