2 Supporting functions for x64 architecture.
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "DebugAgent.h"
18 Read the offset of FP / MMX / XMM registers by register index.
20 @param[in] Index Register index.
21 @param[out] Width Register width returned.
23 @return Offset in register address range.
27 ArchReadFxStatOffset (
32 if (Index
< SOFT_DEBUGGER_REGISTER_ST0
) {
34 case SOFT_DEBUGGER_REGISTER_FP_FCW
:
35 *Width
= (UINT8
) sizeof (UINT16
);
36 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Fcw
);
38 case SOFT_DEBUGGER_REGISTER_FP_FSW
:
39 *Width
= (UINT8
) sizeof (UINT16
);
40 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Fsw
);
42 case SOFT_DEBUGGER_REGISTER_FP_FTW
:
43 *Width
= (UINT8
) sizeof (UINT16
);
44 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Ftw
);
46 case SOFT_DEBUGGER_REGISTER_FP_OPCODE
:
47 *Width
= (UINT8
) sizeof (UINT16
);
48 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Opcode
);
50 case SOFT_DEBUGGER_REGISTER_FP_EIP
:
51 *Width
= (UINT8
) sizeof (UINTN
);
52 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Rip
);
54 case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET
:
55 *Width
= (UINT8
) sizeof (UINTN
);
56 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, DataOffset
);
58 case SOFT_DEBUGGER_REGISTER_FP_MXCSR
:
59 *Width
= (UINT8
) sizeof (UINT32
);
60 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Mxcsr
);
62 case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK
:
63 *Width
= (UINT8
) sizeof (UINT32
);
64 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, Mxcsr_Mask
);
71 if (Index
< SOFT_DEBUGGER_REGISTER_XMM0
) {
73 } else if (Index
< SOFT_DEBUGGER_REGISTER_MM0
) {
77 Index
-= SOFT_DEBUGGER_REGISTER_MM0
- SOFT_DEBUGGER_REGISTER_ST0
;
80 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE
, St0Mm0
) + (Index
- SOFT_DEBUGGER_REGISTER_ST0
) * 16;
84 Write specified register into save CPU context.
86 @param[in] CpuContext Pointer to saved CPU context.
87 @param[in] Index Register index value.
88 @param[in] Offset Offset in register address range
89 @param[in] Width Data width to read.
90 @param[in] RegisterBuffer Pointer to input buffer with data.
94 ArchWriteRegisterBuffer (
95 IN DEBUG_CPU_CONTEXT
*CpuContext
,
99 IN UINT8
*RegisterBuffer
103 if (Index
< SOFT_DEBUGGER_REGISTER_FP_BASE
) {
104 Buffer
= (UINT8
*) CpuContext
+ sizeof (DEBUG_DATA_X64_FX_SAVE_STATE
) + Index
* 8;
107 // If it is MMX register, adjust its index position
109 if (Index
>= SOFT_DEBUGGER_REGISTER_MM0
) {
110 Index
-= SOFT_DEBUGGER_REGISTER_MM0
- SOFT_DEBUGGER_REGISTER_ST0
;
114 // FPU/MMX/XMM registers
116 Buffer
= (UINT8
*) CpuContext
+ ArchReadFxStatOffset (Index
, &Width
);
119 CopyMem (Buffer
+ Offset
, RegisterBuffer
, Width
);
123 Read register value from saved CPU context.
125 @param[in] CpuContext Pointer to saved CPU context.
126 @param[in] Index Register index value.
127 @param[in] Offset Offset in register address range
128 @param[in] Width Data width to read.
130 @return The address of register value.
134 ArchReadRegisterBuffer (
135 IN DEBUG_CPU_CONTEXT
*CpuContext
,
143 if (Index
< SOFT_DEBUGGER_REGISTER_FP_BASE
) {
144 Buffer
= (UINT8
*) CpuContext
+ sizeof (DEBUG_DATA_X64_FX_SAVE_STATE
) + Index
* 8;
146 *Width
= (UINT8
) sizeof (UINTN
);
150 // FPU/MMX/XMM registers
152 Buffer
= (UINT8
*) CpuContext
+ ArchReadFxStatOffset (Index
, Width
);
159 Read group register of common registers.
161 @param[in] CpuContext Pointer to saved CPU context.
162 @param[in] RegisterGroup Pointer to Group registers.
167 IN DEBUG_CPU_CONTEXT
*CpuContext
,
168 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP
*RegisterGroup
171 RegisterGroup
->Cs
= (UINT16
) CpuContext
->Cs
;
172 RegisterGroup
->Ds
= (UINT16
) CpuContext
->Ds
;
173 RegisterGroup
->Es
= (UINT16
) CpuContext
->Es
;
174 RegisterGroup
->Fs
= (UINT16
) CpuContext
->Fs
;
175 RegisterGroup
->Gs
= (UINT16
) CpuContext
->Gs
;
176 RegisterGroup
->Ss
= (UINT16
) CpuContext
->Ss
;
177 RegisterGroup
->Eflags
= (UINT32
) CpuContext
->Eflags
;
178 RegisterGroup
->Rbp
= CpuContext
->Rbp
;
179 RegisterGroup
->Eip
= CpuContext
->Eip
;
180 RegisterGroup
->Rsp
= CpuContext
->Rsp
;
181 RegisterGroup
->Eax
= CpuContext
->Rax
;
182 RegisterGroup
->Rbx
= CpuContext
->Rbx
;
183 RegisterGroup
->Rcx
= CpuContext
->Rcx
;
184 RegisterGroup
->Rdx
= CpuContext
->Rdx
;
185 RegisterGroup
->Rsi
= CpuContext
->Rsi
;
186 RegisterGroup
->Rdi
= CpuContext
->Rdi
;
187 RegisterGroup
->R8
= CpuContext
->R8
;
188 RegisterGroup
->R9
= CpuContext
->R9
;
189 RegisterGroup
->R10
= CpuContext
->R10
;
190 RegisterGroup
->R11
= CpuContext
->R11
;
191 RegisterGroup
->R12
= CpuContext
->R12
;
192 RegisterGroup
->R13
= CpuContext
->R13
;
193 RegisterGroup
->R14
= CpuContext
->R14
;
194 RegisterGroup
->R15
= CpuContext
->R15
;
195 RegisterGroup
->Dr0
= CpuContext
->Dr0
;
196 RegisterGroup
->Dr1
= CpuContext
->Dr1
;
197 RegisterGroup
->Dr2
= CpuContext
->Dr2
;
198 RegisterGroup
->Dr3
= CpuContext
->Dr3
;
199 RegisterGroup
->Dr6
= CpuContext
->Dr6
;
200 RegisterGroup
->Dr7
= CpuContext
->Dr7
;
201 RegisterGroup
->Cr0
= CpuContext
->Cr0
;
202 RegisterGroup
->Cr2
= CpuContext
->Cr2
;
203 RegisterGroup
->Cr3
= CpuContext
->Cr3
;
204 RegisterGroup
->Cr4
= CpuContext
->Cr4
;
205 RegisterGroup
->Cr8
= CpuContext
->Cr8
;
207 CopyMem ((UINT8
*) &RegisterGroup
->Xmm0
[0], (UINT8
*) &CpuContext
->FxSaveState
.Xmm0
[0], 16 * 10);
211 Initialize IDT entries to support source level debug.
219 IA32_IDT_GATE_DESCRIPTOR
*IdtEntry
;
220 UINTN InterruptHandler
;
221 IA32_DESCRIPTOR IdtDescriptor
;
225 AsmReadIdtr (&IdtDescriptor
);
228 // Use current CS as the segment selector of interrupt gate in IDT
230 CodeSegment
= AsmReadCs ();
232 IdtEntry
= (IA32_IDT_GATE_DESCRIPTOR
*) IdtDescriptor
.Base
;
234 for (Index
= 0; Index
< 20; Index
++) {
235 if ((PcdGet32 (PcdExceptionsIgnoredByDebugger
) & (1 << Index
)) != 0) {
237 // If the exception is masked to be reserved, skip it
241 InterruptHandler
= (UINTN
)&Exception0Handle
+ Index
* ExceptionStubHeaderSize
;
242 IdtEntry
[Index
].Bits
.OffsetLow
= (UINT16
)(UINTN
)InterruptHandler
;
243 IdtEntry
[Index
].Bits
.OffsetHigh
= (UINT16
)((UINTN
)InterruptHandler
>> 16);
244 IdtEntry
[Index
].Bits
.OffsetUpper
= (UINT32
)((UINTN
)InterruptHandler
>> 32);
245 IdtEntry
[Index
].Bits
.Selector
= CodeSegment
;
246 IdtEntry
[Index
].Bits
.GateType
= IA32_IDT_GATE_TYPE_INTERRUPT_32
;
249 InterruptHandler
= (UINTN
) &TimerInterruptHandle
;
250 IdtEntry
[DEBUG_TIMER_VECTOR
].Bits
.OffsetLow
= (UINT16
)(UINTN
)InterruptHandler
;
251 IdtEntry
[DEBUG_TIMER_VECTOR
].Bits
.OffsetHigh
= (UINT16
)((UINTN
)InterruptHandler
>> 16);
252 IdtEntry
[DEBUG_TIMER_VECTOR
].Bits
.OffsetUpper
= (UINT32
)((UINTN
)InterruptHandler
>> 32);
253 IdtEntry
[DEBUG_TIMER_VECTOR
].Bits
.Selector
= CodeSegment
;
254 IdtEntry
[DEBUG_TIMER_VECTOR
].Bits
.GateType
= IA32_IDT_GATE_TYPE_INTERRUPT_32
;