]>
Commit | Line | Data |
---|---|---|
18b144ea | 1 | /** @file\r |
2 | x64 Group registers read support functions.\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 segment selector by register index.\r | |
19 | \r | |
20 | @param[in] CpuContext Pointer to saved CPU context.\r | |
21 | @param[in] RegisterIndex Register Index.\r | |
22 | \r | |
23 | @return Value of segment selector.\r | |
24 | \r | |
25 | **/\r | |
26 | UINT64\r | |
27 | ReadRegisterSelectorByIndex (\r | |
28 | IN DEBUG_CPU_CONTEXT *CpuContext,\r | |
29 | IN UINT8 RegisterIndex\r | |
30 | )\r | |
31 | {\r | |
32 | IA32_DESCRIPTOR *Ia32Descriptor;\r | |
33 | IA32_GDT *Ia32Gdt;\r | |
34 | UINT16 Selector;\r | |
35 | UINT32 Data32;\r | |
36 | \r | |
37 | Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r | |
38 | Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r | |
39 | \r | |
40 | Selector = 0;\r | |
41 | \r | |
42 | switch (RegisterIndex) {\r | |
43 | case SOFT_DEBUGGER_REGISTER_CSAS:\r | |
44 | Selector = (UINT16) CpuContext->Cs;\r | |
45 | break;\r | |
46 | case SOFT_DEBUGGER_REGISTER_SSAS:\r | |
47 | Selector = (UINT16) CpuContext->Ss;\r | |
48 | break;\r | |
49 | case SOFT_DEBUGGER_REGISTER_GSAS:\r | |
50 | Selector = (UINT16) CpuContext->Gs;\r | |
51 | break;\r | |
52 | case SOFT_DEBUGGER_REGISTER_FSAS:\r | |
53 | Selector = (UINT16) CpuContext->Fs;\r | |
54 | break;\r | |
55 | case SOFT_DEBUGGER_REGISTER_ESAS:\r | |
56 | Selector = (UINT16) CpuContext->Es;\r | |
57 | break;\r | |
58 | case SOFT_DEBUGGER_REGISTER_DSAS:\r | |
59 | Selector = (UINT16) CpuContext->Ds;\r | |
60 | case SOFT_DEBUGGER_REGISTER_LDTAS:\r | |
61 | case SOFT_DEBUGGER_REGISTER_TSSAS:\r | |
62 | return 0x00820000;\r | |
63 | break;\r | |
64 | }\r | |
65 | \r | |
66 | Data32 = (UINT32) RShiftU64 (Ia32Gdt[Selector / 8].Uint64, 24);\r | |
67 | return (Data32 & (UINT32)(~0xff)) | Selector;\r | |
68 | \r | |
69 | }\r | |
70 | \r | |
71 | /**\r | |
72 | Read group register of Segment Base.\r | |
73 | \r | |
74 | @param[in] CpuContext Pointer to saved CPU context.\r | |
75 | @param[in] RegisterGroupSegBase Pointer to Group registers.\r | |
76 | \r | |
77 | **/\r | |
78 | VOID\r | |
79 | ReadRegisterGroupSegBase (\r | |
80 | IN DEBUG_CPU_CONTEXT *CpuContext,\r | |
81 | IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase\r | |
82 | )\r | |
83 | {\r | |
84 | IA32_DESCRIPTOR *Ia32Descriptor;\r | |
85 | IA32_GDT *Ia32Gdt;\r | |
86 | UINTN Index;\r | |
87 | \r | |
88 | Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r | |
89 | Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r | |
90 | \r | |
91 | Index = CpuContext->Cs / 8;\r | |
92 | RegisterGroupSegBase->CsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r | |
93 | Index = CpuContext->Ss / 8;\r | |
94 | RegisterGroupSegBase->SsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r | |
95 | Index = CpuContext->Gs / 8;\r | |
96 | RegisterGroupSegBase->GsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r | |
97 | Index = CpuContext->Fs / 8;\r | |
98 | RegisterGroupSegBase->FsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r | |
99 | Index = CpuContext->Es / 8;\r | |
100 | RegisterGroupSegBase->EsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r | |
101 | Index = CpuContext->Ds / 8;\r | |
102 | RegisterGroupSegBase->DsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r | |
103 | \r | |
104 | RegisterGroupSegBase->LdtBas = 0;\r | |
105 | RegisterGroupSegBase->TssBas = 0;\r | |
106 | }\r | |
107 | \r | |
108 | /**\r | |
109 | Read group register of Segment Limit.\r | |
110 | \r | |
111 | @param[in] CpuContext Pointer to saved CPU context.\r | |
112 | @param[in] RegisterGroupSegLim Pointer to Group registers.\r | |
113 | \r | |
114 | **/\r | |
115 | VOID\r | |
116 | ReadRegisterGroupSegLim (\r | |
117 | IN DEBUG_CPU_CONTEXT *CpuContext,\r | |
118 | IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim\r | |
119 | )\r | |
120 | {\r | |
121 | IA32_DESCRIPTOR *Ia32Descriptor;\r | |
122 | IA32_GDT *Ia32Gdt;\r | |
123 | UINTN Index;\r | |
124 | \r | |
125 | Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r | |
126 | Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r | |
127 | \r | |
128 | Index = CpuContext->Cs / 8;\r | |
129 | RegisterGroupSegLim->CsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r | |
130 | if (Ia32Gdt[Index].Bits.Granularity == 1) {\r | |
131 | RegisterGroupSegLim->CsLim = (RegisterGroupSegLim->CsLim << 12) | 0xfff;\r | |
132 | }\r | |
133 | \r | |
134 | Index = CpuContext->Ss / 8;\r | |
135 | RegisterGroupSegLim->SsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r | |
136 | if (Ia32Gdt[Index].Bits.Granularity == 1) {\r | |
137 | RegisterGroupSegLim->SsLim = (RegisterGroupSegLim->SsLim << 12) | 0xfff;\r | |
138 | }\r | |
139 | \r | |
140 | Index = CpuContext->Gs / 8;\r | |
141 | RegisterGroupSegLim->GsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r | |
142 | if (Ia32Gdt[Index].Bits.Granularity == 1) {\r | |
143 | RegisterGroupSegLim->GsLim = (RegisterGroupSegLim->GsLim << 12) | 0xfff;\r | |
144 | }\r | |
145 | \r | |
146 | Index = CpuContext->Fs / 8;\r | |
147 | RegisterGroupSegLim->FsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r | |
148 | if (Ia32Gdt[Index].Bits.Granularity == 1) {\r | |
149 | RegisterGroupSegLim->FsLim = (RegisterGroupSegLim->FsLim << 12) | 0xfff;\r | |
150 | }\r | |
151 | \r | |
152 | Index = CpuContext->Es / 8;\r | |
153 | RegisterGroupSegLim->EsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r | |
154 | if (Ia32Gdt[Index].Bits.Granularity == 1) {\r | |
155 | RegisterGroupSegLim->EsLim = (RegisterGroupSegLim->EsLim << 12) | 0xfff;\r | |
156 | }\r | |
157 | \r | |
158 | Index = CpuContext->Ds / 8;\r | |
159 | RegisterGroupSegLim->DsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r | |
160 | if (Ia32Gdt[Index].Bits.Granularity == 1) {\r | |
161 | RegisterGroupSegLim->DsLim = (RegisterGroupSegLim->DsLim << 12) | 0xfff;\r | |
162 | }\r | |
163 | \r | |
164 | RegisterGroupSegLim->LdtLim = 0xffff;\r | |
165 | RegisterGroupSegLim->TssLim = 0xffff;\r | |
166 | }\r | |
167 | \r | |
168 | /**\r | |
169 | Read group register by group index.\r | |
170 | \r | |
171 | @param[in] CpuContext Pointer to saved CPU context.\r | |
172 | @param[in] GroupIndex Group Index.\r | |
173 | \r | |
174 | @retval RETURN_SUCCESS Read successfully.\r | |
175 | @retval RETURN_NOT_SUPPORTED Group index cannot be supported.\r | |
176 | \r | |
177 | **/\r | |
178 | RETURN_STATUS\r | |
179 | ArchReadRegisterGroup (\r | |
180 | IN DEBUG_CPU_CONTEXT *CpuContext,\r | |
181 | IN UINT8 GroupIndex\r | |
182 | )\r | |
183 | {\r | |
184 | UINTN DataN;\r | |
185 | DEBUG_DATA_REPONSE_READ_REGISTER_GROUP RegisterGroup;\r | |
186 | DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BAS_LIM RegisterGroupBasLim;\r | |
187 | DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BASES_X64 RegisterGroupBases64;\r | |
188 | \r | |
189 | switch (GroupIndex) {\r | |
190 | case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT64:\r | |
191 | ReadRegisterGroup (CpuContext, &RegisterGroup);\r | |
192 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT));\r | |
193 | break;\r | |
194 | \r | |
195 | case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BAS_LIM64:\r | |
196 | DataN = (UINTN) (CpuContext->Idtr[0] & 0xffff);\r | |
197 | RegisterGroupBasLim.IdtLim = DataN;\r | |
198 | DataN = (UINTN) (CpuContext->Gdtr[0] & 0xffff);\r | |
199 | RegisterGroupBasLim.GdtLim = DataN;\r | |
200 | DataN = (UINTN) RShiftU64 (CpuContext->Idtr[0], 16);\r | |
201 | DataN |= (UINTN) LShiftU64 (CpuContext->Idtr[1], sizeof (UINTN) * 8 - 16);\r | |
202 | RegisterGroupBasLim.IdtBas = DataN;\r | |
203 | DataN = (UINTN) RShiftU64 (CpuContext->Gdtr[0], 16);\r | |
204 | DataN |= (UINTN) LShiftU64 (CpuContext->Gdtr[1], sizeof (UINTN) * 8 - 16);\r | |
205 | RegisterGroupBasLim.GdtBas = DataN;\r | |
206 | \r | |
207 | ReadRegisterGroupSegLim (CpuContext, (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *) &RegisterGroupBasLim.CsLim);\r | |
208 | ReadRegisterGroupSegBase (CpuContext, (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *) &RegisterGroupBasLim.CsBas);\r | |
209 | \r | |
210 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupBasLim, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BAS_LIM));\r | |
211 | break;\r | |
212 | \r | |
213 | case SOFT_DEBUGGER_REGISTER_GROUP_GP2_64:\r | |
214 | ReadRegisterGroup (CpuContext, &RegisterGroup);\r | |
215 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Eflags, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_GP2));\r | |
216 | break;\r | |
217 | \r | |
218 | case SOFT_DEBUGGER_REGISTER_GROUP_GP64:\r | |
219 | ReadRegisterGroup (CpuContext, &RegisterGroup);\r | |
220 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Eax, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_GP));\r | |
221 | break;\r | |
222 | \r | |
223 | case SOFT_DEBUGGER_REGISTER_GROUP_DR64:\r | |
224 | ReadRegisterGroup (CpuContext, &RegisterGroup);\r | |
225 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Dr0, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_DR));\r | |
226 | break;\r | |
227 | \r | |
228 | case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES64:\r | |
229 | RegisterGroupBases64.Ldtr = (UINT16) CpuContext->Ldtr;\r | |
230 | RegisterGroupBases64.Tr = (UINT16) CpuContext->Tr;\r | |
231 | \r | |
232 | RegisterGroupBases64.Csas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_CSAS);\r | |
233 | RegisterGroupBases64.Ssas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_SSAS);\r | |
234 | RegisterGroupBases64.Gsas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_GSAS);\r | |
235 | RegisterGroupBases64.Fsas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_FSAS);\r | |
236 | RegisterGroupBases64.Esas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_ESAS);\r | |
237 | RegisterGroupBases64.Dsas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_DSAS);\r | |
238 | RegisterGroupBases64.Ldtas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_LDTAS);\r | |
239 | RegisterGroupBases64.Tssas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_TSSAS);\r | |
240 | \r | |
241 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupBases64, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BASES_X64));\r | |
242 | break;\r | |
243 | \r | |
244 | case SOFT_DEBUGGER_REGISTER_GROUP_CR64:\r | |
245 | ReadRegisterGroup (CpuContext, &RegisterGroup);\r | |
246 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Dr7 + 8, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_CR));\r | |
247 | break;\r | |
248 | \r | |
249 | case SOFT_DEBUGGER_REGISTER_GROUP_XMM64:\r | |
250 | ReadRegisterGroup (CpuContext, &RegisterGroup);\r | |
251 | SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Dr7 + 8 * 6, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_XMM));\r | |
252 | break;\r | |
253 | \r | |
254 | default:\r | |
255 | return RETURN_UNSUPPORTED;\r | |
256 | }\r | |
257 | \r | |
258 | return RETURN_SUCCESS;\r | |
259 | }\r |