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
*) ((UINTN
) GET_VARIABLE_DATA_PTR (Variable
) + Variable
->DataSize
+ GET_PAD_SIZE (Variable
->DataSize
));
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
||
128 Variable
->StartId
!= VARIABLE_DATA
||
129 (sizeof (VARIABLE_HEADER
) + Variable
->DataSize
+ Variable
->NameSize
) > MAX_VARIABLE_SIZE
138 VARIABLE_STORE_STATUS
140 GetVariableStoreStatus (
141 IN VARIABLE_STORE_HEADER
*VarStoreHeader
147 This code gets the pointer to the variable name.
151 VarStoreHeader Pointer to the Variable Store Header.
155 EfiRaw Variable store is raw
156 EfiValid Variable store is valid
157 EfiInvalid Variable store is invalid
161 if (VarStoreHeader
->Signature
== VARIABLE_STORE_SIGNATURE
&&
162 VarStoreHeader
->Format
== VARIABLE_STORE_FORMATTED
&&
163 VarStoreHeader
->State
== VARIABLE_STORE_HEALTHY
169 if (VarStoreHeader
->Signature
== 0xffffffff &&
170 VarStoreHeader
->Size
== 0xffffffff &&
171 VarStoreHeader
->Format
== 0xff &&
172 VarStoreHeader
->State
== 0xff
183 CompareWithValidVariable (
184 IN VARIABLE_HEADER
*Variable
,
185 IN CONST CHAR16
*VariableName
,
186 IN CONST EFI_GUID
*VendorGuid
,
187 OUT VARIABLE_POINTER_TRACK
*PtrTrack
193 This function compares a variable with variable entries in database
197 Variable - Pointer to the variable in our database
198 VariableName - Name of the variable to compare to 'Variable'
199 VendorGuid - GUID of the variable to compare to 'Variable'
200 PtrTrack - Variable Track Pointer structure that contains
201 Variable Information.
205 EFI_SUCCESS - Found match variable
206 EFI_NOT_FOUND - Variable not found
210 if (VariableName
[0] == 0) {
211 PtrTrack
->CurrPtr
= Variable
;
215 // Don't use CompareGuid function here for performance reasons.
216 // Instead we compare the GUID a UINT32 at a time and branch
217 // on the first failed comparison.
219 if ((((INT32
*) VendorGuid
)[0] == ((INT32
*) &Variable
->VendorGuid
)[0]) &&
220 (((INT32
*) VendorGuid
)[1] == ((INT32
*) &Variable
->VendorGuid
)[1]) &&
221 (((INT32
*) VendorGuid
)[2] == ((INT32
*) &Variable
->VendorGuid
)[2]) &&
222 (((INT32
*) VendorGuid
)[3] == ((INT32
*) &Variable
->VendorGuid
)[3])
224 if (!CompareMem (VariableName
, GET_VARIABLE_NAME_PTR (Variable
), Variable
->NameSize
)) {
225 PtrTrack
->CurrPtr
= Variable
;
231 return EFI_NOT_FOUND
;
238 IN EFI_PEI_SERVICES
**PeiServices
,
239 IN CONST CHAR16
*VariableName
,
240 IN CONST EFI_GUID
*VendorGuid
,
241 OUT VARIABLE_POINTER_TRACK
*PtrTrack
247 This code finds variable in storage blocks (Non-Volatile)
251 PeiServices - General purpose services available to every PEIM.
252 VariableName - Name of the variable to be found
253 VendorGuid - Vendor GUID to be found.
254 PtrTrack - Variable Track Pointer structure that contains
255 Variable Information.
259 EFI_SUCCESS - Variable found successfully
260 EFI_NOT_FOUND - Variable not found
261 EFI_INVALID_PARAMETER - Invalid variable name
265 EFI_HOB_GUID_TYPE
*GuidHob
;
266 VARIABLE_STORE_HEADER
*VariableStoreHeader
;
267 VARIABLE_HEADER
*Variable
;
268 VARIABLE_HEADER
*MaxIndex
;
269 VARIABLE_INDEX_TABLE
*IndexTable
;
273 if (VariableName
!= 0 && VendorGuid
== NULL
) {
274 return EFI_INVALID_PARAMETER
;
277 // No Variable Address equals zero, so 0 as initial value is safe.
281 GuidHob
= GetFirstGuidHob (&mEfiVariableIndexTableGuid
);
282 if (GuidHob
== NULL
) {
283 IndexTable
= BuildGuidHob (&mEfiVariableIndexTableGuid
, sizeof (VARIABLE_INDEX_TABLE
));
284 IndexTable
->Length
= 0;
285 IndexTable
->StartPtr
= NULL
;
286 IndexTable
->EndPtr
= NULL
;
287 IndexTable
->GoneThrough
= 0;
289 IndexTable
= GET_GUID_HOB_DATA (GuidHob
);
290 for (Count
= 0; Count
< IndexTable
->Length
; Count
++)
292 MaxIndex
= GetVariableByIndex (IndexTable
, Count
);
294 if (CompareWithValidVariable (MaxIndex
, VariableName
, VendorGuid
, PtrTrack
) == EFI_SUCCESS
) {
295 PtrTrack
->StartPtr
= IndexTable
->StartPtr
;
296 PtrTrack
->EndPtr
= IndexTable
->EndPtr
;
302 if (IndexTable
->GoneThrough
) {
303 return EFI_NOT_FOUND
;
307 // If not found in HOB, then let's start from the MaxIndex we've found.
309 if (MaxIndex
!= NULL
) {
310 Variable
= GetNextVariablePtr (MaxIndex
);
312 if (IndexTable
->StartPtr
|| IndexTable
->EndPtr
) {
313 Variable
= IndexTable
->StartPtr
;
315 VariableBase
= (UINT8
*) (UINTN
) PcdGet32 (PcdFlashNvStorageVariableBase
);
316 VariableStoreHeader
= (VARIABLE_STORE_HEADER
*) (VariableBase
+ \
317 ((EFI_FIRMWARE_VOLUME_HEADER
*) (VariableBase
)) -> HeaderLength
);
319 if (GetVariableStoreStatus (VariableStoreHeader
) != EfiValid
) {
320 return EFI_UNSUPPORTED
;
323 if (~VariableStoreHeader
->Size
== 0) {
324 return EFI_NOT_FOUND
;
327 // Find the variable by walk through non-volatile variable store
329 IndexTable
->StartPtr
= (VARIABLE_HEADER
*) (VariableStoreHeader
+ 1);
330 IndexTable
->EndPtr
= (VARIABLE_HEADER
*) ((UINTN
) VariableStoreHeader
+ VariableStoreHeader
->Size
);
333 // Start Pointers for the variable.
334 // Actual Data Pointer where data can be written.
336 Variable
= IndexTable
->StartPtr
;
340 // Find the variable by walk through non-volatile variable store
342 PtrTrack
->StartPtr
= IndexTable
->StartPtr
;
343 PtrTrack
->EndPtr
= IndexTable
->EndPtr
;
345 while (IsValidVariableHeader (Variable
) && (Variable
<= IndexTable
->EndPtr
)) {
346 if (Variable
->State
== VAR_ADDED
) {
348 // Record Variable in VariableIndex HOB
350 if (IndexTable
->Length
< VARIABLE_INDEX_TABLE_VOLUME
)
352 VariableIndexTableUpdate (IndexTable
, Variable
);
355 if (CompareWithValidVariable (Variable
, VariableName
, VendorGuid
, PtrTrack
) == EFI_SUCCESS
) {
360 Variable
= GetNextVariablePtr (Variable
);
363 // If gone through the VariableStore, that means we never find in Firmware any more.
365 if (IndexTable
->Length
< VARIABLE_INDEX_TABLE_VOLUME
) {
366 IndexTable
->GoneThrough
= 1;
369 PtrTrack
->CurrPtr
= NULL
;
371 return EFI_NOT_FOUND
;
377 IN EFI_PEI_SERVICES
**PeiServices
,
378 IN CHAR16
*VariableName
,
379 IN EFI_GUID
* VendorGuid
,
380 OUT UINT32
*Attributes OPTIONAL
,
381 IN OUT UINTN
*DataSize
,
388 Provide the read variable functionality of the variable services.
392 PeiServices - General purpose services available to every PEIM.
394 VariableName - The variable name
396 VendorGuid - The vendor's GUID
398 Attributes - Pointer to the attribute
400 DataSize - Size of data
402 Data - Pointer to data
406 EFI_SUCCESS - The interface could be successfully installed
408 EFI_NOT_FOUND - The variable could not be discovered
410 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
414 VARIABLE_POINTER_TRACK Variable
;
418 if (VariableName
== NULL
|| VendorGuid
== NULL
) {
419 return EFI_INVALID_PARAMETER
;
422 // Find existing variable
424 Status
= FindVariable (PeiServices
, VariableName
, VendorGuid
, &Variable
);
426 if (Variable
.CurrPtr
== NULL
|| Status
!= EFI_SUCCESS
) {
432 VarDataSize
= Variable
.CurrPtr
->DataSize
;
433 if (*DataSize
>= VarDataSize
) {
434 (*PeiServices
)->CopyMem (Data
, GET_VARIABLE_DATA_PTR (Variable
.CurrPtr
), VarDataSize
);
436 if (Attributes
!= NULL
) {
437 *Attributes
= Variable
.CurrPtr
->Attributes
;
440 *DataSize
= VarDataSize
;
443 *DataSize
= VarDataSize
;
444 return EFI_BUFFER_TOO_SMALL
;
452 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI
*This
,
453 IN CONST CHAR16
*VariableName
,
454 IN CONST EFI_GUID
*VariableGuid
,
455 OUT UINT32
*Attributes
,
456 IN OUT UINTN
*DataSize
,
463 Provide the read variable functionality of the variable services.
467 PeiServices - General purpose services available to every PEIM.
469 VariableName - The variable name
471 VendorGuid - The vendor's GUID
473 Attributes - Pointer to the attribute
475 DataSize - Size of data
477 Data - Pointer to data
481 EFI_SUCCESS - The interface could be successfully installed
483 EFI_NOT_FOUND - The variable could not be discovered
485 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
489 return PeiGetVariable (
490 GetPeiServicesTablePointer (),
491 (CHAR16
*)VariableName
,
492 (EFI_GUID
*)VariableGuid
,
501 PeiGetNextVariableName (
502 IN EFI_PEI_SERVICES
**PeiServices
,
503 IN OUT UINTN
*VariableNameSize
,
504 IN OUT CHAR16
*VariableName
,
505 IN OUT EFI_GUID
*VendorGuid
511 Provide the get next variable functionality of the variable services.
515 PeiServices - General purpose services available to every PEIM.
516 VariabvleNameSize - The variable name's size.
517 VariableName - A pointer to the variable's name.
518 VendorGuid - A pointer to the EFI_GUID structure.
520 VariableNameSize - Size of the variable name
522 VariableName - The variable name
524 VendorGuid - The vendor's GUID
528 EFI_SUCCESS - The interface could be successfully installed
530 EFI_NOT_FOUND - The variable could not be discovered
534 VARIABLE_POINTER_TRACK Variable
;
538 if (VariableName
== NULL
) {
539 return EFI_INVALID_PARAMETER
;
542 Status
= FindVariable (PeiServices
, VariableName
, VendorGuid
, &Variable
);
544 if (Variable
.CurrPtr
== NULL
|| Status
!= EFI_SUCCESS
) {
548 if (VariableName
[0] != 0) {
550 // If variable name is not NULL, get next variable
552 Variable
.CurrPtr
= GetNextVariablePtr (Variable
.CurrPtr
);
555 while (!(Variable
.CurrPtr
>= Variable
.EndPtr
|| Variable
.CurrPtr
== NULL
)) {
556 if (IsValidVariableHeader (Variable
.CurrPtr
)) {
557 if (Variable
.CurrPtr
->State
== VAR_ADDED
) {
558 VarNameSize
= (UINTN
) Variable
.CurrPtr
->NameSize
;
559 if (VarNameSize
<= *VariableNameSize
) {
560 (*PeiServices
)->CopyMem (VariableName
, GET_VARIABLE_NAME_PTR (Variable
.CurrPtr
), VarNameSize
);
562 (*PeiServices
)->CopyMem (VendorGuid
, &Variable
.CurrPtr
->VendorGuid
, sizeof (EFI_GUID
));
564 Status
= EFI_SUCCESS
;
566 Status
= EFI_BUFFER_TOO_SMALL
;
569 *VariableNameSize
= VarNameSize
;
575 Variable
.CurrPtr
= GetNextVariablePtr (Variable
.CurrPtr
);
582 return EFI_NOT_FOUND
;
587 PeiGetNextVariableName2 (
588 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI
*This
,
589 IN OUT UINTN
*VariableNameSize
,
590 IN OUT CHAR16
*VariableName
,
591 IN OUT EFI_GUID
*VariableGuid
597 Provide the get next variable functionality of the variable services.
601 PeiServices - General purpose services available to every PEIM.
602 VariabvleNameSize - The variable name's size.
603 VariableName - A pointer to the variable's name.
604 VariableGuid - A pointer to the EFI_GUID structure.
606 VariableNameSize - Size of the variable name
608 VariableName - The variable name
610 VendorGuid - The vendor's GUID
614 EFI_SUCCESS - The interface could be successfully installed
616 EFI_NOT_FOUND - The variable could not be discovered
620 return PeiGetNextVariableName (
621 GetPeiServicesTablePointer (),