]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c
Import SourceLevelDebugPkg.
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / Ia32 / ArchReadGroupRegister.c
1 /** @file
2 IA32 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 group register of Segment Base.
19
20 @param[in] CpuContext Pointer to saved CPU context.
21 @param[in] RegisterGroupSegBase Pointer to Group registers.
22
23 **/
24 VOID
25 ReadRegisterGroupSegBase (
26 IN DEBUG_CPU_CONTEXT *CpuContext,
27 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase
28 )
29 {
30 IA32_DESCRIPTOR *Ia32Descriptor;
31 IA32_GDT *Ia32Gdt;
32 UINTN Index;
33
34 Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;
35 Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);
36
37 Index = CpuContext->Cs / 8;
38 RegisterGroupSegBase->CsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
39 Index = CpuContext->Ss / 8;
40 RegisterGroupSegBase->SsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
41 Index = CpuContext->Gs / 8;
42 RegisterGroupSegBase->GsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
43 Index = CpuContext->Fs / 8;
44 RegisterGroupSegBase->FsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
45 Index = CpuContext->Es / 8;
46 RegisterGroupSegBase->EsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
47 Index = CpuContext->Ds / 8;
48 RegisterGroupSegBase->DsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
49
50 RegisterGroupSegBase->LdtBas = 0;
51 RegisterGroupSegBase->TssBas = 0;
52 }
53
54 /**
55 Read gourp register of Segment Limit.
56
57 @param[in] CpuContext Pointer to saved CPU context.
58 @param[in] RegisterGroupSegLim Pointer to Group registers.
59
60 **/
61 VOID
62 ReadRegisterGroupSegLim (
63 IN DEBUG_CPU_CONTEXT *CpuContext,
64 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim
65 )
66 {
67 IA32_DESCRIPTOR *Ia32Descriptor;
68 IA32_GDT *Ia32Gdt;
69 UINTN Index;
70
71 Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;
72 Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);
73
74 Index = CpuContext->Cs / 8;
75 RegisterGroupSegLim->CsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
76 if (Ia32Gdt[Index].Bits.Granularity == 1) {
77 RegisterGroupSegLim->CsLim = (RegisterGroupSegLim->CsLim << 12) | 0xfff;
78 }
79
80 Index = CpuContext->Ss / 8;
81 RegisterGroupSegLim->SsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
82 if (Ia32Gdt[Index].Bits.Granularity == 1) {
83 RegisterGroupSegLim->SsLim = (RegisterGroupSegLim->SsLim << 12) | 0xfff;
84 }
85
86 Index = CpuContext->Gs / 8;
87 RegisterGroupSegLim->GsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
88 if (Ia32Gdt[Index].Bits.Granularity == 1) {
89 RegisterGroupSegLim->GsLim = (RegisterGroupSegLim->GsLim << 12) | 0xfff;
90 }
91
92 Index = CpuContext->Fs / 8;
93 RegisterGroupSegLim->FsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
94 if (Ia32Gdt[Index].Bits.Granularity == 1) {
95 RegisterGroupSegLim->FsLim = (RegisterGroupSegLim->FsLim << 12) | 0xfff;
96 }
97
98 Index = CpuContext->Es / 8;
99 RegisterGroupSegLim->EsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
100 if (Ia32Gdt[Index].Bits.Granularity == 1) {
101 RegisterGroupSegLim->EsLim = (RegisterGroupSegLim->EsLim << 12) | 0xfff;
102 }
103
104 Index = CpuContext->Ds / 8;
105 RegisterGroupSegLim->DsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
106 if (Ia32Gdt[Index].Bits.Granularity == 1) {
107 RegisterGroupSegLim->DsLim = (RegisterGroupSegLim->DsLim << 12) | 0xfff;
108 }
109
110 RegisterGroupSegLim->LdtLim = 0xffff;
111 RegisterGroupSegLim->TssLim = 0xffff;
112 }
113
114 /**
115 Read group register by group index.
116
117 @param[in] CpuContext Pointer to saved CPU context.
118 @param[in] GroupIndex Group Index.
119
120 @retval RETURN_SUCCESS Read successfully.
121 @retval RETURN_NOT_SUPPORTED Group index cannot be supported.
122
123 **/
124 RETURN_STATUS
125 ArchReadRegisterGroup (
126 IN DEBUG_CPU_CONTEXT *CpuContext,
127 IN UINT8 GroupIndex
128 )
129 {
130 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP RegisterGroup;
131 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM RegisterGroupSegLim;
132 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE RegisterGroupSegBase;
133
134 switch (GroupIndex) {
135 case SOFT_DEBUGGER_REGISTER_GROUP_GPDRS32:
136 ReadRegisterGroup (CpuContext, &RegisterGroup);
137 SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP));
138 break;
139
140 case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_LIMITS32:
141 ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim);
142 SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupSegLim, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM));
143 break;
144
145 case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES32:
146 ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase);
147 SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupSegBase, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE));
148 break;
149
150 default:
151 return RETURN_UNSUPPORTED;
152 }
153
154 return RETURN_SUCCESS;
155 }
156
157 /**
158 Read segment selector by register index.
159
160 @param[in] CpuContext Pointer to saved CPU context.
161 @param[in] RegisterIndex Register Index.
162
163 @return Value of segment selector.
164
165 **/
166 UINT64
167 ReadRegisterSelectorByIndex (
168 IN DEBUG_CPU_CONTEXT *CpuContext,
169 IN UINT8 RegisterIndex
170 )
171 {
172 IA32_DESCRIPTOR *Ia32Descriptor;
173 IA32_GDT *Ia32Gdt;
174 UINT16 Selector;
175 UINT32 Data32;
176
177 Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;
178 Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);
179
180 Selector = 0;
181
182 switch (RegisterIndex) {
183 case SOFT_DEBUGGER_REGISTER_CSAS:
184 Selector = (UINT16) CpuContext->Cs;
185 break;
186 case SOFT_DEBUGGER_REGISTER_SSAS:
187 Selector = (UINT16) CpuContext->Ss;
188 break;
189 case SOFT_DEBUGGER_REGISTER_GSAS:
190 Selector = (UINT16) CpuContext->Gs;
191 break;
192 case SOFT_DEBUGGER_REGISTER_FSAS:
193 Selector = (UINT16) CpuContext->Fs;
194 break;
195 case SOFT_DEBUGGER_REGISTER_ESAS:
196 Selector = (UINT16) CpuContext->Es;
197 break;
198 case SOFT_DEBUGGER_REGISTER_DSAS:
199 Selector = (UINT16) CpuContext->Ds;
200 case SOFT_DEBUGGER_REGISTER_LDTAS:
201 case SOFT_DEBUGGER_REGISTER_TSSAS:
202 return 0x00820000;
203 break;
204 }
205
206 Data32 = (UINT32) RShiftU64 (Ia32Gdt[Selector / 8].Uint64, 24);
207 return (Data32 & (UINT32)(~0xff)) | Selector;
208
209 }
210