/** @file
  Basic paging support for the CPU to enable Stack Guard.

Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Register/Intel/Cpuid.h>
#include <Register/Intel/Msr.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/CpuLib.h>
#include <Library/BaseLib.h>
#include <Guid/MigratedFvInfo.h>

#include "CpuMpPei.h"
#define PAGING_4K_ADDRESS_MASK_64  0x000FFFFFFFFFF000ull

EFI_PEI_NOTIFY_DESCRIPTOR  mPostMemNotifyList[] = {
  {
    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
    &gEfiPeiMemoryDiscoveredPpiGuid,
    MemoryDiscoveredPpiNotifyCallback
  }
};

/**
  The function will check if IA32 PAE is supported.

  @retval TRUE      IA32 PAE is supported.
  @retval FALSE     IA32 PAE is not supported.

**/
BOOLEAN
IsIa32PaeSupported (
  VOID
  )
{
  UINT32                  RegEax;
  CPUID_VERSION_INFO_EDX  RegEdx;

  AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL);
  if (RegEax >= CPUID_VERSION_INFO) {
    AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx.Uint32);
    if (RegEdx.Bits.PAE != 0) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  This API provides a way to allocate memory for page table.

  @param  Pages                 The number of 4 KB pages to allocate.

  @return A pointer to the allocated buffer or NULL if allocation fails.

**/
VOID *
AllocatePageTableMemory (
  IN UINTN  Pages
  )
{
  VOID  *Address;

  Address = AllocatePages (Pages);
  if (Address != NULL) {
    ZeroMem (Address, EFI_PAGES_TO_SIZE (Pages));
  }

  return Address;
}

/**
  This function modifies the page attributes for the memory region specified
  by BaseAddress and Length to not present.

  Caller should make sure BaseAddress and Length is at page boundary.

  @param[in]   BaseAddress      Start address of a memory region.
  @param[in]   Length           Size in bytes of the memory region.

  @retval RETURN_SUCCESS            The memory region is changed to not present.
  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify
                                    the attributes.
  @retval RETURN_UNSUPPORTED        Cannot modify the attributes of given memory.

**/
RETURN_STATUS
ConvertMemoryPageToNotPresent (
  IN  PHYSICAL_ADDRESS  BaseAddress,
  IN  UINT64            Length
  )
{
  EFI_STATUS                  Status;
  UINTN                       PageTable;
  EFI_PHYSICAL_ADDRESS        Buffer;
  UINTN                       BufferSize;
  IA32_MAP_ATTRIBUTE          MapAttribute;
  IA32_MAP_ATTRIBUTE          MapMask;
  PAGING_MODE                 PagingMode;
  IA32_CR4                    Cr4;
  BOOLEAN                     Page5LevelSupport;
  UINT32                      RegEax;
  BOOLEAN                     Page1GSupport;
  CPUID_EXTENDED_CPU_SIG_EDX  RegEdx;

  if (sizeof (UINTN) == sizeof (UINT64)) {
    //
    // Check Page5Level Support or not.
    //
    Cr4.UintN         = AsmReadCr4 ();
    Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);

    //
    // Check Page1G Support or not.
    //
    Page1GSupport = FALSE;
    AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
    if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
      AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
      if (RegEdx.Bits.Page1GB != 0) {
        Page1GSupport = TRUE;
      }
    }

    //
    // Decide Paging Mode according Page5LevelSupport & Page1GSupport.
    //
    if (Page5LevelSupport) {
      PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
    } else {
      PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
    }
  } else {
    PagingMode = PagingPae;
  }

  MapAttribute.Uint64  = 0;
  MapMask.Uint64       = 0;
  MapMask.Bits.Present = 1;
  PageTable            = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
  BufferSize           = 0;

  //
  // Get required buffer size for the pagetable that will be created.
  //
  Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Allocate required Buffer.
    //
    Status = PeiServicesAllocatePages (
               EfiBootServicesData,
               EFI_SIZE_TO_PAGES (BufferSize),
               &Buffer
               );
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL);
  }

  ASSERT_EFI_ERROR (Status);
  AsmWriteCr3 (PageTable);
  return Status;
}

