/** @file
  Library functions which relates with driver health.

Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalBm.h"

GLOBAL_REMOVE_IF_UNREFERENCED
CHAR16  *mBmHealthStatusText[] = {
  L"Healthy",
  L"Repair Required",
  L"Configuration Required",
  L"Failed",
  L"Reconnect Required",
  L"Reboot Required"
};

/**
  Return the controller name.

  @param DriverHealthHandle  The handle on which the Driver Health protocol instance is retrieved.
  @param ControllerHandle    The handle of a controller that the driver specified by DriverBindingHandle is managing.
                             This handle specifies the controller whose name is to be returned.
  @param ChildHandle         The handle of the child controller to retrieve the name of. This is an
                             optional parameter that may be NULL. It will be NULL for device drivers.
                             It will also be NULL for bus drivers that attempt to retrieve the name
                             of the bus controller. It will not be NULL for a bus driver that attempts
                             to retrieve the name of a child controller.

  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller
          specified by ControllerHandle and ChildHandle.
**/
CHAR16 *
BmGetControllerName (
  IN  EFI_HANDLE  DriverHealthHandle,
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_HANDLE  ChildHandle
  )
{
  EFI_STATUS                   Status;
  CHAR16                       *ControllerName;
  CHAR8                        *LanguageVariable;
  CHAR8                        *BestLanguage;
  BOOLEAN                      Iso639Language;
  EFI_COMPONENT_NAME_PROTOCOL  *ComponentName;

  ControllerName = NULL;

  //
  // Locate Component Name (2) protocol on the driver binging handle.
  //
  Iso639Language = FALSE;
  Status         = gBS->HandleProtocol (
                          DriverHealthHandle,
                          &gEfiComponentName2ProtocolGuid,
                          (VOID **)&ComponentName
                          );
  if (EFI_ERROR (Status)) {
    Status = gBS->HandleProtocol (
                    DriverHealthHandle,
                    &gEfiComponentNameProtocolGuid,
                    (VOID **)&ComponentName
                    );
    if (!EFI_ERROR (Status)) {
      Iso639Language = TRUE;
    }
  }

  if (!EFI_ERROR (Status)) {
    GetEfiGlobalVariable2 (Iso639Language ? L"Lang" : L"PlatformLang", (VOID **)&LanguageVariable, NULL);
    BestLanguage = GetBestLanguage (
                     ComponentName->SupportedLanguages,
                     Iso639Language,
                     (LanguageVariable != NULL) ? LanguageVariable : "",
                     Iso639Language ? "eng" : "en-US",
                     NULL
                     );
    if (LanguageVariable != NULL) {
      FreePool (LanguageVariable);
    }

    Status = ComponentName->GetControllerName (
                              ComponentName,
                              ControllerHandle,
                              ChildHandle,
                              BestLanguage,
                              &ControllerName
                              );
  }

  if (!EFI_ERROR (Status)) {
    return AllocateCopyPool (StrSize (ControllerName), ControllerName);
  } else {
    return ConvertDevicePathToText (
             DevicePathFromHandle (ChildHandle != NULL ? ChildHandle : ControllerHandle),
             FALSE,
             FALSE
             );
  }
}

