/** @file
  Implementation of loading microcode on processors.

  Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "MpLib.h"

/**
  Detect whether specified processor can find matching microcode patch and load it.

  @param[in]  CpuMpData        The pointer to CPU MP Data structure.
  @param[in]  ProcessorNumber  The handle number of the processor. The range is
                               from 0 to the total number of logical processors
                               minus 1.
**/
VOID
MicrocodeDetect (
  IN CPU_MP_DATA  *CpuMpData,
  IN UINTN        ProcessorNumber
  )
{
  CPU_MICROCODE_HEADER        *Microcode;
  UINTN                       MicrocodeEnd;
  CPU_AP_DATA                 *BspData;
  UINT32                      LatestRevision;
  CPU_MICROCODE_HEADER        *LatestMicrocode;
  UINT32                      ThreadId;
  EDKII_PEI_MICROCODE_CPU_ID  MicrocodeCpuId;

  if (CpuMpData->MicrocodePatchRegionSize == 0) {
    //
    // There is no microcode patches
    //
    return;
  }

  GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId);
  if (ThreadId != 0) {
    //
    // Skip loading microcode if it is not the first thread in one core.
    //
    return;
  }

  GetProcessorMicrocodeCpuId (&MicrocodeCpuId);

  if (ProcessorNumber != (UINTN)CpuMpData->BspNumber) {
    //
    // Direct use microcode of BSP if AP is the same as BSP.
    // Assume BSP calls this routine() before AP.
    //
    BspData = &(CpuMpData->CpuData[CpuMpData->BspNumber]);
    if ((BspData->ProcessorSignature == MicrocodeCpuId.ProcessorSignature) &&
        (BspData->PlatformId == MicrocodeCpuId.PlatformId) &&
        (BspData->MicrocodeEntryAddr != 0))
    {
      LatestMicrocode = (CPU_MICROCODE_HEADER *)(UINTN)BspData->MicrocodeEntryAddr;
      LatestRevision  = LatestMicrocode->UpdateRevision;
      goto LoadMicrocode;
    }
  }

  //
  // BSP or AP which is different from BSP runs here
  // Use 0 as the starting revision to search for microcode because MicrocodePatchInfo HOB needs
  // the latest microcode location even it's loaded to the processor.
  //
  LatestRevision  = 0;
  LatestMicrocode = NULL;
  Microcode       = (CPU_MICROCODE_HEADER *)(UINTN)CpuMpData->MicrocodePatchAddress;
  MicrocodeEnd    = (UINTN)Microcode + (UINTN)CpuMpData->MicrocodePatchRegionSize;

  do {
    if (!IsValidMicrocode (Microcode, MicrocodeEnd - (UINTN)Microcode, LatestRevision, &MicrocodeCpuId, 1, TRUE)) {
      //
      // It is the padding data between the microcode patches for microcode patches alignment.
      // Because the microcode patch is the multiple of 1-KByte, the padding data should not
      // exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode
      // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
      // find the next possible microcode patch header.
      //
      Microcode = (CPU_MICROCODE_HEADER *)((UINTN)Microcode + SIZE_1KB);
      continue;
    }

    LatestMicrocode = Microcode;
    LatestRevision  = LatestMicrocode->UpdateRevision;

    Microcode = (CPU_MICROCODE_HEADER *)(((UINTN)Microcode) + GetMicrocodeLength (Microcode));
  } while ((UINTN)Microcode < MicrocodeEnd);

LoadMicrocode:
  if (LatestRevision != 0) {
    //
    // Save the detected microcode patch entry address (including the microcode
    // patch header) for each processor even it's the same as the loaded one.
    // It will be used when building the microcode patch cache HOB.
    //
    CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr = (UINTN)LatestMicrocode;
  }

  if (LatestRevision > GetProcessorMicrocodeSignature ()) {
    //
    // BIOS only authenticate updates that contain a numerically larger revision
    // than the currently loaded revision, where Current Signature < New Update
    // Revision. A processor with no loaded update is considered to have a
    // revision equal to zero.
    //
    LoadMicrocode (LatestMicrocode);
  }

  //
  // It's possible that the microcode fails to load. Just capture the CPU microcode revision after loading.
  //
  CpuMpData->CpuData[ProcessorNumber].MicrocodeRevision = GetProcessorMicrocodeSignature ();
}