/**
  Enable PAE Page Table.

  @retval   EFI_SUCCESS           The PAE Page Table was enabled successfully.
  @retval   EFI_OUT_OF_RESOURCES  The PAE Page Table could not be enabled due to lack of available memory.

**/
EFI_STATUS
EnablePaePageTable (
  VOID
  )
{
  EFI_STATUS  Status;

  UINTN               PageTable;
  VOID                *Buffer;
  UINTN               BufferSize;
  IA32_MAP_ATTRIBUTE  MapAttribute;
  IA32_MAP_ATTRIBUTE  MapMask;

  PageTable                   = 0;
  Buffer                      = NULL;
  BufferSize                  = 0;
  MapAttribute.Uint64         = 0;
  MapMask.Uint64              = MAX_UINT64;
  MapAttribute.Bits.Present   = 1;
  MapAttribute.Bits.ReadWrite = 1;

  //
  // 1:1 map 4GB in 32bit mode
  //
  Status = PageTableMap (&PageTable, PagingPae, 0, &BufferSize, 0, SIZE_4GB, &MapAttribute, &MapMask, NULL);
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return Status;
  }

  //
  // Allocate required Buffer.
  //
  Buffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (BufferSize));
  ASSERT (Buffer != NULL);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = PageTableMap (&PageTable, PagingPae, Buffer, &BufferSize, 0, SIZE_4GB, &MapAttribute, &MapMask, NULL);
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status) || (PageTable == 0)) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Write the Pagetable to CR3.
  //
  AsmWriteCr3 (PageTable);

  //
  // Enable CR4.PAE
  //
  AsmWriteCr4 (AsmReadCr4 () | BIT5);

  //
  // Enable CR0.PG
  //
  AsmWriteCr0 (AsmReadCr0 () | BIT31);

  DEBUG ((
    DEBUG_INFO,
    "EnablePaePageTable: Created PageTable = 0x%x, BufferSize = %x\n",
    PageTable,
    BufferSize
    ));

  return Status;
}

/**
  Get the base address of current AP's stack.

  This function is called in AP's context and assumes that whole calling stacks
  (till this function) consumed by AP's wakeup procedure will not exceed 4KB.

  PcdCpuApStackSize must be configured with value taking the Guard page into
  account.

  @param[in,out] Buffer  The pointer to private data buffer.

**/
VOID
EFIAPI
GetStackBase (
  IN OUT VOID  *Buffer
  )
{
  EFI_PHYSICAL_ADDRESS  StackBase;

  StackBase  = (EFI_PHYSICAL_ADDRESS)(UINTN)&StackBase;
  StackBase += BASE_4KB;
  StackBase &= ~((EFI_PHYSICAL_ADDRESS)BASE_4KB - 1);
  StackBase -= PcdGet32 (PcdCpuApStackSize);

  *(EFI_PHYSICAL_ADDRESS *)Buffer = StackBase;
}

