]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Variable/Pei/Variable.c
remove some comments introduced by tools.
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
CommitLineData
8d3a5c82 1/*++\r
2\r
3Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11Module Name:\r
12\r
13 Variable.c\r
14\r
15Abstract:\r
16\r
17 Framework PEIM to provide the Variable functionality\r
18\r
19--*/\r
20\r
21\r
22#include "Variable.h"\r
23\r
24//\r
25// Module globals\r
26//\r
27static EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = {\r
28 PeiGetVariable,\r
29 PeiGetNextVariableName\r
30};\r
31\r
32static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {\r
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
34 &gEfiPeiReadOnlyVariable2PpiGuid,\r
35 &mVariablePpi\r
36};\r
37\r
38EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;\r
39\r
40EFI_STATUS\r
41EFIAPI\r
42PeimInitializeVariableServices (\r
43 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
44 IN EFI_PEI_SERVICES **PeiServices\r
45 )\r
46/*++\r
47\r
48Routine Description:\r
49\r
50 Provide the functionality of the variable services.\r
51\r
52Arguments:\r
53\r
54 FfsHeadher - The FFS file header\r
55 PeiServices - General purpose services available to every PEIM.\r
56\r
57Returns:\r
58\r
59 Status - EFI_SUCCESS if the interface could be successfully\r
60 installed\r
61\r
62--*/\r
63{\r
64 //\r
65 // Publish the variable capability to other modules\r
66 //\r
67 return (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable);\r
68\r
69}\r
70\r
71STATIC\r
72VARIABLE_HEADER *\r
73GetNextVariablePtr (\r
74 IN VARIABLE_HEADER *Variable\r
75 )\r
76/*++\r
77\r
78Routine Description:\r
79\r
80 This code checks if variable header is valid or not.\r
81\r
82Arguments:\r
83 Variable Pointer to the Variable Header.\r
84\r
85Returns:\r
86 TRUE Variable header is valid.\r
87 FALSE Variable header is not valid.\r
88\r
89--*/\r
90{\r
91 return (VARIABLE_HEADER *) ((UINTN) GET_VARIABLE_DATA_PTR (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
92}\r
93\r
94STATIC\r
95BOOLEAN\r
96EFIAPI\r
97IsValidVariableHeader (\r
98 IN VARIABLE_HEADER *Variable\r
99 )\r
100/*++\r
101\r
102Routine Description:\r
103\r
104 This code checks if variable header is valid or not.\r
105\r
106Arguments:\r
107 Variable Pointer to the Variable Header.\r
108\r
109Returns:\r
110 TRUE Variable header is valid.\r
111 FALSE Variable header is not valid.\r
112\r
113--*/\r
114{\r
115 if (Variable == NULL ||\r
116 Variable->StartId != VARIABLE_DATA ||\r
117 (sizeof (VARIABLE_HEADER) + Variable->DataSize + Variable->NameSize) > MAX_VARIABLE_SIZE\r
118 ) {\r
119 return FALSE;\r
120 }\r
121\r
122 return TRUE;\r
123}\r
124\r
125STATIC\r
126VARIABLE_STORE_STATUS\r
127EFIAPI\r
128GetVariableStoreStatus (\r
129 IN VARIABLE_STORE_HEADER *VarStoreHeader\r
130 )\r
131/*++\r
132\r
133Routine Description:\r
134\r
135 This code gets the pointer to the variable name.\r
136\r
137Arguments:\r
138\r
139 VarStoreHeader Pointer to the Variable Store Header.\r
140\r
141Returns:\r
142\r
143 EfiRaw Variable store is raw\r
144 EfiValid Variable store is valid\r
145 EfiInvalid Variable store is invalid\r
146\r
147--*/\r
148{\r
149 if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&\r
150 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&\r
151 VarStoreHeader->State == VARIABLE_STORE_HEALTHY\r
152 ) {\r
153\r
154 return EfiValid;\r
155 }\r
156\r
157 if (VarStoreHeader->Signature == 0xffffffff &&\r
158 VarStoreHeader->Size == 0xffffffff &&\r
159 VarStoreHeader->Format == 0xff &&\r
160 VarStoreHeader->State == 0xff\r
161 ) {\r
162\r
163 return EfiRaw;\r
164 } else {\r
165 return EfiInvalid;\r
166 }\r
167}\r
168\r
169STATIC\r
170EFI_STATUS\r
171CompareWithValidVariable (\r
172 IN VARIABLE_HEADER *Variable,\r
173 IN CONST CHAR16 *VariableName,\r
174 IN CONST EFI_GUID *VendorGuid,\r
175 OUT VARIABLE_POINTER_TRACK *PtrTrack\r
176 )\r
177/*++\r
178\r
179Routine Description:\r
180\r
181 This function compares a variable with variable entries in database\r
182\r
183Arguments:\r
184\r
185 Variable - Pointer to the variable in our database\r
186 VariableName - Name of the variable to compare to 'Variable'\r
187 VendorGuid - GUID of the variable to compare to 'Variable'\r
188 PtrTrack - Variable Track Pointer structure that contains\r
189 Variable Information.\r
190\r
191Returns:\r
192\r
193 EFI_SUCCESS - Found match variable\r
194 EFI_NOT_FOUND - Variable not found\r
195\r
196--*/\r
197{\r
198 if (VariableName[0] == 0) {\r
199 PtrTrack->CurrPtr = Variable;\r
200 return EFI_SUCCESS;\r
201 } else {\r
202 //\r
203 // Don't use CompareGuid function here for performance reasons.\r
204 // Instead we compare the GUID a UINT32 at a time and branch\r
205 // on the first failed comparison.\r
206 //\r
207 if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&\r
208 (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&\r
209 (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&\r
210 (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])\r
211 ) {\r
212 if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), Variable->NameSize)) {\r
213 PtrTrack->CurrPtr = Variable;\r
214 return EFI_SUCCESS;\r
215 }\r
216 }\r
217 }\r
218\r
219 return EFI_NOT_FOUND;\r
220}\r
221\r
222STATIC\r
223EFI_STATUS\r
224EFIAPI\r
225FindVariable (\r
226 IN EFI_PEI_SERVICES **PeiServices,\r
227 IN CONST CHAR16 *VariableName,\r
228 IN CONST EFI_GUID *VendorGuid,\r
229 OUT VARIABLE_POINTER_TRACK *PtrTrack\r
230 )\r
231/*++\r
232\r
233Routine Description:\r
234\r
235 This code finds variable in storage blocks (Non-Volatile)\r
236\r
237Arguments:\r
238\r
239 PeiServices - General purpose services available to every PEIM.\r
240 VariableName - Name of the variable to be found\r
241 VendorGuid - Vendor GUID to be found.\r
242 PtrTrack - Variable Track Pointer structure that contains\r
243 Variable Information.\r
244\r
245Returns:\r
246\r
247 EFI_SUCCESS - Variable found successfully\r
248 EFI_NOT_FOUND - Variable not found\r
249 EFI_INVALID_PARAMETER - Invalid variable name\r
250\r
251--*/\r
252{\r
253 EFI_HOB_GUID_TYPE *GuidHob;\r
254 VARIABLE_STORE_HEADER *VariableStoreHeader;\r
255 VARIABLE_HEADER *Variable;\r
256 VARIABLE_HEADER *MaxIndex;\r
257 VARIABLE_INDEX_TABLE *IndexTable;\r
258 UINT32 Count;\r
259 UINT8 *VariableBase;\r
260\r
261 if (VariableName != 0 && VendorGuid == NULL) {\r
262 return EFI_INVALID_PARAMETER;\r
263 }\r
264 //\r
265 // No Variable Address equals zero, so 0 as initial value is safe.\r
266 //\r
267 MaxIndex = 0;\r
268\r
269 GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);\r
270 if (GuidHob == NULL) {\r
271 IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
272 IndexTable->Length = 0;\r
273 IndexTable->StartPtr = NULL;\r
274 IndexTable->EndPtr = NULL;\r
275 IndexTable->GoneThrough = 0;\r
276 } else {\r
277 IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
278 for (Count = 0; Count < IndexTable->Length; Count++)\r
279 {\r
280 MaxIndex = GetVariableByIndex (IndexTable, Count);\r
281\r
282 if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
283 PtrTrack->StartPtr = IndexTable->StartPtr;\r
284 PtrTrack->EndPtr = IndexTable->EndPtr;\r
285\r
286 return EFI_SUCCESS;\r
287 }\r
288 }\r
289\r
290 if (IndexTable->GoneThrough) {\r
291 return EFI_NOT_FOUND;\r
292 }\r
293 }\r
294 //\r
295 // If not found in HOB, then let's start from the MaxIndex we've found.\r
296 //\r
297 if (MaxIndex != NULL) {\r
298 Variable = GetNextVariablePtr (MaxIndex);\r
299 } else {\r
300 if (IndexTable->StartPtr || IndexTable->EndPtr) {\r
301 Variable = IndexTable->StartPtr;\r
302 } else {\r
303 VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);\r
304 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \\r
305 ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);\r
306\r
307 if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {\r
308 return EFI_UNSUPPORTED;\r
309 }\r
310\r
311 if (~VariableStoreHeader->Size == 0) {\r
312 return EFI_NOT_FOUND;\r
313 }\r
314 //\r
315 // Find the variable by walk through non-volatile variable store\r
316 //\r
317 IndexTable->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
318 IndexTable->EndPtr = (VARIABLE_HEADER *) ((UINTN) VariableStoreHeader + VariableStoreHeader->Size);\r
319\r
320 //\r
321 // Start Pointers for the variable.\r
322 // Actual Data Pointer where data can be written.\r
323 //\r
324 Variable = IndexTable->StartPtr;\r
325 }\r
326 }\r
327 //\r
328 // Find the variable by walk through non-volatile variable store\r
329 //\r
330 PtrTrack->StartPtr = IndexTable->StartPtr;\r
331 PtrTrack->EndPtr = IndexTable->EndPtr;\r
332\r
333 while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {\r
334 if (Variable->State == VAR_ADDED) {\r
335 //\r
336 // Record Variable in VariableIndex HOB\r
337 //\r
338 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME)\r
339 {\r
340 VariableIndexTableUpdate (IndexTable, Variable);\r
341 }\r
342\r
343 if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
344 return EFI_SUCCESS;\r
345 }\r
346 }\r
347\r
348 Variable = GetNextVariablePtr (Variable);\r
349 }\r
350 //\r
351 // If gone through the VariableStore, that means we never find in Firmware any more.\r
352 //\r
353 if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
354 IndexTable->GoneThrough = 1;\r
355 }\r
356\r
357 PtrTrack->CurrPtr = NULL;\r
358\r
359 return EFI_NOT_FOUND;\r
360}\r
361\r
362EFI_STATUS\r
363EFIAPI\r
364PeiGetVariable (\r
365 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,\r
366 IN CONST CHAR16 *VariableName,\r
367 IN CONST EFI_GUID *VariableGuid,\r
368 OUT UINT32 *Attributes,\r
369 IN OUT UINTN *DataSize,\r
370 OUT VOID *Data\r
371 )\r
372/*++\r
373\r
374Routine Description:\r
375\r
376 Provide the read variable functionality of the variable services.\r
377\r
378Arguments:\r
379\r
380 PeiServices - General purpose services available to every PEIM.\r
381\r
382 VariableName - The variable name\r
383\r
384 VendorGuid - The vendor's GUID\r
385\r
386 Attributes - Pointer to the attribute\r
387\r
388 DataSize - Size of data\r
389\r
390 Data - Pointer to data\r
391\r
392Returns:\r
393\r
394 EFI_SUCCESS - The interface could be successfully installed\r
395\r
396 EFI_NOT_FOUND - The variable could not be discovered\r
397\r
398 EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough\r
399\r
400--*/\r
401{\r
402 VARIABLE_POINTER_TRACK Variable;\r
403 UINTN VarDataSize;\r
404 EFI_STATUS Status;\r
405 EFI_PEI_SERVICES **PeiServices;\r
406\r
407 PeiServices = GetPeiServicesTablePointer ();\r
408 if (VariableName == NULL || VariableGuid == NULL) {\r
409 return EFI_INVALID_PARAMETER;\r
410 }\r
411 //\r
412 // Find existing variable\r
413 //\r
414 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);\r
415 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {\r
416 return Status;\r
417 }\r
418 //\r
419 // Get data size\r
420 //\r
421 VarDataSize = Variable.CurrPtr->DataSize;\r
422 if (*DataSize >= VarDataSize) {\r
423 (*PeiServices)->CopyMem (Data, GET_VARIABLE_DATA_PTR (Variable.CurrPtr), VarDataSize);\r
424\r
425 if (Attributes != NULL) {\r
426 *Attributes = Variable.CurrPtr->Attributes;\r
427 }\r
428\r
429 *DataSize = VarDataSize;\r
430 return EFI_SUCCESS;\r
431 } else {\r
432 *DataSize = VarDataSize;\r
433 return EFI_BUFFER_TOO_SMALL;\r
434 }\r
435}\r
436\r
437EFI_STATUS\r
438EFIAPI\r
439PeiGetNextVariableName (\r
440 IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,\r
441 IN OUT UINTN *VariableNameSize,\r
442 IN OUT CHAR16 *VariableName,\r
443 IN OUT EFI_GUID *VariableGuid\r
444 )\r
445/*++\r
446\r
447Routine Description:\r
448\r
449 Provide the get next variable functionality of the variable services.\r
450\r
451Arguments:\r
452\r
453 PeiServices - General purpose services available to every PEIM.\r
454 VariabvleNameSize - The variable name's size.\r
455 VariableName - A pointer to the variable's name.\r
456 VariableGuid - A pointer to the EFI_GUID structure.\r
457\r
458 VariableNameSize - Size of the variable name\r
459\r
460 VariableName - The variable name\r
461\r
462 VendorGuid - The vendor's GUID\r
463\r
464Returns:\r
465\r
466 EFI_SUCCESS - The interface could be successfully installed\r
467\r
468 EFI_NOT_FOUND - The variable could not be discovered\r
469\r
470--*/\r
471{\r
472 VARIABLE_POINTER_TRACK Variable;\r
473 UINTN VarNameSize;\r
474 EFI_STATUS Status;\r
475 EFI_PEI_SERVICES **PeiServices;\r
476\r
477 PeiServices = GetPeiServicesTablePointer ();\r
478 if (VariableName == NULL) {\r
479 return EFI_INVALID_PARAMETER;\r
480 }\r
481\r
482 Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);\r
483 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {\r
484 return Status;\r
485 }\r
486\r
487 if (VariableName[0] != 0) {\r
488 //\r
489 // If variable name is not NULL, get next variable\r
490 //\r
491 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
492 }\r
493\r
494 while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {\r
495 if (IsValidVariableHeader (Variable.CurrPtr)) {\r
496 if (Variable.CurrPtr->State == VAR_ADDED) {\r
497 VarNameSize = (UINTN) Variable.CurrPtr->NameSize;\r
498 if (VarNameSize <= *VariableNameSize) {\r
499 (*PeiServices)->CopyMem (VariableName, GET_VARIABLE_NAME_PTR (Variable.CurrPtr), VarNameSize);\r
500\r
501 (*PeiServices)->CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));\r
502\r
503 Status = EFI_SUCCESS;\r
504 } else {\r
505 Status = EFI_BUFFER_TOO_SMALL;\r
506 }\r
507\r
508 *VariableNameSize = VarNameSize;\r
509 return Status;\r
510 //\r
511 // Variable is found\r
512 //\r
513 } else {\r
514 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
515 }\r
516 } else {\r
517 break;\r
518 }\r
519 }\r
520\r
521 return EFI_NOT_FOUND;\r
522}\r