Import SourceLevelDebugPkg.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10867 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -0,0 +1,255 @@
|
||||
/** @file
|
||||
Supporting functions for x64 architecture.
|
||||
|
||||
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 OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Fcw);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_FSW:
|
||||
*Width = (UINT8) sizeof (UINT16);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Fsw);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_FTW:
|
||||
*Width = (UINT8) sizeof (UINT16);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Ftw);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_OPCODE:
|
||||
*Width = (UINT8) sizeof (UINT16);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Opcode);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_EIP:
|
||||
*Width = (UINT8) sizeof (UINTN);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Rip);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:
|
||||
*Width = (UINT8) sizeof (UINTN);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, DataOffset);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_MXCSR:
|
||||
*Width = (UINT8) sizeof (UINT32);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Mxcsr);
|
||||
|
||||
case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:
|
||||
*Width = (UINT8) sizeof (UINT32);
|
||||
return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Mxcsr_Mask);
|
||||
|
||||
default:
|
||||
return (UINT16) (-1);
|
||||
}
|
||||
}
|
||||
|
||||
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 OFFSET_OF(DEBUG_DATA_X64_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_X64_FX_SAVE_STATE) + Index * 8;
|
||||
} 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_X64_FX_SAVE_STATE) + Index * 8;
|
||||
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 = (UINT32) CpuContext->Eflags;
|
||||
RegisterGroup->Rbp = CpuContext->Rbp;
|
||||
RegisterGroup->Eip = CpuContext->Eip;
|
||||
RegisterGroup->Rsp = CpuContext->Rsp;
|
||||
RegisterGroup->Eax = CpuContext->Rax;
|
||||
RegisterGroup->Rbx = CpuContext->Rbx;
|
||||
RegisterGroup->Rcx = CpuContext->Rcx;
|
||||
RegisterGroup->Rdx = CpuContext->Rdx;
|
||||
RegisterGroup->Rsi = CpuContext->Rsi;
|
||||
RegisterGroup->Rdi = CpuContext->Rdi;
|
||||
RegisterGroup->R8 = CpuContext->R8;
|
||||
RegisterGroup->R9 = CpuContext->R9;
|
||||
RegisterGroup->R10 = CpuContext->R10;
|
||||
RegisterGroup->R11 = CpuContext->R11;
|
||||
RegisterGroup->R12 = CpuContext->R12;
|
||||
RegisterGroup->R13 = CpuContext->R13;
|
||||
RegisterGroup->R14 = CpuContext->R14;
|
||||
RegisterGroup->R15 = CpuContext->R15;
|
||||
RegisterGroup->Dr0 = CpuContext->Dr0;
|
||||
RegisterGroup->Dr1 = CpuContext->Dr1;
|
||||
RegisterGroup->Dr2 = CpuContext->Dr2;
|
||||
RegisterGroup->Dr3 = CpuContext->Dr3;
|
||||
RegisterGroup->Dr6 = CpuContext->Dr6;
|
||||
RegisterGroup->Dr7 = CpuContext->Dr7;
|
||||
RegisterGroup->Cr0 = CpuContext->Cr0;
|
||||
RegisterGroup->Cr2 = CpuContext->Cr2;
|
||||
RegisterGroup->Cr3 = CpuContext->Cr3;
|
||||
RegisterGroup->Cr4 = CpuContext->Cr4;
|
||||
RegisterGroup->Cr8 = CpuContext->Cr8;
|
||||
|
||||
CopyMem ((UINT8 *) &RegisterGroup->Xmm0[0], (UINT8 *) &CpuContext->FxSaveState.Xmm0[0], 16 * 10);
|
||||
}
|
||||
|
||||
/**
|
||||
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.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
|
||||
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[DEBUG_TIMER_VECTOR].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
|
||||
IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector = CodeSegment;
|
||||
IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
|
||||
}
|
Reference in New Issue
Block a user