/** @file
*
*  Copyright (c) 2017, Linaro, Ltd. All rights reserved.
*
*  SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DtPlatformDtbLoaderLib.h>
#include <Library/HiiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiRuntimeServicesTableLib.h>

#include "DtPlatformDxe.h"

extern  UINT8  DtPlatformHiiBin[];
extern  UINT8  DtPlatformDxeStrings[];

typedef struct {
  VENDOR_DEVICE_PATH          VendorDevicePath;
  EFI_DEVICE_PATH_PROTOCOL    End;
} HII_VENDOR_DEVICE_PATH;

STATIC HII_VENDOR_DEVICE_PATH  mDtPlatformDxeVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    DT_PLATFORM_FORMSET_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

STATIC
EFI_STATUS
InstallHiiPages (
  VOID
  )
{
  EFI_STATUS      Status;
  EFI_HII_HANDLE  HiiHandle;
  EFI_HANDLE      DriverHandle;

  DriverHandle = NULL;
  Status       = gBS->InstallMultipleProtocolInterfaces (
                        &DriverHandle,
                        &gEfiDevicePathProtocolGuid,
                        &mDtPlatformDxeVendorDevicePath,
                        NULL
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  HiiHandle = HiiAddPackages (
                &gDtPlatformFormSetGuid,
                DriverHandle,
                DtPlatformDxeStrings,
                DtPlatformHiiBin,
                NULL
                );

  if (HiiHandle == NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           DriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mDtPlatformDxeVendorDevicePath,
           NULL
           );
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  The entry point for DtPlatformDxe driver.

  @param[in] ImageHandle     The image handle of the driver.
  @param[in] SystemTable     The system table.

  @retval EFI_ALREADY_STARTED     The driver already exists in system.
  @retval EFI_OUT_OF_RESOURCES    Fail to execute entry point due to lack of
                                  resources.
  @retval EFI_SUCCESS             All the related protocols are installed on
                                  the driver.

**/
EFI_STATUS
EFIAPI
DtPlatformDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS             Status;
  DT_ACPI_VARSTORE_DATA  DtAcpiPref;
  UINTN                  BufferSize;
  VOID                   *Dtb;
  UINTN                  DtbSize;

  Dtb    = NULL;
  Status = DtPlatformLoadDtb (&Dtb, &DtbSize);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_WARN,
      "%a: no DTB blob could be loaded, defaulting to ACPI (Status == %r)\n",
      __func__,
      Status
      ));
    DtAcpiPref.Pref = DT_ACPI_SELECT_ACPI;
  } else {
    //
    // Get the current DT/ACPI preference from the DtAcpiPref variable.
    //
    BufferSize = sizeof (DtAcpiPref);
    Status     = gRT->GetVariable (
                        DT_ACPI_VARIABLE_NAME,
                        &gDtPlatformFormSetGuid,
                        NULL,
                        &BufferSize,
                        &DtAcpiPref
                        );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_WARN,
        "%a: no DT/ACPI preference found, defaulting to %a\n",
        __func__,
        PcdGetBool (PcdDefaultDtPref) ? "DT" : "ACPI"
        ));
      DtAcpiPref.Pref = PcdGetBool (PcdDefaultDtPref) ? DT_ACPI_SELECT_DT
                                                      : DT_ACPI_SELECT_ACPI;
    }
  }

  if (!EFI_ERROR (Status) &&
      (DtAcpiPref.Pref != DT_ACPI_SELECT_ACPI) &&
      (DtAcpiPref.Pref != DT_ACPI_SELECT_DT))
  {
    DEBUG ((
      DEBUG_WARN,
      "%a: invalid value for %s, defaulting to %a\n",
      __func__,
      DT_ACPI_VARIABLE_NAME,
      PcdGetBool (PcdDefaultDtPref) ? "DT" : "ACPI"
      ));
    DtAcpiPref.Pref = PcdGetBool (PcdDefaultDtPref) ? DT_ACPI_SELECT_DT
                                                    : DT_ACPI_SELECT_ACPI;
    Status = EFI_INVALID_PARAMETER; // trigger setvar below
  }

  //
  // Write the newly selected default value back to the variable store.
  //
  if (EFI_ERROR (Status)) {
    Status = gRT->SetVariable (
                    DT_ACPI_VARIABLE_NAME,
                    &gDtPlatformFormSetGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    sizeof (DtAcpiPref),
                    &DtAcpiPref
                    );
    if (EFI_ERROR (Status)) {
      goto FreeDtb;
    }
  }

  if (DtAcpiPref.Pref == DT_ACPI_SELECT_ACPI) {
    //
    // ACPI was selected: install the gEdkiiPlatformHasAcpiGuid GUID as a
    // NULL protocol to unlock dispatch of ACPI related drivers.
    //
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ImageHandle,
                    &gEdkiiPlatformHasAcpiGuid,
                    NULL,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: failed to install gEdkiiPlatformHasAcpiGuid as a protocol\n",
        __func__
        ));
      goto FreeDtb;
    }
  } else if (DtAcpiPref.Pref == DT_ACPI_SELECT_DT) {
    //
    // DT was selected: copy the blob into newly allocated memory and install
    // a reference to it as the FDT configuration table.
    //
    Status = gBS->InstallConfigurationTable (&gFdtTableGuid, Dtb);
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: failed to install FDT configuration table\n",
        __func__
        ));
      goto FreeDtb;
    }
  } else {
    ASSERT (FALSE);
  }

  //
  // No point in installing the HII pages if ACPI is the only description
  // we have
  //
  if (Dtb == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Note that we don't uninstall the gEdkiiPlatformHasAcpiGuid protocol nor
  // the FDT configuration table if the following call fails. While that will
  // cause loading of this driver to fail, proceeding with ACPI and DT both
  // disabled will guarantee a failed boot, and so it is better to leave them
  // installed in that case.
  //
  return InstallHiiPages ();

FreeDtb:
  if (Dtb != NULL) {
    FreePool (Dtb);
  }

  return Status;
}