/**
  Return the driver name.

  @param DriverHealthHandle  The handle on which the Driver Health protocol instance is retrieved.

  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller
          specified by DriverHealthHandle.
**/
CHAR16 *
BmGetDriverName (
  IN  EFI_HANDLE  DriverHealthHandle
  )
{
  EFI_STATUS                   Status;
  CHAR16                       *DriverName;
  CHAR8                        *LanguageVariable;
  CHAR8                        *BestLanguage;
  BOOLEAN                      Iso639Language;
  EFI_COMPONENT_NAME_PROTOCOL  *ComponentName;

  DriverName = NULL;

  //
  // Locate Component Name (2) protocol on the driver binging handle.
  //
  Iso639Language = FALSE;
  Status         = gBS->HandleProtocol (
                          DriverHealthHandle,
                          &gEfiComponentName2ProtocolGuid,
                          (VOID **)&ComponentName
                          );
  if (EFI_ERROR (Status)) {
    Status = gBS->HandleProtocol (
                    DriverHealthHandle,
                    &gEfiComponentNameProtocolGuid,
                    (VOID **)&ComponentName
                    );
    if (!EFI_ERROR (Status)) {
      Iso639Language = TRUE;
    }
  }

  if (!EFI_ERROR (Status)) {
    GetEfiGlobalVariable2 (Iso639Language ? L"Lang" : L"PlatformLang", (VOID **)&LanguageVariable, NULL);
    BestLanguage = GetBestLanguage (
                     ComponentName->SupportedLanguages,
                     Iso639Language,
                     (LanguageVariable != NULL) ? LanguageVariable : "",
                     Iso639Language ? "eng" : "en-US",
                     NULL
                     );
    if (LanguageVariable != NULL) {
      FreePool (LanguageVariable);
    }

    Status = ComponentName->GetDriverName (
                              ComponentName,
                              BestLanguage,
                              &DriverName
                              );
  }

  if (!EFI_ERROR (Status)) {
    return AllocateCopyPool (StrSize (DriverName), DriverName);
  } else {
    return ConvertDevicePathToText (
             DevicePathFromHandle (DriverHealthHandle),
             FALSE,
             FALSE
             );
  }
}

/**
  Display a set of messages returned by the GetHealthStatus () service of the EFI Driver Health Protocol

  @param DriverHealthInfo  Pointer to the Driver Health information entry.
**/
VOID
BmDisplayMessages (
  IN  EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  *DriverHealthInfo
  )
{
  UINTN       Index;
  EFI_STRING  String;
  CHAR16      *ControllerName = NULL;
  CHAR16      *DriverName     = NULL;

  if ((DriverHealthInfo->MessageList == NULL) ||
      (DriverHealthInfo->MessageList[0].HiiHandle == NULL))
  {
    return;
  }

  if (DriverHealthInfo->DriverHealthHandle != NULL) {
    DriverName = BmGetDriverName (DriverHealthInfo->DriverHealthHandle);
    if (DriverName != NULL) {
      DEBUG ((DEBUG_INFO, "Driver: %s\n", DriverName));
      Print (L"Driver: %s\n", DriverName);
    }
  }

  if (DriverHealthInfo->ControllerHandle != NULL) {
    ControllerName = BmGetControllerName (
                       DriverHealthInfo->DriverHealthHandle,
                       DriverHealthInfo->ControllerHandle,
                       DriverHealthInfo->ChildHandle
                       );
    if (ControllerName != NULL) {
      DEBUG ((DEBUG_INFO, "Controller: %s\n", ControllerName));
      Print (L"Controller: %s\n", ControllerName);
    }
  }

  if ((DriverName == NULL) && (ControllerName == NULL)) {
    return;
  }

  for (Index = 0; DriverHealthInfo->MessageList[Index].HiiHandle != NULL; Index++) {
    String = HiiGetString (
               DriverHealthInfo->MessageList[Index].HiiHandle,
               DriverHealthInfo->MessageList[Index].StringId,
               NULL
               );
    if (String != NULL) {
      Print (L"  %s\n", String);
      DEBUG ((DEBUG_INFO, "  %s\n", String));
      FreePool (String);
    }
  }

  if (ControllerName != NULL) {
    FreePool (ControllerName);
    ControllerName = NULL;
  }

  if (DriverName != NULL) {
    FreePool (DriverName);
    DriverName = NULL;
  }
}

