TianoCore EDK2 master
Loading...
Searching...
No Matches
VariableDxe.c
Go to the documentation of this file.
1
13#include "Variable.h"
14
15#include <Protocol/VariablePolicy.h>
16#include <Library/VariablePolicyLib.h>
17
19EFIAPI
21 OUT BOOLEAN *State
22 );
23
25EFI_EVENT mVirtualAddressChangeEvent = NULL;
26VOID *mFtwRegistration = NULL;
27VOID ***mVarCheckAddressPointer = NULL;
28UINTN mVarCheckAddressPointerCount = 0;
30EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol = {
31 EDKII_VARIABLE_POLICY_PROTOCOL_REVISION,
32 DisableVariablePolicy,
34 RegisterVariablePolicy,
35 DumpVariablePolicy,
36 LockVariablePolicy,
37 GetVariablePolicyInfo,
38 GetLockOnVariableStateVariablePolicyInfo
39};
40EDKII_VAR_CHECK_PROTOCOL mVarCheck = {
44};
45
51VOID
52EFIAPI
54 VOID
55 );
56
62BOOLEAN
64 VOID
65 )
66{
67 return EfiAtRuntime ();
68}
69
89 IN EFI_TPL Priority
90 )
91{
92 return EfiInitializeLock (Lock, Priority);
93}
94
107VOID
110 )
111{
112 if (!AtRuntime ()) {
114 }
115}
116
129VOID
132 )
133{
134 if (!AtRuntime ()) {
136 }
137}
138
151 OUT VOID **FtwProtocol
152 )
153{
154 EFI_STATUS Status;
155
156 //
157 // Locate Fault Tolerent Write protocol
158 //
159 Status = gBS->LocateProtocol (
160 &gEfiFaultTolerantWriteProtocolGuid,
161 NULL,
162 FtwProtocol
163 );
164 return Status;
165}
166
181 IN EFI_HANDLE FvBlockHandle,
183 )
184{
185 //
186 // To get the FVB protocol interface on the handle
187 //
188 return gBS->HandleProtocol (
189 FvBlockHandle,
190 &gEfiFirmwareVolumeBlockProtocolGuid,
191 (VOID **)FvBlock
192 );
193}
194
212 OUT UINTN *NumberHandles,
213 OUT EFI_HANDLE **Buffer
214 )
215{
216 EFI_STATUS Status;
217
218 //
219 // Locate all handles of Fvb protocol
220 //
221 Status = gBS->LocateHandleBuffer (
223 &gEfiFirmwareVolumeBlockProtocolGuid,
224 NULL,
225 NumberHandles,
226 Buffer
227 );
228 return Status;
229}
230
241VOID
242EFIAPI
244 IN EFI_EVENT Event,
245 IN VOID *Context
246 )
247{
248 UINTN Index;
249
250 if (mVariableModuleGlobal->FvbInstance != NULL) {
251 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->GetBlockSize);
252 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);
253 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->GetAttributes);
254 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->SetAttributes);
255 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->Read);
256 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->Write);
257 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance->EraseBlocks);
258 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance);
259 }
260
261 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->PlatformLangCodes);
262 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->LangCodes);
263 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->PlatformLang);
264 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
265 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
266 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->VariableGlobal.HobVariableBase);
267 EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal);
268 EfiConvertPointer (0x0, (VOID **)&mNvVariableCache);
269 EfiConvertPointer (0x0, (VOID **)&mNvFvHeaderCache);
270
271 if (mAuthContextOut.AddressPointer != NULL) {
272 for (Index = 0; Index < mAuthContextOut.AddressPointerCount; Index++) {
273 EfiConvertPointer (0x0, (VOID **)mAuthContextOut.AddressPointer[Index]);
274 }
275 }
276
277 if (mVarCheckAddressPointer != NULL) {
278 for (Index = 0; Index < mVarCheckAddressPointerCount; Index++) {
279 EfiConvertPointer (0x0, (VOID **)mVarCheckAddressPointer[Index]);
280 }
281 }
282}
283
295VOID
296EFIAPI
298 EFI_EVENT Event,
299 VOID *Context
300 )
301{
302 EFI_STATUS Status;
303
304 if (!mEndOfDxe) {
306
307 Status = LockVariablePolicy ();
308 ASSERT_EFI_ERROR (Status);
309 //
310 // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.
311 //
312 mEndOfDxe = TRUE;
313 mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);
314 //
315 // The initialization for variable quota.
316 //
318 }
319
320 ReclaimForOS ();
321 if (FeaturePcdGet (PcdVariableCollectStatistics)) {
322 if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
323 gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo);
324 } else {
325 gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
326 }
327 }
328
329 gBS->CloseEvent (Event);
330}
331
341VOID
342EFIAPI
344 EFI_EVENT Event,
345 VOID *Context
346 )
347{
348 EFI_STATUS Status;
349
350 DEBUG ((DEBUG_INFO, "[Variable]END_OF_DXE is signaled\n"));
352 Status = LockVariablePolicy ();
353 ASSERT_EFI_ERROR (Status);
354 mEndOfDxe = TRUE;
355 mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);
356 //
357 // The initialization for variable quota.
358 //
360 if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
361 ReclaimForOS ();
362 }
363
364 gBS->CloseEvent (Event);
365}
366
371VOID
373 VOID
374 )
375{
376 EFI_STATUS Status;
377
379 if (EFI_ERROR (Status)) {
380 DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
381 }
382
383 //
384 // Some Secure Boot Policy Var (SecureBoot, etc) updates following other
385 // Secure Boot Policy Variable change. Record their initial value.
386 //
388
389 //
390 // Install the Variable Write Architectural protocol.
391 //
392 Status = gBS->InstallProtocolInterface (
393 &mHandle,
394 &gEfiVariableWriteArchProtocolGuid,
396 NULL
397 );
398 ASSERT_EFI_ERROR (Status);
399}
400
411VOID
412EFIAPI
414 IN EFI_EVENT Event,
415 IN VOID *Context
416 )
417{
418 EFI_STATUS Status;
421 EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
423 EFI_PHYSICAL_ADDRESS BaseAddress;
424 UINT64 Length;
425 EFI_PHYSICAL_ADDRESS VariableStoreBase;
426 UINT64 VariableStoreLength;
427 UINTN FtwMaxBlockSize;
428 UINT32 NvStorageVariableSize;
429 UINT64 NvStorageVariableSize64;
430
431 //
432 // Ensure FTW protocol is installed.
433 //
434 Status = GetFtwProtocol ((VOID **)&FtwProtocol);
435 if (EFI_ERROR (Status)) {
436 return;
437 }
438
439 Status = GetVariableFlashNvStorageInfo (&NvStorageVariableBase, &NvStorageVariableSize64);
440 ASSERT_EFI_ERROR (Status);
441
442 Status = SafeUint64ToUint32 (NvStorageVariableSize64, &NvStorageVariableSize);
443 // This driver currently assumes the size will be UINT32 so assert the value is safe for now.
444 ASSERT_EFI_ERROR (Status);
445
446 VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;
447
448 Status = FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize);
449 if (!EFI_ERROR (Status)) {
450 ASSERT (NvStorageVariableSize <= FtwMaxBlockSize);
451 }
452
453 //
454 // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.
455 //
456 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;
457
458 //
459 // Find the proper FVB protocol for variable.
460 //
461 Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
462 if (EFI_ERROR (Status)) {
463 return;
464 }
465
466 mVariableModuleGlobal->FvbInstance = FvbProtocol;
467
468 //
469 // Mark the variable storage region of the FLASH as RUNTIME.
470 //
471 VariableStoreLength = mNvVariableCache->Size;
472 BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);
473 Length = VariableStoreLength + (VariableStoreBase - BaseAddress);
474 Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);
475
476 Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
477 if (EFI_ERROR (Status)) {
478 DEBUG ((DEBUG_WARN, "Variable driver failed to get flash memory attribute.\n"));
479 } else {
480 if ((GcdDescriptor.Attributes & EFI_MEMORY_RUNTIME) == 0) {
481 Status = gDS->SetMemorySpaceAttributes (
482 BaseAddress,
483 Length,
484 GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
485 );
486 if (EFI_ERROR (Status)) {
487 DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
488 }
489 }
490 }
491
492 //
493 // Initializes variable write service after FTW was ready.
494 //
496
497 //
498 // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.
499 //
500 gBS->CloseEvent (Event);
501}
502
515EFIAPI
517 OUT BOOLEAN *State
518 )
519{
520 *State = IsVariablePolicyEnabled ();
521 return EFI_SUCCESS;
522}
523
537EFIAPI
539 IN EFI_HANDLE ImageHandle,
540 IN EFI_SYSTEM_TABLE *SystemTable
541 )
542{
543 EFI_STATUS Status;
544 EFI_EVENT ReadyToBootEvent;
545 EFI_EVENT EndOfDxeEvent;
546
547 Status = VariableCommonInitialize ();
548 ASSERT_EFI_ERROR (Status);
549
550 Status = gBS->InstallMultipleProtocolInterfaces (
551 &mHandle,
552 &gEdkiiVariableLockProtocolGuid,
553 &mVariableLock,
554 NULL
555 );
556 ASSERT_EFI_ERROR (Status);
557
558 Status = gBS->InstallMultipleProtocolInterfaces (
559 &mHandle,
560 &gEdkiiVarCheckProtocolGuid,
561 &mVarCheck,
562 NULL
563 );
564 ASSERT_EFI_ERROR (Status);
565
566 SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
567 SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
568 SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
569 SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;
570
571 //
572 // Now install the Variable Runtime Architectural protocol on a new handle.
573 //
574 Status = gBS->InstallProtocolInterface (
575 &mHandle,
576 &gEfiVariableArchProtocolGuid,
578 NULL
579 );
580 ASSERT_EFI_ERROR (Status);
581
582 if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {
583 //
584 // Register FtwNotificationEvent () notify function.
585 //
587 &gEfiFaultTolerantWriteProtocolGuid,
588 TPL_CALLBACK,
590 (VOID *)SystemTable,
591 &mFtwRegistration
592 );
593 } else {
594 //
595 // Emulated non-volatile variable mode does not depend on FVB and FTW.
596 //
598 }
599
600 Status = gBS->CreateEventEx (
601 EVT_NOTIFY_SIGNAL,
602 TPL_NOTIFY,
604 NULL,
605 &gEfiEventVirtualAddressChangeGuid,
606 &mVirtualAddressChangeEvent
607 );
608 ASSERT_EFI_ERROR (Status);
609
610 //
611 // Register the event handling function to reclaim variable for OS usage.
612 //
614 TPL_NOTIFY,
616 NULL,
617 &ReadyToBootEvent
618 );
619 ASSERT_EFI_ERROR (Status);
620
621 //
622 // Register the event handling function to set the End Of DXE flag.
623 //
624 Status = gBS->CreateEventEx (
625 EVT_NOTIFY_SIGNAL,
626 TPL_CALLBACK,
628 NULL,
629 &gEfiEndOfDxeEventGroupGuid,
630 &EndOfDxeEvent
631 );
632 ASSERT_EFI_ERROR (Status);
633
634 // Register and initialize the VariablePolicy engine.
635 Status = InitVariablePolicyLib (VariableServiceGetVariable);
636 ASSERT_EFI_ERROR (Status);
637 Status = VarCheckRegisterSetVariableCheckHandler (ValidateSetVariable);
638 ASSERT_EFI_ERROR (Status);
639 Status = gBS->InstallMultipleProtocolInterfaces (
640 &mHandle,
641 &gEdkiiVariablePolicyProtocolGuid,
642 &mVariablePolicyProtocol,
643 NULL
644 );
645 ASSERT_EFI_ERROR (Status);
646
647 return EFI_SUCCESS;
648}
UINT64 UINTN
EFI_DXE_SERVICES * gDS
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID MorLockInitAtEndOfDxe(VOID)
RETURN_STATUS EFIAPI SafeUint64ToUint32(IN UINT64 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:2698
EFI_STATUS EFIAPI Lock(IN EFI_SMM_ACCESS2_PROTOCOL *This)
Definition: SmmAccessDxe.c:133
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:434
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: UefiLib.c:405
EFI_STATUS EFIAPI EfiCreateEventReadyToBootEx(IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *ReadyToBootEvent)
Definition: UefiNotTiano.c:164
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
BOOLEAN EFIAPI EfiAtRuntime(VOID)
Definition: RuntimeLib.c:167
EFI_STATUS EFIAPI EfiConvertPointer(IN UINTN DebugDisposition, IN OUT VOID **Address)
Definition: RuntimeLib.c:561
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_FIRMWARE_VOLUME_HEADER * mNvFvHeaderCache
Definition: Variable.c:44
VARIABLE_INFO_ENTRY * gVariableInfo
Definition: Variable.c:49
VOID InitializeVariableQuota(VOID)
Definition: Variable.c:488
VARIABLE_STORE_HEADER * mNvVariableCache
Definition: Variable.c:39
EFI_STATUS VariableWriteServiceInitialize(VOID)
Definition: Variable.c:3415
VOID ReclaimForOS(VOID)
Definition: Variable.c:3202
EFI_STATUS VariableCommonInitialize(VOID)
Definition: Variable.c:3703
EFI_STATUS EFIAPI VariableServiceGetNextVariableName(IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid)
Definition: Variable.c:2502
EFI_STATUS EFIAPI VariableServiceQueryVariableInfo(IN UINT32 Attributes, OUT UINT64 *MaximumVariableStorageSize, OUT UINT64 *RemainingVariableStorageSize, OUT UINT64 *MaximumVariableSize)
Definition: Variable.c:3120
EFI_STATUS GetFvbInfoByAddress(IN EFI_PHYSICAL_ADDRESS Address, OUT EFI_HANDLE *FvbHandle OPTIONAL, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvbProtocol OPTIONAL)
Definition: Variable.c:3811
EFI_STATUS EFIAPI VariableServiceSetVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
Definition: Variable.c:2612
EFI_STATUS EFIAPI VarCheckVariablePropertySet(IN CHAR16 *Name, IN EFI_GUID *Guid, IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty)
Definition: VarCheck.c:59
EFI_STATUS EFIAPI VarCheckRegisterSetVariableCheckHandler(IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler)
Definition: VarCheck.c:29
EFI_STATUS EFIAPI VarCheckVariablePropertyGet(IN CHAR16 *Name, IN EFI_GUID *Guid, OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty)
Definition: VarCheck.c:88
VOID ***EFIAPI VarCheckLibInitializeAtEndOfDxe(IN OUT UINTN *AddressPointerCount OPTIONAL)
Definition: VarCheckLib.c:304
VOID EFIAPI OnReadyToBoot(EFI_EVENT Event, VOID *Context)
Definition: VariableDxe.c:297
EFI_STATUS GetFvbByHandle(IN EFI_HANDLE FvBlockHandle, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock)
Definition: VariableDxe.c:180
EFI_LOCK * InitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: VariableDxe.c:87
BOOLEAN AtRuntime(VOID)
Definition: VariableDxe.c:63
EFI_STATUS EFIAPI VariableServiceInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: VariableDxe.c:538
VOID EFIAPI OnEndOfDxe(EFI_EVENT Event, VOID *Context)
Definition: VariableDxe.c:343
VOID EFIAPI RecordSecureBootPolicyVarData(VOID)
Definition: Measurement.c:347
VOID ReleaseLockOnlyAtBootTime(IN EFI_LOCK *Lock)
Definition: VariableDxe.c:130
VOID EFIAPI FtwNotificationEvent(IN EFI_EVENT Event, IN VOID *Context)
Definition: VariableDxe.c:413
VOID AcquireLockOnlyAtBootTime(IN EFI_LOCK *Lock)
Definition: VariableDxe.c:108
VOID EFIAPI VariableClassAddressChangeEvent(IN EFI_EVENT Event, IN VOID *Context)
Definition: VariableDxe.c:243
EFI_STATUS GetFtwProtocol(OUT VOID **FtwProtocol)
Definition: VariableDxe.c:150
EFI_STATUS GetFvbCountAndBuffer(OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
Definition: VariableDxe.c:211
VOID VariableWriteServiceInitializeDxe(VOID)
Definition: VariableDxe.c:372
EFI_STATUS EFIAPI ProtocolIsVariablePolicyEnabled(OUT BOOLEAN *State)
Definition: VariableDxe.c:516
EFI_HANDLE mHandle
Definition: VariableDxe.c:24
EFI_STATUS EFIAPI GetVariableFlashNvStorageInfo(OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length)
EFI_STATUS EFIAPI VariableLockRequestToLock(IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid)
=== CODE UNDER TEST ===========================================================================