/**
  Setup stack Guard page at the stack base of each processor. BSP and APs have
  different way to get stack base address.

**/
VOID
SetupStackGuardPage (
  VOID
  )
{
  EFI_PEI_HOB_POINTERS  Hob;
  EFI_PHYSICAL_ADDRESS  StackBase;
  UINTN                 NumberOfProcessors;
  UINTN                 Bsp;
  UINTN                 Index;
  EFI_STATUS            Status;

  //
  // One extra page at the bottom of the stack is needed for Guard page.
  //
  if (PcdGet32 (PcdCpuApStackSize) <= EFI_PAGE_SIZE) {
    DEBUG ((DEBUG_ERROR, "PcdCpuApStackSize is not big enough for Stack Guard!\n"));
    ASSERT (FALSE);
  }

  Status = MpInitLibGetNumberOfProcessors (&NumberOfProcessors, NULL);
  ASSERT_EFI_ERROR (Status);

  if (EFI_ERROR (Status)) {
    NumberOfProcessors = 1;
  }

  MpInitLibWhoAmI (&Bsp);
  for (Index = 0; Index < NumberOfProcessors; ++Index) {
    StackBase = 0;

    if (Index == Bsp) {
      Hob.Raw = GetHobList ();
      while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
        if (CompareGuid (
              &gEfiHobMemoryAllocStackGuid,
              &(Hob.MemoryAllocationStack->AllocDescriptor.Name)
              ))
        {
          StackBase = Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress;
          break;
        }

        Hob.Raw = GET_NEXT_HOB (Hob);
      }
    } else {
      //
      // Ask AP to return is stack base address.
      //
      MpInitLibStartupThisAP (GetStackBase, Index, NULL, 0, (VOID *)&StackBase, NULL);
    }

    ASSERT (StackBase != 0);
    //
    // Set Guard page at stack base address.
    //
    ConvertMemoryPageToNotPresent (StackBase, EFI_PAGE_SIZE);
    DEBUG ((
      DEBUG_INFO,
      "Stack Guard set at %lx [cpu%lu]!\n",
      (UINT64)StackBase,
      (UINT64)Index
      ));
  }

  //
  // Publish the changes of page table.
  //
  CpuFlushTlb ();
}

/**
  Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.

  Doing this in the memory-discovered callback is to make sure the Stack Guard
  feature to cover as most PEI code as possible.

  @param[in] PeiServices          General purpose services available to every PEIM.
  @param[in] NotifyDescriptor     The notification structure this PEIM registered on install.
  @param[in] Ppi                  The memory discovered PPI.  Not used.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval others                  There's error in MP initialization.
**/
EFI_STATUS
EFIAPI
MemoryDiscoveredPpiNotifyCallback (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS              Status;
  BOOLEAN                 InitStackGuard;
  EDKII_MIGRATED_FV_INFO  *MigratedFvInfo;
  EFI_PEI_HOB_POINTERS    Hob;
  IA32_CR0                Cr0;

  //
  // Paging must be setup first. Otherwise the exception TSS setup during MP
  // initialization later will not contain paging information and then fail
  // the task switch (for the sake of stack switch).
  //
  InitStackGuard = FALSE;
  Hob.Raw        = NULL;
  if (IsIa32PaeSupported ()) {
    Hob.Raw        = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
    InitStackGuard = PcdGetBool (PcdCpuStackGuard);
  }

  //
  // Some security features depend on the page table enabling. So, here
  // is to enable paging if it is not enabled (only in 32bit mode).
  //
  Cr0.UintN = AsmReadCr0 ();
  if ((Cr0.Bits.PG == 0) && (InitStackGuard || (Hob.Raw != NULL))) {
    ASSERT (sizeof (UINTN) == sizeof (UINT32));

    Status = EnablePaePageTable ();
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "MemoryDiscoveredPpiNotifyCallback: Failed to enable PAE page table: %r.\n", Status));
      CpuDeadLoop ();
    }
  }

  Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices);
  ASSERT_EFI_ERROR (Status);

  if (InitStackGuard) {
    SetupStackGuardPage ();
  }

  while (Hob.Raw != NULL) {
    MigratedFvInfo = GET_GUID_HOB_DATA (Hob);

    //
    // Enable #PF exception, so if the code access SPI after disable NEM, it will generate
    // the exception to avoid potential vulnerability.
    //
    ConvertMemoryPageToNotPresent (MigratedFvInfo->FvOrgBase, MigratedFvInfo->FvLength);

    Hob.Raw = GET_NEXT_HOB (Hob);
    Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
  }

  CpuFlushTlb ();

  return Status;
}
