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