[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 2/2] target-mips: Set GDB register widths correct
From: |
Maciej W. Rozycki |
Subject: |
[Qemu-devel] [PATCH v2 2/2] target-mips: Set GDB register widths correctly |
Date: |
Thu, 11 Dec 2014 00:22:05 +0000 |
User-agent: |
Alpine 1.10 (DEB 962 2008-03-14) |
Set register widths in the GDB stub as follows:
- for the system emulation mode -- to the native register size of the
processor selected, any MIPS I, MIPS II or MIPS32 (any revision)
processor will have 32-bit general purpose registers and any MIPS III,
MIPS IV or MIPS64 (again, any revision) will have 64-bit general
purpose registers,
- for the user emulation mode -- to the register size defined by the
ABI, that is the emulation of the o32 ABI will have 32-bit general
purpose registers and the emulation of the n32 and n64 ABIs will have
64-bit general purpose registers.
With the the user emulation mode, the o32 ABI and a 64-bit processor
selected handle native 64-bit registers such that on reads they are
truncated to low 32 bits only and on writes the 32-bit value stored is
sign-extended from bit #31, which is how hardware instructions supported
with the o32 ABI have been defined in the architecture.
Also correctly wrap the address space in the 32-bit o32 and n32 ABIs by
sign-extending any addresses processed from bit #31, matching how the
hardware operates in the user mode according to CP0.Status.UX == 0 and
CP0.Status.PX == 0 (for o32) and CP0.Status.UX == 0 and CP0.Status.PX ==
1 (for n32). This is also how GDB works operating on real processors in
conjunction with JTAG hardware and associated debug-mode firmware across
all execution modes.
As a side effect fix the case where registers are presented as 64-bit
quantities while talking to a 32-bit processor.
Signed-off-by: Maciej W. Rozycki <address@hidden>
---
Changes from v1:
- rename 3/3 to 2/2.
qemu-mips-regsize.diff
Index: qemu-git-trunk/gdbstub.c
===================================================================
--- qemu-git-trunk.orig/gdbstub.c 2014-12-05 18:38:40.847529339 +0000
+++ qemu-git-trunk/gdbstub.c 2014-12-05 18:41:00.358928442 +0000
@@ -789,7 +789,7 @@ static int gdb_handle_packet(GDBState *s
break;
case 'c':
if (*p != '\0') {
- addr = strtoull(p, (char **)&p, 16);
+ addr = target_address(s->c_cpu, strtoull(p, (char **)&p, 16));
gdb_set_cpu_pc(s, addr);
}
s->signal = 0;
@@ -875,7 +875,7 @@ static int gdb_handle_packet(GDBState *s
break;
case 's':
if (*p != '\0') {
- addr = strtoull(p, (char **)&p, 16);
+ addr = target_address(s->c_cpu, strtoull(p, (char **)&p, 16));
gdb_set_cpu_pc(s, addr);
}
cpu_single_step(s->c_cpu, sstep_flags);
@@ -930,7 +930,7 @@ static int gdb_handle_packet(GDBState *s
put_packet(s, "OK");
break;
case 'm':
- addr = strtoull(p, (char **)&p, 16);
+ addr = target_address(s->g_cpu, strtoull(p, (char **)&p, 16));
if (*p == ',')
p++;
len = strtoull(p, NULL, 16);
@@ -942,7 +942,7 @@ static int gdb_handle_packet(GDBState *s
}
break;
case 'M':
- addr = strtoull(p, (char **)&p, 16);
+ addr = target_address(s->g_cpu, strtoull(p, (char **)&p, 16));
if (*p == ',')
p++;
len = strtoull(p, (char **)&p, 16);
@@ -987,7 +987,7 @@ static int gdb_handle_packet(GDBState *s
type = strtoul(p, (char **)&p, 16);
if (*p == ',')
p++;
- addr = strtoull(p, (char **)&p, 16);
+ addr = target_address(s->g_cpu, strtoull(p, (char **)&p, 16));
if (*p == ',')
p++;
len = strtoull(p, (char **)&p, 16);
Index: qemu-git-trunk/target-alpha/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-alpha/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-alpha/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -500,4 +500,7 @@ static inline void cpu_get_tb_cpu_state(
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* !defined (__CPU_ALPHA_H__) */
Index: qemu-git-trunk/target-arm/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-arm/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-arm/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -1539,4 +1539,7 @@ enum {
QEMU_PSCI_CONDUIT_HVC = 2,
};
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-cris/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-cris/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-cris/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -277,4 +277,7 @@ void cris_cpu_list(FILE *f, fprintf_func
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-i386/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-i386/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-i386/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -1378,4 +1378,7 @@ void enable_compat_apic_id_mode(void);
#define APIC_DEFAULT_ADDRESS 0xfee00000
#define APIC_SPACE_SIZE 0x100000
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* CPU_I386_H */
Index: qemu-git-trunk/target-lm32/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-lm32/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-lm32/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -248,4 +248,7 @@ static inline void cpu_get_tb_cpu_state(
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-m68k/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-m68k/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-m68k/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -254,4 +254,7 @@ static inline void cpu_get_tb_cpu_state(
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-microblaze/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-microblaze/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-microblaze/cpu.h 2014-12-05 18:41:00.358928442
+0000
@@ -364,4 +364,7 @@ void mb_cpu_unassigned_access(CPUState *
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-mips/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-mips/cpu.h 2014-12-05 18:40:55.358929758
+0000
+++ qemu-git-trunk/target-mips/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -1008,4 +1008,38 @@ static inline void cpu_mips_store_cause(
}
#endif
+/* Macros below used by gdbstub. */
+#define target_address(cs, addr) mips_address(&MIPS_CPU(cs)->env, (addr))
+
+/* System emulation always uses the processor's native register size;
+ any processor that supports at least MIPS III instructions has 64-bit
+ registers. User emulation uses the ABI register size. */
+#ifndef CONFIG_USER_ONLY
+# define mips64_p(env) (((env)->insn_flags & ISA_MIPS3) != 0)
+# define mips_address(env, addr) \
+ (mips64_p(env) ? (addr) : ((int64_t)(int32_t)(addr)))
+# define mips_get_reg(env, buf, val) \
+ (mips64_p(env) ? gdb_get_reg64((buf), (val)) : gdb_get_reg32((buf), (val)))
+# define mips_set_reg(env, buf) \
+ (mips64_p(env) ? ldq_p(buf) : ((int64_t)(int32_t)ldl_p(buf)))
+# define mips_regsize(env) (4 << mips64_p(env))
+#elif defined(TARGET_ABI_MIPSN64)
+# define mips_address(env, addr) (addr)
+# define mips_get_reg(env, buf, val) gdb_get_reg64((buf), (val))
+# define mips_set_reg(env, buf) ldq_p(buf)
+# define mips_regsize(env) 8
+#elif defined(TARGET_ABI_MIPSN32)
+# define mips_address(env, addr) ((int64_t)(int32_t)(addr))
+# define mips_get_reg(env, buf, val) gdb_get_reg64((buf), (val))
+# define mips_set_reg(env, buf) ldq_p(buf)
+# define mips_regsize(env) 8
+#elif defined(TARGET_ABI_MIPSO32)
+# define mips_address(env, addr) ((int64_t)(int32_t)(addr))
+# define mips_get_reg(env, buf, val) gdb_get_reg32((buf), (val))
+# define mips_set_reg(env, buf) (((int64_t)(int32_t)ldl_p(buf)))
+# define mips_regsize(env) 4
+#else
+# error Unsupported user-mode MIPS ABI
+#endif
+
#endif /* !defined (__MIPS_CPU_H__) */
Index: qemu-git-trunk/target-mips/gdbstub.c
===================================================================
--- qemu-git-trunk.orig/target-mips/gdbstub.c 2014-12-05 18:40:52.857534413
+0000
+++ qemu-git-trunk/target-mips/gdbstub.c 2014-12-05 18:41:00.358928442
+0000
@@ -21,54 +21,56 @@
#include "qemu-common.h"
#include "exec/gdbstub.h"
+#include "cpu.h"
+
int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env;
if (n < 32) {
- return gdb_get_regl(mem_buf, env->active_tc.gpr[n]);
+ return mips_get_reg(env, mem_buf, env->active_tc.gpr[n]);
}
if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) {
switch (n) {
case 70:
- return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31);
+ return mips_get_reg(env, mem_buf, (int32_t)env->active_fpu.fcr31);
case 71:
- return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0);
+ return mips_get_reg(env, mem_buf, (int32_t)env->active_fpu.fcr0);
default:
if (env->CP0_Status & (1 << CP0St_FR)) {
- return gdb_get_regl(mem_buf,
+ return mips_get_reg(env, mem_buf,
env->active_fpu.fpr[n - 38].d);
} else {
- return gdb_get_regl(mem_buf,
+ return mips_get_reg(env, mem_buf,
env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
}
}
}
switch (n) {
case 32:
- return gdb_get_regl(mem_buf, (int32_t)env->CP0_Status);
+ return mips_get_reg(env, mem_buf, (int32_t)env->CP0_Status);
case 33:
- return gdb_get_regl(mem_buf, env->active_tc.LO[0]);
+ return mips_get_reg(env, mem_buf, env->active_tc.LO[0]);
case 34:
- return gdb_get_regl(mem_buf, env->active_tc.HI[0]);
+ return mips_get_reg(env, mem_buf, env->active_tc.HI[0]);
case 35:
- return gdb_get_regl(mem_buf, env->CP0_BadVAddr);
+ return mips_get_reg(env, mem_buf, env->CP0_BadVAddr);
case 36:
- return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause);
+ return mips_get_reg(env, mem_buf, (int32_t)env->CP0_Cause);
case 37:
- return gdb_get_regl(mem_buf, env->active_tc.PC |
- !!(env->hflags & MIPS_HFLAG_M16));
+ return mips_get_reg(env, mem_buf, env->active_tc.PC |
+ !!(env->hflags & MIPS_HFLAG_M16));
case 72:
- return gdb_get_regl(mem_buf, 0); /* fp */
+ return mips_get_reg(env, mem_buf, 0); /* fp */
case 89:
- return gdb_get_regl(mem_buf, (int32_t)env->CP0_PRid);
+ return mips_get_reg(env, mem_buf, (int32_t)env->CP0_PRid);
default:
if (n > 89) {
return 0;
}
/* 16 embedded regs. */
- return gdb_get_regl(mem_buf, 0);
+ return mips_get_reg(env, mem_buf, 0);
}
return 0;
@@ -80,11 +82,11 @@ int mips_cpu_gdb_write_register(CPUState
CPUMIPSState *env = &cpu->env;
target_ulong tmp;
- tmp = ldtul_p(mem_buf);
+ tmp = mips_set_reg(env, mem_buf);
if (n < 32) {
env->active_tc.gpr[n] = tmp;
- return sizeof(target_ulong);
+ return mips_regsize(env);
}
if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) {
switch (n) {
@@ -106,7 +108,7 @@ int mips_cpu_gdb_write_register(CPUState
}
break;
}
- return sizeof(target_ulong);
+ return mips_regsize(env);
}
switch (n) {
case 32:
@@ -146,5 +148,5 @@ int mips_cpu_gdb_write_register(CPUState
break;
}
- return sizeof(target_ulong);
+ return mips_regsize(env);
}
Index: qemu-git-trunk/target-moxie/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-moxie/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-moxie/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -155,4 +155,7 @@ static inline void cpu_get_tb_cpu_state(
int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
int rw, int mmu_idx);
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* _CPU_MOXIE_H */
Index: qemu-git-trunk/target-openrisc/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-openrisc/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-openrisc/cpu.h 2014-12-05 18:41:00.358928442
+0000
@@ -427,4 +427,7 @@ static inline target_ulong cpu_get_pc(CP
return env->pc;
}
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* CPU_OPENRISC_H */
Index: qemu-git-trunk/target-ppc/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-ppc/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-ppc/cpu.h 2014-12-05 18:41:00.358928442 +0000
@@ -2310,4 +2310,7 @@ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
*/
PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* !defined (__CPU_PPC_H__) */
Index: qemu-git-trunk/target-s390x/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-s390x/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-s390x/cpu.h 2014-12-05 18:41:00.858923584 +0000
@@ -1149,4 +1149,7 @@ static inline int s390_assign_subch_ioev
}
}
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-sh4/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-sh4/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-sh4/cpu.h 2014-12-05 18:41:00.858923584 +0000
@@ -354,4 +354,7 @@ static inline void cpu_get_tb_cpu_state(
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* _CPU_SH4_H */
Index: qemu-git-trunk/target-sparc/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-sparc/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-sparc/cpu.h 2014-12-05 18:41:00.858923584 +0000
@@ -753,4 +753,7 @@ static inline bool tb_am_enabled(int tb_
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
Index: qemu-git-trunk/target-tricore/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-tricore/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-tricore/cpu.h 2014-12-05 18:41:00.858923584 +0000
@@ -400,4 +400,7 @@ static inline void cpu_pc_from_tb(CPUTri
env->PC = tb->pc;
}
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /*__TRICORE_CPU_H__ */
Index: qemu-git-trunk/target-unicore32/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-unicore32/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-unicore32/cpu.h 2014-12-05 18:41:00.858923584
+0000
@@ -159,4 +159,7 @@ int uc32_cpu_handle_mmu_fault(CPUState *
void uc32_translate_init(void);
void switch_mode(CPUUniCore32State *, int);
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif /* QEMU_UNICORE32_CPU_H */
Index: qemu-git-trunk/target-xtensa/cpu.h
===================================================================
--- qemu-git-trunk.orig/target-xtensa/cpu.h 2014-12-05 18:38:40.847529339
+0000
+++ qemu-git-trunk/target-xtensa/cpu.h 2014-12-05 18:41:00.858923584 +0000
@@ -533,4 +533,7 @@ static inline void cpu_get_tb_cpu_state(
#include "exec/cpu-all.h"
#include "exec/exec-all.h"
+/* Used by gdbstub. */
+#define target_address(cs, addr) (addr)
+
#endif
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, (continued)
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, Peter Maydell, 2014/12/10
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, Maciej W. Rozycki, 2014/12/10
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, Peter Maydell, 2014/12/10
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, Maciej W. Rozycki, 2014/12/10
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, Peter Maydell, 2014/12/11
- Re: [Qemu-devel] [PATCH 1/3] target-mips: Add n32/n64 configuration files, Maciej W. Rozycki, 2014/12/11
[Qemu-devel] [PATCH 2/3] target-mips: Rework ABIs to allow all required configurations, Maciej W. Rozycki, 2014/12/10
[Qemu-devel] [PATCH 3/3] target-mips: Set GDB register widths correctly, Maciej W. Rozycki, 2014/12/10
[Qemu-devel] [PATCH v2 1/2] target-mips: Rework ABIs to allow all required configurations, Maciej W. Rozycki, 2014/12/10
[Qemu-devel] [PATCH v2 2/2] target-mips: Set GDB register widths correctly,
Maciej W. Rozycki <=