/** @file
  Implement all four UEFI Runtime Variable services for the nonvolatile
  and volatile storage space and install variable architecture protocol.

Copyright (C) 2013, Red Hat, Inc.
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Variable.h"

#include <Protocol/VariablePolicy.h>
#include <Library/VariablePolicyLib.h>

EFI_STATUS
EFIAPI
ProtocolIsVariablePolicyEnabled (
  OUT BOOLEAN  *State
  );

EFI_HANDLE                      mHandle                      = NULL;
EFI_EVENT                       mVirtualAddressChangeEvent   = NULL;
VOID                            *mFtwRegistration            = NULL;
VOID                            ***mVarCheckAddressPointer   = NULL;
UINTN                           mVarCheckAddressPointerCount = 0;
EDKII_VARIABLE_LOCK_PROTOCOL    mVariableLock                = { VariableLockRequestToLock };
EDKII_VARIABLE_POLICY_PROTOCOL  mVariablePolicyProtocol      = {
  EDKII_VARIABLE_POLICY_PROTOCOL_REVISION,
  DisableVariablePolicy,
  ProtocolIsVariablePolicyEnabled,
  RegisterVariablePolicy,
  DumpVariablePolicy,
  LockVariablePolicy,
  GetVariablePolicyInfo,
  GetLockOnVariableStateVariablePolicyInfo
};
EDKII_VAR_CHECK_PROTOCOL        mVarCheck = {
  VarCheckRegisterSetVariableCheckHandler,
  VarCheckVariablePropertySet,
  VarCheckVariablePropertyGet
};

STATIC EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  mFvbProtocolShadow;

/**
  Some Secure Boot Policy Variable may update following other variable changes(SecureBoot follows PK change, etc).
  Record their initial State when variable write service is ready.

**/
VOID
EFIAPI
RecordSecureBootPolicyVarData (
  VOID
  );

/**
  Return TRUE if ExitBootServices () has been called.

  @retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
AtRuntime (
  VOID
  )
{
  return EfiAtRuntime ();
}

/**
  Initializes a basic mutual exclusion lock.

  This function initializes a basic mutual exclusion lock to the released state
  and returns the lock.  Each lock provides mutual exclusion access at its task
  priority level.  Since there is no preemption or multiprocessor support in EFI,
  acquiring the lock only consists of raising to the locks TPL.
  If Lock is NULL, then ASSERT().
  If Priority is not a valid TPL value, then ASSERT().

  @param  Lock       A pointer to the lock data structure to initialize.
  @param  Priority   EFI TPL is associated with the lock.

  @return The lock.

**/
EFI_LOCK *
InitializeLock (
  IN OUT EFI_LOCK  *Lock,
  IN     EFI_TPL   Priority
  )
{
  return EfiInitializeLock (Lock, Priority);
}

/**
  Acquires lock only at boot time. Simply returns at runtime.

  This is a temperary function that will be removed when
  EfiAcquireLock() in UefiLib can handle the call in UEFI
  Runtimer driver in RT phase.
  It calls EfiAcquireLock() at boot time, and simply returns
  at runtime.

  @param  Lock         A pointer to the lock to acquire.

**/
VOID
AcquireLockOnlyAtBootTime (
  IN EFI_LOCK  *Lock
  )
{
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvbInstance;

  if (!AtRuntime ()) {
    EfiAcquireLock (Lock);
  } else {
    //
    // Check whether we need to swap in the converted pointer values for the
    // FVB protocol methods. This handles the case where the FVB producer did
    // not convert its own pointers during SetVirtualAddressMap.
    //
    FvbInstance = mVariableModuleGlobal->FvbInstance;
    if ((FvbInstance != NULL) &&
        (FvbInstance->GetBlockSize != mFvbProtocolShadow.GetBlockSize))
    {
      FvbInstance->GetBlockSize       = mFvbProtocolShadow.GetBlockSize;
      FvbInstance->GetPhysicalAddress = mFvbProtocolShadow.GetPhysicalAddress;
      FvbInstance->GetAttributes      = mFvbProtocolShadow.GetAttributes;
      FvbInstance->SetAttributes      = mFvbProtocolShadow.SetAttributes;
      FvbInstance->Read               = mFvbProtocolShadow.Read;
      FvbInstance->Write              = mFvbProtocolShadow.Write;
      FvbInstance->EraseBlocks        = mFvbProtocolShadow.EraseBlocks;
    }
  }
}

