/** @file
*  Main file supporting the SEC Phase for Versatile Express
*
*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
*
*  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 <Uefi.h>
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/PcdLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/PeCoffLib.h>

#include <Pi/PiFirmwareFile.h>
#include <Pi/PiFirmwareVolume.h>

#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))


// Vector Table for Sec Phase
VOID
DebugAgentVectorTable (
  VOID
  );

/**
  Returns the highest bit set of the State field

  @param ErasePolarity   Erase Polarity  as defined by EFI_FVB2_ERASE_POLARITY
                         in the Attributes field.
  @param FfsHeader       Pointer to FFS File Header


  @retval the highest bit in the State field

**/
STATIC
EFI_FFS_FILE_STATE
GetFileState (
  IN UINT8                ErasePolarity,
  IN EFI_FFS_FILE_HEADER  *FfsHeader
  )
{
  EFI_FFS_FILE_STATE  FileState;
  EFI_FFS_FILE_STATE  HighestBit;

  FileState = FfsHeader->State;

  if (ErasePolarity != 0) {
    FileState = (EFI_FFS_FILE_STATE)~FileState;
  }

  HighestBit = 0x80;
  while (HighestBit != 0 && (HighestBit & FileState) == 0) {
    HighestBit >>= 1;
  }

  return HighestBit;
}

/**
  Calculates the checksum of the header of a file.
  The header is a zero byte checksum, so zero means header is good

  @param FfsHeader       Pointer to FFS File Header

  @retval Checksum of the header

**/
STATIC
UINT8
CalculateHeaderChecksum (
  IN EFI_FFS_FILE_HEADER  *FileHeader
  )
{
  UINT8   Sum;

  // Calculate the sum of the header
  Sum = CalculateSum8 ((CONST VOID*)FileHeader,sizeof(EFI_FFS_FILE_HEADER));

  // State field (since this indicates the different state of file).
  Sum = (UINT8)(Sum - FileHeader->State);

  // Checksum field of the file is not part of the header checksum.
  Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);

  return Sum;
}

EFI_STATUS
GetFfsFile (
  IN  EFI_FIRMWARE_VOLUME_HEADER           *FwVolHeader,
  IN  EFI_FV_FILETYPE                      FileType,
  OUT EFI_FFS_FILE_HEADER                  **FileHeader
  )
{
  UINT64                                FvLength;
  UINTN                                 FileOffset;
  EFI_FFS_FILE_HEADER                   *FfsFileHeader;
  UINT8                                 ErasePolarity;
  UINT8                                 FileState;
  UINT32                                FileLength;
  UINT32                                FileOccupiedSize;

  ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);

  FvLength = FwVolHeader->FvLength;
  FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
  FileOffset = FwVolHeader->HeaderLength;

  if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
    ErasePolarity = 1;
  } else {
    ErasePolarity = 0;
  }

  while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
    // Get FileState which is the highest bit of the State
    FileState = GetFileState (ErasePolarity, FfsFileHeader);

    switch (FileState) {

    case EFI_FILE_HEADER_INVALID:
      FileOffset += sizeof(EFI_FFS_FILE_HEADER);
      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
      break;

    case EFI_FILE_DATA_VALID:
    case EFI_FILE_MARKED_FOR_UPDATE:
      if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
        ASSERT (FALSE);
        return EFI_NOT_FOUND;
      }

      if (FfsFileHeader->Type == FileType) {
        *FileHeader = FfsFileHeader;
        return EFI_SUCCESS;
      }

      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);

      FileOffset += FileOccupiedSize;
      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
      break;

    case EFI_FILE_DELETED:
      FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
      FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
      FileOffset += FileOccupiedSize;
      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
      break;

    default:
      return EFI_NOT_FOUND;
    }
  }
  return EFI_NOT_FOUND;
}

