/** @file
  Implementation of MicrocodeLib.

  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi/UefiBaseType.h>
#include <Register/Intel/Cpuid.h>
#include <Register/Intel/ArchitecturalMsr.h>
#include <Register/Intel/Microcode.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Ppi/ShadowMicrocode.h>

/**
  Get microcode update signature of currently loaded microcode update.

  @return  Microcode signature.
**/
UINT32
EFIAPI
GetProcessorMicrocodeSignature (
  VOID
  )
{
  MSR_IA32_BIOS_SIGN_ID_REGISTER  BiosSignIdMsr;

  AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
  BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
  return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
}

/**
  Get the processor signature and platform ID for current processor.

  @param MicrocodeCpuId  Return the processor signature and platform ID.
**/
VOID
EFIAPI
GetProcessorMicrocodeCpuId (
  EDKII_PEI_MICROCODE_CPU_ID  *MicrocodeCpuId
  )
{
  MSR_IA32_PLATFORM_ID_REGISTER  PlatformIdMsr;

  ASSERT (MicrocodeCpuId != NULL);

  PlatformIdMsr.Uint64       = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
  MicrocodeCpuId->PlatformId = (UINT8)PlatformIdMsr.Bits.PlatformId;
  AsmCpuid (CPUID_VERSION_INFO, &MicrocodeCpuId->ProcessorSignature, NULL, NULL, NULL);
}

/**
  Return the total size of the microcode entry.

  Logic follows pseudo code in SDM as below:

     N = 512
     If (Update.DataSize != 00000000H)
       N = Update.TotalSize / 4

  If Microcode is NULL, then ASSERT.

  @param Microcode  Pointer to the microcode entry.

  @return The microcode total size.
**/
UINT32
EFIAPI
GetMicrocodeLength (
  IN CPU_MICROCODE_HEADER  *Microcode
  )
{
  UINT32  TotalSize;

  ASSERT (Microcode != NULL);

  TotalSize = 2048;
  if (Microcode->DataSize != 0) {
    TotalSize = Microcode->TotalSize;
  }

  return TotalSize;
}

/**
  Load the microcode to the processor.

  If Microcode is NULL, then ASSERT.

  @param Microcode  Pointer to the microcode entry.
**/
VOID
EFIAPI
LoadMicrocode (
  IN CPU_MICROCODE_HEADER  *Microcode
  )
{
  ASSERT (Microcode != NULL);

  AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, (UINT64)(UINTN)(Microcode + 1));
}