/**
  The repair notify function.
  @param Value  A value between 0 and Limit that identifies the current progress
                of the repair operation.
  @param Limit  The maximum value of Value for the current repair operation.
                If Limit is 0, then the completion progress is indeterminate.
                For example, a driver that wants to specify progress in percent
                would use a Limit value of 100.

  @retval EFI_SUCCESS  Successfully return from the notify function.
**/
EFI_STATUS
EFIAPI
BmRepairNotify (
  IN UINTN  Value,
  IN UINTN  Limit
  )
{
  DEBUG ((DEBUG_INFO, "[BDS]RepairNotify: %d/%d\n", Value, Limit));
  Print (L"[BDS]RepairNotify: %d/%d\n", Value, Limit);

  return EFI_SUCCESS;
}

/**
  Collect the Driver Health status of a single controller.

  @param DriverHealthInfo        A pointer to the array containing all of the platform driver health information.
  @param Count                   Return the updated array count.
  @param DriverHealthHandle      The handle on which the Driver Health protocol instance is retrieved.
  @param ControllerHandle        The handle of the controller..
  @param ChildHandle             The handle of the child controller to retrieve the health
                                 status on.  This is an optional parameter that may be NULL.

  @retval Status                 The status returned from GetHealthStatus.
  @retval EFI_ABORTED            The health status is healthy so no further query is needed.

**/
EFI_STATUS
BmGetSingleControllerHealthStatus (
  IN OUT EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  **DriverHealthInfo,
  IN OUT UINTN                                *Count,
  IN  EFI_HANDLE                              DriverHealthHandle,
  IN  EFI_HANDLE                              ControllerHandle   OPTIONAL,
  IN  EFI_HANDLE                              ChildHandle        OPTIONAL
  )
{
  EFI_STATUS                     Status;
  EFI_DRIVER_HEALTH_PROTOCOL     *DriverHealth;
  EFI_DRIVER_HEALTH_HII_MESSAGE  *MessageList;
  EFI_HII_HANDLE                 FormHiiHandle;
  EFI_DRIVER_HEALTH_STATUS       HealthStatus;

  ASSERT (DriverHealthHandle != NULL);
  //
  // Retrieve the Driver Health Protocol from DriverHandle
  //
  Status = gBS->HandleProtocol (
                  DriverHealthHandle,
                  &gEfiDriverHealthProtocolGuid,
                  (VOID **)&DriverHealth
                  );
  ASSERT_EFI_ERROR (Status);

  if (ControllerHandle == NULL) {
    //
    // If ControllerHandle is NULL, the return the cumulative health status of the driver
    //
    Status = DriverHealth->GetHealthStatus (DriverHealth, NULL, NULL, &HealthStatus, NULL, NULL);
    if (!EFI_ERROR (Status) && (HealthStatus == EfiDriverHealthStatusHealthy)) {
      *DriverHealthInfo = ReallocatePool (
                            (*Count)     * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),
                            (*Count + 1) * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),
                            *DriverHealthInfo
                            );
      ASSERT (*DriverHealthInfo != NULL);

      (*DriverHealthInfo)[*Count].DriverHealthHandle = DriverHealthHandle;
      (*DriverHealthInfo)[*Count].DriverHealth       = DriverHealth;
      (*DriverHealthInfo)[*Count].HealthStatus       = HealthStatus;

      *Count = *Count + 1;

      Status = EFI_ABORTED;
    }

    return Status;
  }

  MessageList   = NULL;
  FormHiiHandle = NULL;

  //
  // Collect the health status with the optional HII message list
  //
  Status = DriverHealth->GetHealthStatus (DriverHealth, ControllerHandle, ChildHandle, &HealthStatus, &MessageList, &FormHiiHandle);
  if (!EFI_ERROR (Status)) {
    *DriverHealthInfo = ReallocatePool (
                          (*Count)     * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),
                          (*Count + 1) * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),
                          *DriverHealthInfo
                          );
    ASSERT (*DriverHealthInfo != NULL);
    (*DriverHealthInfo)[*Count].DriverHealth       = DriverHealth;
    (*DriverHealthInfo)[*Count].DriverHealthHandle = DriverHealthHandle;
    (*DriverHealthInfo)[*Count].ControllerHandle   = ControllerHandle;
    (*DriverHealthInfo)[*Count].ChildHandle        = ChildHandle;
    (*DriverHealthInfo)[*Count].HiiHandle          = FormHiiHandle;
    (*DriverHealthInfo)[*Count].MessageList        = MessageList;
    (*DriverHealthInfo)[*Count].HealthStatus       = HealthStatus;

    *Count = *Count + 1;
  }

  return Status;
}

