diff options
author | Richard Henderson <rth@twiddle.net> | 2012-08-23 10:44:45 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-01-05 12:00:27 -0800 |
commit | 6ee77b16630bc86c1a44f9df61b072c7974ba503 (patch) | |
tree | 5ae3861bc59868687e138878118cae205273d78e /gdbstub.c | |
parent | 79be7c7b603f89da209098a03a5459beb09a579b (diff) | |
download | qemu-6ee77b16630bc86c1a44f9df61b072c7974ba503.tar.gz qemu-6ee77b16630bc86c1a44f9df61b072c7974ba503.tar.bz2 qemu-6ee77b16630bc86c1a44f9df61b072c7974ba503.zip |
target-s390: Fix gdbstub
The real gdb protocol doesn't split out pc or cc as real registers.
Those are pseudos that are extracted as needed from the PSW. Don't
modify env->cc_op during read -- that way lies heisenbugs.
Fill in the XXX for the fp registers.
Remove duplicated defines in cpu.h.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'gdbstub.c')
-rw-r--r-- | gdbstub.c | 78 |
1 files changed, 48 insertions, 30 deletions
@@ -40,6 +40,7 @@ #include "cpu.h" #include "qemu/sockets.h" #include "sysemu/kvm.h" +#include "qemu/bitops.h" #ifndef TARGET_CPU_MEMORY_RW_DEBUG static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, @@ -1535,27 +1536,34 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_S390X) -#define NUM_CORE_REGS S390_NUM_TOTAL_REGS +#define NUM_CORE_REGS S390_NUM_REGS static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) { + uint64_t val; + int cc_op; + switch (n) { - case S390_PSWM_REGNUM: GET_REGL(env->psw.mask); break; - case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); break; - case S390_R0_REGNUM ... S390_R15_REGNUM: - GET_REGL(env->regs[n-S390_R0_REGNUM]); break; - case S390_A0_REGNUM ... S390_A15_REGNUM: - GET_REG32(env->aregs[n-S390_A0_REGNUM]); break; - case S390_FPC_REGNUM: GET_REG32(env->fpc); break; - case S390_F0_REGNUM ... S390_F15_REGNUM: - /* XXX */ - break; - case S390_PC_REGNUM: GET_REGL(env->psw.addr); break; - case S390_CC_REGNUM: - env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, - env->cc_vr); - GET_REG32(env->cc_op); - break; + case S390_PSWM_REGNUM: + cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); + val = deposit64(env->psw.mask, 44, 2, cc_op); + GET_REGL(val); + break; + case S390_PSWA_REGNUM: + GET_REGL(env->psw.addr); + break; + case S390_R0_REGNUM ... S390_R15_REGNUM: + GET_REGL(env->regs[n-S390_R0_REGNUM]); + break; + case S390_A0_REGNUM ... S390_A15_REGNUM: + GET_REG32(env->aregs[n-S390_A0_REGNUM]); + break; + case S390_FPC_REGNUM: + GET_REG32(env->fpc); + break; + case S390_F0_REGNUM ... S390_F15_REGNUM: + GET_REG64(env->fregs[n-S390_F0_REGNUM].ll); + break; } return 0; @@ -1570,20 +1578,30 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n) tmp32 = ldl_p(mem_buf); switch (n) { - case S390_PSWM_REGNUM: env->psw.mask = tmpl; break; - case S390_PSWA_REGNUM: env->psw.addr = tmpl; break; - case S390_R0_REGNUM ... S390_R15_REGNUM: - env->regs[n-S390_R0_REGNUM] = tmpl; break; - case S390_A0_REGNUM ... S390_A15_REGNUM: - env->aregs[n-S390_A0_REGNUM] = tmp32; r=4; break; - case S390_FPC_REGNUM: env->fpc = tmp32; r=4; break; - case S390_F0_REGNUM ... S390_F15_REGNUM: - /* XXX */ - break; - case S390_PC_REGNUM: env->psw.addr = tmpl; break; - case S390_CC_REGNUM: env->cc_op = tmp32; r=4; break; + case S390_PSWM_REGNUM: + env->psw.mask = tmpl; + env->cc_op = extract64(tmpl, 44, 2); + break; + case S390_PSWA_REGNUM: + env->psw.addr = tmpl; + break; + case S390_R0_REGNUM ... S390_R15_REGNUM: + env->regs[n-S390_R0_REGNUM] = tmpl; + break; + case S390_A0_REGNUM ... S390_A15_REGNUM: + env->aregs[n-S390_A0_REGNUM] = tmp32; + r = 4; + break; + case S390_FPC_REGNUM: + env->fpc = tmp32; + r = 4; + break; + case S390_F0_REGNUM ... S390_F15_REGNUM: + env->fregs[n-S390_F0_REGNUM].ll = tmpl; + break; + default: + return 0; } - return r; } #elif defined (TARGET_LM32) |