/** @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 Library 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 initialized 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;
}