/**
  Releases lock only at boot time. Simply returns at runtime.

  This is a temperary function which will be removed when
  EfiReleaseLock() in UefiLib can handle the call in UEFI
  Runtimer driver in RT phase.
  It calls EfiReleaseLock() at boot time and simply returns
  at runtime.

  @param  Lock         A pointer to the lock to release.

**/
VOID
ReleaseLockOnlyAtBootTime (
  IN EFI_LOCK  *Lock
  )
{
  if (!AtRuntime ()) {
    EfiReleaseLock (Lock);
  }
}

/**
  Retrieve the Fault Tolerent Write protocol interface.

  @param[out] FtwProtocol       The interface of Ftw protocol

  @retval EFI_SUCCESS           The FTW protocol instance was found and returned in FtwProtocol.
  @retval EFI_NOT_FOUND         The FTW protocol instance was not found.
  @retval EFI_INVALID_PARAMETER SarProtocol is NULL.

**/
EFI_STATUS
GetFtwProtocol (
  OUT VOID  **FtwProtocol
  )
{
  EFI_STATUS  Status;

  //
  // Locate Fault Tolerent Write protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiFaultTolerantWriteProtocolGuid,
                  NULL,
                  FtwProtocol
                  );
  return Status;
}

/**
  Retrieve the FVB protocol interface by HANDLE.

  @param[in]  FvBlockHandle     The handle of FVB protocol that provides services for
                                reading, writing, and erasing the target block.
  @param[out] FvBlock           The interface of FVB protocol

  @retval EFI_SUCCESS           The interface information for the specified protocol was returned.
  @retval EFI_UNSUPPORTED       The device does not support the FVB protocol.
  @retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.

**/
EFI_STATUS
GetFvbByHandle (
  IN  EFI_HANDLE                          FvBlockHandle,
  OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  **FvBlock
  )
{
  //
  // To get the FVB protocol interface on the handle
  //
  return gBS->HandleProtocol (
                FvBlockHandle,
                &gEfiFirmwareVolumeBlockProtocolGuid,
                (VOID **)FvBlock
                );
}

/**
  Function returns an array of handles that support the FVB protocol
  in a buffer allocated from pool.

  @param[out]  NumberHandles    The number of handles returned in Buffer.
  @param[out]  Buffer           A pointer to the buffer to return the requested
                                array of  handles that support FVB protocol.

  @retval EFI_SUCCESS           The array of handles was returned in Buffer, and the number of
                                handles in Buffer was returned in NumberHandles.
  @retval EFI_NOT_FOUND         No FVB handle was found.
  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the matching results.
  @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.

**/
EFI_STATUS
GetFvbCountAndBuffer (
  OUT UINTN       *NumberHandles,
  OUT EFI_HANDLE  **Buffer
  )
{
  EFI_STATUS  Status;

  //
  // Locate all handles of Fvb protocol
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiFirmwareVolumeBlockProtocolGuid,
                  NULL,
                  NumberHandles,
                  Buffer
                  );
  return Status;
}

