]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/EmuVariable/RuntimeDxe/EmuVariable.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Universal / EmuVariable / RuntimeDxe / EmuVariable.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
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
12 Module Name:
13
14 EmuVariable.c
15
16 Abstract:
17
18 Revision History
19
20 --*/
21
22 #include "Variable.h"
23
24 //
25 // Don't use module globals after the SetVirtualAddress map is signaled
26 //
27 ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
28
29 STATIC
30 UINT32
31 EFIAPI
32 ArrayLength (
33 IN CHAR16 *String
34 )
35 /*++
36
37 Routine Description:
38
39 Determine the length of null terminated char16 array.
40
41 Arguments:
42
43 String Null-terminated CHAR16 array pointer.
44
45 Returns:
46
47 UINT32 Number of bytes in the string, including the double NULL at the end;
48
49 --*/
50 {
51 UINT32 Count;
52
53 if (NULL == String) {
54 return 0;
55 }
56
57 Count = 0;
58
59 while (0 != String[Count]) {
60 Count++;
61 }
62
63 return (Count * 2) + 2;
64 }
65
66 STATIC
67 VARIABLE_STORE_STATUS
68 EFIAPI
69 GetVariableStoreStatus (
70 IN VARIABLE_STORE_HEADER *VarStoreHeader
71 )
72 /*++
73
74 Routine Description:
75
76 This code gets the pointer to the variable name.
77
78 Arguments:
79
80 VarStoreHeader Pointer to the Variable Store Header.
81
82 Returns:
83
84 EfiHealthy Variable store is healthy
85 EfiRaw Variable store is raw
86 EfiInvalid Variable store is invalid
87
88 --*/
89 {
90 if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&
91 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
92 VarStoreHeader->State == VARIABLE_STORE_HEALTHY
93 ) {
94
95 return EfiValid;
96 } else if (VarStoreHeader->Signature == 0xffffffff &&
97 VarStoreHeader->Size == 0xffffffff &&
98 VarStoreHeader->Format == 0xff &&
99 VarStoreHeader->State == 0xff
100 ) {
101
102 return EfiRaw;
103 } else {
104 return EfiInvalid;
105 }
106 }
107
108 STATIC
109 UINT8 *
110 EFIAPI
111 GetVariableDataPtr (
112 IN VARIABLE_HEADER *Variable
113 )
114 /*++
115
116 Routine Description:
117
118 This code gets the pointer to the variable data.
119
120 Arguments:
121
122 Variable Pointer to the Variable Header.
123
124 Returns:
125
126 UINT8* Pointer to Variable Data
127
128 --*/
129 {
130 if (Variable->StartId != VARIABLE_DATA) {
131 return NULL;
132 }
133 //
134 // Be careful about pad size for alignment
135 //
136 return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));
137 }
138
139 STATIC
140 VARIABLE_HEADER *
141 EFIAPI
142 GetNextVariablePtr (
143 IN VARIABLE_HEADER *Variable
144 )
145 /*++
146
147 Routine Description:
148
149 This code gets the pointer to the next variable header.
150
151 Arguments:
152
153 Variable Pointer to the Variable Header.
154
155 Returns:
156
157 VARIABLE_HEADER* Pointer to next variable header.
158
159 --*/
160 {
161 VARIABLE_HEADER *VarHeader;
162
163 if (Variable->StartId != VARIABLE_DATA) {
164 return NULL;
165 }
166 //
167 // Be careful about pad size for alignment
168 //
169 VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
170
171 if (VarHeader->StartId != VARIABLE_DATA ||
172 (sizeof (VARIABLE_HEADER) + VarHeader->DataSize + VarHeader->NameSize) > MAX_VARIABLE_SIZE
173 ) {
174 return NULL;
175 }
176
177 return VarHeader;
178 }
179
180 STATIC
181 VARIABLE_HEADER *
182 EFIAPI
183 GetEndPointer (
184 IN VARIABLE_STORE_HEADER *VolHeader
185 )
186 /*++
187
188 Routine Description:
189
190 This code gets the pointer to the last variable memory pointer byte
191
192 Arguments:
193
194 Variable Pointer to the Variable Header.
195
196 Returns:
197
198 VARIABLE_HEADER* Pointer to last unavailable Variable Header
199
200 --*/
201 {
202 //
203 // The end of variable store
204 //
205 return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size);
206 }
207
208 STATIC
209 EFI_STATUS
210 EFIAPI
211 FindVariable (
212 IN CHAR16 *VariableName,
213 IN EFI_GUID *VendorGuid,
214 OUT VARIABLE_POINTER_TRACK *PtrTrack,
215 IN VARIABLE_GLOBAL *Global
216 )
217 /*++
218
219 Routine Description:
220
221 This code finds variable in storage blocks (Volatile or Non-Volatile)
222
223 Arguments:
224
225 VariableName Name of the variable to be found
226 VendorGuid Vendor GUID to be found.
227 PtrTrack Variable Track Pointer structure that contains
228 Variable Information.
229 Contains the pointer of Variable header.
230 Global VARIABLE_GLOBAL pointer
231
232 Returns:
233
234 EFI STATUS
235
236 --*/
237 {
238 VARIABLE_HEADER *Variable[2];
239 VARIABLE_STORE_HEADER *VariableStoreHeader[2];
240 UINTN Index;
241
242 //
243 // 0: Non-Volatile, 1: Volatile
244 //
245 VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);
246 VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);
247
248 //
249 // Start Pointers for the variable.
250 // Actual Data Pointer where data can be written.
251 //
252 Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);
253 Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);
254
255 if (VariableName[0] != 0 && VendorGuid == NULL) {
256 return EFI_INVALID_PARAMETER;
257 }
258 //
259 // Find the variable by walk through non-volatile and volatile variable store
260 //
261 for (Index = 0; Index < 2; Index++) {
262 PtrTrack->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);
263 PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
264
265 while ((Variable[Index] != NULL) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {
266 if (Variable[Index]->StartId == VARIABLE_DATA && Variable[Index]->State == VAR_ADDED) {
267 if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
268 if (VariableName[0] == 0) {
269 PtrTrack->CurrPtr = Variable[Index];
270 PtrTrack->Volatile = (BOOLEAN) Index;
271 return EFI_SUCCESS;
272 } else {
273 if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
274 if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), ArrayLength (VariableName))) {
275 PtrTrack->CurrPtr = Variable[Index];
276 PtrTrack->Volatile = (BOOLEAN) Index;
277 return EFI_SUCCESS;
278 }
279 }
280 }
281 }
282 }
283
284 Variable[Index] = GetNextVariablePtr (Variable[Index]);
285 }
286 }
287 PtrTrack->CurrPtr = NULL;
288 return EFI_NOT_FOUND;
289 }
290
291 EFI_STATUS
292 EFIAPI
293 GetVariable (
294 IN CHAR16 *VariableName,
295 IN EFI_GUID * VendorGuid,
296 OUT UINT32 *Attributes OPTIONAL,
297 IN OUT UINTN *DataSize,
298 OUT VOID *Data,
299 IN VARIABLE_GLOBAL * Global,
300 IN UINT32 Instance
301 )
302 /*++
303
304 Routine Description:
305
306 This code finds variable in storage blocks (Volatile or Non-Volatile)
307
308 Arguments:
309
310 VariableName Name of Variable to be found
311 VendorGuid Variable vendor GUID
312 Attributes OPTIONAL Attribute value of the variable found
313 DataSize Size of Data found. If size is less than the
314 data, this value contains the required size.
315 Data Data pointer
316 Global Pointer to VARIABLE_GLOBAL structure
317 Instance Instance of the Firmware Volume.
318
319 Returns:
320
321 EFI STATUS
322
323 --*/
324 {
325 VARIABLE_POINTER_TRACK Variable;
326 UINTN VarDataSize;
327 EFI_STATUS Status;
328
329 if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {
330 return EFI_INVALID_PARAMETER;
331 }
332 //
333 // Find existing variable
334 //
335 Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
336
337 if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
338 return Status;
339 }
340 //
341 // Get data size
342 //
343 VarDataSize = Variable.CurrPtr->DataSize;
344 if (*DataSize >= VarDataSize) {
345 if (Data == NULL) {
346 return EFI_INVALID_PARAMETER;
347 }
348
349 CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);
350 if (Attributes != NULL) {
351 *Attributes = Variable.CurrPtr->Attributes;
352 }
353
354 *DataSize = VarDataSize;
355 return EFI_SUCCESS;
356 } else {
357 *DataSize = VarDataSize;
358 return EFI_BUFFER_TOO_SMALL;
359 }
360 }
361
362 EFI_STATUS
363 EFIAPI
364 GetNextVariableName (
365 IN OUT UINTN *VariableNameSize,
366 IN OUT CHAR16 *VariableName,
367 IN OUT EFI_GUID *VendorGuid,
368 IN VARIABLE_GLOBAL *Global,
369 IN UINT32 Instance
370 )
371 /*++
372
373 Routine Description:
374
375 This code Finds the Next available variable
376
377 Arguments:
378
379 VariableNameSize Size of the variable
380 VariableName Pointer to variable name
381 VendorGuid Variable Vendor Guid
382 Global VARIABLE_GLOBAL structure pointer.
383 Instance FV instance
384
385 Returns:
386
387 EFI STATUS
388
389 --*/
390 {
391 VARIABLE_POINTER_TRACK Variable;
392 UINTN VarNameSize;
393 EFI_STATUS Status;
394
395 if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
396 return EFI_INVALID_PARAMETER;
397 }
398
399 Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
400
401 if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
402 return Status;
403 }
404
405 while (TRUE) {
406 if (VariableName[0] != 0) {
407 //
408 // If variable name is not NULL, get next variable
409 //
410 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
411 }
412 //
413 // If both volatile and non-volatile variable store are parsed,
414 // return not found
415 //
416 if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {
417 Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));
418 if (Variable.Volatile) {
419 Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));
420 Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));
421 } else {
422 goto Error;
423 }
424
425 Variable.CurrPtr = Variable.StartPtr;
426 if (Variable.CurrPtr->StartId != VARIABLE_DATA) {
427 continue;
428 }
429 }
430 //
431 // Variable is found
432 //
433 if (Variable.CurrPtr->StartId == VARIABLE_DATA && Variable.CurrPtr->State == VAR_ADDED) {
434 if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {
435 VarNameSize = Variable.CurrPtr->NameSize;
436 if (VarNameSize <= *VariableNameSize) {
437 CopyMem (
438 VariableName,
439 GET_VARIABLE_NAME_PTR (Variable.CurrPtr),
440 VarNameSize
441 );
442 CopyMem (
443 VendorGuid,
444 &Variable.CurrPtr->VendorGuid,
445 sizeof (EFI_GUID)
446 );
447 Status = EFI_SUCCESS;
448 } else {
449 Status = EFI_BUFFER_TOO_SMALL;
450 }
451
452 *VariableNameSize = VarNameSize;
453 return Status;
454 }
455 }
456 }
457
458 Error:
459 return EFI_NOT_FOUND;
460 }
461
462 EFI_STATUS
463 EFIAPI
464 SetVariable (
465 IN CHAR16 *VariableName,
466 IN EFI_GUID *VendorGuid,
467 IN UINT32 Attributes,
468 IN UINTN DataSize,
469 IN VOID *Data,
470 IN VARIABLE_GLOBAL *Global,
471 IN UINTN *VolatileOffset,
472 IN UINTN *NonVolatileOffset,
473 IN UINT32 Instance
474 )
475 /*++
476
477 Routine Description:
478
479 This code sets variable in storage blocks (Volatile or Non-Volatile)
480
481 Arguments:
482
483 VariableName Name of Variable to be found
484 VendorGuid Variable vendor GUID
485 Attributes Attribute value of the variable found
486 DataSize Size of Data found. If size is less than the
487 data, this value contains the required size.
488 Data Data pointer
489 Global Pointer to VARIABLE_GLOBAL structure
490 VolatileOffset The offset of last volatile variable
491 NonVolatileOffset The offset of last non-volatile variable
492 Instance Instance of the Firmware Volume.
493
494 Returns:
495
496 EFI STATUS
497
498 --*/
499 {
500 VARIABLE_POINTER_TRACK Variable;
501 EFI_STATUS Status;
502 VARIABLE_HEADER *NextVariable;
503 UINTN VarNameSize;
504 UINTN VarNameOffset;
505 UINTN VarDataOffset;
506 UINTN VarSize;
507
508 if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
509 return EFI_INVALID_PARAMETER;
510 }
511
512 Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
513
514 if (Status == EFI_INVALID_PARAMETER) {
515 return Status;
516 } else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) {
517 //
518 // If EfiAtRuntime and the variable is Volatile and Runtime Access,
519 // the volatile is ReadOnly, and SetVariable should be aborted and
520 // return EFI_WRITE_PROTECTED.
521 //
522 return EFI_WRITE_PROTECTED;
523 } else if (sizeof (VARIABLE_HEADER) + (ArrayLength (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {
524 //
525 // The size of the VariableName, including the Unicode Null in bytes plus
526 // the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.
527 //
528 return EFI_INVALID_PARAMETER;
529 } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS
530 ) {
531 //
532 // Make sure if runtime bit is set, boot service bit is set also
533 //
534 return EFI_INVALID_PARAMETER;
535 } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
536 //
537 // Runtime but Attribute is not Runtime
538 //
539 return EFI_INVALID_PARAMETER;
540 } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
541 //
542 // Cannot set volatile variable in Runtime
543 //
544 return EFI_INVALID_PARAMETER;
545 } else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
546 //
547 // Setting a data variable with no access, or zero DataSize attributes
548 // specified causes it to be deleted.
549 //
550 if (!EFI_ERROR (Status)) {
551 Variable.CurrPtr->State &= VAR_DELETED;
552 return EFI_SUCCESS;
553 }
554
555 return EFI_NOT_FOUND;
556 } else {
557 if (!EFI_ERROR (Status)) {
558 //
559 // If the variable is marked valid and the same data has been passed in
560 // then return to the caller immediately.
561 //
562 if (Variable.CurrPtr->DataSize == DataSize &&
563 !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)
564 ) {
565 return EFI_SUCCESS;
566 } else if (Variable.CurrPtr->State == VAR_ADDED) {
567 //
568 // Mark the old variable as in delete transition
569 //
570 Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;
571 }
572 }
573 //
574 // Create a new variable and copy the data.
575 //
576 VarNameOffset = sizeof (VARIABLE_HEADER);
577 VarNameSize = ArrayLength (VariableName);
578 VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
579 VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
580
581 if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
582 if ((UINT32) (VarSize +*NonVolatileOffset) >
583 ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
584 ) {
585 return EFI_OUT_OF_RESOURCES;
586 }
587
588 NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
589 *NonVolatileOffset = *NonVolatileOffset + VarSize;
590 } else {
591 if (EfiAtRuntime ()) {
592 return EFI_INVALID_PARAMETER;
593 }
594
595 if ((UINT32) (VarSize +*VolatileOffset) >
596 ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
597 ) {
598 return EFI_OUT_OF_RESOURCES;
599 }
600
601 NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);
602 *VolatileOffset = *VolatileOffset + VarSize;
603 }
604
605 NextVariable->StartId = VARIABLE_DATA;
606 NextVariable->Attributes = Attributes;
607 NextVariable->State = VAR_ADDED;
608 NextVariable->Reserved = 0;
609
610 //
611 // There will be pad bytes after Data, the NextVariable->NameSize and
612 // NextVariable->NameSize should not include pad size so that variable
613 // service can get actual size in GetVariable
614 //
615 NextVariable->NameSize = (UINT32)VarNameSize;
616 NextVariable->DataSize = (UINT32)DataSize;
617
618 CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
619 CopyMem (
620 (UINT8 *) ((UINTN) NextVariable + VarNameOffset),
621 VariableName,
622 VarNameSize
623 );
624 CopyMem (
625 (UINT8 *) ((UINTN) NextVariable + VarDataOffset),
626 Data,
627 DataSize
628 );
629
630 //
631 // Mark the old variable as deleted
632 //
633 if (!EFI_ERROR (Status)) {
634 Variable.CurrPtr->State &= VAR_DELETED;
635 }
636 }
637
638 return EFI_SUCCESS;
639 }
640
641 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
642 EFI_STATUS
643 EFIAPI
644 QueryVariableInfo (
645 IN UINT32 Attributes,
646 OUT UINT64 *MaximumVariableStorageSize,
647 OUT UINT64 *RemainingVariableStorageSize,
648 OUT UINT64 *MaximumVariableSize,
649 IN VARIABLE_GLOBAL *Global,
650 IN UINT32 Instance
651 )
652 /*++
653
654 Routine Description:
655
656 This code returns information about the EFI variables.
657
658 Arguments:
659
660 Attributes Attributes bitmask to specify the type of variables
661 on which to return information.
662 MaximumVariableStorageSize Pointer to the maximum size of the storage space available
663 for the EFI variables associated with the attributes specified.
664 RemainingVariableStorageSize Pointer to the remaining size of the storage space available
665 for the EFI variables associated with the attributes specified.
666 MaximumVariableSize Pointer to the maximum size of the individual EFI variables
667 associated with the attributes specified.
668 Global Pointer to VARIABLE_GLOBAL structure.
669 Instance Instance of the Firmware Volume.
670
671 Returns:
672
673 EFI STATUS
674 EFI_INVALID_PARAMETER - An invalid combination of attribute bits was supplied.
675 EFI_SUCCESS - Query successfully.
676 EFI_UNSUPPORTED - The attribute is not supported on this platform.
677
678 --*/
679 {
680 VARIABLE_HEADER *Variable;
681 VARIABLE_HEADER *NextVariable;
682 UINT64 VariableSize;
683 VARIABLE_STORE_HEADER *VariableStoreHeader;
684
685 if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) {
686 return EFI_INVALID_PARAMETER;
687 }
688
689 if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)) == 0) {
690 //
691 // Make sure the Attributes combination is supported by the platform.
692 //
693 return EFI_UNSUPPORTED;
694 } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
695 //
696 // Make sure if runtime bit is set, boot service bit is set also.
697 //
698 return EFI_INVALID_PARAMETER;
699 } else if (EfiAtRuntime () && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
700 //
701 // Make sure RT Attribute is set if we are in Runtime phase.
702 //
703 return EFI_INVALID_PARAMETER;
704 } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
705 //
706 // Cannot Query volatile variable in Runtime
707 //
708 return EFI_INVALID_PARAMETER;
709 }
710
711 if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
712 //
713 // Query is Volatile related.
714 //
715 VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);
716 } else {
717 //
718 // Query is Non-Volatile related.
719 //
720 VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);
721 }
722
723 //
724 // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize
725 // with the storage size (excluding the storage header size)
726 //
727 *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
728 *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
729
730 //
731 // Let *MaximumVariableSize be MAX_VARIABLE_SIZE
732 //
733 *MaximumVariableSize = MAX_VARIABLE_SIZE;
734
735 //
736 // Point to the starting address of the variables.
737 //
738 Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
739
740 //
741 // Now walk through the related variable store.
742 //
743 while (Variable < GetEndPointer (VariableStoreHeader)) {
744 if (Variable->StartId != VARIABLE_DATA) {
745 break;
746 }
747
748 NextVariable = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
749 VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable;
750
751 if (Variable->State == VAR_ADDED) {
752 *RemainingVariableStorageSize -= VariableSize;
753 }
754
755 //
756 // Go to the next one.
757 //
758 Variable = NextVariable;
759 }
760
761 return EFI_SUCCESS;
762 }
763 #endif
764
765 STATIC
766 EFI_STATUS
767 EFIAPI
768 InitializeVariableStore (
769 OUT EFI_PHYSICAL_ADDRESS *VariableBase,
770 OUT UINTN *LastVariableOffset
771 )
772 /*++
773
774 Routine Description:
775 This function initializes variable store
776
777 Arguments:
778
779 Returns:
780
781 --*/
782 {
783 VARIABLE_STORE_HEADER *VariableStore;
784
785 //
786 // Allocate memory for volatile variable store
787 //
788 VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (
789 VARIABLE_STORE_SIZE
790 );
791 if (NULL == VariableStore) {
792 return EFI_OUT_OF_RESOURCES;
793 }
794
795 SetMem (VariableStore, VARIABLE_STORE_SIZE, 0xff);
796
797 //
798 // Variable Specific Data
799 //
800 *VariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;
801 *LastVariableOffset = sizeof (VARIABLE_STORE_HEADER);
802
803 VariableStore->Signature = VARIABLE_STORE_SIGNATURE;
804 VariableStore->Size = VARIABLE_STORE_SIZE;
805 VariableStore->Format = VARIABLE_STORE_FORMATTED;
806 VariableStore->State = VARIABLE_STORE_HEALTHY;
807 VariableStore->Reserved = 0;
808 VariableStore->Reserved1 = 0;
809
810 return EFI_SUCCESS;
811 }
812
813 EFI_STATUS
814 EFIAPI
815 VariableCommonInitialize (
816 IN EFI_HANDLE ImageHandle,
817 IN EFI_SYSTEM_TABLE *SystemTable
818 )
819 /*++
820
821 Routine Description:
822 This function does common initialization for variable services
823
824 Arguments:
825
826 Returns:
827
828 --*/
829 {
830 EFI_STATUS Status;
831
832 //
833 // Allocate memory for mVariableModuleGlobal
834 //
835 mVariableModuleGlobal = (ESAL_VARIABLE_GLOBAL *) AllocateRuntimePool (
836 sizeof (ESAL_VARIABLE_GLOBAL)
837 );
838 if (NULL == mVariableModuleGlobal) {
839 return EFI_OUT_OF_RESOURCES;
840 }
841 //
842 // Intialize volatile variable store
843 //
844 Status = InitializeVariableStore (
845 &mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase,
846 &mVariableModuleGlobal->VolatileLastVariableOffset
847 );
848
849 if (EFI_ERROR (Status)) {
850 return Status;
851 }
852 //
853 // Intialize non volatile variable store
854 //
855 Status = InitializeVariableStore (
856 &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,
857 &mVariableModuleGlobal->NonVolatileLastVariableOffset
858 );
859
860 return Status;
861 }