/** @file
  PE/Coff Extra Action library instances.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PeCoffExtraActionLib.h>

/**
  Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7.

  It assumes that DebugAgent will set both Lx and Gx bit when setting up the hardware breakpoint.


  @param  RegisterIndex  Index of Dr register. The value range is from 0 to 3.
  @param  Dr7            Value of Dr7 register.

  @return TRUE   The hardware breakpoint specified in the Drx is enabled.
  @return FALSE  The hardware breakpoint specified in the Drx is disabled.

**/
BOOLEAN
IsDrxEnabled (
  IN  UINT8  RegisterIndex,
  IN  UINTN  Dr7
  )
{
  return (BOOLEAN) (((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1));
}

/**
  Common routine to report the PE/COFF image loading/relocating or unloading event.

  If ImageContext is NULL, then ASSERT().

  @param  ImageContext  Pointer to the image context structure that describes the
                        PE/COFF image.
  @param  Signature     IMAGE_LOAD_SIGNATURE or IMAGE_UNLOAD_SIGNATURE.

**/
VOID
PeCoffLoaderExtraActionCommon (
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
  IN     UINTN                         Signature
  )
{
  BOOLEAN                    InterruptState;
  UINTN                      Dr0;
  UINTN                      Dr1;
  UINTN                      Dr2;
  UINTN                      Dr3;
  UINTN                      Dr7;
  UINTN                      Cr4;
  UINTN                      NewDr7;
  UINT8                      LoadImageMethod;
  UINT8                      DebugAgentStatus;
  IA32_DESCRIPTOR            IdtDescriptor;
  IA32_IDT_GATE_DESCRIPTOR   OriginalIdtEntry;
  BOOLEAN                    IdtEntryHooked;
  UINT32                     RegEdx;

  ASSERT (ImageContext != NULL);

  if (ImageContext->PdbPointer != NULL) {
    DEBUG((EFI_D_ERROR, "    PDB = %a\n", ImageContext->PdbPointer));
  }

  //
  // Disable interrupts and save the current interrupt state
  //
  InterruptState = SaveAndDisableInterrupts ();

  IdtEntryHooked  = FALSE;
  LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
  if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
    //
    // If the CPU does not support Debug Extensions(CPUID:01 EDX:BIT2)
    // then force use of DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3
    //
    AsmCpuid (1, NULL, NULL, NULL, &RegEdx);
    if ((RegEdx & BIT2) == 0) {
      LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3;
    }
  }
  AsmReadIdtr (&IdtDescriptor);
  if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
    if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) {
      //
      // Do not trigger INT3 if Debug Agent did not setup IDT entries.
      //
      return;
    }
  } else {
    if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) {
      //
      // Save and update IDT entry for INT1
      //
      SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
      IdtEntryHooked = TRUE;
    }
  }

  //
  // Save Debug Register State
  //
  Dr0 = AsmReadDr0 ();
  Dr1 = AsmReadDr1 ();
  Dr2 = AsmReadDr2 ();
  Dr3 = AsmReadDr3 ();
  Dr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't
  Cr4 = AsmReadCr4 ();

  //
  // DR0 = Signature
  // DR1 = The address of the Null-terminated ASCII string for the PE/COFF image's PDB file name
  // DR2 = The pointer to the ImageContext structure
  // DR3 = IO_PORT_BREAKPOINT_ADDRESS
  // DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte
  // CR4 = Make sure DE(BIT3) is set
  //
  AsmWriteDr7 (BIT10);
  AsmWriteDr0 (Signature);
  AsmWriteDr1 ((UINTN) ImageContext->PdbPointer);
  AsmWriteDr2 ((UINTN) ImageContext);
  AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);

  if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
    AsmWriteDr7 (0x20000480);
    AsmWriteCr4 (Cr4 | BIT3);
    //
    // Do an IN from IO_PORT_BREAKPOINT_ADDRESS to generate a HW breakpoint until the port
    // returns a read value other than DEBUG_AGENT_IMAGE_WAIT
    //
    do {
      DebugAgentStatus = IoRead8 (IO_PORT_BREAKPOINT_ADDRESS);
    } while (DebugAgentStatus == DEBUG_AGENT_IMAGE_WAIT);

  } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
    //
    // Generate a software break point.
    //
    CpuBreakpoint ();
  }

  //
  // Restore Debug Register State only when Host didn't change it inside exception handler.
  // E.g.: User halts the target and sets the HW breakpoint while target is
  //       in the above exception handler
  //
  NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't
  if (!IsDrxEnabled (0, NewDr7) && (AsmReadDr0 () == 0 || AsmReadDr0 () == Signature)) {
    //
    // If user changed Dr3 (by setting HW bp in the above exception handler,
    // we will not set Dr0 to 0 in GO/STEP handler because the break cause is not IMAGE_LOAD/_UNLOAD.
    //
    AsmWriteDr0 (Dr0);
  }
  if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN) ImageContext->PdbPointer)) {
    AsmWriteDr1 (Dr1);
  }
  if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN) ImageContext)) {
    AsmWriteDr2 (Dr2);
  }
  if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) {
    AsmWriteDr3 (Dr3);
  }
  if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
    if (AsmReadCr4 () == (Cr4 | BIT3)) {
      AsmWriteCr4 (Cr4);
    }
    if (NewDr7 == 0x20000480) {
      AsmWriteDr7 (Dr7);
    }
  } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
    if (NewDr7 == BIT10) {
      AsmWriteDr7 (Dr7);
    }
  }
  //
  // Restore original IDT entry for INT1 if it was hooked.
  //
  if (IdtEntryHooked) {
    RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
  }
  //
  // Restore the interrupt state
  //
  SetInterruptState (InterruptState);
}

/**
  Performs additional actions after a PE/COFF image has been loaded and relocated.

  @param  ImageContext  Pointer to the image context structure that describes the
                        PE/COFF image that has already been loaded and relocated.

**/
VOID
EFIAPI
PeCoffLoaderRelocateImageExtraAction (
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
  )
{
  PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_LOAD_SIGNATURE);
}

/**
  Performs additional actions just before a PE/COFF image is unloaded.  Any resources
  that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.

  @param  ImageContext  Pointer to the image context structure that describes the
                        PE/COFF image that is being unloaded.

**/
VOID
EFIAPI
PeCoffLoaderUnloadImageExtraAction (
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
  )
{
  PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_UNLOAD_SIGNATURE);
}
