]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/VariablePei/Variable.c
Fix building issue for Intel Compiler
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / VariablePei / 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_VARIABLE_PPI mVariablePpi = {
28 PeiGetVariable,
29 PeiGetNextVariableName
30 };
31
32 static EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariable2Ppi = {
33 PeiGetVariable2,
34 PeiGetNextVariableName2
35 };
36
37 static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable[] = {
38 {
39 (EFI_PEI_PPI_DESCRIPTOR_PPI),
40 &gEfiPeiReadOnlyVariable2PpiGuid,
41 &mVariable2Ppi
42 },
43 {
44 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
45 &gEfiPeiReadOnlyVariablePpiGuid,
46 &mVariablePpi
47 }
48 };
49
50 EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;
51
52 EFI_STATUS
53 EFIAPI
54 PeimInitializeVariableServices (
55 IN EFI_FFS_FILE_HEADER *FfsHeader,
56 IN EFI_PEI_SERVICES **PeiServices
57 )
58 /*++
59
60 Routine Description:
61
62 Provide the functionality of the variable services.
63
64 Arguments:
65
66 FfsHeadher - The FFS file header
67 PeiServices - General purpose services available to every PEIM.
68
69 Returns:
70
71 Status - EFI_SUCCESS if the interface could be successfully
72 installed
73
74 --*/
75 {
76 //
77 // Publish the variable capability to other modules
78 //
79 return (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable[0]);
80
81 }
82
83 STATIC
84 VARIABLE_HEADER *
85 GetNextVariablePtr (
86 IN VARIABLE_HEADER *Variable
87 )
88 /*++
89
90 Routine Description:
91
92 This code checks if variable header is valid or not.
93
94 Arguments:
95 Variable Pointer to the Variable Header.
96
97 Returns:
98 TRUE Variable header is valid.
99 FALSE Variable header is not valid.
100
101 --*/
102 {
103 return (VARIABLE_HEADER *) ((UINTN) GET_VARIABLE_DATA_PTR (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
104 }
105
106 STATIC
107 BOOLEAN
108 EFIAPI
109 IsValidVariableHeader (
110 IN VARIABLE_HEADER *Variable
111 )
112 /*++
113
114 Routine Description:
115
116 This code checks if variable header is valid or not.
117
118 Arguments:
119 Variable Pointer to the Variable Header.
120
121 Returns:
122 TRUE Variable header is valid.
123 FALSE Variable header is not valid.
124
125 --*/
126 {
127 if (Variable == NULL ||
128 Variable->StartId != VARIABLE_DATA ||
129 (sizeof (VARIABLE_HEADER) + Variable->DataSize + Variable->NameSize) > MAX_VARIABLE_SIZE
130 ) {
131 return FALSE;
132 }
133
134 return TRUE;
135 }
136
137 STATIC
138 VARIABLE_STORE_STATUS
139 EFIAPI
140 GetVariableStoreStatus (
141 IN VARIABLE_STORE_HEADER *VarStoreHeader
142 )
143 /*++
144
145 Routine Description:
146
147 This code gets the pointer to the variable name.
148
149 Arguments:
150
151 VarStoreHeader Pointer to the Variable Store Header.
152
153 Returns:
154
155 EfiRaw Variable store is raw
156 EfiValid Variable store is valid
157 EfiInvalid Variable store is invalid
158
159 --*/
160 {
161 if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&
162 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
163 VarStoreHeader->State == VARIABLE_STORE_HEALTHY
164 ) {
165
166 return EfiValid;
167 }
168
169 if (VarStoreHeader->Signature == 0xffffffff &&
170 VarStoreHeader->Size == 0xffffffff &&
171 VarStoreHeader->Format == 0xff &&
172 VarStoreHeader->State == 0xff
173 ) {
174
175 return EfiRaw;
176 } else {
177 return EfiInvalid;
178 }
179 }
180
181 STATIC
182 EFI_STATUS
183 CompareWithValidVariable (
184 IN VARIABLE_HEADER *Variable,
185 IN CONST CHAR16 *VariableName,
186 IN CONST EFI_GUID *VendorGuid,
187 OUT VARIABLE_POINTER_TRACK *PtrTrack
188 )
189 /*++
190
191 Routine Description:
192
193 This function compares a variable with variable entries in database
194
195 Arguments:
196
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.
202
203 Returns:
204
205 EFI_SUCCESS - Found match variable
206 EFI_NOT_FOUND - Variable not found
207
208 --*/
209 {
210 if (VariableName[0] == 0) {
211 PtrTrack->CurrPtr = Variable;
212 return EFI_SUCCESS;
213 } else {
214 //
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.
218 //
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])
223 ) {
224 if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), Variable->NameSize)) {
225 PtrTrack->CurrPtr = Variable;
226 return EFI_SUCCESS;
227 }
228 }
229 }
230
231 return EFI_NOT_FOUND;
232 }
233
234 STATIC
235 EFI_STATUS
236 EFIAPI
237 FindVariable (
238 IN EFI_PEI_SERVICES **PeiServices,
239 IN CONST CHAR16 *VariableName,
240 IN CONST EFI_GUID *VendorGuid,
241 OUT VARIABLE_POINTER_TRACK *PtrTrack
242 )
243 /*++
244
245 Routine Description:
246
247 This code finds variable in storage blocks (Non-Volatile)
248
249 Arguments:
250
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.
256
257 Returns:
258
259 EFI_SUCCESS - Variable found successfully
260 EFI_NOT_FOUND - Variable not found
261 EFI_INVALID_PARAMETER - Invalid variable name
262
263 --*/
264 {
265 EFI_HOB_GUID_TYPE *GuidHob;
266 VARIABLE_STORE_HEADER *VariableStoreHeader;
267 VARIABLE_HEADER *Variable;
268 VARIABLE_HEADER *MaxIndex;
269 VARIABLE_INDEX_TABLE *IndexTable;
270 UINT32 Count;
271 UINT8 *VariableBase;
272
273 if (VariableName != 0 && VendorGuid == NULL) {
274 return EFI_INVALID_PARAMETER;
275 }
276 //
277 // No Variable Address equals zero, so 0 as initial value is safe.
278 //
279 MaxIndex = 0;
280
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;
288 } else {
289 IndexTable = GET_GUID_HOB_DATA (GuidHob);
290 for (Count = 0; Count < IndexTable->Length; Count++)
291 {
292 MaxIndex = GetVariableByIndex (IndexTable, Count);
293
294 if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
295 PtrTrack->StartPtr = IndexTable->StartPtr;
296 PtrTrack->EndPtr = IndexTable->EndPtr;
297
298 return EFI_SUCCESS;
299 }
300 }
301
302 if (IndexTable->GoneThrough) {
303 return EFI_NOT_FOUND;
304 }
305 }
306 //
307 // If not found in HOB, then let's start from the MaxIndex we've found.
308 //
309 if (MaxIndex != NULL) {
310 Variable = GetNextVariablePtr (MaxIndex);
311 } else {
312 if (IndexTable->StartPtr || IndexTable->EndPtr) {
313 Variable = IndexTable->StartPtr;
314 } else {
315 VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);
316 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \
317 ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);
318
319 if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
320 return EFI_UNSUPPORTED;
321 }
322
323 if (~VariableStoreHeader->Size == 0) {
324 return EFI_NOT_FOUND;
325 }
326 //
327 // Find the variable by walk through non-volatile variable store
328 //
329 IndexTable->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
330 IndexTable->EndPtr = (VARIABLE_HEADER *) ((UINTN) VariableStoreHeader + VariableStoreHeader->Size);
331
332 //
333 // Start Pointers for the variable.
334 // Actual Data Pointer where data can be written.
335 //
336 Variable = IndexTable->StartPtr;
337 }
338 }
339 //
340 // Find the variable by walk through non-volatile variable store
341 //
342 PtrTrack->StartPtr = IndexTable->StartPtr;
343 PtrTrack->EndPtr = IndexTable->EndPtr;
344
345 while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {
346 if (Variable->State == VAR_ADDED) {
347 //
348 // Record Variable in VariableIndex HOB
349 //
350 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME)
351 {
352 VariableIndexTableUpdate (IndexTable, Variable);
353 }
354
355 if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
356 return EFI_SUCCESS;
357 }
358 }
359
360 Variable = GetNextVariablePtr (Variable);
361 }
362 //
363 // If gone through the VariableStore, that means we never find in Firmware any more.
364 //
365 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {
366 IndexTable->GoneThrough = 1;
367 }
368
369 PtrTrack->CurrPtr = NULL;
370
371 return EFI_NOT_FOUND;
372 }
373
374 EFI_STATUS
375 EFIAPI
376 PeiGetVariable (
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,
382 OUT VOID *Data
383 )
384 /*++
385
386 Routine Description:
387
388 Provide the read variable functionality of the variable services.
389
390 Arguments:
391
392 PeiServices - General purpose services available to every PEIM.
393
394 VariableName - The variable name
395
396 VendorGuid - The vendor's GUID
397
398 Attributes - Pointer to the attribute
399
400 DataSize - Size of data
401
402 Data - Pointer to data
403
404 Returns:
405
406 EFI_SUCCESS - The interface could be successfully installed
407
408 EFI_NOT_FOUND - The variable could not be discovered
409
410 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
411
412 --*/
413 {
414 VARIABLE_POINTER_TRACK Variable;
415 UINTN VarDataSize;
416 EFI_STATUS Status;
417
418 if (VariableName == NULL || VendorGuid == NULL) {
419 return EFI_INVALID_PARAMETER;
420 }
421 //
422 // Find existing variable
423 //
424 Status = FindVariable (PeiServices, VariableName, VendorGuid, &Variable);
425
426 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
427 return Status;
428 }
429 //
430 // Get data size
431 //
432 VarDataSize = Variable.CurrPtr->DataSize;
433 if (*DataSize >= VarDataSize) {
434 (*PeiServices)->CopyMem (Data, GET_VARIABLE_DATA_PTR (Variable.CurrPtr), VarDataSize);
435
436 if (Attributes != NULL) {
437 *Attributes = Variable.CurrPtr->Attributes;
438 }
439
440 *DataSize = VarDataSize;
441 return EFI_SUCCESS;
442 } else {
443 *DataSize = VarDataSize;
444 return EFI_BUFFER_TOO_SMALL;
445 }
446 }
447
448
449 EFI_STATUS
450 EFIAPI
451 PeiGetVariable2 (
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,
457 OUT VOID *Data
458 )
459 /*++
460
461 Routine Description:
462
463 Provide the read variable functionality of the variable services.
464
465 Arguments:
466
467 PeiServices - General purpose services available to every PEIM.
468
469 VariableName - The variable name
470
471 VendorGuid - The vendor's GUID
472
473 Attributes - Pointer to the attribute
474
475 DataSize - Size of data
476
477 Data - Pointer to data
478
479 Returns:
480
481 EFI_SUCCESS - The interface could be successfully installed
482
483 EFI_NOT_FOUND - The variable could not be discovered
484
485 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough
486
487 --*/
488 {
489 return PeiGetVariable (
490 GetPeiServicesTablePointer (),
491 (CHAR16*)VariableName,
492 (EFI_GUID*)VariableGuid,
493 Attributes,
494 DataSize,
495 Data
496 );
497 }
498
499 EFI_STATUS
500 EFIAPI
501 PeiGetNextVariableName (
502 IN EFI_PEI_SERVICES **PeiServices,
503 IN OUT UINTN *VariableNameSize,
504 IN OUT CHAR16 *VariableName,
505 IN OUT EFI_GUID *VendorGuid
506 )
507 /*++
508
509 Routine Description:
510
511 Provide the get next variable functionality of the variable services.
512
513 Arguments:
514
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.
519
520 VariableNameSize - Size of the variable name
521
522 VariableName - The variable name
523
524 VendorGuid - The vendor's GUID
525
526 Returns:
527
528 EFI_SUCCESS - The interface could be successfully installed
529
530 EFI_NOT_FOUND - The variable could not be discovered
531
532 --*/
533 {
534 VARIABLE_POINTER_TRACK Variable;
535 UINTN VarNameSize;
536 EFI_STATUS Status;
537
538 if (VariableName == NULL) {
539 return EFI_INVALID_PARAMETER;
540 }
541
542 Status = FindVariable (PeiServices, VariableName, VendorGuid, &Variable);
543
544 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
545 return Status;
546 }
547
548 if (VariableName[0] != 0) {
549 //
550 // If variable name is not NULL, get next variable
551 //
552 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
553 }
554
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);
561
562 (*PeiServices)->CopyMem (VendorGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));
563
564 Status = EFI_SUCCESS;
565 } else {
566 Status = EFI_BUFFER_TOO_SMALL;
567 }
568
569 *VariableNameSize = VarNameSize;
570 return Status;
571 //
572 // Variable is found
573 //
574 } else {
575 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
576 }
577 } else {
578 break;
579 }
580 }
581
582 return EFI_NOT_FOUND;
583 }
584
585 EFI_STATUS
586 EFIAPI
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
592 )
593 /*++
594
595 Routine Description:
596
597 Provide the get next variable functionality of the variable services.
598
599 Arguments:
600
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.
605
606 VariableNameSize - Size of the variable name
607
608 VariableName - The variable name
609
610 VendorGuid - The vendor's GUID
611
612 Returns:
613
614 EFI_SUCCESS - The interface could be successfully installed
615
616 EFI_NOT_FOUND - The variable could not be discovered
617
618 --*/
619 {
620 return PeiGetNextVariableName (
621 GetPeiServicesTablePointer (),
622 VariableNameSize,
623 VariableName,
624 VariableGuid
625 );
626 }