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