]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchReadGroupRegister.c
Import SourceLevelDebugPkg.
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / X64 / ArchReadGroupRegister.c
CommitLineData
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
26UINT64\r
27ReadRegisterSelectorByIndex (\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
78VOID\r
79ReadRegisterGroupSegBase (\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
115VOID\r
116ReadRegisterGroupSegLim (\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
178RETURN_STATUS\r
179ArchReadRegisterGroup (\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