EmbeddedPkg: drop unused Pcds from package .dsc
[mirror_edk2.git] / EmbeddedPkg / Library / HalRuntimeServicesExampleLib / Variable.c
CommitLineData
2ef2b01e
A
1/** @file\r
2 Variable services implemented from system memory\r
3\r
3402aac7 4 There is just a single runtime memory buffer that contans all the data.\r
2ef2b01e 5\r
60274cca
HT
6 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
7 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
3402aac7 8\r
60274cca 9 This program and the accompanying materials\r
2ef2b01e
A
10 are licensed and made available under the terms and conditions of the BSD License\r
11 which accompanies this distribution. The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php\r
13\r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17\r
18**/\r
19\r
20\r
21UINT64 mMaximumVariableStorageSize;\r
22UINT64 mRemainingVariableStorageSize;\r
23UINT64 mMaximumVariableSize;\r
24\r
25typedef struct {\r
26 EFI_GUID VendorGuid;\r
27 UINT32 Attribute;\r
28 UINTN DataSize;\r
29} VARIABLE_ARRAY_ENTRY;\r
30// CHAR16 VariableName[]\r
31// UINT8 Data[]\r
32\r
33VARIABLE_ARRAY_ENTRY *mVariableArray = NULL;\r
34VARIABLE_ARRAY_ENTRY *mVariableArrayNextFree = NULL;\r
35VARIABLE_ARRAY_ENTRY *mVariableArrayEnd = NULL;\r
36\r
37\r
38VARIABLE_ARRAY_ENTRY *\r
39AddEntry (\r
40 IN CHAR16 *VariableName,\r
41 IN EFI_GUID *VendorGuid,\r
42 IN UINT32 Attributes,\r
43 IN UINTN DataSize,\r
44 IN VOID *Data\r
45 )\r
46{\r
47 UINTN Size;\r
48 UINTN SizeOfString;\r
49 VARIABLE_ARRAY_ENTRY *Entry;\r
50 EFI_TPL CurrentTpl;\r
51\r
52\r
3402aac7 53 SizeOfString = StrSize (VariableName);\r
2ef2b01e
A
54 Size = SizeOfString + sizeof (VARIABLE_ARRAY_ENTRY) + DataSize;\r
55 if ((VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + Size) > mVariableArrayEnd) {\r
56 // ran out of space\r
57 return NULL;\r
58 }\r
59\r
60 if (!EfiAtRuntime ()) {\r
61 // Enter critical section\r
62 CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
63 }\r
64\r
65 Entry = mVariableArrayNextFree;\r
66 CopyGuid (&Entry->VendorGuid, VendorGuid);\r
67 Entry->Attribute = Attributes;\r
68 Entry->DataSize = DataSize;\r
69 StrCpy ((CHAR16 *)++mVariableArrayNextFree, VariableName);\r
70 mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + SizeOfString);\r
71 CopyMem (mVariableArrayNextFree, Data, DataSize);\r
72 mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + DataSize);\r
3402aac7 73\r
2ef2b01e
A
74 if (!EfiAtRuntime ()) {\r
75 // Exit Critical section\r
76 gBS->RestoreTPL (CurrentTpl);\r
77 }\r
78\r
79 return Entry;\r
80}\r
3402aac7 81\r
2ef2b01e
A
82VOID\r
83DeleteEntry (\r
84 IN VARIABLE_ARRAY_ENTRY *Entry\r
85 )\r
86{\r
87 UINTN Size;\r
88 UINT8 *Data;\r
89 EFI_TPL CurrentTpl;\r
90\r
91 Size = StrSize ((CHAR16 *)(Entry + 1)) + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize;\r
92 Data = ((UINT8 *)Entry) + Size;\r
93\r
94 CopyMem (Entry, Data, (UINTN)mVariableArrayNextFree - (UINTN)Data);\r
95\r
96 if (!EfiAtRuntime ()) {\r
97 // Enter critical section\r
98 CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);\r
99 }\r
100\r
101 mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) - Size);\r
102\r
103 if (!EfiAtRuntime ()) {\r
104 // Exit Critical section\r
105 gBS->RestoreTPL (CurrentTpl);\r
106 }\r
107}\r
108\r
109\r
110VARIABLE_ARRAY_ENTRY *\r
111GetVariableArrayEntry (\r
112 IN CHAR16 *VariableName,\r
113 IN EFI_GUID *VendorGuid,\r
114 OUT VOID **Data OPTIONAL\r
115 )\r
116{\r
117 VARIABLE_ARRAY_ENTRY *Entry;\r
118 UINTN Size;\r
119\r
120 if (*VariableName == L'\0') {\r
121 // by definition first entry is null-terminated string\r
122 if (mVariableArray == mVariableArrayNextFree) {\r
123 return NULL;\r
124 }\r
125 return mVariableArray;\r
126 }\r
127\r
128 for (Entry = mVariableArray; Entry < mVariableArrayEnd;) {\r
129 if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {\r
130 if (StrCmp (VariableName, (CHAR16 *)(Entry + 1))) {\r
131 Size = StrSize ((CHAR16 *)(Entry + 1));\r
132 if (Data != NULL) {\r
133 *Data = (VOID *)(((UINT8 *)Entry) + (Size + sizeof (VARIABLE_ARRAY_ENTRY)));\r
134 }\r
135 return Entry;\r
136 }\r
137 }\r
138\r
139 Size = StrSize ((CHAR16 *)(Entry + 1)) + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize;\r
140 Entry = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)Entry) + Size);\r
141 }\r
142\r
143 return NULL;\r
144}\r
145\r
146\r
147EFI_STATUS\r
148LibGetVariable (\r
149 IN CHAR16 *VariableName,\r
150 IN EFI_GUID *VendorGuid,\r
151 OUT UINT32 *Attributes OPTIONAL,\r
152 IN OUT UINTN *DataSize,\r
153 OUT VOID *Data\r
154 )\r
155{\r
156 VARIABLE_ARRAY_ENTRY *Entry;\r
157 VOID *InternalData;\r
158\r
159 if (EfiAtRuntime () && (Attributes != NULL)) {\r
160 if ((*Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) {\r
161 return EFI_NOT_FOUND;\r
162 }\r
163 }\r
164\r
165 Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);\r
166 if (Entry == NULL) {\r
167 return EFI_NOT_FOUND;\r
168 }\r
169\r
170 if (*DataSize < Entry->DataSize) {\r
171 *DataSize = Entry->DataSize;\r
172 return EFI_BUFFER_TOO_SMALL;\r
173 }\r
174\r
175 *DataSize = Entry->DataSize;\r
176 if (Attributes != NULL) {\r
177 *Attributes = Entry->Attribute;\r
178 }\r
179\r
180 CopyMem (Data, InternalData, *DataSize);\r
181 return EFI_SUCCESS;\r
182}\r
183\r
184\r
185EFI_STATUS\r
186LibGetNextVariableName (\r
187 IN OUT UINTN *VariableNameSize,\r
188 IN OUT CHAR16 *VariableName,\r
189 IN OUT EFI_GUID *VendorGuid\r
190 )\r
191{\r
192 VARIABLE_ARRAY_ENTRY *Entry;\r
193 VOID *InternalData;\r
194 UINTN StringSize;\r
195 BOOLEAN Done;\r
196\r
197 for (Done = FALSE; !Done; ) {\r
198 Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);\r
199 if (Entry == NULL) {\r
200 return EFI_NOT_FOUND;\r
201 }\r
3402aac7 202\r
2ef2b01e
A
203 // If we are at runtime skip variables that do not have the Runitme attribute set.\r
204 Done = (EfiAtRuntime () && ((Entry->Attribute & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) ? FALSE : TRUE;\r
3402aac7 205 }\r
2ef2b01e
A
206\r
207 StringSize = StrSize ((CHAR16 *)(Entry + 1));\r
208 Entry = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)Entry) + (StringSize + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize));\r
209 if (Entry >= mVariableArrayEnd) {\r
210 return EFI_NOT_FOUND;\r
211 }\r
3402aac7 212\r
2ef2b01e
A
213 if (*VariableNameSize < StringSize) {\r
214 *VariableNameSize = StringSize;\r
215 return EFI_BUFFER_TOO_SMALL;\r
216 }\r
3402aac7 217\r
2ef2b01e
A
218 *VariableNameSize = StringSize;\r
219 CopyMem (VariableName, (CHAR16 *)(Entry + 1), StringSize);\r
220 CopyMem (VendorGuid, &Entry->VendorGuid, sizeof (EFI_GUID));\r
221 return EFI_SUCCESS;\r
222}\r
223\r
224\r
225\r
226EFI_STATUS\r
227LibSetVariable (\r
228 IN CHAR16 *VariableName,\r
229 IN EFI_GUID *VendorGuid,\r
230 IN UINT32 Attributes,\r
231 IN UINTN DataSize,\r
232 IN VOID *Data\r
233 )\r
234{\r
235 VARIABLE_ARRAY_ENTRY *Entry;\r
236 VOID *InternalData;\r
237\r
238 if (EfiAtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {\r
239 return EFI_NOT_FOUND;\r
240 }\r
241\r
242 Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);\r
243 if (Entry == NULL) {\r
244 if (DataSize == 0) {\r
245 return EFI_NOT_FOUND;\r
246 }\r
247 Entry = AddEntry (VariableName, VendorGuid, Attributes, DataSize, Data);\r
248 return (Entry == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;\r
249\r
250 } else if (DataSize == 0) {\r
251 // DataSize is zero so delete\r
252 DeleteEntry (Entry);\r
253 } else if (DataSize == Entry->DataSize) {\r
254 // No change is size so just update the store\r
255 Entry->Attribute |= Attributes;\r
256 CopyMem (InternalData, Data, DataSize);\r
257 } else {\r
258 // Grow the entry by deleting and adding back. Don't lose previous Attributes\r
259 Attributes |= Entry->Attribute;\r
260 DeleteEntry (Entry);\r
261 Entry = AddEntry (VariableName, VendorGuid, Attributes, DataSize, Data);\r
262 return (Entry == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;\r
263 }\r
264}\r
265\r
266\r
267EFI_STATUS\r
268LibQueryVariableInfo (\r
269 IN UINT32 Attributes,\r
270 OUT UINT64 *MaximumVariableStorageSize,\r
271 OUT UINT64 *RemainingVariableStorageSize,\r
272 OUT UINT64 *MaximumVariableSize\r
273 )\r
274{\r
275 *MaximumVariableStorageSize = mMaximumVariableStorageSize;\r
276 *RemainingVariableStorageSize = mRemainingVariableStorageSize;\r
277 *MaximumVariableStorageSize = mRemainingVariableStorageSize;\r
278 return EFI_SUCCESS;\r
279}\r
280\r
281\r
282VOID\r
283LibVariableVirtualAddressChangeEvent (VOID)\r
284{\r
285 EfiConvertPointer (0, (VOID **)&mVariableArray);\r
286 EfiConvertPointer (0, (VOID **)&mVariableArrayNextFree);\r
287 EfiConvertPointer (0, (VOID **)&mVariableArrayEnd);\r
288}\r
289\r
290\r
291VOID\r
292LibVariableInitialize (VOID)\r
293{\r
294 UINTN Size;\r
295\r
296 Size = PcdGet32 (PcdEmbeddedMemVariableStoreSize);\r
297 mVariableArray = mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)AllocateRuntimePool (Size);\r
298 ASSERT (mVariableArray != NULL);\r
299\r
300 mVariableArrayEnd = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArray) + Size);\r
3402aac7 301\r
2ef2b01e
A
302 mMaximumVariableStorageSize = Size - sizeof (VARIABLE_ARRAY_ENTRY);\r
303 mRemainingVariableStorageSize = mMaximumVariableStorageSize;\r
304 mMaximumVariableSize = mMaximumVariableStorageSize;\r
305}\r
3402aac7 306\r