]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c
Import SourceLevelDebugPkg.
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / Ia32 / ArchDebugSupport.c
CommitLineData
18b144ea 1/** @file\r
2 Public include file for Debug Port Library.\r
3\r
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "DebugAgent.h"\r
16\r
17/**\r
18 Read the offset of FP / MMX / XMM registers by register index.\r
19\r
20 @param[in] Index Register index.\r
21 @param[out] Width Register width returned.\r
22\r
23 @return Offset in register address range.\r
24\r
25**/\r
26UINT16\r
27ArchReadFxStatOffset (\r
28 IN UINT8 Index,\r
29 OUT UINT8 *Width\r
30 )\r
31{\r
32 if (Index < SOFT_DEBUGGER_REGISTER_ST0) {\r
33 switch (Index) {\r
34 case SOFT_DEBUGGER_REGISTER_FP_FCW:\r
35 *Width = (UINT8) sizeof (UINT16);\r
36 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fcw);\r
37\r
38 case SOFT_DEBUGGER_REGISTER_FP_FSW:\r
39 *Width = (UINT8) sizeof (UINT16);\r
40 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fsw);\r
41\r
42 case SOFT_DEBUGGER_REGISTER_FP_FTW:\r
43 *Width = (UINT8) sizeof (UINT16);\r
44 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ftw);\r
45\r
46 case SOFT_DEBUGGER_REGISTER_FP_OPCODE:\r
47 *Width = (UINT8) sizeof (UINT16);\r
48 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Opcode);\r
49\r
50 case SOFT_DEBUGGER_REGISTER_FP_EIP:\r
51 *Width = (UINT8) sizeof (UINTN);\r
52 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Eip);\r
53\r
54 case SOFT_DEBUGGER_REGISTER_FP_CS:\r
55 *Width = (UINT8) sizeof (UINT16);\r
56 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Cs);\r
57\r
58 case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:\r
59 *Width = (UINT8) sizeof (UINTN);\r
60 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, DataOffset);\r
61\r
62 case SOFT_DEBUGGER_REGISTER_FP_DS:\r
63 *Width = (UINT8) sizeof (UINT16);\r
64 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ds);\r
65\r
66 case SOFT_DEBUGGER_REGISTER_FP_MXCSR:\r
67 *Width = (UINT8) sizeof (UINTN);\r
68 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr);\r
69\r
70 case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:\r
71 *Width = (UINT8) sizeof (UINTN);\r
72 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr_Mask);\r
73 }\r
74 }\r
75\r
76 if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {\r
77 *Width = 10;\r
78 } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {\r
79 *Width = 16;\r
80 } else {\r
81 *Width = 8;\r
82 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
83 }\r
84\r
85 return (UINT16)(OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16);\r
86}\r
87\r
88/**\r
89 Write specified register into save CPU context.\r
90\r
91 @param[in] CpuContext Pointer to saved CPU context.\r
92 @param[in] Index Register index value.\r
93 @param[in] Offset Offset in register address range.\r
94 @param[in] Width Data width to read.\r
95 @param[in] RegisterBuffer Pointer to input buffer with data.\r
96\r
97**/\r
98VOID\r
99ArchWriteRegisterBuffer (\r
100 IN DEBUG_CPU_CONTEXT *CpuContext,\r
101 IN UINT8 Index,\r
102 IN UINT8 Offset,\r
103 IN UINT8 Width,\r
104 IN UINT8 *RegisterBuffer\r
105 )\r
106{\r
107 UINT8 *Buffer;\r
108 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
109 Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;\r
110 } else {\r
111 //\r
112 // If it is MMX register, adjust its index position\r
113 //\r
114 if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {\r
115 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
116 }\r
117 //\r
118 // FPU/MMX/XMM registers\r
119 //\r
120 Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);\r
121 }\r
122\r
123 CopyMem (Buffer + Offset, RegisterBuffer, Width);\r
124}\r
125\r
126/**\r
127 Read register value from saved CPU context.\r
128\r
129 @param[in] CpuContext Pointer to saved CPU context.\r
130 @param[in] Index Register index value.\r
131 @param[in] Offset Offset in register address range\r
132 @param[in] Width Data width to read.\r
133\r
134 @return The address of register value.\r
135\r
136**/\r
137UINT8 *\r
138ArchReadRegisterBuffer (\r
139 IN DEBUG_CPU_CONTEXT *CpuContext,\r
140 IN UINT8 Index,\r
141 IN UINT8 Offset,\r
142 IN UINT8 *Width\r
143 )\r
144{\r
145 UINT8 *Buffer;\r
146\r
147 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
148 Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;\r
149 if (*Width == 0) {\r
150 *Width = (UINT8) sizeof (UINTN);\r
151 }\r
152 } else {\r
153 //\r
154 // FPU/MMX/XMM registers\r
155 //\r
156 Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);\r
157 }\r
158\r
159 return Buffer;\r
160}\r
161\r
162/**\r
163 Read group register of common registers.\r
164\r
165 @param[in] CpuContext Pointer to saved CPU context.\r
166 @param[in] RegisterGroup Pointer to Group registers.\r
167\r
168**/\r
169VOID\r
170ReadRegisterGroup (\r
171 IN DEBUG_CPU_CONTEXT *CpuContext,\r
172 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP *RegisterGroup\r
173 )\r
174{\r
175 RegisterGroup->Cs = (UINT16) CpuContext->Cs;\r
176 RegisterGroup->Ds = (UINT16) CpuContext->Ds;\r
177 RegisterGroup->Es = (UINT16) CpuContext->Es;\r
178 RegisterGroup->Fs = (UINT16) CpuContext->Fs;\r
179 RegisterGroup->Gs = (UINT16) CpuContext->Gs;\r
180 RegisterGroup->Ss = (UINT16) CpuContext->Ss;\r
181 RegisterGroup->Eflags = CpuContext->Eflags;\r
182 RegisterGroup->Ebp = CpuContext->Ebp;\r
183 RegisterGroup->Eip = CpuContext->Eip;\r
184 RegisterGroup->Esp = CpuContext->Esp;\r
185 RegisterGroup->Eax = CpuContext->Eax;\r
186 RegisterGroup->Ebx = CpuContext->Ebx;\r
187 RegisterGroup->Ecx = CpuContext->Ecx;\r
188 RegisterGroup->Edx = CpuContext->Edx;\r
189 RegisterGroup->Esi = CpuContext->Esi;\r
190 RegisterGroup->Edi = CpuContext->Edi;\r
191 RegisterGroup->Dr0 = CpuContext->Dr0;\r
192 RegisterGroup->Dr1 = CpuContext->Dr1;\r
193 RegisterGroup->Dr2 = CpuContext->Dr2;\r
194 RegisterGroup->Dr3 = CpuContext->Dr3;\r
195 RegisterGroup->Dr6 = CpuContext->Dr6;\r
196 RegisterGroup->Dr7 = CpuContext->Dr7;\r
197}\r
198\r
199/**\r
200 Initialize IDT entries to support source level debug.\r
201\r
202**/\r
203VOID\r
204InitializeDebugIdt (\r
205 VOID\r
206 )\r
207{\r
208 IA32_IDT_GATE_DESCRIPTOR *IdtEntry;\r
209 UINTN InterruptHandler;\r
210 IA32_DESCRIPTOR IdtDescriptor;\r
211 UINTN Index;\r
212 UINT16 CodeSegment;\r
213\r
214 AsmReadIdtr (&IdtDescriptor);\r
215\r
216 //\r
217 // Use current CS as the segment selector of interrupt gate in IDT\r
218 //\r
219 CodeSegment = AsmReadCs ();\r
220\r
221 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
222\r
223 for (Index = 0; Index < 20; Index ++) {\r
224 if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {\r
225 //\r
226 // If the exception is masked to be reserved, skip it\r
227 //\r
228 continue;\r
229 }\r
230 InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;\r
231 IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;\r
232 IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);\r
233 IdtEntry[Index].Bits.Selector = CodeSegment;\r
234 IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
235 }\r
236\r
237 InterruptHandler = (UINTN) &TimerInterruptHandle;\r
238 IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;\r
239 IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);\r
240 IdtEntry[Index].Bits.Selector = CodeSegment;\r
241 IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
242}\r