/**
  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.

  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
  It convers pointer to new virtual address.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
VariableClassAddressChangeEvent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  UINTN  Index;

  if (mVariableModuleGlobal->FvbInstance != NULL) {
    //
    // This module did not produce the FVB protocol instance that provides the
    // variable store, so it should not be the one performing the pointer
    // conversion on its members. However, some FVB protocol implementations
    // may rely on this behavior, which was present in older versions of this
    // driver, so we need to perform the conversion if the protocol producer
    // fails to do so. So let's record the converted values now, and swap them
    // in later if they haven't changed values.
    //
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.GetBlockSize);
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.GetPhysicalAddress);
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.GetAttributes);
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.SetAttributes);
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.Read);
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.Write);
    EfiConvertPointer (0x0, (VOID **)&mFvbProtocolShadow.EraseBlocks);
    EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->FvbInstance);
  }

  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->PlatformLangCodes);
  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->LangCodes);
  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->PlatformLang);
  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal->VariableGlobal.HobVariableBase);
  EfiConvertPointer (0x0, (VOID **)&mVariableModuleGlobal);
  EfiConvertPointer (0x0, (VOID **)&mNvVariableCache);
  EfiConvertPointer (0x0, (VOID **)&mNvFvHeaderCache);

  if (mAuthContextOut.AddressPointer != NULL) {
    for (Index = 0; Index < mAuthContextOut.AddressPointerCount; Index++) {
      EfiConvertPointer (0x0, (VOID **)mAuthContextOut.AddressPointer[Index]);
    }
  }

  if (mVarCheckAddressPointer != NULL) {
    for (Index = 0; Index < mVarCheckAddressPointerCount; Index++) {
      EfiConvertPointer (0x0, (VOID **)mVarCheckAddressPointer[Index]);
    }
  }
}

/**
  Notification function of EVT_GROUP_READY_TO_BOOT event group.

  This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
  When the Boot Manager is about to load and execute a boot option, it reclaims variable
  storage if free size is below the threshold.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
OnReadyToBoot (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  EFI_STATUS  Status;

  if (!mEndOfDxe) {
    MorLockInitAtEndOfDxe ();

    Status = LockVariablePolicy ();
    ASSERT_EFI_ERROR (Status);
    //
    // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.
    //
    mEndOfDxe               = TRUE;
    mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);
    //
    // The initialization for variable quota.
    //
    InitializeVariableQuota ();
  }

  ReclaimForOS ();
  if (FeaturePcdGet (PcdVariableCollectStatistics)) {
    if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
      gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo);
    } else {
      gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
    }
  }

  gBS->CloseEvent (Event);
}

/**
  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
OnEndOfDxe (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  EFI_STATUS  Status;

  DEBUG ((DEBUG_INFO, "[Variable]END_OF_DXE is signaled\n"));
  MorLockInitAtEndOfDxe ();
  Status = LockVariablePolicy ();
  ASSERT_EFI_ERROR (Status);
  mEndOfDxe               = TRUE;
  mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);
  //
  // The initialization for variable quota.
  //
  InitializeVariableQuota ();
  if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
    ReclaimForOS ();
  }

  gBS->CloseEvent (Event);
}

/**
  Initializes variable write service for DXE.

**/
VOID
VariableWriteServiceInitializeDxe (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = VariableWriteServiceInitialize ();
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
  }

  //
  // Some Secure Boot Policy Var (SecureBoot, etc) updates following other
  // Secure Boot Policy Variable change. Record their initial value.
  //
  RecordSecureBootPolicyVarData ();

  //
  // Install the Variable Write Architectural protocol.
  //
  Status = gBS->InstallProtocolInterface (
                  &mHandle,
                  &gEfiVariableWriteArchProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);
}

/**
  Fault Tolerant Write protocol notification event handler.

  Non-Volatile variable write may needs FTW protocol to reclaim when
  writting variable.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  Pointer to the notification function's context.

**/
VOID
EFIAPI
FtwNotificationEvent (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS                          Status;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvbProtocol;
  EFI_FAULT_TOLERANT_WRITE_PROTOCOL   *FtwProtocol;
  EFI_PHYSICAL_ADDRESS                NvStorageVariableBase;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     GcdDescriptor;
  EFI_PHYSICAL_ADDRESS                BaseAddress;
  UINT64                              Length;
  EFI_PHYSICAL_ADDRESS                VariableStoreBase;
  UINT64                              VariableStoreLength;
  UINTN                               FtwMaxBlockSize;
  UINT32                              NvStorageVariableSize;
  UINT64                              NvStorageVariableSize64;

  //
  // Ensure FTW protocol is installed.
  //
  Status = GetFtwProtocol ((VOID **)&FtwProtocol);
  if (EFI_ERROR (Status)) {
    return;
  }

  Status = GetVariableFlashNvStorageInfo (&NvStorageVariableBase, &NvStorageVariableSize64);
  ASSERT_EFI_ERROR (Status);

  Status = SafeUint64ToUint32 (NvStorageVariableSize64, &NvStorageVariableSize);
  // This driver currently assumes the size will be UINT32 so assert the value is safe for now.
  ASSERT_EFI_ERROR (Status);

  VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;

  Status = FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize);
  if (!EFI_ERROR (Status)) {
    ASSERT (NvStorageVariableSize <= FtwMaxBlockSize);
  }

  //
  // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.
  //
  mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;

  //
  // Find the proper FVB protocol for variable.
  //
  Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
  if (EFI_ERROR (Status)) {
    return;
  }

  mVariableModuleGlobal->FvbInstance = FvbProtocol;

  //
  // Store the boot time values of the function pointers so we can compare
  // them later. This is needed to avoid double conversion during the call
  // to SetVirtualAddressMap.
  //
  CopyMem (&mFvbProtocolShadow, FvbProtocol, sizeof mFvbProtocolShadow);

  //
  // Mark the variable storage region of the FLASH as RUNTIME.
  //
  VariableStoreLength = mNvVariableCache->Size;
  BaseAddress         = VariableStoreBase & (~EFI_PAGE_MASK);
  Length              = VariableStoreLength + (VariableStoreBase - BaseAddress);
  Length              = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);

  Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_WARN, "Variable driver failed to get flash memory attribute.\n"));
  } else {
    if ((GcdDescriptor.Attributes & EFI_MEMORY_RUNTIME) == 0) {
      Status = gDS->SetMemorySpaceAttributes (
                      BaseAddress,
                      Length,
                      GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
                      );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
      }
    }
  }

  //
  // Initializes variable write service after FTW was ready.
  //
  VariableWriteServiceInitializeDxe ();

  //
  // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.
  //
  gBS->CloseEvent (Event);
}

