]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Variable/Pei/Variable.c
remove some comments introduced by tools.
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
1 /*++
2
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
8
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.
11 Module Name:
12
13 Variable.c
14
15 Abstract:
16
17 Framework PEIM to provide the Variable functionality
18
19 --*/
20
21
22 #include "Variable.h"
23
24 //
25 // Module globals
26 //
27 static EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = {
28 PeiGetVariable,
29 PeiGetNextVariableName
30 };
31
32 static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
34 &gEfiPeiReadOnlyVariable2PpiGuid,
35 &mVariablePpi
36 };
37
38 EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;
39
40 EFI_STATUS
41 EFIAPI
42 PeimInitializeVariableServices (
43 IN EFI_FFS_FILE_HEADER *FfsHeader,
44 IN EFI_PEI_SERVICES **PeiServices
45 )
46 /*++
47
48 Routine Description:
49
50 Provide the functionality of the variable services.
51
52 Arguments:
53
54 FfsHeadher - The FFS file header
55 PeiServices - General purpose services available to every PEIM.
56
57 Returns:
58
59 Status - EFI_SUCCESS if the interface could be successfully
60 installed
61
62 --*/
63 {
64 //
65 // Publish the variable capability to other modules
66 //
67 return (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable);
68
69 }
70
71 STATIC
72 VARIABLE_HEADER *
73 GetNextVariablePtr (
74 IN VARIABLE_HEADER *Variable
75 )
76 /*++
77
78 Routine Description:
79
80 This code checks if variable header is valid or not.
81
82 Arguments:
83 Variable Pointer to the Variable Header.
84
85 Returns:
86 TRUE Variable header is valid.
87 FALSE Variable header is not valid.
88
89 --*/
90 {
91 return (VARIABLE_HEADER *) ((UINTN) GET_VARIABLE_DATA_PTR (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
92 }
93
94 STATIC
95 BOOLEAN
96 EFIAPI
97 IsValidVariableHeader (
98 IN VARIABLE_HEADER *Variable
99 )
100 /*++
101
102 Routine Description:
103
104 This code checks if variable header is valid or not.
105
106 Arguments:
107 Variable Pointer to the Variable Header.
108
109 Returns:
110 TRUE Variable header is valid.
111 FALSE Variable header is not valid.
112
113 --*/
114 {
115 if (Variable == NULL ||
116 Variable->StartId != VARIABLE_DATA ||
117 (sizeof (VARIABLE_HEADER) + Variable->DataSize + Variable->NameSize) > MAX_VARIABLE_SIZE
118 ) {
119 return FALSE;
120 }
121
122 return TRUE;
123 }
124
125 STATIC
126 VARIABLE_STORE_STATUS
127 EFIAPI
128 GetVariableStoreStatus (
129 IN VARIABLE_STORE_HEADER *VarStoreHeader
130 )
131 /*++
132
133 Routine Description:
134
135 This code gets the pointer to the variable name.
136
137 Arguments:
138
139 VarStoreHeader Pointer to the Variable Store Header.
140
141 Returns:
142
143 EfiRaw Variable store is raw
144 EfiValid Variable store is valid
145 EfiInvalid Variable store is invalid
146
147 --*/
148 {
149 if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&
150 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
151 VarStoreHeader->State == VARIABLE_STORE_HEALTHY
152 ) {
153
154 return EfiValid;
155 }
156
157 if (VarStoreHeader->Signature == 0xffffffff &&
158 VarStoreHeader->Size == 0xffffffff &&
159 VarStoreHeader->Format == 0xff &&
160 VarStoreHeader->State == 0xff
161 ) {
162
163 return EfiRaw;
164 } else {
165 return EfiInvalid;
166 }
167 }
168
169 STATIC
170 EFI_STATUS
171 CompareWithValidVariable (
172 IN VARIABLE_HEADER *Variable,
173 IN CONST CHAR16 *VariableName,
174 IN CONST EFI_GUID *VendorGuid,
175 OUT VARIABLE_POINTER_TRACK *PtrTrack
176 )
177 /*++
178
179 Routine Description:
180
181 This function compares a variable with variable entries in database
182
183 Arguments:
184
185 Variable - Pointer to the variable in our database
186 VariableName - Name of the variable to compare to 'Variable'
187 VendorGuid - GUID of the variable to compare to 'Variable'
188 PtrTrack - Variable Track Pointer structure that contains
189 Variable Information.
190
191 Returns:
192
193 EFI_SUCCESS - Found match variable
194 EFI_NOT_FOUND - Variable not found
195
196 --*/
197 {
198 if (VariableName[0] == 0) {
199 PtrTrack->CurrPtr = Variable;
200 return EFI_SUCCESS;
201 } else {
202 //
203 // Don't use CompareGuid function here for performance reasons.
204 // Instead we compare the GUID a UINT32 at a time and branch
205 // on the first failed comparison.
206 //
207 if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&
208 (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&
209 (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&
210 (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])
211 ) {
212 if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), Variable->NameSize)) {
213 PtrTrack->CurrPtr = Variable;
214 return EFI_SUCCESS;
215 }
216 }
217 }
218
219 return EFI_NOT_FOUND;
220 }
221
222 STATIC
223 EFI_STATUS
224 EFIAPI
225 FindVariable (
226 IN EFI_PEI_SERVICES **PeiServices,
227 IN CONST CHAR16 *VariableName,
228 IN CONST EFI_GUID *VendorGuid,
229 OUT VARIABLE_POINTER_TRACK *PtrTrack
230 )
231 /*++
232
233 Routine Description:
234
235 This code finds variable in storage blocks (Non-Volatile)
236
237 Arguments:
238
239 PeiServices - General purpose services available to every PEIM.
240 VariableName - Name of the variable to be found
241 VendorGuid - Vendor GUID to be found.
242 PtrTrack - Variable Track Pointer structure that contains
243 Variable Information.
244
245 Returns:
246
247 EFI_SUCCESS - Variable found successfully
248 EFI_NOT_FOUND - Variable not found
249 EFI_INVALID_PARAMETER - Invalid variable name
250
251 --*/
252 {
253 EFI_HOB_GUID_TYPE *GuidHob;
254 VARIABLE_STORE_HEADER *VariableStoreHeader;
255 VARIABLE_HEADER *Variable;
256 VARIABLE_HEADER *MaxIndex;
257 VARIABLE_INDEX_TABLE *IndexTable;
258 UINT32 Count;
259 UINT8 *VariableBase;
260
261 if (VariableName != 0 && VendorGuid == NULL) {
262 return EFI_INVALID_PARAMETER;
263 }
264 //
265 // No Variable Address equals zero, so 0 as initial value is safe.
266 //
267 MaxIndex = 0;
268
269 GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);
270 if (GuidHob == NULL) {
271 IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));
272 IndexTable->Length = 0;
273 IndexTable->StartPtr = NULL;
274 IndexTable->EndPtr = NULL;
275 IndexTable->GoneThrough = 0;
276 } else {
277 IndexTable = GET_GUID_HOB_DATA (GuidHob);
278 for (Count = 0; Count < IndexTable->Length; Count++)
279 {
280 MaxIndex = GetVariableByIndex (IndexTable, Count);
281
282 if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
283 PtrTrack->StartPtr = IndexTable->StartPtr;
284 PtrTrack->EndPtr = IndexTable->EndPtr;
285
286 return EFI_SUCCESS;
287 }
288 }
289
290 if (IndexTable->GoneThrough) {
291 return EFI_NOT_FOUND;
292 }
293 }
294 //
295 // If not found in HOB, then let's start from the MaxIndex we've found.
296 //
297 if (MaxIndex != NULL) {
298 Variable = GetNextVariablePtr (MaxIndex);
299 } else {
300 if (IndexTable->StartPtr || IndexTable->EndPtr) {
301 Variable = IndexTable->StartPtr;
302 } else {
303 VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);
304 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \
305 ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);
306
307 if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
308 return EFI_UNSUPPORTED;
309 }
310
311 if (~VariableStoreHeader->Size == 0) {
312 return EFI_NOT_FOUND;
313 }
314 //
315 // Find the variable by walk through non-volatile variable store
316 //
317 IndexTable->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
318 IndexTable->EndPtr = (VARIABLE_HEADER *) ((UINTN) VariableStoreHeader + VariableStoreHeader->Size);
319
320 //
321 // Start Pointers for the variable.
322 // Actual Data Pointer where data can be written.
323 //
324 Variable = IndexTable->StartPtr;
325 }
326 }
327 //
328 // Find the variable by walk through non-volatile variable store
329 //
330 PtrTrack->StartPtr = IndexTable->StartPtr;
331 PtrTrack->EndPtr = IndexTable->EndPtr;
332
333 while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {
334 if (Variable->State == VAR_ADDED) {
335 //
336 // Record Variable in VariableIndex HOB
337 //
338 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME)
339 {
340 VariableIndexTableUpdate (IndexTable, Variable);
341 }
342
343 if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
344 return EFI_SUCCESS;
345 }
346 }
347
348 Variable = GetNextVariablePtr (Variable);
349 }
350 //
351 // If gone through the VariableStore, that means we never find in Firmware any more.
352 //
353 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {
354 IndexTable->GoneThrough = 1;
355 }
356
357 PtrTrack->CurrPtr = NULL;
358
359 return EFI_NOT_FOUND;
360 }
361
362 EFI_STATUS
363 EFIAPI
364 PeiGetVariable (
365 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
366 IN CONST CHAR16 *VariableName,
367 IN CONST EFI_GUID *VariableGuid,
368 OUT UINT32 *Attributes,
369 IN OUT UINTN *DataSize,
370 OUT VOID *Data
371 )
372 /*++
373
374 Routine Description:
375
376 Provide the read variable functionality of the variable services.
377
378 Arguments:
379
380 PeiServices - General purpose services available to every PEIM.
381
382 VariableName - The variable name
383
384 VendorGuid - The vendor's GUID
385
386 Attributes - Pointer to the attribute
387
388 DataSize - Size of data
389
390 Data - Pointer to data
391
392 Returns:
393
394 EFI_SUCCESS - The interface could be successfully installed
395
396 EFI_NOT_FOUND - The variable could not be discovered
397
398 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
399
400 --*/
401 {
402 VARIABLE_POINTER_TRACK Variable;
403 UINTN VarDataSize;
404 EFI_STATUS Status;
405 EFI_PEI_SERVICES **PeiServices;
406
407 PeiServices = GetPeiServicesTablePointer ();
408 if (VariableName == NULL || VariableGuid == NULL) {
409 return EFI_INVALID_PARAMETER;
410 }
411 //
412 // Find existing variable
413 //
414 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);
415 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
416 return Status;
417 }
418 //
419 // Get data size
420 //
421 VarDataSize = Variable.CurrPtr->DataSize;
422 if (*DataSize >= VarDataSize) {
423 (*PeiServices)->CopyMem (Data, GET_VARIABLE_DATA_PTR (Variable.CurrPtr), VarDataSize);
424
425 if (Attributes != NULL) {
426 *Attributes = Variable.CurrPtr->Attributes;
427 }
428
429 *DataSize = VarDataSize;
430 return EFI_SUCCESS;
431 } else {
432 *DataSize = VarDataSize;
433 return EFI_BUFFER_TOO_SMALL;
434 }
435 }
436
437 EFI_STATUS
438 EFIAPI
439 PeiGetNextVariableName (
440 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
441 IN OUT UINTN *VariableNameSize,
442 IN OUT CHAR16 *VariableName,
443 IN OUT EFI_GUID *VariableGuid
444 )
445 /*++
446
447 Routine Description:
448
449 Provide the get next variable functionality of the variable services.
450
451 Arguments:
452
453 PeiServices - General purpose services available to every PEIM.
454 VariabvleNameSize - The variable name's size.
455 VariableName - A pointer to the variable's name.
456 VariableGuid - A pointer to the EFI_GUID structure.
457
458 VariableNameSize - Size of the variable name
459
460 VariableName - The variable name
461
462 VendorGuid - The vendor's GUID
463
464 Returns:
465
466 EFI_SUCCESS - The interface could be successfully installed
467
468 EFI_NOT_FOUND - The variable could not be discovered
469
470 --*/
471 {
472 VARIABLE_POINTER_TRACK Variable;
473 UINTN VarNameSize;
474 EFI_STATUS Status;
475 EFI_PEI_SERVICES **PeiServices;
476
477 PeiServices = GetPeiServicesTablePointer ();
478 if (VariableName == NULL) {
479 return EFI_INVALID_PARAMETER;
480 }
481
482 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);
483 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
484 return Status;
485 }
486
487 if (VariableName[0] != 0) {
488 //
489 // If variable name is not NULL, get next variable
490 //
491 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
492 }
493
494 while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {
495 if (IsValidVariableHeader (Variable.CurrPtr)) {
496 if (Variable.CurrPtr->State == VAR_ADDED) {
497 VarNameSize = (UINTN) Variable.CurrPtr->NameSize;
498 if (VarNameSize <= *VariableNameSize) {
499 (*PeiServices)->CopyMem (VariableName, GET_VARIABLE_NAME_PTR (Variable.CurrPtr), VarNameSize);
500
501 (*PeiServices)->CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));
502
503 Status = EFI_SUCCESS;
504 } else {
505 Status = EFI_BUFFER_TOO_SMALL;
506 }
507
508 *VariableNameSize = VarNameSize;
509 return Status;
510 //
511 // Variable is found
512 //
513 } else {
514 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
515 }
516 } else {
517 break;
518 }
519 }
520
521 return EFI_NOT_FOUND;
522 }