/**@file
  Negotiate SMI features with QEMU, and configure UefiCpuPkg/PiSmmCpuDxeSmm
  accordingly.

  Copyright (C) 2016-2017, Red Hat, Inc.

  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 <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/QemuFwCfgS3Lib.h>

#include "SmiFeatures.h"

//
// The following bit value stands for "broadcast SMI" in the
// "etc/smi/supported-features" and "etc/smi/requested-features" fw_cfg files.
//
#define ICH9_LPC_SMI_F_BROADCAST BIT0

//
// Provides a scratch buffer (allocated in EfiReservedMemoryType type memory)
// for the S3 boot script fragment to write to and read from.
//
#pragma pack (1)
typedef union {
  UINT64 Features;
  UINT8  FeaturesOk;
} SCRATCH_BUFFER;
#pragma pack ()

//
// These carry the selector keys of the "etc/smi/requested-features" and
// "etc/smi/features-ok" fw_cfg files from NegotiateSmiFeatures() to
// AppendFwCfgBootScript().
//
STATIC FIRMWARE_CONFIG_ITEM mRequestedFeaturesItem;
STATIC FIRMWARE_CONFIG_ITEM mFeaturesOkItem;

//
// Carries the negotiated SMI features from NegotiateSmiFeatures() to
// AppendFwCfgBootScript().
//
STATIC UINT64 mSmiFeatures;

/**
  Negotiate SMI features with QEMU.

  @retval FALSE  If SMI feature negotiation is not supported by QEMU. This is
                 not an error, it just means that SaveSmiFeatures() should not
                 be called.

  @retval TRUE   SMI feature negotiation is supported, and it has completed
                 successfully as well. (Failure to negotiate is a fatal error
                 and the function never returns in that case.)
**/
BOOLEAN
NegotiateSmiFeatures (
  VOID
  )
{
  FIRMWARE_CONFIG_ITEM SupportedFeaturesItem;
  UINTN                SupportedFeaturesSize;
  UINTN                RequestedFeaturesSize;
  UINTN                FeaturesOkSize;

  //
  // Look up the fw_cfg files used for feature negotiation. The selector keys
  // of "etc/smi/requested-features" and "etc/smi/features-ok" are saved
  // statically. If the files are missing, then QEMU doesn't support SMI
  // feature negotiation.
  //
  if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smi/supported-features",
                      &SupportedFeaturesItem, &SupportedFeaturesSize)) ||
      RETURN_ERROR (QemuFwCfgFindFile ("etc/smi/requested-features",
                      &mRequestedFeaturesItem, &RequestedFeaturesSize)) ||
      RETURN_ERROR (QemuFwCfgFindFile ("etc/smi/features-ok",
                      &mFeaturesOkItem, &FeaturesOkSize))) {
    DEBUG ((DEBUG_INFO, "%a: SMI feature negotiation unavailable\n",
      __FUNCTION__));
    return FALSE;
  }

  //
  // If the files are present but their sizes disagree with us, that's a fatal
  // error (we can't trust the behavior of SMIs either way).
  //
  if (SupportedFeaturesSize != sizeof mSmiFeatures ||
      RequestedFeaturesSize != sizeof mSmiFeatures ||
      FeaturesOkSize != sizeof (UINT8)) {
    DEBUG ((DEBUG_ERROR, "%a: size mismatch in feature negotiation\n",
      __FUNCTION__));
    goto FatalError;
  }

  //
  // Get the features supported by the host.
  //
  QemuFwCfgSelectItem (SupportedFeaturesItem);
  QemuFwCfgReadBytes (sizeof mSmiFeatures, &mSmiFeatures);

  //
  // We want broadcast SMI and nothing else.
  //
  mSmiFeatures &= ICH9_LPC_SMI_F_BROADCAST;
  QemuFwCfgSelectItem (mRequestedFeaturesItem);
  QemuFwCfgWriteBytes (sizeof mSmiFeatures, &mSmiFeatures);

  //
  // Invoke feature validation in QEMU. If the selection is accepted, the
  // features will be locked down. If the selection is rejected, feature
  // negotiation remains open; however we don't know what to do in that case,
  // so that's a fatal error.
  //
  QemuFwCfgSelectItem (mFeaturesOkItem);
  if (QemuFwCfgRead8 () != 1) {
    DEBUG ((DEBUG_ERROR, "%a: negotiation failed for feature bitmap 0x%Lx\n",
      __FUNCTION__, mSmiFeatures));
    goto FatalError;
  }

  if ((mSmiFeatures & ICH9_LPC_SMI_F_BROADCAST) == 0) {
    //
    // If we can't get broadcast SMIs from QEMU, that's acceptable too,
    // although not optimal.
    //
    DEBUG ((DEBUG_INFO, "%a: SMI broadcast unavailable\n", __FUNCTION__));
  } else {
    //
    // Configure the traditional AP sync / SMI delivery mode for
    // PiSmmCpuDxeSmm. Effectively, restore the UefiCpuPkg defaults, from which
    // the original QEMU behavior (i.e., unicast SMI) used to differ.
    //
    if (RETURN_ERROR (PcdSet64S (PcdCpuSmmApSyncTimeout, 1000000)) ||
        RETURN_ERROR (PcdSet8S (PcdCpuSmmSyncMode, 0x00))) {
      DEBUG ((DEBUG_ERROR, "%a: PiSmmCpuDxeSmm PCD configuration failed\n",
        __FUNCTION__));
      goto FatalError;
    }
    DEBUG ((DEBUG_INFO, "%a: using SMI broadcast\n", __FUNCTION__));
  }

  //
  // Negotiation successful (although we may not have gotten the optimal
  // feature set).
  //
  return TRUE;

