/** @file

  Functions and types shared by the SMM accessor PEI and DXE modules.

  Copyright (C) 2015, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Guid/AcpiS3Context.h>
#include <IndustryStandard/Q35MchIch9.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/PciLib.h>

#include "SmramInternal.h"

//
// The value of PcdQ35TsegMbytes is saved into this variable at module startup.
//
UINT16  mQ35TsegMbytes;

//
// The value of PcdQ35SmramAtDefaultSmbase is saved into this variable at
// module startup.
//
STATIC BOOLEAN  mQ35SmramAtDefaultSmbase;

/**
  Save PcdQ35TsegMbytes into mQ35TsegMbytes.
**/
VOID
InitQ35TsegMbytes (
  VOID
  )
{
  mQ35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);
}

/**
  Save PcdQ35SmramAtDefaultSmbase into mQ35SmramAtDefaultSmbase.
**/
VOID
InitQ35SmramAtDefaultSmbase (
  VOID
  )
{
  mQ35SmramAtDefaultSmbase = PcdGetBool (PcdQ35SmramAtDefaultSmbase);
}

/**
  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
  OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
  from the D_LCK and T_EN bits.

  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
  the LockState and OpenState fields being up-to-date on entry, and they need
  to restore the same invariant on exit, if they touch the bits in question.

  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
                         locked.
  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
                         iff SMRAM is open.
**/
VOID
GetStates (
  OUT BOOLEAN  *LockState,
  OUT BOOLEAN  *OpenState
  )
{
  UINT8  SmramVal, EsmramcVal;

  SmramVal   = PciRead8 (DRAMC_REGISTER_Q35 (MCH_SMRAM));
  EsmramcVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC));

  *LockState = !!(SmramVal & MCH_SMRAM_D_LCK);
  *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
}

//
// The functions below follow the PEI_SMM_ACCESS_PPI and
// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
// pointers are removed (TSEG doesn't depend on them), and so is the
// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
//
// The LockState and OpenState members that are common to both
// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
// isolation from the rest of the (non-shared) members.
//

EFI_STATUS
SmramAccessOpen (
  OUT BOOLEAN  *LockState,
  OUT BOOLEAN  *OpenState
  )
{
  //
  // Open TSEG by clearing T_EN.
  //
  PciAnd8 (
    DRAMC_REGISTER_Q35 (MCH_ESMRAMC),
    (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff)
    );

  GetStates (LockState, OpenState);
  if (!*OpenState) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
SmramAccessClose (
  OUT BOOLEAN  *LockState,
  OUT BOOLEAN  *OpenState
  )
{
  //
  // Close TSEG by setting T_EN.
  //
  PciOr8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), MCH_ESMRAMC_T_EN);

  GetStates (LockState, OpenState);
  if (*OpenState) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
SmramAccessLock (
  OUT    BOOLEAN  *LockState,
  IN OUT BOOLEAN  *OpenState
  )
{
  if (*OpenState) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Close & lock TSEG by setting T_EN and D_LCK.
  //
  PciOr8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), MCH_ESMRAMC_T_EN);
  PciOr8 (DRAMC_REGISTER_Q35 (MCH_SMRAM), MCH_SMRAM_D_LCK);

  //
  // Close & lock the SMRAM at the default SMBASE, if it exists.
  //
  if (mQ35SmramAtDefaultSmbase) {
    PciWrite8 (
      DRAMC_REGISTER_Q35 (MCH_DEFAULT_SMBASE_CTL),
      MCH_DEFAULT_SMBASE_LCK
      );
  }

  GetStates (LockState, OpenState);
  if (*OpenState || !*LockState) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
SmramAccessGetCapabilities (
  IN BOOLEAN                   LockState,
  IN BOOLEAN                   OpenState,
  IN OUT UINTN                 *SmramMapSize,
  IN OUT EFI_SMRAM_DESCRIPTOR  *SmramMap
  )
{
  UINTN   OriginalSize;
  UINT32  TsegMemoryBaseMb, TsegMemoryBase;
  UINT64  CommonRegionState;
  UINT8   TsegSizeBits;

  OriginalSize  = *SmramMapSize;
  *SmramMapSize = DescIdxCount * sizeof *SmramMap;
  if (OriginalSize < *SmramMapSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Read the TSEG Memory Base register.
  //
  TsegMemoryBaseMb = PciRead32 (DRAMC_REGISTER_Q35 (MCH_TSEGMB));
  TsegMemoryBase   = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20;

  //
  // Precompute the region state bits that will be set for all regions.
  //
  CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) |
                      (LockState ? EFI_SMRAM_LOCKED : 0) |
                      EFI_CACHEABLE;

  //
  // The first region hosts an SMM_S3_RESUME_STATE object. It is located at the
  // start of TSEG. We round up the size to whole pages, and we report it as
  // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
  //
  SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
  SmramMap[DescIdxSmmS3ResumeState].CpuStart      = TsegMemoryBase;
  SmramMap[DescIdxSmmS3ResumeState].PhysicalSize  =
    EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE)));
  SmramMap[DescIdxSmmS3ResumeState].RegionState =
    CommonRegionState | EFI_ALLOCATED;

  //
  // Get the TSEG size bits from the ESMRAMC register.
  //
  TsegSizeBits = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC)) &
                 MCH_ESMRAMC_TSEG_MASK;

  //
  // The second region is the main one, following the first.
  //
  SmramMap[DescIdxMain].PhysicalStart =
    SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
  SmramMap[DescIdxMain].CpuStart     = SmramMap[DescIdxMain].PhysicalStart;
  SmramMap[DescIdxMain].PhysicalSize =
    (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
     TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
     TsegSizeBits == MCH_ESMRAMC_TSEG_1MB ? SIZE_1MB :
     mQ35TsegMbytes * SIZE_1MB) -
    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
  SmramMap[DescIdxMain].RegionState = CommonRegionState;

  return EFI_SUCCESS;
}