EFI_STATUS
GetImageContext (
  IN  EFI_FFS_FILE_HEADER           *FfsHeader,
  OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
  )
{
  EFI_STATUS                              Status;
  UINTN                                   ParsedLength;
  UINTN                                   SectionSize;
  UINTN                                   SectionLength;
  EFI_COMMON_SECTION_HEADER               *Section;
  VOID                                    *EfiImage;
  UINTN                                   ImageAddress;
  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY         *DebugEntry;
  VOID                                    *CodeViewEntryPointer;

  Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
  SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
  SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
  ParsedLength = 0;
  EfiImage = NULL;

  while (ParsedLength < SectionSize) {
    if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
      EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(Section + 1);
      break;
    }

    //
    // Size is 24 bits wide so mask upper 8 bits.
    // SectionLength is adjusted it is 4 byte aligned.
    // Go to the next section
    //
    SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
    SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
    ASSERT (SectionLength != 0);
    ParsedLength += SectionLength;
    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
  }

  if (EfiImage == NULL) {
    return EFI_NOT_FOUND;
  }

  // Initialize the Image Context
  ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
  ImageContext->Handle    = EfiImage;
  ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;

  Status =  PeCoffLoaderGetImageInfo (ImageContext);
  if (!EFI_ERROR(Status) && ((VOID*)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) {
    ImageAddress = ImageContext->ImageAddress;
    if (ImageContext->IsTeImage) {
      ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER*)EfiImage)->StrippedSize;
    }

    DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(ImageAddress + ImageContext->DebugDirectoryEntryRva);
    if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
      CodeViewEntryPointer = (VOID *) (ImageAddress + (UINTN) DebugEntry->RVA);
      switch (* (UINT32 *) CodeViewEntryPointer) {
      case CODEVIEW_SIGNATURE_NB10:
        ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
        break;
      case CODEVIEW_SIGNATURE_RSDS:
        ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
        break;
      case CODEVIEW_SIGNATURE_MTOC:
        ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
        break;
      default:
        break;
      }
    }
  }

  return Status;
}

/**
  Initialize debug agent.

  This function is used to set up debug environment to support source level debugging.
  If certain Debug Agent Library instance has to save some private data in the stack,
  this function must work on the mode that doesn't return to the caller, then
  the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
  function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
  responsible to invoke the passing-in function at the end of InitializeDebugAgent().

  If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by
  passing in the Context to be its parameter.

  If Function() is NULL, Debug Agent Library instance will return after setup debug
  environment.

  @param[in] InitFlag     Init flag is used to decide the initialize process.
  @param[in] Context      Context needed according to InitFlag; it was optional.
  @param[in] Function     Continue function called by debug agent library; it was
                          optional.

**/
VOID
EFIAPI
InitializeDebugAgent (
  IN UINT32                InitFlag,
  IN VOID                  *Context, OPTIONAL
  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL
  )
{
  EFI_STATUS            Status;
  EFI_FFS_FILE_HEADER   *FfsHeader;
  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;

  // Now we've got UART, check the Debug Agent Vector Table
  // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure
  // 'Align=4K' is defined into your FDF for this module.
  ASSERT (((UINTN)DebugAgentVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
  ArmWriteVBar ((UINTN)DebugAgentVectorTable);

  // We use InitFlag to know if DebugAgent has been intialized from
  // Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC)
  // modules
  if (InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) {
    //
    // Get the Sec or PrePeiCore module (defined as SEC type module)
    //
    Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdSecureFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);
    if (!EFI_ERROR(Status)) {
      Status = GetImageContext (FfsHeader,&ImageContext);
      if (!EFI_ERROR(Status)) {
        PeCoffLoaderRelocateImageExtraAction (&ImageContext);
      }
    }
  } else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {
    //
    // Get the PrePi or PrePeiCore module (defined as SEC type module)
    //
    Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);
    if (!EFI_ERROR(Status)) {
      Status = GetImageContext (FfsHeader,&ImageContext);
      if (!EFI_ERROR(Status)) {
        PeCoffLoaderRelocateImageExtraAction (&ImageContext);
      }
    }

    //
    // Get the PeiCore module (defined as PEI_CORE type module)
    //
    Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_PEI_CORE, &FfsHeader);
    if (!EFI_ERROR(Status)) {
      Status = GetImageContext (FfsHeader,&ImageContext);
      if (!EFI_ERROR(Status)) {
        PeCoffLoaderRelocateImageExtraAction (&ImageContext);
      }
    }
  }
}

/**
  Enable/Disable the interrupt of debug timer and return the interrupt state
  prior to the operation.

  If EnableStatus is TRUE, enable the interrupt of debug timer.
  If EnableStatus is FALSE, disable the interrupt of debug timer.

  @param[in] EnableStatus    Enable/Disable.

  @return FALSE always.

**/
BOOLEAN
EFIAPI
SaveAndSetDebugTimerInterrupt (
  IN BOOLEAN                EnableStatus
  )
{
  return FALSE;
}

