/** @file
  Reset Architectural and Reset Notification protocols implementation.

  Copyright (c) 2006 - 2018, 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 "ResetSystem.h"

GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mResetTypeStr[] = {
  L"Cold", L"Warm", L"Shutdown", L"PlatformSpecific"
};

//
// The current ResetSystem() notification recursion depth
//
UINTN  mResetNotifyDepth = 0;

/**
  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 EFI_RESET_NOTIFICATION_PROTOCOL *This,
  IN EFI_RESET_SYSTEM                ResetFunction
  )
{
  RESET_NOTIFICATION_INSTANCE        *Instance;
  LIST_ENTRY                         *Link;
  RESET_NOTIFY_ENTRY                 *Entry;

  if (ResetFunction == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = RESET_NOTIFICATION_INSTANCE_FROM_THIS (This);

  for ( Link = GetFirstNode (&Instance->ResetNotifies)
      ; !IsNull (&Instance->ResetNotifies, Link)
      ; Link = GetNextNode (&Instance->ResetNotifies, Link)
      ) {
    Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
    if (Entry->ResetNotify == ResetFunction) {
      return EFI_ALREADY_STARTED;
    }
  }

  ASSERT (IsNull (&Instance->ResetNotifies, Link));
  Entry = AllocatePool (sizeof (*Entry));
  if (Entry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  Entry->Signature   = RESET_NOTIFY_ENTRY_SIGNATURE;
  Entry->ResetNotify = ResetFunction;
  InsertTailList (&Instance->ResetNotifies, &Entry->Link);
  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 EFI_RESET_NOTIFICATION_PROTOCOL *This,
  IN EFI_RESET_SYSTEM                ResetFunction
  )
{
  RESET_NOTIFICATION_INSTANCE        *Instance;
  LIST_ENTRY                         *Link;
  RESET_NOTIFY_ENTRY                 *Entry;

  if (ResetFunction == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = RESET_NOTIFICATION_INSTANCE_FROM_THIS (This);

  for ( Link = GetFirstNode (&Instance->ResetNotifies)
      ; !IsNull (&Instance->ResetNotifies, Link)
      ; Link = GetNextNode (&Instance->ResetNotifies, Link)
      ) {
    Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
    if (Entry->ResetNotify == ResetFunction) {
      RemoveEntryList (&Entry->Link);
      FreePool (Entry);
      return EFI_SUCCESS;
    }
  }

  return EFI_INVALID_PARAMETER;
}

RESET_NOTIFICATION_INSTANCE mResetNotification = {
  RESET_NOTIFICATION_INSTANCE_SIGNATURE,
  {
    RegisterResetNotify,
    UnregisterResetNotify
  },
  INITIALIZE_LIST_HEAD_VARIABLE (mResetNotification.ResetNotifies)
};

RESET_NOTIFICATION_INSTANCE mPlatformSpecificResetFilter = {
  RESET_NOTIFICATION_INSTANCE_SIGNATURE,
  {
    RegisterResetNotify,
    UnregisterResetNotify
  },
  INITIALIZE_LIST_HEAD_VARIABLE (mPlatformSpecificResetFilter.ResetNotifies)
};

RESET_NOTIFICATION_INSTANCE mPlatformSpecificResetHandler = {
  RESET_NOTIFICATION_INSTANCE_SIGNATURE,
  {
    RegisterResetNotify,
    UnregisterResetNotify
  },
  INITIALIZE_LIST_HEAD_VARIABLE (mPlatformSpecificResetHandler.ResetNotifies)
};

/**
  The driver's entry point.

  It initializes the Reset Architectural Protocol.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.
  @param[in] SystemTable  A pointer to the EFI System Table.

  @retval EFI_SUCCESS     The entry point is executed successfully.
  @retval other           Cannot install ResetArch protocol.

**/
EFI_STATUS
EFIAPI
InitializeResetSystem (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  Handle;

  //
  // Make sure the Reset Architectural Protocol is not already installed in the system
  //
  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiResetArchProtocolGuid);

  //
  // Hook the runtime service table
  //
  gRT->ResetSystem = ResetSystem;

  //
  // Now install the Reset RT AP on a new handle
  //
  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiResetArchProtocolGuid,         NULL,
                  &gEfiResetNotificationProtocolGuid, &mResetNotification.ResetNotification,
                  &gEdkiiPlatformSpecificResetFilterProtocolGuid, &mPlatformSpecificResetFilter.ResetNotification,
                  &gEdkiiPlatformSpecificResetHandlerProtocolGuid, &mPlatformSpecificResetHandler.ResetNotification,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  Put the system into S3 power state.
