/** @file
  Implementation of Reset2, ResetFilter and ResetHandler PPIs.

  Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "ResetSystem.h"

GLOBAL_REMOVE_IF_UNREFERENCED CHAR16  *mResetTypeStr[] = {
  L"Cold", L"Warm", L"Shutdown", L"PlatformSpecific"
};

EFI_PEI_RESET2_PPI  mPpiReset2 = {
  ResetSystem2
};

EFI_GUID  *mProcessingOrder[] = {
  &gEdkiiPlatformSpecificResetFilterPpiGuid,
  &gEdkiiPlatformSpecificResetNotificationPpiGuid,
  &gEdkiiPlatformSpecificResetHandlerPpiGuid
};

RESET_FILTER_INSTANCE  mResetFilter = {
  {
    RegisterResetNotify,
    UnregisterResetNotify
  },
  &gEdkiiPlatformSpecificResetFilterPpiGuid
};

RESET_FILTER_INSTANCE  mResetNotification = {
  {
    RegisterResetNotify,
    UnregisterResetNotify
  },
  &gEdkiiPlatformSpecificResetNotificationPpiGuid
};

RESET_FILTER_INSTANCE  mResetHandler = {
  {
    RegisterResetNotify,
    UnregisterResetNotify
  },
  &gEdkiiPlatformSpecificResetHandlerPpiGuid
};

EFI_PEI_PPI_DESCRIPTOR  mPpiListReset[] = {
  {
    EFI_PEI_PPI_DESCRIPTOR_PPI,
    &gEfiPeiReset2PpiGuid,
    &mPpiReset2
  },
  {
    EFI_PEI_PPI_DESCRIPTOR_PPI,
    &gEdkiiPlatformSpecificResetFilterPpiGuid,
    &mResetFilter.ResetFilter
  },
  {
    EFI_PEI_PPI_DESCRIPTOR_PPI,
    &gEdkiiPlatformSpecificResetNotificationPpiGuid,
    &mResetNotification.ResetFilter
  },
  {
    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
    &gEdkiiPlatformSpecificResetHandlerPpiGuid,
    &mResetHandler.ResetFilter
  }
};

/**
  Register a notification function to be called when ResetSystem() is called.

  The RegisterResetNotify() function registers a notification function that is called when
  ResetSystem() is called and prior to completing the reset of the platform.
  The registered functions must not perform a platform reset themselves. These
  notifications are intended only for the notification of components which may need some
  special-purpose maintenance prior to the platform resetting.
  The list of registered reset notification functions are processed if ResetSystem()is called
  before ExitBootServices(). The list of registered reset notification functions is ignored if
  ResetSystem() is called after ExitBootServices().

  @param[in]  This              A pointer to the EFI_RESET_NOTIFICATION_PROTOCOL instance.
  @param[in]  ResetFunction     Points to the function to be called when a ResetSystem() is executed.

  @retval EFI_SUCCESS           The reset notification function was successfully registered.
  @retval EFI_INVALID_PARAMETER ResetFunction is NULL.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to register the reset notification function.
  @retval EFI_ALREADY_STARTED   The reset notification function specified by ResetFunction has already been registered.

**/
EFI_STATUS
EFIAPI
RegisterResetNotify (
  IN EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI  *This,
  IN EFI_RESET_SYSTEM                          ResetFunction
  )
{
  RESET_FILTER_INSTANCE  *ResetFilter;
  RESET_FILTER_LIST      *List;
  VOID                   *Hob;
  UINTN                  Index;

  if (ResetFunction == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ResetFilter = (RESET_FILTER_INSTANCE *)This;
  ASSERT (
    CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetFilterPpiGuid) ||
    CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetNotificationPpiGuid) ||
    CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetHandlerPpiGuid)
    );

  Hob = GetFirstGuidHob (ResetFilter->Guid);
  if (Hob == NULL) {
    //
    // When the GUIDed HOB doesn't exist, create it.
    //
    List = (RESET_FILTER_LIST *)BuildGuidHob (
                                  ResetFilter->Guid,
                                  sizeof (RESET_FILTER_LIST) + sizeof (EFI_RESET_SYSTEM) * PcdGet32 (PcdMaximumPeiResetNotifies)
                                  );
    if (List == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    List->Signature = RESET_FILTER_LIST_SIGNATURE;
    List->Count     = PcdGet32 (PcdMaximumPeiResetNotifies);
    ZeroMem (List->ResetFilters, sizeof (EFI_RESET_SYSTEM) * List->Count);
    List->ResetFilters[0] = ResetFunction;
    return EFI_SUCCESS;
  } else {
    List = (RESET_FILTER_LIST *)GET_GUID_HOB_DATA (Hob);
    ASSERT (List->Signature == RESET_FILTER_LIST_SIGNATURE);
    //
    // Firstly check whether the ResetFunction is already registerred.
    //
    for (Index = 0; Index < List->Count; Index++) {
      if (List->ResetFilters[Index] == ResetFunction) {
        break;
      }
    }

    if (Index != List->Count) {
      return EFI_ALREADY_STARTED;
    }

    //
    // Secondly find the first free slot.
    //
    for (Index = 0; Index < List->Count; Index++) {
      if (List->ResetFilters[Index] == NULL) {
        break;
      }
    }

    if (Index == List->Count) {
      return EFI_OUT_OF_RESOURCES;
    }

    List->ResetFilters[Index] = ResetFunction;
    return EFI_SUCCESS;
  }
}

