]>
Commit | Line | Data |
---|---|---|
cfae5c90 AF |
1 | /* |
2 | * s390x gdb server stub | |
3 | * | |
4 | * Copyright (c) 2003-2005 Fabrice Bellard | |
5 | * Copyright (c) 2013 SUSE LINUX Products GmbH | |
6 | * | |
7 | * This library is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU Lesser General Public | |
9 | * License as published by the Free Software Foundation; either | |
41c6a6dd | 10 | * version 2.1 of the License, or (at your option) any later version. |
cfae5c90 AF |
11 | * |
12 | * This library is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * Lesser General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public | |
18 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
14a48c1d | 20 | |
9615495a | 21 | #include "qemu/osdep.h" |
33c11879 | 22 | #include "cpu.h" |
b6b47223 | 23 | #include "s390x-internal.h" |
63c91552 | 24 | #include "exec/exec-all.h" |
5b50e790 | 25 | #include "exec/gdbstub.h" |
4ea5fe99 | 26 | #include "gdbstub/helpers.h" |
5b50e790 | 27 | #include "qemu/bitops.h" |
b3946626 | 28 | #include "sysemu/hw_accel.h" |
14a48c1d | 29 | #include "sysemu/tcg.h" |
cfae5c90 | 30 | |
a010bdbe | 31 | int s390_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) |
cfae5c90 | 32 | { |
d0143fa9 | 33 | CPUS390XState *env = cpu_env(cs); |
cfae5c90 AF |
34 | |
35 | switch (n) { | |
36 | case S390_PSWM_REGNUM: | |
deb60cc7 | 37 | return gdb_get_regl(mem_buf, s390_cpu_get_psw_mask(env)); |
cfae5c90 | 38 | case S390_PSWA_REGNUM: |
986a2998 | 39 | return gdb_get_regl(mem_buf, env->psw.addr); |
cfae5c90 | 40 | case S390_R0_REGNUM ... S390_R15_REGNUM: |
218829db | 41 | return gdb_get_regl(mem_buf, env->regs[n - S390_R0_REGNUM]); |
cfae5c90 | 42 | } |
cfae5c90 AF |
43 | return 0; |
44 | } | |
45 | ||
5b50e790 | 46 | int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) |
cfae5c90 | 47 | { |
d0143fa9 | 48 | CPUS390XState *env = cpu_env(cs); |
73d510c9 | 49 | target_ulong tmpl = ldtul_p(mem_buf); |
cfae5c90 AF |
50 | |
51 | switch (n) { | |
52 | case S390_PSWM_REGNUM: | |
deb60cc7 | 53 | s390_cpu_set_psw(env, tmpl, env->psw.addr); |
cfae5c90 AF |
54 | break; |
55 | case S390_PSWA_REGNUM: | |
56 | env->psw.addr = tmpl; | |
57 | break; | |
58 | case S390_R0_REGNUM ... S390_R15_REGNUM: | |
218829db | 59 | env->regs[n - S390_R0_REGNUM] = tmpl; |
cfae5c90 | 60 | break; |
73d510c9 DH |
61 | default: |
62 | return 0; | |
63 | } | |
64 | return 8; | |
65 | } | |
66 | ||
67 | /* the values represent the positions in s390-acr.xml */ | |
68 | #define S390_A0_REGNUM 0 | |
69 | #define S390_A15_REGNUM 15 | |
73d510c9 | 70 | |
66260159 | 71 | static int cpu_read_ac_reg(CPUState *cs, GByteArray *buf, int n) |
73d510c9 | 72 | { |
66260159 AO |
73 | S390CPU *cpu = S390_CPU(cs); |
74 | CPUS390XState *env = &cpu->env; | |
75 | ||
73d510c9 | 76 | switch (n) { |
cfae5c90 | 77 | case S390_A0_REGNUM ... S390_A15_REGNUM: |
a010bdbe | 78 | return gdb_get_reg32(buf, env->aregs[n]); |
73d510c9 DH |
79 | default: |
80 | return 0; | |
81 | } | |
82 | } | |
83 | ||
66260159 | 84 | static int cpu_write_ac_reg(CPUState *cs, uint8_t *mem_buf, int n) |
73d510c9 | 85 | { |
66260159 AO |
86 | S390CPU *cpu = S390_CPU(cs); |
87 | CPUS390XState *env = &cpu->env; | |
88 | ||
73d510c9 DH |
89 | switch (n) { |
90 | case S390_A0_REGNUM ... S390_A15_REGNUM: | |
91 | env->aregs[n] = ldl_p(mem_buf); | |
29a0af61 | 92 | cpu_synchronize_post_init(env_cpu(env)); |
73d510c9 DH |
93 | return 4; |
94 | default: | |
95 | return 0; | |
96 | } | |
97 | } | |
98 | ||
99 | /* the values represent the positions in s390-fpr.xml */ | |
100 | #define S390_FPC_REGNUM 0 | |
101 | #define S390_F0_REGNUM 1 | |
102 | #define S390_F15_REGNUM 16 | |
73d510c9 | 103 | |
66260159 | 104 | static int cpu_read_fp_reg(CPUState *cs, GByteArray *buf, int n) |
73d510c9 | 105 | { |
66260159 AO |
106 | S390CPU *cpu = S390_CPU(cs); |
107 | CPUS390XState *env = &cpu->env; | |
108 | ||
73d510c9 | 109 | switch (n) { |
cfae5c90 | 110 | case S390_FPC_REGNUM: |
a010bdbe | 111 | return gdb_get_reg32(buf, env->fpc); |
cfae5c90 | 112 | case S390_F0_REGNUM ... S390_F15_REGNUM: |
a010bdbe | 113 | return gdb_get_reg64(buf, *get_freg(env, n - S390_F0_REGNUM)); |
cfae5c90 AF |
114 | default: |
115 | return 0; | |
116 | } | |
73d510c9 DH |
117 | } |
118 | ||
66260159 | 119 | static int cpu_write_fp_reg(CPUState *cs, uint8_t *mem_buf, int n) |
73d510c9 | 120 | { |
66260159 AO |
121 | S390CPU *cpu = S390_CPU(cs); |
122 | CPUS390XState *env = &cpu->env; | |
123 | ||
73d510c9 DH |
124 | switch (n) { |
125 | case S390_FPC_REGNUM: | |
126 | env->fpc = ldl_p(mem_buf); | |
127 | return 4; | |
128 | case S390_F0_REGNUM ... S390_F15_REGNUM: | |
4f83d7d2 | 129 | *get_freg(env, n - S390_F0_REGNUM) = ldtul_p(mem_buf); |
73d510c9 DH |
130 | return 8; |
131 | default: | |
132 | return 0; | |
133 | } | |
134 | } | |
135 | ||
ca343c7a EF |
136 | /* the values represent the positions in s390-vx.xml */ |
137 | #define S390_V0L_REGNUM 0 | |
138 | #define S390_V15L_REGNUM 15 | |
139 | #define S390_V16_REGNUM 16 | |
140 | #define S390_V31_REGNUM 31 | |
ca343c7a | 141 | |
66260159 | 142 | static int cpu_read_vreg(CPUState *cs, GByteArray *buf, int n) |
ca343c7a | 143 | { |
66260159 AO |
144 | S390CPU *cpu = S390_CPU(cs); |
145 | CPUS390XState *env = &cpu->env; | |
ca343c7a EF |
146 | int ret; |
147 | ||
148 | switch (n) { | |
149 | case S390_V0L_REGNUM ... S390_V15L_REGNUM: | |
a010bdbe | 150 | ret = gdb_get_reg64(buf, env->vregs[n][1]); |
ca343c7a EF |
151 | break; |
152 | case S390_V16_REGNUM ... S390_V31_REGNUM: | |
a010bdbe AB |
153 | ret = gdb_get_reg64(buf, env->vregs[n][0]); |
154 | ret += gdb_get_reg64(buf, env->vregs[n][1]); | |
ca343c7a EF |
155 | break; |
156 | default: | |
157 | ret = 0; | |
158 | } | |
159 | ||
160 | return ret; | |
161 | } | |
162 | ||
66260159 | 163 | static int cpu_write_vreg(CPUState *cs, uint8_t *mem_buf, int n) |
ca343c7a | 164 | { |
66260159 AO |
165 | S390CPU *cpu = S390_CPU(cs); |
166 | CPUS390XState *env = &cpu->env; | |
167 | ||
ca343c7a EF |
168 | switch (n) { |
169 | case S390_V0L_REGNUM ... S390_V15L_REGNUM: | |
4f83d7d2 | 170 | env->vregs[n][1] = ldtul_p(mem_buf + 8); |
ca343c7a EF |
171 | return 8; |
172 | case S390_V16_REGNUM ... S390_V31_REGNUM: | |
4f83d7d2 DH |
173 | env->vregs[n][0] = ldtul_p(mem_buf); |
174 | env->vregs[n][1] = ldtul_p(mem_buf + 8); | |
ca343c7a EF |
175 | return 16; |
176 | default: | |
177 | return 0; | |
178 | } | |
179 | } | |
180 | ||
5b9f6345 DH |
181 | /* the values represent the positions in s390-cr.xml */ |
182 | #define S390_C0_REGNUM 0 | |
183 | #define S390_C15_REGNUM 15 | |
5b9f6345 DH |
184 | |
185 | #ifndef CONFIG_USER_ONLY | |
66260159 | 186 | static int cpu_read_c_reg(CPUState *cs, GByteArray *buf, int n) |
5b9f6345 | 187 | { |
66260159 AO |
188 | S390CPU *cpu = S390_CPU(cs); |
189 | CPUS390XState *env = &cpu->env; | |
190 | ||
5b9f6345 DH |
191 | switch (n) { |
192 | case S390_C0_REGNUM ... S390_C15_REGNUM: | |
a010bdbe | 193 | return gdb_get_regl(buf, env->cregs[n]); |
5b9f6345 DH |
194 | default: |
195 | return 0; | |
196 | } | |
197 | } | |
198 | ||
66260159 | 199 | static int cpu_write_c_reg(CPUState *cs, uint8_t *mem_buf, int n) |
5b9f6345 | 200 | { |
66260159 AO |
201 | S390CPU *cpu = S390_CPU(cs); |
202 | CPUS390XState *env = &cpu->env; | |
203 | ||
5b9f6345 DH |
204 | switch (n) { |
205 | case S390_C0_REGNUM ... S390_C15_REGNUM: | |
206 | env->cregs[n] = ldtul_p(mem_buf); | |
207 | if (tcg_enabled()) { | |
29a0af61 | 208 | tlb_flush(env_cpu(env)); |
5b9f6345 | 209 | } |
29a0af61 | 210 | cpu_synchronize_post_init(env_cpu(env)); |
5b9f6345 DH |
211 | return 8; |
212 | default: | |
213 | return 0; | |
214 | } | |
215 | } | |
8a641ff6 DH |
216 | |
217 | /* the values represent the positions in s390-virt.xml */ | |
218 | #define S390_VIRT_CKC_REGNUM 0 | |
219 | #define S390_VIRT_CPUTM_REGNUM 1 | |
220 | #define S390_VIRT_BEA_REGNUM 2 | |
221 | #define S390_VIRT_PREFIX_REGNUM 3 | |
8a641ff6 | 222 | |
66260159 | 223 | static int cpu_read_virt_reg(CPUState *cs, GByteArray *mem_buf, int n) |
8a641ff6 | 224 | { |
66260159 AO |
225 | S390CPU *cpu = S390_CPU(cs); |
226 | CPUS390XState *env = &cpu->env; | |
227 | ||
8a641ff6 DH |
228 | switch (n) { |
229 | case S390_VIRT_CKC_REGNUM: | |
230 | return gdb_get_regl(mem_buf, env->ckc); | |
231 | case S390_VIRT_CPUTM_REGNUM: | |
232 | return gdb_get_regl(mem_buf, env->cputm); | |
233 | case S390_VIRT_BEA_REGNUM: | |
234 | return gdb_get_regl(mem_buf, env->gbea); | |
235 | case S390_VIRT_PREFIX_REGNUM: | |
236 | return gdb_get_regl(mem_buf, env->psa); | |
8a641ff6 DH |
237 | default: |
238 | return 0; | |
239 | } | |
240 | } | |
241 | ||
66260159 | 242 | static int cpu_write_virt_reg(CPUState *cs, uint8_t *mem_buf, int n) |
8a641ff6 | 243 | { |
66260159 AO |
244 | S390CPU *cpu = S390_CPU(cs); |
245 | CPUS390XState *env = &cpu->env; | |
246 | ||
8a641ff6 DH |
247 | switch (n) { |
248 | case S390_VIRT_CKC_REGNUM: | |
249 | env->ckc = ldtul_p(mem_buf); | |
66260159 | 250 | cpu_synchronize_post_init(cs); |
8a641ff6 DH |
251 | return 8; |
252 | case S390_VIRT_CPUTM_REGNUM: | |
253 | env->cputm = ldtul_p(mem_buf); | |
66260159 | 254 | cpu_synchronize_post_init(cs); |
8a641ff6 DH |
255 | return 8; |
256 | case S390_VIRT_BEA_REGNUM: | |
257 | env->gbea = ldtul_p(mem_buf); | |
66260159 | 258 | cpu_synchronize_post_init(cs); |
8a641ff6 DH |
259 | return 8; |
260 | case S390_VIRT_PREFIX_REGNUM: | |
261 | env->psa = ldtul_p(mem_buf); | |
66260159 | 262 | cpu_synchronize_post_init(cs); |
8a641ff6 | 263 | return 8; |
8afc43ea IL |
264 | default: |
265 | return 0; | |
266 | } | |
267 | } | |
268 | ||
269 | /* the values represent the positions in s390-virt-kvm.xml */ | |
270 | #define S390_VIRT_KVM_PP_REGNUM 0 | |
271 | #define S390_VIRT_KVM_PFT_REGNUM 1 | |
272 | #define S390_VIRT_KVM_PFS_REGNUM 2 | |
273 | #define S390_VIRT_KVM_PFC_REGNUM 3 | |
8afc43ea | 274 | |
66260159 | 275 | static int cpu_read_virt_kvm_reg(CPUState *cs, GByteArray *mem_buf, int n) |
8afc43ea | 276 | { |
66260159 AO |
277 | S390CPU *cpu = S390_CPU(cs); |
278 | CPUS390XState *env = &cpu->env; | |
279 | ||
8afc43ea IL |
280 | switch (n) { |
281 | case S390_VIRT_KVM_PP_REGNUM: | |
282 | return gdb_get_regl(mem_buf, env->pp); | |
283 | case S390_VIRT_KVM_PFT_REGNUM: | |
284 | return gdb_get_regl(mem_buf, env->pfault_token); | |
285 | case S390_VIRT_KVM_PFS_REGNUM: | |
286 | return gdb_get_regl(mem_buf, env->pfault_select); | |
287 | case S390_VIRT_KVM_PFC_REGNUM: | |
288 | return gdb_get_regl(mem_buf, env->pfault_compare); | |
289 | default: | |
290 | return 0; | |
291 | } | |
292 | } | |
293 | ||
66260159 | 294 | static int cpu_write_virt_kvm_reg(CPUState *cs, uint8_t *mem_buf, int n) |
8afc43ea | 295 | { |
66260159 AO |
296 | S390CPU *cpu = S390_CPU(cs); |
297 | CPUS390XState *env = &cpu->env; | |
298 | ||
8afc43ea IL |
299 | switch (n) { |
300 | case S390_VIRT_KVM_PP_REGNUM: | |
8a641ff6 | 301 | env->pp = ldtul_p(mem_buf); |
29a0af61 | 302 | cpu_synchronize_post_init(env_cpu(env)); |
8a641ff6 | 303 | return 8; |
8afc43ea | 304 | case S390_VIRT_KVM_PFT_REGNUM: |
8a641ff6 | 305 | env->pfault_token = ldtul_p(mem_buf); |
29a0af61 | 306 | cpu_synchronize_post_init(env_cpu(env)); |
8a641ff6 | 307 | return 8; |
8afc43ea | 308 | case S390_VIRT_KVM_PFS_REGNUM: |
8a641ff6 | 309 | env->pfault_select = ldtul_p(mem_buf); |
29a0af61 | 310 | cpu_synchronize_post_init(env_cpu(env)); |
8a641ff6 | 311 | return 8; |
8afc43ea | 312 | case S390_VIRT_KVM_PFC_REGNUM: |
8a641ff6 | 313 | env->pfault_compare = ldtul_p(mem_buf); |
29a0af61 | 314 | cpu_synchronize_post_init(env_cpu(env)); |
8a641ff6 DH |
315 | return 8; |
316 | default: | |
317 | return 0; | |
318 | } | |
319 | } | |
5b9f6345 DH |
320 | #endif |
321 | ||
86158a2a CB |
322 | /* the values represent the positions in s390-gs.xml */ |
323 | #define S390_GS_RESERVED_REGNUM 0 | |
324 | #define S390_GS_GSD_REGNUM 1 | |
325 | #define S390_GS_GSSM_REGNUM 2 | |
326 | #define S390_GS_GSEPLA_REGNUM 3 | |
86158a2a | 327 | |
66260159 | 328 | static int cpu_read_gs_reg(CPUState *cs, GByteArray *buf, int n) |
86158a2a | 329 | { |
66260159 AO |
330 | S390CPU *cpu = S390_CPU(cs); |
331 | CPUS390XState *env = &cpu->env; | |
332 | ||
a010bdbe | 333 | return gdb_get_regl(buf, env->gscb[n]); |
86158a2a CB |
334 | } |
335 | ||
66260159 | 336 | static int cpu_write_gs_reg(CPUState *cs, uint8_t *mem_buf, int n) |
86158a2a | 337 | { |
66260159 AO |
338 | S390CPU *cpu = S390_CPU(cs); |
339 | CPUS390XState *env = &cpu->env; | |
340 | ||
86158a2a | 341 | env->gscb[n] = ldtul_p(mem_buf); |
29a0af61 | 342 | cpu_synchronize_post_init(env_cpu(env)); |
86158a2a CB |
343 | return 8; |
344 | } | |
345 | ||
73d510c9 DH |
346 | void s390_cpu_gdb_init(CPUState *cs) |
347 | { | |
348 | gdb_register_coprocessor(cs, cpu_read_ac_reg, | |
349 | cpu_write_ac_reg, | |
ac1e8671 | 350 | gdb_find_static_feature("s390-acr.xml"), 0); |
73d510c9 DH |
351 | |
352 | gdb_register_coprocessor(cs, cpu_read_fp_reg, | |
353 | cpu_write_fp_reg, | |
ac1e8671 | 354 | gdb_find_static_feature("s390-fpr.xml"), 0); |
ca343c7a EF |
355 | |
356 | gdb_register_coprocessor(cs, cpu_read_vreg, | |
357 | cpu_write_vreg, | |
ac1e8671 | 358 | gdb_find_static_feature("s390-vx.xml"), 0); |
5b9f6345 | 359 | |
86158a2a CB |
360 | gdb_register_coprocessor(cs, cpu_read_gs_reg, |
361 | cpu_write_gs_reg, | |
ac1e8671 | 362 | gdb_find_static_feature("s390-gs.xml"), 0); |
86158a2a | 363 | |
5b9f6345 DH |
364 | #ifndef CONFIG_USER_ONLY |
365 | gdb_register_coprocessor(cs, cpu_read_c_reg, | |
366 | cpu_write_c_reg, | |
ac1e8671 | 367 | gdb_find_static_feature("s390-cr.xml"), 0); |
8a641ff6 | 368 | |
8afc43ea IL |
369 | gdb_register_coprocessor(cs, cpu_read_virt_reg, |
370 | cpu_write_virt_reg, | |
ac1e8671 | 371 | gdb_find_static_feature("s390-virt.xml"), 0); |
8afc43ea | 372 | |
8a641ff6 | 373 | if (kvm_enabled()) { |
8afc43ea IL |
374 | gdb_register_coprocessor(cs, cpu_read_virt_kvm_reg, |
375 | cpu_write_virt_kvm_reg, | |
ac1e8671 | 376 | gdb_find_static_feature("s390-virt-kvm.xml"), |
8afc43ea | 377 | 0); |
8a641ff6 | 378 | } |
5b9f6345 | 379 | #endif |
cfae5c90 | 380 | } |