FatalError:
  ASSERT (FALSE);
  CpuDeadLoop ();
  //
  // Keep the compiler happy.
  //
  return FALSE;
}

/**
  FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib.
**/
STATIC
VOID
EFIAPI
AppendFwCfgBootScript (
  IN OUT VOID *Context,              OPTIONAL
  IN OUT VOID *ExternalScratchBuffer
  )
{
  SCRATCH_BUFFER *ScratchBuffer;
  RETURN_STATUS  Status;

  ScratchBuffer = ExternalScratchBuffer;

  //
  // Write the negotiated feature bitmap into "etc/smi/requested-features".
  //
  ScratchBuffer->Features = mSmiFeatures;
  Status = QemuFwCfgS3ScriptWriteBytes (mRequestedFeaturesItem,
             sizeof ScratchBuffer->Features);
  if (RETURN_ERROR (Status)) {
    goto FatalError;
  }

  //
  // Read back "etc/smi/features-ok". This invokes the feature validation &
  // lockdown. (The validation succeeded at first boot.)
  //
  Status = QemuFwCfgS3ScriptReadBytes (mFeaturesOkItem,
             sizeof ScratchBuffer->FeaturesOk);
  if (RETURN_ERROR (Status)) {
    goto FatalError;
  }

  //
  // If "etc/smi/features-ok" read as 1, we're good. Otherwise, hang the S3
  // resume process.
  //
  Status = QemuFwCfgS3ScriptCheckValue (&ScratchBuffer->FeaturesOk,
             sizeof ScratchBuffer->FeaturesOk, MAX_UINT8, 1);
  if (RETURN_ERROR (Status)) {
    goto FatalError;
  }

  DEBUG ((DEBUG_VERBOSE, "%a: SMI feature negotiation boot script saved\n",
    __FUNCTION__));
  return;

FatalError:
  ASSERT (FALSE);
  CpuDeadLoop ();
}


/**
  Append a boot script fragment that will re-select the previously negotiated
  SMI features during S3 resume.
**/
VOID
SaveSmiFeatures (
  VOID
  )
{
  RETURN_STATUS Status;

  //
  // We are already running at TPL_CALLBACK, on the stack of
  // OnS3SaveStateInstalled(). But that's okay, we can easily queue more
  // notification functions while executing a notification function.
  //
  Status = QemuFwCfgS3CallWhenBootScriptReady (AppendFwCfgBootScript, NULL,
             sizeof (SCRATCH_BUFFER));
  if (RETURN_ERROR (Status)) {
    ASSERT (FALSE);
    CpuDeadLoop ();
  }
}