/**
  This API function returns whether or not the policy engine is
  currently being enforced.

  @param[out]   State       Pointer to a return value for whether the policy enforcement
                            is currently enabled.

  @retval     EFI_SUCCESS
  @retval     Others        An error has prevented this command from completing.

**/
EFI_STATUS
EFIAPI
ProtocolIsVariablePolicyEnabled (
  OUT BOOLEAN  *State
  )
{
  *State = IsVariablePolicyEnabled ();
  return EFI_SUCCESS;
}

/**
  Variable Driver main entry point. The Variable driver places the 4 EFI
  runtime services in the EFI System Table and installs arch protocols
  for variable read and write services being available. It also registers
  a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       Variable service successfully initialized.

**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   ReadyToBootEvent;
  EFI_EVENT   EndOfDxeEvent;

  Status = VariableCommonInitialize ();
  ASSERT_EFI_ERROR (Status);

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mHandle,
                  &gEdkiiVariableLockProtocolGuid,
                  &mVariableLock,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mHandle,
                  &gEdkiiVarCheckProtocolGuid,
                  &mVarCheck,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  SystemTable->RuntimeServices->GetVariable         = VariableServiceGetVariable;
  SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
  SystemTable->RuntimeServices->SetVariable         = VariableServiceSetVariable;
  SystemTable->RuntimeServices->QueryVariableInfo   = VariableServiceQueryVariableInfo;

  //
  // Now install the Variable Runtime Architectural protocol on a new handle.
  //
  Status = gBS->InstallProtocolInterface (
                  &mHandle,
                  &gEfiVariableArchProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {
    //
    // Register FtwNotificationEvent () notify function.
    //
    EfiCreateProtocolNotifyEvent (
      &gEfiFaultTolerantWriteProtocolGuid,
      TPL_CALLBACK,
      FtwNotificationEvent,
      (VOID *)SystemTable,
      &mFtwRegistration
      );
  } else {
    //
    // Emulated non-volatile variable mode does not depend on FVB and FTW.
    //
    VariableWriteServiceInitializeDxe ();
  }

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  VariableClassAddressChangeEvent,
                  NULL,
                  &gEfiEventVirtualAddressChangeGuid,
                  &mVirtualAddressChangeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register the event handling function to reclaim variable for OS usage.
  //
  Status = EfiCreateEventReadyToBootEx (
             TPL_NOTIFY,
             OnReadyToBoot,
             NULL,
             &ReadyToBootEvent
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Register the event handling function to set the End Of DXE flag.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  OnEndOfDxe,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &EndOfDxeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  // Register and initialize the VariablePolicy engine.
  Status = InitVariablePolicyLib (VariableServiceGetVariable);
  ASSERT_EFI_ERROR (Status);
  Status = VarCheckRegisterSetVariableCheckHandler (ValidateSetVariable);
  ASSERT_EFI_ERROR (Status);
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mHandle,
                  &gEdkiiVariablePolicyProtocolGuid,
                  &mVariablePolicyProtocol,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