/**
  Unregister a notification function.

  The UnregisterResetNotify() function removes the previously registered
  notification using RegisterResetNotify().

  @param[in]  This              A pointer to the EFI_RESET_NOTIFICATION_PROTOCOL instance.
  @param[in]  ResetFunction     The pointer to the ResetFunction being unregistered.

  @retval EFI_SUCCESS           The reset notification function was unregistered.
  @retval EFI_INVALID_PARAMETER ResetFunction is NULL.
  @retval EFI_INVALID_PARAMETER The reset notification function specified by ResetFunction was not previously
                                registered using RegisterResetNotify().

**/
EFI_STATUS
EFIAPI
UnregisterResetNotify (
  IN EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI  *This,
  IN EFI_RESET_SYSTEM                          ResetFunction
  )
{
  RESET_FILTER_INSTANCE  *ResetFilter;
  RESET_FILTER_LIST      *List;
  VOID                   *Hob;
  UINTN                  Index;

  if (ResetFunction == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ResetFilter = (RESET_FILTER_INSTANCE *)This;
  ASSERT (
    CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetFilterPpiGuid) ||
    CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetNotificationPpiGuid) ||
    CompareGuid (ResetFilter->Guid, &gEdkiiPlatformSpecificResetHandlerPpiGuid)
    );

  Hob = GetFirstGuidHob (ResetFilter->Guid);
  if (Hob == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  List = (RESET_FILTER_LIST *)GET_GUID_HOB_DATA (Hob);
  ASSERT (List->Signature == RESET_FILTER_LIST_SIGNATURE);
  for (Index = 0; Index < List->Count; Index++) {
    if (List->ResetFilters[Index] == ResetFunction) {
      break;
    }
  }

  if (Index == List->Count) {
    return EFI_INVALID_PARAMETER;
  }

  List->ResetFilters[Index] = NULL;
  return EFI_SUCCESS;
}

/**
  The PEIM's entry point.

  It initializes the Reset2, ResetFilter and ResetHandler PPIs.

  @param[in] FileHandle  Handle of the file being invoked.
  @param[in] PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCCESS         The entry point is executed successfully.
  @retval EFI_ALREADY_STARTED The Reset2 PPI was already installed.
  @retval others              Status code returned from PeiServicesInstallPpi().

**/
EFI_STATUS
EFIAPI
InitializeResetSystem (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  EFI_STATUS  Status;
  VOID        *Ppi;

  Status = PeiServicesLocatePpi (&gEfiPeiReset2PpiGuid, 0, NULL, (VOID **)&Ppi);
  if (Status != EFI_NOT_FOUND) {
    return EFI_ALREADY_STARTED;
  }

  PeiServicesInstallPpi (mPpiListReset);

  return Status;
}

