/** @file
  Esrt management implementation.

Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "EsrtImpl.h"

/**
  Find Esrt Entry stored in ESRT repository. 

  @param[in]     FwClass           Firmware class guid in Esrt entry
  @param[in]     Attribute         Esrt from Non FMP or FMP instance
  @param[out]    Entry             Esrt entry returned
  
  @retval EFI_SUCCESS            Successfully find an Esrt entry
  @retval EF_NOT_FOUND           No Esrt entry found

**/
EFI_STATUS
GetEsrtEntry (
  IN  EFI_GUID              *FwClass,
  IN  UINTN                 Attribute,
  OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
  )
{
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  UINTN                      Index;
  UINTN                      EsrtNum;

  EsrtRepository = NULL;

  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }
  
  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (EFI_ERROR(Status)) {
    goto EXIT;
  }

  if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
    DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
    Status = EFI_ABORTED;
    goto EXIT;
  }

  Status  = EFI_NOT_FOUND;
  EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
  for (Index = 0; Index < EsrtNum; Index++) {
    if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {
      CopyMem(Entry, &EsrtRepository[Index], sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
      Status = EFI_SUCCESS;
      break;
    }
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  return Status;
}

/**
  Insert a new ESRT entry into ESRT Cache repository.

  @param[in]  Entry                Esrt entry to be set
  @param[in]  Attribute            Esrt from Esrt private protocol or FMP instance
  
  @retval EFI_SUCCESS          Successfully set a variable.

**/
EFI_STATUS
InsertEsrtEntry(
  IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
  UINTN                        Attribute
  )
{
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepositoryNew;

  EsrtRepository    = NULL;
  EsrtRepositoryNew = NULL;

  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }

  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (Status == EFI_NOT_FOUND) {
    //
    // If not exist, create new Esrt cache repository
    //
    Status = gRT->SetVariable(
                    VariableName,
                    &gEfiCallerIdGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
                    Entry
                    );
    return Status;

  } else if (Status == EFI_SUCCESS) {
    //
    // if exist, update Esrt cache repository
    //
    if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
      DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
      //
      // Repository is corrupt. Clear Repository before insert new entry
      //
      Status = gRT->SetVariable(
                      VariableName,
                      &gEfiCallerIdGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      0,
                      EsrtRepository
                      );
      FreePool(EsrtRepository);
      RepositorySize = 0;
      EsrtRepository = NULL;
    }

    //
    // Check Repository size constraint
    //
    if ((Attribute == ESRT_FROM_FMP && RepositorySize >= PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY))
      ||(Attribute == ESRT_FROM_NONFMP && RepositorySize >= PcdGet32(PcdMaxNonFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) ) {
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    EsrtRepositoryNew = AllocatePool(RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
    if (EsrtRepositoryNew == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    if (RepositorySize != 0 && EsrtRepository != NULL) {
      CopyMem(EsrtRepositoryNew, EsrtRepository, RepositorySize);
    }
    CopyMem((UINT8 *)EsrtRepositoryNew + RepositorySize, Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));

    Status = gRT->SetVariable(
                    VariableName,
                    &gEfiCallerIdGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
                    EsrtRepositoryNew
                    );
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  if (EsrtRepositoryNew != NULL) {
    FreePool(EsrtRepositoryNew);
  }

  return Status;
}

/**
  Delete ESRT Entry from ESRT repository. 

  @param[in]    FwClass              FwClass of Esrt entry to delete  
  @param[in]    Attribute            Esrt from Esrt private protocol or FMP instance
  
  @retval EFI_SUCCESS         Insert all entries Successfully 
  @retval EFI_NOT_FOUND       ESRT entry with FwClass doesn't exsit
  
**/
EFI_STATUS
DeleteEsrtEntry(
  IN  EFI_GUID        *FwClass,
  IN  UINTN           Attribute
  )
{  
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  UINTN                      Index;
  UINTN                      EsrtNum;

  EsrtRepository = NULL;
  
  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }
  
  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (EFI_ERROR(Status)) {
    goto EXIT;
  }

  if ((RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) != 0) {
    DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
    //
    // Repository is corrupt. Clear Repository before insert new entry
    //
    Status = gRT->SetVariable(
                    VariableName,
                    &gEfiCallerIdGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    0,
                    EsrtRepository
                    );
    goto EXIT;
  }

  Status = EFI_NOT_FOUND;
  EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
  for (Index = 0; Index < EsrtNum; Index++) {
    //
    // Delete Esrt entry if it is found in repository
    //
    if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {
      //
      // If delete Esrt entry is not at the rail
      //
      if (Index < EsrtNum - 1) {
        CopyMem(&EsrtRepository[Index], &EsrtRepository[Index + 1], (EsrtNum - Index - 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
      }

      //
      // Update New Repository
      //
      Status = gRT->SetVariable(
                      VariableName,
                      &gEfiCallerIdGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      (EsrtNum - 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
                      EsrtRepository
                      );
      break;
    }
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  return Status;

}

/**
  Update one ESRT entry in ESRT repository

  @param[in]    Entry                Esrt entry to be set
  @param[in]    Attribute            Esrt from Non Esrt or FMP instance
  
  @retval EFI_SUCCESS          Successfully Update a variable.
  @retval EFI_NOT_FOUND        The Esrt enry doesn't exist

**/
EFI_STATUS
UpdateEsrtEntry(
  IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
  UINTN                        Attribute
  )
{
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  UINTN                      Index;
  UINTN                      EsrtNum;

  EsrtRepository    = NULL;

  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }

  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (!EFI_ERROR(Status)) {
    //
    // if exist, update Esrt cache repository
    //
    if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
      DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
      //
      // Repository is corrupt. Clear Repository before insert new entry
      //
      Status = gRT->SetVariable(
                      VariableName,
                      &gEfiCallerIdGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      0,
                      EsrtRepository
                      );
      Status = EFI_NOT_FOUND;
      goto EXIT;
    }

    Status = EFI_NOT_FOUND;
    EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
    for (Index = 0; Index < EsrtNum; Index++) {
      //
      // Update Esrt entry if it is found in repository
      //
      if (CompareGuid(&Entry->FwClass, &EsrtRepository[Index].FwClass)) {

        CopyMem(&EsrtRepository[Index], Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
        //
        // Update New Repository
        //
        Status = gRT->SetVariable(
                        VariableName,
                        &gEfiCallerIdGuid,
                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                        RepositorySize,
                        EsrtRepository
                        );
        break;
      }
    }
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  return Status;
}

/**
  Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.

  @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR

  @return TRUE  It is a system FMP.
  @return FALSE It is a device FMP.
**/
BOOLEAN
IsSystemFmp (
  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR   *FmpImageInfo
  )
{
  GUID      *Guid;
  UINTN     Count;
  UINTN     Index;

  Guid = PcdGetPtr(PcdSystemFmpCapsuleImageTypeIdGuid);
  Count = PcdGetSize(PcdSystemFmpCapsuleImageTypeIdGuid)/sizeof(GUID);

  for (Index = 0; Index < Count; Index++, Guid++) {
    if (CompareGuid(&FmpImageInfo->ImageTypeId, Guid)) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .

  @param[in, out]     EsrtEntry            Esrt entry to be Init
  @param[in]          FmpImageInfo         FMP image info descriptor
  @param[in]          DescriptorVersion    FMP Image info descriptor version
  
**/
VOID 
SetEsrtEntryFromFmpInfo (
  IN OUT EFI_SYSTEM_RESOURCE_ENTRY   *EsrtEntry,
  IN EFI_FIRMWARE_IMAGE_DESCRIPTOR   *FmpImageInfo,
  IN UINT32                          DescriptorVersion
  )
{
  EsrtEntry->FwVersion                = FmpImageInfo->Version;
  EsrtEntry->FwClass                  = FmpImageInfo->ImageTypeId;
  if (IsSystemFmp(FmpImageInfo)) {
    EsrtEntry->FwType                   = ESRT_FW_TYPE_SYSTEMFIRMWARE;
  } else {
    EsrtEntry->FwType                   = ESRT_FW_TYPE_DEVICEFIRMWARE;
  }
  EsrtEntry->LowestSupportedFwVersion = 0;
  EsrtEntry->CapsuleFlags             = 0;
  EsrtEntry->LastAttemptVersion       = 0;
  EsrtEntry->LastAttemptStatus        = LAST_ATTEMPT_STATUS_SUCCESS;

  if (DescriptorVersion >= 2) {
    //
    // LowestSupportedImageVersion only available in FMP V2 or higher
    //
    EsrtEntry->LowestSupportedFwVersion = FmpImageInfo->LowestSupportedImageVersion;
  } 

  if (DescriptorVersion >= 3) {
    //
    // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher
    //
    EsrtEntry->LastAttemptVersion = FmpImageInfo->LastAttemptVersion;
    EsrtEntry->LastAttemptStatus  = FmpImageInfo->LastAttemptStatus;
  } 

  //
  // Set capsule customized flag
  //
  if ((FmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0
   && (FmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0) {
    EsrtEntry->CapsuleFlags = PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag);
  }
}
