]> git.proxmox.com Git - mirror_edk2.git/blame - FmpDevicePkg/FmpDxe/VariableSupport.c
EmulatorPkg: don't display the cpu current speed
[mirror_edk2.git] / FmpDevicePkg / FmpDxe / VariableSupport.c
CommitLineData
a6d73269 1/** @file\r
b0bacc00
KM
2 UEFI variable support functions for Firmware Management Protocol based\r
3 firmware updates.\r
4\r
5 Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>\r
6 Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
7\r
bcef758c 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
b0bacc00
KM
9\r
10**/\r
11\r
12#include <PiDxe.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/UefiBootServicesTableLib.h>\r
15#include <Library/UefiRuntimeServicesTableLib.h>\r
16#include <Library/UefiLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18#include <Protocol/VariableLock.h>\r
19#include "VariableSupport.h"\r
20\r
21///\r
22/// Array of UEFI variable names that are locked in LockAllFmpVariables().\r
23///\r
24const CHAR16 *mFmpVariableLockList[] = {\r
25 VARNAME_VERSION,\r
26 VARNAME_LSV,\r
27 VARNAME_LASTATTEMPTSTATUS,\r
28 VARNAME_LASTATTEMPTVERSION\r
29};\r
30\r
31/**\r
32 Returns the value used to fill in the Version field of the\r
33 EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()\r
34 service of the Firmware Management Protocol. The value is read from a UEFI\r
35 variable. If the UEFI variables does not exist, then a default version value\r
36 is returned.\r
37\r
38 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpVersion"\r
39\r
40 @return The version of the firmware image in the firmware device.\r
41\r
42**/\r
43UINT32\r
44GetVersionFromVariable (\r
45 VOID\r
46 )\r
47{\r
48 EFI_STATUS Status;\r
49 UINT32 *Value;\r
50 UINTN Size;\r
51 UINT32 Version;\r
52\r
53 Value = NULL;\r
54 Size = 0;\r
55 Version = DEFAULT_VERSION;\r
56\r
57 Status = GetVariable2 (VARNAME_VERSION, &gEfiCallerIdGuid, (VOID **)&Value, &Size);\r
b1be077f 58 if (EFI_ERROR (Status) || (Value == NULL)) {\r
b0bacc00
KM
59 DEBUG ((DEBUG_ERROR, "Failed to get the Version from variable. Status = %r\n", Status));\r
60 return Version;\r
61 }\r
62\r
63 //\r
64 // No error from call\r
65 //\r
66 if (Size == sizeof (*Value)) {\r
67 //\r
68 // Successful read\r
69 //\r
70 Version = *Value;\r
71 } else {\r
72 //\r
73 // Return default since size was unknown\r
74 //\r
75 DEBUG ((DEBUG_ERROR, "Getting version Variable returned a size different than expected. Size = 0x%x\n", Size));\r
76 }\r
77\r
78 FreePool (Value);\r
79\r
80 return Version;\r
81}\r
82\r
83/**\r
84 Returns the value used to fill in the LowestSupportedVersion field of the\r
85 EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()\r
86 service of the Firmware Management Protocol. The value is read from a UEFI\r
87 variable. If the UEFI variables does not exist, then a default lowest\r
88 supported version value is returned.\r
89\r
90 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpLsv"\r
91\r
92 @return The lowest supported version of the firmware image in the firmware\r
93 device.\r
94\r
95**/\r
96UINT32\r
97GetLowestSupportedVersionFromVariable (\r
98 VOID\r
99 )\r
100{\r
101 EFI_STATUS Status;\r
102 UINT32 *Value;\r
103 UINTN Size;\r
104 UINT32 Version;\r
105\r
106 Value = NULL;\r
107 Size = 0;\r
108 Version = DEFAULT_LOWESTSUPPORTEDVERSION;\r
109\r
110 Status = GetVariable2 (VARNAME_LSV, &gEfiCallerIdGuid, (VOID **)&Value, &Size);\r
b1be077f 111 if (EFI_ERROR (Status) || (Value == NULL)) {\r
b0bacc00
KM
112 DEBUG ((DEBUG_WARN, "Warning: Failed to get the Lowest Supported Version from variable. Status = %r\n", Status));\r
113 return Version;\r
114 }\r
115\r
116 //\r
117 // No error from call\r
118 //\r
119 if (Size == sizeof (*Value)) {\r
120 //\r
121 // Successful read\r
122 //\r
123 Version = *Value;\r
124 } else {\r
125 //\r
126 // Return default since size was unknown\r
127 //\r
128 DEBUG ((DEBUG_ERROR, "Getting LSV Variable returned a size different than expected. Size = 0x%x\n", Size));\r
129 }\r
130\r
131 FreePool (Value);\r
132\r
133 return Version;\r
134}\r
135\r
136/**\r
137 Returns the value used to fill in the LastAttemptStatus field of the\r
138 EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()\r
139 service of the Firmware Management Protocol. The value is read from a UEFI\r
140 variable. If the UEFI variables does not exist, then a default last attempt\r
141 status value is returned.\r
142\r
143 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptStatus"\r
144\r
145 @return The last attempt status value for the most recent capsule update.\r
146\r
147**/\r
148UINT32\r
149GetLastAttemptStatusFromVariable (\r
150 VOID\r
151 )\r
152{\r
153 EFI_STATUS Status;\r
154 UINT32 *Value;\r
155 UINTN Size;\r
156 UINT32 LastAttemptStatus;\r
157\r
158 Value = NULL;\r
159 Size = 0;\r
160 LastAttemptStatus = DEFAULT_LASTATTEMPT;\r
161\r
162 Status = GetVariable2 (VARNAME_LASTATTEMPTSTATUS, &gEfiCallerIdGuid, (VOID **)&Value, &Size);\r
b1be077f 163 if (EFI_ERROR (Status) || (Value == NULL)) {\r
b0bacc00
KM
164 DEBUG ((DEBUG_WARN, "Warning: Failed to get the Last Attempt Status from variable. Status = %r\n", Status));\r
165 return LastAttemptStatus;\r
166 }\r
167\r
168 //\r
169 // No error from call\r
170 //\r
171 if (Size == sizeof (*Value)) {\r
172 //\r
173 // Successful read\r
174 //\r
175 LastAttemptStatus = *Value;\r
176 } else {\r
177 //\r
178 // Return default since size was unknown\r
179 //\r
180 DEBUG (\r
181 (DEBUG_ERROR,\r
182 "Getting Last Attempt Status Variable returned a size different than expected. Size = 0x%x\n",\r
183 Size)\r
184 );\r
185 }\r
186\r
187 FreePool (Value);\r
188\r
189 return LastAttemptStatus;\r
190}\r
191\r
192/**\r
193 Returns the value used to fill in the LastAttemptVersion field of the\r
194 EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()\r
195 service of the Firmware Management Protocol. The value is read from a UEFI\r
196 variable. If the UEFI variables does not exist, then a default last attempt\r
197 version value is returned.\r
198\r
199 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion"\r
200\r
201 @return The last attempt version value for the most recent capsule update.\r
202\r
203**/\r
204UINT32\r
205GetLastAttemptVersionFromVariable (\r
206 VOID\r
207 )\r
208{\r
209 EFI_STATUS Status;\r
210 UINT32 *Value;\r
211 UINTN Size;\r
212 UINT32 Version;\r
213\r
214 Value = NULL;\r
215 Size = 0;\r
216 Version = DEFAULT_LASTATTEMPT;\r
217\r
218 Status = GetVariable2 (VARNAME_LASTATTEMPTVERSION, &gEfiCallerIdGuid, (VOID **)&Value, &Size);\r
b1be077f 219 if (EFI_ERROR (Status) || (Value == NULL)) {\r
b0bacc00
KM
220 DEBUG ((DEBUG_WARN, "Warning: Failed to get the Last Attempt Version from variable. Status = %r\n", Status));\r
221 return Version;\r
222 }\r
223\r
224 //\r
225 // No error from call\r
226 //\r
227 if (Size == sizeof (*Value)) {\r
228 //\r
229 // Successful read\r
230 //\r
231 Version = *Value;\r
232 } else {\r
233 //\r
234 // Return default since size was unknown\r
235 //\r
236 DEBUG (\r
237 (DEBUG_ERROR,\r
238 "Getting Last Attempt Version variable returned a size different than expected. Size = 0x%x\n",\r
239 Size)\r
240 );\r
241 }\r
242\r
243 FreePool (Value);\r
244\r
245 return Version;\r
246}\r
247\r
248\r
249/**\r
250 Saves the version current of the firmware image in the firmware device to a\r
251 UEFI variable.\r
252\r
253 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpVersion"\r
254\r
255 @param[in] Version The version of the firmware image in the firmware device.\r
256\r
257**/\r
258VOID\r
259SetVersionInVariable (\r
260 UINT32 Version\r
261 )\r
262{\r
263 EFI_STATUS Status;\r
264 UINT32 Current;\r
265\r
266 Status = EFI_SUCCESS;\r
267\r
268 Current = GetVersionFromVariable();\r
269 if (Current != Version) {\r
270 Status = gRT->SetVariable (\r
271 VARNAME_VERSION,\r
272 &gEfiCallerIdGuid,\r
273 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
274 sizeof (Version),\r
275 &Version\r
276 );\r
277 if (EFI_ERROR (Status)) {\r
278 DEBUG ((DEBUG_ERROR, "Failed to set the Version into a variable. Status = %r\n", Status));\r
279 }\r
280 } else {\r
281 DEBUG ((DEBUG_INFO, "Version variable doesn't need to update. Same value as before.\n"));\r
282 }\r
283}\r
284\r
285/**\r
286 Saves the lowest supported version current of the firmware image in the\r
287 firmware device to a UEFI variable.\r
288\r
289 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpLsv"\r
290\r
a6d73269
SZ
291 @param[in] LowestSupportedVersion The lowest supported version of the firmware image\r
292 in the firmware device.\r
b0bacc00
KM
293\r
294**/\r
295VOID\r
296SetLowestSupportedVersionInVariable (\r
297 UINT32 LowestSupportedVersion\r
298 )\r
299{\r
300 EFI_STATUS Status;\r
301 UINT32 Current;\r
302\r
303 Status = EFI_SUCCESS;\r
304\r
305 Current = GetLowestSupportedVersionFromVariable();\r
306 if (LowestSupportedVersion > Current) {\r
307 Status = gRT->SetVariable (\r
308 VARNAME_LSV,\r
309 &gEfiCallerIdGuid,\r
310 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
311 sizeof (LowestSupportedVersion), &LowestSupportedVersion\r
312 );\r
313 if (EFI_ERROR (Status)) {\r
314 DEBUG ((DEBUG_ERROR, "Failed to set the LSV into a variable. Status = %r\n", Status));\r
315 }\r
316 } else {\r
317 DEBUG ((DEBUG_INFO, "LSV variable doesn't need to update. Same value as before.\n"));\r
318 }\r
319}\r
320\r
321/**\r
322 Saves the last attempt status value of the most recent FMP capsule update to a\r
323 UEFI variable.\r
324\r
325 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptStatus"\r
326\r
327 @param[in] LastAttemptStatus The last attempt status of the most recent FMP\r
328 capsule update.\r
329\r
330**/\r
331VOID\r
332SetLastAttemptStatusInVariable (\r
333 UINT32 LastAttemptStatus\r
334 )\r
335{\r
336 EFI_STATUS Status;\r
337 UINT32 Current;\r
338\r
339 Status = EFI_SUCCESS;\r
340\r
341 Current = GetLastAttemptStatusFromVariable();\r
342 if (Current != LastAttemptStatus) {\r
343 Status = gRT->SetVariable (\r
344 VARNAME_LASTATTEMPTSTATUS,\r
345 &gEfiCallerIdGuid,\r
346 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
347 sizeof (LastAttemptStatus),\r
348 &LastAttemptStatus\r
349 );\r
350 if (EFI_ERROR (Status)) {\r
351 DEBUG ((DEBUG_ERROR, "Failed to set the LastAttemptStatus into a variable. Status = %r\n", Status));\r
352 }\r
353 } else {\r
354 DEBUG ((DEBUG_INFO, "LastAttemptStatus variable doesn't need to update. Same value as before.\n"));\r
355 }\r
356}\r
357\r
358/**\r
359 Saves the last attempt version value of the most recent FMP capsule update to\r
360 a UEFI variable.\r
361\r
362 UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion"\r
363\r
364 @param[in] LastAttemptVersion The last attempt version value of the most\r
365 recent FMP capsule update.\r
366\r
367**/\r
368VOID\r
369SetLastAttemptVersionInVariable (\r
370 UINT32 LastAttemptVersion\r
371 )\r
372{\r
373 EFI_STATUS Status;\r
374 UINT32 Current;\r
375\r
376 Status = EFI_SUCCESS;\r
377\r
378 Current = GetLastAttemptVersionFromVariable();\r
379 if (Current != LastAttemptVersion) {\r
380 Status = gRT->SetVariable (\r
381 VARNAME_LASTATTEMPTVERSION,\r
382 &gEfiCallerIdGuid,\r
383 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
384 sizeof (LastAttemptVersion),\r
385 &LastAttemptVersion\r
386 );\r
387 if (EFI_ERROR (Status)) {\r
388 DEBUG ((DEBUG_ERROR, "Failed to set the LastAttemptVersion into a variable. Status = %r\n", Status));\r
389 }\r
390 } else {\r
391 DEBUG ((DEBUG_INFO, "LastAttemptVersion variable doesn't need to update. Same value as before.\n"));\r
392 }\r
393}\r
394\r
395/**\r
396 Locks all the UEFI Variables used by this module.\r
397\r
398 @retval EFI_SUCCESS All UEFI variables are locked.\r
399 @retval EFI_UNSUPPORTED Variable Lock Protocol not found.\r
400 @retval Other One of the UEFI variables could not be locked.\r
401\r
402**/\r
403EFI_STATUS\r
404LockAllFmpVariables (\r
405 VOID\r
406 )\r
407{\r
408 EFI_STATUS Status;\r
409 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
410 EFI_STATUS ReturnStatus;\r
411 UINTN Index;\r
412\r
413 VariableLock = NULL;\r
414 Status = gBS->LocateProtocol (\r
415 &gEdkiiVariableLockProtocolGuid,\r
416 NULL,\r
417 (VOID **)&VariableLock\r
418 );\r
419 if (EFI_ERROR (Status)) {\r
420 DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to locate Variable Lock Protocol (%r).\n", Status));\r
421 return EFI_UNSUPPORTED;\r
422 }\r
423\r
424 ReturnStatus = EFI_SUCCESS;\r
425 for (Index = 0; Index < ARRAY_SIZE (mFmpVariableLockList); Index++) {\r
426 Status = VariableLock->RequestToLock (\r
427 VariableLock,\r
428 (CHAR16 *)mFmpVariableLockList[Index],\r
429 &gEfiCallerIdGuid\r
430 );\r
431 if (EFI_ERROR (Status)) {\r
432 DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to lock variable %g %s. Status = %r\n",\r
433 &gEfiCallerIdGuid,\r
434 mFmpVariableLockList[Index],\r
435 Status\r
436 ));\r
437 if (!EFI_ERROR (ReturnStatus)) {\r
438 ReturnStatus = Status;\r
439 }\r
440 }\r
441 }\r
442\r
443 return ReturnStatus;\r
444}\r