/**
  Actual worker function that shadows the required microcode patches into memory.

  @param[in, out]  CpuMpData        The pointer to CPU MP Data structure.
  @param[in]       Patches          The pointer to an array of information on
                                    the microcode patches that will be loaded
                                    into memory.
  @param[in]       PatchCount       The number of microcode patches that will
                                    be loaded into memory.
  @param[in]       TotalLoadSize    The total size of all the microcode patches
                                    to be loaded.
**/
VOID
ShadowMicrocodePatchWorker (
  IN OUT CPU_MP_DATA           *CpuMpData,
  IN     MICROCODE_PATCH_INFO  *Patches,
  IN     UINTN                 PatchCount,
  IN     UINTN                 TotalLoadSize
  )
{
  UINTN  Index;
  VOID   *MicrocodePatchInRam;
  UINT8  *Walker;

  ASSERT ((Patches != NULL) && (PatchCount != 0));

  MicrocodePatchInRam = AllocatePages (EFI_SIZE_TO_PAGES (TotalLoadSize));
  if (MicrocodePatchInRam == NULL) {
    return;
  }

  //
  // Load all the required microcode patches into memory
  //
  for (Walker = MicrocodePatchInRam, Index = 0; Index < PatchCount; Index++) {
    CopyMem (
      Walker,
      (VOID *)Patches[Index].Address,
      Patches[Index].Size
      );
    Walker += Patches[Index].Size;
  }

  //
  // Update the microcode patch related fields in CpuMpData
  //
  CpuMpData->MicrocodePatchAddress    = (UINTN)MicrocodePatchInRam;
  CpuMpData->MicrocodePatchRegionSize = TotalLoadSize;

  DEBUG ((
    DEBUG_INFO,
    "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n",
    __func__,
    CpuMpData->MicrocodePatchAddress,
    CpuMpData->MicrocodePatchRegionSize
    ));

  return;
}

/**
  Shadow the required microcode patches data into memory according to PCD
  PcdCpuMicrocodePatchAddress and PcdCpuMicrocodePatchRegionSize.

  @param[in, out]  CpuMpData    The pointer to CPU MP Data structure.
**/
VOID
ShadowMicrocodePatchByPcd (
  IN OUT CPU_MP_DATA  *CpuMpData
  )
{
  UINTN                       Index;
  CPU_MICROCODE_HEADER        *MicrocodeEntryPoint;
  UINTN                       MicrocodeEnd;
  UINTN                       TotalSize;
  MICROCODE_PATCH_INFO        *PatchInfoBuffer;
  UINTN                       MaxPatchNumber;
  UINTN                       PatchCount;
  UINTN                       TotalLoadSize;
  EDKII_PEI_MICROCODE_CPU_ID  *MicrocodeCpuIds;
  BOOLEAN                     Valid;

  //
  // Initialize the microcode patch related fields in CpuMpData as the values
  // specified by the PCD pair. If the microcode patches are loaded into memory,
  // these fields will be updated.
  //
  CpuMpData->MicrocodePatchAddress    = PcdGet64 (PcdCpuMicrocodePatchAddress);
  CpuMpData->MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);

  MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(UINTN)CpuMpData->MicrocodePatchAddress;
  MicrocodeEnd        = (UINTN)MicrocodeEntryPoint +
                        (UINTN)CpuMpData->MicrocodePatchRegionSize;
  if ((MicrocodeEntryPoint == NULL) || ((UINTN)MicrocodeEntryPoint == MicrocodeEnd)) {
    //
    // There is no microcode patches
    //
    return;
  }

  PatchCount      = 0;
  MaxPatchNumber  = DEFAULT_MAX_MICROCODE_PATCH_NUM;
  TotalLoadSize   = 0;
  PatchInfoBuffer = AllocatePool (MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO));
  if (PatchInfoBuffer == NULL) {
    return;
  }

  MicrocodeCpuIds = AllocatePages (
                      EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDKII_PEI_MICROCODE_CPU_ID))
                      );
  if (MicrocodeCpuIds == NULL) {
    FreePool (PatchInfoBuffer);
    return;
  }

  for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
    MicrocodeCpuIds[Index].PlatformId         = CpuMpData->CpuData[Index].PlatformId;
    MicrocodeCpuIds[Index].ProcessorSignature = CpuMpData->CpuData[Index].ProcessorSignature;
  }

  //
  // Process the header of each microcode patch within the region.
  // The purpose is to decide which microcode patch(es) will be loaded into memory.
  // Microcode checksum is not verified because it's slow when performing on flash.
  //
  do {
    Valid = IsValidMicrocode (
              MicrocodeEntryPoint,
              MicrocodeEnd - (UINTN)MicrocodeEntryPoint,
              0,
              MicrocodeCpuIds,
              CpuMpData->CpuCount,
              FALSE
              );
    if (!Valid) {
      //
      // Padding data between the microcode patches, skip 1KB to check next entry.
      //
      MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(((UINTN)MicrocodeEntryPoint) + SIZE_1KB);
      continue;
    }

    PatchCount++;
    if (PatchCount > MaxPatchNumber) {
      //
      // Current 'PatchInfoBuffer' cannot hold the information, double the size
      // and allocate a new buffer.
      //
      if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)) {
        //
        // Overflow check for MaxPatchNumber
        //
        goto OnExit;
      }

      PatchInfoBuffer = ReallocatePool (
                          MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO),
                          2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO),
                          PatchInfoBuffer
                          );
      if (PatchInfoBuffer == NULL) {
        goto OnExit;
      }

      MaxPatchNumber = MaxPatchNumber * 2;
    }

    TotalSize = GetMicrocodeLength (MicrocodeEntryPoint);

    //
    // Store the information of this microcode patch
    //
    PatchInfoBuffer[PatchCount - 1].Address = (UINTN)MicrocodeEntryPoint;
    PatchInfoBuffer[PatchCount - 1].Size    = TotalSize;
    TotalLoadSize                          += TotalSize;

    //
    // Process the next microcode patch
    //
    MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)((UINTN)MicrocodeEntryPoint + TotalSize);
  } while ((UINTN)MicrocodeEntryPoint < MicrocodeEnd);

  if (PatchCount != 0) {
    DEBUG ((
      DEBUG_INFO,
      "%a: 0x%x microcode patches will be loaded into memory, with size 0x%x.\n",
      __func__,
      PatchCount,
      TotalLoadSize
      ));

    ShadowMicrocodePatchWorker (CpuMpData, PatchInfoBuffer, PatchCount, TotalLoadSize);
  }