**/
VOID
DoS3 (
  VOID
  )
{
  EnterS3WithImmediateWake ();

  //
  // Should not return
  //
  CpuDeadLoop ();
}

/**
  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. ResetData is only
                                valid if ResetStatus is something other than EFI_SUCCESS
                                unless the ResetType is EfiResetPlatformSpecific
                                where a minimum amount of ResetData is always required.
                                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
ResetSystem (
  IN EFI_RESET_TYPE   ResetType,
  IN EFI_STATUS       ResetStatus,
  IN UINTN            DataSize,
  IN VOID             *ResetData OPTIONAL
  )
{
  EFI_STATUS          Status;
  UINTN               Size;
  UINTN               CapsuleDataPtr;
  LIST_ENTRY          *Link;
  RESET_NOTIFY_ENTRY  *Entry;

  //
  // Only do REPORT_STATUS_CODE() on first call to ResetSystem()
  //
  if (mResetNotifyDepth == 0) {
    //
    // Indicate reset system runtime service is called.
    //
    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM));
  }

  mResetNotifyDepth++;
  DEBUG ((DEBUG_INFO, "DXE ResetSystem2: Reset call depth = %d.\n", mResetNotifyDepth));

  if (mResetNotifyDepth <= MAX_RESET_NOTIFY_DEPTH) {
    if (!EfiAtRuntime ()) {
      //
      // Call reset notification functions registered through the
      // EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL.
      //
      for ( Link = GetFirstNode (&mPlatformSpecificResetFilter.ResetNotifies)
          ; !IsNull (&mPlatformSpecificResetFilter.ResetNotifies, Link)
          ; Link = GetNextNode (&mPlatformSpecificResetFilter.ResetNotifies, Link)
          ) {
        Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
        Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
      }
      //
      // Call reset notification functions registered through the
      // EFI_RESET_NOTIFICATION_PROTOCOL.
      //
      for ( Link = GetFirstNode (&mResetNotification.ResetNotifies)
          ; !IsNull (&mResetNotification.ResetNotifies, Link)
          ; Link = GetNextNode (&mResetNotification.ResetNotifies, Link)
          ) {
        Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
        Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
      }
      //
      // call reset notification functions registered through the
      // EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL.
      //
      for ( Link = GetFirstNode (&mPlatformSpecificResetHandler.ResetNotifies)
          ; !IsNull (&mPlatformSpecificResetHandler.ResetNotifies, Link)
          ; Link = GetNextNode (&mPlatformSpecificResetHandler.ResetNotifies, Link)
          ) {
        Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
        Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
      }
    }
  } else {
    ASSERT (ResetType < ARRAY_SIZE (mResetTypeStr));
    DEBUG ((DEBUG_ERROR, "DXE ResetSystem2: Maximum reset call depth is met. Use the current reset type: %s!\n", mResetTypeStr[ResetType]));
  }

  switch (ResetType) {
  case EfiResetWarm:

    //
    //Check if there are pending capsules to process
    //
    Size = sizeof (CapsuleDataPtr);
    Status =  EfiGetVariable (
                 EFI_CAPSULE_VARIABLE_NAME,
                 &gEfiCapsuleVendorGuid,
                 NULL,
                 &Size,
                 (VOID *) &CapsuleDataPtr
                 );

    if (Status == EFI_SUCCESS) {
      //
      //Process capsules across a system reset.
      //
      DoS3();
    }

    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);
}