/**
  Determine if a microcode patch matchs the specific processor signature and flag.

  @param[in]  ProcessorSignature    The processor signature field value in a
                                    microcode patch.
  @param[in]  ProcessorFlags        The processor flags field value in a
                                    microcode patch.
  @param[in]  MicrocodeCpuId        A pointer to an array of EDKII_PEI_MICROCODE_CPU_ID
                                    structures.
  @param[in]  MicrocodeCpuIdCount   Number of elements in MicrocodeCpuId array.

  @retval TRUE     The specified microcode patch matches to one of the MicrocodeCpuId.
  @retval FALSE    The specified microcode patch doesn't match to any of the MicrocodeCpuId.
**/
BOOLEAN
IsProcessorMatchedMicrocode (
  IN UINT32                      ProcessorSignature,
  IN UINT32                      ProcessorFlags,
  IN EDKII_PEI_MICROCODE_CPU_ID  *MicrocodeCpuId,
  IN UINTN                       MicrocodeCpuIdCount
  )
{
  UINTN  Index;

  if (MicrocodeCpuIdCount == 0) {
    return TRUE;
  }

  for (Index = 0; Index < MicrocodeCpuIdCount; Index++) {
    if ((ProcessorSignature == MicrocodeCpuId[Index].ProcessorSignature) &&
        ((ProcessorFlags & (1 << MicrocodeCpuId[Index].PlatformId)) != 0))
    {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Detect whether specified processor can find matching microcode patch and load it.

  Microcode format is as below:
  +----------------------------------------+-------------------------------------------------+
  |          CPU_MICROCODE_HEADER          |                                                 |
  +----------------------------------------+                                                 V
  |              Update Data               |                                               CPU_MICROCODE_HEADER.Checksum
  +----------------------------------------+-------+                                         ^
  |  CPU_MICROCODE_EXTENDED_TABLE_HEADER   |       |                                         |
  +----------------------------------------+       V                                         |
  |      CPU_MICROCODE_EXTENDED_TABLE[0]   |  CPU_MICROCODE_EXTENDED_TABLE_HEADER.Checksum   |
  |      CPU_MICROCODE_EXTENDED_TABLE[1]   |       ^                                         |
  |                   ...                  |       |                                         |
  +----------------------------------------+-------+-----------------------------------------+

  There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format.
  The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount
  of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure.

  If Microcode is NULL, then ASSERT.

  @param Microcode            Pointer to a microcode entry.
  @param MicrocodeLength      The total length of the microcode entry.
  @param MinimumRevision      The microcode whose revision <= MinimumRevision is treated as invalid.
                              Caller can supply value get from GetProcessorMicrocodeSignature() to check
                              whether the microcode is newer than loaded one.
                              Caller can supply 0 to treat any revision (except 0) microcode as valid.
  @param MicrocodeCpuIds      Pointer to an array of processor signature and platform ID that represents
                              a set of processors.
                              Caller can supply zero-element array to skip the processor signature and
                              platform ID check.
  @param MicrocodeCpuIdCount  The number of elements in MicrocodeCpuIds.
  @param VerifyChecksum       FALSE to skip all the checksum verifications.

  @retval TRUE  The microcode is valid.
  @retval FALSE The microcode is invalid.
**/
BOOLEAN
EFIAPI
IsValidMicrocode (
  IN CPU_MICROCODE_HEADER        *Microcode,
  IN UINTN                       MicrocodeLength,
  IN UINT32                      MinimumRevision,
  IN EDKII_PEI_MICROCODE_CPU_ID  *MicrocodeCpuIds,
  IN UINTN                       MicrocodeCpuIdCount,
  IN BOOLEAN                     VerifyChecksum
  )
{
  UINTN                                Index;
  UINT32                               DataSize;
  UINT32                               TotalSize;
  CPU_MICROCODE_EXTENDED_TABLE         *ExtendedTable;
  CPU_MICROCODE_EXTENDED_TABLE_HEADER  *ExtendedTableHeader;
  UINT32                               ExtendedTableLength;
  UINT32                               Sum32;
  BOOLEAN                              Match;

  ASSERT (Microcode != NULL);

  //
  // It's invalid when:
  //   the input microcode buffer is so small that even cannot contain the header.
  //   the input microcode buffer is so large that exceeds MAX_ADDRESS.
  //
  if ((MicrocodeLength < sizeof (CPU_MICROCODE_HEADER)) || (MicrocodeLength > (MAX_ADDRESS - (UINTN)Microcode))) {
    return FALSE;
  }

  //
  // Per SDM, HeaderVersion and LoaderRevision should both be 1.
  //
  if ((Microcode->HeaderVersion != 1) || (Microcode->LoaderRevision != 1)) {
    return FALSE;
  }

  //
  // The microcode revision should be larger than the minimum revision.
  //
  if (Microcode->UpdateRevision <= MinimumRevision) {
    return FALSE;
  }

  DataSize = Microcode->DataSize;
  if (DataSize == 0) {
    DataSize = 2000;
  }

  //
  // Per SDM, DataSize should be multiple of DWORDs.
  //
  if ((DataSize % 4) != 0) {
    return FALSE;
  }

  TotalSize = GetMicrocodeLength (Microcode);

  //
  // Check whether the whole microcode is within the buffer.
  // TotalSize should be multiple of 1024.
  //
  if (((TotalSize % SIZE_1KB) != 0) || (TotalSize > MicrocodeLength)) {
    return FALSE;
  }

  //
  // The summation of all DWORDs in microcode should be zero.
  //
  if (VerifyChecksum && (CalculateSum32 ((UINT32 *)Microcode, TotalSize) != 0)) {
    return FALSE;
  }

  Sum32 = Microcode->ProcessorSignature.Uint32 + Microcode->ProcessorFlags + Microcode->Checksum;

  //
  // Check the processor signature and platform ID in the primary header.
  //
  Match = IsProcessorMatchedMicrocode (
            Microcode->ProcessorSignature.Uint32,
            Microcode->ProcessorFlags,
            MicrocodeCpuIds,
            MicrocodeCpuIdCount
            );
  if (Match) {
    return TRUE;
  }

  ExtendedTableLength = TotalSize - (DataSize + sizeof (CPU_MICROCODE_HEADER));
  if ((ExtendedTableLength < sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)) || ((ExtendedTableLength % 4) != 0)) {
    return FALSE;
  }

  //
  // Extended Table exist, check if the CPU in support list
  //
  ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINTN)(Microcode + 1) + DataSize);
  if (ExtendedTableHeader->ExtendedSignatureCount > MAX_UINT32 / sizeof (CPU_MICROCODE_EXTENDED_TABLE)) {
    return FALSE;
  }

  if (ExtendedTableHeader->ExtendedSignatureCount * sizeof (CPU_MICROCODE_EXTENDED_TABLE)
      > ExtendedTableLength - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER))
  {
    return FALSE;
  }

  //
  // Check the extended table checksum
  //
  if (VerifyChecksum && (CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength) != 0)) {
    return FALSE;
  }

  ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
  for (Index = 0; Index < ExtendedTableHeader->ExtendedSignatureCount; Index++) {
    if (VerifyChecksum &&
        (ExtendedTable[Index].ProcessorSignature.Uint32 + ExtendedTable[Index].ProcessorFlag
         + ExtendedTable[Index].Checksum != Sum32))
    {
      //
      // The extended table entry is valid when the summation of Processor Signature, Processor Flags
      // and Checksum equal to the coresponding summation from primary header. Because:
      //    CalculateSum32 (Header + Update Binary) == 0
      //    CalculateSum32 (Header + Update Binary)
      //        - (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)
      //        + (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum) == 0
      // So,
      //    (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)
      //     == (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum)
      //
      continue;
    }

    Match = IsProcessorMatchedMicrocode (
              ExtendedTable[Index].ProcessorSignature.Uint32,
              ExtendedTable[Index].ProcessorFlag,
              MicrocodeCpuIds,
              MicrocodeCpuIdCount
              );
    if (Match) {
      return TRUE;
    }
  }

  return FALSE;
}