OnExit:
  if (PatchInfoBuffer != NULL) {
    FreePool (PatchInfoBuffer);
  }

  FreePages (MicrocodeCpuIds, EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDKII_PEI_MICROCODE_CPU_ID)));
}

/**
  Shadow the required microcode patches data into memory.

  @param[in, out]  CpuMpData    The pointer to CPU MP Data structure.
**/
VOID
ShadowMicrocodeUpdatePatch (
  IN OUT CPU_MP_DATA  *CpuMpData
  )
{
  EFI_STATUS  Status;

  Status = PlatformShadowMicrocode (CpuMpData);
  if (EFI_ERROR (Status)) {
    ShadowMicrocodePatchByPcd (CpuMpData);
  }
}

/**
  Get the cached microcode patch base address and size from the microcode patch
  information cache HOB.

  @param[out] Address       Base address of the microcode patches data.
                            It will be updated if the microcode patch
                            information cache HOB is found.
  @param[out] RegionSize    Size of the microcode patches data.
                            It will be updated if the microcode patch
                            information cache HOB is found.

  @retval  TRUE     The microcode patch information cache HOB is found.
  @retval  FALSE    The microcode patch information cache HOB is not found.

**/
BOOLEAN
GetMicrocodePatchInfoFromHob (
  UINT64  *Address,
  UINT64  *RegionSize
  )
{
  EFI_HOB_GUID_TYPE          *GuidHob;
  EDKII_MICROCODE_PATCH_HOB  *MicrocodePathHob;

  GuidHob = GetFirstGuidHob (&gEdkiiMicrocodePatchHobGuid);
  if (GuidHob == NULL) {
    DEBUG ((DEBUG_INFO, "%a: Microcode patch cache HOB is not found.\n", __func__));
    return FALSE;
  }

  MicrocodePathHob = GET_GUID_HOB_DATA (GuidHob);

  *Address    = MicrocodePathHob->MicrocodePatchAddress;
  *RegionSize = MicrocodePathHob->MicrocodePatchRegionSize;

  DEBUG ((
    DEBUG_INFO,
    "%a: MicrocodeBase = 0x%lx, MicrocodeSize = 0x%lx\n",
    __func__,
    *Address,
    *RegionSize
    ));

  return TRUE;
}
