2 Variable services implemented from system memory
4 There is just a single runtime memory buffer that contans all the data.
6 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
7 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 UINT64 mMaximumVariableStorageSize
;
22 UINT64 mRemainingVariableStorageSize
;
23 UINT64 mMaximumVariableSize
;
29 } VARIABLE_ARRAY_ENTRY
;
30 // CHAR16 VariableName[]
33 VARIABLE_ARRAY_ENTRY
*mVariableArray
= NULL
;
34 VARIABLE_ARRAY_ENTRY
*mVariableArrayNextFree
= NULL
;
35 VARIABLE_ARRAY_ENTRY
*mVariableArrayEnd
= NULL
;
38 VARIABLE_ARRAY_ENTRY
*
40 IN CHAR16
*VariableName
,
41 IN EFI_GUID
*VendorGuid
,
49 VARIABLE_ARRAY_ENTRY
*Entry
;
53 SizeOfString
= StrSize (VariableName
);
54 Size
= SizeOfString
+ sizeof (VARIABLE_ARRAY_ENTRY
) + DataSize
;
55 if ((VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)mVariableArrayNextFree
) + Size
) > mVariableArrayEnd
) {
60 if (!EfiAtRuntime ()) {
61 // Enter critical section
62 CurrentTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
65 Entry
= mVariableArrayNextFree
;
66 CopyGuid (&Entry
->VendorGuid
, VendorGuid
);
67 Entry
->Attribute
= Attributes
;
68 Entry
->DataSize
= DataSize
;
69 StrCpy ((CHAR16
*)++mVariableArrayNextFree
, VariableName
);
70 mVariableArrayNextFree
= (VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)mVariableArrayNextFree
) + SizeOfString
);
71 CopyMem (mVariableArrayNextFree
, Data
, DataSize
);
72 mVariableArrayNextFree
= (VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)mVariableArrayNextFree
) + DataSize
);
74 if (!EfiAtRuntime ()) {
75 // Exit Critical section
76 gBS
->RestoreTPL (CurrentTpl
);
84 IN VARIABLE_ARRAY_ENTRY
*Entry
91 Size
= StrSize ((CHAR16
*)(Entry
+ 1)) + sizeof (VARIABLE_ARRAY_ENTRY
) + Entry
->DataSize
;
92 Data
= ((UINT8
*)Entry
) + Size
;
94 CopyMem (Entry
, Data
, (UINTN
)mVariableArrayNextFree
- (UINTN
)Data
);
96 if (!EfiAtRuntime ()) {
97 // Enter critical section
98 CurrentTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
101 mVariableArrayNextFree
= (VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)mVariableArrayNextFree
) - Size
);
103 if (!EfiAtRuntime ()) {
104 // Exit Critical section
105 gBS
->RestoreTPL (CurrentTpl
);
110 VARIABLE_ARRAY_ENTRY
*
111 GetVariableArrayEntry (
112 IN CHAR16
*VariableName
,
113 IN EFI_GUID
*VendorGuid
,
114 OUT VOID
**Data OPTIONAL
117 VARIABLE_ARRAY_ENTRY
*Entry
;
120 if (*VariableName
== L
'\0') {
121 // by definition first entry is null-terminated string
122 if (mVariableArray
== mVariableArrayNextFree
) {
125 return mVariableArray
;
128 for (Entry
= mVariableArray
; Entry
< mVariableArrayEnd
;) {
129 if (CompareGuid (VendorGuid
, &Entry
->VendorGuid
)) {
130 if (StrCmp (VariableName
, (CHAR16
*)(Entry
+ 1))) {
131 Size
= StrSize ((CHAR16
*)(Entry
+ 1));
133 *Data
= (VOID
*)(((UINT8
*)Entry
) + (Size
+ sizeof (VARIABLE_ARRAY_ENTRY
)));
139 Size
= StrSize ((CHAR16
*)(Entry
+ 1)) + sizeof (VARIABLE_ARRAY_ENTRY
) + Entry
->DataSize
;
140 Entry
= (VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)Entry
) + Size
);
149 IN CHAR16
*VariableName
,
150 IN EFI_GUID
*VendorGuid
,
151 OUT UINT32
*Attributes OPTIONAL
,
152 IN OUT UINTN
*DataSize
,
156 VARIABLE_ARRAY_ENTRY
*Entry
;
159 if (EfiAtRuntime () && (Attributes
!= NULL
)) {
160 if ((*Attributes
& EFI_VARIABLE_RUNTIME_ACCESS
) == 0) {
161 return EFI_NOT_FOUND
;
165 Entry
= GetVariableArrayEntry (VariableName
, VendorGuid
, &InternalData
);
167 return EFI_NOT_FOUND
;
170 if (*DataSize
< Entry
->DataSize
) {
171 *DataSize
= Entry
->DataSize
;
172 return EFI_BUFFER_TOO_SMALL
;
175 *DataSize
= Entry
->DataSize
;
176 if (Attributes
!= NULL
) {
177 *Attributes
= Entry
->Attribute
;
180 CopyMem (Data
, InternalData
, *DataSize
);
186 LibGetNextVariableName (
187 IN OUT UINTN
*VariableNameSize
,
188 IN OUT CHAR16
*VariableName
,
189 IN OUT EFI_GUID
*VendorGuid
192 VARIABLE_ARRAY_ENTRY
*Entry
;
197 for (Done
= FALSE
; !Done
; ) {
198 Entry
= GetVariableArrayEntry (VariableName
, VendorGuid
, &InternalData
);
200 return EFI_NOT_FOUND
;
203 // If we are at runtime skip variables that do not have the Runitme attribute set.
204 Done
= (EfiAtRuntime () && ((Entry
->Attribute
& EFI_VARIABLE_RUNTIME_ACCESS
) == 0)) ? FALSE
: TRUE
;
207 StringSize
= StrSize ((CHAR16
*)(Entry
+ 1));
208 Entry
= (VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)Entry
) + (StringSize
+ sizeof (VARIABLE_ARRAY_ENTRY
) + Entry
->DataSize
));
209 if (Entry
>= mVariableArrayEnd
) {
210 return EFI_NOT_FOUND
;
213 if (*VariableNameSize
< StringSize
) {
214 *VariableNameSize
= StringSize
;
215 return EFI_BUFFER_TOO_SMALL
;
218 *VariableNameSize
= StringSize
;
219 CopyMem (VariableName
, (CHAR16
*)(Entry
+ 1), StringSize
);
220 CopyMem (VendorGuid
, &Entry
->VendorGuid
, sizeof (EFI_GUID
));
228 IN CHAR16
*VariableName
,
229 IN EFI_GUID
*VendorGuid
,
230 IN UINT32 Attributes
,
235 VARIABLE_ARRAY_ENTRY
*Entry
;
238 if (EfiAtRuntime () && ((Attributes
& EFI_VARIABLE_RUNTIME_ACCESS
) == 0)) {
239 return EFI_NOT_FOUND
;
242 Entry
= GetVariableArrayEntry (VariableName
, VendorGuid
, &InternalData
);
245 return EFI_NOT_FOUND
;
247 Entry
= AddEntry (VariableName
, VendorGuid
, Attributes
, DataSize
, Data
);
248 return (Entry
== NULL
) ? EFI_OUT_OF_RESOURCES
: EFI_SUCCESS
;
250 } else if (DataSize
== 0) {
251 // DataSize is zero so delete
253 } else if (DataSize
== Entry
->DataSize
) {
254 // No change is size so just update the store
255 Entry
->Attribute
|= Attributes
;
256 CopyMem (InternalData
, Data
, DataSize
);
258 // Grow the entry by deleting and adding back. Don't lose previous Attributes
259 Attributes
|= Entry
->Attribute
;
261 Entry
= AddEntry (VariableName
, VendorGuid
, Attributes
, DataSize
, Data
);
262 return (Entry
== NULL
) ? EFI_OUT_OF_RESOURCES
: EFI_SUCCESS
;
268 LibQueryVariableInfo (
269 IN UINT32 Attributes
,
270 OUT UINT64
*MaximumVariableStorageSize
,
271 OUT UINT64
*RemainingVariableStorageSize
,
272 OUT UINT64
*MaximumVariableSize
275 *MaximumVariableStorageSize
= mMaximumVariableStorageSize
;
276 *RemainingVariableStorageSize
= mRemainingVariableStorageSize
;
277 *MaximumVariableStorageSize
= mRemainingVariableStorageSize
;
283 LibVariableVirtualAddressChangeEvent (VOID
)
285 EfiConvertPointer (0, (VOID
**)&mVariableArray
);
286 EfiConvertPointer (0, (VOID
**)&mVariableArrayNextFree
);
287 EfiConvertPointer (0, (VOID
**)&mVariableArrayEnd
);
292 LibVariableInitialize (VOID
)
296 Size
= PcdGet32 (PcdEmbeddedMemVariableStoreSize
);
297 mVariableArray
= mVariableArrayNextFree
= (VARIABLE_ARRAY_ENTRY
*)AllocateRuntimePool (Size
);
298 ASSERT (mVariableArray
!= NULL
);
300 mVariableArrayEnd
= (VARIABLE_ARRAY_ENTRY
*)(((UINT8
*)mVariableArray
) + Size
);
302 mMaximumVariableStorageSize
= Size
- sizeof (VARIABLE_ARRAY_ENTRY
);
303 mRemainingVariableStorageSize
= mMaximumVariableStorageSize
;
304 mMaximumVariableSize
= mMaximumVariableStorageSize
;