/**
  Resets the entire platform.

  @param[in] ResetType          The type of reset to perform.
  @param[in] ResetStatus        The status code for the reset.
  @param[in] DataSize           The size, in bytes, of ResetData.
  @param[in] ResetData          For a ResetType of EfiResetCold, EfiResetWarm, or
                                EfiResetShutdown the data buffer starts with a Null-terminated
                                string, optionally followed by additional binary data.
                                The string is a description that the caller may use to further
                                indicate the reason for the system reset.
                                For a ResetType of EfiResetPlatformSpecific the data buffer
                                also starts with a Null-terminated string that is followed
                                by an EFI_GUID that describes the specific type of reset to perform.
**/
VOID
EFIAPI
ResetSystem2 (
  IN EFI_RESET_TYPE  ResetType,
  IN EFI_STATUS      ResetStatus,
  IN UINTN           DataSize,
  IN VOID            *ResetData OPTIONAL
  )
{
  VOID               *Hob;
  UINTN              Index;
  RESET_FILTER_LIST  *List;
  UINTN              OrderIndex;
  UINT8              RecursionDepth;
  UINT8              *RecursionDepthPointer;

  //
  // The recursion depth is stored in GUIDed HOB using gEfiCallerIdGuid.
  //
  Hob = GetFirstGuidHob (&gEfiCallerIdGuid);
  if (Hob == NULL) {
    RecursionDepth        = 0;
    RecursionDepthPointer = BuildGuidDataHob (&gEfiCallerIdGuid, &RecursionDepth, sizeof (RecursionDepth));
  } else {
    RecursionDepthPointer = (UINT8 *)GET_GUID_HOB_DATA (Hob);
  }

  //
  // Only do REPORT_STATUS_CODE() on first call to ResetSystem()
  //
  if (*RecursionDepthPointer == 0) {
    //
    // Indicate reset system PEI service is called.
    //
    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_RESET_SYSTEM));
  }

  //
  // Increase the call depth
  //
  (*RecursionDepthPointer)++;
  DEBUG ((DEBUG_INFO, "PEI ResetSystem2: Reset call depth = %d.\n", *RecursionDepthPointer));

  if (*RecursionDepthPointer <= MAX_RESET_NOTIFY_DEPTH) {
    //
    // Iteratively call Reset Filters and Reset Handlers.
    //
    for (OrderIndex = 0; OrderIndex < ARRAY_SIZE (mProcessingOrder); OrderIndex++) {
      Hob = GetFirstGuidHob (mProcessingOrder[OrderIndex]);
      if (Hob != NULL) {
        List = (RESET_FILTER_LIST *)GET_GUID_HOB_DATA (Hob);
        ASSERT (List->Signature == RESET_FILTER_LIST_SIGNATURE);

        for (Index = 0; Index < List->Count; Index++) {
          if (List->ResetFilters[Index] != NULL) {
            List->ResetFilters[Index](ResetType, ResetStatus, DataSize, ResetData);
          }
        }
      }
    }
  } else {
    ASSERT (ResetType < ARRAY_SIZE (mResetTypeStr));
    DEBUG ((DEBUG_ERROR, "PEI ResetSystem2: Maximum reset call depth is met. Use the current reset type: %s!\n", mResetTypeStr[ResetType]));
  }

  switch (ResetType) {
    case EfiResetWarm:
      ResetWarm ();
      break;

    case EfiResetCold:
      ResetCold ();
      break;

    case EfiResetShutdown:
      ResetShutdown ();
      return;

    case EfiResetPlatformSpecific:
      ResetPlatformSpecific (DataSize, ResetData);
      return;

    default:
      return;
  }

  //
  // Given we should have reset getting here would be bad
  //
  ASSERT (FALSE);
}