/**
  Return all the Driver Health information.

  When the cumulative health status of all the controllers managed by the
  driver who produces the EFI_DRIVER_HEALTH_PROTOCOL is healthy, only one
  EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO entry is created for such
  EFI_DRIVER_HEALTH_PROTOCOL instance.
  Otherwise, every controller creates one EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO
  entry. Additionally every child controller creates one
  EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO entry if the driver is a bus driver.

  @param Count      Return the count of the Driver Health information.

  @retval NULL      No Driver Health information is returned.
  @retval !NULL     Pointer to the Driver Health information array.
**/
EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO *
EFIAPI
EfiBootManagerGetDriverHealthInfo (
  UINTN  *Count
  )
{
  EFI_STATUS                           Status;
  UINTN                                NumHandles;
  EFI_HANDLE                           *DriverHealthHandles;
  UINTN                                DriverHealthIndex;
  EFI_HANDLE                           *Handles;
  UINTN                                HandleCount;
  UINTN                                ControllerIndex;
  UINTN                                ChildIndex;
  EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  *DriverHealthInfo;

  //
  // Initialize local variables
  //
  *Count              = 0;
  DriverHealthInfo    = NULL;
  Handles             = NULL;
  DriverHealthHandles = NULL;
  NumHandles          = 0;
  HandleCount         = 0;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDriverHealthProtocolGuid,
                  NULL,
                  &NumHandles,
                  &DriverHealthHandles
                  );

  if ((Status == EFI_NOT_FOUND) || (NumHandles == 0)) {
    //
    // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND
    //
    return NULL;
  }

  ASSERT_EFI_ERROR (Status);
  ASSERT (DriverHealthHandles != NULL);

  //
  // Check the health status of all controllers in the platform
  // Start by looping through all the Driver Health Protocol handles in the handle database
  //
  for (DriverHealthIndex = 0; DriverHealthIndex < NumHandles; DriverHealthIndex++) {
    //
    // Get the cumulative health status of the driver
    //
    Status = BmGetSingleControllerHealthStatus (&DriverHealthInfo, Count, DriverHealthHandles[DriverHealthIndex], NULL, NULL);
    if (EFI_ERROR (Status)) {
      continue;
    }

    //
    // See if the list of all handles in the handle database has been retrieved
    //
    //
    if (Handles == NULL) {
      //
      // Retrieve the list of all handles from the handle database
      //
      Status = gBS->LocateHandleBuffer (
                      AllHandles,
                      NULL,
                      NULL,
                      &HandleCount,
                      &Handles
                      );
      ASSERT_EFI_ERROR (Status);
    }

    //
    // Loop through all the controller handles in the handle database
    //
    for (ControllerIndex = 0; ControllerIndex < HandleCount; ControllerIndex++) {
      Status = BmGetSingleControllerHealthStatus (&DriverHealthInfo, Count, DriverHealthHandles[DriverHealthIndex], Handles[ControllerIndex], NULL);
      if (EFI_ERROR (Status)) {
        continue;
      }

      //
      // Loop through all the child handles in the handle database
      //
      for (ChildIndex = 0; ChildIndex < HandleCount; ChildIndex++) {
        Status = BmGetSingleControllerHealthStatus (&DriverHealthInfo, Count, DriverHealthHandles[DriverHealthIndex], Handles[ControllerIndex], Handles[ChildIndex]);
        if (EFI_ERROR (Status)) {
          continue;
        }
      }
    }
  }

  Status = EFI_SUCCESS;

  if (Handles != NULL) {
    FreePool (Handles);
  }

  if (DriverHealthHandles != NULL) {
    FreePool (DriverHealthHandles);
  }

  return DriverHealthInfo;
}

