git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10867 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			243 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Public include file for Debug Port Library.
 | 
						|
 | 
						|
  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
 | 
						|
  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 "DebugAgent.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Read the offset of FP / MMX / XMM registers by register index.
 | 
						|
 | 
						|
  @param[in]  Index    Register index.
 | 
						|
  @param[out] Width    Register width returned.
 | 
						|
 | 
						|
  @return Offset in register address range.
 | 
						|
 | 
						|
**/
 | 
						|
UINT16
 | 
						|
ArchReadFxStatOffset (
 | 
						|
  IN  UINT8                     Index,
 | 
						|
  OUT UINT8                     *Width
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Index < SOFT_DEBUGGER_REGISTER_ST0) {
 | 
						|
    switch (Index) {
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_FCW:
 | 
						|
      *Width = (UINT8) sizeof (UINT16);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fcw);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_FSW:
 | 
						|
  	  *Width = (UINT8) sizeof (UINT16);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fsw);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_FTW:
 | 
						|
      *Width = (UINT8) sizeof (UINT16);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ftw);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_OPCODE:
 | 
						|
      *Width = (UINT8) sizeof (UINT16);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Opcode);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_EIP:
 | 
						|
      *Width = (UINT8) sizeof (UINTN);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Eip);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_CS:
 | 
						|
      *Width = (UINT8) sizeof (UINT16);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Cs);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:
 | 
						|
      *Width = (UINT8) sizeof (UINTN);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, DataOffset);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_DS:
 | 
						|
      *Width = (UINT8) sizeof (UINT16);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ds);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_MXCSR:
 | 
						|
      *Width = (UINT8) sizeof (UINTN);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr);
 | 
						|
 | 
						|
    case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:
 | 
						|
      *Width = (UINT8) sizeof (UINTN);
 | 
						|
      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr_Mask);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {
 | 
						|
    *Width = 10;
 | 
						|
  } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {
 | 
						|
    *Width = 16;
 | 
						|
  } else {
 | 
						|
    *Width = 8;
 | 
						|
    Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
 | 
						|
  }
 | 
						|
 | 
						|
  return (UINT16)(OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Write specified register into save CPU context.
 | 
						|
 | 
						|
  @param[in] CpuContext         Pointer to saved CPU context.
 | 
						|
  @param[in] Index              Register index value.
 | 
						|
  @param[in] Offset             Offset in register address range.
 | 
						|
  @param[in] Width              Data width to read.
 | 
						|
  @param[in] RegisterBuffer     Pointer to input buffer with data.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ArchWriteRegisterBuffer (
 | 
						|
  IN DEBUG_CPU_CONTEXT               *CpuContext,
 | 
						|
  IN UINT8                           Index,
 | 
						|
  IN UINT8                           Offset,
 | 
						|
  IN UINT8                           Width,
 | 
						|
  IN UINT8                           *RegisterBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8           *Buffer;
 | 
						|
  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {
 | 
						|
    Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // If it is MMX register, adjust its index position
 | 
						|
    //
 | 
						|
    if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {
 | 
						|
      Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // FPU/MMX/XMM registers
 | 
						|
    //
 | 
						|
    Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);
 | 
						|
  }
 | 
						|
 | 
						|
  CopyMem (Buffer + Offset, RegisterBuffer, Width);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Read register value from saved CPU context.
 | 
						|
 | 
						|
  @param[in] CpuContext         Pointer to saved CPU context.
 | 
						|
  @param[in] Index              Register index value.
 | 
						|
  @param[in] Offset             Offset in register address range
 | 
						|
  @param[in] Width              Data width to read.
 | 
						|
 | 
						|
  @return The address of register value.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8 *
 | 
						|
ArchReadRegisterBuffer (
 | 
						|
  IN DEBUG_CPU_CONTEXT               *CpuContext,
 | 
						|
  IN UINT8                           Index,
 | 
						|
  IN UINT8                           Offset,
 | 
						|
  IN UINT8                           *Width
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8           *Buffer;
 | 
						|
 | 
						|
  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {
 | 
						|
    Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;
 | 
						|
    if (*Width == 0) {
 | 
						|
      *Width = (UINT8) sizeof (UINTN);
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // FPU/MMX/XMM registers
 | 
						|
    //
 | 
						|
    Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);
 | 
						|
  }
 | 
						|
 | 
						|
  return Buffer;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Read group register of common registers.
 | 
						|
 | 
						|
  @param[in] CpuContext           Pointer to saved CPU context.
 | 
						|
  @param[in] RegisterGroup        Pointer to Group registers.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ReadRegisterGroup (
 | 
						|
  IN DEBUG_CPU_CONTEXT                       *CpuContext,
 | 
						|
  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  *RegisterGroup
 | 
						|
  )
 | 
						|
{
 | 
						|
  RegisterGroup->Cs     = (UINT16) CpuContext->Cs;
 | 
						|
  RegisterGroup->Ds     = (UINT16) CpuContext->Ds;
 | 
						|
  RegisterGroup->Es     = (UINT16) CpuContext->Es;
 | 
						|
  RegisterGroup->Fs     = (UINT16) CpuContext->Fs;
 | 
						|
  RegisterGroup->Gs     = (UINT16) CpuContext->Gs;
 | 
						|
  RegisterGroup->Ss     = (UINT16) CpuContext->Ss;
 | 
						|
  RegisterGroup->Eflags = CpuContext->Eflags;
 | 
						|
  RegisterGroup->Ebp    = CpuContext->Ebp;
 | 
						|
  RegisterGroup->Eip    = CpuContext->Eip;
 | 
						|
  RegisterGroup->Esp    = CpuContext->Esp;
 | 
						|
  RegisterGroup->Eax    = CpuContext->Eax;
 | 
						|
  RegisterGroup->Ebx    = CpuContext->Ebx;
 | 
						|
  RegisterGroup->Ecx    = CpuContext->Ecx;
 | 
						|
  RegisterGroup->Edx    = CpuContext->Edx;
 | 
						|
  RegisterGroup->Esi    = CpuContext->Esi;
 | 
						|
  RegisterGroup->Edi    = CpuContext->Edi;
 | 
						|
  RegisterGroup->Dr0    = CpuContext->Dr0;
 | 
						|
  RegisterGroup->Dr1    = CpuContext->Dr1;
 | 
						|
  RegisterGroup->Dr2    = CpuContext->Dr2;
 | 
						|
  RegisterGroup->Dr3    = CpuContext->Dr3;
 | 
						|
  RegisterGroup->Dr6    = CpuContext->Dr6;
 | 
						|
  RegisterGroup->Dr7    = CpuContext->Dr7;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize IDT entries to support source level debug.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
InitializeDebugIdt (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;
 | 
						|
  UINTN                      InterruptHandler;
 | 
						|
  IA32_DESCRIPTOR            IdtDescriptor;
 | 
						|
  UINTN                      Index;
 | 
						|
  UINT16                     CodeSegment;
 | 
						|
 | 
						|
  AsmReadIdtr (&IdtDescriptor);
 | 
						|
 | 
						|
  //
 | 
						|
  // Use current CS as the segment selector of interrupt gate in IDT
 | 
						|
  //
 | 
						|
  CodeSegment = AsmReadCs ();
 | 
						|
 | 
						|
  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
 | 
						|
 | 
						|
  for (Index = 0; Index < 20; Index ++) {
 | 
						|
    if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {
 | 
						|
      //
 | 
						|
      // If the exception is masked to be reserved, skip it
 | 
						|
      //
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
    InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;
 | 
						|
    IdtEntry[Index].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;
 | 
						|
    IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
 | 
						|
    IdtEntry[Index].Bits.Selector        = CodeSegment;
 | 
						|
    IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;
 | 
						|
  }
 | 
						|
 | 
						|
  InterruptHandler = (UINTN) &TimerInterruptHandle;
 | 
						|
  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;
 | 
						|
  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
 | 
						|
  IdtEntry[Index].Bits.Selector        = CodeSegment;
 | 
						|
  IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;
 | 
						|
}
 |