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