/**
  Free the Driver Health information array.

  @param DriverHealthInfo       Pointer to array of the Driver Health information.
  @param Count                  Count of the array.

  @retval EFI_SUCCESS           The array is freed.
  @retval EFI_INVALID_PARAMETER The array is NULL.
**/
EFI_STATUS
EFIAPI
EfiBootManagerFreeDriverHealthInfo (
  EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  *DriverHealthInfo,
  UINTN                                Count
  )
{
  UINTN  Index;

  for (Index = 0; Index < Count; Index++) {
    if (DriverHealthInfo[Index].MessageList != NULL) {
      FreePool (DriverHealthInfo[Index].MessageList);
    }
  }

  return gBS->FreePool (DriverHealthInfo);
}

/**
  Repair all the controllers according to the Driver Health status queried.

  @param ReconnectRepairCount     To record the number of recursive call of
                                  this function itself.
**/
VOID
BmRepairAllControllers (
  UINTN  ReconnectRepairCount
  )
{
  EFI_STATUS                           Status;
  EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO  *DriverHealthInfo;
  EFI_DRIVER_HEALTH_STATUS             HealthStatus;
  UINTN                                Count;
  UINTN                                Index;
  BOOLEAN                              RepairRequired;
  BOOLEAN                              ConfigurationRequired;
  BOOLEAN                              ReconnectRequired;
  BOOLEAN                              RebootRequired;
  EFI_HII_HANDLE                       *HiiHandles;
  EFI_FORM_BROWSER2_PROTOCOL           *FormBrowser2;
  UINT32                               MaxRepairCount;
  UINT32                               RepairCount;

  //
  // Configure PcdDriverHealthConfigureForm to ZeroGuid to disable driver health check.
  //
  if (IsZeroGuid (PcdGetPtr (PcdDriverHealthConfigureForm))) {
    return;
  }

  Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&FormBrowser2);
  ASSERT_EFI_ERROR (Status);

  MaxRepairCount = PcdGet32 (PcdMaxRepairCount);
  RepairCount    = 0;

  do {
    RepairRequired        = FALSE;
    ConfigurationRequired = FALSE;

    //
    // Deal with Repair Required
    //
    DriverHealthInfo = EfiBootManagerGetDriverHealthInfo (&Count);
    for (Index = 0; Index < Count; Index++) {
      if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusConfigurationRequired) {
        ConfigurationRequired = TRUE;
      }

      if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusRepairRequired) {
        RepairRequired = TRUE;

        BmDisplayMessages (&DriverHealthInfo[Index]);

        Status = DriverHealthInfo[Index].DriverHealth->Repair (
                                                         DriverHealthInfo[Index].DriverHealth,
                                                         DriverHealthInfo[Index].ControllerHandle,
                                                         DriverHealthInfo[Index].ChildHandle,
                                                         BmRepairNotify
                                                         );
        if (!EFI_ERROR (Status) && !ConfigurationRequired) {
          Status = DriverHealthInfo[Index].DriverHealth->GetHealthStatus (
                                                           DriverHealthInfo[Index].DriverHealth,
                                                           DriverHealthInfo[Index].ControllerHandle,
                                                           DriverHealthInfo[Index].ChildHandle,
                                                           &HealthStatus,
                                                           NULL,
                                                           NULL
                                                           );
          if (!EFI_ERROR (Status) && (HealthStatus == EfiDriverHealthStatusConfigurationRequired)) {
            ConfigurationRequired = TRUE;
          }
        }
      }
    }

    if (ConfigurationRequired) {
      HiiHandles = HiiGetHiiHandles (NULL);
      if (HiiHandles != NULL) {
        for (Index = 0; HiiHandles[Index] != NULL; Index++) {
          Status = FormBrowser2->SendForm (
                                   FormBrowser2,
                                   &HiiHandles[Index],
                                   1,
                                   PcdGetPtr (PcdDriverHealthConfigureForm),
                                   0,
                                   NULL,
                                   NULL
                                   );
          if (!EFI_ERROR (Status)) {
            break;
          }
        }

        FreePool (HiiHandles);
      }
    }

    EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);
    RepairCount++;
  } while ((RepairRequired || ConfigurationRequired) && ((MaxRepairCount == 0) || (RepairCount < MaxRepairCount)));

  RebootRequired    = FALSE;
  ReconnectRequired = FALSE;
  DriverHealthInfo  = EfiBootManagerGetDriverHealthInfo (&Count);
  for (Index = 0; Index < Count; Index++) {
    BmDisplayMessages (&DriverHealthInfo[Index]);

    if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusReconnectRequired) {
      Status = gBS->DisconnectController (DriverHealthInfo[Index].ControllerHandle, NULL, NULL);
      if (EFI_ERROR (Status)) {
        //
        // Disconnect failed. Need to promote reconnect to a reboot.
        //
        RebootRequired = TRUE;
      } else {
        gBS->ConnectController (DriverHealthInfo[Index].ControllerHandle, NULL, NULL, TRUE);
        ReconnectRequired = TRUE;
      }
    }

    if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusRebootRequired) {
      RebootRequired = TRUE;
    }
  }

  EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);

  DEBUG_CODE_BEGIN ();
  CHAR16  *ControllerName = NULL;
  CHAR16  *DriverName     = NULL;
  CHAR16  String[512];

  DriverHealthInfo = EfiBootManagerGetDriverHealthInfo (&Count);
  for (Index = 0; Index < Count; Index++) {
    if (DriverHealthInfo == NULL) {
      continue;
    }

    ZeroMem (String, sizeof (String));
    if (DriverHealthInfo[Index].DriverHealthHandle != NULL) {
      DriverName = BmGetDriverName (DriverHealthInfo[Index].DriverHealthHandle);
    }

    if (DriverHealthInfo[Index].ControllerHandle != NULL) {
      ControllerName = BmGetControllerName (
                         DriverHealthInfo[Index].DriverHealthHandle,
                         DriverHealthInfo[Index].ControllerHandle,
                         DriverHealthInfo[Index].ChildHandle
                         );
    }

    if ((DriverName == NULL) && (ControllerName == NULL)) {
      continue;
    }

    UnicodeSPrint (
      String,
      sizeof (String),
      L"%s%s%s",
      DriverName != NULL ? DriverName : L"",
      (DriverName != NULL && ControllerName != NULL) ? L"    " : L"",
      ControllerName != NULL ? ControllerName : L""
      );

    DEBUG ((
      DEBUG_INFO,
      "%02d: %s - %s\n",
      Index,
      String,
      mBmHealthStatusText[DriverHealthInfo[Index].HealthStatus]
      ));

    if (ControllerName != NULL) {
      FreePool (ControllerName);
      ControllerName = NULL;
    }

    if (DriverName != NULL) {
      FreePool (DriverName);
      DriverName = NULL;
    }
  }

  EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);
  DEBUG_CODE_END ();

  if (ReconnectRequired) {
    if (ReconnectRepairCount < MAX_RECONNECT_REPAIR) {
      BmRepairAllControllers (ReconnectRepairCount + 1);
    } else {
      DEBUG ((
        DEBUG_ERROR,
        "[%a:%d] Repair failed after %d retries.\n",
        __func__,
        DEBUG_LINE_NUMBER,
        ReconnectRepairCount
        ));
    }
  }

  if (RebootRequired) {
    DEBUG ((DEBUG_INFO, "[BDS] One of the Driver Health instances requires rebooting.\n"));
    gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
  }
}
