All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub
@ 2013-06-29 20:01 Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
                   ` (41 more replies)
  0 siblings, 42 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Green, Blue Swirl, Max Filippov, jan.kiszka,
	Anthony Liguori, Paolo Bonzini, Guan Xuetao, Andreas Färber,
	Aurélien Jarno

Hello,

This series cleans up gdbstub by changing all its internal CPU state to CPUState
and by moving most target-specific code into the target directories.

It depends on part 10 and starts with a follow-up, consolidating reset logging.

Support for m68k, moxie and unicore32 to set the PC via gdbstub is added.

Lightweight subclasses for XtensaCPU are introduced, keeping the XtensaConfig
mechanisms, to stop xtensa from deviating at gdbstub level wrt register count.

I'm wondering whether there would be interest in adding a "program-counter"
dynamic property to the CPU, given that a setter has been factored out here?

Available for testing at:
git://github.com/afaerber/qemu-cpu.git qom-cpu-11.v1
https://github.com/afaerber/qemu-cpu/commits/qom-cpu-11.v1

Regards,
Andreas

Cc: Anthony Liguori <anthony@codemonkey.ws>
Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Aurélien Jarno <aurelien@aurel32.net>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Jan Kiszka <jan.kiszka@web.de> (gdbstub)
Cc: Anthony Green <green@moxielogic.com> (moxie)
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn> (unicore32)
Cc: Max Filippov <jcmvbkbc@gmail.com> (xtensa)

Andreas Färber (41):
  log: Change log_cpu_state[_mask]() argument to CPUState
  cpu: Move reset logging to CPUState
  gdbstub: Change GDBState::query_cpu to CPUState
  cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  target-m68k: Implement CPUClass::set_pc()
  target-moxie: Implement CPUClass::set_pc()
  target-unicore32: Implement CPUClass::set_pc()
  cpu: Introduce CPUClass::synchronize_from_tb() to drop
    cpu_pc_from_tb()
  gdbstub: Replace two find_cpu() with qemu_get_cpu()
  target-alpha: Change gen_intermediate_code_internal() argument to
    AlphaCPU
  target-arm: Change gen_intermediate_code_internal() argument to ARMCPU
  target-cris: Change gen_intermediate_code_internal() argument to
    CRISCPU
  target-i386: Change gen_intermediate_code_internal() argument to
    X86CPU
  target-lm32: Change gen_intermediate_code_internal() argument to
    LM32CPU
  target-m68k: Change gen_intermediate_code_internal() argument to
    M68kCPU
  target-microblaze: Change gen_intermediate_code_internal() argument
    types
  target-mips: Change gen_intermediate_code_internal() argument to
    MIPSCPU
  target-ppc: Change gen_intermediate_code_internal() argument to
    PowerPCCPU
  target-s390x: Change gen_intermediate_code_internal() argument to
    S390CPU
  target-sh4: Change gen_intermediate_code_internal() argument to
    SuperHCPU
  target-sparc: Change gen_intermediate_code_internal() argument to
    SPARCCPU
  target-unicore32: Change gen_intermediate_code_internal() signature
  target-xtensa: Change gen_intermediate_code_internal() arg to
    XtensaCPU
  target-alpha: Change DisasContext::env to CPUState
  cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
  gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
  cpu: Change cpu_single_step() argument to CPUState
  kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState
  gdbstub: Change syscall callback argument to CPUState
  gdbstub: Change gdb_handlesig() argument to CPUState
  gdbstub: Change GDBState::c_cpu to CPUState
  gdbstub: Change gdb_{read,write}_register() argument to CPUState
  cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
  exec: Change cpu_memory_rw_debug() argument to CPUState
  cpu: Introduce CPUClass::memory_rw_debug() for
    target_memory_rw_debug()
  gdbstub: Change GDBState::g_cpu to CPUState
  cpu: Move gdb_regs field from CPU_COMMON to CPUState
  gdbstub: Change gdb_register_coprocessor() argument to CPUState
  target-xtensa: Introduce XtensaCPU subclasses
  gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass
  cpu: Introduce CPUClass::gdb_{read,write}_register()

 bsd-user/main.c                 |   10 +-
 cpu-exec.c                      |   16 +-
 cpus.c                          |    6 +-
 disas.c                         |    4 +-
 exec.c                          |   38 +-
 gdbstub.c                       | 1590 ++++-----------------------------------
 hw/i386/kvmvapic.c              |   78 +-
 hw/xtensa/pic_cpu.c             |   47 +-
 include/exec/cpu-all.h          |   14 +-
 include/exec/cpu-defs.h         |    3 -
 include/exec/exec-all.h         |    3 -
 include/exec/gdbstub.h          |   45 +-
 include/exec/softmmu-semi.h     |   18 +-
 include/qemu/log.h              |   26 +-
 include/qemu/typedefs.h         |    3 +
 include/qom/cpu.h               |   95 ++-
 include/sysemu/kvm.h            |    4 +-
 kvm-all.c                       |   12 +-
 kvm-stub.c                      |    4 +-
 linux-user/main.c               |   40 +-
 linux-user/signal.c             |    3 +-
 monitor.c                       |    2 +-
 qom/cpu.c                       |   30 +
 target-alpha/Makefile.objs      |    1 +
 target-alpha/cpu-qom.h          |    3 +
 target-alpha/cpu.c              |   18 +-
 target-alpha/cpu.h              |    5 -
 target-alpha/gdbstub.c          |   93 +++
 target-alpha/helper.c           |    5 +-
 target-alpha/translate.c        |   25 +-
 target-arm/Makefile.objs        |    1 +
 target-arm/arm-semi.c           |   10 +-
 target-arm/cpu-qom.h            |    5 +
 target-arm/cpu.c                |   21 +-
 target-arm/cpu.h                |    5 -
 target-arm/gdbstub.c            |  102 +++
 target-arm/helper.c             |   15 +-
 target-arm/translate.c          |   16 +-
 target-cris/Makefile.objs       |    1 +
 target-cris/cpu-qom.h           |    6 +
 target-cris/cpu.c               |   24 +-
 target-cris/cpu.h               |    4 -
 target-cris/gdbstub.c           |  130 ++++
 target-cris/helper.c            |    7 +-
 target-cris/translate.c         |   16 +-
 target-i386/Makefile.objs       |    1 +
 target-i386/cpu-qom.h           |    5 +
 target-i386/cpu.c               |   28 +-
 target-i386/cpu.h               |    5 -
 target-i386/gdbstub.c           |  231 ++++++
 target-i386/helper.c            |   12 +-
 target-i386/kvm.c               |   20 +-
 target-i386/seg_helper.c        |    5 +-
 target-i386/smm_helper.c        |    6 +-
 target-i386/translate.c         |   14 +-
 target-lm32/Makefile.objs       |    1 +
 target-lm32/cpu-qom.h           |    3 +
 target-lm32/cpu.c               |   21 +-
 target-lm32/cpu.h               |    5 -
 target-lm32/gdbstub.c           |   92 +++
 target-lm32/helper.c            |   10 +-
 target-lm32/translate.c         |   16 +-
 target-m68k/Makefile.objs       |    1 +
 target-m68k/cpu-qom.h           |    3 +
 target-m68k/cpu.c               |   19 +-
 target-m68k/cpu.h               |    5 -
 target-m68k/gdbstub.c           |   75 ++
 target-m68k/helper.c            |    5 +-
 target-m68k/m68k-semi.c         |    5 +-
 target-m68k/translate.c         |   16 +-
 target-microblaze/Makefile.objs |    1 +
 target-microblaze/cpu-qom.h     |    3 +
 target-microblaze/cpu.c         |   21 +-
 target-microblaze/cpu.h         |    5 -
 target-microblaze/gdbstub.c     |   56 ++
 target-microblaze/helper.c      |   16 +-
 target-microblaze/translate.c   |   19 +-
 target-mips/Makefile.objs       |    1 +
 target-mips/cpu-qom.h           |    3 +
 target-mips/cpu.c               |   39 +-
 target-mips/cpu.h               |    7 -
 target-mips/gdbstub.c           |  154 ++++
 target-mips/helper.c            |    9 +-
 target-mips/translate.c         |   20 +-
 target-moxie/cpu.c              |   18 +-
 target-moxie/cpu.h              |    6 +-
 target-moxie/helper.c           |   11 +-
 target-moxie/translate.c        |    5 +-
 target-openrisc/Makefile.objs   |    1 +
 target-openrisc/cpu.c           |   21 +-
 target-openrisc/cpu.h           |    8 +-
 target-openrisc/gdbstub.c       |   86 +++
 target-openrisc/mmu.c           |    5 +-
 target-openrisc/translate.c     |    9 +-
 target-ppc/Makefile.objs        |    1 +
 target-ppc/cpu-qom.h            |    3 +
 target-ppc/cpu.h                |    5 -
 target-ppc/gdbstub.c            |  131 ++++
 target-ppc/mmu-hash32.c         |    2 +-
 target-ppc/mmu-hash64.c         |    2 +-
 target-ppc/mmu_helper.c         |    6 +-
 target-ppc/translate.c          |   17 +-
 target-ppc/translate_init.c     |   32 +-
 target-s390x/Makefile.objs      |    1 +
 target-s390x/cpu-qom.h          |    3 +
 target-s390x/cpu.c              |   19 +-
 target-s390x/cpu.h              |    5 -
 target-s390x/gdbstub.c          |   88 +++
 target-s390x/helper.c           |    5 +-
 target-s390x/translate.c        |   14 +-
 target-sh4/Makefile.objs        |    1 +
 target-sh4/cpu-qom.h            |    3 +
 target-sh4/cpu.c                |   28 +-
 target-sh4/cpu.h                |    6 -
 target-sh4/gdbstub.c            |  146 ++++
 target-sh4/helper.c             |    7 +-
 target-sh4/translate.c          |   17 +-
 target-sparc/Makefile.objs      |    1 +
 target-sparc/cpu-qom.h          |    3 +
 target-sparc/cpu.c              |   39 +-
 target-sparc/cpu.h              |   11 +-
 target-sparc/gdbstub.c          |  208 +++++
 target-sparc/int32_helper.c     |    2 +-
 target-sparc/int64_helper.c     |    2 +-
 target-sparc/mmu_helper.c       |   22 +-
 target-sparc/translate.c        |   13 +-
 target-unicore32/cpu-qom.h      |    1 +
 target-unicore32/cpu.c          |   11 +
 target-unicore32/cpu.h          |    5 -
 target-unicore32/softmmu.c      |    7 +-
 target-unicore32/translate.c    |   16 +-
 target-xtensa/Makefile.objs     |    1 +
 target-xtensa/cpu-qom.h         |    6 +
 target-xtensa/cpu.c             |   46 +-
 target-xtensa/cpu.h             |   27 +-
 target-xtensa/gdbstub.c         |  111 +++
 target-xtensa/helper.c          |  108 ++-
 target-xtensa/op_helper.c       |  121 ++-
 target-xtensa/translate.c       |   29 +-
 target-xtensa/xtensa-semi.c     |   14 +-
 140 files changed, 2965 insertions(+), 2113 deletions(-)
 create mode 100644 target-alpha/gdbstub.c
 create mode 100644 target-arm/gdbstub.c
 create mode 100644 target-cris/gdbstub.c
 create mode 100644 target-i386/gdbstub.c
 create mode 100644 target-lm32/gdbstub.c
 create mode 100644 target-m68k/gdbstub.c
 create mode 100644 target-microblaze/gdbstub.c
 create mode 100644 target-mips/gdbstub.c
 create mode 100644 target-openrisc/gdbstub.c
 create mode 100644 target-ppc/gdbstub.c
 create mode 100644 target-s390x/gdbstub.c
 create mode 100644 target-sh4/gdbstub.c
 create mode 100644 target-sparc/gdbstub.c
 create mode 100644 target-xtensa/gdbstub.c

-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:03   ` Richard Henderson
  2013-07-02  1:26   ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
                   ` (40 subsequent siblings)
  41 siblings, 2 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Anthony Green, Riku Voipio,
	Alexander Graf, Blue Swirl, Michael Walle, jan.kiszka,
	Paul Brook, Edgar E. Iglesias, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Since commit 878096eeb278a8ac1ccd6667af73e026f29b4cf5 (cpu: Turn
cpu_dump_{state,statistics}() into CPUState hooks) CPUArchState is no
longer needed.

Add documentation and make the functions available through qemu/log.h
outside NEED_CPU_H to allow use in qom/cpu.c. Moving them to qom/cpu.h
was not yet possible due to convoluted include paths, so that some
devices grow an implicit and unneeded dependency on qom/cpu.h for now.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c                    |  6 +++---
 exec.c                        |  2 +-
 include/qemu/log.h            | 26 +++++++++++++++++++++-----
 linux-user/main.c             |  5 +++--
 target-arm/cpu.c              |  2 +-
 target-cris/cpu.c             |  2 +-
 target-i386/cpu.c             |  2 +-
 target-i386/seg_helper.c      |  5 +++--
 target-i386/smm_helper.c      |  6 ++++--
 target-lm32/cpu.c             |  2 +-
 target-lm32/helper.c          |  4 ++--
 target-m68k/cpu.c             |  2 +-
 target-microblaze/cpu.c       |  2 +-
 target-microblaze/helper.c    | 12 ++++++------
 target-microblaze/translate.c |  5 ++++-
 target-mips/cpu.c             |  2 +-
 target-mips/helper.c          |  2 +-
 target-moxie/cpu.c            |  2 +-
 target-openrisc/cpu.c         |  2 +-
 target-openrisc/translate.c   |  2 +-
 target-ppc/mmu-hash32.c       |  2 +-
 target-ppc/mmu-hash64.c       |  2 +-
 target-ppc/mmu_helper.c       |  2 +-
 target-ppc/translate_init.c   |  2 +-
 target-s390x/cpu.c            |  2 +-
 target-sh4/cpu.c              |  2 +-
 target-sh4/helper.c           |  2 +-
 target-sparc/cpu.c            |  2 +-
 target-sparc/int32_helper.c   |  2 +-
 target-sparc/int64_helper.c   |  2 +-
 30 files changed, 68 insertions(+), 45 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 503b103..9c46846 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -577,15 +577,15 @@ int cpu_exec(CPUArchState *env)
                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
                     /* restore flags in standard format */
 #if defined(TARGET_I386)
-                    log_cpu_state(env, CPU_DUMP_CCOP);
+                    log_cpu_state(cpu, CPU_DUMP_CCOP);
 #elif defined(TARGET_M68K)
                     cpu_m68k_flush_flags(env, env->cc_op);
                     env->cc_op = CC_OP_FLAGS;
                     env->sr = (env->sr & 0xffe0)
                               | env->cc_dest | (env->cc_x << 4);
-                    log_cpu_state(env, 0);
+                    log_cpu_state(cpu, 0);
 #else
-                    log_cpu_state(env, 0);
+                    log_cpu_state(cpu, 0);
 #endif
                 }
 #endif /* DEBUG_DISAS */
diff --git a/exec.c b/exec.c
index fe419f7..4e20143 100644
--- a/exec.c
+++ b/exec.c
@@ -613,7 +613,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
         qemu_log("qemu: fatal: ");
         qemu_log_vprintf(fmt, ap2);
         qemu_log("\n");
-        log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+        log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP);
         qemu_log_flush();
         qemu_log_close();
     }
diff --git a/include/qemu/log.h b/include/qemu/log.h
index a9cf214..d515424 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -5,6 +5,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include "qemu/compiler.h"
+#include "qom/cpu.h"
 #ifdef NEED_CPU_H
 #include "disas/disas.h"
 #endif
@@ -70,22 +71,37 @@ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
 
 /* Special cases: */
 
-#ifdef NEED_CPU_H
 /* cpu_dump_state() logging functions: */
-static inline void log_cpu_state(CPUArchState *env1, int flags)
+/**
+ * log_cpu_state:
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state().
+ */
+static inline void log_cpu_state(CPUState *cpu, int flags)
 {
     if (qemu_log_enabled()) {
-        cpu_dump_state(ENV_GET_CPU(env1), qemu_logfile, fprintf, flags);
+        cpu_dump_state(cpu, qemu_logfile, fprintf, flags);
     }
 }
 
-static inline void log_cpu_state_mask(int mask, CPUArchState *env1, int flags)
+/**
+ * log_cpu_state_mask:
+ * @mask: Mask when to log.
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state() if loglevel includes @mask.
+ */
+static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags)
 {
     if (qemu_loglevel & mask) {
-        log_cpu_state(env1, flags);
+        log_cpu_state(cpu, flags);
     }
 }
 
+#ifdef NEED_CPU_H
 /* disas() and target_disas() to qemu_logfile: */
 static inline void log_target_disas(CPUArchState *env, target_ulong start,
                                     target_ulong len, int flags)
diff --git a/linux-user/main.c b/linux-user/main.c
index 67ea9ba..7f15d3d 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1302,11 +1302,12 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
 
 #define EXCP_DUMP(env, fmt, ...)                                        \
 do {                                                                    \
+    CPUState *cs = ENV_GET_CPU(env);                                    \
     fprintf(stderr, fmt , ## __VA_ARGS__);                              \
-    cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0);               \
+    cpu_dump_state(cs, stderr, fprintf, 0);                             \
     qemu_log(fmt, ## __VA_ARGS__);                                      \
     if (qemu_log_enabled()) {                                           \
-        log_cpu_state(env, 0);                                          \
+        log_cpu_state(cs, 0);                                           \
     }                                                                   \
 } while (0)
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 1bc227e..84974a9 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -65,7 +65,7 @@ static void arm_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     acc->parent_reset(s);
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 6a3bdf0..f6c4f3f 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -36,7 +36,7 @@ static void cris_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     ccc->parent_reset(s);
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index b7416fe..82a451b 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2177,7 +2177,7 @@ static void x86_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+        log_cpu_state(s, CPU_DUMP_FPU | CPU_DUMP_CCOP);
     }
 
     xcc->parent_reset(s);
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 9c799e1..42ee823 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -31,7 +31,7 @@
 #ifdef DEBUG_PCALL
 # define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
 # define LOG_PCALL_STATE(env)                                  \
-    log_cpu_state_mask(CPU_LOG_PCALL, (env), CPU_DUMP_CCOP)
+    log_cpu_state_mask(CPU_LOG_PCALL, CPU(x86_env_get_cpu(env)), CPU_DUMP_CCOP)
 #else
 # define LOG_PCALL(...) do { } while (0)
 # define LOG_PCALL_STATE(env) do { } while (0)
@@ -1165,6 +1165,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
 {
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         if ((env->cr[0] & CR0_PE_MASK)) {
+            X86CPU *cpu = x86_env_get_cpu(env);
             static int count;
 
             qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx
@@ -1180,7 +1181,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
                 qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]);
             }
             qemu_log("\n");
-            log_cpu_state(env, CPU_DUMP_CCOP);
+            log_cpu_state(CPU(cpu), CPU_DUMP_CCOP);
 #if 0
             {
                 int i;
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 2489573..5abdfc8 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -42,12 +42,13 @@ void helper_rsm(CPUX86State *env)
 
 void do_smm_enter(CPUX86State *env)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
     target_ulong sm_state;
     SegmentCache *dt;
     int i, offset;
 
     qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
-    log_cpu_state_mask(CPU_LOG_INT, env, CPU_DUMP_CCOP);
+    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
 
     env->hflags |= HF_SMM_MASK;
     cpu_smm_update(env);
@@ -179,6 +180,7 @@ void do_smm_enter(CPUX86State *env)
 
 void helper_rsm(CPUX86State *env)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
     target_ulong sm_state;
     int i, offset;
     uint32_t val;
@@ -295,7 +297,7 @@ void helper_rsm(CPUX86State *env)
     cpu_smm_update(env);
 
     qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
-    log_cpu_state_mask(CPU_LOG_INT, env, CPU_DUMP_CCOP);
+    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
 }
 
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 02f8436..6e44d45 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -31,7 +31,7 @@ static void lm32_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     lcc->parent_reset(s);
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 03fa5fb..615b44e 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -70,7 +70,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
         } else {
             env->pc = env->eba + (env->exception_index * 32);
         }
-        log_cpu_state_mask(CPU_LOG_INT, env, 0);
+        log_cpu_state_mask(CPU_LOG_INT, cs, 0);
         break;
     case EXCP_BREAKPOINT:
     case EXCP_WATCHPOINT:
@@ -79,7 +79,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
         env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
         env->ie &= ~IE_IE;
         env->pc = env->deba + (env->exception_index * 32);
-        log_cpu_state_mask(CPU_LOG_INT, env, 0);
+        log_cpu_state_mask(CPU_LOG_INT, cs, 0);
         break;
     default:
         cpu_abort(env, "unhandled exception type=%d\n",
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 799869f..c9ac30f 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -37,7 +37,7 @@ static void m68k_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index a0fcdf4..d93519e 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -35,7 +35,7 @@ static void mb_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 01d4bbf..86aad6a 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -152,7 +152,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                           "hw exception at pc=%x ear=%x esr=%x iflags=%x\n",
                           env->sregs[SR_PC], env->sregs[SR_EAR],
                           env->sregs[SR_ESR], env->iflags);
-            log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
             env->sregs[SR_PC] = cpu->base_vectors + 0x20;
             break;
@@ -175,7 +175,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                                   "bimm exception at pc=%x iflags=%x\n",
                                   env->sregs[SR_PC], env->iflags);
                     env->regs[17] -= 4;
-                    log_cpu_state_mask(CPU_LOG_INT, env, 0);
+                    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
                 }
             } else if (env->iflags & IMM_FLAG) {
                 D(qemu_log("IMM_FLAG set at exception\n"));
@@ -192,7 +192,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                           "exception at pc=%x ear=%x iflags=%x\n",
                           env->sregs[SR_PC], env->sregs[SR_EAR], env->iflags);
-            log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
             env->sregs[SR_PC] = cpu->base_vectors + 0x20;
             break;
@@ -222,7 +222,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                          env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags,
                          sym);
 
-                    log_cpu_state(env, 0);
+                    log_cpu_state(CPU(cpu), 0);
                 }
             }
 #endif
@@ -236,7 +236,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
 
             env->regs[14] = env->sregs[SR_PC];
             env->sregs[SR_PC] = cpu->base_vectors + 0x10;
-            //log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            //log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
             break;
 
         case EXCP_BREAK:
@@ -247,7 +247,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                         "break at pc=%x msr=%x %x iflags=%x\n",
                         env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);
-            log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
             env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             env->sregs[SR_MSR] |= t;
             env->sregs[SR_MSR] |= MSR_BIP;
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 54f439f..f9acdb1 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1741,6 +1741,9 @@ static void
 gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
                                int search_pc)
 {
+#if !SIM_COMPAT
+    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
+#endif
     uint16_t *gen_opc_end;
     uint32_t pc_start;
     int j, lj;
@@ -1776,7 +1779,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 #if !SIM_COMPAT
         qemu_log("--------------\n");
-        log_cpu_state(env, 0);
+        log_cpu_state(CPU(cpu), 0);
 #endif
     }
 
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index b61e207..cab9572 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -31,7 +31,7 @@ static void mips_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 36929dd..6983b92 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -276,7 +276,7 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
     int ret = 0;
 
 #if 0
-    log_cpu_state(env, 0);
+    log_cpu_state(CPU(mips_env_get_cpu(env)), 0);
 #endif
     qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n",
               __func__, env->active_tc.PC, address, rw, mmu_idx);
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index f3c0d22..7314d4b 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -30,7 +30,7 @@ static void moxie_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index fd90d37..cab5b52 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -28,7 +28,7 @@ static void openrisc_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(&cpu->env, 0);
+        log_cpu_state(s, 0);
     }
 
     occ->parent_reset(s);
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index c59fd02..f222834 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1684,7 +1684,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
     dc->singlestep_enabled = cpu->env.singlestep_enabled;
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("-----------------------------------------\n");
-        log_cpu_state(&cpu->env, 0);
+        log_cpu_state(CPU(cpu), 0);
     }
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index f6adf22..b5ebe07 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -29,7 +29,7 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
 #  define LOG_MMU_STATE(...) do { } while (0)
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 5c67ec3..759cef3 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -28,7 +28,7 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
 #  define LOG_MMU_STATE(...) do { } while (0)
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 53deba5..26f513f 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -32,7 +32,7 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
 #  define LOG_MMU_STATE(...) do { } while (0)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index fa5e09f..3700a1a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8188,7 +8188,7 @@ static void ppc_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     pcc->parent_reset(s);
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index c3697cd..732d393 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -67,7 +67,7 @@ static void s390_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     s390_del_running_cpu(cpu);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index e739156..653acec 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -33,7 +33,7 @@ static void superh_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     scc->parent_reset(s);
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index ce10ca8..cb6a2d2 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -159,7 +159,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
 	}
 	qemu_log("exception 0x%03x [%s] raised\n",
 		  irq_vector, expname);
-	log_cpu_state(env, 0);
+        log_cpu_state(cs, 0);
     }
 
     env->ssr = env->sr;
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 65ae6f7..4cbb206 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -32,7 +32,7 @@ static void sparc_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     scc->parent_reset(s);
diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c
index 7221460..d532238 100644
--- a/target-sparc/int32_helper.c
+++ b/target-sparc/int32_helper.c
@@ -86,7 +86,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
         }
 
         qemu_log("%6d: %s (v=%02x)\n", count, name, intno);
-        log_cpu_state(env, 0);
+        log_cpu_state(cs, 0);
 #if 0
         {
             int i;
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index f411884..bf7dd86 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -92,7 +92,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
         }
 
         qemu_log("%6d: %s (v=%04x)\n", count, name, intno);
-        log_cpu_state(env, 0);
+        log_cpu_state(cs, 0);
 #if 0
         {
             int i;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:04   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu " Andreas Färber
                   ` (39 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Anthony Green, Alexander Graf,
	Blue Swirl, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Andreas Färber, Aurelien Jarno,
	Richard Henderson

x86 was using additional CPU_DUMP_* flags, so make that configurable in
CPUClass::reset_dump_flags.

This adds reset logging for alpha, unicore32 and xtensa.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/qom/cpu.h           | 2 ++
 qom/cpu.c                   | 8 ++++++++
 target-arm/cpu.c            | 5 -----
 target-cris/cpu.c           | 5 -----
 target-i386/cpu.c           | 6 +-----
 target-lm32/cpu.c           | 5 -----
 target-m68k/cpu.c           | 5 -----
 target-microblaze/cpu.c     | 5 -----
 target-mips/cpu.c           | 5 -----
 target-moxie/cpu.c          | 5 -----
 target-openrisc/cpu.c       | 5 -----
 target-ppc/translate_init.c | 5 -----
 target-s390x/cpu.c          | 5 -----
 target-sh4/cpu.c            | 5 -----
 target-sparc/cpu.c          | 5 -----
 15 files changed, 11 insertions(+), 65 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index a08a8ab..147c256 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -53,6 +53,7 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
  * @class_by_name: Callback to map -cpu command line model name to an
  * instantiatable CPU type.
  * @reset: Callback to reset the #CPUState to its initial state.
+ * @reset_dump_flags: #CPUDumpFlags to use for reset logging.
  * @do_interrupt: Callback for interrupt handling.
  * @do_unassigned_access: Callback for unassigned access handling.
  * @dump_state: Callback for dumping state.
@@ -72,6 +73,7 @@ typedef struct CPUClass {
     ObjectClass *(*class_by_name)(const char *cpu_model);
 
     void (*reset)(CPUState *cpu);
+    int reset_dump_flags;
     void (*do_interrupt)(CPUState *cpu);
     CPUUnassignedAccess do_unassigned_access;
     void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
diff --git a/qom/cpu.c b/qom/cpu.c
index ee8f632..5c45ab5 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -22,6 +22,7 @@
 #include "qom/cpu.h"
 #include "sysemu/kvm.h"
 #include "qemu/notify.h"
+#include "qemu/log.h"
 #include "sysemu/sysemu.h"
 
 typedef struct CPUExistsArgs {
@@ -187,6 +188,13 @@ void cpu_reset(CPUState *cpu)
 
 static void cpu_common_reset(CPUState *cpu)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index);
+        log_cpu_state(cpu, cc->reset_dump_flags);
+    }
+
     cpu->exit_request = 0;
     cpu->interrupt_request = 0;
     cpu->current_tb = NULL;
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 84974a9..be26acc 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -63,11 +63,6 @@ static void arm_cpu_reset(CPUState *s)
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
     CPUARMState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     acc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUARMState, breakpoints));
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index f6c4f3f..2abb57f 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -34,11 +34,6 @@ static void cris_cpu_reset(CPUState *s)
     CPUCRISState *env = &cpu->env;
     uint32_t vr;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     ccc->parent_reset(s);
 
     vr = env->pregs[PR_VR];
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 82a451b..e3f75a8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2175,11 +2175,6 @@ static void x86_cpu_reset(CPUState *s)
     CPUX86State *env = &cpu->env;
     int i;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, CPU_DUMP_FPU | CPU_DUMP_CCOP);
-    }
-
     xcc->parent_reset(s);
 
 
@@ -2523,6 +2518,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 
     xcc->parent_reset = cc->reset;
     cc->reset = x86_cpu_reset;
+    cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
 
     cc->do_interrupt = x86_cpu_do_interrupt;
     cc->dump_state = x86_cpu_dump_state;
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 6e44d45..04327ac 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -29,11 +29,6 @@ static void lm32_cpu_reset(CPUState *s)
     LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
     CPULM32State *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     lcc->parent_reset(s);
 
     /* reset cpu state */
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index c9ac30f..1b6ef66 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -35,11 +35,6 @@ static void m68k_cpu_reset(CPUState *s)
     M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
     CPUM68KState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUM68KState, breakpoints));
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index d93519e..dce1c7e 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -33,11 +33,6 @@ static void mb_cpu_reset(CPUState *s)
     MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(cpu);
     CPUMBState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUMBState, breakpoints));
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index cab9572..60a3faf 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -29,11 +29,6 @@ static void mips_cpu_reset(CPUState *s)
     MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
     CPUMIPSState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 7314d4b..92ca594 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -28,11 +28,6 @@ static void moxie_cpu_reset(CPUState *s)
     MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
     CPUMoxieState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUMoxieState, breakpoints));
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index cab5b52..8bced98 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -26,11 +26,6 @@ static void openrisc_cpu_reset(CPUState *s)
     OpenRISCCPU *cpu = OPENRISC_CPU(s);
     OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     occ->parent_reset(s);
 
     memset(&cpu->env, 0, offsetof(CPUOpenRISCState, breakpoints));
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3700a1a..95b0b21 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8186,11 +8186,6 @@ static void ppc_cpu_reset(CPUState *s)
     CPUPPCState *env = &cpu->env;
     target_ulong msr;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     pcc->parent_reset(s);
 
     msr = (target_ulong)0;
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 732d393..1ef2fc0 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -65,11 +65,6 @@ static void s390_cpu_reset(CPUState *s)
     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
     CPUS390XState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     s390_del_running_cpu(cpu);
 
     scc->parent_reset(s);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 653acec..03487eb 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -31,11 +31,6 @@ static void superh_cpu_reset(CPUState *s)
     SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(cpu);
     CPUSH4State *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     scc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUSH4State, breakpoints));
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 4cbb206..87c3a50 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -30,11 +30,6 @@ static void sparc_cpu_reset(CPUState *s)
     SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
     CPUSPARCState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     scc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUSPARCState, breakpoints));
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:05   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc() Andreas Färber
                   ` (38 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Since first_cpu/next_cpu are CPUState, CPUArchState is no longer needed.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 5793bcd..4a0d04e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -289,7 +289,7 @@ enum RSState {
 typedef struct GDBState {
     CPUArchState *c_cpu; /* current CPU for step/continue ops */
     CPUArchState *g_cpu; /* current CPU for other ops */
-    CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */
+    CPUState *query_cpu; /* for q{f|s}ThreadInfo */
     enum RSState state; /* parsing state */
     char line_buf[MAX_PACKET_LENGTH];
     int line_buf_index;
@@ -2399,15 +2399,14 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "QC1");
             break;
         } else if (strcmp(p,"fThreadInfo") == 0) {
-            s->query_cpu = first_cpu->env_ptr;
+            s->query_cpu = first_cpu;
             goto report_cpuinfo;
         } else if (strcmp(p,"sThreadInfo") == 0) {
         report_cpuinfo:
             if (s->query_cpu) {
-                snprintf(buf, sizeof(buf), "m%x",
-                         cpu_index(ENV_GET_CPU(s->query_cpu)));
+                snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
                 put_packet(s, buf);
-                s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
+                s->query_cpu = s->query_cpu->next_cpu;
             } else
                 put_packet(s, "l");
             break;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (2 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:09   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 05/41] target-m68k: Implement CPUClass::set_pc() Andreas Färber
                   ` (37 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Andreas Färber, Aurelien Jarno,
	Richard Henderson

This moves setting the Program Counter from gdbstub into target code.
Use uint64_t type as maximum replacement for target_ulong.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c                   | 39 ++++++---------------------------------
 include/qom/cpu.h           |  1 +
 target-alpha/cpu.c          |  8 ++++++++
 target-arm/cpu.c            |  8 ++++++++
 target-cris/cpu.c           |  8 ++++++++
 target-i386/cpu.c           |  8 ++++++++
 target-lm32/cpu.c           |  8 ++++++++
 target-microblaze/cpu.c     |  8 ++++++++
 target-mips/cpu.c           | 14 ++++++++++++++
 target-openrisc/cpu.c       |  8 ++++++++
 target-ppc/translate_init.c |  8 ++++++++
 target-s390x/cpu.c          |  8 ++++++++
 target-sh4/cpu.c            |  8 ++++++++
 target-sparc/cpu.c          |  9 +++++++++
 target-xtensa/cpu.c         |  8 ++++++++
 15 files changed, 118 insertions(+), 33 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 4a0d04e..bdf4496 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2042,40 +2042,13 @@ static void gdb_breakpoint_remove_all(void)
 
 static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 {
-    cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
-#if defined(TARGET_I386)
-    s->c_cpu->eip = pc;
-#elif defined (TARGET_PPC)
-    s->c_cpu->nip = pc;
-#elif defined (TARGET_SPARC)
-    s->c_cpu->pc = pc;
-    s->c_cpu->npc = pc + 4;
-#elif defined (TARGET_ARM)
-    s->c_cpu->regs[15] = pc;
-#elif defined (TARGET_SH4)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_MIPS)
-    s->c_cpu->active_tc.PC = pc & ~(target_ulong)1;
-    if (pc & 1) {
-        s->c_cpu->hflags |= MIPS_HFLAG_M16;
-    } else {
-        s->c_cpu->hflags &= ~(MIPS_HFLAG_M16);
+    CPUState *cpu = ENV_GET_CPU(s->c_cpu);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    cpu_synchronize_state(cpu);
+    if (cc->set_pc) {
+        cc->set_pc(cpu, pc);
     }
-#elif defined (TARGET_MICROBLAZE)
-    s->c_cpu->sregs[SR_PC] = pc;
-#elif defined(TARGET_OPENRISC)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_CRIS)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_ALPHA)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_S390X)
-    s->c_cpu->psw.addr = pc;
-#elif defined (TARGET_LM32)
-    s->c_cpu->pc = pc;
-#elif defined(TARGET_XTENSA)
-    s->c_cpu->pc = pc;
-#endif
 }
 
 static CPUArchState *find_cpu(uint32_t thread_id)
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 147c256..3701eb1 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -84,6 +84,7 @@ typedef struct CPUClass {
     bool (*get_paging_enabled)(const CPUState *cpu);
     void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
                                Error **errp);
+    void (*set_pc)(CPUState *cpu, uint64_t value);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 2670805..9679ac4 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -24,6 +24,13 @@
 #include "migration/vmstate.h"
 
 
+static void alpha_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev);
@@ -264,6 +271,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);
+    cc->set_pc = alpha_cpu_set_pc;
     device_class_set_vmsd(dc, &vmstate_alpha_cpu);
 }
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index be26acc..281e252 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -25,6 +25,13 @@
 #endif
 #include "sysemu/sysemu.h"
 
+static void arm_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    cpu->env.regs[15] = value;
+}
+
 static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
 {
     /* Reset a single ARMCPRegInfo register */
@@ -811,6 +818,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = arm_cpu_class_by_name;
     cc->do_interrupt = arm_cpu_do_interrupt;
     cc->dump_state = arm_cpu_dump_state;
+    cc->set_pc = arm_cpu_set_pc;
     cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
 }
 
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 2abb57f..f7e8c2a 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -26,6 +26,13 @@
 #include "mmu.h"
 
 
+static void cris_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    CRISCPU *cpu = CRIS_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 /* CPUClass::reset() */
 static void cris_cpu_reset(CPUState *s)
 {
@@ -247,6 +254,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = cris_cpu_class_by_name;
     cc->do_interrupt = cris_cpu_do_interrupt;
     cc->dump_state = cris_cpu_dump_state;
+    cc->set_pc = cris_cpu_set_pc;
 }
 
 static const TypeInfo cris_cpu_type_info = {
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e3f75a8..83584e6 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2506,6 +2506,13 @@ static bool x86_cpu_get_paging_enabled(const CPUState *cs)
     return cpu->env.cr[0] & CR0_PG_MASK;
 }
 
+static void x86_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    X86CPU *cpu = X86_CPU(cs);
+
+    cpu->env.eip = value;
+}
+
 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 {
     X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -2522,6 +2529,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = x86_cpu_do_interrupt;
     cc->dump_state = x86_cpu_dump_state;
+    cc->set_pc = x86_cpu_set_pc;
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 04327ac..5a0b809 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -22,6 +22,13 @@
 #include "qemu-common.h"
 
 
+static void lm32_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    LM32CPU *cpu = LM32_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 /* CPUClass::reset() */
 static void lm32_cpu_reset(CPUState *s)
 {
@@ -79,6 +86,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = lm32_cpu_do_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
+    cc->set_pc = lm32_cpu_set_pc;
     cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
 }
 
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index dce1c7e..5fa6f63 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -26,6 +26,13 @@
 #include "migration/vmstate.h"
 
 
+static void mb_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+
+    cpu->env.sregs[SR_PC] = value;
+}
+
 /* CPUClass::reset() */
 static void mb_cpu_reset(CPUState *s)
 {
@@ -134,6 +141,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = mb_cpu_do_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access);
+    cc->set_pc = mb_cpu_set_pc;
     dc->vmsd = &vmstate_mb_cpu;
     dc->props = mb_properties;
 }
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 60a3faf..9e6b7d5 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -22,6 +22,19 @@
 #include "qemu-common.h"
 
 
+static void mips_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
+
+    env->active_tc.PC = value & ~(target_ulong)1;
+    if (value & 1) {
+        env->hflags |= MIPS_HFLAG_M16;
+    } else {
+        env->hflags &= ~(MIPS_HFLAG_M16);
+    }
+}
+
 /* CPUClass::reset() */
 static void mips_cpu_reset(CPUState *s)
 {
@@ -76,6 +89,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->do_interrupt = mips_cpu_do_interrupt;
     cc->dump_state = mips_cpu_dump_state;
     cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
+    cc->set_pc = mips_cpu_set_pc;
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 8bced98..aa79420 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -20,6 +20,13 @@
 #include "cpu.h"
 #include "qemu-common.h"
 
+static void openrisc_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 /* CPUClass::reset() */
 static void openrisc_cpu_reset(CPUState *s)
 {
@@ -144,6 +151,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
+    cc->set_pc = openrisc_cpu_set_pc;
     device_class_set_vmsd(dc, &vmstate_openrisc_cpu);
 }
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 95b0b21..815ce0c 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8178,6 +8178,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
     return cpu_list;
 }
 
+static void ppc_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+    cpu->env.nip = value;
+}
+
 /* CPUClass::reset() */
 static void ppc_cpu_reset(CPUState *s)
 {
@@ -8304,6 +8311,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = ppc_cpu_do_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
+    cc->set_pc = ppc_cpu_set_pc;
 }
 
 static const TypeInfo ppc_cpu_type_info = {
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 1ef2fc0..6fd9bdd 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -58,6 +58,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
 }
 #endif
 
+static void s390_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    S390CPU *cpu = S390_CPU(cs);
+
+    cpu->env.psw.addr = value;
+}
+
 /* CPUClass::reset() */
 static void s390_cpu_reset(CPUState *s)
 {
@@ -165,6 +172,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
+    cc->set_pc = s390_cpu_set_pc;
     dc->vmsd = &vmstate_s390_cpu;
 }
 
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 03487eb..75fcf5c 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -24,6 +24,13 @@
 #include "migration/vmstate.h"
 
 
+static void superh_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 /* CPUClass::reset() */
 static void superh_cpu_reset(CPUState *s)
 {
@@ -269,6 +276,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = superh_cpu_class_by_name;
     cc->do_interrupt = superh_cpu_do_interrupt;
     cc->dump_state = superh_cpu_dump_state;
+    cc->set_pc = superh_cpu_set_pc;
     dc->vmsd = &vmstate_sh_cpu;
 }
 
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 87c3a50..0cb5c6b 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -723,6 +723,14 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf(f, "\n");
 }
 
+static void sparc_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    SPARCCPU *cpu = SPARC_CPU(cs);
+
+    cpu->env.pc = value;
+    cpu->env.npc = value + 4;
+}
+
 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
@@ -767,6 +775,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
     cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
+    cc->set_pc = sparc_cpu_set_pc;
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 0488984..a388c6f 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -33,6 +33,13 @@
 #include "migration/vmstate.h"
 
 
+static void xtensa_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    XtensaCPU *cpu = XTENSA_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 /* CPUClass::reset() */
 static void xtensa_cpu_reset(CPUState *s)
 {
@@ -100,6 +107,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
+    cc->set_pc = xtensa_cpu_set_pc;
     dc->vmsd = &vmstate_xtensa_cpu;
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 05/41] target-m68k: Implement CPUClass::set_pc()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (3 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc() Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 06/41] target-moxie: " Andreas Färber
                   ` (36 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber, Paul Brook

This adds support for GDB's c addr (Continue) and s addr (Single Step).

Prepares for dropping cpu_pc_from_tb().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-m68k/cpu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 1b6ef66..1ac1893 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -23,6 +23,13 @@
 #include "migration/vmstate.h"
 
 
+static void m68k_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    M68kCPU *cpu = M68K_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 static void m68k_set_feature(CPUM68KState *env, int feature)
 {
     env->features |= (1u << feature);
@@ -182,6 +189,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
+    cc->set_pc = m68k_cpu_set_pc;
     dc->vmsd = &vmstate_m68k_cpu;
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 06/41] target-moxie: Implement CPUClass::set_pc()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (4 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 05/41] target-m68k: Implement CPUClass::set_pc() Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 07/41] target-unicore32: " Andreas Färber
                   ` (35 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Green, jan.kiszka, Andreas Färber

This adds support for GDB's c addr (Continue) and s addr (Single Step).

Prepares for dropping cpu_pc_from_tb().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-moxie/cpu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 92ca594..8e32584 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -22,6 +22,13 @@
 #include "migration/vmstate.h"
 #include "machine.h"
 
+static void moxie_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    MoxieCPU *cpu = MOXIE_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
 static void moxie_cpu_reset(CPUState *s)
 {
     MoxieCPU *cpu = MOXIE_CPU(s);
@@ -93,6 +100,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = moxie_cpu_do_interrupt;
     cc->dump_state = moxie_cpu_dump_state;
+    cc->set_pc = moxie_cpu_set_pc;
     cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 07/41] target-unicore32: Implement CPUClass::set_pc()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (5 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 06/41] target-moxie: " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb() Andreas Färber
                   ` (34 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Guan Xuetao, jan.kiszka, Andreas Färber

This adds support for GDB's c addr (Continue) and s addr (Single Step).

Prepares for dropping cpu_pc_from_tb().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-unicore32/cpu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 6572f01..2e99bd3 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -16,6 +16,13 @@
 #include "qemu-common.h"
 #include "migration/vmstate.h"
 
+static void uc32_cpu_set_pc(CPUState *cs, uint64_t value)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+
+    cpu->env.regs[31] = value;
+}
+
 static inline void set_feature(CPUUniCore32State *env, int feature)
 {
     env->features |= feature;
@@ -131,6 +138,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->do_interrupt = uc32_cpu_do_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
+    cc->set_pc = uc32_cpu_set_pc;
     dc->vmsd = &vmstate_uc32_cpu;
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (6 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 07/41] target-unicore32: " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:13   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu() Andreas Färber
                   ` (33 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Anthony Green, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Guan Xuetao, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Where no extra implementation is needed, fall back to CPUClass::set_pc().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c              |  8 +++++++-
 include/exec/exec-all.h |  3 ---
 include/qemu/typedefs.h |  3 +++
 include/qom/cpu.h       |  1 +
 target-alpha/cpu.h      |  5 -----
 target-arm/cpu.h        |  5 -----
 target-cris/cpu.h       |  4 ----
 target-i386/cpu.c       |  8 ++++++++
 target-i386/cpu.h       |  5 -----
 target-lm32/cpu.h       |  5 -----
 target-m68k/cpu.h       |  5 -----
 target-microblaze/cpu.h |  5 -----
 target-mips/cpu.c       | 11 +++++++++++
 target-mips/cpu.h       |  7 -------
 target-moxie/cpu.h      |  5 -----
 target-openrisc/cpu.h   |  5 -----
 target-ppc/cpu.h        |  5 -----
 target-s390x/cpu.h      |  5 -----
 target-sh4/cpu.c        |  9 +++++++++
 target-sh4/cpu.h        |  6 ------
 target-sparc/cpu.c      |  9 +++++++++
 target-sparc/cpu.h      |  6 ------
 target-unicore32/cpu.h  |  5 -----
 target-xtensa/cpu.h     |  5 -----
 24 files changed, 48 insertions(+), 87 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 9c46846..88f4e75 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -59,8 +59,14 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
          * counter hit zero); we must restore the guest PC to the address
          * of the start of the TB.
          */
+        CPUClass *cc = CPU_GET_CLASS(cpu);
         TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
-        cpu_pc_from_tb(env, tb);
+        if (cc->synchronize_from_tb) {
+            cc->synchronize_from_tb(cpu, tb);
+        } else {
+            assert(cc->set_pc);
+            cc->set_pc(cpu, tb->pc);
+        }
     }
     if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
         /* We were asked to stop executing TBs (probably a pending
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index b2162a4..5e33e03 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -40,9 +40,6 @@ typedef ram_addr_t tb_page_addr_t;
 #define DISAS_UPDATE  2 /* cpu state was modified dynamically */
 #define DISAS_TB_JUMP 3 /* only pc was modified statically */
 
-struct TranslationBlock;
-typedef struct TranslationBlock TranslationBlock;
-
 /* XXX: make safe guess about sizes */
 #define MAX_OP_PER_INSTR 208
 
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 698fc03..dba6e95 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -24,6 +24,9 @@ typedef struct MemoryRegionSection MemoryRegionSection;
 
 typedef struct MemoryMappingList MemoryMappingList;
 
+struct TranslationBlock;
+typedef struct TranslationBlock TranslationBlock;
+
 typedef struct NICInfo NICInfo;
 typedef struct HCIInfo HCIInfo;
 typedef struct AudioState AudioState;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 3701eb1..d8b77af 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -85,6 +85,7 @@ typedef struct CPUClass {
     void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
                                Error **errp);
     void (*set_pc)(CPUState *cpu, uint64_t value);
+    void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 066f032..c85dc6e 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 #endif /* !defined (__CPU_ALPHA_H__) */
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1369604..0027492 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -796,11 +796,6 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
-{
-    env->regs[15] = tb->pc;
-}
-
 /* Load an instruction and return it in the standard little-endian order */
 static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
                                     bool do_swap)
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index c12a8ca..4b9fc4c 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 83584e6..eda2444 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2513,6 +2513,13 @@ static void x86_cpu_set_pc(CPUState *cs, uint64_t value)
     cpu->env.eip = value;
 }
 
+static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+    X86CPU *cpu = X86_CPU(cs);
+
+    cpu->env.eip = tb->pc - tb->cs_base;
+}
+
 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 {
     X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -2530,6 +2537,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = x86_cpu_do_interrupt;
     cc->dump_state = x86_cpu_dump_state;
     cc->set_pc = x86_cpu_set_pc;
+    cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 2849672..b746bb1 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1148,11 +1148,6 @@ static inline bool cpu_has_work(CPUState *cs)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb)
-{
-    env->eip = tb->pc - tb->cs_base;
-}
-
 static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 856bdc7..dbfe043 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -232,9 +232,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPULM32State *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 #endif
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 9fdf89e..cfd6846 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -260,9 +260,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 #endif
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 6c35475..7508cf5 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -365,9 +365,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUMBState *env, TranslationBlock *tb)
-{
-    env->sregs[SR_PC] = tb->pc;
-}
-
 #endif
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 9e6b7d5..ce39c23 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -35,6 +35,16 @@ static void mips_cpu_set_pc(CPUState *cs, uint64_t value)
     }
 }
 
+static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
+
+    env->active_tc.PC = tb->pc;
+    env->hflags &= ~MIPS_HFLAG_BMASK;
+    env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
+}
+
 /* CPUClass::reset() */
 static void mips_cpu_reset(CPUState *s)
 {
@@ -90,6 +100,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->dump_state = mips_cpu_dump_state;
     cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
     cc->set_pc = mips_cpu_set_pc;
+    cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7ffd2e3..a29c82f 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -732,13 +732,6 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb)
-{
-    env->active_tc.PC = tb->pc;
-    env->hflags &= ~MIPS_HFLAG_BMASK;
-    env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
-}
-
 static inline void compute_hflags(CPUMIPSState *env)
 {
     env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 72d02c2..d5030a4 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -143,11 +143,6 @@ static inline int cpu_mmu_index(CPUMoxieState *env)
 #include "exec/cpu-all.h"
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUMoxieState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 0aff8f2..82bfd03 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -428,9 +428,4 @@ static inline target_ulong cpu_get_pc(CPUOpenRISCState *env)
     return env->pc;
 }
 
-static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 #endif /* CPU_OPENRISC_H */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 13137ce..2e366ea 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2142,11 +2142,6 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb)
-{
-    env->nip = tb->pc;
-}
-
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
 
 #endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f497253..341772f 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1041,11 +1041,6 @@ static inline bool cpu_has_work(CPUState *cpu)
         (env->psw.mask & PSW_MASK_EXT);
 }
 
-static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
-{
-    env->psw.addr = tb->pc;
-}
-
 /* fpu_helper.c */
 uint32_t set_cc_nz_f32(float32 v);
 uint32_t set_cc_nz_f64(float64 v);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 75fcf5c..d535fe8 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -31,6 +31,14 @@ static void superh_cpu_set_pc(CPUState *cs, uint64_t value)
     cpu->env.pc = value;
 }
 
+static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+
+    cpu->env.pc = tb->pc;
+    cpu->env.flags = tb->flags;
+}
+
 /* CPUClass::reset() */
 static void superh_cpu_reset(CPUState *s)
 {
@@ -277,6 +285,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = superh_cpu_do_interrupt;
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
+    cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
     dc->vmsd = &vmstate_sh_cpu;
 }
 
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index c8df18b..276d295 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -359,10 +359,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUSH4State *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-    env->flags = tb->flags;
-}
-
 #endif				/* _CPU_SH4_H */
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 0cb5c6b..1e3984f 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -731,6 +731,14 @@ static void sparc_cpu_set_pc(CPUState *cs, uint64_t value)
     cpu->env.npc = value + 4;
 }
 
+static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+    SPARCCPU *cpu = SPARC_CPU(cs);
+
+    cpu->env.pc = tb->pc;
+    cpu->env.npc = tb->cs_base;
+}
+
 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
@@ -776,6 +784,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = sparc_cpu_dump_state;
     cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
     cc->set_pc = sparc_cpu_set_pc;
+    cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 41b014a..0f35a22 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -759,10 +759,4 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUSPARCState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-    env->npc = tb->cs_base;
-}
-
 #endif
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index d4be525..967511e 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -146,11 +146,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env)
 #include "cpu-qom.h"
 #include "exec/exec-all.h"
 
-static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock *tb)
-{
-    env->regs[31] = tb->pc;
-}
-
 static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 6c9fc35..a8f02f6 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -522,9 +522,4 @@ static inline int cpu_has_work(CPUState *cpu)
     return env->pending_irq_level;
 }
 
-static inline void cpu_pc_from_tb(CPUXtensaState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 #endif
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (7 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb() Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:14   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
                   ` (32 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Since commit cb446ecab714b2444a270be209e0533bcd2ee534 (kvm: Change
cpu_synchronize_state() argument to CPUState), one was no longer
accessing CPUArchState, the other was just checking existence.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index bdf4496..07838eb 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2065,6 +2065,7 @@ static CPUArchState *find_cpu(uint32_t thread_id)
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
     CPUArchState *env;
+    CPUState *cpu;
     const char *p;
     uint32_t thread;
     int ch, reg_size, type, res;
@@ -2333,9 +2334,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'T':
         thread = strtoull(p, (char **)&p, 16);
-        env = find_cpu(thread);
+        cpu = qemu_get_cpu(thread);
 
-        if (env != NULL) {
+        if (cpu != NULL) {
             put_packet(s, "OK");
         } else {
             put_packet(s, "E22");
@@ -2385,9 +2386,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             break;
         } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
             thread = strtoull(p+16, (char **)&p, 16);
-            env = find_cpu(thread);
-            if (env != NULL) {
-                CPUState *cpu = ENV_GET_CPU(env);
+            cpu = qemu_get_cpu(thread);
+            if (cpu != NULL) {
                 cpu_synchronize_state(cpu);
                 len = snprintf((char *)mem_buf, sizeof(mem_buf),
                                "CPU#%d [%s]", cpu->cpu_index,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (8 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu() Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:15   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 11/41] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU Andreas Färber
                   ` (31 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber, Richard Henderson

Also use bool argument while at it.

Prepares for replacing DisasContext::env with CPUState and for moving
singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-alpha/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 4db16db..dd7f0fb 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3375,10 +3375,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     return ret;
 }
 
-static inline void gen_intermediate_code_internal(CPUAlphaState *env,
+static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUAlphaState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     target_ulong pc_start;
     uint32_t insn;
@@ -3502,12 +3503,12 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
 
 void gen_intermediate_code (CPUAlphaState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 11/41] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (9 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 12/41] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU Andreas Färber
                   ` (30 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, jan.kiszka, Andreas Färber, Paul Brook

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-arm/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index af2aef2..9310c58 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9796,10 +9796,11 @@ undef:
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUARMState *env,
+static inline void gen_intermediate_code_internal(ARMCPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUARMState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
     uint16_t *gen_opc_end;
@@ -10072,12 +10073,12 @@ done_generating:
 
 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
 }
 
 static const char *cpu_mode_names[16] = {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 12/41] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (10 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 11/41] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 13/41] target-i386: Change gen_intermediate_code_internal() argument to X86CPU Andreas Färber
                   ` (29 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E. Iglesias, jan.kiszka, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-cris/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-cris/translate.c b/target-cris/translate.c
index 09d0d2b..ce1f03b 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3162,9 +3162,10 @@ static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
 
 /* generate intermediate code for basic block 'tb'.  */
 static void
-gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
-                               int search_pc)
+gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUCRISState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
     unsigned int insn_len;
@@ -3419,12 +3420,12 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
 
 void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true);
 }
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 13/41] target-i386: Change gen_intermediate_code_internal() argument to X86CPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (11 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 12/41] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 14/41] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU Andreas Färber
                   ` (28 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-i386/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 14b0298..6550c27 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8251,10 +8251,11 @@ void optimize_flags_init(void)
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUX86State *env,
+static inline void gen_intermediate_code_internal(X86CPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUX86State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_ptr;
     uint16_t *gen_opc_end;
@@ -8428,12 +8429,12 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
 
 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(x86_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(x86_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 14/41] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (12 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 13/41] target-i386: Change gen_intermediate_code_internal() argument to X86CPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 15/41] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU Andreas Färber
                   ` (27 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle, jan.kiszka, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-lm32/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 227a801..6d107dc 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1011,9 +1011,10 @@ static void check_breakpoint(CPULM32State *env, DisasContext *dc)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-static void gen_intermediate_code_internal(CPULM32State *env,
-        TranslationBlock *tb, int search_pc)
+static void gen_intermediate_code_internal(LM32CPU *cpu,
+        TranslationBlock *tb, bool search_pc)
 {
+    CPULM32State *env = &cpu->env;
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -1133,12 +1134,12 @@ static void gen_intermediate_code_internal(CPULM32State *env,
 
 void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(lm32_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPULM32State *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(lm32_env_get_cpu(env), tb, true);
 }
 
 void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 15/41] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (13 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 14/41] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 16/41] target-microblaze: Change gen_intermediate_code_internal() argument types Andreas Färber
                   ` (26 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber, Paul Brook

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-m68k/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 3752094..2d73af5 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2971,9 +2971,10 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
 
 /* generate intermediate code for basic block 'tb'.  */
 static inline void
-gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
-                               int search_pc)
+gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUM68KState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     uint16_t *gen_opc_end;
     CPUBreakpoint *bp;
@@ -3096,12 +3097,12 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
 
 void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, true);
 }
 
 void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 16/41] target-microblaze: Change gen_intermediate_code_internal() argument types
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (14 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 15/41] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 17/41] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU Andreas Färber
                   ` (25 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E. Iglesias, jan.kiszka, Andreas Färber

Use MicroBlazeCPU and bool.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-microblaze/translate.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index f9acdb1..6484378 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1738,12 +1738,10 @@ static void check_breakpoint(CPUMBState *env, DisasContext *dc)
 
 /* generate intermediate code for basic block 'tb'.  */
 static void
-gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
-                               int search_pc)
+gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
-#if !SIM_COMPAT
-    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
-#endif
+    CPUMBState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
     int j, lj;
@@ -1944,12 +1942,12 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
 
 void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true);
 }
 
 void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 17/41] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (15 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 16/41] target-microblaze: Change gen_intermediate_code_internal() argument types Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 18/41] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU Andreas Färber
                   ` (24 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber, Aurelien Jarno

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-mips/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 160c0c0..8246c20 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15540,9 +15540,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
 }
 
 static inline void
-gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
-                                int search_pc)
+gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUMIPSState *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
     uint16_t *gen_opc_end;
@@ -15698,12 +15699,12 @@ done_generating:
 
 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
 }
 
 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 18/41] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (16 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 17/41] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 19/41] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU Andreas Färber
                   ` (23 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: open list:PowerPC, jan.kiszka, Andreas Färber, Alexander Graf

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-ppc/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3643863..eb96272 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9726,10 +9726,11 @@ void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
 }
 
 /*****************************************************************************/
-static inline void gen_intermediate_code_internal(CPUPPCState *env,
+static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUPPCState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     opc_handler_t **table, *handler;
     target_ulong pc_start;
@@ -9917,12 +9918,12 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
 
 void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 19/41] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (17 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 18/41] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 20/41] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU Andreas Färber
                   ` (22 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alexander Graf, jan.kiszka, Andreas Färber, Richard Henderson

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-s390x/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index cd9880e..cba7b87 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -4736,10 +4736,11 @@ static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
     return ret;
 }
 
-static inline void gen_intermediate_code_internal(CPUS390XState *env,
+static inline void gen_intermediate_code_internal(S390CPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUS390XState *env = &cpu->env;
     DisasContext dc;
     target_ulong pc_start;
     uint64_t next_page_start;
@@ -4872,12 +4873,12 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
 
 void gen_intermediate_code (CPUS390XState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(s390_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(s390_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 20/41] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (18 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 19/41] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 21/41] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU Andreas Färber
                   ` (21 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber, Aurelien Jarno

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-sh4/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 292c9e9..2fbe668 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1846,9 +1846,10 @@ static void decode_opc(DisasContext * ctx)
 }
 
 static inline void
-gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
-                               int search_pc)
+gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUSH4State *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
     static uint16_t *gen_opc_end;
@@ -1969,12 +1970,12 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
 
 void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(sh_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUSH4State * env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(sh_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 21/41] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (19 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 20/41] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 22/41] target-unicore32: Change gen_intermediate_code_internal() signature Andreas Färber
                   ` (20 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, jan.kiszka, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-sparc/translate.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index eb6e800..5e771e5 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5219,9 +5219,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
     }
 }
 
-static inline void gen_intermediate_code_internal(TranslationBlock * tb,
-                                                  int spc, CPUSPARCState *env)
+static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
+                                                  TranslationBlock *tb,
+                                                  bool spc)
 {
+    CPUSPARCState *env = &cpu->env;
     target_ulong pc_start, last_pc;
     uint16_t *gen_opc_end;
     DisasContext dc1, *dc = &dc1;
@@ -5347,12 +5349,12 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
 
 void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
 {
-    gen_intermediate_code_internal(tb, 0, env);
+    gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
 {
-    gen_intermediate_code_internal(tb, 1, env);
+    gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, true);
 }
 
 void gen_intermediate_code_init(CPUSPARCState *env)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 22/41] target-unicore32: Change gen_intermediate_code_internal() signature
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (20 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 21/41] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
                   ` (19 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Guan Xuetao, jan.kiszka, Andreas Färber

Use UniCore32CPU and bool.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-unicore32/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index e1fe4e6..d85185d 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1876,9 +1876,10 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
-        TranslationBlock *tb, int search_pc)
+static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
+        TranslationBlock *tb, bool search_pc)
 {
+    CPUUniCore32State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
     uint16_t *gen_opc_end;
@@ -2065,12 +2066,12 @@ done_generating:
 
 void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(uc32_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUUniCore32State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(uc32_env_get_cpu(env), tb, true);
 }
 
 static const char *cpu_mode_names[16] = {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (21 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 22/41] target-unicore32: Change gen_intermediate_code_internal() signature Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:16   ` Richard Henderson
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState Andreas Färber
                   ` (18 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Filippov, jan.kiszka, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-xtensa/translate.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index dcb90a5..d5f2068 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2875,9 +2875,11 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
     }
 }
 
-static void gen_intermediate_code_internal(
-        CPUXtensaState *env, TranslationBlock *tb, int search_pc)
+static void gen_intermediate_code_internal(XtensaCPU *cpu,
+                                           TranslationBlock *tb,
+                                           bool search_pc)
 {
+    CPUXtensaState *env = &cpu->env;
     DisasContext dc;
     int insn_count = 0;
     int j, lj = -1;
@@ -3006,12 +3008,12 @@ static void gen_intermediate_code_internal(
 
 void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, true);
 }
 
 void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (22 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 17:18   ` Richard Henderson
  2013-07-01 17:23   ` Richard Henderson
  2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
                   ` (17 subsequent siblings)
  41 siblings, 2 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber, Richard Henderson

Needed for moving singlestep_enabled to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-alpha/translate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index dd7f0fb..147285a 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -38,7 +38,7 @@
 typedef struct DisasContext DisasContext;
 struct DisasContext {
     struct TranslationBlock *tb;
-    CPUAlphaState *env;
+    AlphaCPU *cpu;
     uint64_t pc;
     int mem_idx;
 
@@ -380,7 +380,7 @@ static int use_goto_tb(DisasContext *ctx, uint64_t dest)
     /* Check for the dest on the same page as the start of the TB.  We
        also want to suppress goto_tb in the case of single-steping and IO.  */
     return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
-            && !ctx->env->singlestep_enabled
+            && !ctx->cpu->env.singlestep_enabled
             && !(ctx->tb->cflags & CF_LAST_IO));
 }
 
@@ -2245,7 +2245,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
         case 0x6C:
             /* IMPLVER */
             if (rc != 31)
-                tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
+                tcg_gen_movi_i64(cpu_ir[rc], ctx->cpu->env.implver);
             break;
         default:
             goto invalid_opc;
@@ -3394,7 +3394,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
     ctx.tb = tb;
-    ctx.env = env;
+    ctx.cpu = alpha_env_get_cpu(env);
     ctx.pc = pc_start;
     ctx.mem_idx = cpu_mmu_index(env);
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH RFC qom-cpu 25/41] cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
@ 2013-06-29 20:01   ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
                     ` (40 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: jan.kiszka, Andreas Färber, Gleb Natapov, Marcelo Tosatti,
	Richard Henderson, Paul Brook, Peter Maydell, Edgar E. Iglesias,
	Michael Walle, Aurelien Jarno, Anthony Green, Alexander Graf,
	Blue Swirl, Guan Xuetao, Max Filippov, open list:Overall,
	open list:PowerPC

Prepares for changing cpu_single_step() argument to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c                    |  2 +-
 cpus.c                        |  2 +-
 exec.c                        | 10 ++++++----
 include/exec/cpu-defs.h       |  1 -
 include/qom/cpu.h             |  1 +
 kvm-all.c                     |  2 +-
 target-alpha/translate.c      | 12 ++++++++----
 target-arm/translate.c        |  7 ++++---
 target-cris/translate.c       |  7 ++++---
 target-i386/kvm.c             |  6 ++++--
 target-i386/translate.c       |  5 +++--
 target-lm32/translate.c       |  7 ++++---
 target-m68k/translate.c       |  7 ++++---
 target-microblaze/translate.c |  8 +++++---
 target-mips/translate.c       | 11 +++++++----
 target-moxie/translate.c      |  5 +++--
 target-openrisc/translate.c   |  7 ++++---
 target-ppc/translate.c        |  8 +++++---
 target-s390x/translate.c      |  5 +++--
 target-sh4/translate.c        |  8 +++++---
 target-sparc/translate.c      |  3 ++-
 target-unicore32/translate.c  |  7 ++++---
 target-xtensa/translate.c     |  7 ++++---
 23 files changed, 83 insertions(+), 55 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 88f4e75..d52e581 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -297,7 +297,7 @@ int cpu_exec(CPUArchState *env)
             for(;;) {
                 interrupt_request = cpu->interrupt_request;
                 if (unlikely(interrupt_request)) {
-                    if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
+                    if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
                         /* Mask out external interrupts for this step. */
                         interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
                     }
diff --git a/cpus.c b/cpus.c
index f97983d..8b99deb 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1148,7 +1148,7 @@ static void tcg_exec_all(void)
         CPUArchState *env = cpu->env_ptr;
 
         qemu_clock_enable(vm_clock,
-                          (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
+                          (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
         if (cpu_can_run(cpu)) {
             r = tcg_cpu_exec(env);
diff --git a/exec.c b/exec.c
index 4e20143..f2d848c 100644
--- a/exec.c
+++ b/exec.c
@@ -584,11 +584,13 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
 void cpu_single_step(CPUArchState *env, int enabled)
 {
 #if defined(TARGET_HAS_ICE)
-    if (env->singlestep_enabled != enabled) {
-        env->singlestep_enabled = enabled;
-        if (kvm_enabled())
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    if (cpu->singlestep_enabled != enabled) {
+        cpu->singlestep_enabled = enabled;
+        if (kvm_enabled()) {
             kvm_update_guest_debug(env, 0);
-        else {
+        } else {
             /* must flush all the translated code to avoid inconsistencies */
             /* XXX: only flush what is necessary */
             tb_flush(env);
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 39094b3..12b1ca7 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -170,7 +170,6 @@ typedef struct CPUWatchpoint {
     /* from this point: preserved by CPU reset */                       \
     /* ice debug support */                                             \
     QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;            \
-    int singlestep_enabled;                                             \
                                                                         \
     QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;            \
     CPUWatchpoint *watchpoint_hit;                                      \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index d8b77af..a02b142 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -148,6 +148,7 @@ struct CPUState {
     volatile sig_atomic_t exit_request;
     volatile sig_atomic_t tcg_exit_req;
     uint32_t interrupt_request;
+    int singlestep_enabled;
 
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
diff --git a/kvm-all.c b/kvm-all.c
index 00ef85d..65e93cd 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1886,7 +1886,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
 
     data.dbg.control = reinject_trap;
 
-    if (env->singlestep_enabled) {
+    if (cpu->singlestep_enabled) {
         data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
     }
     kvm_arch_update_guest_debug(cpu, &data.dbg);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 147285a..0229a66 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -377,10 +377,12 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
 
 static int use_goto_tb(DisasContext *ctx, uint64_t dest)
 {
+    CPUState *cs = CPU(ctx->cpu);
+
     /* Check for the dest on the same page as the start of the TB.  We
        also want to suppress goto_tb in the case of single-steping and IO.  */
     return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
-            && !ctx->cpu->env.singlestep_enabled
+            && !cs->singlestep_enabled
             && !(ctx->tb->cflags & CF_LAST_IO));
 }
 
@@ -3379,6 +3381,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUAlphaState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     target_ulong pc_start;
@@ -3394,9 +3397,10 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
     ctx.tb = tb;
-    ctx.cpu = alpha_env_get_cpu(env);
+    ctx.cpu = cpu;
     ctx.pc = pc_start;
     ctx.mem_idx = cpu_mmu_index(env);
+    cs = CPU(ctx.cpu);
 
     /* ??? Every TB begins with unset rounding mode, to be initialized on
        the first fp insn of the TB.  Alternately we could define a proper
@@ -3453,7 +3457,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
                 || tcg_ctx.gen_opc_ptr >= gen_opc_end
                 || num_insns >= max_insns
                 || singlestep
-                || env->singlestep_enabled)) {
+                || cs->singlestep_enabled)) {
             ret = EXIT_PC_STALE;
         }
     } while (ret == NO_EXIT);
@@ -3470,7 +3474,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
         /* FALLTHRU */
     case EXIT_PC_UPDATED:
-        if (env->singlestep_enabled) {
+        if (cs->singlestep_enabled) {
             gen_excp_1(EXCP_DEBUG, 0);
         } else {
             tcg_gen_exit_tb(0);
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9310c58..19e3fb9 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9800,6 +9800,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
@@ -9819,7 +9820,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->condjmp = 0;
     dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
     dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
@@ -9969,7 +9970,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !cs->singlestep_enabled &&
              !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
@@ -9986,7 +9987,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
     /* At this stage dc->condjmp will only be set when the skipped
        instruction was a conditional branch or trap, and the PC has
        already been written.  */
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (dc->condjmp) {
             gen_set_condexec(dc);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index ce1f03b..e6a8c76 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3165,6 +3165,7 @@ static void
 gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUCRISState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -3197,7 +3198,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
     dc->is_jmp = DISAS_NEXT;
     dc->ppc = pc_start;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->flags_uptodate = 1;
     dc->flagx_known = 1;
     dc->flags_x = tb->flags & X_FLAG;
@@ -3337,7 +3338,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
 
         /* If we are rexecuting a branch due to exceptions on
            delay slots dont break.  */
-        if (!(tb->pc & 1) && env->singlestep_enabled) {
+        if (!(tb->pc & 1) && cs->singlestep_enabled) {
             break;
         }
     } while (!dc->is_jmp && !dc->cpustate_changed
@@ -3370,7 +3371,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
 
     cris_evaluate_flags(dc);
 
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(env_pc, npc);
         }
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index cc3dcec..793cf16 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1597,6 +1597,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu)
 
 static int kvm_guest_debug_workarounds(X86CPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     int ret = 0;
     unsigned long reinject_trap = 0;
@@ -1619,7 +1620,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu)
      * reinject them via SET_GUEST_DEBUG.
      */
     if (reinject_trap ||
-        (!kvm_has_robust_singlestep() && env->singlestep_enabled)) {
+        (!kvm_has_robust_singlestep() && cs->singlestep_enabled)) {
         ret = kvm_update_guest_debug(env, reinject_trap);
     }
     return ret;
@@ -2045,13 +2046,14 @@ static CPUWatchpoint hw_watchpoint;
 static int kvm_handle_debug(X86CPU *cpu,
                             struct kvm_debug_exit_arch *arch_info)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     int ret = 0;
     int n;
 
     if (arch_info->exception == 1) {
         if (arch_info->dr6 & (1 << 14)) {
-            if (env->singlestep_enabled) {
+            if (cs->singlestep_enabled) {
                 ret = EXCP_DEBUG;
             }
         } else {
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 6550c27..065a9d3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8255,6 +8255,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_ptr;
@@ -8281,7 +8282,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
     dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
     dc->cs_base = cs_base;
@@ -8302,7 +8303,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 #endif
     dc->flags = flags;
-    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
+    dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK)
 #ifndef CONFIG_SOFTMMU
                     || (flags & HF_SOFTMMU_MASK)
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 6d107dc..1b87b7d 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1014,6 +1014,7 @@ static void check_breakpoint(CPULM32State *env, DisasContext *dc)
 static void gen_intermediate_code_internal(LM32CPU *cpu,
         TranslationBlock *tb, bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPULM32State *env = &cpu->env;
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
@@ -1031,7 +1032,7 @@ static void gen_intermediate_code_internal(LM32CPU *cpu,
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->nr_nops = 0;
 
     if (pc_start & 3) {
@@ -1076,7 +1077,7 @@ static void gen_intermediate_code_internal(LM32CPU *cpu,
 
     } while (!dc->is_jmp
          && tcg_ctx.gen_opc_ptr < gen_opc_end
-         && !env->singlestep_enabled
+         && !cs->singlestep_enabled
          && !singlestep
          && (dc->pc < next_page_start)
          && num_insns < max_insns);
@@ -1085,7 +1086,7 @@ static void gen_intermediate_code_internal(LM32CPU *cpu,
         gen_io_end();
     }
 
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
         }
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 2d73af5..d562eeb 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2974,6 +2974,7 @@ static inline void
 gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUM68KState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     uint16_t *gen_opc_end;
@@ -2995,7 +2996,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
     dc->cc_op = CC_OP_DYNAMIC;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
     dc->is_mem = 0;
@@ -3038,14 +3039,14 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !cs->singlestep_enabled &&
              !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (!dc->is_jmp) {
             gen_flush_cc_op(dc);
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 6484378..2d3b9a8 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1741,6 +1741,7 @@ static void
 gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUMBState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -1766,7 +1767,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
         dc->jmp = JMP_INDIRECT;
     }
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
     dc->nr_nops = 0;
@@ -1859,8 +1860,9 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
                 break;
             }
         }
-        if (env->singlestep_enabled)
+        if (cs->singlestep_enabled) {
             break;
+        }
     } while (!dc->is_jmp && !dc->cpustate_changed
          && tcg_ctx.gen_opc_ptr < gen_opc_end
                  && !singlestep
@@ -1887,7 +1889,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     }
     t_sync_flags(dc);
 
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 8246c20..877f8df 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15543,6 +15543,7 @@ static inline void
 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUMIPSState *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
@@ -15561,7 +15562,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
-    ctx.singlestep_enabled = env->singlestep_enabled;
+    ctx.singlestep_enabled = cs->singlestep_enabled;
     ctx.insn_flags = env->insn_flags;
     ctx.tb = tb;
     ctx.bstate = BS_NONE;
@@ -15637,8 +15638,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
            This is what GDB expects and is consistent with what the
            hardware does (e.g. if a delay slot instruction faults, the
            reported PC is the PC of the branch).  */
-        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
+        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
             break;
+        }
 
         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
             break;
@@ -15653,9 +15655,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
         if (singlestep)
             break;
     }
-    if (tb->cflags & CF_LAST_IO)
+    if (tb->cflags & CF_LAST_IO) {
         gen_io_end();
-    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
+    }
+    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
         gen_helper_0e0i(raise_exception, EXCP_DEBUG);
     } else {
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index b0ae38a..dab6626 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -824,6 +824,7 @@ static void
 gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     DisasContext ctx;
     target_ulong pc_start;
     uint16_t *gen_opc_end;
@@ -871,7 +872,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
         ctx.pc += decode_opc(cpu, &ctx);
         num_insns++;
 
-        if (env->singlestep_enabled) {
+        if (cs->singlestep_enabled) {
             break;
         }
 
@@ -880,7 +881,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
         }
     } while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end);
 
-    if (env->singlestep_enabled) {
+    if (cs->singlestep_enabled) {
         tcg_gen_movi_tl(cpu_pc, ctx.pc);
         gen_helper_debug(cpu_env);
     } else {
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index f222834..a6050ba 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1662,6 +1662,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
                                                   TranslationBlock *tb,
                                                   int search_pc)
 {
+    CPUState *cs = CPU(cpu);
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -1681,7 +1682,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
     dc->mem_idx = cpu_mmu_index(&cpu->env);
     dc->synced_flags = dc->tb_flags = tb->flags;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
-    dc->singlestep_enabled = cpu->env.singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("-----------------------------------------\n");
         log_cpu_state(CPU(cpu), 0);
@@ -1743,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
         }
     } while (!dc->is_jmp
              && tcg_ctx.gen_opc_ptr < gen_opc_end
-             && !cpu->env.singlestep_enabled
+             && !cs->singlestep_enabled
              && !singlestep
              && (dc->pc < next_page_start)
              && num_insns < max_insns);
@@ -1755,7 +1756,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
         dc->is_jmp = DISAS_UPDATE;
         tcg_gen_movi_tl(cpu_pc, dc->pc);
     }
-    if (unlikely(cpu->env.singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
         }
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index eb96272..f07d70d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9730,6 +9730,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     opc_handler_t **table, *handler;
@@ -9770,8 +9771,9 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
         ctx.singlestep_enabled = 0;
     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
-    if (unlikely(env->singlestep_enabled))
+    if (unlikely(cs->singlestep_enabled)) {
         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
+    }
 #if defined (DO_SINGLE_STEP) && 0
     /* Single step trace mode */
     msr_se = 1;
@@ -9873,7 +9875,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                      ctx.exception != POWERPC_EXCP_BRANCH)) {
             gen_exception(ctxp, POWERPC_EXCP_TRACE);
         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
-                            (env->singlestep_enabled) ||
+                            (cs->singlestep_enabled) ||
                             singlestep ||
                             num_insns >= max_insns)) {
             /* if we reach a page boundary or are single stepping, stop
@@ -9887,7 +9889,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
     if (ctx.exception == POWERPC_EXCP_NONE) {
         gen_goto_tb(&ctx, 0, ctx.nip);
     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
-        if (unlikely(env->singlestep_enabled)) {
+        if (unlikely(cs->singlestep_enabled)) {
             gen_debug_exception(ctxp);
         }
         /* Generate the return instruction */
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index cba7b87..1fb76c5 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -4740,6 +4740,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUS390XState *env = &cpu->env;
     DisasContext dc;
     target_ulong pc_start;
@@ -4761,7 +4762,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
     dc.tb = tb;
     dc.pc = pc_start;
     dc.cc_op = CC_OP_DYNAMIC;
-    do_debug = dc.singlestep_enabled = env->singlestep_enabled;
+    do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
 
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
@@ -4818,7 +4819,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
                 || tcg_ctx.gen_opc_ptr >= gen_opc_end
                 || num_insns >= max_insns
                 || singlestep
-                || env->singlestep_enabled)) {
+                || cs->singlestep_enabled)) {
             status = EXIT_PC_STALE;
         }
     } while (status == NO_EXIT);
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 2fbe668..59f3d47 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1849,6 +1849,7 @@ static inline void
 gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUSH4State *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
@@ -1868,7 +1869,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
        so assume it is a dynamic branch.  */
     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
     ctx.tb = tb;
-    ctx.singlestep_enabled = env->singlestep_enabled;
+    ctx.singlestep_enabled = cs->singlestep_enabled;
     ctx.features = env->features;
     ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
 
@@ -1914,8 +1915,9 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
 	ctx.pc += 2;
 	if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
 	    break;
-	if (env->singlestep_enabled)
+        if (cs->singlestep_enabled) {
 	    break;
+        }
         if (num_insns >= max_insns)
             break;
         if (singlestep)
@@ -1923,7 +1925,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (env->singlestep_enabled) {
+    if (cs->singlestep_enabled) {
         tcg_gen_movi_i32(cpu_pc, ctx.pc);
         gen_helper_debug(cpu_env);
     } else {
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5e771e5..093e0e2 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5223,6 +5223,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool spc)
 {
+    CPUState *cs = CPU(cpu);
     CPUSPARCState *env = &cpu->env;
     target_ulong pc_start, last_pc;
     uint16_t *gen_opc_end;
@@ -5244,7 +5245,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
     dc->def = env->def;
     dc->fpu_enabled = tb_fpu_enabled(tb->flags);
     dc->address_mask_32bit = tb_am_enabled(tb->flags);
-    dc->singlestep = (env->singlestep_enabled || singlestep);
+    dc->singlestep = (cs->singlestep_enabled || singlestep);
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
     num_insns = 0;
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index d85185d..68be1c6 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1879,6 +1879,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
 static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
         TranslationBlock *tb, bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUUniCore32State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
@@ -1900,7 +1901,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->condjmp = 0;
     cpu_F0s = tcg_temp_new_i32();
     cpu_F1s = tcg_temp_new_i32();
@@ -1971,7 +1972,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
          * ensures prefetch aborts occur at the right place.  */
         num_insns++;
     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !cs->singlestep_enabled &&
              !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
@@ -1988,7 +1989,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
     /* At this stage dc->condjmp will only be set when the skipped
        instruction was a conditional branch or trap, and the PC has
        already been written.  */
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (dc->condjmp) {
             if (dc->is_jmp == DISAS_SYSCALL) {
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index d5f2068..cc36fa4 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2879,6 +2879,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
                                            TranslationBlock *tb,
                                            bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUXtensaState *env = &cpu->env;
     DisasContext dc;
     int insn_count = 0;
@@ -2894,7 +2895,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
     }
 
     dc.config = env->config;
-    dc.singlestep_enabled = env->singlestep_enabled;
+    dc.singlestep_enabled = cs->singlestep_enabled;
     dc.tb = tb;
     dc.pc = pc_start;
     dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
@@ -2917,7 +2918,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
 
     gen_tb_start();
 
-    if (env->singlestep_enabled && env->exception_taken) {
+    if (cs->singlestep_enabled && env->exception_taken) {
         env->exception_taken = 0;
         tcg_gen_movi_i32(cpu_pc, dc.pc);
         gen_exception(&dc, EXCP_DEBUG);
@@ -2970,7 +2971,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
         if (dc.icount) {
             tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
         }
-        if (env->singlestep_enabled) {
+        if (cs->singlestep_enabled) {
             tcg_gen_movi_i32(cpu_pc, dc.pc);
             gen_exception(&dc, EXCP_DEBUG);
             break;
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 25/41] cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
@ 2013-06-29 20:01   ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:Overall, Gleb Natapov,
	open list:PowerPC, Anthony Green, Marcelo Tosatti,
	Alexander Graf, Blue Swirl, Max Filippov, Michael Walle,
	jan.kiszka, Paul Brook, Edgar E. Iglesias, Guan Xuetao,
	Andreas Färber, Aurelien Jarno, Richard Henderson

Prepares for changing cpu_single_step() argument to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c                    |  2 +-
 cpus.c                        |  2 +-
 exec.c                        | 10 ++++++----
 include/exec/cpu-defs.h       |  1 -
 include/qom/cpu.h             |  1 +
 kvm-all.c                     |  2 +-
 target-alpha/translate.c      | 12 ++++++++----
 target-arm/translate.c        |  7 ++++---
 target-cris/translate.c       |  7 ++++---
 target-i386/kvm.c             |  6 ++++--
 target-i386/translate.c       |  5 +++--
 target-lm32/translate.c       |  7 ++++---
 target-m68k/translate.c       |  7 ++++---
 target-microblaze/translate.c |  8 +++++---
 target-mips/translate.c       | 11 +++++++----
 target-moxie/translate.c      |  5 +++--
 target-openrisc/translate.c   |  7 ++++---
 target-ppc/translate.c        |  8 +++++---
 target-s390x/translate.c      |  5 +++--
 target-sh4/translate.c        |  8 +++++---
 target-sparc/translate.c      |  3 ++-
 target-unicore32/translate.c  |  7 ++++---
 target-xtensa/translate.c     |  7 ++++---
 23 files changed, 83 insertions(+), 55 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 88f4e75..d52e581 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -297,7 +297,7 @@ int cpu_exec(CPUArchState *env)
             for(;;) {
                 interrupt_request = cpu->interrupt_request;
                 if (unlikely(interrupt_request)) {
-                    if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
+                    if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
                         /* Mask out external interrupts for this step. */
                         interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
                     }
diff --git a/cpus.c b/cpus.c
index f97983d..8b99deb 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1148,7 +1148,7 @@ static void tcg_exec_all(void)
         CPUArchState *env = cpu->env_ptr;
 
         qemu_clock_enable(vm_clock,
-                          (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
+                          (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
         if (cpu_can_run(cpu)) {
             r = tcg_cpu_exec(env);
diff --git a/exec.c b/exec.c
index 4e20143..f2d848c 100644
--- a/exec.c
+++ b/exec.c
@@ -584,11 +584,13 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
 void cpu_single_step(CPUArchState *env, int enabled)
 {
 #if defined(TARGET_HAS_ICE)
-    if (env->singlestep_enabled != enabled) {
-        env->singlestep_enabled = enabled;
-        if (kvm_enabled())
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    if (cpu->singlestep_enabled != enabled) {
+        cpu->singlestep_enabled = enabled;
+        if (kvm_enabled()) {
             kvm_update_guest_debug(env, 0);
-        else {
+        } else {
             /* must flush all the translated code to avoid inconsistencies */
             /* XXX: only flush what is necessary */
             tb_flush(env);
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 39094b3..12b1ca7 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -170,7 +170,6 @@ typedef struct CPUWatchpoint {
     /* from this point: preserved by CPU reset */                       \
     /* ice debug support */                                             \
     QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;            \
-    int singlestep_enabled;                                             \
                                                                         \
     QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;            \
     CPUWatchpoint *watchpoint_hit;                                      \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index d8b77af..a02b142 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -148,6 +148,7 @@ struct CPUState {
     volatile sig_atomic_t exit_request;
     volatile sig_atomic_t tcg_exit_req;
     uint32_t interrupt_request;
+    int singlestep_enabled;
 
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
diff --git a/kvm-all.c b/kvm-all.c
index 00ef85d..65e93cd 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1886,7 +1886,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
 
     data.dbg.control = reinject_trap;
 
-    if (env->singlestep_enabled) {
+    if (cpu->singlestep_enabled) {
         data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
     }
     kvm_arch_update_guest_debug(cpu, &data.dbg);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 147285a..0229a66 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -377,10 +377,12 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
 
 static int use_goto_tb(DisasContext *ctx, uint64_t dest)
 {
+    CPUState *cs = CPU(ctx->cpu);
+
     /* Check for the dest on the same page as the start of the TB.  We
        also want to suppress goto_tb in the case of single-steping and IO.  */
     return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
-            && !ctx->cpu->env.singlestep_enabled
+            && !cs->singlestep_enabled
             && !(ctx->tb->cflags & CF_LAST_IO));
 }
 
@@ -3379,6 +3381,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUAlphaState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     target_ulong pc_start;
@@ -3394,9 +3397,10 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
     ctx.tb = tb;
-    ctx.cpu = alpha_env_get_cpu(env);
+    ctx.cpu = cpu;
     ctx.pc = pc_start;
     ctx.mem_idx = cpu_mmu_index(env);
+    cs = CPU(ctx.cpu);
 
     /* ??? Every TB begins with unset rounding mode, to be initialized on
        the first fp insn of the TB.  Alternately we could define a proper
@@ -3453,7 +3457,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
                 || tcg_ctx.gen_opc_ptr >= gen_opc_end
                 || num_insns >= max_insns
                 || singlestep
-                || env->singlestep_enabled)) {
+                || cs->singlestep_enabled)) {
             ret = EXIT_PC_STALE;
         }
     } while (ret == NO_EXIT);
@@ -3470,7 +3474,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
         tcg_gen_movi_i64(cpu_pc, ctx.pc);
         /* FALLTHRU */
     case EXIT_PC_UPDATED:
-        if (env->singlestep_enabled) {
+        if (cs->singlestep_enabled) {
             gen_excp_1(EXCP_DEBUG, 0);
         } else {
             tcg_gen_exit_tb(0);
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9310c58..19e3fb9 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9800,6 +9800,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
@@ -9819,7 +9820,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->condjmp = 0;
     dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
     dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
@@ -9969,7 +9970,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
          * ensures prefetch aborts occur at the right place.  */
         num_insns ++;
     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !cs->singlestep_enabled &&
              !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
@@ -9986,7 +9987,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
     /* At this stage dc->condjmp will only be set when the skipped
        instruction was a conditional branch or trap, and the PC has
        already been written.  */
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (dc->condjmp) {
             gen_set_condexec(dc);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index ce1f03b..e6a8c76 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3165,6 +3165,7 @@ static void
 gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUCRISState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -3197,7 +3198,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
     dc->is_jmp = DISAS_NEXT;
     dc->ppc = pc_start;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->flags_uptodate = 1;
     dc->flagx_known = 1;
     dc->flags_x = tb->flags & X_FLAG;
@@ -3337,7 +3338,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
 
         /* If we are rexecuting a branch due to exceptions on
            delay slots dont break.  */
-        if (!(tb->pc & 1) && env->singlestep_enabled) {
+        if (!(tb->pc & 1) && cs->singlestep_enabled) {
             break;
         }
     } while (!dc->is_jmp && !dc->cpustate_changed
@@ -3370,7 +3371,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
 
     cris_evaluate_flags(dc);
 
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(env_pc, npc);
         }
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index cc3dcec..793cf16 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1597,6 +1597,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu)
 
 static int kvm_guest_debug_workarounds(X86CPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     int ret = 0;
     unsigned long reinject_trap = 0;
@@ -1619,7 +1620,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu)
      * reinject them via SET_GUEST_DEBUG.
      */
     if (reinject_trap ||
-        (!kvm_has_robust_singlestep() && env->singlestep_enabled)) {
+        (!kvm_has_robust_singlestep() && cs->singlestep_enabled)) {
         ret = kvm_update_guest_debug(env, reinject_trap);
     }
     return ret;
@@ -2045,13 +2046,14 @@ static CPUWatchpoint hw_watchpoint;
 static int kvm_handle_debug(X86CPU *cpu,
                             struct kvm_debug_exit_arch *arch_info)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     int ret = 0;
     int n;
 
     if (arch_info->exception == 1) {
         if (arch_info->dr6 & (1 << 14)) {
-            if (env->singlestep_enabled) {
+            if (cs->singlestep_enabled) {
                 ret = EXCP_DEBUG;
             }
         } else {
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 6550c27..065a9d3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8255,6 +8255,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_ptr;
@@ -8281,7 +8282,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
     dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
     dc->cs_base = cs_base;
@@ -8302,7 +8303,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 #endif
     dc->flags = flags;
-    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
+    dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK)
 #ifndef CONFIG_SOFTMMU
                     || (flags & HF_SOFTMMU_MASK)
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 6d107dc..1b87b7d 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1014,6 +1014,7 @@ static void check_breakpoint(CPULM32State *env, DisasContext *dc)
 static void gen_intermediate_code_internal(LM32CPU *cpu,
         TranslationBlock *tb, bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPULM32State *env = &cpu->env;
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
@@ -1031,7 +1032,7 @@ static void gen_intermediate_code_internal(LM32CPU *cpu,
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->nr_nops = 0;
 
     if (pc_start & 3) {
@@ -1076,7 +1077,7 @@ static void gen_intermediate_code_internal(LM32CPU *cpu,
 
     } while (!dc->is_jmp
          && tcg_ctx.gen_opc_ptr < gen_opc_end
-         && !env->singlestep_enabled
+         && !cs->singlestep_enabled
          && !singlestep
          && (dc->pc < next_page_start)
          && num_insns < max_insns);
@@ -1085,7 +1086,7 @@ static void gen_intermediate_code_internal(LM32CPU *cpu,
         gen_io_end();
     }
 
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
         }
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 2d73af5..d562eeb 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2974,6 +2974,7 @@ static inline void
 gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUM68KState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     uint16_t *gen_opc_end;
@@ -2995,7 +2996,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
     dc->cc_op = CC_OP_DYNAMIC;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
     dc->is_mem = 0;
@@ -3038,14 +3039,14 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
 	disas_m68k_insn(env, dc);
         num_insns++;
     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !cs->singlestep_enabled &&
              !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (!dc->is_jmp) {
             gen_flush_cc_op(dc);
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 6484378..2d3b9a8 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1741,6 +1741,7 @@ static void
 gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUMBState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -1766,7 +1767,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
         dc->jmp = JMP_INDIRECT;
     }
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
     dc->nr_nops = 0;
@@ -1859,8 +1860,9 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
                 break;
             }
         }
-        if (env->singlestep_enabled)
+        if (cs->singlestep_enabled) {
             break;
+        }
     } while (!dc->is_jmp && !dc->cpustate_changed
          && tcg_ctx.gen_opc_ptr < gen_opc_end
                  && !singlestep
@@ -1887,7 +1889,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     }
     t_sync_flags(dc);
 
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 8246c20..877f8df 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15543,6 +15543,7 @@ static inline void
 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUMIPSState *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
@@ -15561,7 +15562,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
-    ctx.singlestep_enabled = env->singlestep_enabled;
+    ctx.singlestep_enabled = cs->singlestep_enabled;
     ctx.insn_flags = env->insn_flags;
     ctx.tb = tb;
     ctx.bstate = BS_NONE;
@@ -15637,8 +15638,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
            This is what GDB expects and is consistent with what the
            hardware does (e.g. if a delay slot instruction faults, the
            reported PC is the PC of the branch).  */
-        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
+        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
             break;
+        }
 
         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
             break;
@@ -15653,9 +15655,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
         if (singlestep)
             break;
     }
-    if (tb->cflags & CF_LAST_IO)
+    if (tb->cflags & CF_LAST_IO) {
         gen_io_end();
-    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
+    }
+    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
         gen_helper_0e0i(raise_exception, EXCP_DEBUG);
     } else {
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index b0ae38a..dab6626 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -824,6 +824,7 @@ static void
 gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     DisasContext ctx;
     target_ulong pc_start;
     uint16_t *gen_opc_end;
@@ -871,7 +872,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
         ctx.pc += decode_opc(cpu, &ctx);
         num_insns++;
 
-        if (env->singlestep_enabled) {
+        if (cs->singlestep_enabled) {
             break;
         }
 
@@ -880,7 +881,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
         }
     } while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end);
 
-    if (env->singlestep_enabled) {
+    if (cs->singlestep_enabled) {
         tcg_gen_movi_tl(cpu_pc, ctx.pc);
         gen_helper_debug(cpu_env);
     } else {
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index f222834..a6050ba 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1662,6 +1662,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
                                                   TranslationBlock *tb,
                                                   int search_pc)
 {
+    CPUState *cs = CPU(cpu);
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -1681,7 +1682,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
     dc->mem_idx = cpu_mmu_index(&cpu->env);
     dc->synced_flags = dc->tb_flags = tb->flags;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
-    dc->singlestep_enabled = cpu->env.singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("-----------------------------------------\n");
         log_cpu_state(CPU(cpu), 0);
@@ -1743,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
         }
     } while (!dc->is_jmp
              && tcg_ctx.gen_opc_ptr < gen_opc_end
-             && !cpu->env.singlestep_enabled
+             && !cs->singlestep_enabled
              && !singlestep
              && (dc->pc < next_page_start)
              && num_insns < max_insns);
@@ -1755,7 +1756,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
         dc->is_jmp = DISAS_UPDATE;
         tcg_gen_movi_tl(cpu_pc, dc->pc);
     }
-    if (unlikely(cpu->env.singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
         }
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index eb96272..f07d70d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9730,6 +9730,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     opc_handler_t **table, *handler;
@@ -9770,8 +9771,9 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
         ctx.singlestep_enabled = 0;
     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
-    if (unlikely(env->singlestep_enabled))
+    if (unlikely(cs->singlestep_enabled)) {
         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
+    }
 #if defined (DO_SINGLE_STEP) && 0
     /* Single step trace mode */
     msr_se = 1;
@@ -9873,7 +9875,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                      ctx.exception != POWERPC_EXCP_BRANCH)) {
             gen_exception(ctxp, POWERPC_EXCP_TRACE);
         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
-                            (env->singlestep_enabled) ||
+                            (cs->singlestep_enabled) ||
                             singlestep ||
                             num_insns >= max_insns)) {
             /* if we reach a page boundary or are single stepping, stop
@@ -9887,7 +9889,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
     if (ctx.exception == POWERPC_EXCP_NONE) {
         gen_goto_tb(&ctx, 0, ctx.nip);
     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
-        if (unlikely(env->singlestep_enabled)) {
+        if (unlikely(cs->singlestep_enabled)) {
             gen_debug_exception(ctxp);
         }
         /* Generate the return instruction */
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index cba7b87..1fb76c5 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -4740,6 +4740,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUS390XState *env = &cpu->env;
     DisasContext dc;
     target_ulong pc_start;
@@ -4761,7 +4762,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
     dc.tb = tb;
     dc.pc = pc_start;
     dc.cc_op = CC_OP_DYNAMIC;
-    do_debug = dc.singlestep_enabled = env->singlestep_enabled;
+    do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
 
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
@@ -4818,7 +4819,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
                 || tcg_ctx.gen_opc_ptr >= gen_opc_end
                 || num_insns >= max_insns
                 || singlestep
-                || env->singlestep_enabled)) {
+                || cs->singlestep_enabled)) {
             status = EXIT_PC_STALE;
         }
     } while (status == NO_EXIT);
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 2fbe668..59f3d47 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1849,6 +1849,7 @@ static inline void
 gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUSH4State *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
@@ -1868,7 +1869,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
        so assume it is a dynamic branch.  */
     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
     ctx.tb = tb;
-    ctx.singlestep_enabled = env->singlestep_enabled;
+    ctx.singlestep_enabled = cs->singlestep_enabled;
     ctx.features = env->features;
     ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
 
@@ -1914,8 +1915,9 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
 	ctx.pc += 2;
 	if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
 	    break;
-	if (env->singlestep_enabled)
+        if (cs->singlestep_enabled) {
 	    break;
+        }
         if (num_insns >= max_insns)
             break;
         if (singlestep)
@@ -1923,7 +1925,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (env->singlestep_enabled) {
+    if (cs->singlestep_enabled) {
         tcg_gen_movi_i32(cpu_pc, ctx.pc);
         gen_helper_debug(cpu_env);
     } else {
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5e771e5..093e0e2 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5223,6 +5223,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
                                                   TranslationBlock *tb,
                                                   bool spc)
 {
+    CPUState *cs = CPU(cpu);
     CPUSPARCState *env = &cpu->env;
     target_ulong pc_start, last_pc;
     uint16_t *gen_opc_end;
@@ -5244,7 +5245,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
     dc->def = env->def;
     dc->fpu_enabled = tb_fpu_enabled(tb->flags);
     dc->address_mask_32bit = tb_am_enabled(tb->flags);
-    dc->singlestep = (env->singlestep_enabled || singlestep);
+    dc->singlestep = (cs->singlestep_enabled || singlestep);
     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
     num_insns = 0;
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index d85185d..68be1c6 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1879,6 +1879,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
 static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
         TranslationBlock *tb, bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUUniCore32State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
@@ -1900,7 +1901,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->condjmp = 0;
     cpu_F0s = tcg_temp_new_i32();
     cpu_F1s = tcg_temp_new_i32();
@@ -1971,7 +1972,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
          * ensures prefetch aborts occur at the right place.  */
         num_insns++;
     } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
-             !env->singlestep_enabled &&
+             !cs->singlestep_enabled &&
              !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
@@ -1988,7 +1989,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
     /* At this stage dc->condjmp will only be set when the skipped
        instruction was a conditional branch or trap, and the PC has
        already been written.  */
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (dc->condjmp) {
             if (dc->is_jmp == DISAS_SYSCALL) {
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index d5f2068..cc36fa4 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2879,6 +2879,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
                                            TranslationBlock *tb,
                                            bool search_pc)
 {
+    CPUState *cs = CPU(cpu);
     CPUXtensaState *env = &cpu->env;
     DisasContext dc;
     int insn_count = 0;
@@ -2894,7 +2895,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
     }
 
     dc.config = env->config;
-    dc.singlestep_enabled = env->singlestep_enabled;
+    dc.singlestep_enabled = cs->singlestep_enabled;
     dc.tb = tb;
     dc.pc = pc_start;
     dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
@@ -2917,7 +2918,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
 
     gen_tb_start();
 
-    if (env->singlestep_enabled && env->exception_taken) {
+    if (cs->singlestep_enabled && env->exception_taken) {
         env->exception_taken = 0;
         tcg_gen_movi_i32(cpu_pc, dc.pc);
         gen_exception(&dc, EXCP_DEBUG);
@@ -2970,7 +2971,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
         if (dc.icount) {
             tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
         }
-        if (env->singlestep_enabled) {
+        if (cs->singlestep_enabled) {
             tcg_gen_movi_i32(cpu_pc, dc.pc);
             gen_exception(&dc, EXCP_DEBUG);
             break;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 26/41] gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (24 preceding siblings ...)
  2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 27/41] cpu: Change cpu_single_step() argument to CPUState Andreas Färber
                   ` (15 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

In particular reindent to 4 instead of 2 spaces.

Prepares for changing cpu_single_step() argument in gdb_handlesig().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 94 +++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 07838eb..ede5cb1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2759,66 +2759,66 @@ gdb_queuesig (void)
 }
 
 int
-gdb_handlesig (CPUArchState *env, int sig)
+gdb_handlesig(CPUArchState *env, int sig)
 {
-  GDBState *s;
-  char buf[256];
-  int n;
+    GDBState *s;
+    char buf[256];
+    int n;
 
-  s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return sig;
+    s = gdbserver_state;
+    if (gdbserver_fd < 0 || s->fd < 0) {
+        return sig;
+    }
 
-  /* disable single step if it was enabled */
-  cpu_single_step(env, 0);
-  tb_flush(env);
+    /* disable single step if it was enabled */
+    cpu_single_step(env, 0);
+    tb_flush(env);
 
-  if (sig != 0)
-    {
-      snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
-      put_packet(s, buf);
-    }
-  /* put_packet() might have detected that the peer terminated the 
-     connection.  */
-  if (s->fd < 0)
-      return sig;
-
-  sig = 0;
-  s->state = RS_IDLE;
-  s->running_state = 0;
-  while (s->running_state == 0) {
-      n = read (s->fd, buf, 256);
-      if (n > 0)
-        {
-          int i;
+    if (sig != 0) {
+        snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
+        put_packet(s, buf);
+    }
+    /* put_packet() might have detected that the peer terminated the
+       connection.  */
+    if (s->fd < 0) {
+        return sig;
+    }
 
-          for (i = 0; i < n; i++)
-            gdb_read_byte (s, buf[i]);
-        }
-      else if (n == 0 || errno != EAGAIN)
-        {
-          /* XXX: Connection closed.  Should probably wait for another
-             connection before continuing.  */
-          return sig;
+    sig = 0;
+    s->state = RS_IDLE;
+    s->running_state = 0;
+    while (s->running_state == 0) {
+        n = read(s->fd, buf, 256);
+        if (n > 0) {
+            int i;
+
+            for (i = 0; i < n; i++) {
+                gdb_read_byte(s, buf[i]);
+            }
+        } else if (n == 0 || errno != EAGAIN) {
+            /* XXX: Connection closed.  Should probably wait for another
+               connection before continuing.  */
+            return sig;
         }
-  }
-  sig = s->signal;
-  s->signal = 0;
-  return sig;
+    }
+    sig = s->signal;
+    s->signal = 0;
+    return sig;
 }
 
 /* Tell the remote gdb that the process has exited due to SIG.  */
 void gdb_signalled(CPUArchState *env, int sig)
 {
-  GDBState *s;
-  char buf[4];
+    GDBState *s;
+    char buf[4];
 
-  s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return;
+    s = gdbserver_state;
+    if (gdbserver_fd < 0 || s->fd < 0) {
+        return;
+    }
 
-  snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
-  put_packet(s, buf);
+    snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
+    put_packet(s, buf);
 }
 
 static void gdb_accept(void)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 27/41] cpu: Change cpu_single_step() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (25 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 26/41] gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01   ` [Qemu-devel] [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert, remove}_breakpoint() " Andreas Färber
                   ` (14 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Use CPUState::env_ptr for now.

Needed for GdbState::c_cpu.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 exec.c                 | 4 ++--
 gdbstub.c              | 9 +++++----
 include/exec/cpu-all.h | 6 ------
 include/qom/cpu.h      | 6 ++++++
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/exec.c b/exec.c
index f2d848c..56a1d84 100644
--- a/exec.c
+++ b/exec.c
@@ -581,10 +581,10 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
 
 /* enable or disable single step mode. EXCP_DEBUG is returned by the
    CPU loop after each instruction */
-void cpu_single_step(CPUArchState *env, int enabled)
+void cpu_single_step(CPUState *cpu, int enabled)
 {
 #if defined(TARGET_HAS_ICE)
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUArchState *env = cpu->env_ptr;
 
     if (cpu->singlestep_enabled != enabled) {
         cpu->singlestep_enabled = enabled;
diff --git a/gdbstub.c b/gdbstub.c
index ede5cb1..17da380 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2153,7 +2153,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                     s->c_cpu = env;
                 }
                 if (res == 's') {
-                    cpu_single_step(s->c_cpu, sstep_flags);
+                    cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags);
                 }
                 s->signal = res_signal;
                 gdb_continue(s);
@@ -2181,7 +2181,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             addr = strtoull(p, (char **)&p, 16);
             gdb_set_cpu_pc(s, addr);
         }
-        cpu_single_step(s->c_cpu, sstep_flags);
+        cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags);
         gdb_continue(s);
 	return RS_IDLE;
     case 'F':
@@ -2568,7 +2568,7 @@ send_packet:
     put_packet(s, buf);
 
     /* disable single step if it was enabled */
-    cpu_single_step(env, 0);
+    cpu_single_step(cpu, 0);
 }
 #endif
 
@@ -2761,6 +2761,7 @@ gdb_queuesig (void)
 int
 gdb_handlesig(CPUArchState *env, int sig)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     GDBState *s;
     char buf[256];
     int n;
@@ -2771,7 +2772,7 @@ gdb_handlesig(CPUArchState *env, int sig)
     }
 
     /* disable single step if it was enabled */
-    cpu_single_step(env, 0);
+    cpu_single_step(cpu, 0);
     tb_flush(env);
 
     if (sig != 0) {
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 6499cd0..1f3c002 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -428,12 +428,6 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
 void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
 void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
 
-#define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
-#define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
-#define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */
-
-void cpu_single_step(CPUArchState *env, int enabled);
-
 #if !defined(CONFIG_USER_ONLY)
 
 /* Return the physical page corresponding to a virtual one. Use it
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index a02b142..cd10b1d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -482,6 +482,12 @@ void cpu_resume(CPUState *cpu);
  */
 void qemu_init_vcpu(CPUState *cpu);
 
+#define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
+#define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
+#define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */
+
+void cpu_single_step(CPUState *cpu, int enabled);
+
 #ifdef CONFIG_SOFTMMU
 extern const struct VMStateDescription vmstate_cpu_common;
 #else
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
@ 2013-06-29 20:01   ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
                     ` (40 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: jan.kiszka, Andreas Färber, Gleb Natapov, Marcelo Tosatti,
	open list:Overall

CPUArchState is no longer directly used since converting CPU loops to
CPUState.

Prepares for changing GDBState::c_cpu to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c            | 12 ++++++++----
 include/sysemu/kvm.h |  4 ++--
 kvm-all.c            | 10 ++++------
 kvm-stub.c           |  4 ++--
 4 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 17da380..b77cd3e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1954,8 +1954,10 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     CPUArchState *env;
     int err = 0;
 
-    if (kvm_enabled())
-        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+    if (kvm_enabled()) {
+        return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu),
+                                     addr, len, type);
+    }
 
     switch (type) {
     case GDB_BREAKPOINT_SW:
@@ -1991,8 +1993,10 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     CPUArchState *env;
     int err = 0;
 
-    if (kvm_enabled())
-        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+    if (kvm_enabled()) {
+        return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu),
+                                     addr, len, type);
+    }
 
     switch (type) {
     case GDB_BREAKPOINT_SW:
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 9460d5a..60a587e 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -159,9 +159,9 @@ void *kvm_arch_ram_alloc(ram_addr_t size);
 void kvm_setup_guest_memory(void *start, size_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type);
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type);
 void kvm_remove_all_breakpoints(CPUState *cpu);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
diff --git a/kvm-all.c b/kvm-all.c
index 65e93cd..9991953 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1896,10 +1896,9 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return data.err;
 }
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
     int err;
 
@@ -1942,10 +1941,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
     return 0;
 }
 
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
     int err;
 
@@ -2018,13 +2016,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -EINVAL;
 }
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
diff --git a/kvm-stub.c b/kvm-stub.c
index a6c2b01..b7f3569 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -ENOSYS;
 }
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert, remove}_breakpoint() argument to CPUState
@ 2013-06-29 20:01   ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcelo Tosatti, jan.kiszka, Andreas Färber, Gleb Natapov,
	open list:Overall

CPUArchState is no longer directly used since converting CPU loops to
CPUState.

Prepares for changing GDBState::c_cpu to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c            | 12 ++++++++----
 include/sysemu/kvm.h |  4 ++--
 kvm-all.c            | 10 ++++------
 kvm-stub.c           |  4 ++--
 4 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 17da380..b77cd3e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1954,8 +1954,10 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     CPUArchState *env;
     int err = 0;
 
-    if (kvm_enabled())
-        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+    if (kvm_enabled()) {
+        return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu),
+                                     addr, len, type);
+    }
 
     switch (type) {
     case GDB_BREAKPOINT_SW:
@@ -1991,8 +1993,10 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     CPUArchState *env;
     int err = 0;
 
-    if (kvm_enabled())
-        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+    if (kvm_enabled()) {
+        return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu),
+                                     addr, len, type);
+    }
 
     switch (type) {
     case GDB_BREAKPOINT_SW:
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 9460d5a..60a587e 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -159,9 +159,9 @@ void *kvm_arch_ram_alloc(ram_addr_t size);
 void kvm_setup_guest_memory(void *start, size_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type);
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type);
 void kvm_remove_all_breakpoints(CPUState *cpu);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
diff --git a/kvm-all.c b/kvm-all.c
index 65e93cd..9991953 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1896,10 +1896,9 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return data.err;
 }
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
     int err;
 
@@ -1942,10 +1941,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
     return 0;
 }
 
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
     int err;
 
@@ -2018,13 +2016,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -EINVAL;
 }
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
diff --git a/kvm-stub.c b/kvm-stub.c
index a6c2b01..b7f3569 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -ENOSYS;
 }
 
-int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
+int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 29/41] gdbstub: Change syscall callback argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (27 preceding siblings ...)
  2013-06-29 20:01   ` [Qemu-devel] [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert, remove}_breakpoint() " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 30/41] gdbstub: Change gdb_handlesig() " Andreas Färber
                   ` (12 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, jan.kiszka, Andreas Färber, Paul Brook

Callback implementations were specific to arm and m68k, so can easily
cast to ARMCPU and M68kCPU respectively.

Prepares for changing GDBState::c_cpu to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c               | 2 +-
 include/exec/gdbstub.h  | 2 +-
 target-arm/arm-semi.c   | 8 ++++++--
 target-m68k/m68k-semi.c | 5 ++++-
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index b77cd3e..63ac5fe 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2204,7 +2204,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                 p++;
             type = *p;
             if (s->current_syscall_cb) {
-                s->current_syscall_cb(s->c_cpu, ret, err);
+                s->current_syscall_cb(ENV_GET_CPU(s->c_cpu), ret, err);
                 s->current_syscall_cb = NULL;
             }
             if (type == 'C') {
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index ded4160..de0f4fb 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -11,7 +11,7 @@
 #define GDB_WATCHPOINT_ACCESS    4
 
 #ifdef NEED_CPU_H
-typedef void (*gdb_syscall_complete_cb)(CPUArchState *env,
+typedef void (*gdb_syscall_complete_cb)(CPUState *cpu,
                                         target_ulong ret, target_ulong err);
 
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index 5f01bca..4ecea65 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -122,8 +122,10 @@ static target_ulong arm_semi_syscall_len;
 static target_ulong syscall_err;
 #endif
 
-static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
+static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
 #ifdef CONFIG_USER_ONLY
     TaskState *ts = env->opaque;
 #endif
@@ -152,8 +154,10 @@ static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
     }
 }
 
-static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err)
+static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
     /* The size is always stored in big-endian order, extract
        the value. We assume the size always fit in 32 bits.  */
     uint32_t size;
diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c
index 239fadb..94c4983 100644
--- a/target-m68k/m68k-semi.c
+++ b/target-m68k/m68k-semi.c
@@ -161,8 +161,11 @@ static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, uint32_t err)
 
 static int m68k_semi_is_fseek;
 
-static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err)
+static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
+
     if (m68k_semi_is_fseek) {
         /* FIXME: We've already lost the high bits of the fseek
            return value.  */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 30/41] gdbstub: Change gdb_handlesig() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (28 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 29/41] gdbstub: Change syscall callback " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 31/41] gdbstub: Change GDBState::c_cpu " Andreas Färber
                   ` (11 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio, jan.kiszka, Andreas Färber

Prepares for changing GDBState::c_cpu to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 bsd-user/main.c        | 10 ++++++----
 gdbstub.c              |  6 +++---
 include/exec/gdbstub.h |  2 +-
 linux-user/main.c      | 35 +++++++++++++++++++----------------
 linux-user/signal.c    |  3 ++-
 5 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 1e92552..f9246aa 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -643,7 +643,7 @@ void cpu_loop(CPUSPARCState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
 #if 0
                 if (sig)
                   {
@@ -738,6 +738,7 @@ int main(int argc, char **argv)
     struct image_info info1, *info = &info1;
     TaskState ts1, *ts = &ts1;
     CPUArchState *env;
+    CPUState *cpu;
     int optind;
     const char *r;
     int gdbstub_port = 0;
@@ -912,10 +913,11 @@ int main(int argc, char **argv)
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    cpu = ENV_GET_CPU(env);
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)
-    cpu_reset(ENV_GET_CPU(env));
+    cpu_reset(cpu);
 #endif
-    thread_cpu = ENV_GET_CPU(env);
+    thread_cpu = cpu;
 
     if (getenv("QEMU_STRACE")) {
         do_strace = 1;
@@ -1134,7 +1136,7 @@ int main(int argc, char **argv)
 
     if (gdbstub_port) {
         gdbserver_start (gdbstub_port);
-        gdb_handlesig(env, 0);
+        gdb_handlesig(cpu, 0);
     }
     cpu_loop(env);
     /* never exits */
diff --git a/gdbstub.c b/gdbstub.c
index 63ac5fe..81a8941 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2634,7 +2634,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
     va_end(va);
 #ifdef CONFIG_USER_ONLY
     put_packet(s, s->syscall_buf);
-    gdb_handlesig(s->c_cpu, 0);
+    gdb_handlesig(ENV_GET_CPU(s->c_cpu), 0);
 #else
     /* In this case wait to send the syscall packet until notification that
        the CPU has stopped.  This must be done because if the packet is sent
@@ -2763,9 +2763,9 @@ gdb_queuesig (void)
 }
 
 int
-gdb_handlesig(CPUArchState *env, int sig)
+gdb_handlesig(CPUState *cpu, int sig)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUArchState *env = cpu->env_ptr;
     GDBState *s;
     char buf[256];
     int n;
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index de0f4fb..0f1ad9a 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -20,7 +20,7 @@ void gdb_set_stop_cpu(CPUState *cpu);
 void gdb_exit(CPUArchState *, int);
 #ifdef CONFIG_USER_ONLY
 int gdb_queuesig (void);
-int gdb_handlesig (CPUArchState *, int);
+int gdb_handlesig(CPUState *, int);
 void gdb_signalled(CPUArchState *, int);
 void gdbserver_fork(CPUArchState *);
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 7f15d3d..27f8232 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -312,6 +312,7 @@ static void set_idt(int n, unsigned int dpl)
 
 void cpu_loop(CPUX86State *env)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     int trapnr;
     abi_ulong pc;
     target_siginfo_t info;
@@ -443,7 +444,7 @@ void cpu_loop(CPUX86State *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -875,7 +876,7 @@ void cpu_loop(CPUARMState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -966,7 +967,7 @@ void cpu_loop(CPUUniCore32State *env)
             {
                 int sig;
 
-                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig) {
                     info.si_signo = sig;
                     info.si_errno = 0;
@@ -1233,7 +1234,7 @@ void cpu_loop (CPUSPARCState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -1764,7 +1765,7 @@ void cpu_loop(CPUPPCState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig) {
                     info.si_signo = sig;
                     info.si_errno = 0;
@@ -2315,7 +2316,7 @@ done_syscall:
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -2475,7 +2476,7 @@ void cpu_loop(CPUOpenRISCState *env)
             break;
         }
         if (gdbsig) {
-            gdb_handlesig(env, gdbsig);
+            gdb_handlesig(cs, gdbsig);
             if (gdbsig != TARGET_SIGTRAP) {
                 exit(1);
             }
@@ -2518,7 +2519,7 @@ void cpu_loop(CPUSH4State *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -2586,7 +2587,7 @@ void cpu_loop(CPUCRISState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -2686,7 +2687,7 @@ void cpu_loop(CPUMBState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -2779,7 +2780,7 @@ void cpu_loop(CPUM68KState *env)
             {
                 int sig;
 
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
                 if (sig)
                   {
                     info.si_signo = sig;
@@ -3006,7 +3007,7 @@ void cpu_loop(CPUAlphaState *env)
             }
             break;
         case EXCP_DEBUG:
-            info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
+            info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
             if (info.si_signo) {
                 env->lock_addr = -1;
                 info.si_errno = 0;
@@ -3059,7 +3060,7 @@ void cpu_loop(CPUS390XState *env)
             break;
 
         case EXCP_DEBUG:
-            sig = gdb_handlesig(env, TARGET_SIGTRAP);
+            sig = gdb_handlesig(cs, TARGET_SIGTRAP);
             if (sig) {
                 n = TARGET_TRAP_BRKPT;
                 goto do_signal_pc;
@@ -3541,6 +3542,7 @@ int main(int argc, char **argv, char **envp)
     struct linux_binprm bprm;
     TaskState *ts;
     CPUArchState *env;
+    CPUState *cpu;
     int optind;
     char **target_environ, **wrk;
     char **target_argv;
@@ -3637,11 +3639,12 @@ int main(int argc, char **argv, char **envp)
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
+    cpu = ENV_GET_CPU(env);
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)
-    cpu_reset(ENV_GET_CPU(env));
+    cpu_reset(cpu);
 #endif
 
-    thread_cpu = ENV_GET_CPU(env);
+    thread_cpu = cpu;
 
     if (getenv("QEMU_STRACE")) {
         do_strace = 1;
@@ -4076,7 +4079,7 @@ int main(int argc, char **argv, char **envp)
                     gdbstub_port);
             exit(1);
         }
-        gdb_handlesig(env, 0);
+        gdb_handlesig(cpu, 0);
     }
     cpu_loop(env);
     /* never exits */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 42d8911..bba85c7 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5386,6 +5386,7 @@ long do_rt_sigreturn(CPUArchState *env)
 
 void process_pending_signals(CPUArchState *cpu_env)
 {
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
     int sig;
     abi_ulong handler;
     sigset_t set, old_set;
@@ -5419,7 +5420,7 @@ void process_pending_signals(CPUArchState *cpu_env)
     if (!k->first)
         k->pending = 0;
 
-    sig = gdb_handlesig (cpu_env, sig);
+    sig = gdb_handlesig(cpu, sig);
     if (!sig) {
         sa = NULL;
         handler = TARGET_SIG_IGN;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 31/41] gdbstub: Change GDBState::c_cpu to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (29 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 30/41] gdbstub: Change gdb_handlesig() " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 32/41] gdbstub: Change gdb_{read, write}_register() argument " Andreas Färber
                   ` (10 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Allows us to drop find_cpu().
Xtensa still needs env for its num_g_regs.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 68 +++++++++++++++++++++++++++++----------------------------------
 1 file changed, 31 insertions(+), 37 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 81a8941..a8fafe2 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -287,7 +287,7 @@ enum RSState {
     RS_CHKSUM2,
 };
 typedef struct GDBState {
-    CPUArchState *c_cpu; /* current CPU for step/continue ops */
+    CPUState *c_cpu; /* current CPU for step/continue ops */
     CPUArchState *g_cpu; /* current CPU for other ops */
     CPUState *query_cpu; /* for q{f|s}ThreadInfo */
     enum RSState state; /* parsing state */
@@ -1955,8 +1955,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     int err = 0;
 
     if (kvm_enabled()) {
-        return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu),
-                                     addr, len, type);
+        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
     }
 
     switch (type) {
@@ -1994,8 +1993,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     int err = 0;
 
     if (kvm_enabled()) {
-        return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu),
-                                     addr, len, type);
+        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
     }
 
     switch (type) {
@@ -2031,7 +2029,7 @@ static void gdb_breakpoint_remove_all(void)
     CPUArchState *env;
 
     if (kvm_enabled()) {
-        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
+        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
         return;
     }
 
@@ -2046,7 +2044,7 @@ static void gdb_breakpoint_remove_all(void)
 
 static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 {
-    CPUState *cpu = ENV_GET_CPU(s->c_cpu);
+    CPUState *cpu = s->c_cpu;
     CPUClass *cc = CPU_GET_CLASS(cpu);
 
     cpu_synchronize_state(cpu);
@@ -2055,20 +2053,11 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
     }
 }
 
-static CPUArchState *find_cpu(uint32_t thread_id)
-{
-    CPUState *cpu;
-
-    cpu = qemu_get_cpu(thread_id);
-    if (cpu == NULL) {
-        return NULL;
-    }
-    return cpu->env_ptr;
-}
-
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
+#ifdef TARGET_XTENSA
     CPUArchState *env;
+#endif
     CPUState *cpu;
     const char *p;
     uint32_t thread;
@@ -2087,7 +2076,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     case '?':
         /* TODO: Make this return the correct value for user-mode.  */
         snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
-                 cpu_index(ENV_GET_CPU(s->c_cpu)));
+                 cpu_index(s->c_cpu));
         put_packet(s, buf);
         /* Remove all the breakpoints when this query is issued,
          * because gdb is doing and initial connect and the state
@@ -2149,15 +2138,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             }
             if (res) {
                 if (res_thread != -1 && res_thread != 0) {
-                    env = find_cpu(res_thread);
-                    if (env == NULL) {
+                    cpu = qemu_get_cpu(res_thread);
+                    if (cpu == NULL) {
                         put_packet(s, "E22");
                         break;
                     }
-                    s->c_cpu = env;
+                    s->c_cpu = cpu;
                 }
                 if (res == 's') {
-                    cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags);
+                    cpu_single_step(s->c_cpu, sstep_flags);
                 }
                 s->signal = res_signal;
                 gdb_continue(s);
@@ -2185,7 +2174,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             addr = strtoull(p, (char **)&p, 16);
             gdb_set_cpu_pc(s, addr);
         }
-        cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags);
+        cpu_single_step(s->c_cpu, sstep_flags);
         gdb_continue(s);
 	return RS_IDLE;
     case 'F':
@@ -2204,7 +2193,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                 p++;
             type = *p;
             if (s->current_syscall_cb) {
-                s->current_syscall_cb(ENV_GET_CPU(s->c_cpu), ret, err);
+                s->current_syscall_cb(s->c_cpu, ret, err);
                 s->current_syscall_cb = NULL;
             }
             if (type == 'C') {
@@ -2216,7 +2205,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'g':
         cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
+#ifdef TARGET_XTENSA
         env = s->g_cpu;
+#endif
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
@@ -2227,7 +2218,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'G':
         cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
+#ifdef TARGET_XTENSA
         env = s->g_cpu;
+#endif
         registers = mem_buf;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
@@ -2317,18 +2310,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "OK");
             break;
         }
-        env = find_cpu(thread);
-        if (env == NULL) {
+        cpu = qemu_get_cpu(thread);
+        if (cpu == NULL) {
             put_packet(s, "E22");
             break;
         }
         switch (type) {
         case 'c':
-            s->c_cpu = env;
+            s->c_cpu = cpu;
             put_packet(s, "OK");
             break;
         case 'g':
-            s->g_cpu = env;
+            s->g_cpu = cpu->env_ptr;
             put_packet(s, "OK");
             break;
         default:
@@ -2403,7 +2396,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
 #ifdef CONFIG_USER_ONLY
         else if (strncmp(p, "Offsets", 7) == 0) {
-            TaskState *ts = s->c_cpu->opaque;
+            CPUArchState *env = s->c_cpu->env_ptr;
+            TaskState *ts = env->opaque;
 
             snprintf(buf, sizeof(buf),
                      "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
@@ -2495,7 +2489,7 @@ void gdb_set_stop_cpu(CPUState *cpu)
 {
     CPUArchState *env = cpu->env_ptr;
 
-    gdbserver_state->c_cpu = env;
+    gdbserver_state->c_cpu = cpu;
     gdbserver_state->g_cpu = env;
 }
 
@@ -2503,8 +2497,8 @@ void gdb_set_stop_cpu(CPUState *cpu)
 static void gdb_vm_state_change(void *opaque, int running, RunState state)
 {
     GDBState *s = gdbserver_state;
-    CPUArchState *env = s->c_cpu;
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUArchState *env = s->c_cpu->env_ptr;
+    CPUState *cpu = s->c_cpu;
     char buf[256];
     const char *type;
     int ret;
@@ -2634,7 +2628,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
     va_end(va);
 #ifdef CONFIG_USER_ONLY
     put_packet(s, s->syscall_buf);
-    gdb_handlesig(ENV_GET_CPU(s->c_cpu), 0);
+    gdb_handlesig(s->c_cpu, 0);
 #else
     /* In this case wait to send the syscall packet until notification that
        the CPU has stopped.  This must be done because if the packet is sent
@@ -2642,7 +2636,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
        is still in the running state, which can cause packets to be dropped
        and state transition 'T' packets to be sent while the syscall is still
        being processed.  */
-    cpu_exit(ENV_GET_CPU(s->c_cpu));
+    cpu_exit(s->c_cpu);
 #endif
 }
 
@@ -2851,7 +2845,7 @@ static void gdb_accept(void)
     socket_set_nodelay(fd);
 
     s = g_malloc0(sizeof(GDBState));
-    s->c_cpu = first_cpu->env_ptr;
+    s->c_cpu = first_cpu;
     s->g_cpu = first_cpu->env_ptr;
     s->fd = fd;
     gdb_has_xml = 0;
@@ -3036,7 +3030,7 @@ int gdbserver_start(const char *device)
         mon_chr = s->mon_chr;
         memset(s, 0, sizeof(GDBState));
     }
-    s->c_cpu = first_cpu->env_ptr;
+    s->c_cpu = first_cpu;
     s->g_cpu = first_cpu->env_ptr;
     s->chr = chr;
     s->state = chr ? RS_IDLE : RS_INACTIVE;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 32/41] gdbstub: Change gdb_{read, write}_register() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (30 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 31/41] gdbstub: Change GDBState::c_cpu " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook Andreas Färber
                   ` (9 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Use CPUState::env_ptr for now.

Prepares for changing GDBState::g_cpu to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index a8fafe2..cee9c13 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1866,8 +1866,9 @@ static const char *get_feature_xml(const char *p, const char **newp)
 }
 #endif
 
-static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
+static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
+    CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
 
     if (reg < NUM_CORE_REGS)
@@ -1881,8 +1882,9 @@ static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
     return 0;
 }
 
-static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg)
+static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
+    CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
 
     if (reg < NUM_CORE_REGS)
@@ -2210,7 +2212,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 #endif
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
-            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
+            reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu),
+                                         mem_buf + len, addr);
             len += reg_size;
         }
         memtohex(buf, mem_buf, len);
@@ -2225,7 +2228,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
         for (addr = 0; addr < num_g_regs && len > 0; addr++) {
-            reg_size = gdb_write_register(s->g_cpu, registers, addr);
+            reg_size = gdb_write_register(ENV_GET_CPU(s->g_cpu), registers,
+                                          addr);
             len -= reg_size;
             registers += reg_size;
         }
@@ -2264,7 +2268,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (!gdb_has_xml)
             goto unknown_command;
         addr = strtoull(p, (char **)&p, 16);
-        reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
+        reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr);
         if (reg_size) {
             memtohex(buf, mem_buf, reg_size);
             put_packet(s, buf);
@@ -2280,7 +2284,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             p++;
         reg_size = strlen(p) / 2;
         hextomem(mem_buf, p, reg_size);
-        gdb_write_register(s->g_cpu, mem_buf, addr);
+        gdb_write_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr);
         put_packet(s, "OK");
         break;
     case 'Z':
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (31 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 32/41] gdbstub: Change gdb_{read, write}_register() argument " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-06 20:19   ` Andreas Färber
  2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
                   ` (8 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Anthony Green, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Guan Xuetao, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Since all targets now assign a softmmu-only field, we can drop helpers
cpu_class_set_{do_unassigned_access,vmsd}() and device_class_set_vmsd().

Prepares for changing cpu_memory_rw_debug() argument to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 exec.c                      | 20 ++++++------
 hw/i386/kvmvapic.c          |  6 ++--
 include/exec/cpu-all.h      |  5 ---
 include/qom/cpu.h           | 74 +++++++++++++--------------------------------
 target-alpha/cpu-qom.h      |  1 +
 target-alpha/cpu.c          |  7 +++--
 target-alpha/helper.c       |  5 +--
 target-arm/cpu-qom.h        |  2 ++
 target-arm/cpu.c            |  5 ++-
 target-arm/helper.c         |  8 +++--
 target-cris/cpu-qom.h       |  2 ++
 target-cris/cpu.c           |  3 ++
 target-cris/helper.c        |  7 +++--
 target-i386/cpu-qom.h       |  2 ++
 target-i386/cpu.c           |  3 +-
 target-i386/helper.c        |  4 ++-
 target-lm32/cpu-qom.h       |  1 +
 target-lm32/cpu.c           |  5 ++-
 target-lm32/helper.c        |  6 ++--
 target-m68k/cpu-qom.h       |  1 +
 target-m68k/cpu.c           |  3 ++
 target-m68k/helper.c        |  2 +-
 target-microblaze/cpu-qom.h |  1 +
 target-microblaze/cpu.c     |  5 ++-
 target-microblaze/helper.c  |  4 ++-
 target-mips/cpu-qom.h       |  1 +
 target-mips/cpu.c           |  5 ++-
 target-mips/helper.c        |  7 +++--
 target-moxie/cpu.c          |  5 ++-
 target-moxie/cpu.h          |  1 +
 target-moxie/helper.c       | 11 +++----
 target-openrisc/cpu.c       |  5 ++-
 target-openrisc/cpu.h       |  1 +
 target-openrisc/mmu.c       |  5 ++-
 target-ppc/cpu-qom.h        |  1 +
 target-ppc/mmu_helper.c     |  4 ++-
 target-s390x/cpu-qom.h      |  1 +
 target-s390x/cpu.c          |  3 ++
 target-s390x/helper.c       |  5 +--
 target-sh4/cpu-qom.h        |  1 +
 target-sh4/cpu.c            |  3 ++
 target-sh4/helper.c         |  5 +--
 target-sparc/cpu-qom.h      |  1 +
 target-sparc/cpu.c          |  5 ++-
 target-sparc/mmu_helper.c   | 11 ++++---
 target-unicore32/cpu-qom.h  |  1 +
 target-unicore32/cpu.c      |  3 ++
 target-unicore32/softmmu.c  |  7 +++--
 target-xtensa/cpu-qom.h     |  1 +
 target-xtensa/cpu.c         |  3 ++
 target-xtensa/helper.c      |  7 +++--
 target-xtensa/xtensa-semi.c |  4 +--
 52 files changed, 168 insertions(+), 121 deletions(-)

diff --git a/exec.c b/exec.c
index 56a1d84..359dc64 100644
--- a/exec.c
+++ b/exec.c
@@ -411,14 +411,14 @@ void cpu_exec_init(CPUArchState *env)
 
 #if defined(TARGET_HAS_ICE)
 #if defined(CONFIG_USER_ONLY)
-static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
     tb_invalidate_phys_page_range(pc, pc + 1, 0);
 }
 #else
-static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
-    tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) |
+    tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) |
             (pc & ~TARGET_PAGE_MASK));
 }
 #endif
@@ -521,15 +521,17 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
     bp->flags = flags;
 
     /* keep all GDB-injected breakpoints in front */
-    if (flags & BP_GDB)
+    if (flags & BP_GDB) {
         QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
-    else
+    } else {
         QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
+    }
 
-    breakpoint_invalidate(env, pc);
+    breakpoint_invalidate(ENV_GET_CPU(env), pc);
 
-    if (breakpoint)
+    if (breakpoint) {
         *breakpoint = bp;
+    }
     return 0;
 #else
     return -ENOSYS;
@@ -560,7 +562,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
 #if defined(TARGET_HAS_ICE)
     QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
 
-    breakpoint_invalidate(env, breakpoint->pc);
+    breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
 
     g_free(breakpoint);
 #endif
@@ -2572,7 +2574,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 
     while (len > 0) {
         page = addr & TARGET_PAGE_MASK;
-        phys_addr = cpu_get_phys_page_debug(env, page);
+        phys_addr = cpu_get_phys_page_debug(ENV_GET_CPU(env), page);
         /* if no physical page mapped, return an error */
         if (phys_addr == -1)
             return -1;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index d60864e..76fca34 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -146,6 +146,7 @@ static void update_guest_rom_state(VAPICROMState *s)
 
 static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     hwaddr paddr;
     target_ulong addr;
 
@@ -158,7 +159,7 @@ static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
      * virtual address space for the APIC mapping.
      */
     for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
-        paddr = cpu_get_phys_page_debug(env, addr);
+        paddr = cpu_get_phys_page_debug(cs, addr);
         if (paddr != APIC_DEFAULT_ADDRESS) {
             continue;
         }
@@ -271,6 +272,7 @@ instruction_ok:
 
 static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     hwaddr paddr;
     uint32_t rom_state_vaddr;
     uint32_t pos, patch, offset;
@@ -287,7 +289,7 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
 
     /* find out virtual address of the ROM */
     rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
-    paddr = cpu_get_phys_page_debug(env, rom_state_vaddr);
+    paddr = cpu_get_phys_page_debug(cs, rom_state_vaddr);
     if (paddr == -1) {
         return -1;
     }
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 1f3c002..16eeb7a 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -430,11 +430,6 @@ void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
 
 #if !defined(CONFIG_USER_ONLY)
 
-/* Return the physical page corresponding to a virtual one. Use it
-   only for debugging because no protection checks are done. Return -1
-   if no page found. */
-hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
-
 /* memory API */
 
 extern int phys_ram_fd;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index cd10b1d..9717650 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -61,6 +61,7 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
+ * @get_phys_page_debug: Callback for obtaining a physical address.
  * @vmsd: State description for migration.
  *
  * Represents a CPU family or model.
@@ -86,6 +87,7 @@ typedef struct CPUClass {
                                Error **errp);
     void (*set_pc)(CPUState *cpu, uint64_t value);
     void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
+    hwaddr (*get_phys_page_debug)(CPUState *cpu, uint64_t addr);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
@@ -262,6 +264,25 @@ void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 
+#ifndef CONFIG_USER_ONLY
+/**
+ * cpu_get_phys_page_debug:
+ * @cpu: The CPU to obtain the physical page address for.
+ * @addr: The virtual address.
+ *
+ * Obtains the physical page corresponding to a virtual one.
+ * Use it only for debugging because no protection checks are done.
+ *
+ * Returns: Corresponding physical page address or -1 if no page found.
+ */
+static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    return cc->get_phys_page_debug(cpu, addr);
+}
+#endif
+
 /**
  * cpu_reset:
  * @cpu: The CPU whose state is to be reset.
@@ -280,59 +301,6 @@ void cpu_reset(CPUState *cpu);
 ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
 
 /**
- * cpu_class_set_vmsd:
- * @cc: CPU class
- * @value: Value to set. Unused for %CONFIG_USER_ONLY.
- *
- * Sets #VMStateDescription for @cc.
- *
- * The @value argument is intentionally discarded for the non-softmmu targets
- * to avoid linker errors or excessive preprocessor usage. If this behavior
- * is undesired, you should assign #CPUClass.vmsd directly instead.
- */
-#ifndef CONFIG_USER_ONLY
-static inline void cpu_class_set_vmsd(CPUClass *cc,
-                                      const struct VMStateDescription *value)
-{
-    cc->vmsd = value;
-}
-#else
-#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL)
-#endif
-
-#ifndef CONFIG_USER_ONLY
-static inline void cpu_class_set_do_unassigned_access(CPUClass *cc,
-                                                      CPUUnassignedAccess value)
-{
-    cc->do_unassigned_access = value;
-}
-#else
-#define cpu_class_set_do_unassigned_access(cc, value) \
-    ((cc)->do_unassigned_access = NULL)
-#endif
-
-/**
- * device_class_set_vmsd:
- * @dc: Device class
- * @value: Value to set. Unused for %CONFIG_USER_ONLY.
- *
- * Sets #VMStateDescription for @dc.
- *
- * The @value argument is intentionally discarded for the non-softmmu targets
- * to avoid linker errors or excessive preprocessor usage. If this behavior
- * is undesired, you should assign #DeviceClass.vmsd directly instead.
- */
-#ifndef CONFIG_USER_ONLY
-static inline void device_class_set_vmsd(DeviceClass *dc,
-                                         const struct VMStateDescription *value)
-{
-    dc->vmsd = value;
-}
-#else
-#define device_class_set_vmsd(dc, value) ((dc)->vmsd = NULL)
-#endif
-
-/**
  * qemu_cpu_has_work:
  * @cpu: The vCPU to check.
  *
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 60125b1..50cccca 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -81,5 +81,6 @@ extern const struct VMStateDescription vmstate_alpha_cpu;
 void alpha_cpu_do_interrupt(CPUState *cpu);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                           int flags);
+hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 9679ac4..e03e74b 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -270,9 +270,12 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);
     cc->set_pc = alpha_cpu_set_pc;
-    device_class_set_vmsd(dc, &vmstate_alpha_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = alpha_cpu_unassigned_access;
+    cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
+    dc->vmsd = &vmstate_alpha_cpu;
+#endif
 }
 
 static const TypeInfo alpha_cpu_type_info = {
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index ff57dd6..bef210a 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -315,12 +315,13 @@ static int get_physical_address(CPUAlphaState *env, target_ulong addr,
     return ret;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUAlphaState *env, target_ulong addr)
+hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    AlphaCPU *cpu = ALPHA_CPU(cs);
     target_ulong phys;
     int prot, fail;
 
-    fail = get_physical_address(env, addr, 0, 0, &phys, &prot);
+    fail = get_physical_address(&cpu->env, addr, 0, 0, &phys, &prot);
     return (fail >= 0 ? -1 : phys);
 }
 
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 48ba605..c6d54c2 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -147,4 +147,6 @@ void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 
+hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+
 #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 281e252..5f8a8f9 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -819,7 +819,10 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = arm_cpu_do_interrupt;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
-    cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_arm_cpu;
+#endif
 }
 
 static void cpu_register(const ARMCPUInfo *info)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5f639fd..da4d4a6 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2749,17 +2749,19 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
+hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
     hwaddr phys_addr;
     target_ulong page_size;
     int prot;
     int ret;
 
-    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size);
+    ret = get_phys_addr(&cpu->env, addr, 0, 0, &phys_addr, &prot, &page_size);
 
-    if (ret != 0)
+    if (ret != 0) {
         return -1;
+    }
 
     return phys_addr;
 }
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index af7d14d..cd19070 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -79,4 +79,6 @@ void crisv10_cpu_do_interrupt(CPUState *cpu);
 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 
+hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+
 #endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index f7e8c2a..4d45b98 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -255,6 +255,9 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = cris_cpu_do_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
+#endif
 }
 
 static const TypeInfo cris_cpu_type_info = {
diff --git a/target-cris/helper.c b/target-cris/helper.c
index aba7537..44d8916 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -255,16 +255,17 @@ void cris_cpu_do_interrupt(CPUState *cs)
           env->pregs[PR_ERP]);
 }
 
-hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr)
+hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    CRISCPU *cpu = CRIS_CPU(cs);
     uint32_t phy = addr;
     struct cris_mmu_result res;
     int miss;
 
-    miss = cris_mmu_translate(&res, env, addr, 0, 0, 1);
+    miss = cris_mmu_translate(&res, &cpu->env, addr, 0, 0, 1);
     /* If D TLB misses, try I TLB.  */
     if (miss) {
-        miss = cris_mmu_translate(&res, env, addr, 2, 0, 1);
+        miss = cris_mmu_translate(&res, &cpu->env, addr, 2, 0, 1);
     }
 
     if (!miss) {
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7e55e5f..b762d06 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -104,4 +104,6 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
 void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 
+hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index eda2444..6b1205d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2542,12 +2542,13 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
     cc->get_memory_mapping = x86_cpu_get_memory_mapping;
+    cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
     cc->write_elf64_note = x86_cpu_write_elf64_note;
     cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
     cc->write_elf32_note = x86_cpu_write_elf32_note;
     cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
+    cc->vmsd = &vmstate_x86_cpu;
 #endif
-    cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
 }
 
 static const TypeInfo x86_cpu_type_info = {
diff --git a/target-i386/helper.c b/target-i386/helper.c
index d6f43d7..9726def 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -884,8 +884,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr)
+hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     target_ulong pde_addr, pte_addr;
     uint64_t pte;
     hwaddr paddr;
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index e3bb619..5c4810f 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -78,5 +78,6 @@ extern const struct VMStateDescription vmstate_lm32_cpu;
 void lm32_cpu_do_interrupt(CPUState *cpu);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 5a0b809..705dd55 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -87,7 +87,10 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = lm32_cpu_do_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
-    cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_lm32_cpu;
+#endif
 }
 
 static const TypeInfo lm32_cpu_type_info = {
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 615b44e..33cb463 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -37,10 +37,12 @@ int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
     return 0;
 }
 
-hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr)
+hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    LM32CPU *cpu = LM32_CPU(cs);
+
     addr &= TARGET_PAGE_MASK;
-    if (env->flags & LM32_FLAG_IGNORE_MSB) {
+    if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) {
         return addr & 0x7fffffff;
     } else {
         return addr;
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 858bf30..9ec8c35 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -73,5 +73,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 void m68k_cpu_do_interrupt(CPUState *cpu);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 1ac1893..5328fda 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -190,6 +190,9 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_m68k_cpu;
 }
 
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 54fa419..0a94ca7 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -290,7 +290,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
 /* MMU */
 
 /* TODO: This will need fixing once the MMU is implemented.  */
-hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr)
+hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
     return addr;
 }
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index ec2b989..be05858 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -74,5 +74,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 void mb_cpu_do_interrupt(CPUState *cs);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
+hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 5fa6f63..90cc088 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -140,8 +140,11 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = mb_cpu_do_interrupt;
     cc->dump_state = mb_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access);
     cc->set_pc = mb_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = mb_cpu_unassigned_access;
+    cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_mb_cpu;
     dc->props = mb_properties;
 }
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 86aad6a..7a96335 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -265,8 +265,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
     }
 }
 
-hwaddr cpu_get_phys_page_debug(CPUMBState * env, target_ulong addr)
+hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
     target_ulong vaddr, paddr = 0;
     struct microblaze_mmu_lookup lu;
     unsigned int hit;
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 654744a..291b061 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -77,5 +77,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 void mips_cpu_do_interrupt(CPUState *cpu);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index ce39c23..10f6f69 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -98,9 +98,12 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->do_interrupt = mips_cpu_do_interrupt;
     cc->dump_state = mips_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = mips_cpu_unassigned_access;
+    cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
+#endif
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 6983b92..eef985b 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -254,13 +254,16 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
 }
 
 #if !defined(CONFIG_USER_ONLY)
-hwaddr cpu_get_phys_page_debug(CPUMIPSState *env, target_ulong addr)
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    MIPSCPU *cpu = MIPS_CPU(cs);
     hwaddr phys_addr;
     int prot;
 
-    if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
+    if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0,
+                             ACCESS_INT) != 0) {
         return -1;
+    }
     return phys_addr;
 }
 #endif
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 8e32584..42bad13 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -101,7 +101,10 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = moxie_cpu_do_interrupt;
     cc->dump_state = moxie_cpu_dump_state;
     cc->set_pc = moxie_cpu_set_pc;
-    cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_moxie_cpu;
+#endif
 }
 
 static void moxielite_initfn(Object *obj)
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index d5030a4..09037dd 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -118,6 +118,7 @@ int cpu_moxie_exec(CPUMoxieState *s);
 void moxie_cpu_do_interrupt(CPUState *cs);
 void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
+hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 void moxie_translate_init(void);
 int cpu_moxie_signal_handler(int host_signum, void *pinfo,
                              void *puc);
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index ea0788f..150acb5 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -118,11 +118,6 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
     return 1;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
-    return addr;
-}
-
 #else /* !CONFIG_USER_ONLY */
 
 int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
@@ -162,12 +157,14 @@ void moxie_cpu_do_interrupt(CPUState *cs)
     }
 }
 
-hwaddr cpu_get_phys_page_debug(CPUMoxieState *env, target_ulong addr)
+hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    MoxieCPU *cpu = MOXIE_CPU(cs);
     uint32_t phy = addr;
     MoxieMMUResult res;
     int miss;
-    miss = moxie_mmu_translate(&res, env, addr, 0, 0);
+
+    miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
     if (!miss) {
         phy = res.phy;
     }
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index aa79420..2b7a40e 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -152,7 +152,10 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
-    device_class_set_vmsd(dc, &vmstate_openrisc_cpu);
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
+    dc->vmsd = &vmstate_openrisc_cpu;
+#endif
 }
 
 static void cpu_register(const OpenRISCCPUInfo *info)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 82bfd03..5747655 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -349,6 +349,7 @@ int cpu_openrisc_exec(CPUOpenRISCState *s);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
+hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 void openrisc_translate_init(void);
 int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                   target_ulong address,
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index d354e1f..bd004eb 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -219,12 +219,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
 #endif
 
 #ifndef CONFIG_USER_ONLY
-hwaddr cpu_get_phys_page_debug(CPUOpenRISCState *env,
-                                           target_ulong addr)
+hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
     hwaddr phys_addr;
     int prot;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
 
     if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
         return -1;
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 7132599..7216cc4 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -105,5 +105,6 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
 void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 26f513f..afdf4f2 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1317,8 +1317,10 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
     return ret;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
     mmu_ctx_t ctx;
 
     switch (env->mmu_model) {
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 4c091e3..cac55cc 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -74,5 +74,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 6fd9bdd..ea29f9c 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -173,6 +173,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_s390_cpu;
 }
 
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index b425054..b1e3c23 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -417,9 +417,10 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
     return 0;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUS390XState *env,
-                                           target_ulong vaddr)
+hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, uint64_t vaddr)
 {
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
     target_ulong raddr;
     int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
     int old_exc = env->exception_index;
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index c229a9a..6f50a0a 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -86,5 +86,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
 void superh_cpu_do_interrupt(CPUState *cpu);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);
+hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index d535fe8..c9d6590 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -286,6 +286,9 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_sh_cpu;
 }
 
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index cb6a2d2..ee475c0 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -508,12 +508,13 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
     return 0;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUSH4State * env, target_ulong addr)
+hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    SuperHCPU *cpu = SUPERH_CPU(cs);
     target_ulong physical;
     int prot;
 
-    get_physical_address(env, &physical, &prot, addr, 0, 0);
+    get_physical_address(&cpu->env, &physical, &prot, addr, 0, 0);
     return physical;
 }
 
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index 033a5b5..1b39274 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -78,5 +78,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
 void sparc_cpu_do_interrupt(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
+hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 1e3984f..c3e2d3d 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -782,9 +782,12 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
-    cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
     cc->set_pc = sparc_cpu_set_pc;
     cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
+#ifndef CONFIG_USER_ONLY
+    cc->do_unassigned_access = sparc_cpu_unassigned_access;
+    cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
+#endif
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 3983c96..99562fb 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -310,6 +310,7 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
 
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     target_ulong va, va1, va2;
     unsigned int n, m, o;
     hwaddr pde_ptr, pa;
@@ -322,20 +323,20 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
         pde = mmu_probe(env, va, 2);
         if (pde) {
-            pa = cpu_get_phys_page_debug(env, va);
+            pa = cpu_get_phys_page_debug(cs, va);
             (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
                            " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
             for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
                 pde = mmu_probe(env, va1, 1);
                 if (pde) {
-                    pa = cpu_get_phys_page_debug(env, va1);
+                    pa = cpu_get_phys_page_debug(cs, va1);
                     (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
                                    TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
                                    va1, pa, pde);
                     for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
                         pde = mmu_probe(env, va2, 0);
                         if (pde) {
-                            pa = cpu_get_phys_page_debug(env, va2);
+                            pa = cpu_get_phys_page_debug(cs, va2);
                             (*cpu_fprintf)(f, "  VA: " TARGET_FMT_lx ", PA: "
                                            TARGET_FMT_plx " PTE: "
                                            TARGET_FMT_lx "\n",
@@ -833,8 +834,10 @@ hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
 }
 #endif
 
-hwaddr cpu_get_phys_page_debug(CPUSPARCState *env, target_ulong addr)
+hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     hwaddr phys_addr;
     int mmu_idx = cpu_mmu_index(env);
     MemoryRegionSection section;
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index 350d480..c894d55 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -63,5 +63,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
 void uc32_cpu_do_interrupt(CPUState *cpu);
 void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
                          fprintf_function cpu_fprintf, int flags);
+hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 2e99bd3..c5edddb 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -139,6 +139,9 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = uc32_cpu_do_interrupt;
     cc->dump_state = uc32_cpu_dump_state;
     cc->set_pc = uc32_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_uc32_cpu;
 }
 
diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
index eadaeb1..6ebde59 100644
--- a/target-unicore32/softmmu.c
+++ b/target-unicore32/softmmu.c
@@ -261,9 +261,10 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
     return ret;
 }
 
-hwaddr cpu_get_phys_page_debug(CPUUniCore32State *env,
-        target_ulong addr)
+hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
-    cpu_abort(env, "%s not supported yet\n", __func__);
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+
+    cpu_abort(&cpu->env, "%s not supported yet\n", __func__);
     return addr;
 }
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 31e7498..944d3cc 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -83,5 +83,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
 void xtensa_cpu_do_interrupt(CPUState *cpu);
 void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);
+hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
 #endif
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index a388c6f..6556caa 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -108,6 +108,9 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
+#endif
     dc->vmsd = &vmstate_xtensa_cpu;
 }
 
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 6f613c66..a67c849 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -108,17 +108,18 @@ void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
     }
 }
 
-hwaddr cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong addr)
+hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 {
+    XtensaCPU *cpu = XTENSA_CPU(cs);
     uint32_t paddr;
     uint32_t page_size;
     unsigned access;
 
-    if (xtensa_get_physical_addr(env, false, addr, 0, 0,
+    if (xtensa_get_physical_addr(&cpu->env, false, addr, 0, 0,
                 &paddr, &page_size, &access) == 0) {
         return paddr;
     }
-    if (xtensa_get_physical_addr(env, false, addr, 2, 0,
+    if (xtensa_get_physical_addr(&cpu->env, false, addr, 2, 0,
                 &paddr, &page_size, &access) == 0) {
         return paddr;
     }
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
index 5fe0361..d9dd222 100644
--- a/target-xtensa/xtensa-semi.c
+++ b/target-xtensa/xtensa-semi.c
@@ -152,6 +152,7 @@ static uint32_t errno_h2g(int host_errno)
 
 void HELPER(simcall)(CPUXtensaState *env)
 {
+    CPUState *cs = CPU(xtensa_env_get_cpu(env));
     uint32_t *regs = env->regs;
 
     switch (regs[2]) {
@@ -169,8 +170,7 @@ void HELPER(simcall)(CPUXtensaState *env)
             uint32_t len = regs[5];
 
             while (len > 0) {
-                hwaddr paddr =
-                    cpu_get_phys_page_debug(env, vaddr);
+                hwaddr paddr = cpu_get_phys_page_debug(cs, vaddr);
                 uint32_t page_left =
                     TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1));
                 uint32_t io_sz = page_left < len ? page_left : len;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [PATCH RFC qom-cpu 34/41] exec: Change cpu_memory_rw_debug() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
@ 2013-06-29 20:01   ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
                     ` (40 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: jan.kiszka, Andreas Färber, Luiz Capitulino, Paul Brook,
	Peter Maydell, Gleb Natapov, Marcelo Tosatti, Blue Swirl,
	Max Filippov, open list:X86

Propagate X86CPU in kvmvapic for simplicity.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                      |  4 +--
 disas.c                     |  4 +--
 exec.c                      |  6 ++--
 gdbstub.c                   |  2 +-
 hw/i386/kvmvapic.c          | 72 +++++++++++++++++++++++----------------------
 include/exec/cpu-all.h      |  3 +-
 include/exec/softmmu-semi.h | 18 +++++++-----
 monitor.c                   |  2 +-
 target-arm/arm-semi.c       |  2 +-
 target-i386/helper.c        |  8 +++--
 target-i386/kvm.c           | 14 ++++-----
 target-sparc/mmu_helper.c   |  5 ++--
 target-xtensa/xtensa-semi.c | 10 +++----
 13 files changed, 77 insertions(+), 73 deletions(-)

diff --git a/cpus.c b/cpus.c
index 8b99deb..9dbd5ff 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1247,7 +1247,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
 {
     FILE *f;
     uint32_t l;
-    CPUArchState *env;
     CPUState *cpu;
     uint8_t buf[1024];
 
@@ -1261,7 +1260,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
                   "a CPU number");
         return;
     }
-    env = cpu->env_ptr;
 
     f = fopen(filename, "wb");
     if (!f) {
@@ -1273,7 +1271,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
         l = sizeof(buf);
         if (l > size)
             l = size;
-        cpu_memory_rw_debug(env, addr, buf, l, 0);
+        cpu_memory_rw_debug(cpu, addr, buf, l, 0);
         if (fwrite(buf, 1, l, f) != l) {
             error_set(errp, QERR_IO_ERROR);
             goto exit;
diff --git a/disas.c b/disas.c
index e51127e..71007fb 100644
--- a/disas.c
+++ b/disas.c
@@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr,
 {
     CPUDebug *s = container_of(info, CPUDebug, info);
 
-    cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0);
+    cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
     return 0;
 }
 
@@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
     if (monitor_disas_is_physical) {
         cpu_physical_memory_read(memaddr, myaddr, length);
     } else {
-        cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0);
+        cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
     }
     return 0;
 }
diff --git a/exec.c b/exec.c
index 359dc64..f4906cf 100644
--- a/exec.c
+++ b/exec.c
@@ -1847,7 +1847,7 @@ MemoryRegion *get_system_io(void)
 
 /* physical memory access (slow version, mainly for debug) */
 #if defined(CONFIG_USER_ONLY)
-int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write)
 {
     int l, flags;
@@ -2565,7 +2565,7 @@ void stq_be_phys(hwaddr addr, uint64_t val)
 }
 
 /* virtual memory access for debug (includes writing to ROM) */
-int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write)
 {
     int l;
@@ -2574,7 +2574,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 
     while (len > 0) {
         page = addr & TARGET_PAGE_MASK;
-        phys_addr = cpu_get_phys_page_debug(ENV_GET_CPU(env), page);
+        phys_addr = cpu_get_phys_page_debug(cpu, page);
         /* if no physical page mapped, return an error */
         if (phys_addr == -1)
             return -1;
diff --git a/gdbstub.c b/gdbstub.c
index cee9c13..43ecc0d 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -46,7 +46,7 @@
 static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr,
                                          uint8_t *buf, int len, int is_write)
 {
-    return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+    return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write);
 }
 #else
 /* target_memory_rw_debug() defined in cpu.h */
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 76fca34..860dea7 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -188,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)
          modrm_reg(opcode[1]) == instr->modrm_reg);
 }
 
-static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
+static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
                                     target_ulong *pip, TPRAccess access)
 {
+    CPUState *cs = CPU(cpu);
     const TPRInstruction *instr;
     target_ulong ip = *pip;
     uint8_t opcode[2];
@@ -211,7 +212,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
      * RSP, used by the patched instruction, is zero, so the guest gets a
      * double fault and dies.
      */
-    if (env->regs[R_ESP] == 0) {
+    if (cpu->env.regs[R_ESP] == 0) {
         return -1;
     }
 
@@ -226,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
             if (instr->access != access) {
                 continue;
             }
-            if (cpu_memory_rw_debug(env, ip - instr->length, opcode,
+            if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,
                                     sizeof(opcode), 0) < 0) {
                 return -1;
             }
@@ -237,7 +238,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
         }
         return -1;
     } else {
-        if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) {
+        if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {
             return -1;
         }
         for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
@@ -254,7 +255,7 @@ instruction_ok:
      * Grab the virtual TPR address from the instruction
      * and update the cached values.
      */
-    if (cpu_memory_rw_debug(env, ip + instr->addr_offset,
+    if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,
                             (void *)&real_tpr_addr,
                             sizeof(real_tpr_addr), 0) < 0) {
         return -1;
@@ -334,8 +335,9 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
  * cannot be accessed or is considered invalid. This also ensures that we are
  * not patching the wrong guest.
  */
-static int get_kpcr_number(CPUX86State *env)
+static int get_kpcr_number(X86CPU *cpu)
 {
+    CPUX86State *env = &cpu->env;
     struct kpcr {
         uint8_t  fill1[0x1c];
         uint32_t self;
@@ -343,7 +345,7 @@ static int get_kpcr_number(CPUX86State *env)
         uint8_t  number;
     } QEMU_PACKED kpcr;
 
-    if (cpu_memory_rw_debug(env, env->segs[R_FS].base,
+    if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base,
                             (void *)&kpcr, sizeof(kpcr), 0) < 0 ||
         kpcr.self != env->segs[R_FS].base) {
         return -1;
@@ -351,9 +353,9 @@ static int get_kpcr_number(CPUX86State *env)
     return kpcr.number;
 }
 
-static int vapic_enable(VAPICROMState *s, CPUX86State *env)
+static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
 {
-    int cpu_number = get_kpcr_number(env);
+    int cpu_number = get_kpcr_number(cpu);
     hwaddr vapic_paddr;
     static const uint8_t enabled = 1;
 
@@ -364,26 +366,26 @@ static int vapic_enable(VAPICROMState *s, CPUX86State *env)
         (((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
     cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
                            (void *)&enabled, sizeof(enabled), 1);
-    apic_enable_vapic(env->apic_state, vapic_paddr);
+    apic_enable_vapic(cpu->env.apic_state, vapic_paddr);
 
     s->state = VAPIC_ACTIVE;
 
     return 0;
 }
 
-static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte)
+static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
 {
-    cpu_memory_rw_debug(env, addr, &byte, 1, 1);
+    cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
 }
 
-static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
+static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
                        uint32_t target)
 {
     uint32_t offset;
 
     offset = cpu_to_le32(target - ip - 5);
-    patch_byte(env, ip, 0xe8); /* call near */
-    cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
+    patch_byte(cpu, ip, 0xe8); /* call near */
+    cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
 }
 
 static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
@@ -411,32 +413,32 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
 
     pause_all_vcpus();
 
-    cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
+    cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
 
     switch (opcode[0]) {
     case 0x89: /* mov r32 to r/m32 */
-        patch_byte(env, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
-        patch_call(s, env, ip + 1, handlers->set_tpr);
+        patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
+        patch_call(s, cpu, ip + 1, handlers->set_tpr);
         break;
     case 0x8b: /* mov r/m32 to r32 */
-        patch_byte(env, ip, 0x90);
-        patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
+        patch_byte(cpu, ip, 0x90);
+        patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
         break;
     case 0xa1: /* mov abs to eax */
-        patch_call(s, env, ip, handlers->get_tpr[0]);
+        patch_call(s, cpu, ip, handlers->get_tpr[0]);
         break;
     case 0xa3: /* mov eax to abs */
-        patch_call(s, env, ip, handlers->set_tpr_eax);
+        patch_call(s, cpu, ip, handlers->set_tpr_eax);
         break;
     case 0xc7: /* mov imm32, r/m32 (c7/0) */
-        patch_byte(env, ip, 0x68);  /* push imm32 */
-        cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0);
-        cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1);
-        patch_call(s, env, ip + 5, handlers->set_tpr);
+        patch_byte(cpu, ip, 0x68);  /* push imm32 */
+        cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
+        cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
+        patch_call(s, cpu, ip + 5, handlers->set_tpr);
         break;
     case 0xff: /* push r/m32 */
-        patch_byte(env, ip, 0x50); /* push eax */
-        patch_call(s, env, ip + 1, handlers->get_tpr_stack);
+        patch_byte(cpu, ip, 0x50); /* push eax */
+        patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
         break;
     default:
         abort();
@@ -460,16 +462,16 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
 
     cpu_synchronize_state(cs);
 
-    if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
+    if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) {
         if (s->state == VAPIC_ACTIVE) {
-            vapic_enable(s, env);
+            vapic_enable(s, cpu);
         }
         return;
     }
     if (update_rom_mapping(s, env, ip) < 0) {
         return;
     }
-    if (vapic_enable(s, env) < 0) {
+    if (vapic_enable(s, cpu) < 0) {
         return;
     }
     patch_instruction(s, cpu, ip);
@@ -668,8 +670,8 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
              * accurate.
              */
             pause_all_vcpus();
-            patch_byte(env, env->eip - 2, 0x66);
-            patch_byte(env, env->eip - 1, 0x90);
+            patch_byte(cpu, env->eip - 2, 0x66);
+            patch_byte(cpu, env->eip - 1, 0x90);
             resume_all_vcpus();
         }
 
@@ -682,7 +684,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
         if (find_real_tpr_addr(s, env) < 0) {
             break;
         }
-        vapic_enable(s, env);
+        vapic_enable(s, cpu);
         break;
     default:
     case 4:
@@ -724,7 +726,7 @@ static void do_vapic_enable(void *data)
     VAPICROMState *s = data;
     X86CPU *cpu = X86_CPU(first_cpu);
 
-    vapic_enable(s, &cpu->env);
+    vapic_enable(s, cpu);
 }
 
 static int vapic_post_load(void *opaque, int version_id)
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 16eeb7a..928e93a 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -22,6 +22,7 @@
 #include "qemu-common.h"
 #include "exec/cpu-common.h"
 #include "qemu/thread.h"
+#include "qom/cpu.h"
 
 /* some important defines:
  *
@@ -484,7 +485,7 @@ void qemu_mutex_lock_ramlist(void);
 void qemu_mutex_unlock_ramlist(void);
 #endif /* !CONFIG_USER_ONLY */
 
-int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
 #endif /* CPU_ALL_H */
diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h
index 93798b9..8401f7d 100644
--- a/include/exec/softmmu-semi.h
+++ b/include/exec/softmmu-semi.h
@@ -13,14 +13,14 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
 {
     uint32_t val;
 
-    cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
+    cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
     return tswap32(val);
 }
 static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
 {
     uint8_t val;
 
-    cpu_memory_rw_debug(env, addr, &val, 1, 0);
+    cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, 0);
     return val;
 }
 
@@ -31,7 +31,7 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
 static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
 {
     val = tswap32(val);
-    cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
+    cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
 }
 #define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
 #define put_user_ual(arg, p) put_user_u32(arg, p)
@@ -42,8 +42,9 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
     uint8_t *p;
     /* TODO: Make this something that isn't fixed size.  */
     p = malloc(len);
-    if (p && copy)
-        cpu_memory_rw_debug(env, addr, p, len, 0);
+    if (p && copy) {
+        cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0);
+    }
     return p;
 }
 #define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
@@ -58,7 +59,7 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
         return NULL;
     }
     do {
-        cpu_memory_rw_debug(env, addr, &c, 1, 0);
+        cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0);
         addr++;
         *(p++) = c;
     } while (c);
@@ -68,8 +69,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
 static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
                                 target_ulong len)
 {
-    if (len)
-        cpu_memory_rw_debug(env, addr, p, len, 1);
+    if (len) {
+        cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1);
+    }
     free(p);
 }
 #define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
diff --git a/monitor.c b/monitor.c
index 2ba7876..c0d0341 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1156,7 +1156,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
             cpu_physical_memory_read(addr, buf, l);
         } else {
             env = mon_get_cpu();
-            if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
+            if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) {
                 monitor_printf(mon, " Cannot access memory\n");
                 break;
             }
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index 4ecea65..ee469c4 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -161,7 +161,7 @@ static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
     /* The size is always stored in big-endian order, extract
        the value. We assume the size always fit in 32 bits.  */
     uint32_t size;
-    cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
+    cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
     env->regs[0] = be32_to_cpu(size);
 #ifdef CONFIG_USER_ONLY
     ((TaskState *)env->opaque)->swi_errno = err;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 9726def..bf3d61a 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -363,7 +363,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
         cpu_fprintf(f, "Code=");
         for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
-            if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
+            if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
                 snprintf(codestr, sizeof(codestr), "%02x", code);
             } else {
                 snprintf(codestr, sizeof(codestr), "??");
@@ -1260,6 +1260,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
                             target_ulong *base, unsigned int *limit,
                             unsigned int *flags)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     SegmentCache *dt;
     target_ulong ptr;
     uint32_t e1, e2;
@@ -1272,8 +1274,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
     index = selector & ~7;
     ptr = dt->base + index;
     if ((index + 7) > dt->limit
-        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
-        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
+        || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
+        || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
         return 0;
 
     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 793cf16..98829cf 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1935,25 +1935,23 @@ static int kvm_handle_tpr_access(X86CPU *cpu)
     return 1;
 }
 
-int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
 {
-    CPUX86State *env = &X86_CPU(cpu)->env;
     static const uint8_t int3 = 0xcc;
 
-    if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
-        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&int3, 1, 1)) {
+    if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
+        cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) {
         return -EINVAL;
     }
     return 0;
 }
 
-int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
 {
-    CPUX86State *env = &X86_CPU(cpu)->env;
     uint8_t int3;
 
-    if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
-        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
+    if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
+        cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
         return -EINVAL;
     }
     return 0;
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 99562fb..bf89236 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -356,6 +356,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
 int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
                            uint8_t *buf, int len, int is_write)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     int i;
     int len1;
     int cwp = env->cwp;
@@ -390,7 +391,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
             /* Handle access before this window.  */
             if (addr < fp) {
                 len1 = fp - addr;
-                if (cpu_memory_rw_debug(env, addr, buf, len1, is_write) != 0) {
+                if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) {
                     return -1;
                 }
                 addr += len1;
@@ -426,7 +427,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
             }
         }
     }
-    return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+    return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
 }
 
 #else /* !TARGET_SPARC64 */
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
index d9dd222..424253d 100644
--- a/target-xtensa/xtensa-semi.c
+++ b/target-xtensa/xtensa-semi.c
@@ -204,8 +204,8 @@ void HELPER(simcall)(CPUXtensaState *env)
             int i;
 
             for (i = 0; i < ARRAY_SIZE(name); ++i) {
-                rc = cpu_memory_rw_debug(
-                        env, regs[3] + i, (uint8_t *)name + i, 1, 0);
+                rc = cpu_memory_rw_debug(cs, regs[3] + i,
+                                         (uint8_t *)name + i, 1, 0);
                 if (rc != 0 || name[i] == 0) {
                     break;
                 }
@@ -249,7 +249,7 @@ void HELPER(simcall)(CPUXtensaState *env)
             FD_SET(fd, &fdset);
 
             if (target_tv) {
-                cpu_memory_rw_debug(env, target_tv,
+                cpu_memory_rw_debug(cs, target_tv,
                         (uint8_t *)target_tvv, sizeof(target_tvv), 0);
                 tv.tv_sec = (int32_t)tswap32(target_tvv[0]);
                 tv.tv_usec = (int32_t)tswap32(target_tvv[1]);
@@ -284,8 +284,8 @@ void HELPER(simcall)(CPUXtensaState *env)
             };
 
             argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text));
-            cpu_memory_rw_debug(
-                    env, regs[3], (uint8_t *)&argv, sizeof(argv), 1);
+            cpu_memory_rw_debug(cs,
+                                regs[3], (uint8_t *)&argv, sizeof(argv), 1);
         }
         break;
 
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 34/41] exec: Change cpu_memory_rw_debug() argument to CPUState
@ 2013-06-29 20:01   ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:X86, Gleb Natapov, Marcelo Tosatti,
	Luiz Capitulino, Blue Swirl, Max Filippov, jan.kiszka,
	Paul Brook, Andreas Färber

Propagate X86CPU in kvmvapic for simplicity.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                      |  4 +--
 disas.c                     |  4 +--
 exec.c                      |  6 ++--
 gdbstub.c                   |  2 +-
 hw/i386/kvmvapic.c          | 72 +++++++++++++++++++++++----------------------
 include/exec/cpu-all.h      |  3 +-
 include/exec/softmmu-semi.h | 18 +++++++-----
 monitor.c                   |  2 +-
 target-arm/arm-semi.c       |  2 +-
 target-i386/helper.c        |  8 +++--
 target-i386/kvm.c           | 14 ++++-----
 target-sparc/mmu_helper.c   |  5 ++--
 target-xtensa/xtensa-semi.c | 10 +++----
 13 files changed, 77 insertions(+), 73 deletions(-)

diff --git a/cpus.c b/cpus.c
index 8b99deb..9dbd5ff 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1247,7 +1247,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
 {
     FILE *f;
     uint32_t l;
-    CPUArchState *env;
     CPUState *cpu;
     uint8_t buf[1024];
 
@@ -1261,7 +1260,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
                   "a CPU number");
         return;
     }
-    env = cpu->env_ptr;
 
     f = fopen(filename, "wb");
     if (!f) {
@@ -1273,7 +1271,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
         l = sizeof(buf);
         if (l > size)
             l = size;
-        cpu_memory_rw_debug(env, addr, buf, l, 0);
+        cpu_memory_rw_debug(cpu, addr, buf, l, 0);
         if (fwrite(buf, 1, l, f) != l) {
             error_set(errp, QERR_IO_ERROR);
             goto exit;
diff --git a/disas.c b/disas.c
index e51127e..71007fb 100644
--- a/disas.c
+++ b/disas.c
@@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr,
 {
     CPUDebug *s = container_of(info, CPUDebug, info);
 
-    cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0);
+    cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
     return 0;
 }
 
@@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
     if (monitor_disas_is_physical) {
         cpu_physical_memory_read(memaddr, myaddr, length);
     } else {
-        cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0);
+        cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
     }
     return 0;
 }
diff --git a/exec.c b/exec.c
index 359dc64..f4906cf 100644
--- a/exec.c
+++ b/exec.c
@@ -1847,7 +1847,7 @@ MemoryRegion *get_system_io(void)
 
 /* physical memory access (slow version, mainly for debug) */
 #if defined(CONFIG_USER_ONLY)
-int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write)
 {
     int l, flags;
@@ -2565,7 +2565,7 @@ void stq_be_phys(hwaddr addr, uint64_t val)
 }
 
 /* virtual memory access for debug (includes writing to ROM) */
-int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write)
 {
     int l;
@@ -2574,7 +2574,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 
     while (len > 0) {
         page = addr & TARGET_PAGE_MASK;
-        phys_addr = cpu_get_phys_page_debug(ENV_GET_CPU(env), page);
+        phys_addr = cpu_get_phys_page_debug(cpu, page);
         /* if no physical page mapped, return an error */
         if (phys_addr == -1)
             return -1;
diff --git a/gdbstub.c b/gdbstub.c
index cee9c13..43ecc0d 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -46,7 +46,7 @@
 static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr,
                                          uint8_t *buf, int len, int is_write)
 {
-    return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+    return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write);
 }
 #else
 /* target_memory_rw_debug() defined in cpu.h */
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 76fca34..860dea7 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -188,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)
          modrm_reg(opcode[1]) == instr->modrm_reg);
 }
 
-static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
+static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
                                     target_ulong *pip, TPRAccess access)
 {
+    CPUState *cs = CPU(cpu);
     const TPRInstruction *instr;
     target_ulong ip = *pip;
     uint8_t opcode[2];
@@ -211,7 +212,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
      * RSP, used by the patched instruction, is zero, so the guest gets a
      * double fault and dies.
      */
-    if (env->regs[R_ESP] == 0) {
+    if (cpu->env.regs[R_ESP] == 0) {
         return -1;
     }
 
@@ -226,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
             if (instr->access != access) {
                 continue;
             }
-            if (cpu_memory_rw_debug(env, ip - instr->length, opcode,
+            if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,
                                     sizeof(opcode), 0) < 0) {
                 return -1;
             }
@@ -237,7 +238,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
         }
         return -1;
     } else {
-        if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) {
+        if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {
             return -1;
         }
         for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
@@ -254,7 +255,7 @@ instruction_ok:
      * Grab the virtual TPR address from the instruction
      * and update the cached values.
      */
-    if (cpu_memory_rw_debug(env, ip + instr->addr_offset,
+    if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,
                             (void *)&real_tpr_addr,
                             sizeof(real_tpr_addr), 0) < 0) {
         return -1;
@@ -334,8 +335,9 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
  * cannot be accessed or is considered invalid. This also ensures that we are
  * not patching the wrong guest.
  */
-static int get_kpcr_number(CPUX86State *env)
+static int get_kpcr_number(X86CPU *cpu)
 {
+    CPUX86State *env = &cpu->env;
     struct kpcr {
         uint8_t  fill1[0x1c];
         uint32_t self;
@@ -343,7 +345,7 @@ static int get_kpcr_number(CPUX86State *env)
         uint8_t  number;
     } QEMU_PACKED kpcr;
 
-    if (cpu_memory_rw_debug(env, env->segs[R_FS].base,
+    if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base,
                             (void *)&kpcr, sizeof(kpcr), 0) < 0 ||
         kpcr.self != env->segs[R_FS].base) {
         return -1;
@@ -351,9 +353,9 @@ static int get_kpcr_number(CPUX86State *env)
     return kpcr.number;
 }
 
-static int vapic_enable(VAPICROMState *s, CPUX86State *env)
+static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
 {
-    int cpu_number = get_kpcr_number(env);
+    int cpu_number = get_kpcr_number(cpu);
     hwaddr vapic_paddr;
     static const uint8_t enabled = 1;
 
@@ -364,26 +366,26 @@ static int vapic_enable(VAPICROMState *s, CPUX86State *env)
         (((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
     cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
                            (void *)&enabled, sizeof(enabled), 1);
-    apic_enable_vapic(env->apic_state, vapic_paddr);
+    apic_enable_vapic(cpu->env.apic_state, vapic_paddr);
 
     s->state = VAPIC_ACTIVE;
 
     return 0;
 }
 
-static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte)
+static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
 {
-    cpu_memory_rw_debug(env, addr, &byte, 1, 1);
+    cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
 }
 
-static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
+static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
                        uint32_t target)
 {
     uint32_t offset;
 
     offset = cpu_to_le32(target - ip - 5);
-    patch_byte(env, ip, 0xe8); /* call near */
-    cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
+    patch_byte(cpu, ip, 0xe8); /* call near */
+    cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
 }
 
 static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
@@ -411,32 +413,32 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
 
     pause_all_vcpus();
 
-    cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
+    cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
 
     switch (opcode[0]) {
     case 0x89: /* mov r32 to r/m32 */
-        patch_byte(env, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
-        patch_call(s, env, ip + 1, handlers->set_tpr);
+        patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
+        patch_call(s, cpu, ip + 1, handlers->set_tpr);
         break;
     case 0x8b: /* mov r/m32 to r32 */
-        patch_byte(env, ip, 0x90);
-        patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
+        patch_byte(cpu, ip, 0x90);
+        patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
         break;
     case 0xa1: /* mov abs to eax */
-        patch_call(s, env, ip, handlers->get_tpr[0]);
+        patch_call(s, cpu, ip, handlers->get_tpr[0]);
         break;
     case 0xa3: /* mov eax to abs */
-        patch_call(s, env, ip, handlers->set_tpr_eax);
+        patch_call(s, cpu, ip, handlers->set_tpr_eax);
         break;
     case 0xc7: /* mov imm32, r/m32 (c7/0) */
-        patch_byte(env, ip, 0x68);  /* push imm32 */
-        cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0);
-        cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1);
-        patch_call(s, env, ip + 5, handlers->set_tpr);
+        patch_byte(cpu, ip, 0x68);  /* push imm32 */
+        cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
+        cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
+        patch_call(s, cpu, ip + 5, handlers->set_tpr);
         break;
     case 0xff: /* push r/m32 */
-        patch_byte(env, ip, 0x50); /* push eax */
-        patch_call(s, env, ip + 1, handlers->get_tpr_stack);
+        patch_byte(cpu, ip, 0x50); /* push eax */
+        patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
         break;
     default:
         abort();
@@ -460,16 +462,16 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
 
     cpu_synchronize_state(cs);
 
-    if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
+    if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) {
         if (s->state == VAPIC_ACTIVE) {
-            vapic_enable(s, env);
+            vapic_enable(s, cpu);
         }
         return;
     }
     if (update_rom_mapping(s, env, ip) < 0) {
         return;
     }
-    if (vapic_enable(s, env) < 0) {
+    if (vapic_enable(s, cpu) < 0) {
         return;
     }
     patch_instruction(s, cpu, ip);
@@ -668,8 +670,8 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
              * accurate.
              */
             pause_all_vcpus();
-            patch_byte(env, env->eip - 2, 0x66);
-            patch_byte(env, env->eip - 1, 0x90);
+            patch_byte(cpu, env->eip - 2, 0x66);
+            patch_byte(cpu, env->eip - 1, 0x90);
             resume_all_vcpus();
         }
 
@@ -682,7 +684,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
         if (find_real_tpr_addr(s, env) < 0) {
             break;
         }
-        vapic_enable(s, env);
+        vapic_enable(s, cpu);
         break;
     default:
     case 4:
@@ -724,7 +726,7 @@ static void do_vapic_enable(void *data)
     VAPICROMState *s = data;
     X86CPU *cpu = X86_CPU(first_cpu);
 
-    vapic_enable(s, &cpu->env);
+    vapic_enable(s, cpu);
 }
 
 static int vapic_post_load(void *opaque, int version_id)
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 16eeb7a..928e93a 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -22,6 +22,7 @@
 #include "qemu-common.h"
 #include "exec/cpu-common.h"
 #include "qemu/thread.h"
+#include "qom/cpu.h"
 
 /* some important defines:
  *
@@ -484,7 +485,7 @@ void qemu_mutex_lock_ramlist(void);
 void qemu_mutex_unlock_ramlist(void);
 #endif /* !CONFIG_USER_ONLY */
 
-int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
+int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
 #endif /* CPU_ALL_H */
diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h
index 93798b9..8401f7d 100644
--- a/include/exec/softmmu-semi.h
+++ b/include/exec/softmmu-semi.h
@@ -13,14 +13,14 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
 {
     uint32_t val;
 
-    cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
+    cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
     return tswap32(val);
 }
 static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
 {
     uint8_t val;
 
-    cpu_memory_rw_debug(env, addr, &val, 1, 0);
+    cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, 0);
     return val;
 }
 
@@ -31,7 +31,7 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
 static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
 {
     val = tswap32(val);
-    cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
+    cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
 }
 #define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
 #define put_user_ual(arg, p) put_user_u32(arg, p)
@@ -42,8 +42,9 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
     uint8_t *p;
     /* TODO: Make this something that isn't fixed size.  */
     p = malloc(len);
-    if (p && copy)
-        cpu_memory_rw_debug(env, addr, p, len, 0);
+    if (p && copy) {
+        cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0);
+    }
     return p;
 }
 #define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
@@ -58,7 +59,7 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
         return NULL;
     }
     do {
-        cpu_memory_rw_debug(env, addr, &c, 1, 0);
+        cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0);
         addr++;
         *(p++) = c;
     } while (c);
@@ -68,8 +69,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
 static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
                                 target_ulong len)
 {
-    if (len)
-        cpu_memory_rw_debug(env, addr, p, len, 1);
+    if (len) {
+        cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1);
+    }
     free(p);
 }
 #define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
diff --git a/monitor.c b/monitor.c
index 2ba7876..c0d0341 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1156,7 +1156,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
             cpu_physical_memory_read(addr, buf, l);
         } else {
             env = mon_get_cpu();
-            if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
+            if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) {
                 monitor_printf(mon, " Cannot access memory\n");
                 break;
             }
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index 4ecea65..ee469c4 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -161,7 +161,7 @@ static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
     /* The size is always stored in big-endian order, extract
        the value. We assume the size always fit in 32 bits.  */
     uint32_t size;
-    cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
+    cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
     env->regs[0] = be32_to_cpu(size);
 #ifdef CONFIG_USER_ONLY
     ((TaskState *)env->opaque)->swi_errno = err;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 9726def..bf3d61a 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -363,7 +363,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
         cpu_fprintf(f, "Code=");
         for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
-            if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
+            if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
                 snprintf(codestr, sizeof(codestr), "%02x", code);
             } else {
                 snprintf(codestr, sizeof(codestr), "??");
@@ -1260,6 +1260,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
                             target_ulong *base, unsigned int *limit,
                             unsigned int *flags)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     SegmentCache *dt;
     target_ulong ptr;
     uint32_t e1, e2;
@@ -1272,8 +1274,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
     index = selector & ~7;
     ptr = dt->base + index;
     if ((index + 7) > dt->limit
-        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
-        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
+        || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
+        || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
         return 0;
 
     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 793cf16..98829cf 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1935,25 +1935,23 @@ static int kvm_handle_tpr_access(X86CPU *cpu)
     return 1;
 }
 
-int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
 {
-    CPUX86State *env = &X86_CPU(cpu)->env;
     static const uint8_t int3 = 0xcc;
 
-    if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
-        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&int3, 1, 1)) {
+    if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
+        cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) {
         return -EINVAL;
     }
     return 0;
 }
 
-int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
 {
-    CPUX86State *env = &X86_CPU(cpu)->env;
     uint8_t int3;
 
-    if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
-        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
+    if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
+        cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
         return -EINVAL;
     }
     return 0;
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 99562fb..bf89236 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -356,6 +356,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
 int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
                            uint8_t *buf, int len, int is_write)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     int i;
     int len1;
     int cwp = env->cwp;
@@ -390,7 +391,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
             /* Handle access before this window.  */
             if (addr < fp) {
                 len1 = fp - addr;
-                if (cpu_memory_rw_debug(env, addr, buf, len1, is_write) != 0) {
+                if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) {
                     return -1;
                 }
                 addr += len1;
@@ -426,7 +427,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
             }
         }
     }
-    return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+    return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
 }
 
 #else /* !TARGET_SPARC64 */
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
index d9dd222..424253d 100644
--- a/target-xtensa/xtensa-semi.c
+++ b/target-xtensa/xtensa-semi.c
@@ -204,8 +204,8 @@ void HELPER(simcall)(CPUXtensaState *env)
             int i;
 
             for (i = 0; i < ARRAY_SIZE(name); ++i) {
-                rc = cpu_memory_rw_debug(
-                        env, regs[3] + i, (uint8_t *)name + i, 1, 0);
+                rc = cpu_memory_rw_debug(cs, regs[3] + i,
+                                         (uint8_t *)name + i, 1, 0);
                 if (rc != 0 || name[i] == 0) {
                     break;
                 }
@@ -249,7 +249,7 @@ void HELPER(simcall)(CPUXtensaState *env)
             FD_SET(fd, &fdset);
 
             if (target_tv) {
-                cpu_memory_rw_debug(env, target_tv,
+                cpu_memory_rw_debug(cs, target_tv,
                         (uint8_t *)target_tvv, sizeof(target_tvv), 0);
                 tv.tv_sec = (int32_t)tswap32(target_tvv[0]);
                 tv.tv_usec = (int32_t)tswap32(target_tvv[1]);
@@ -284,8 +284,8 @@ void HELPER(simcall)(CPUXtensaState *env)
             };
 
             argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text));
-            cpu_memory_rw_debug(
-                    env, regs[3], (uint8_t *)&argv, sizeof(argv), 1);
+            cpu_memory_rw_debug(cs,
+                                regs[3], (uint8_t *)&argv, sizeof(argv), 1);
         }
         break;
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 35/41] cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (33 preceding siblings ...)
  2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 36/41] gdbstub: Change GDBState::g_cpu to CPUState Andreas Färber
                   ` (6 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, jan.kiszka, Andreas Färber

Make inline target_memory_rw_debug() always available and change its
argument to CPUState. Let it check if CPUClass::memory_rw_debug provides
a specialized callback and fall back to cpu_memory_rw_debug() otherwise.

The only overriding implementation is for 32-bit sparc.

This prepares for changing GDBState::g_cpu to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c                 | 21 ++++++++++++---------
 include/qom/cpu.h         |  2 ++
 target-sparc/cpu.c        |  3 +++
 target-sparc/cpu.h        |  5 ++---
 target-sparc/mmu_helper.c |  8 +++++---
 5 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 43ecc0d..fa44550 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -42,15 +42,16 @@
 #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,
-                                         uint8_t *buf, int len, int is_write)
+static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
+                                         uint8_t *buf, int len, bool is_write)
 {
-    return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->memory_rw_debug) {
+        return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
+    }
+    return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
 }
-#else
-/* target_memory_rw_debug() defined in cpu.h */
-#endif
 
 enum {
     GDB_SIGNAL_0 = 0,
@@ -2240,7 +2241,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (*p == ',')
             p++;
         len = strtoull(p, NULL, 16);
-        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
+        if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len,
+                                   false) != 0) {
             put_packet (s, "E14");
         } else {
             memtohex(buf, mem_buf, len);
@@ -2255,7 +2257,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (*p == ':')
             p++;
         hextomem(mem_buf, p, len);
-        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) {
+        if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len,
+                                   true) != 0) {
             put_packet(s, "E14");
         } else {
             put_packet(s, "OK");
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 9717650..820dca4 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -77,6 +77,8 @@ typedef struct CPUClass {
     int reset_dump_flags;
     void (*do_interrupt)(CPUState *cpu);
     CPUUnassignedAccess do_unassigned_access;
+    int (*memory_rw_debug)(CPUState *cpu, uint64_t addr,
+                           uint8_t *buf, int len, bool is_write);
     void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
     void (*dump_statistics)(CPUState *cpu, FILE *f,
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index c3e2d3d..bd9d216 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -782,6 +782,9 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
+#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
+    cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
+#endif
     cc->set_pc = sparc_cpu_set_pc;
     cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
 #ifndef CONFIG_USER_ONLY
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 0f35a22..b043772 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -526,9 +526,8 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
 
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
-int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
-                           uint8_t *buf, int len, int is_write);
-#define TARGET_CPU_MEMORY_RW_DEBUG
+int sparc_cpu_memory_rw_debug(CPUState *cpu, uint64_t addr,
+                              uint8_t *buf, int len, bool is_write);
 #endif
 
 
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index bf89236..66ed1ba 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -353,10 +353,12 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
  * reads (and only reads) in stack frames as if windows were flushed. We assume
  * that the sparc ABI is followed.
  */
-int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
-                           uint8_t *buf, int len, int is_write)
+int sparc_cpu_memory_rw_debug(CPUState *cs, uint64_t address,
+                              uint8_t *buf, int len, bool is_write)
 {
-    CPUState *cs = CPU(sparc_env_get_cpu(env));
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
+    target_ulong addr = address;
     int i;
     int len1;
     int cwp = env->cwp;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 36/41] gdbstub: Change GDBState::g_cpu to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (34 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 35/41] cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug() Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 37/41] cpu: Move gdb_regs field from CPU_COMMON " Andreas Färber
                   ` (5 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Use CPUState::env_ptr for Xtensa.

This removes the last user of CPUArchState from gdb_set_stop_cpu().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index fa44550..7be2342 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -289,7 +289,7 @@ enum RSState {
 };
 typedef struct GDBState {
     CPUState *c_cpu; /* current CPU for step/continue ops */
-    CPUArchState *g_cpu; /* current CPU for other ops */
+    CPUState *g_cpu; /* current CPU for other ops */
     CPUState *query_cpu; /* for q{f|s}ThreadInfo */
     enum RSState state; /* parsing state */
     char line_buf[MAX_PACKET_LENGTH];
@@ -2207,30 +2207,28 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
         break;
     case 'g':
-        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
+        cpu_synchronize_state(s->g_cpu);
 #ifdef TARGET_XTENSA
-        env = s->g_cpu;
+        env = s->g_cpu->env_ptr;
 #endif
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
-            reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu),
-                                         mem_buf + len, addr);
+            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
             len += reg_size;
         }
         memtohex(buf, mem_buf, len);
         put_packet(s, buf);
         break;
     case 'G':
-        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
+        cpu_synchronize_state(s->g_cpu);
 #ifdef TARGET_XTENSA
-        env = s->g_cpu;
+        env = s->g_cpu->env_ptr;
 #endif
         registers = mem_buf;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
         for (addr = 0; addr < num_g_regs && len > 0; addr++) {
-            reg_size = gdb_write_register(ENV_GET_CPU(s->g_cpu), registers,
-                                          addr);
+            reg_size = gdb_write_register(s->g_cpu, registers, addr);
             len -= reg_size;
             registers += reg_size;
         }
@@ -2241,8 +2239,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (*p == ',')
             p++;
         len = strtoull(p, NULL, 16);
-        if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len,
-                                   false) != 0) {
+        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
             put_packet (s, "E14");
         } else {
             memtohex(buf, mem_buf, len);
@@ -2257,7 +2254,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (*p == ':')
             p++;
         hextomem(mem_buf, p, len);
-        if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len,
+        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
                                    true) != 0) {
             put_packet(s, "E14");
         } else {
@@ -2271,7 +2268,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (!gdb_has_xml)
             goto unknown_command;
         addr = strtoull(p, (char **)&p, 16);
-        reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr);
+        reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
         if (reg_size) {
             memtohex(buf, mem_buf, reg_size);
             put_packet(s, buf);
@@ -2287,7 +2284,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             p++;
         reg_size = strlen(p) / 2;
         hextomem(mem_buf, p, reg_size);
-        gdb_write_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr);
+        gdb_write_register(s->g_cpu, mem_buf, addr);
         put_packet(s, "OK");
         break;
     case 'Z':
@@ -2328,7 +2325,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "OK");
             break;
         case 'g':
-            s->g_cpu = cpu->env_ptr;
+            s->g_cpu = cpu;
             put_packet(s, "OK");
             break;
         default:
@@ -2494,10 +2491,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 
 void gdb_set_stop_cpu(CPUState *cpu)
 {
-    CPUArchState *env = cpu->env_ptr;
-
     gdbserver_state->c_cpu = cpu;
-    gdbserver_state->g_cpu = env;
+    gdbserver_state->g_cpu = cpu;
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -2853,7 +2848,7 @@ static void gdb_accept(void)
 
     s = g_malloc0(sizeof(GDBState));
     s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu;
     s->fd = fd;
     gdb_has_xml = 0;
 
@@ -3038,7 +3033,7 @@ int gdbserver_start(const char *device)
         memset(s, 0, sizeof(GDBState));
     }
     s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu;
     s->chr = chr;
     s->state = chr ? RS_IDLE : RS_INACTIVE;
     s->mon_chr = mon_chr;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 37/41] cpu: Move gdb_regs field from CPU_COMMON to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (35 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 36/41] gdbstub: Change GDBState::g_cpu to CPUState Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 38/41] gdbstub: Change gdb_register_coprocessor() argument " Andreas Färber
                   ` (4 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, Andreas Färber

Prepares for changing gdb_register_coprocessor() argument to CPUState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c               | 11 ++++++-----
 include/exec/cpu-defs.h |  2 --
 include/qom/cpu.h       |  1 +
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 7be2342..d862cca 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1840,7 +1840,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
         /* Generate the XML description for this CPU.  */
         if (!target_xml[0]) {
             GDBRegisterState *r;
-            CPUArchState *env = first_cpu->env_ptr;
+            CPUState *cpu = first_cpu;
 
             snprintf(target_xml, sizeof(target_xml),
                      "<?xml version=\"1.0\"?>"
@@ -1849,7 +1849,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
                      "<xi:include href=\"%s\"/>",
                      GDB_CORE_XML);
 
-            for (r = env->gdb_regs; r; r = r->next) {
+            for (r = cpu->gdb_regs; r; r = r->next) {
                 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
                 pstrcat(target_xml, sizeof(target_xml), r->xml);
                 pstrcat(target_xml, sizeof(target_xml), "\"/>");
@@ -1875,7 +1875,7 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     if (reg < NUM_CORE_REGS)
         return cpu_gdb_read_register(env, mem_buf, reg);
 
-    for (r = env->gdb_regs; r; r = r->next) {
+    for (r = cpu->gdb_regs; r; r = r->next) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
             return r->get_reg(env, mem_buf, reg - r->base_reg);
         }
@@ -1891,7 +1891,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     if (reg < NUM_CORE_REGS)
         return cpu_gdb_write_register(env, mem_buf, reg);
 
-    for (r = env->gdb_regs; r; r = r->next) {
+    for (r = cpu->gdb_regs; r; r = r->next) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
             return r->set_reg(env, mem_buf, reg - r->base_reg);
         }
@@ -1910,11 +1910,12 @@ void gdb_register_coprocessor(CPUArchState * env,
                              gdb_reg_cb get_reg, gdb_reg_cb set_reg,
                              int num_regs, const char *xml, int g_pos)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     GDBRegisterState *s;
     GDBRegisterState **p;
     static int last_reg = NUM_CORE_REGS;
 
-    p = &env->gdb_regs;
+    p = &cpu->gdb_regs;
     while (*p) {
         /* Check for duplicates.  */
         if (strcmp((*p)->xml, xml) == 0)
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 12b1ca7..b5b93db 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -174,8 +174,6 @@ typedef struct CPUWatchpoint {
     QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;            \
     CPUWatchpoint *watchpoint_hit;                                      \
                                                                         \
-    struct GDBRegisterState *gdb_regs;                                  \
-                                                                        \
     /* Core interrupt code */                                           \
     sigjmp_buf jmp_env;                                                 \
     int exception_index;                                                \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 820dca4..78fbdac 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -156,6 +156,7 @@ struct CPUState {
 
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
+    struct GDBRegisterState *gdb_regs;
     CPUState *next_cpu;
 
     int kvm_fd;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 38/41] gdbstub: Change gdb_register_coprocessor() argument to CPUState
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (36 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 37/41] cpu: Move gdb_regs field from CPU_COMMON " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses Andreas Färber
                   ` (3 subsequent siblings)
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexander Graf, open list:PowerPC, Paul Brook,
	jan.kiszka, Andreas Färber

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c                   |  7 +++----
 include/exec/gdbstub.h      |  2 +-
 target-arm/helper.c         |  7 ++++---
 target-m68k/helper.c        |  3 ++-
 target-ppc/translate_init.c | 15 ++++++++-------
 5 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index d862cca..4ebe9e0 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1906,11 +1906,10 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
    gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
  */
 
-void gdb_register_coprocessor(CPUArchState * env,
-                             gdb_reg_cb get_reg, gdb_reg_cb set_reg,
-                             int num_regs, const char *xml, int g_pos)
+void gdb_register_coprocessor(CPUState *cpu,
+                              gdb_reg_cb get_reg, gdb_reg_cb set_reg,
+                              int num_regs, const char *xml, int g_pos)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     GDBRegisterState *s;
     GDBRegisterState **p;
     static int last_reg = NUM_CORE_REGS;
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 0f1ad9a..1bd00ae 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -26,7 +26,7 @@ void gdbserver_fork(CPUArchState *);
 #endif
 /* Get or set a register.  Returns the size of the register.  */
 typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
-void gdb_register_coprocessor(CPUArchState *env,
+void gdb_register_coprocessor(CPUState *cpu,
                               gdb_reg_cb get_reg, gdb_reg_cb set_reg,
                               int num_regs, const char *xml, int g_pos);
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index da4d4a6..5045934 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1502,16 +1502,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
 
 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
 
     if (arm_feature(env, ARM_FEATURE_NEON)) {
-        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
+        gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
                                  51, "arm-neon.xml", 0);
     } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
-        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
+        gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
                                  35, "arm-vfp3.xml", 0);
     } else if (arm_feature(env, ARM_FEATURE_VFP)) {
-        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
+        gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
                                  19, "arm-vfp.xml", 0);
     }
 }
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 0a94ca7..871e5ef 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -121,10 +121,11 @@ M68kCPU *cpu_m68k_init(const char *cpu_model)
 
 void m68k_cpu_init_gdb(M68kCPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     CPUM68KState *env = &cpu->env;
 
     if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
-        gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
+        gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg,
                                  11, "cf-fp.xml", 18);
     }
     /* TODO: Add [E]MAC registers.  */
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 815ce0c..24821f9 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7695,8 +7695,8 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu)
 
 static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
 {
+    CPUState *cs = CPU(dev);
     PowerPCCPU *cpu = POWERPC_CPU(dev);
-    CPUPPCState *env = &cpu->env;
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     Error *local_err = NULL;
 #if !defined(CONFIG_USER_ONLY)
@@ -7740,15 +7740,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
     init_ppc_proc(cpu);
 
     if (pcc->insns_flags & PPC_FLOAT) {
-        gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg,
+        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
                                  33, "power-fpu.xml", 0);
     }
     if (pcc->insns_flags & PPC_ALTIVEC) {
-        gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg,
+        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
                                  34, "power-altivec.xml", 0);
     }
     if (pcc->insns_flags & PPC_SPE) {
-        gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg,
+        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
                                  34, "power-spe.xml", 0);
     }
 
@@ -7756,6 +7756,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
 
 #if defined(PPC_DUMP_CPU)
     {
+        CPUPPCState *env = &cpu->env;
         const char *mmu_model, *excp_model, *bus_model;
         switch (env->mmu_model) {
         case POWERPC_MMU_32B:
@@ -7907,10 +7908,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
             printf("                        none\n");
         printf("    Time-base/decrementer clock source: %s\n",
                env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
+        dump_ppc_insns(env);
+        dump_ppc_sprs(env);
+        fflush(stdout);
     }
-    dump_ppc_insns(env);
-    dump_ppc_sprs(env);
-    fflush(stdout);
 #endif
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (37 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 38/41] gdbstub: Change gdb_register_coprocessor() argument " Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-06 12:55   ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 40/41] gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass Andreas Färber
                   ` (2 subsequent siblings)
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Filippov, jan.kiszka, Andreas Färber

Register a CPU type per core registered. Save the XtensaConfig in
XtensaCPUClass instead of CPUXtensaState.

Prepares for storing per-class GDB register count.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c                 |  17 ++++---
 hw/xtensa/pic_cpu.c       |  47 ++++++++++++------
 target-xtensa/cpu-qom.h   |   3 ++
 target-xtensa/cpu.c       |  30 ++++++++++--
 target-xtensa/cpu.h       |  22 +++++----
 target-xtensa/helper.c    |  93 +++++++++++++++++++++++------------
 target-xtensa/op_helper.c | 121 ++++++++++++++++++++++++++++++++--------------
 target-xtensa/translate.c |  12 +++--
 8 files changed, 236 insertions(+), 109 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 4ebe9e0..d08cfd3 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1692,14 +1692,16 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
  * reset bit 0 in the 'flags' field of the registers definitions in the
  * gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
  */
-#define NUM_CORE_REGS (env->config->gdb_regmap.num_regs)
+#define NUM_CORE_REGS \
+  (XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env))->config->gdb_regmap.num_regs)
 #define num_g_regs NUM_CORE_REGS
 
 static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 {
-    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
+    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
 
-    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
+    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
         return 0;
     }
 
@@ -1710,7 +1712,7 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 
     case 1: /*ar*/
         xtensa_sync_phys_from_window(env);
-        GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]);
+        GET_REG32(env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg]);
         break;
 
     case 2: /*SR*/
@@ -1738,10 +1740,11 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 
 static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 {
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
     uint32_t tmp;
-    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
+    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
 
-    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
+    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
         return 0;
     }
 
@@ -1753,7 +1756,7 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
         break;
 
     case 1: /*ar*/
-        env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
+        env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg] = tmp;
         xtensa_sync_window_from_phys(env);
         break;
 
diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c
index 7f015ff..048038d 100644
--- a/hw/xtensa/pic_cpu.c
+++ b/hw/xtensa/pic_cpu.c
@@ -31,13 +31,15 @@
 
 void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     uint32_t old_ccount = env->sregs[CCOUNT];
 
     env->sregs[CCOUNT] += d;
 
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
         int i;
-        for (i = 0; i < env->config->nccompare; ++i) {
+        for (i = 0; i < xcc->config->nccompare; ++i) {
             if (env->sregs[CCOMPARE + i] - old_ccount <= d) {
                 xtensa_timer_irq(env, i, 1);
             }
@@ -47,7 +49,9 @@ void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
 
 void check_interrupts(CPUXtensaState *env)
 {
-    CPUState *cs = CPU(xtensa_env_get_cpu(env));
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     int minlevel = xtensa_get_cintlevel(env);
     uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
     int level;
@@ -60,11 +64,11 @@ void check_interrupts(CPUXtensaState *env)
 
         xtensa_advance_ccount(env,
                 muldiv64(now - env->halt_clock,
-                    env->config->clock_freq_khz, 1000000));
+                    xcc->config->clock_freq_khz, 1000000));
         env->halt_clock = now;
     }
-    for (level = env->config->nlevel; level > minlevel; --level) {
-        if (env->config->level_mask[level] & int_set_enabled) {
+    for (level = xcc->config->nlevel; level > minlevel; --level) {
+        if (xcc->config->level_mask[level] & int_set_enabled) {
             env->pending_irq_level = level;
             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
             qemu_log_mask(CPU_LOG_INT,
@@ -86,15 +90,17 @@ void check_interrupts(CPUXtensaState *env)
 static void xtensa_set_irq(void *opaque, int irq, int active)
 {
     CPUXtensaState *env = opaque;
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
 
-    if (irq >= env->config->ninterrupt) {
+    if (irq >= xcc->config->ninterrupt) {
         qemu_log("%s: bad IRQ %d\n", __func__, irq);
     } else {
         uint32_t irq_bit = 1 << irq;
 
         if (active) {
             env->sregs[INTSET] |= irq_bit;
-        } else if (env->config->interrupt[irq].inttype == INTTYPE_LEVEL) {
+        } else if (xcc->config->interrupt[irq].inttype == INTTYPE_LEVEL) {
             env->sregs[INTSET] &= ~irq_bit;
         }
 
@@ -104,15 +110,20 @@ static void xtensa_set_irq(void *opaque, int irq, int active)
 
 void xtensa_timer_irq(CPUXtensaState *env, uint32_t id, uint32_t active)
 {
-    qemu_set_irq(env->irq_inputs[env->config->timerint[id]], active);
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    qemu_set_irq(env->irq_inputs[xcc->config->timerint[id]], active);
 }
 
 void xtensa_rearm_ccompare_timer(CPUXtensaState *env)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     int i;
     uint32_t wake_ccount = env->sregs[CCOUNT] - 1;
 
-    for (i = 0; i < env->config->nccompare; ++i) {
+    for (i = 0; i < xcc->config->nccompare; ++i) {
         if (env->sregs[CCOMPARE + i] - env->sregs[CCOUNT] <
                 wake_ccount - env->sregs[CCOUNT]) {
             wake_ccount = env->sregs[CCOMPARE + i];
@@ -121,7 +132,7 @@ void xtensa_rearm_ccompare_timer(CPUXtensaState *env)
     env->wake_ccount = wake_ccount;
     qemu_mod_timer(env->ccompare_timer, env->halt_clock +
             muldiv64(wake_ccount - env->sregs[CCOUNT],
-                1000000, env->config->clock_freq_khz));
+                1000000, xcc->config->clock_freq_khz));
 }
 
 static void xtensa_ccompare_cb(void *opaque)
@@ -143,11 +154,12 @@ static void xtensa_ccompare_cb(void *opaque)
 void xtensa_irq_init(CPUXtensaState *env)
 {
     XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
 
     env->irq_inputs = (void **)qemu_allocate_irqs(
-            xtensa_set_irq, env, env->config->ninterrupt);
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT) &&
-            env->config->nccompare > 0) {
+            xtensa_set_irq, env, xcc->config->ninterrupt);
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT) &&
+            xcc->config->nccompare > 0) {
         env->ccompare_timer =
             qemu_new_timer_ns(vm_clock, &xtensa_ccompare_cb, cpu);
     }
@@ -155,8 +167,11 @@ void xtensa_irq_init(CPUXtensaState *env)
 
 void *xtensa_get_extint(CPUXtensaState *env, unsigned extint)
 {
-    if (extint < env->config->nextint) {
-        unsigned irq = env->config->extint[extint];
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (extint < xcc->config->nextint) {
+        unsigned irq = xcc->config->extint[extint];
         return env->irq_inputs[irq];
     } else {
         qemu_log("%s: trying to acquire invalid external interrupt %d\n",
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 944d3cc..878eb15 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -45,6 +45,7 @@
  * XtensaCPUClass:
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
+ * @config: The CPU core configuration.
  *
  * An Xtensa CPU model.
  */
@@ -55,6 +56,8 @@ typedef struct XtensaCPUClass {
 
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
+
+    const XtensaConfig *config;
 } XtensaCPUClass;
 
 /**
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 6556caa..75762ad 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -50,20 +50,39 @@ static void xtensa_cpu_reset(CPUState *s)
     xcc->parent_reset(s);
 
     env->exception_taken = 0;
-    env->pc = env->config->exception_vector[EXC_RESET];
+    env->pc = xcc->config->exception_vector[EXC_RESET];
     env->sregs[LITBASE] &= ~1;
-    env->sregs[PS] = xtensa_option_enabled(env->config,
+    env->sregs[PS] = xtensa_option_enabled(xcc->config,
             XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
-    env->sregs[VECBASE] = env->config->vecbase;
+    env->sregs[VECBASE] = xcc->config->vecbase;
     env->sregs[IBREAKENABLE] = 0;
     env->sregs[CACHEATTR] = 0x22222222;
-    env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
+    env->sregs[ATOMCTL] = xtensa_option_enabled(xcc->config,
             XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
 
     env->pending_irq_level = 0;
     reset_mmu(env);
 }
 
+static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
+{
+    ObjectClass *oc;
+    char *typename;
+
+    if (cpu_model == NULL) {
+        return NULL;
+    }
+
+    typename = g_strdup_printf("%s-" TYPE_XTENSA_CPU, cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    if (!oc || !object_class_dynamic_cast(oc, TYPE_XTENSA_CPU) ||
+        object_class_is_abstract(oc)) {
+        return NULL;
+    }
+    return oc;
+}
+
 static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
@@ -105,6 +124,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     xcc->parent_reset = cc->reset;
     cc->reset = xtensa_cpu_reset;
 
+    cc->class_by_name = xtensa_cpu_class_by_name;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
@@ -119,7 +139,7 @@ static const TypeInfo xtensa_cpu_type_info = {
     .parent = TYPE_CPU,
     .instance_size = sizeof(XtensaCPU),
     .instance_init = xtensa_cpu_initfn,
-    .abstract = false,
+    .abstract = true,
     .class_size = sizeof(XtensaCPUClass),
     .class_init = xtensa_cpu_class_init,
 };
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index a8f02f6..9ad0ac6 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -333,7 +333,6 @@ typedef struct XtensaConfigList {
 } XtensaConfigList;
 
 typedef struct CPUXtensaState {
-    const XtensaConfig *config;
     uint32_t regs[16];
     uint32_t pc;
     uint32_t sregs[256];
@@ -432,16 +431,18 @@ static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt)
 
 static inline int xtensa_get_cintlevel(const CPUXtensaState *env)
 {
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
     int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT;
-    if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) {
-        level = env->config->excm_level;
+    if ((env->sregs[PS] & PS_EXCM) && xcc->config->excm_level > level) {
+        level = xcc->config->excm_level;
     }
     return level;
 }
 
 static inline int xtensa_get_ring(const CPUXtensaState *env)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
     } else {
         return 0;
@@ -450,7 +451,8 @@ static inline int xtensa_get_ring(const CPUXtensaState *env)
 
 static inline int xtensa_get_cring(const CPUXtensaState *env)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) &&
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU) &&
             (env->sregs[PS] & PS_EXCM) == 0) {
         return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
     } else {
@@ -488,6 +490,8 @@ static inline int cpu_mmu_index(CPUXtensaState *env)
 static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
         target_ulong *cs_base, int *flags)
 {
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
+
     *pc = env->pc;
     *cs_base = 0;
     *flags = 0;
@@ -495,19 +499,19 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
     if (env->sregs[PS] & PS_EXCM) {
         *flags |= XTENSA_TBFLAG_EXCM;
     }
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) &&
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_EXTENDED_L32R) &&
             (env->sregs[LITBASE] & 1)) {
         *flags |= XTENSA_TBFLAG_LITBASE;
     }
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) {
-        if (xtensa_get_cintlevel(env) < env->config->debug_level) {
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_DEBUG)) {
+        if (xtensa_get_cintlevel(env) < xcc->config->debug_level) {
             *flags |= XTENSA_TBFLAG_DEBUG;
         }
         if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) {
             *flags |= XTENSA_TBFLAG_ICOUNT;
         }
     }
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_COPROCESSOR)) {
         *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
     }
 }
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index a67c849..a1e524d 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -35,17 +35,36 @@
 
 static struct XtensaConfigList *xtensa_cores;
 
+static void xtensa_core_class_init(ObjectClass *oc, void *data)
+{
+    XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
+    const XtensaConfig *config = data;
+
+    xcc->config = config;
+}
+
 void xtensa_register_core(XtensaConfigList *node)
 {
+    TypeInfo type = {
+        .parent = TYPE_XTENSA_CPU,
+        .class_init = xtensa_core_class_init,
+        .class_data = (void *)node->config,
+    };
+
     node->next = xtensa_cores;
     xtensa_cores = node;
+    type.name = g_strdup_printf("%s-" TYPE_XTENSA_CPU, node->config->name);
+    type_register(&type);
+    g_free((gpointer)type.name);
 }
 
 static uint32_t check_hw_breakpoints(CPUXtensaState *env)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     unsigned i;
 
-    for (i = 0; i < env->config->ndbreak; ++i) {
+    for (i = 0; i < xcc->config->ndbreak; ++i) {
         if (env->cpu_watchpoint[i] &&
                 env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) {
             return DEBUGCAUSE_DB | (i << DEBUGCAUSE_DBNUM_SHIFT);
@@ -72,24 +91,17 @@ void xtensa_breakpoint_handler(CPUXtensaState *env)
 
 XtensaCPU *cpu_xtensa_init(const char *cpu_model)
 {
+    ObjectClass *oc;
     XtensaCPU *cpu;
     CPUXtensaState *env;
-    const XtensaConfig *config = NULL;
-    XtensaConfigList *core = xtensa_cores;
 
-    for (; core; core = core->next)
-        if (strcmp(core->config->name, cpu_model) == 0) {
-            config = core->config;
-            break;
-        }
-
-    if (config == NULL) {
+    oc = cpu_class_by_name(TYPE_XTENSA_CPU, cpu_model);
+    if (oc == NULL) {
         return NULL;
     }
 
-    cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU));
+    cpu = XTENSA_CPU(object_new(object_class_get_name(oc)));
     env = &cpu->env;
-    env->config = config;
 
     xtensa_irq_init(env);
 
@@ -128,9 +140,12 @@ hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
 
 static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
 {
-    if (xtensa_option_enabled(env->config,
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config,
                 XTENSA_OPTION_RELOCATABLE_VECTOR)) {
-        return vector - env->config->vecbase + env->sregs[VECBASE];
+        return vector - xcc->config->vecbase + env->sregs[VECBASE];
     } else {
         return vector;
     }
@@ -144,11 +159,13 @@ static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
  */
 static void handle_interrupt(CPUXtensaState *env)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     int level = env->pending_irq_level;
 
     if (level > xtensa_get_cintlevel(env) &&
-            level <= env->config->nlevel &&
-            (env->config->level_mask[level] &
+            level <= xcc->config->nlevel &&
+            (xcc->config->level_mask[level] &
              env->sregs[INTSET] &
              env->sregs[INTENABLE])) {
         if (level > 1) {
@@ -157,12 +174,12 @@ static void handle_interrupt(CPUXtensaState *env)
             env->sregs[PS] =
                 (env->sregs[PS] & ~PS_INTLEVEL) | level | PS_EXCM;
             env->pc = relocated_vector(env,
-                    env->config->interrupt_vector[level]);
+                    xcc->config->interrupt_vector[level]);
         } else {
             env->sregs[EXCCAUSE] = LEVEL1_INTERRUPT_CAUSE;
 
             if (env->sregs[PS] & PS_EXCM) {
-                if (env->config->ndepc) {
+                if (xcc->config->ndepc) {
                     env->sregs[DEPC] = env->pc;
                 } else {
                     env->sregs[EPC1] = env->pc;
@@ -182,6 +199,7 @@ static void handle_interrupt(CPUXtensaState *env)
 void xtensa_cpu_do_interrupt(CPUState *cs)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     CPUXtensaState *env = &cpu->env;
 
     if (env->exception_index == EXC_IRQ) {
@@ -212,9 +230,9 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
                 "pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n",
                 __func__, env->exception_index,
                 env->pc, env->regs[0], env->sregs[PS], env->sregs[CCOUNT]);
-        if (env->config->exception_vector[env->exception_index]) {
+        if (xcc->config->exception_vector[env->exception_index]) {
             env->pc = relocated_vector(env,
-                    env->config->exception_vector[env->exception_index]);
+                    xcc->config->exception_vector[env->exception_index]);
             env->exception_taken = 1;
         } else {
             qemu_log("%s(pc = %08x) bad exception_index: %d\n",
@@ -309,15 +327,18 @@ static void reset_tlb_region_way0(CPUXtensaState *env,
 
 void reset_mmu(CPUXtensaState *env)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         env->sregs[RASID] = 0x04030201;
         env->sregs[ITLBCFG] = 0;
         env->sregs[DTLBCFG] = 0;
         env->autorefill_idx = 0;
-        reset_tlb_mmu_all_ways(env, &env->config->itlb, env->itlb);
-        reset_tlb_mmu_all_ways(env, &env->config->dtlb, env->dtlb);
-        reset_tlb_mmu_ways56(env, &env->config->itlb, env->itlb);
-        reset_tlb_mmu_ways56(env, &env->config->dtlb, env->dtlb);
+        reset_tlb_mmu_all_ways(env, &xcc->config->itlb, env->itlb);
+        reset_tlb_mmu_all_ways(env, &xcc->config->dtlb, env->dtlb);
+        reset_tlb_mmu_ways56(env, &xcc->config->itlb, env->itlb);
+        reset_tlb_mmu_ways56(env, &xcc->config->dtlb, env->dtlb);
     } else {
         reset_tlb_region_way0(env, env->itlb);
         reset_tlb_region_way0(env, env->dtlb);
@@ -347,8 +368,10 @@ static unsigned get_ring(const CPUXtensaState *env, uint8_t asid)
 int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
         uint32_t *pwi, uint32_t *pei, uint8_t *pring)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     const xtensa_tlb *tlb = dtlb ?
-        &env->config->dtlb : &env->config->itlb;
+        &xcc->config->dtlb : &xcc->config->itlb;
     const xtensa_tlb_entry (*entry)[MAX_TLB_WAY_SIZE] = dtlb ?
         env->dtlb : env->itlb;
 
@@ -586,10 +609,13 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
         uint32_t vaddr, int is_write, int mmu_idx,
         uint32_t *paddr, uint32_t *page_size, unsigned *access)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         return get_physical_addr_mmu(env, update_tlb,
                 vaddr, is_write, mmu_idx, paddr, page_size, access, true);
-    } else if (xtensa_option_bits_enabled(env->config,
+    } else if (xtensa_option_bits_enabled(xcc->config,
                 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
                 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) {
         return get_physical_addr_region(env, vaddr, is_write, mmu_idx,
@@ -606,11 +632,13 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
 static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
         CPUXtensaState *env, bool dtlb)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     unsigned wi, ei;
     const xtensa_tlb *conf =
-        dtlb ? &env->config->dtlb : &env->config->itlb;
+        dtlb ? &xcc->config->dtlb : &xcc->config->itlb;
     unsigned (*attr_to_access)(uint32_t) =
-        xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) ?
+        xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU) ?
         mmu_attr_to_access : region_attr_to_access;
 
     for (wi = 0; wi < conf->nways; ++wi) {
@@ -666,7 +694,10 @@ static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
 
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env)
 {
-    if (xtensa_option_bits_enabled(env->config,
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_bits_enabled(xcc->config,
                 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
                 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION) |
                 XTENSA_OPTION_BIT(XTENSA_OPTION_MMU))) {
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 4c41de0..2f08766 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -50,8 +50,11 @@ static void do_unaligned_access(CPUXtensaState *env,
 static void do_unaligned_access(CPUXtensaState *env,
         target_ulong addr, int is_write, int is_user, uintptr_t retaddr)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
-            !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
+            !xtensa_option_enabled(xcc->config, XTENSA_OPTION_HW_ALIGNMENT)) {
         cpu_restore_state(env, retaddr);
         HELPER(exception_cause_vaddr)(env,
                 env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
@@ -101,11 +104,13 @@ void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
 
 void HELPER(exception_cause)(CPUXtensaState *env, uint32_t pc, uint32_t cause)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     uint32_t vector;
 
     env->pc = pc;
     if (env->sregs[PS] & PS_EXCM) {
-        if (env->config->ndepc) {
+        if (xcc->config->ndepc) {
             env->sregs[DEPC] = pc;
         } else {
             env->sregs[EPC1] = pc;
@@ -131,14 +136,19 @@ void HELPER(exception_cause_vaddr)(CPUXtensaState *env,
 
 void debug_exception_env(CPUXtensaState *env, uint32_t cause)
 {
-    if (xtensa_get_cintlevel(env) < env->config->debug_level) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_get_cintlevel(env) < xcc->config->debug_level) {
         HELPER(debug_exception)(env, env->pc, cause);
     }
 }
 
 void HELPER(debug_exception)(CPUXtensaState *env, uint32_t pc, uint32_t cause)
 {
-    unsigned level = env->config->debug_level;
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+    unsigned level = xcc->config->debug_level;
 
     env->pc = pc;
     env->sregs[DEBUGCAUSE] = cause;
@@ -165,12 +175,15 @@ uint32_t HELPER(nsau)(uint32_t v)
 static void copy_window_from_phys(CPUXtensaState *env,
         uint32_t window, uint32_t phys, uint32_t n)
 {
-    assert(phys < env->config->nareg);
-    if (phys + n <= env->config->nareg) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    assert(phys < xcc->config->nareg);
+    if (phys + n <= xcc->config->nareg) {
         memcpy(env->regs + window, env->phys_regs + phys,
                 n * sizeof(uint32_t));
     } else {
-        uint32_t n1 = env->config->nareg - phys;
+        uint32_t n1 = xcc->config->nareg - phys;
         memcpy(env->regs + window, env->phys_regs + phys,
                 n1 * sizeof(uint32_t));
         memcpy(env->regs + window + n1, env->phys_regs,
@@ -181,12 +194,15 @@ static void copy_window_from_phys(CPUXtensaState *env,
 static void copy_phys_from_window(CPUXtensaState *env,
         uint32_t phys, uint32_t window, uint32_t n)
 {
-    assert(phys < env->config->nareg);
-    if (phys + n <= env->config->nareg) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    assert(phys < xcc->config->nareg);
+    if (phys + n <= xcc->config->nareg) {
         memcpy(env->phys_regs + phys, env->regs + window,
                 n * sizeof(uint32_t));
     } else {
-        uint32_t n1 = env->config->nareg - phys;
+        uint32_t n1 = xcc->config->nareg - phys;
         memcpy(env->phys_regs + phys, env->regs + window,
                 n1 * sizeof(uint32_t));
         memcpy(env->phys_regs, env->regs + window + n1,
@@ -197,7 +213,10 @@ static void copy_phys_from_window(CPUXtensaState *env,
 
 static inline unsigned windowbase_bound(unsigned a, const CPUXtensaState *env)
 {
-    return a & (env->config->nareg / 4 - 1);
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    return a & (xcc->config->nareg / 4 - 1);
 }
 
 static inline unsigned windowstart_bit(unsigned a, const CPUXtensaState *env)
@@ -375,7 +394,9 @@ void HELPER(dump_state)(CPUXtensaState *env)
 
 void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
 {
-    CPUState *cpu;
+    CPUState *cs;
+    XtensaCPU *cpu;
+    XtensaCPUClass *xcc;
 
     env->pc = pc;
     env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) |
@@ -386,10 +407,12 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
         return;
     }
 
-    cpu = CPU(xtensa_env_get_cpu(env));
+    cpu = xtensa_env_get_cpu(env);
+    cs = CPU(cpu);
+    xcc = XTENSA_CPU_GET_CLASS(cpu);
     env->halt_clock = qemu_get_clock_ns(vm_clock);
-    cpu->halted = 1;
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
+    cs->halted = 1;
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
         xtensa_rearm_ccompare_timer(env);
     }
     HELPER(exception)(env, EXCP_HLT);
@@ -418,6 +441,8 @@ void HELPER(check_interrupts)(CPUXtensaState *env)
  */
 void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     uint32_t paddr, page_size, access;
     uint32_t atomctl = env->sregs[ATOMCTL];
     int rc = xtensa_get_physical_addr(env, true, vaddr, 1,
@@ -441,7 +466,7 @@ void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
      * See ISA, 4.3.12.4 The Atomic Operation Control Register (ATOMCTL)
      * under the Conditional Store Option.
      */
-    if (!xtensa_option_enabled(env->config, XTENSA_OPTION_DCACHE)) {
+    if (!xtensa_option_enabled(xcc->config, XTENSA_OPTION_DCACHE)) {
         access = PAGE_CACHE_BYPASS;
     }
 
@@ -500,10 +525,13 @@ static uint32_t get_page_size(const CPUXtensaState *env, bool dtlb, uint32_t way
  */
 uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         bool varway56 = dtlb ?
-            env->config->dtlb.varway56 :
-            env->config->itlb.varway56;
+            xcc->config->dtlb.varway56 :
+            xcc->config->itlb.varway56;
 
         switch (way) {
         case 4:
@@ -537,18 +565,21 @@ uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t
  */
 static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
     if (way < 4) {
         bool is32 = (dtlb ?
-                env->config->dtlb.nrefillentries :
-                env->config->itlb.nrefillentries) == 32;
+                xcc->config->dtlb.nrefillentries :
+                xcc->config->itlb.nrefillentries) == 32;
         return is32 ? 0xffff8000 : 0xffffc000;
     } else if (way == 4) {
         return xtensa_tlb_get_addr_mask(env, dtlb, way) << 2;
     } else if (way <= 6) {
         uint32_t mask = xtensa_tlb_get_addr_mask(env, dtlb, way);
         bool varway56 = dtlb ?
-            env->config->dtlb.varway56 :
-            env->config->itlb.varway56;
+            xcc->config->dtlb.varway56 :
+            xcc->config->itlb.varway56;
 
         if (varway56) {
             return mask << (way == 5 ? 2 : 3);
@@ -567,9 +598,11 @@ static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
 void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
         uint32_t *vpn, uint32_t wi, uint32_t *ei)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     bool varway56 = dtlb ?
-        env->config->dtlb.varway56 :
-        env->config->itlb.varway56;
+        xcc->config->dtlb.varway56 :
+        xcc->config->itlb.varway56;
 
     if (!dtlb) {
         wi &= 7;
@@ -577,8 +610,8 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
 
     if (wi < 4) {
         bool is32 = (dtlb ?
-                env->config->dtlb.nrefillentries :
-                env->config->itlb.nrefillentries) == 32;
+                xcc->config->dtlb.nrefillentries :
+                xcc->config->itlb.nrefillentries) == 32;
         *ei = (v >> 12) & (is32 ? 0x7 : 0x3);
     } else {
         switch (wi) {
@@ -622,7 +655,10 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
 static void split_tlb_entry_spec(CPUXtensaState *env, uint32_t v, bool dtlb,
         uint32_t *vpn, uint32_t *wi, uint32_t *ei)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         *wi = v & (dtlb ? 0xf : 0x7);
         split_tlb_entry_spec_way(env, v, dtlb, vpn, *wi, ei);
     } else {
@@ -648,7 +684,10 @@ static xtensa_tlb_entry *get_tlb_entry(CPUXtensaState *env,
 
 uint32_t HELPER(rtlb0)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         uint32_t wi;
         const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi);
         return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid;
@@ -665,7 +704,10 @@ uint32_t HELPER(rtlb1)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
 
 void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         uint32_t wi;
         xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi);
         if (entry->variable && entry->asid) {
@@ -677,7 +719,10 @@ void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
 
 uint32_t HELPER(ptlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
 {
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         uint32_t wi;
         uint32_t ei;
         uint8_t ring;
@@ -714,9 +759,11 @@ void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
 void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
         unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     xtensa_tlb_entry *entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);
 
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
         if (entry->variable) {
             if (entry->asid) {
                 tlb_flush_page(env, entry->vaddr);
@@ -729,7 +776,7 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
         }
     } else {
         tlb_flush_page(env, entry->vaddr);
-        if (xtensa_option_enabled(env->config,
+        if (xtensa_option_enabled(xcc->config,
                     XTENSA_OPTION_REGION_TRANSLATION)) {
             entry->paddr = pte & REGION_PAGE_MASK;
         }
@@ -749,15 +796,17 @@ void HELPER(wtlb)(CPUXtensaState *env, uint32_t p, uint32_t v, uint32_t dtlb)
 
 void HELPER(wsr_ibreakenable)(CPUXtensaState *env, uint32_t v)
 {
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     uint32_t change = v ^ env->sregs[IBREAKENABLE];
     unsigned i;
 
-    for (i = 0; i < env->config->nibreak; ++i) {
+    for (i = 0; i < xcc->config->nibreak; ++i) {
         if (change & (1 << i)) {
             tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]);
         }
     }
-    env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1);
+    env->sregs[IBREAKENABLE] = v & ((1 << xcc->config->nibreak) - 1);
 }
 
 void HELPER(wsr_ibreaka)(CPUXtensaState *env, uint32_t i, uint32_t v)
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index cc36fa4..c64b54e 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2881,6 +2881,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
 {
     CPUState *cs = CPU(cpu);
     CPUXtensaState *env = &cpu->env;
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
     DisasContext dc;
     int insn_count = 0;
     int j, lj = -1;
@@ -2894,7 +2895,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
         max_insns = CF_COUNT_MASK;
     }
 
-    dc.config = env->config;
+    dc.config = xcc->config;
     dc.singlestep_enabled = cs->singlestep_enabled;
     dc.tb = tb;
     dc.pc = pc_start;
@@ -3021,13 +3022,14 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
                            fprintf_function cpu_fprintf, int flags)
 {
     XtensaCPU *cpu = XTENSA_CPU(cs);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cs);
     CPUXtensaState *env = &cpu->env;
     int i, j;
 
     cpu_fprintf(f, "PC=%08x\n\n", env->pc);
 
     for (i = j = 0; i < 256; ++i) {
-        if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
+        if (xtensa_option_bits_enabled(xcc->config, sregnames[i].opt_bits)) {
             cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
                     (j++ % 4) == 3 ? '\n' : ' ');
         }
@@ -3036,7 +3038,7 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
     cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
 
     for (i = j = 0; i < 256; ++i) {
-        if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
+        if (xtensa_option_bits_enabled(xcc->config, uregnames[i].opt_bits)) {
             cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
                     (j++ % 4) == 3 ? '\n' : ' ');
         }
@@ -3051,12 +3053,12 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
 
     cpu_fprintf(f, "\n");
 
-    for (i = 0; i < env->config->nareg; ++i) {
+    for (i = 0; i < xcc->config->nareg; ++i) {
         cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
                 (i % 4) == 3 ? '\n' : ' ');
     }
 
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
+    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_FP_COPROCESSOR)) {
         cpu_fprintf(f, "\n");
 
         for (i = 0; i < 16; ++i) {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 40/41] gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (38 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register() Andreas Färber
  2013-06-30 12:23 ` [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Michael Walle
  41 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Andreas Färber, Aurelien Jarno,
	Richard Henderson

As a side effect this should fix coprocessor register numbering for SMP.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c                   | 80 ++++++++++-----------------------------------
 include/qom/cpu.h           |  3 ++
 qom/cpu.c                   |  9 +++++
 target-alpha/cpu.c          |  1 +
 target-arm/cpu.c            |  1 +
 target-cris/cpu.c           |  2 ++
 target-i386/cpu.c           |  1 +
 target-lm32/cpu.c           |  1 +
 target-m68k/cpu.c           |  1 +
 target-microblaze/cpu.c     |  1 +
 target-mips/cpu.c           |  2 ++
 target-openrisc/cpu.c       |  1 +
 target-ppc/translate_init.c |  2 ++
 target-s390x/cpu.c          |  1 +
 target-sh4/cpu.c            |  1 +
 target-sparc/cpu.c          |  6 ++++
 target-xtensa/cpu.c         |  3 ++
 target-xtensa/helper.c      |  8 +++++
 18 files changed, 61 insertions(+), 63 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index d08cfd3..1a827c2 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -530,8 +530,6 @@ static const int gpr_map[16] = {
 #endif
 static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
 
-#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25)
-
 #define IDX_IP_REG      CPU_NB_REGS
 #define IDX_FLAGS_REG   (IDX_IP_REG + 1)
 #define IDX_SEG_REGS    (IDX_FLAGS_REG + 1)
@@ -702,7 +700,6 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n)
    historical mishap the FP registers appear in between core integer
    regs and PC, MSR, CR, and so forth.  We hack round this by giving the
    FP regs zero size when talking to a newer gdb.  */
-#define NUM_CORE_REGS 71
 #if defined (TARGET_PPC64)
 #define GDB_CORE_XML "power64-core.xml"
 #else
@@ -796,12 +793,6 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
 
 #elif defined (TARGET_SPARC)
 
-#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
-#define NUM_CORE_REGS 86
-#else
-#define NUM_CORE_REGS 72
-#endif
-
 #ifdef TARGET_ABI32
 #define GET_REGA(val) GET_REG32(val)
 #else
@@ -948,7 +939,6 @@ static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
    the FPA registers appear in between core integer regs and the CPSR.
    We hack round this by giving the FPA regs zero size when talking to a
    newer gdb.  */
-#define NUM_CORE_REGS 26
 #define GDB_CORE_XML "arm-core.xml"
 
 static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
@@ -1017,8 +1007,6 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n)
 
 #elif defined (TARGET_M68K)
 
-#define NUM_CORE_REGS 18
-
 #define GDB_CORE_XML "cf-core.xml"
 
 static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
@@ -1063,8 +1051,6 @@ static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_MIPS)
 
-#define NUM_CORE_REGS 73
-
 static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
@@ -1165,8 +1151,6 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
 }
 #elif defined(TARGET_OPENRISC)
 
-#define NUM_CORE_REGS (32 + 3)
-
 static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
@@ -1195,9 +1179,10 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_write_register(CPUOpenRISCState *env,
                                   uint8_t *mem_buf, int n)
 {
+    CPUClass *cc = CPU_GET_CLASS(openrisc_env_get_cpu(env));
     uint32_t tmp;
 
-    if (n > NUM_CORE_REGS) {
+    if (n > cc->gdb_num_core_regs) {
         return 0;
     }
 
@@ -1230,8 +1215,6 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env,
 /* Hint: Use "set architecture sh4" in GDB to see fpu registers */
 /* FIXME: We should use XML for this.  */
 
-#define NUM_CORE_REGS 59
-
 static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
 {
     switch (n) {
@@ -1347,8 +1330,6 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_MICROBLAZE)
 
-#define NUM_CORE_REGS (32 + 5)
-
 static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
@@ -1361,10 +1342,12 @@ static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
 
 static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
 {
+    CPUClass *cc = CPU_GET_CLASS(mb_env_get_cpu(env));
     uint32_t tmp;
 
-    if (n > NUM_CORE_REGS)
+    if (n > cc->gdb_num_core_regs) {
 	return 0;
+    }
 
     tmp = ldl_p(mem_buf);
 
@@ -1377,8 +1360,6 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_CRIS)
 
-#define NUM_CORE_REGS 49
-
 static int
 read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
 {
@@ -1473,8 +1454,6 @@ static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_ALPHA)
 
-#define NUM_CORE_REGS 67
-
 static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
 {
     uint64_t val;
@@ -1543,8 +1522,6 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_S390X)
 
-#define NUM_CORE_REGS  S390_NUM_REGS
-
 static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n)
 {
     uint64_t val;
@@ -1614,7 +1591,6 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
 #elif defined (TARGET_LM32)
 
 #include "hw/lm32/lm32_pic.h"
-#define NUM_CORE_REGS (32 + 7)
 
 static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
 {
@@ -1651,9 +1627,10 @@ static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
 
 static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
 {
+    CPUClass *cc = CPU_GET_CLASS(lm32_env_get_cpu(env));
     uint32_t tmp;
 
-    if (n > NUM_CORE_REGS) {
+    if (n > cc->gdb_num_core_regs) {
         return 0;
     }
 
@@ -1687,15 +1664,6 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
 }
 #elif defined(TARGET_XTENSA)
 
-/* Use num_core_regs to see only non-privileged registers in an unmodified gdb.
- * Use num_regs to see all registers. gdb modification is required for that:
- * reset bit 0 in the 'flags' field of the registers definitions in the
- * gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
- */
-#define NUM_CORE_REGS \
-  (XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env))->config->gdb_regmap.num_regs)
-#define num_g_regs NUM_CORE_REGS
-
 static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 {
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
@@ -1786,8 +1754,6 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 }
 #else
 
-#define NUM_CORE_REGS 0
-
 static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
 {
     return 0;
@@ -1800,10 +1766,6 @@ static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
 
 #endif
 
-#if !defined(TARGET_XTENSA)
-static int num_g_regs = NUM_CORE_REGS;
-#endif
-
 #ifdef GDB_CORE_XML
 /* Encode data using the encoding for 'x' packets.  */
 static int memtox(char *buf, const char *mem, int len)
@@ -1872,11 +1834,13 @@ static const char *get_feature_xml(const char *p, const char **newp)
 
 static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
 
-    if (reg < NUM_CORE_REGS)
+    if (reg < cc->gdb_num_core_regs) {
         return cpu_gdb_read_register(env, mem_buf, reg);
+    }
 
     for (r = cpu->gdb_regs; r; r = r->next) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
@@ -1888,11 +1852,13 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 
 static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
 
-    if (reg < NUM_CORE_REGS)
+    if (reg < cc->gdb_num_core_regs) {
         return cpu_gdb_write_register(env, mem_buf, reg);
+    }
 
     for (r = cpu->gdb_regs; r; r = r->next) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
@@ -1915,7 +1881,6 @@ void gdb_register_coprocessor(CPUState *cpu,
 {
     GDBRegisterState *s;
     GDBRegisterState **p;
-    static int last_reg = NUM_CORE_REGS;
 
     p = &cpu->gdb_regs;
     while (*p) {
@@ -1926,21 +1891,19 @@ void gdb_register_coprocessor(CPUState *cpu,
     }
 
     s = g_new0(GDBRegisterState, 1);
-    s->base_reg = last_reg;
+    s->base_reg = cpu->gdb_num_regs;
     s->num_regs = num_regs;
     s->get_reg = get_reg;
     s->set_reg = set_reg;
     s->xml = xml;
 
     /* Add to end of list.  */
-    last_reg += num_regs;
+    cpu->gdb_num_regs += num_regs;
     *p = s;
     if (g_pos) {
         if (g_pos != s->base_reg) {
             fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
                     "Expected %d got %d\n", xml, g_pos, s->base_reg);
-        } else {
-            num_g_regs = last_reg;
         }
     }
 }
@@ -2061,9 +2024,6 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
-#ifdef TARGET_XTENSA
-    CPUArchState *env;
-#endif
     CPUState *cpu;
     const char *p;
     uint32_t thread;
@@ -2211,11 +2171,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'g':
         cpu_synchronize_state(s->g_cpu);
-#ifdef TARGET_XTENSA
-        env = s->g_cpu->env_ptr;
-#endif
         len = 0;
-        for (addr = 0; addr < num_g_regs; addr++) {
+        for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
             len += reg_size;
         }
@@ -2224,13 +2181,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'G':
         cpu_synchronize_state(s->g_cpu);
-#ifdef TARGET_XTENSA
-        env = s->g_cpu->env_ptr;
-#endif
         registers = mem_buf;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
-        for (addr = 0; addr < num_g_regs && len > 0; addr++) {
+        for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
             reg_size = gdb_write_register(s->g_cpu, registers, addr);
             len -= reg_size;
             registers += reg_size;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 78fbdac..f89c49e 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -100,6 +100,8 @@ typedef struct CPUClass {
                             int cpuid, void *opaque);
     int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
                                 void *opaque);
+
+    int gdb_num_core_regs;
 } CPUClass;
 
 struct KVMState;
@@ -157,6 +159,7 @@ struct CPUState {
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
     struct GDBRegisterState *gdb_regs;
+    int gdb_num_regs;
     CPUState *next_cpu;
 
     int kvm_fd;
diff --git a/qom/cpu.c b/qom/cpu.c
index 5c45ab5..2839ddf 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -226,6 +226,14 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
     }
 }
 
+static void cpu_common_initfn(Object *obj)
+{
+    CPUState *cpu = CPU(obj);
+    CPUClass *cc = CPU_GET_CLASS(obj);
+
+    cpu->gdb_num_regs = cc->gdb_num_core_regs;
+}
+
 static int64_t cpu_common_get_arch_id(CPUState *cpu)
 {
     return cpu->cpu_index;
@@ -253,6 +261,7 @@ static const TypeInfo cpu_type_info = {
     .name = TYPE_CPU,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(CPUState),
+    .instance_init = cpu_common_initfn,
     .abstract = true,
     .class_size = sizeof(CPUClass),
     .class_init = cpu_class_init,
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index e03e74b..028cec1 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -276,6 +276,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_alpha_cpu;
 #endif
+    cc->gdb_num_core_regs = 67;
 }
 
 static const TypeInfo alpha_cpu_type_info = {
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 5f8a8f9..e04bcc3 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -823,6 +823,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_arm_cpu;
 #endif
+    cc->gdb_num_core_regs = 26;
 }
 
 static void cpu_register(const ARMCPUInfo *info)
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 4d45b98..426a321 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -258,6 +258,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
 #endif
+
+    cc->gdb_num_core_regs = 49;
 }
 
 static const TypeInfo cris_cpu_type_info = {
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6b1205d..7c6f1d3 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2549,6 +2549,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
     cc->vmsd = &vmstate_x86_cpu;
 #endif
+    cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
 }
 
 static const TypeInfo x86_cpu_type_info = {
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 705dd55..ec5f0e0 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -91,6 +91,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_lm32_cpu;
 #endif
+    cc->gdb_num_core_regs = 32 + 7;
 }
 
 static const TypeInfo lm32_cpu_type_info = {
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 5328fda..35c203c 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -194,6 +194,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
 #endif
     dc->vmsd = &vmstate_m68k_cpu;
+    cc->gdb_num_core_regs = 18;
 }
 
 static void register_cpu_type(const M68kCPUInfo *info)
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 90cc088..f2e538a 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -147,6 +147,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 #endif
     dc->vmsd = &vmstate_mb_cpu;
     dc->props = mb_properties;
+    cc->gdb_num_core_regs = 32 + 5;
 }
 
 static const TypeInfo mb_cpu_type_info = {
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 10f6f69..17d49b8 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -104,6 +104,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->do_unassigned_access = mips_cpu_unassigned_access;
     cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
 #endif
+
+    cc->gdb_num_core_regs = 73;
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 2b7a40e..a2cd4be 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -156,6 +156,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_openrisc_cpu;
 #endif
+    cc->gdb_num_core_regs = 32 + 3;
 }
 
 static void cpu_register(const OpenRISCCPUInfo *info)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 24821f9..e1d9d02 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8313,6 +8313,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
+
+    cc->gdb_num_core_regs = 71;
 }
 
 static const TypeInfo ppc_cpu_type_info = {
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index ea29f9c..ae62143 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -177,6 +177,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
 #endif
     dc->vmsd = &vmstate_s390_cpu;
+    cc->gdb_num_core_regs = S390_NUM_REGS;
 }
 
 static const TypeInfo s390_cpu_type_info = {
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index c9d6590..7f5c47a 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -290,6 +290,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
 #endif
     dc->vmsd = &vmstate_sh_cpu;
+    cc->gdb_num_core_regs = 59;
 }
 
 static const TypeInfo superh_cpu_type_info = {
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index bd9d216..b35f2d1 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -791,6 +791,12 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_unassigned_access = sparc_cpu_unassigned_access;
     cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
 #endif
+
+#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
+    cc->gdb_num_core_regs = 86;
+#else
+    cc->gdb_num_core_regs = 72;
+#endif
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 75762ad..eaafacf 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -85,8 +85,11 @@ static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
 
 static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
 {
+    CPUState *cs = CPU(dev);
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
 
+    cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
+
     xcc->parent_realize(dev, errp);
 }
 
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index a1e524d..29f4db6 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -37,10 +37,18 @@ static struct XtensaConfigList *xtensa_cores;
 
 static void xtensa_core_class_init(ObjectClass *oc, void *data)
 {
+    CPUClass *cc = CPU_CLASS(oc);
     XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
     const XtensaConfig *config = data;
 
     xcc->config = config;
+
+    /* Use num_core_regs to see only non-privileged registers in an unmodified
+     * gdb. Use num_regs to see all registers. gdb modification is required
+     * for that: reset bit 0 in the 'flags' field of the registers definitions
+     * in the gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
+     */
+    cc->gdb_num_core_regs = config->gdb_regmap.num_regs;
 }
 
 void xtensa_register_core(XtensaConfigList *node)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register()
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (39 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 40/41] gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass Andreas Färber
@ 2013-06-29 20:01 ` Andreas Färber
  2013-07-01 18:07   ` Richard Henderson
  2013-06-30 12:23 ` [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Michael Walle
  41 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-06-29 20:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, open list:PowerPC, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Andreas Färber, Aurelien Jarno,
	Richard Henderson

Replace GET_REG*() macros by gdb_get_reg*() inline functions for
clarity and drop breaks after return.

Allows to move target-specific code to new target-*/gdbstub.c files.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c                       | 1274 +--------------------------------------
 include/exec/gdbstub.h          |   39 ++
 include/qom/cpu.h               |    4 +
 qom/cpu.c                       |   13 +
 target-alpha/Makefile.objs      |    1 +
 target-alpha/cpu-qom.h          |    2 +
 target-alpha/cpu.c              |    2 +
 target-alpha/gdbstub.c          |   93 +++
 target-arm/Makefile.objs        |    1 +
 target-arm/cpu-qom.h            |    3 +
 target-arm/cpu.c                |    2 +
 target-arm/gdbstub.c            |  102 ++++
 target-cris/Makefile.objs       |    1 +
 target-cris/cpu-qom.h           |    4 +
 target-cris/cpu.c               |    6 +
 target-cris/gdbstub.c           |  130 ++++
 target-i386/Makefile.objs       |    1 +
 target-i386/cpu-qom.h           |    3 +
 target-i386/cpu.c               |    2 +
 target-i386/gdbstub.c           |  231 +++++++
 target-lm32/Makefile.objs       |    1 +
 target-lm32/cpu-qom.h           |    2 +
 target-lm32/cpu.c               |    2 +
 target-lm32/gdbstub.c           |   92 +++
 target-m68k/Makefile.objs       |    1 +
 target-m68k/cpu-qom.h           |    2 +
 target-m68k/cpu.c               |    2 +
 target-m68k/gdbstub.c           |   75 +++
 target-microblaze/Makefile.objs |    1 +
 target-microblaze/cpu-qom.h     |    2 +
 target-microblaze/cpu.c         |    2 +
 target-microblaze/gdbstub.c     |   56 ++
 target-mips/Makefile.objs       |    1 +
 target-mips/cpu-qom.h           |    2 +
 target-mips/cpu.c               |    2 +
 target-mips/gdbstub.c           |  154 +++++
 target-openrisc/Makefile.objs   |    1 +
 target-openrisc/cpu.c           |    2 +
 target-openrisc/cpu.h           |    2 +
 target-openrisc/gdbstub.c       |   86 +++
 target-ppc/Makefile.objs        |    1 +
 target-ppc/cpu-qom.h            |    2 +
 target-ppc/gdbstub.c            |  131 ++++
 target-ppc/translate_init.c     |    2 +
 target-s390x/Makefile.objs      |    1 +
 target-s390x/cpu-qom.h          |    2 +
 target-s390x/cpu.c              |    2 +
 target-s390x/gdbstub.c          |   88 +++
 target-sh4/Makefile.objs        |    1 +
 target-sh4/cpu-qom.h            |    2 +
 target-sh4/cpu.c                |    2 +
 target-sh4/gdbstub.c            |  146 +++++
 target-sparc/Makefile.objs      |    1 +
 target-sparc/cpu-qom.h          |    2 +
 target-sparc/cpu.c              |    2 +
 target-sparc/gdbstub.c          |  208 +++++++
 target-xtensa/Makefile.objs     |    1 +
 target-xtensa/cpu-qom.h         |    2 +
 target-xtensa/cpu.c             |    2 +
 target-xtensa/gdbstub.c         |  111 ++++
 60 files changed, 1844 insertions(+), 1267 deletions(-)
 create mode 100644 target-alpha/gdbstub.c
 create mode 100644 target-arm/gdbstub.c
 create mode 100644 target-cris/gdbstub.c
 create mode 100644 target-i386/gdbstub.c
 create mode 100644 target-lm32/gdbstub.c
 create mode 100644 target-m68k/gdbstub.c
 create mode 100644 target-microblaze/gdbstub.c
 create mode 100644 target-mips/gdbstub.c
 create mode 100644 target-openrisc/gdbstub.c
 create mode 100644 target-ppc/gdbstub.c
 create mode 100644 target-s390x/gdbstub.c
 create mode 100644 target-sh4/gdbstub.c
 create mode 100644 target-sparc/gdbstub.c
 create mode 100644 target-xtensa/gdbstub.c

diff --git a/gdbstub.c b/gdbstub.c
index 1a827c2..a9a0770 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -40,7 +40,6 @@
 #include "cpu.h"
 #include "qemu/sockets.h"
 #include "sysemu/kvm.h"
-#include "qemu/bitops.h"
 
 static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
                                          uint8_t *buf, int len, bool is_write)
@@ -319,7 +318,7 @@ static GDBState *gdbserver_state;
 /* This is an ugly hack to cope with both new and old gdb.
    If gdb sends qXfer:features:read then assume we're talking to a newish
    gdb that understands target descriptions.  */
-static int gdb_has_xml;
+bool gdb_has_xml;
 
 #ifdef CONFIG_USER_ONLY
 /* XXX: This is not thread safe.  Do we care?  */
@@ -489,1281 +488,22 @@ static int put_packet(GDBState *s, const char *buf)
     return put_packet_binary(s, buf, strlen(buf));
 }
 
-/* The GDB remote protocol transfers values in target byte order.  This means
-   we can use the raw memory access routines to access the value buffer.
-   Conveniently, these also handle the case where the buffer is mis-aligned.
- */
-#define GET_REG8(val) do { \
-    stb_p(mem_buf, val); \
-    return 1; \
-    } while(0)
-#define GET_REG16(val) do { \
-    stw_p(mem_buf, val); \
-    return 2; \
-    } while(0)
-#define GET_REG32(val) do { \
-    stl_p(mem_buf, val); \
-    return 4; \
-    } while(0)
-#define GET_REG64(val) do { \
-    stq_p(mem_buf, val); \
-    return 8; \
-    } while(0)
-
-#if TARGET_LONG_BITS == 64
-#define GET_REGL(val) GET_REG64(val)
-#define ldtul_p(addr) ldq_p(addr)
-#else
-#define GET_REGL(val) GET_REG32(val)
-#define ldtul_p(addr) ldl_p(addr)
-#endif
-
-#if defined(TARGET_I386)
-
-#ifdef TARGET_X86_64
-static const int gpr_map[16] = {
-    R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP,
-    8, 9, 10, 11, 12, 13, 14, 15
-};
-#else
-#define gpr_map gpr_map32
-#endif
-static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
-
-#define IDX_IP_REG      CPU_NB_REGS
-#define IDX_FLAGS_REG   (IDX_IP_REG + 1)
-#define IDX_SEG_REGS    (IDX_FLAGS_REG + 1)
-#define IDX_FP_REGS     (IDX_SEG_REGS + 6)
-#define IDX_XMM_REGS    (IDX_FP_REGS + 16)
-#define IDX_MXCSR_REG   (IDX_XMM_REGS + CPU_NB_REGS)
+#if defined(TARGET_PPC)
 
-static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n)
-{
-    if (n < CPU_NB_REGS) {
-        if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
-            GET_REG64(env->regs[gpr_map[n]]);
-        } else if (n < CPU_NB_REGS32) {
-            GET_REG32(env->regs[gpr_map32[n]]);
-        }
-    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
-#ifdef USE_X86LDOUBLE
-        /* FIXME: byteswap float values - after fixing fpregs layout. */
-        memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10);
-#else
-        memset(mem_buf, 0, 10);
-#endif
-        return 10;
-    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
-        n -= IDX_XMM_REGS;
-        if (n < CPU_NB_REGS32 ||
-            (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) {
-            stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0));
-            stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1));
-            return 16;
-        }
-    } else {
-        switch (n) {
-        case IDX_IP_REG:
-            if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
-                GET_REG64(env->eip);
-            } else {
-                GET_REG32(env->eip);
-            }
-        case IDX_FLAGS_REG: GET_REG32(env->eflags);
-
-        case IDX_SEG_REGS:     GET_REG32(env->segs[R_CS].selector);
-        case IDX_SEG_REGS + 1: GET_REG32(env->segs[R_SS].selector);
-        case IDX_SEG_REGS + 2: GET_REG32(env->segs[R_DS].selector);
-        case IDX_SEG_REGS + 3: GET_REG32(env->segs[R_ES].selector);
-        case IDX_SEG_REGS + 4: GET_REG32(env->segs[R_FS].selector);
-        case IDX_SEG_REGS + 5: GET_REG32(env->segs[R_GS].selector);
-
-        case IDX_FP_REGS + 8:  GET_REG32(env->fpuc);
-        case IDX_FP_REGS + 9:  GET_REG32((env->fpus & ~0x3800) |
-                                         (env->fpstt & 0x7) << 11);
-        case IDX_FP_REGS + 10: GET_REG32(0); /* ftag */
-        case IDX_FP_REGS + 11: GET_REG32(0); /* fiseg */
-        case IDX_FP_REGS + 12: GET_REG32(0); /* fioff */
-        case IDX_FP_REGS + 13: GET_REG32(0); /* foseg */
-        case IDX_FP_REGS + 14: GET_REG32(0); /* fooff */
-        case IDX_FP_REGS + 15: GET_REG32(0); /* fop */
-
-        case IDX_MXCSR_REG: GET_REG32(env->mxcsr);
-        }
-    }
-    return 0;
-}
-
-static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf)
-{
-    uint16_t selector = ldl_p(mem_buf);
-
-    if (selector != env->segs[sreg].selector) {
-#if defined(CONFIG_USER_ONLY)
-        cpu_x86_load_seg(env, sreg, selector);
-#else
-        unsigned int limit, flags;
-        target_ulong base;
-
-        if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
-            base = selector << 4;
-            limit = 0xffff;
-            flags = 0;
-        } else {
-            if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, &flags))
-                return 4;
-        }
-        cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags);
-#endif
-    }
-    return 4;
-}
-
-static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    if (n < CPU_NB_REGS) {
-        if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
-            env->regs[gpr_map[n]] = ldtul_p(mem_buf);
-            return sizeof(target_ulong);
-        } else if (n < CPU_NB_REGS32) {
-            n = gpr_map32[n];
-            env->regs[n] &= ~0xffffffffUL;
-            env->regs[n] |= (uint32_t)ldl_p(mem_buf);
-            return 4;
-        }
-    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
-#ifdef USE_X86LDOUBLE
-        /* FIXME: byteswap float values - after fixing fpregs layout. */
-        memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10);
-#endif
-        return 10;
-    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
-        n -= IDX_XMM_REGS;
-        if (n < CPU_NB_REGS32 ||
-            (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) {
-            env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf);
-            env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8);
-            return 16;
-        }
-    } else {
-        switch (n) {
-        case IDX_IP_REG:
-            if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
-                env->eip = ldq_p(mem_buf);
-                return 8;
-            } else {
-                env->eip &= ~0xffffffffUL;
-                env->eip |= (uint32_t)ldl_p(mem_buf);
-                return 4;
-            }
-        case IDX_FLAGS_REG:
-            env->eflags = ldl_p(mem_buf);
-            return 4;
-
-        case IDX_SEG_REGS:     return cpu_x86_gdb_load_seg(env, R_CS, mem_buf);
-        case IDX_SEG_REGS + 1: return cpu_x86_gdb_load_seg(env, R_SS, mem_buf);
-        case IDX_SEG_REGS + 2: return cpu_x86_gdb_load_seg(env, R_DS, mem_buf);
-        case IDX_SEG_REGS + 3: return cpu_x86_gdb_load_seg(env, R_ES, mem_buf);
-        case IDX_SEG_REGS + 4: return cpu_x86_gdb_load_seg(env, R_FS, mem_buf);
-        case IDX_SEG_REGS + 5: return cpu_x86_gdb_load_seg(env, R_GS, mem_buf);
-
-        case IDX_FP_REGS + 8:
-            env->fpuc = ldl_p(mem_buf);
-            return 4;
-        case IDX_FP_REGS + 9:
-            tmp = ldl_p(mem_buf);
-            env->fpstt = (tmp >> 11) & 7;
-            env->fpus = tmp & ~0x3800;
-            return 4;
-        case IDX_FP_REGS + 10: /* ftag */  return 4;
-        case IDX_FP_REGS + 11: /* fiseg */ return 4;
-        case IDX_FP_REGS + 12: /* fioff */ return 4;
-        case IDX_FP_REGS + 13: /* foseg */ return 4;
-        case IDX_FP_REGS + 14: /* fooff */ return 4;
-        case IDX_FP_REGS + 15: /* fop */   return 4;
-
-        case IDX_MXCSR_REG:
-            env->mxcsr = ldl_p(mem_buf);
-            return 4;
-        }
-    }
-    /* Unrecognised register.  */
-    return 0;
-}
-
-#elif defined (TARGET_PPC)
-
-/* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
-   expects whatever the target description contains.  Due to a
-   historical mishap the FP registers appear in between core integer
-   regs and PC, MSR, CR, and so forth.  We hack round this by giving the
-   FP regs zero size when talking to a newer gdb.  */
 #if defined (TARGET_PPC64)
 #define GDB_CORE_XML "power64-core.xml"
 #else
 #define GDB_CORE_XML "power-core.xml"
 #endif
 
-static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        /* gprs */
-        GET_REGL(env->gpr[n]);
-    } else if (n < 64) {
-        /* fprs */
-        if (gdb_has_xml)
-            return 0;
-        stfq_p(mem_buf, env->fpr[n-32]);
-        return 8;
-    } else {
-        switch (n) {
-        case 64: GET_REGL(env->nip);
-        case 65: GET_REGL(env->msr);
-        case 66:
-            {
-                uint32_t cr = 0;
-                int i;
-                for (i = 0; i < 8; i++)
-                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
-                GET_REG32(cr);
-            }
-        case 67: GET_REGL(env->lr);
-        case 68: GET_REGL(env->ctr);
-        case 69: GET_REGL(env->xer);
-        case 70:
-            {
-                if (gdb_has_xml)
-                    return 0;
-                GET_REG32(env->fpscr);
-            }
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        /* gprs */
-        env->gpr[n] = ldtul_p(mem_buf);
-        return sizeof(target_ulong);
-    } else if (n < 64) {
-        /* fprs */
-        if (gdb_has_xml)
-            return 0;
-        env->fpr[n-32] = ldfq_p(mem_buf);
-        return 8;
-    } else {
-        switch (n) {
-        case 64:
-            env->nip = ldtul_p(mem_buf);
-            return sizeof(target_ulong);
-        case 65:
-            ppc_store_msr(env, ldtul_p(mem_buf));
-            return sizeof(target_ulong);
-        case 66:
-            {
-                uint32_t cr = ldl_p(mem_buf);
-                int i;
-                for (i = 0; i < 8; i++)
-                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
-                return 4;
-            }
-        case 67:
-            env->lr = ldtul_p(mem_buf);
-            return sizeof(target_ulong);
-        case 68:
-            env->ctr = ldtul_p(mem_buf);
-            return sizeof(target_ulong);
-        case 69:
-            env->xer = ldtul_p(mem_buf);
-            return sizeof(target_ulong);
-        case 70:
-            /* fpscr */
-            if (gdb_has_xml)
-                return 0;
-            store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
-            return sizeof(target_ulong);
-        }
-    }
-    return 0;
-}
-
-#elif defined (TARGET_SPARC)
-
-#ifdef TARGET_ABI32
-#define GET_REGA(val) GET_REG32(val)
-#else
-#define GET_REGA(val) GET_REGL(val)
-#endif
-
-static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 8) {
-        /* g0..g7 */
-        GET_REGA(env->gregs[n]);
-    }
-    if (n < 32) {
-        /* register window */
-        GET_REGA(env->regwptr[n - 8]);
-    }
-#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
-    if (n < 64) {
-        /* fprs */
-        if (n & 1) {
-            GET_REG32(env->fpr[(n - 32) / 2].l.lower);
-        } else {
-            GET_REG32(env->fpr[(n - 32) / 2].l.upper);
-        }
-    }
-    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-    switch (n) {
-    case 64: GET_REGA(env->y);
-    case 65: GET_REGA(cpu_get_psr(env));
-    case 66: GET_REGA(env->wim);
-    case 67: GET_REGA(env->tbr);
-    case 68: GET_REGA(env->pc);
-    case 69: GET_REGA(env->npc);
-    case 70: GET_REGA(env->fsr);
-    case 71: GET_REGA(0); /* csr */
-    default: GET_REGA(0);
-    }
-#else
-    if (n < 64) {
-        /* f0-f31 */
-        if (n & 1) {
-            GET_REG32(env->fpr[(n - 32) / 2].l.lower);
-        } else {
-            GET_REG32(env->fpr[(n - 32) / 2].l.upper);
-        }
-    }
-    if (n < 80) {
-        /* f32-f62 (double width, even numbers only) */
-        GET_REG64(env->fpr[(n - 32) / 2].ll);
-    }
-    switch (n) {
-    case 80: GET_REGL(env->pc);
-    case 81: GET_REGL(env->npc);
-    case 82: GET_REGL((cpu_get_ccr(env) << 32) |
-                      ((env->asi & 0xff) << 24) |
-                      ((env->pstate & 0xfff) << 8) |
-                      cpu_get_cwp64(env));
-    case 83: GET_REGL(env->fsr);
-    case 84: GET_REGL(env->fprs);
-    case 85: GET_REGL(env->y);
-    }
-#endif
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
-{
-#if defined(TARGET_ABI32)
-    abi_ulong tmp;
-
-    tmp = ldl_p(mem_buf);
-#else
-    target_ulong tmp;
-
-    tmp = ldtul_p(mem_buf);
-#endif
-
-    if (n < 8) {
-        /* g0..g7 */
-        env->gregs[n] = tmp;
-    } else if (n < 32) {
-        /* register window */
-        env->regwptr[n - 8] = tmp;
-    }
-#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
-    else if (n < 64) {
-        /* fprs */
-        /* f0-f31 */
-        if (n & 1) {
-            env->fpr[(n - 32) / 2].l.lower = tmp;
-        } else {
-            env->fpr[(n - 32) / 2].l.upper = tmp;
-        }
-    } else {
-        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-        switch (n) {
-        case 64: env->y = tmp; break;
-        case 65: cpu_put_psr(env, tmp); break;
-        case 66: env->wim = tmp; break;
-        case 67: env->tbr = tmp; break;
-        case 68: env->pc = tmp; break;
-        case 69: env->npc = tmp; break;
-        case 70: env->fsr = tmp; break;
-        default: return 0;
-        }
-    }
-    return 4;
-#else
-    else if (n < 64) {
-        /* f0-f31 */
-        tmp = ldl_p(mem_buf);
-        if (n & 1) {
-            env->fpr[(n - 32) / 2].l.lower = tmp;
-        } else {
-            env->fpr[(n - 32) / 2].l.upper = tmp;
-        }
-        return 4;
-    } else if (n < 80) {
-        /* f32-f62 (double width, even numbers only) */
-        env->fpr[(n - 32) / 2].ll = tmp;
-    } else {
-        switch (n) {
-        case 80: env->pc = tmp; break;
-        case 81: env->npc = tmp; break;
-        case 82:
-            cpu_put_ccr(env, tmp >> 32);
-	    env->asi = (tmp >> 24) & 0xff;
-	    env->pstate = (tmp >> 8) & 0xfff;
-            cpu_put_cwp64(env, tmp & 0xff);
-	    break;
-        case 83: env->fsr = tmp; break;
-        case 84: env->fprs = tmp; break;
-        case 85: env->y = tmp; break;
-        default: return 0;
-        }
-    }
-    return 8;
-#endif
-}
 #elif defined (TARGET_ARM)
 
-/* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
-   whatever the target description contains.  Due to a historical mishap
-   the FPA registers appear in between core integer regs and the CPSR.
-   We hack round this by giving the FPA regs zero size when talking to a
-   newer gdb.  */
 #define GDB_CORE_XML "arm-core.xml"
 
-static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 16) {
-        /* Core integer register.  */
-        GET_REG32(env->regs[n]);
-    }
-    if (n < 24) {
-        /* FPA registers.  */
-        if (gdb_has_xml)
-            return 0;
-        memset(mem_buf, 0, 12);
-        return 12;
-    }
-    switch (n) {
-    case 24:
-        /* FPA status register.  */
-        if (gdb_has_xml)
-            return 0;
-        GET_REG32(0);
-    case 25:
-        /* CPSR */
-        GET_REG32(cpsr_read(env));
-    }
-    /* Unknown register.  */
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    tmp = ldl_p(mem_buf);
-
-    /* Mask out low bit of PC to workaround gdb bugs.  This will probably
-       cause problems if we ever implement the Jazelle DBX extensions.  */
-    if (n == 15)
-        tmp &= ~1;
-
-    if (n < 16) {
-        /* Core integer register.  */
-        env->regs[n] = tmp;
-        return 4;
-    }
-    if (n < 24) { /* 16-23 */
-        /* FPA registers (ignored).  */
-        if (gdb_has_xml)
-            return 0;
-        return 12;
-    }
-    switch (n) {
-    case 24:
-        /* FPA status register (ignored).  */
-        if (gdb_has_xml)
-            return 0;
-        return 4;
-    case 25:
-        /* CPSR */
-        cpsr_write (env, tmp, 0xffffffff);
-        return 4;
-    }
-    /* Unknown register.  */
-    return 0;
-}
-
 #elif defined (TARGET_M68K)
 
 #define GDB_CORE_XML "cf-core.xml"
 
-static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 8) {
-        /* D0-D7 */
-        GET_REG32(env->dregs[n]);
-    } else if (n < 16) {
-        /* A0-A7 */
-        GET_REG32(env->aregs[n - 8]);
-    } else {
-	switch (n) {
-        case 16: GET_REG32(env->sr);
-        case 17: GET_REG32(env->pc);
-        }
-    }
-    /* FP registers not included here because they vary between
-       ColdFire and m68k.  Use XML bits for these.  */
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 8) {
-        /* D0-D7 */
-        env->dregs[n] = tmp;
-    } else if (n < 16) {
-        /* A0-A7 */
-        env->aregs[n - 8] = tmp;
-    } else {
-        switch (n) {
-        case 16: env->sr = tmp; break;
-        case 17: env->pc = tmp; break;
-        default: return 0;
-        }
-    }
-    return 4;
-}
-#elif defined (TARGET_MIPS)
-
-static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REGL(env->active_tc.gpr[n]);
-    }
-    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
-        if (n >= 38 && n < 70) {
-            if (env->CP0_Status & (1 << CP0St_FR))
-		GET_REGL(env->active_fpu.fpr[n - 38].d);
-            else
-		GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
-        }
-        switch (n) {
-        case 70: GET_REGL((int32_t)env->active_fpu.fcr31);
-        case 71: GET_REGL((int32_t)env->active_fpu.fcr0);
-        }
-    }
-    switch (n) {
-    case 32: GET_REGL((int32_t)env->CP0_Status);
-    case 33: GET_REGL(env->active_tc.LO[0]);
-    case 34: GET_REGL(env->active_tc.HI[0]);
-    case 35: GET_REGL(env->CP0_BadVAddr);
-    case 36: GET_REGL((int32_t)env->CP0_Cause);
-    case 37: GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16));
-    case 72: GET_REGL(0); /* fp */
-    case 89: GET_REGL((int32_t)env->CP0_PRid);
-    }
-    if (n >= 73 && n <= 88) {
-	/* 16 embedded regs.  */
-	GET_REGL(0);
-    }
-
-    return 0;
-}
-
-/* convert MIPS rounding mode in FCR31 to IEEE library */
-static unsigned int ieee_rm[] =
-  {
-    float_round_nearest_even,
-    float_round_to_zero,
-    float_round_up,
-    float_round_down
-  };
-#define RESTORE_ROUNDING_MODE \
-    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
-
-static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
-{
-    target_ulong tmp;
-
-    tmp = ldtul_p(mem_buf);
-
-    if (n < 32) {
-        env->active_tc.gpr[n] = tmp;
-        return sizeof(target_ulong);
-    }
-    if (env->CP0_Config1 & (1 << CP0C1_FP)
-            && n >= 38 && n < 73) {
-        if (n < 70) {
-            if (env->CP0_Status & (1 << CP0St_FR))
-              env->active_fpu.fpr[n - 38].d = tmp;
-            else
-              env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
-        }
-        switch (n) {
-        case 70:
-            env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
-            /* set rounding mode */
-            RESTORE_ROUNDING_MODE;
-            break;
-        case 71: env->active_fpu.fcr0 = tmp; break;
-        }
-        return sizeof(target_ulong);
-    }
-    switch (n) {
-    case 32: env->CP0_Status = tmp; break;
-    case 33: env->active_tc.LO[0] = tmp; break;
-    case 34: env->active_tc.HI[0] = tmp; break;
-    case 35: env->CP0_BadVAddr = tmp; break;
-    case 36: env->CP0_Cause = tmp; break;
-    case 37:
-        env->active_tc.PC = tmp & ~(target_ulong)1;
-        if (tmp & 1) {
-            env->hflags |= MIPS_HFLAG_M16;
-        } else {
-            env->hflags &= ~(MIPS_HFLAG_M16);
-        }
-        break;
-    case 72: /* fp, ignored */ break;
-    default: 
-	if (n > 89)
-	    return 0;
-	/* Other registers are readonly.  Ignore writes.  */
-	break;
-    }
-
-    return sizeof(target_ulong);
-}
-#elif defined(TARGET_OPENRISC)
-
-static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REG32(env->gpr[n]);
-    } else {
-        switch (n) {
-        case 32:    /* PPC */
-            GET_REG32(env->ppc);
-            break;
-
-        case 33:    /* NPC */
-            GET_REG32(env->npc);
-            break;
-
-        case 34:    /* SR */
-            GET_REG32(env->sr);
-            break;
-
-        default:
-            break;
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUOpenRISCState *env,
-                                  uint8_t *mem_buf, int n)
-{
-    CPUClass *cc = CPU_GET_CLASS(openrisc_env_get_cpu(env));
-    uint32_t tmp;
-
-    if (n > cc->gdb_num_core_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 32) {
-        env->gpr[n] = tmp;
-    } else {
-        switch (n) {
-        case 32: /* PPC */
-            env->ppc = tmp;
-            break;
-
-        case 33: /* NPC */
-            env->npc = tmp;
-            break;
-
-        case 34: /* SR */
-            env->sr = tmp;
-            break;
-
-        default:
-            break;
-        }
-    }
-    return 4;
-}
-#elif defined (TARGET_SH4)
-
-/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
-/* FIXME: We should use XML for this.  */
-
-static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
-{
-    switch (n) {
-    case 0 ... 7:
-        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
-            GET_REGL(env->gregs[n + 16]);
-        } else {
-            GET_REGL(env->gregs[n]);
-        }
-    case 8 ... 15:
-        GET_REGL(env->gregs[n]);
-    case 16:
-        GET_REGL(env->pc);
-    case 17:
-        GET_REGL(env->pr);
-    case 18:
-        GET_REGL(env->gbr);
-    case 19:
-        GET_REGL(env->vbr);
-    case 20:
-        GET_REGL(env->mach);
-    case 21:
-        GET_REGL(env->macl);
-    case 22:
-        GET_REGL(env->sr);
-    case 23:
-        GET_REGL(env->fpul);
-    case 24:
-        GET_REGL(env->fpscr);
-    case 25 ... 40:
-        if (env->fpscr & FPSCR_FR) {
-            stfl_p(mem_buf, env->fregs[n - 9]);
-        } else {
-            stfl_p(mem_buf, env->fregs[n - 25]);
-        }
-        return 4;
-    case 41:
-        GET_REGL(env->ssr);
-    case 42:
-        GET_REGL(env->spc);
-    case 43 ... 50:
-        GET_REGL(env->gregs[n - 43]);
-    case 51 ... 58:
-        GET_REGL(env->gregs[n - (51 - 16)]);
-    }
-
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
-{
-    switch (n) {
-    case 0 ... 7:
-        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
-            env->gregs[n + 16] = ldl_p(mem_buf);
-        } else {
-            env->gregs[n] = ldl_p(mem_buf);
-        }
-        break;
-    case 8 ... 15:
-        env->gregs[n] = ldl_p(mem_buf);
-        break;
-    case 16:
-        env->pc = ldl_p(mem_buf);
-        break;
-    case 17:
-        env->pr = ldl_p(mem_buf);
-        break;
-    case 18:
-        env->gbr = ldl_p(mem_buf);
-        break;
-    case 19:
-        env->vbr = ldl_p(mem_buf);
-        break;
-    case 20:
-        env->mach = ldl_p(mem_buf);
-        break;
-    case 21:
-        env->macl = ldl_p(mem_buf);
-        break;
-    case 22:
-        env->sr = ldl_p(mem_buf);
-        break;
-    case 23:
-        env->fpul = ldl_p(mem_buf);
-        break;
-    case 24:
-        env->fpscr = ldl_p(mem_buf);
-        break;
-    case 25 ... 40:
-        if (env->fpscr & FPSCR_FR) {
-            env->fregs[n - 9] = ldfl_p(mem_buf);
-        } else {
-            env->fregs[n - 25] = ldfl_p(mem_buf);
-        }
-        break;
-    case 41:
-        env->ssr = ldl_p(mem_buf);
-        break;
-    case 42:
-        env->spc = ldl_p(mem_buf);
-        break;
-    case 43 ... 50:
-        env->gregs[n - 43] = ldl_p(mem_buf);
-        break;
-    case 51 ... 58:
-        env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
-        break;
-    default: return 0;
-    }
-
-    return 4;
-}
-#elif defined (TARGET_MICROBLAZE)
-
-static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-	GET_REG32(env->regs[n]);
-    } else {
-	GET_REG32(env->sregs[n - 32]);
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
-{
-    CPUClass *cc = CPU_GET_CLASS(mb_env_get_cpu(env));
-    uint32_t tmp;
-
-    if (n > cc->gdb_num_core_regs) {
-	return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 32) {
-	env->regs[n] = tmp;
-    } else {
-	env->sregs[n - 32] = tmp;
-    }
-    return 4;
-}
-#elif defined (TARGET_CRIS)
-
-static int
-read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 15) {
-        GET_REG32(env->regs[n]);
-    }
-
-    if (n == 15) {
-        GET_REG32(env->pc);
-    }
-
-    if (n < 32) {
-        switch (n) {
-        case 16:
-            GET_REG8(env->pregs[n - 16]);
-            break;
-        case 17:
-            GET_REG8(env->pregs[n - 16]);
-            break;
-        case 20:
-        case 21:
-            GET_REG16(env->pregs[n - 16]);
-            break;
-        default:
-            if (n >= 23) {
-                GET_REG32(env->pregs[n - 16]);
-            }
-            break;
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n)
-{
-    uint8_t srs;
-
-    if (env->pregs[PR_VR] < 32)
-        return read_register_crisv10(env, mem_buf, n);
-
-    srs = env->pregs[PR_SRS];
-    if (n < 16) {
-	GET_REG32(env->regs[n]);
-    }
-
-    if (n >= 21 && n < 32) {
-	GET_REG32(env->pregs[n - 16]);
-    }
-    if (n >= 33 && n < 49) {
-	GET_REG32(env->sregs[srs][n - 33]);
-    }
-    switch (n) {
-    case 16: GET_REG8(env->pregs[0]);
-    case 17: GET_REG8(env->pregs[1]);
-    case 18: GET_REG32(env->pregs[2]);
-    case 19: GET_REG8(srs);
-    case 20: GET_REG16(env->pregs[4]);
-    case 32: GET_REG32(env->pc);
-    }
-
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    if (n > 49)
-	return 0;
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 16) {
-	env->regs[n] = tmp;
-    }
-
-    if (n >= 21 && n < 32) {
-	env->pregs[n - 16] = tmp;
-    }
-
-    /* FIXME: Should support function regs be writable?  */
-    switch (n) {
-    case 16: return 1;
-    case 17: return 1;
-    case 18: env->pregs[PR_PID] = tmp; break;
-    case 19: return 1;
-    case 20: return 2;
-    case 32: env->pc = tmp; break;
-    }
-
-    return 4;
-}
-#elif defined (TARGET_ALPHA)
-
-static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
-{
-    uint64_t val;
-    CPU_DoubleU d;
-
-    switch (n) {
-    case 0 ... 30:
-        val = env->ir[n];
-        break;
-    case 32 ... 62:
-        d.d = env->fir[n - 32];
-        val = d.ll;
-        break;
-    case 63:
-        val = cpu_alpha_load_fpcr(env);
-        break;
-    case 64:
-        val = env->pc;
-        break;
-    case 66:
-        val = env->unique;
-        break;
-    case 31:
-    case 65:
-        /* 31 really is the zero register; 65 is unassigned in the
-           gdb protocol, but is still required to occupy 8 bytes. */
-        val = 0;
-        break;
-    default:
-        return 0;
-    }
-    GET_REGL(val);
-}
-
-static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
-{
-    target_ulong tmp = ldtul_p(mem_buf);
-    CPU_DoubleU d;
-
-    switch (n) {
-    case 0 ... 30:
-        env->ir[n] = tmp;
-        break;
-    case 32 ... 62:
-        d.ll = tmp;
-        env->fir[n - 32] = d.d;
-        break;
-    case 63:
-        cpu_alpha_store_fpcr(env, tmp);
-        break;
-    case 64:
-        env->pc = tmp;
-        break;
-    case 66:
-        env->unique = tmp;
-        break;
-    case 31:
-    case 65:
-        /* 31 really is the zero register; 65 is unassigned in the
-           gdb protocol, but is still required to occupy 8 bytes. */
-        break;
-    default:
-        return 0;
-    }
-    return 8;
-}
-#elif defined (TARGET_S390X)
-
-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:
-        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;
-}
-
-static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
-{
-    target_ulong tmpl;
-    uint32_t tmp32;
-    int r = 8;
-    tmpl = ldtul_p(mem_buf);
-    tmp32 = ldl_p(mem_buf);
-
-    switch (n) {
-    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)
-
-#include "hw/lm32/lm32_pic.h"
-
-static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REG32(env->regs[n]);
-    } else {
-        switch (n) {
-        case 32:
-            GET_REG32(env->pc);
-            break;
-        /* FIXME: put in right exception ID */
-        case 33:
-            GET_REG32(0);
-            break;
-        case 34:
-            GET_REG32(env->eba);
-            break;
-        case 35:
-            GET_REG32(env->deba);
-            break;
-        case 36:
-            GET_REG32(env->ie);
-            break;
-        case 37:
-            GET_REG32(lm32_pic_get_im(env->pic_state));
-            break;
-        case 38:
-            GET_REG32(lm32_pic_get_ip(env->pic_state));
-            break;
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
-{
-    CPUClass *cc = CPU_GET_CLASS(lm32_env_get_cpu(env));
-    uint32_t tmp;
-
-    if (n > cc->gdb_num_core_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 32) {
-        env->regs[n] = tmp;
-    } else {
-        switch (n) {
-        case 32:
-            env->pc = tmp;
-            break;
-        case 34:
-            env->eba = tmp;
-            break;
-        case 35:
-            env->deba = tmp;
-            break;
-        case 36:
-            env->ie = tmp;
-            break;
-        case 37:
-            lm32_pic_set_im(env->pic_state, tmp);
-            break;
-        case 38:
-            lm32_pic_set_ip(env->pic_state, tmp);
-            break;
-        }
-    }
-    return 4;
-}
-#elif defined(TARGET_XTENSA)
-
-static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
-{
-    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
-    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
-
-    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
-        return 0;
-    }
-
-    switch (reg->type) {
-    case 9: /*pc*/
-        GET_REG32(env->pc);
-        break;
-
-    case 1: /*ar*/
-        xtensa_sync_phys_from_window(env);
-        GET_REG32(env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg]);
-        break;
-
-    case 2: /*SR*/
-        GET_REG32(env->sregs[reg->targno & 0xff]);
-        break;
-
-    case 3: /*UR*/
-        GET_REG32(env->uregs[reg->targno & 0xff]);
-        break;
-
-    case 4: /*f*/
-        GET_REG32(float32_val(env->fregs[reg->targno & 0x0f]));
-        break;
-
-    case 8: /*a*/
-        GET_REG32(env->regs[reg->targno & 0x0f]);
-        break;
-
-    default:
-        qemu_log("%s from reg %d of unsupported type %d\n",
-                __func__, n, reg->type);
-        return 0;
-    }
-}
-
-static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
-{
-    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
-    uint32_t tmp;
-    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
-
-    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    switch (reg->type) {
-    case 9: /*pc*/
-        env->pc = tmp;
-        break;
-
-    case 1: /*ar*/
-        env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg] = tmp;
-        xtensa_sync_window_from_phys(env);
-        break;
-
-    case 2: /*SR*/
-        env->sregs[reg->targno & 0xff] = tmp;
-        break;
-
-    case 3: /*UR*/
-        env->uregs[reg->targno & 0xff] = tmp;
-        break;
-
-    case 4: /*f*/
-        env->fregs[reg->targno & 0x0f] = make_float32(tmp);
-        break;
-
-    case 8: /*a*/
-        env->regs[reg->targno & 0x0f] = tmp;
-        break;
-
-    default:
-        qemu_log("%s to reg %d of unsupported type %d\n",
-                __func__, n, reg->type);
-        return 0;
-    }
-
-    return 4;
-}
-#else
-
-static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
-{
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
-{
-    return 0;
-}
-
 #endif
 
 #ifdef GDB_CORE_XML
@@ -1839,7 +579,7 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     GDBRegisterState *r;
 
     if (reg < cc->gdb_num_core_regs) {
-        return cpu_gdb_read_register(env, mem_buf, reg);
+        return cc->gdb_read_register(cpu, mem_buf, reg);
     }
 
     for (r = cpu->gdb_regs; r; r = r->next) {
@@ -1857,7 +597,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     GDBRegisterState *r;
 
     if (reg < cc->gdb_num_core_regs) {
-        return cpu_gdb_write_register(env, mem_buf, reg);
+        return cc->gdb_write_register(cpu, mem_buf, reg);
     }
 
     for (r = cpu->gdb_regs; r; r = r->next) {
@@ -2398,7 +1138,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             const char *xml;
             target_ulong total_len;
 
-            gdb_has_xml = 1;
+            gdb_has_xml = true;
             p += 19;
             xml = get_feature_xml(p, &p);
             if (!xml) {
@@ -2807,7 +1547,7 @@ static void gdb_accept(void)
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
     s->fd = fd;
-    gdb_has_xml = 0;
+    gdb_has_xml = false;
 
     gdbserver_state = s;
 
@@ -2893,7 +1633,7 @@ static void gdb_chr_event(void *opaque, int event)
     switch (event) {
     case CHR_EVENT_OPENED:
         vm_stop(RUN_STATE_PAUSED);
-        gdb_has_xml = 0;
+        gdb_has_xml = false;
         break;
     default:
         break;
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 1bd00ae..4d580f0 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -39,6 +39,43 @@ static inline int cpu_index(CPUState *cpu)
 #endif
 }
 
+/* The GDB remote protocol transfers values in target byte order.  This means
+ * we can use the raw memory access routines to access the value buffer.
+ * Conveniently, these also handle the case where the buffer is mis-aligned.
+ */
+
+static inline int gdb_get_reg8(uint8_t *mem_buf, uint8_t val)
+{
+    stb_p(mem_buf, val);
+    return 1;
+}
+
+static inline int gdb_get_reg16(uint8_t *mem_buf, uint16_t val)
+{
+    stw_p(mem_buf, val);
+    return 2;
+}
+
+static inline int gdb_get_reg32(uint8_t *mem_buf, uint32_t val)
+{
+    stl_p(mem_buf, val);
+    return 4;
+}
+
+static inline int gdb_get_reg64(uint8_t *mem_buf, uint64_t val)
+{
+    stq_p(mem_buf, val);
+    return 8;
+}
+
+#if TARGET_LONG_BITS == 64
+#define gdb_get_regl(buf, val) gdb_get_reg64(buf, val)
+#define ldtul_p(addr) ldq_p(addr)
+#else
+#define gdb_get_regl(buf, val) gdb_get_reg32(buf, val)
+#define ldtul_p(addr) ldl_p(addr)
+#endif
+
 #endif
 
 #ifdef CONFIG_USER_ONLY
@@ -47,6 +84,8 @@ int gdbserver_start(int);
 int gdbserver_start(const char *port);
 #endif
 
+extern bool gdb_has_xml;
+
 /* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */
 extern const char *const xml_builtin[][2];
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index f89c49e..a422815 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -62,6 +62,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
  * @get_phys_page_debug: Callback for obtaining a physical address.
+ * @gdb_read_register: Callback for letting GDB read a register.
+ * @gdb_write_register: Callback for letting GDB write a register.
  * @vmsd: State description for migration.
  *
  * Represents a CPU family or model.
@@ -90,6 +92,8 @@ typedef struct CPUClass {
     void (*set_pc)(CPUState *cpu, uint64_t value);
     void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
     hwaddr (*get_phys_page_debug)(CPUState *cpu, uint64_t addr);
+    int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
+    int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
 
     const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
diff --git a/qom/cpu.c b/qom/cpu.c
index 2839ddf..dbc9fb6 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -157,6 +157,17 @@ static int cpu_common_write_elf64_note(WriteCoreDumpFunction f,
 }
 
 
+static int cpu_common_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg)
+{
+    return 0;
+}
+
+static int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg)
+{
+    return 0;
+}
+
+
 void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
@@ -253,6 +264,8 @@ static void cpu_class_init(ObjectClass *klass, void *data)
     k->write_elf32_note = cpu_common_write_elf32_note;
     k->write_elf64_qemunote = cpu_common_write_elf64_qemunote;
     k->write_elf64_note = cpu_common_write_elf64_note;
+    k->gdb_read_register = cpu_common_gdb_read_register;
+    k->gdb_write_register = cpu_common_gdb_write_register;
     dc->realize = cpu_common_realizefn;
     dc->no_user = 1;
 }
diff --git a/target-alpha/Makefile.objs b/target-alpha/Makefile.objs
index 590304c..b96c5da 100644
--- a/target-alpha/Makefile.objs
+++ b/target-alpha/Makefile.objs
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += translate.o helper.o cpu.o
 obj-y += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
+obj-y += gdbstub.o
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 50cccca..8922207 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -82,5 +82,7 @@ void alpha_cpu_do_interrupt(CPUState *cpu);
 void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                           int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 028cec1..14dadae 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -271,6 +271,8 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
     cc->set_pc = alpha_cpu_set_pc;
+    cc->gdb_read_register = alpha_cpu_gdb_read_register;
+    cc->gdb_write_register = alpha_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->do_unassigned_access = alpha_cpu_unassigned_access;
     cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
diff --git a/target-alpha/gdbstub.c b/target-alpha/gdbstub.c
new file mode 100644
index 0000000..980f140
--- /dev/null
+++ b/target-alpha/gdbstub.c
@@ -0,0 +1,93 @@
+/*
+ * Alpha gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int alpha_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+    CPUAlphaState *env = &cpu->env;
+    uint64_t val;
+    CPU_DoubleU d;
+
+    switch (n) {
+    case 0 ... 30:
+        val = env->ir[n];
+        break;
+    case 32 ... 62:
+        d.d = env->fir[n - 32];
+        val = d.ll;
+        break;
+    case 63:
+        val = cpu_alpha_load_fpcr(env);
+        break;
+    case 64:
+        val = env->pc;
+        break;
+    case 66:
+        val = env->unique;
+        break;
+    case 31:
+    case 65:
+        /* 31 really is the zero register; 65 is unassigned in the
+           gdb protocol, but is still required to occupy 8 bytes. */
+        val = 0;
+        break;
+    default:
+        return 0;
+    }
+    return gdb_get_regl(mem_buf, val);
+}
+
+int alpha_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+    CPUAlphaState *env = &cpu->env;
+    target_ulong tmp = ldtul_p(mem_buf);
+    CPU_DoubleU d;
+
+    switch (n) {
+    case 0 ... 30:
+        env->ir[n] = tmp;
+        break;
+    case 32 ... 62:
+        d.ll = tmp;
+        env->fir[n - 32] = d.d;
+        break;
+    case 63:
+        cpu_alpha_store_fpcr(env, tmp);
+        break;
+    case 64:
+        env->pc = tmp;
+        break;
+    case 66:
+        env->unique = tmp;
+        break;
+    case 31:
+    case 65:
+        /* 31 really is the zero register; 65 is unassigned in the
+           gdb protocol, but is still required to occupy 8 bytes. */
+        break;
+    default:
+        return 0;
+    }
+    return 8;
+}
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 4a6e52e..2d9f77f 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -4,3 +4,4 @@ obj-$(CONFIG_KVM) += kvm.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += neon_helper.o iwmmxt_helper.o
+obj-y += gdbstub.o
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index c6d54c2..f542531 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -149,4 +149,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
 hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
+int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
 #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index e04bcc3..44290fa 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -819,6 +819,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = arm_cpu_do_interrupt;
     cc->dump_state = arm_cpu_dump_state;
     cc->set_pc = arm_cpu_set_pc;
+    cc->gdb_read_register = arm_cpu_gdb_read_register;
+    cc->gdb_write_register = arm_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_arm_cpu;
diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c
new file mode 100644
index 0000000..1c34396
--- /dev/null
+++ b/target-arm/gdbstub.c
@@ -0,0 +1,102 @@
+/*
+ * ARM gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+/* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
+   whatever the target description contains.  Due to a historical mishap
+   the FPA registers appear in between core integer regs and the CPSR.
+   We hack round this by giving the FPA regs zero size when talking to a
+   newer gdb.  */
+
+int arm_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+
+    if (n < 16) {
+        /* Core integer register.  */
+        return gdb_get_reg32(mem_buf, env->regs[n]);
+    }
+    if (n < 24) {
+        /* FPA registers.  */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        memset(mem_buf, 0, 12);
+        return 12;
+    }
+    switch (n) {
+    case 24:
+        /* FPA status register.  */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        return gdb_get_reg32(mem_buf, 0);
+    case 25:
+        /* CPSR */
+        return gdb_get_reg32(mem_buf, cpsr_read(env));
+    }
+    /* Unknown register.  */
+    return 0;
+}
+
+int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    uint32_t tmp;
+
+    tmp = ldl_p(mem_buf);
+
+    /* Mask out low bit of PC to workaround gdb bugs.  This will probably
+       cause problems if we ever implement the Jazelle DBX extensions.  */
+    if (n == 15) {
+        tmp &= ~1;
+    }
+
+    if (n < 16) {
+        /* Core integer register.  */
+        env->regs[n] = tmp;
+        return 4;
+    }
+    if (n < 24) { /* 16-23 */
+        /* FPA registers (ignored).  */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        return 12;
+    }
+    switch (n) {
+    case 24:
+        /* FPA status register (ignored).  */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        return 4;
+    case 25:
+        /* CPSR */
+        cpsr_write(env, tmp, 0xffffffff);
+        return 4;
+    }
+    /* Unknown register.  */
+    return 0;
+}
diff --git a/target-cris/Makefile.objs b/target-cris/Makefile.objs
index afb87bc..7779227 100644
--- a/target-cris/Makefile.objs
+++ b/target-cris/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index cd19070..b81a708 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -81,4 +81,8 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
 hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
+int crisv10_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
 #endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 426a321..dd67f14 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -175,6 +175,7 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 8;
     cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->gdb_read_register = crisv10_cpu_gdb_read_register;
 }
 
 static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
@@ -184,6 +185,7 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 9;
     cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->gdb_read_register = crisv10_cpu_gdb_read_register;
 }
 
 static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
@@ -193,6 +195,7 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 10;
     cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->gdb_read_register = crisv10_cpu_gdb_read_register;
 }
 
 static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
@@ -202,6 +205,7 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->vr = 11;
     cc->do_interrupt = crisv10_cpu_do_interrupt;
+    cc->gdb_read_register = crisv10_cpu_gdb_read_register;
 }
 
 static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
@@ -255,6 +259,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = cris_cpu_do_interrupt;
     cc->dump_state = cris_cpu_dump_state;
     cc->set_pc = cris_cpu_set_pc;
+    cc->gdb_read_register = cris_cpu_gdb_read_register;
+    cc->gdb_write_register = cris_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
 #endif
diff --git a/target-cris/gdbstub.c b/target-cris/gdbstub.c
new file mode 100644
index 0000000..55ec994
--- /dev/null
+++ b/target-cris/gdbstub.c
@@ -0,0 +1,130 @@
+/*
+ * CRIS gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int crisv10_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
+
+    if (n < 15) {
+        return gdb_get_reg32(mem_buf, env->regs[n]);
+    }
+
+    if (n == 15) {
+        return gdb_get_reg32(mem_buf, env->pc);
+    }
+
+    if (n < 32) {
+        switch (n) {
+        case 16:
+        case 17:
+            return gdb_get_reg8(mem_buf, env->pregs[n - 16]);
+        case 20:
+        case 21:
+            return gdb_get_reg16(mem_buf, env->pregs[n - 16]);
+            break;
+        default:
+            if (n >= 23) {
+                return gdb_get_reg32(mem_buf, env->pregs[n - 16]);
+            }
+            break;
+        }
+    }
+    return 0;
+}
+
+int cris_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
+    uint8_t srs;
+
+    srs = env->pregs[PR_SRS];
+    if (n < 16) {
+        return gdb_get_reg32(mem_buf, env->regs[n]);
+    }
+
+    if (n >= 21 && n < 32) {
+        return gdb_get_reg32(mem_buf, env->pregs[n - 16]);
+    }
+    if (n >= 33 && n < 49) {
+        return gdb_get_reg32(mem_buf, env->sregs[srs][n - 33]);
+    }
+    switch (n) {
+    case 16:
+        return gdb_get_reg8(mem_buf, env->pregs[0]);
+    case 17:
+        return gdb_get_reg8(mem_buf, env->pregs[1]);
+    case 18:
+        return gdb_get_reg32(mem_buf, env->pregs[2]);
+    case 19:
+        return gdb_get_reg8(mem_buf, srs);
+    case 20:
+        return gdb_get_reg16(mem_buf, env->pregs[4]);
+    case 32:
+        return gdb_get_reg32(mem_buf, env->pc);
+    }
+
+    return 0;
+}
+
+int cris_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
+    uint32_t tmp;
+
+    if (n > 49) {
+        return 0;
+    }
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 16) {
+        env->regs[n] = tmp;
+    }
+
+    if (n >= 21 && n < 32) {
+        env->pregs[n - 16] = tmp;
+    }
+
+    /* FIXME: Should support function regs be writable?  */
+    switch (n) {
+    case 16:
+        return 1;
+    case 17:
+        return 1;
+    case 18:
+        env->pregs[PR_PID] = tmp;
+        break;
+    case 19:
+        return 1;
+    case 20:
+        return 2;
+    case 32:
+        env->pc = tmp;
+        break;
+    }
+
+    return 4;
+}
diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index c1d4f05..3b629d4d 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -1,6 +1,7 @@
 obj-y += translate.o helper.o cpu.o
 obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
 obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
+obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
 obj-$(CONFIG_KVM) += kvm.o hyperv.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index b762d06..59f04b2 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -106,4 +106,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
 hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
 
+int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 7c6f1d3..549b058 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2538,6 +2538,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->dump_state = x86_cpu_dump_state;
     cc->set_pc = x86_cpu_set_pc;
     cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
+    cc->gdb_read_register = x86_cpu_gdb_read_register;
+    cc->gdb_write_register = x86_cpu_gdb_write_register;
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
diff --git a/target-i386/gdbstub.c b/target-i386/gdbstub.c
new file mode 100644
index 0000000..a76cf6d
--- /dev/null
+++ b/target-i386/gdbstub.c
@@ -0,0 +1,231 @@
+/*
+ * x86 gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+#ifdef TARGET_X86_64
+static const int gpr_map[16] = {
+    R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP,
+    8, 9, 10, 11, 12, 13, 14, 15
+};
+#else
+#define gpr_map gpr_map32
+#endif
+static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+#define IDX_IP_REG      CPU_NB_REGS
+#define IDX_FLAGS_REG   (IDX_IP_REG + 1)
+#define IDX_SEG_REGS    (IDX_FLAGS_REG + 1)
+#define IDX_FP_REGS     (IDX_SEG_REGS + 6)
+#define IDX_XMM_REGS    (IDX_FP_REGS + 16)
+#define IDX_MXCSR_REG   (IDX_XMM_REGS + CPU_NB_REGS)
+
+int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    if (n < CPU_NB_REGS) {
+        if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
+            return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]);
+        } else if (n < CPU_NB_REGS32) {
+            return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
+        }
+    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
+#ifdef USE_X86LDOUBLE
+        /* FIXME: byteswap float values - after fixing fpregs layout. */
+        memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10);
+#else
+        memset(mem_buf, 0, 10);
+#endif
+        return 10;
+    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
+        n -= IDX_XMM_REGS;
+        if (n < CPU_NB_REGS32 ||
+            (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) {
+            stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0));
+            stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1));
+            return 16;
+        }
+    } else {
+        switch (n) {
+        case IDX_IP_REG:
+            if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
+                return gdb_get_reg64(mem_buf, env->eip);
+            } else {
+                return gdb_get_reg32(mem_buf, env->eip);
+            }
+        case IDX_FLAGS_REG:
+            return gdb_get_reg32(mem_buf, env->eflags);
+
+        case IDX_SEG_REGS:
+            return gdb_get_reg32(mem_buf, env->segs[R_CS].selector);
+        case IDX_SEG_REGS + 1:
+            return gdb_get_reg32(mem_buf, env->segs[R_SS].selector);
+        case IDX_SEG_REGS + 2:
+            return gdb_get_reg32(mem_buf, env->segs[R_DS].selector);
+        case IDX_SEG_REGS + 3:
+            return gdb_get_reg32(mem_buf, env->segs[R_ES].selector);
+        case IDX_SEG_REGS + 4:
+            return gdb_get_reg32(mem_buf, env->segs[R_FS].selector);
+        case IDX_SEG_REGS + 5:
+            return gdb_get_reg32(mem_buf, env->segs[R_GS].selector);
+
+        case IDX_FP_REGS + 8:
+            return gdb_get_reg32(mem_buf, env->fpuc);
+        case IDX_FP_REGS + 9:
+            return gdb_get_reg32(mem_buf, (env->fpus & ~0x3800) |
+                                 (env->fpstt & 0x7) << 11);
+        case IDX_FP_REGS + 10:
+            return gdb_get_reg32(mem_buf, 0); /* ftag */
+        case IDX_FP_REGS + 11:
+            return gdb_get_reg32(mem_buf, 0); /* fiseg */
+        case IDX_FP_REGS + 12:
+            return gdb_get_reg32(mem_buf, 0); /* fioff */
+        case IDX_FP_REGS + 13:
+            return gdb_get_reg32(mem_buf, 0); /* foseg */
+        case IDX_FP_REGS + 14:
+            return gdb_get_reg32(mem_buf, 0); /* fooff */
+        case IDX_FP_REGS + 15:
+            return gdb_get_reg32(mem_buf, 0); /* fop */
+
+        case IDX_MXCSR_REG:
+            return gdb_get_reg32(mem_buf, env->mxcsr);
+        }
+    }
+    return 0;
+}
+
+static int x86_cpu_gdb_load_seg(X86CPU *cpu, int sreg, uint8_t *mem_buf)
+{
+    CPUX86State *env = &cpu->env;
+    uint16_t selector = ldl_p(mem_buf);
+
+    if (selector != env->segs[sreg].selector) {
+#if defined(CONFIG_USER_ONLY)
+        cpu_x86_load_seg(env, sreg, selector);
+#else
+        unsigned int limit, flags;
+        target_ulong base;
+
+        if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
+            base = selector << 4;
+            limit = 0xffff;
+            flags = 0;
+        } else {
+            if (!cpu_x86_get_descr_debug(env, selector, &base, &limit,
+                                         &flags)) {
+                return 4;
+            }
+        }
+        cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags);
+#endif
+    }
+    return 4;
+}
+
+int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+    uint32_t tmp;
+
+    if (n < CPU_NB_REGS) {
+        if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
+            env->regs[gpr_map[n]] = ldtul_p(mem_buf);
+            return sizeof(target_ulong);
+        } else if (n < CPU_NB_REGS32) {
+            n = gpr_map32[n];
+            env->regs[n] &= ~0xffffffffUL;
+            env->regs[n] |= (uint32_t)ldl_p(mem_buf);
+            return 4;
+        }
+    } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
+#ifdef USE_X86LDOUBLE
+        /* FIXME: byteswap float values - after fixing fpregs layout. */
+        memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10);
+#endif
+        return 10;
+    } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
+        n -= IDX_XMM_REGS;
+        if (n < CPU_NB_REGS32 ||
+            (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) {
+            env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf);
+            env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8);
+            return 16;
+        }
+    } else {
+        switch (n) {
+        case IDX_IP_REG:
+            if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) {
+                env->eip = ldq_p(mem_buf);
+                return 8;
+            } else {
+                env->eip &= ~0xffffffffUL;
+                env->eip |= (uint32_t)ldl_p(mem_buf);
+                return 4;
+            }
+        case IDX_FLAGS_REG:
+            env->eflags = ldl_p(mem_buf);
+            return 4;
+
+        case IDX_SEG_REGS:
+            return x86_cpu_gdb_load_seg(cpu, R_CS, mem_buf);
+        case IDX_SEG_REGS + 1:
+            return x86_cpu_gdb_load_seg(cpu, R_SS, mem_buf);
+        case IDX_SEG_REGS + 2:
+            return x86_cpu_gdb_load_seg(cpu, R_DS, mem_buf);
+        case IDX_SEG_REGS + 3:
+            return x86_cpu_gdb_load_seg(cpu, R_ES, mem_buf);
+        case IDX_SEG_REGS + 4:
+            return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf);
+        case IDX_SEG_REGS + 5:
+            return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf);
+
+        case IDX_FP_REGS + 8:
+            env->fpuc = ldl_p(mem_buf);
+            return 4;
+        case IDX_FP_REGS + 9:
+            tmp = ldl_p(mem_buf);
+            env->fpstt = (tmp >> 11) & 7;
+            env->fpus = tmp & ~0x3800;
+            return 4;
+        case IDX_FP_REGS + 10: /* ftag */
+            return 4;
+        case IDX_FP_REGS + 11: /* fiseg */
+            return 4;
+        case IDX_FP_REGS + 12: /* fioff */
+            return 4;
+        case IDX_FP_REGS + 13: /* foseg */
+            return 4;
+        case IDX_FP_REGS + 14: /* fooff */
+            return 4;
+        case IDX_FP_REGS + 15: /* fop */
+            return 4;
+
+        case IDX_MXCSR_REG:
+            env->mxcsr = ldl_p(mem_buf);
+            return 4;
+        }
+    }
+    /* Unrecognised register.  */
+    return 0;
+}
diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs
index ca20f21..4023687 100644
--- a/target-lm32/Makefile.objs
+++ b/target-lm32/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index 5c4810f..b568cf9 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -79,5 +79,7 @@ void lm32_cpu_do_interrupt(CPUState *cpu);
 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int lm32_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index ec5f0e0..ea13dc6 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -87,6 +87,8 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = lm32_cpu_do_interrupt;
     cc->dump_state = lm32_cpu_dump_state;
     cc->set_pc = lm32_cpu_set_pc;
+    cc->gdb_read_register = lm32_cpu_gdb_read_register;
+    cc->gdb_write_register = lm32_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_lm32_cpu;
diff --git a/target-lm32/gdbstub.c b/target-lm32/gdbstub.c
new file mode 100644
index 0000000..4979a98
--- /dev/null
+++ b/target-lm32/gdbstub.c
@@ -0,0 +1,92 @@
+/*
+ * LM32 gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+#include "hw/lm32/lm32_pic.h"
+
+int lm32_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    LM32CPU *cpu = LM32_CPU(cs);
+    CPULM32State *env = &cpu->env;
+
+    if (n < 32) {
+        return gdb_get_reg32(mem_buf, env->regs[n]);
+    } else {
+        switch (n) {
+        case 32:
+            return gdb_get_reg32(mem_buf, env->pc);
+        /* FIXME: put in right exception ID */
+        case 33:
+            return gdb_get_reg32(mem_buf, 0);
+        case 34:
+            return gdb_get_reg32(mem_buf, env->eba);
+        case 35:
+            return gdb_get_reg32(mem_buf, env->deba);
+        case 36:
+            return gdb_get_reg32(mem_buf, env->ie);
+        case 37:
+            return gdb_get_reg32(mem_buf, lm32_pic_get_im(env->pic_state));
+        case 38:
+            return gdb_get_reg32(mem_buf, lm32_pic_get_ip(env->pic_state));
+        }
+    }
+    return 0;
+}
+
+int lm32_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    LM32CPU *cpu = LM32_CPU(cs);
+    CPUClass *cc = CPU_GET_CLASS(cs);
+    CPULM32State *env = &cpu->env;
+    uint32_t tmp;
+
+    if (n > cc->gdb_num_core_regs) {
+        return 0;
+    }
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 32) {
+        env->regs[n] = tmp;
+    } else {
+        switch (n) {
+        case 32:
+            env->pc = tmp;
+            break;
+        case 34:
+            env->eba = tmp;
+            break;
+        case 35:
+            env->deba = tmp;
+            break;
+        case 36:
+            env->ie = tmp;
+            break;
+        case 37:
+            lm32_pic_set_im(env->pic_state, tmp);
+            break;
+        case 38:
+            lm32_pic_set_ip(env->pic_state, tmp);
+            break;
+        }
+    }
+    return 4;
+}
diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs
index 2e2b850..02cf616 100644
--- a/target-m68k/Makefile.objs
+++ b/target-m68k/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += m68k-semi.o
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += gdbstub.o
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 9ec8c35..0afd23f 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -74,5 +74,7 @@ void m68k_cpu_do_interrupt(CPUState *cpu);
 void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 35c203c..b59a4fd 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -190,6 +190,8 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     cc->do_interrupt = m68k_cpu_do_interrupt;
     cc->dump_state = m68k_cpu_dump_state;
     cc->set_pc = m68k_cpu_set_pc;
+    cc->gdb_read_register = m68k_cpu_gdb_read_register;
+    cc->gdb_write_register = m68k_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
 #endif
diff --git a/target-m68k/gdbstub.c b/target-m68k/gdbstub.c
new file mode 100644
index 0000000..ae8179c
--- /dev/null
+++ b/target-m68k/gdbstub.c
@@ -0,0 +1,75 @@
+/*
+ * m68k gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int m68k_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
+
+    if (n < 8) {
+        /* D0-D7 */
+        return gdb_get_reg32(mem_buf, env->dregs[n]);
+    } else if (n < 16) {
+        /* A0-A7 */
+        return gdb_get_reg32(mem_buf, env->aregs[n - 8]);
+    } else {
+        switch (n) {
+        case 16:
+            return gdb_get_reg32(mem_buf, env->sr);
+        case 17:
+            return gdb_get_reg32(mem_buf, env->pc);
+        }
+    }
+    /* FP registers not included here because they vary between
+       ColdFire and m68k.  Use XML bits for these.  */
+    return 0;
+}
+
+int m68k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
+    uint32_t tmp;
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 8) {
+        /* D0-D7 */
+        env->dregs[n] = tmp;
+    } else if (n < 16) {
+        /* A0-A7 */
+        env->aregs[n - 8] = tmp;
+    } else {
+        switch (n) {
+        case 16:
+            env->sr = tmp;
+            break;
+        case 17:
+            env->pc = tmp;
+            break;
+        default:
+            return 0;
+        }
+    }
+    return 4;
+}
diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs
index 985330e..f3d7b44 100644
--- a/target-microblaze/Makefile.objs
+++ b/target-microblaze/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += mmu.o
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index be05858..1ee576a 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -75,5 +75,7 @@ void mb_cpu_do_interrupt(CPUState *cs);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int mb_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index f2e538a..72bd4dc 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -141,6 +141,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = mb_cpu_do_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
+    cc->gdb_read_register = mb_cpu_gdb_read_register;
+    cc->gdb_write_register = mb_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->do_unassigned_access = mb_cpu_unassigned_access;
     cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
diff --git a/target-microblaze/gdbstub.c b/target-microblaze/gdbstub.c
new file mode 100644
index 0000000..a70e2ee
--- /dev/null
+++ b/target-microblaze/gdbstub.c
@@ -0,0 +1,56 @@
+/*
+ * MicroBlaze gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int mb_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
+
+    if (n < 32) {
+        return gdb_get_reg32(mem_buf, env->regs[n]);
+    } else {
+        return gdb_get_reg32(mem_buf, env->sregs[n - 32]);
+    }
+    return 0;
+}
+
+int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUClass *cc = CPU_GET_CLASS(cs);
+    CPUMBState *env = &cpu->env;
+    uint32_t tmp;
+
+    if (n > cc->gdb_num_core_regs) {
+        return 0;
+    }
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 32) {
+        env->regs[n] = tmp;
+    } else {
+        env->sregs[n - 32] = tmp;
+    }
+    return 4;
+}
diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs
index 119c816..0277d56 100644
--- a/target-mips/Makefile.objs
+++ b/target-mips/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
+obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 291b061..25ca9f9 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -78,5 +78,7 @@ void mips_cpu_do_interrupt(CPUState *cpu);
 void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int mips_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 17d49b8..ca66d41 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -100,6 +100,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->dump_state = mips_cpu_dump_state;
     cc->set_pc = mips_cpu_set_pc;
     cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
+    cc->gdb_read_register = mips_cpu_gdb_read_register;
+    cc->gdb_write_register = mips_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->do_unassigned_access = mips_cpu_unassigned_access;
     cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c
new file mode 100644
index 0000000..6b2bba9
--- /dev/null
+++ b/target-mips/gdbstub.c
@@ -0,0 +1,154 @@
+/*
+ * MIPS gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.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]);
+    }
+    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+        if (n >= 38 && n < 70) {
+            if (env->CP0_Status & (1 << CP0St_FR)) {
+                return gdb_get_regl(mem_buf, env->active_fpu.fpr[n - 38].d);
+            } else {
+                return gdb_get_regl(mem_buf,
+                    env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
+            }
+        }
+        switch (n) {
+        case 70:
+            return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31);
+        case 71:
+            return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0);
+        }
+    }
+    switch (n) {
+    case 32:
+        return gdb_get_regl(mem_buf, (int32_t)env->CP0_Status);
+    case 33:
+        return gdb_get_regl(mem_buf, env->active_tc.LO[0]);
+    case 34:
+        return gdb_get_regl(mem_buf, env->active_tc.HI[0]);
+    case 35:
+        return gdb_get_regl(mem_buf, env->CP0_BadVAddr);
+    case 36:
+        return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause);
+    case 37:
+        return gdb_get_regl(mem_buf, env->active_tc.PC |
+                            !!(env->hflags & MIPS_HFLAG_M16));
+    case 72:
+        return gdb_get_regl(mem_buf, 0); /* fp */
+    case 89:
+        return gdb_get_regl(mem_buf, (int32_t)env->CP0_PRid);
+    }
+    if (n >= 73 && n <= 88) {
+        /* 16 embedded regs.  */
+        return gdb_get_regl(mem_buf, 0);
+    }
+
+    return 0;
+}
+
+/* convert MIPS rounding mode in FCR31 to IEEE library */
+static unsigned int ieee_rm[] = {
+    float_round_nearest_even,
+    float_round_to_zero,
+    float_round_up,
+    float_round_down
+};
+#define RESTORE_ROUNDING_MODE \
+    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \
+                            &env->active_fpu.fp_status)
+
+int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
+    target_ulong tmp;
+
+    tmp = ldtul_p(mem_buf);
+
+    if (n < 32) {
+        env->active_tc.gpr[n] = tmp;
+        return sizeof(target_ulong);
+    }
+    if (env->CP0_Config1 & (1 << CP0C1_FP)
+            && n >= 38 && n < 73) {
+        if (n < 70) {
+            if (env->CP0_Status & (1 << CP0St_FR)) {
+                env->active_fpu.fpr[n - 38].d = tmp;
+            } else {
+                env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
+            }
+        }
+        switch (n) {
+        case 70:
+            env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
+            /* set rounding mode */
+            RESTORE_ROUNDING_MODE;
+            break;
+        case 71:
+            env->active_fpu.fcr0 = tmp;
+            break;
+        }
+        return sizeof(target_ulong);
+    }
+    switch (n) {
+    case 32:
+        env->CP0_Status = tmp;
+        break;
+    case 33:
+        env->active_tc.LO[0] = tmp;
+        break;
+    case 34:
+        env->active_tc.HI[0] = tmp;
+        break;
+    case 35:
+        env->CP0_BadVAddr = tmp;
+        break;
+    case 36:
+        env->CP0_Cause = tmp;
+        break;
+    case 37:
+        env->active_tc.PC = tmp & ~(target_ulong)1;
+        if (tmp & 1) {
+            env->hflags |= MIPS_HFLAG_M16;
+        } else {
+            env->hflags &= ~(MIPS_HFLAG_M16);
+        }
+        break;
+    case 72: /* fp, ignored */
+        break;
+    default:
+        if (n > 89) {
+            return 0;
+        }
+        /* Other registers are readonly.  Ignore writes.  */
+        break;
+    }
+
+    return sizeof(target_ulong);
+}
diff --git a/target-openrisc/Makefile.objs b/target-openrisc/Makefile.objs
index 44dc539..397d016 100644
--- a/target-openrisc/Makefile.objs
+++ b/target-openrisc/Makefile.objs
@@ -2,3 +2,4 @@ obj-$(CONFIG_SOFTMMU) += machine.o
 obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
 obj-y += exception_helper.o fpu_helper.o int_helper.o \
          interrupt_helper.o mmu_helper.o sys_helper.o
+obj-y += gdbstub.o
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index a2cd4be..7b620d9 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -152,6 +152,8 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = openrisc_cpu_do_interrupt;
     cc->dump_state = openrisc_cpu_dump_state;
     cc->set_pc = openrisc_cpu_set_pc;
+    cc->gdb_read_register = openrisc_cpu_gdb_read_register;
+    cc->gdb_write_register = openrisc_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_openrisc_cpu;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 5747655..bcd15ca 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -350,6 +350,8 @@ void openrisc_cpu_do_interrupt(CPUState *cpu);
 void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void openrisc_translate_init(void);
 int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                   target_ulong address,
diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c
new file mode 100644
index 0000000..78874df
--- /dev/null
+++ b/target-openrisc/gdbstub.c
@@ -0,0 +1,86 @@
+/*
+ * OpenRISC gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+    CPUOpenRISCState *env = &cpu->env;
+
+    if (n < 32) {
+        return gdb_get_reg32(mem_buf, env->gpr[n]);
+    } else {
+        switch (n) {
+        case 32:    /* PPC */
+            return gdb_get_reg32(mem_buf, env->ppc);
+            break;
+
+        case 33:    /* NPC */
+            return gdb_get_reg32(mem_buf, env->npc);
+            break;
+
+        case 34:    /* SR */
+            return gdb_get_reg32(mem_buf, env->sr);
+            break;
+
+        default:
+            break;
+        }
+    }
+    return 0;
+}
+
+int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+    CPUClass *cc = CPU_GET_CLASS(cs);
+    CPUOpenRISCState *env = &cpu->env;
+    uint32_t tmp;
+
+    if (n > cc->gdb_num_core_regs) {
+        return 0;
+    }
+
+    tmp = ldl_p(mem_buf);
+
+    if (n < 32) {
+        env->gpr[n] = tmp;
+    } else {
+        switch (n) {
+        case 32: /* PPC */
+            env->ppc = tmp;
+            break;
+
+        case 33: /* NPC */
+            env->npc = tmp;
+            break;
+
+        case 34: /* SR */
+            env->sr = tmp;
+            break;
+
+        default:
+            break;
+        }
+    }
+    return 4;
+}
diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
index 2c43c34..8274e8a 100644
--- a/target-ppc/Makefile.objs
+++ b/target-ppc/Makefile.objs
@@ -12,3 +12,4 @@ obj-y += timebase_helper.o
 obj-y += misc_helper.o
 obj-y += mem_helper.o
 obj-$(CONFIG_USER_ONLY) += user_only_helper.o
+obj-y += gdbstub.o
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 7216cc4..658e962 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -106,5 +106,7 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
new file mode 100644
index 0000000..1c91090
--- /dev/null
+++ b/target-ppc/gdbstub.c
@@ -0,0 +1,131 @@
+/*
+ * PowerPC gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+/* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
+ * expects whatever the target description contains.  Due to a
+ * historical mishap the FP registers appear in between core integer
+ * regs and PC, MSR, CR, and so forth.  We hack round this by giving the
+ * FP regs zero size when talking to a newer gdb.
+ */
+
+int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (n < 32) {
+        /* gprs */
+        return gdb_get_regl(mem_buf, env->gpr[n]);
+    } else if (n < 64) {
+        /* fprs */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        stfq_p(mem_buf, env->fpr[n-32]);
+        return 8;
+    } else {
+        switch (n) {
+        case 64:
+            return gdb_get_regl(mem_buf, env->nip);
+        case 65:
+            return gdb_get_regl(mem_buf, env->msr);
+        case 66:
+            {
+                uint32_t cr = 0;
+                int i;
+                for (i = 0; i < 8; i++) {
+                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
+                }
+                return gdb_get_reg32(mem_buf, cr);
+            }
+        case 67:
+            return gdb_get_regl(mem_buf, env->lr);
+        case 68:
+            return gdb_get_regl(mem_buf, env->ctr);
+        case 69:
+            return gdb_get_regl(mem_buf, env->xer);
+        case 70:
+            {
+                if (gdb_has_xml) {
+                    return 0;
+                }
+                return gdb_get_reg32(mem_buf, env->fpscr);
+            }
+        }
+    }
+    return 0;
+}
+
+int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (n < 32) {
+        /* gprs */
+        env->gpr[n] = ldtul_p(mem_buf);
+        return sizeof(target_ulong);
+    } else if (n < 64) {
+        /* fprs */
+        if (gdb_has_xml) {
+            return 0;
+        }
+        env->fpr[n-32] = ldfq_p(mem_buf);
+        return 8;
+    } else {
+        switch (n) {
+        case 64:
+            env->nip = ldtul_p(mem_buf);
+            return sizeof(target_ulong);
+        case 65:
+            ppc_store_msr(env, ldtul_p(mem_buf));
+            return sizeof(target_ulong);
+        case 66:
+            {
+                uint32_t cr = ldl_p(mem_buf);
+                int i;
+                for (i = 0; i < 8; i++) {
+                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
+                }
+                return 4;
+            }
+        case 67:
+            env->lr = ldtul_p(mem_buf);
+            return sizeof(target_ulong);
+        case 68:
+            env->ctr = ldtul_p(mem_buf);
+            return sizeof(target_ulong);
+        case 69:
+            env->xer = ldtul_p(mem_buf);
+            return sizeof(target_ulong);
+        case 70:
+            /* fpscr */
+            if (gdb_has_xml) {
+                return 0;
+            }
+            store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
+            return sizeof(target_ulong);
+        }
+    }
+    return 0;
+}
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e1d9d02..1b7d96b 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8313,6 +8313,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
+    cc->gdb_read_register = ppc_cpu_gdb_read_register;
+    cc->gdb_write_register = ppc_cpu_gdb_write_register;
 
     cc->gdb_num_core_regs = 71;
 }
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 4e63417..ab938e7 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,4 +1,5 @@
 obj-y += translate.o helper.o cpu.o interrupt.o
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
+obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += ioinst.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index cac55cc..5cec1ed 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -75,5 +75,7 @@ void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
 hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index ae62143..3b15b36 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -173,6 +173,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
+    cc->gdb_read_register = s390_cpu_gdb_read_register;
+    cc->gdb_write_register = s390_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
 #endif
diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c
new file mode 100644
index 0000000..a129742
--- /dev/null
+++ b/target-s390x/gdbstub.c
@@ -0,0 +1,88 @@
+/*
+ * s390x gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+#include "qemu/bitops.h"
+
+int s390_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
+    uint64_t val;
+    int cc_op;
+
+    switch (n) {
+    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);
+        return gdb_get_regl(mem_buf, val);
+    case S390_PSWA_REGNUM:
+        return gdb_get_regl(mem_buf, env->psw.addr);
+    case S390_R0_REGNUM ... S390_R15_REGNUM:
+        return gdb_get_regl(mem_buf, env->regs[n-S390_R0_REGNUM]);
+    case S390_A0_REGNUM ... S390_A15_REGNUM:
+        return gdb_get_reg32(mem_buf, env->aregs[n-S390_A0_REGNUM]);
+    case S390_FPC_REGNUM:
+        return gdb_get_reg32(mem_buf, env->fpc);
+    case S390_F0_REGNUM ... S390_F15_REGNUM:
+        return gdb_get_reg64(mem_buf, env->fregs[n-S390_F0_REGNUM].ll);
+    }
+
+    return 0;
+}
+
+int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
+    target_ulong tmpl;
+    uint32_t tmp32;
+    int r = 8;
+    tmpl = ldtul_p(mem_buf);
+    tmp32 = ldl_p(mem_buf);
+
+    switch (n) {
+    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;
+}
diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs
index cb448a8..a285358 100644
--- a/target-sh4/Makefile.objs
+++ b/target-sh4/Makefile.objs
@@ -1 +1,2 @@
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += gdbstub.o
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index 6f50a0a..209069a 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -87,5 +87,7 @@ void superh_cpu_do_interrupt(CPUState *cpu);
 void superh_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);
 hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int superh_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 7f5c47a..2fe12a6 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -286,6 +286,8 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     cc->dump_state = superh_cpu_dump_state;
     cc->set_pc = superh_cpu_set_pc;
     cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
+    cc->gdb_read_register = superh_cpu_gdb_read_register;
+    cc->gdb_write_register = superh_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
 #endif
diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c
new file mode 100644
index 0000000..df4fa2a
--- /dev/null
+++ b/target-sh4/gdbstub.c
@@ -0,0 +1,146 @@
+/*
+ * SuperH gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
+/* FIXME: We should use XML for this.  */
+
+int superh_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+    CPUSH4State *env = &cpu->env;
+
+    switch (n) {
+    case 0 ... 7:
+        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+            return gdb_get_regl(mem_buf, env->gregs[n + 16]);
+        } else {
+            return gdb_get_regl(mem_buf, env->gregs[n]);
+        }
+    case 8 ... 15:
+        return gdb_get_regl(mem_buf, env->gregs[n]);
+    case 16:
+        return gdb_get_regl(mem_buf, env->pc);
+    case 17:
+        return gdb_get_regl(mem_buf, env->pr);
+    case 18:
+        return gdb_get_regl(mem_buf, env->gbr);
+    case 19:
+        return gdb_get_regl(mem_buf, env->vbr);
+    case 20:
+        return gdb_get_regl(mem_buf, env->mach);
+    case 21:
+        return gdb_get_regl(mem_buf, env->macl);
+    case 22:
+        return gdb_get_regl(mem_buf, env->sr);
+    case 23:
+        return gdb_get_regl(mem_buf, env->fpul);
+    case 24:
+        return gdb_get_regl(mem_buf, env->fpscr);
+    case 25 ... 40:
+        if (env->fpscr & FPSCR_FR) {
+            stfl_p(mem_buf, env->fregs[n - 9]);
+        } else {
+            stfl_p(mem_buf, env->fregs[n - 25]);
+        }
+        return 4;
+    case 41:
+        return gdb_get_regl(mem_buf, env->ssr);
+    case 42:
+        return gdb_get_regl(mem_buf, env->spc);
+    case 43 ... 50:
+        return gdb_get_regl(mem_buf, env->gregs[n - 43]);
+    case 51 ... 58:
+        return gdb_get_regl(mem_buf, env->gregs[n - (51 - 16)]);
+    }
+
+    return 0;
+}
+
+int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+    CPUSH4State *env = &cpu->env;
+
+    switch (n) {
+    case 0 ... 7:
+        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+            env->gregs[n + 16] = ldl_p(mem_buf);
+        } else {
+            env->gregs[n] = ldl_p(mem_buf);
+        }
+        break;
+    case 8 ... 15:
+        env->gregs[n] = ldl_p(mem_buf);
+        break;
+    case 16:
+        env->pc = ldl_p(mem_buf);
+        break;
+    case 17:
+        env->pr = ldl_p(mem_buf);
+        break;
+    case 18:
+        env->gbr = ldl_p(mem_buf);
+        break;
+    case 19:
+        env->vbr = ldl_p(mem_buf);
+        break;
+    case 20:
+        env->mach = ldl_p(mem_buf);
+        break;
+    case 21:
+        env->macl = ldl_p(mem_buf);
+        break;
+    case 22:
+        env->sr = ldl_p(mem_buf);
+        break;
+    case 23:
+        env->fpul = ldl_p(mem_buf);
+        break;
+    case 24:
+        env->fpscr = ldl_p(mem_buf);
+        break;
+    case 25 ... 40:
+        if (env->fpscr & FPSCR_FR) {
+            env->fregs[n - 9] = ldfl_p(mem_buf);
+        } else {
+            env->fregs[n - 25] = ldfl_p(mem_buf);
+        }
+        break;
+    case 41:
+        env->ssr = ldl_p(mem_buf);
+        break;
+    case 42:
+        env->spc = ldl_p(mem_buf);
+        break;
+    case 43 ... 50:
+        env->gregs[n - 43] = ldl_p(mem_buf);
+        break;
+    case 51 ... 58:
+        env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
+        break;
+    default:
+        return 0;
+    }
+
+    return 4;
+}
diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs
index 9fc42ea..1cd81cc 100644
--- a/target-sparc/Makefile.objs
+++ b/target-sparc/Makefile.objs
@@ -4,3 +4,4 @@ obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
 obj-$(TARGET_SPARC) += int32_helper.o
 obj-$(TARGET_SPARC64) += int64_helper.o
 obj-$(TARGET_SPARC64) += vis_helper.o
+obj-y += gdbstub.o
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index 1b39274..3f9e84c 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -79,5 +79,7 @@ void sparc_cpu_do_interrupt(CPUState *cpu);
 void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
                           fprintf_function cpu_fprintf, int flags);
 hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index b35f2d1..855f097 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -787,6 +787,8 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
 #endif
     cc->set_pc = sparc_cpu_set_pc;
     cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
+    cc->gdb_read_register = sparc_cpu_gdb_read_register;
+    cc->gdb_write_register = sparc_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->do_unassigned_access = sparc_cpu_unassigned_access;
     cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c
new file mode 100644
index 0000000..25fb2a3
--- /dev/null
+++ b/target-sparc/gdbstub.c
@@ -0,0 +1,208 @@
+/*
+ * SPARC gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+#ifdef TARGET_ABI32
+#define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
+#else
+#define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
+#endif
+
+int sparc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
+
+    if (n < 8) {
+        /* g0..g7 */
+        return gdb_get_rega(mem_buf, env->gregs[n]);
+    }
+    if (n < 32) {
+        /* register window */
+        return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
+    }
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
+    if (n < 64) {
+        /* fprs */
+        if (n & 1) {
+            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
+        } else {
+            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
+        }
+    }
+    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+    switch (n) {
+    case 64:
+        return gdb_get_rega(mem_buf, env->y);
+    case 65:
+        return gdb_get_rega(mem_buf, cpu_get_psr(env));
+    case 66:
+        return gdb_get_rega(mem_buf, env->wim);
+    case 67:
+        return gdb_get_rega(mem_buf, env->tbr);
+    case 68:
+        return gdb_get_rega(mem_buf, env->pc);
+    case 69:
+        return gdb_get_rega(mem_buf, env->npc);
+    case 70:
+        return gdb_get_rega(mem_buf, env->fsr);
+    case 71:
+        return gdb_get_rega(mem_buf, 0); /* csr */
+    default:
+        return gdb_get_rega(mem_buf, 0);
+    }
+#else
+    if (n < 64) {
+        /* f0-f31 */
+        if (n & 1) {
+            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
+        } else {
+            return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
+        }
+    }
+    if (n < 80) {
+        /* f32-f62 (double width, even numbers only) */
+        return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
+    }
+    switch (n) {
+    case 80:
+        return gdb_get_regl(mem_buf, env->pc);
+    case 81:
+        return gdb_get_regl(mem_buf, env->npc);
+    case 82:
+        return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
+                            ((env->asi & 0xff) << 24) |
+                            ((env->pstate & 0xfff) << 8) |
+                            cpu_get_cwp64(env));
+    case 83:
+        return gdb_get_regl(mem_buf, env->fsr);
+    case 84:
+        return gdb_get_regl(mem_buf, env->fprs);
+    case 85:
+        return gdb_get_regl(mem_buf, env->y);
+    }
+#endif
+    return 0;
+}
+
+int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
+#if defined(TARGET_ABI32)
+    abi_ulong tmp;
+
+    tmp = ldl_p(mem_buf);
+#else
+    target_ulong tmp;
+
+    tmp = ldtul_p(mem_buf);
+#endif
+
+    if (n < 8) {
+        /* g0..g7 */
+        env->gregs[n] = tmp;
+    } else if (n < 32) {
+        /* register window */
+        env->regwptr[n - 8] = tmp;
+    }
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
+    else if (n < 64) {
+        /* fprs */
+        /* f0-f31 */
+        if (n & 1) {
+            env->fpr[(n - 32) / 2].l.lower = tmp;
+        } else {
+            env->fpr[(n - 32) / 2].l.upper = tmp;
+        }
+    } else {
+        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+        switch (n) {
+        case 64:
+            env->y = tmp;
+            break;
+        case 65:
+            cpu_put_psr(env, tmp);
+            break;
+        case 66:
+            env->wim = tmp;
+            break;
+        case 67:
+            env->tbr = tmp;
+            break;
+        case 68:
+            env->pc = tmp;
+            break;
+        case 69:
+            env->npc = tmp;
+            break;
+        case 70:
+            env->fsr = tmp;
+            break;
+        default:
+            return 0;
+        }
+    }
+    return 4;
+#else
+    else if (n < 64) {
+        /* f0-f31 */
+        tmp = ldl_p(mem_buf);
+        if (n & 1) {
+            env->fpr[(n - 32) / 2].l.lower = tmp;
+        } else {
+            env->fpr[(n - 32) / 2].l.upper = tmp;
+        }
+        return 4;
+    } else if (n < 80) {
+        /* f32-f62 (double width, even numbers only) */
+        env->fpr[(n - 32) / 2].ll = tmp;
+    } else {
+        switch (n) {
+        case 80:
+            env->pc = tmp;
+            break;
+        case 81:
+            env->npc = tmp;
+            break;
+        case 82:
+            cpu_put_ccr(env, tmp >> 32);
+            env->asi = (tmp >> 24) & 0xff;
+            env->pstate = (tmp >> 8) & 0xfff;
+            cpu_put_cwp64(env, tmp & 0xff);
+            break;
+        case 83:
+            env->fsr = tmp;
+            break;
+        case 84:
+            env->fprs = tmp;
+            break;
+        case 85:
+            env->y = tmp;
+            break;
+        default:
+            return 0;
+        }
+    }
+    return 8;
+#endif
+}
diff --git a/target-xtensa/Makefile.objs b/target-xtensa/Makefile.objs
index 644b7f9..5c150a8 100644
--- a/target-xtensa/Makefile.objs
+++ b/target-xtensa/Makefile.objs
@@ -3,3 +3,4 @@ obj-y += core-dc232b.o
 obj-y += core-dc233c.o
 obj-y += core-fsf.o
 obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += gdbstub.o
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 878eb15..9a2da25 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -87,5 +87,7 @@ void xtensa_cpu_do_interrupt(CPUState *cpu);
 void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);
 hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, uint64_t addr);
+int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index eaafacf..0743ce2 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -131,6 +131,8 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
+    cc->gdb_read_register = xtensa_cpu_gdb_read_register;
+    cc->gdb_write_register = xtensa_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
 #endif
diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c
new file mode 100644
index 0000000..b8cef35
--- /dev/null
+++ b/target-xtensa/gdbstub.c
@@ -0,0 +1,111 @@
+/*
+ * Xtensa gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    XtensaCPU *cpu = XTENSA_CPU(cs);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cs);
+    CPUXtensaState *env = &cpu->env;
+    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
+
+    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
+        return 0;
+    }
+
+    switch (reg->type) {
+    case 9: /*pc*/
+        return gdb_get_reg32(mem_buf, env->pc);
+
+    case 1: /*ar*/
+        xtensa_sync_phys_from_window(env);
+        return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff)
+                                                     % xcc->config->nareg]);
+
+    case 2: /*SR*/
+        return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]);
+
+    case 3: /*UR*/
+        return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]);
+
+    case 4: /*f*/
+        return gdb_get_reg32(mem_buf,
+                             float32_val(env->fregs[reg->targno & 0x0f]));
+
+    case 8: /*a*/
+        return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);
+
+    default:
+        qemu_log("%s from reg %d of unsupported type %d\n",
+                __func__, n, reg->type);
+        return 0;
+    }
+}
+
+int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    XtensaCPU *cpu = XTENSA_CPU(cs);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cs);
+    CPUXtensaState *env = &cpu->env;
+    uint32_t tmp;
+    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
+
+    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
+        return 0;
+    }
+
+    tmp = ldl_p(mem_buf);
+
+    switch (reg->type) {
+    case 9: /*pc*/
+        env->pc = tmp;
+        break;
+
+    case 1: /*ar*/
+        env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg] = tmp;
+        xtensa_sync_window_from_phys(env);
+        break;
+
+    case 2: /*SR*/
+        env->sregs[reg->targno & 0xff] = tmp;
+        break;
+
+    case 3: /*UR*/
+        env->uregs[reg->targno & 0xff] = tmp;
+        break;
+
+    case 4: /*f*/
+        env->fregs[reg->targno & 0x0f] = make_float32(tmp);
+        break;
+
+    case 8: /*a*/
+        env->regs[reg->targno & 0x0f] = tmp;
+        break;
+
+    default:
+        qemu_log("%s to reg %d of unsupported type %d\n",
+                __func__, n, reg->type);
+        return 0;
+    }
+
+    return 4;
+}
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub
  2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
                   ` (40 preceding siblings ...)
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register() Andreas Färber
@ 2013-06-30 12:23 ` Michael Walle
  41 siblings, 0 replies; 85+ messages in thread
From: Michael Walle @ 2013-06-30 12:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

On Sat, Jun 29, 2013 at 10:01:16PM +0200, Andreas Färber wrote:
> Hello,
> 
> This series cleans up gdbstub by changing all its internal CPU state to CPUState
> and by moving most target-specific code into the target directories.
> 
> It depends on part 10 and starts with a follow-up, consolidating reset logging.
> 
> Support for m68k, moxie and unicore32 to set the PC via gdbstub is added.
> 
> Lightweight subclasses for XtensaCPU are introduced, keeping the XtensaConfig
> mechanisms, to stop xtensa from deviating at gdbstub level wrt register count.
> 
> I'm wondering whether there would be interest in adding a "program-counter"
> dynamic property to the CPU, given that a setter has been factored out here?
> 
> Available for testing at:
> git://github.com/afaerber/qemu-cpu.git qom-cpu-11.v1
> https://github.com/afaerber/qemu-cpu/commits/qom-cpu-11.v1

For all lm32 parts:
Acked-by: Michael Walle <michael@walle.cc>

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
@ 2013-07-01 17:03   ` Richard Henderson
  2013-07-01 17:21     ` Andreas Färber
  2013-07-02  1:26   ` Andreas Färber
  1 sibling, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:03 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Green, Riku Voipio, qemu-devel,
	Alexander Graf, Blue Swirl, Michael Walle, PowerPC, Paul Brook,
	Edgar E. Iglesias, jan.kiszka, Aurelien Jarno

On 06/29/2013 01:01 PM, Andreas Färber wrote:
>          if ((env->cr[0] & CR0_PE_MASK)) {
> +            X86CPU *cpu = x86_env_get_cpu(env);
>              static int count;
>  
>              qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx
> @@ -1180,7 +1181,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
>                  qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]);
>              }
>              qemu_log("\n");
> -            log_cpu_state(env, CPU_DUMP_CCOP);
> +            log_cpu_state(CPU(cpu), CPU_DUMP_CCOP);

Not a bug, but I'd like to know your rationale for adding X86CPU *cpu variables
as opposed to CPUState *cs variables?  Especially when the cpu variable is
never used without the cast to CPU.

Otherwise,

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging to CPUState
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
@ 2013-07-01 17:04   ` Richard Henderson
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:04 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Green, qemu-devel, Alexander Graf,
	Blue Swirl, Michael Walle, PowerPC, Paul Brook,
	Edgar E. Iglesias, jan.kiszka, Aurelien Jarno

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> x86 was using additional CPU_DUMP_* flags, so make that configurable in
> CPUClass::reset_dump_flags.
> 
> This adds reset logging for alpha, unicore32 and xtensa.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu to CPUState
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu " Andreas Färber
@ 2013-07-01 17:05   ` Richard Henderson
  2013-07-02 22:11     ` Andreas Färber
  0 siblings, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:05 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Since first_cpu/next_cpu are CPUState, CPUArchState is no longer needed.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  gdbstub.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc() Andreas Färber
@ 2013-07-01 17:09   ` Richard Henderson
  2013-07-01 17:25     ` Andreas Färber
  0 siblings, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:09 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, qemu-devel, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, PowerPC, Paul Brook,
	Edgar E. Iglesias, jan.kiszka, Aurelien Jarno

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> This moves setting the Program Counter from gdbstub into target code.
> Use uint64_t type as maximum replacement for target_ulong.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  gdbstub.c                   | 39 ++++++---------------------------------
>  include/qom/cpu.h           |  1 +
>  target-alpha/cpu.c          |  8 ++++++++
>  target-arm/cpu.c            |  8 ++++++++
>  target-cris/cpu.c           |  8 ++++++++
>  target-i386/cpu.c           |  8 ++++++++
>  target-lm32/cpu.c           |  8 ++++++++
>  target-microblaze/cpu.c     |  8 ++++++++
>  target-mips/cpu.c           | 14 ++++++++++++++
>  target-openrisc/cpu.c       |  8 ++++++++
>  target-ppc/translate_init.c |  8 ++++++++
>  target-s390x/cpu.c          |  8 ++++++++
>  target-sh4/cpu.c            |  8 ++++++++
>  target-sparc/cpu.c          |  9 +++++++++
>  target-xtensa/cpu.c         |  8 ++++++++
>  15 files changed, 118 insertions(+), 33 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb()
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb() Andreas Färber
@ 2013-07-01 17:13   ` Richard Henderson
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:13 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Green, qemu-devel, Alexander Graf,
	Blue Swirl, Max Filippov, Michael Walle, PowerPC, Paul Brook,
	Edgar E. Iglesias, jan.kiszka, Guan Xuetao, Aurelien Jarno

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Where no extra implementation is needed, fall back to CPUClass::set_pc().
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpu-exec.c              |  8 +++++++-
>  include/exec/exec-all.h |  3 ---
>  include/qemu/typedefs.h |  3 +++
>  include/qom/cpu.h       |  1 +
>  target-alpha/cpu.h      |  5 -----
>  target-arm/cpu.h        |  5 -----
>  target-cris/cpu.h       |  4 ----
>  target-i386/cpu.c       |  8 ++++++++
>  target-i386/cpu.h       |  5 -----
>  target-lm32/cpu.h       |  5 -----
>  target-m68k/cpu.h       |  5 -----
>  target-microblaze/cpu.h |  5 -----
>  target-mips/cpu.c       | 11 +++++++++++
>  target-mips/cpu.h       |  7 -------
>  target-moxie/cpu.h      |  5 -----
>  target-openrisc/cpu.h   |  5 -----
>  target-ppc/cpu.h        |  5 -----
>  target-s390x/cpu.h      |  5 -----
>  target-sh4/cpu.c        |  9 +++++++++
>  target-sh4/cpu.h        |  6 ------
>  target-sparc/cpu.c      |  9 +++++++++
>  target-sparc/cpu.h      |  6 ------
>  target-unicore32/cpu.h  |  5 -----
>  target-xtensa/cpu.h     |  5 -----
>  24 files changed, 48 insertions(+), 87 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu()
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu() Andreas Färber
@ 2013-07-01 17:14   ` Richard Henderson
  2013-07-06  0:42     ` Andreas Färber
  0 siblings, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:14 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Since commit cb446ecab714b2444a270be209e0533bcd2ee534 (kvm: Change
> cpu_synchronize_state() argument to CPUState), one was no longer
> accessing CPUArchState, the other was just checking existence.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  gdbstub.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
@ 2013-07-01 17:15   ` Richard Henderson
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:15 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Also use bool argument while at it.
> 
> Prepares for replacing DisasContext::env with CPUState and for moving
> singlestep_enabled field to CPUState.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  target-alpha/translate.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
@ 2013-07-01 17:16   ` Richard Henderson
  2013-07-01 17:51     ` Andreas Färber
  2013-07-02 21:13     ` Andreas Färber
  0 siblings, 2 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:16 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Max Filippov, jan.kiszka, qemu-devel

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Also use bool type while at it.
> 
> Prepares for moving singlestep_enabled field to CPUState.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  target-xtensa/translate.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)

All of 10-23/41,

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState Andreas Färber
@ 2013-07-01 17:18   ` Richard Henderson
  2013-07-01 17:23   ` Richard Henderson
  1 sibling, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:18 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Needed for moving singlestep_enabled to CPUState.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  target-alpha/translate.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-07-01 17:03   ` Richard Henderson
@ 2013-07-01 17:21     ` Andreas Färber
  2013-07-01 20:22       ` Richard Henderson
  0 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-01 17:21 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, Anthony Green, Riku Voipio, qemu-devel,
	Alexander Graf, Blue Swirl, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, Jan Kiszka, Aurelien Jarno

Am 01.07.2013 19:03, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>>          if ((env->cr[0] & CR0_PE_MASK)) {
>> +            X86CPU *cpu = x86_env_get_cpu(env);
>>              static int count;
>>  
>>              qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx
>> @@ -1180,7 +1181,7 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
>>                  qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]);
>>              }
>>              qemu_log("\n");
>> -            log_cpu_state(env, CPU_DUMP_CCOP);
>> +            log_cpu_state(CPU(cpu), CPU_DUMP_CCOP);
> 
> Not a bug, but I'd like to know your rationale for adding X86CPU *cpu variables
> as opposed to CPUState *cs variables?  Especially when the cpu variable is
> never used without the cast to CPU.

It's been a few days already, but I believe that I was preparing for
changing the function argument to X86CPU for any static helpers. So the
local variable would get dropped or replaced by a CPUX86State variable.

Generally, Anthony had veto'ed against CPU(cpu)->something, so I
introduce CPUState variables to avoid that, but if there's only one use
case like here and we stay within 80 chars then there is no strict need
for a separate variable IMO, whether FooCPU or CPUState.
Similarly, when there's just one or two short uses of CPU*State I have
chosen to not introduce an extra CPUFooState variable (e.g., set_pc).

> Otherwise,
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

Thanks. If Blue or you don't have any further comments on the previous
part 10 series v3, I will queue that on qom-cpu (rebasing right now).

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState Andreas Färber
  2013-07-01 17:18   ` Richard Henderson
@ 2013-07-01 17:23   ` Richard Henderson
  2013-07-01 17:42     ` Andreas Färber
  1 sibling, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:23 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> -    CPUAlphaState *env;
> +    AlphaCPU *cpu;

Actually, I take this back.  I'd prefer that we simply pull out the two
variables that we need and place them in the DisasContext.  That's the way it
should have been in the first place.

> @@ -3394,7 +3394,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>      gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
>  
>      ctx.tb = tb;
> -    ctx.env = env;
> +    ctx.cpu = alpha_env_get_cpu(env);

This should have been ctx.cpu = cpu anyway, apparently fixed in the next patch.


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  2013-07-01 17:09   ` Richard Henderson
@ 2013-07-01 17:25     ` Andreas Färber
  2013-07-01 19:03       ` Richard Henderson
  0 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-01 17:25 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, qemu-devel, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, Jan Kiszka, Aurelien Jarno

Richard or anyone,

Am 01.07.2013 19:09, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> This moves setting the Program Counter from gdbstub into target code.
>> Use uint64_t type as maximum replacement for target_ulong.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  gdbstub.c                   | 39 ++++++---------------------------------
>>  include/qom/cpu.h           |  1 +
>>  target-alpha/cpu.c          |  8 ++++++++
>>  target-arm/cpu.c            |  8 ++++++++
>>  target-cris/cpu.c           |  8 ++++++++
>>  target-i386/cpu.c           |  8 ++++++++
>>  target-lm32/cpu.c           |  8 ++++++++
>>  target-microblaze/cpu.c     |  8 ++++++++
>>  target-mips/cpu.c           | 14 ++++++++++++++
>>  target-openrisc/cpu.c       |  8 ++++++++
>>  target-ppc/translate_init.c |  8 ++++++++
>>  target-s390x/cpu.c          |  8 ++++++++
>>  target-sh4/cpu.c            |  8 ++++++++
>>  target-sparc/cpu.c          |  9 +++++++++
>>  target-xtensa/cpu.c         |  8 ++++++++
>>  15 files changed, 118 insertions(+), 33 deletions(-)
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

This is the first case where I am proposing the use of uint64_t in place
of target_ulong. In this case a gdb command using such a hook is not
performance-sensitive. Do you see this as an acceptable path for adding
further CPUClass hooks such as MMU fault handling?

Should we introduce some ulong-target-max typedef similar to hwaddr or
use plain uint64_t as done here?

Thanks,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 25/41] cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
  2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
  (?)
@ 2013-07-01 17:27   ` Richard Henderson
  -1 siblings, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 17:27 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Gleb Natapov, Anthony Green, Marcelo Tosatti,
	qemu-devel, Alexander Graf, Blue Swirl, Max Filippov,
	Michael Walle, jan.kiszka, Paul Brook, Edgar E. Iglesias,
	Guan Xuetao, Aurelien Jarno

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> --- a/target-alpha/translate.c
> +++ b/target-alpha/translate.c
> @@ -377,10 +377,12 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
>  
>  static int use_goto_tb(DisasContext *ctx, uint64_t dest)
>  {
> +    CPUState *cs = CPU(ctx->cpu);
> +
>      /* Check for the dest on the same page as the start of the TB.  We
>         also want to suppress goto_tb in the case of single-steping and IO.  */
>      return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
> -            && !ctx->cpu->env.singlestep_enabled
> +            && !cs->singlestep_enabled
>              && !(ctx->tb->cflags & CF_LAST_IO));
>  }

So continuing the thought from 24/, this stays

  && !ctx->singlestep_enabled.

>  
> @@ -3379,6 +3381,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>                                                    TranslationBlock *tb,
>                                                    bool search_pc)
>  {
> +    CPUState *cs = CPU(cpu);
>      CPUAlphaState *env = &cpu->env;
>      DisasContext ctx, *ctxp = &ctx;
>      target_ulong pc_start;
> @@ -3394,9 +3397,10 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>      gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
>  
>      ctx.tb = tb;
> -    ctx.cpu = alpha_env_get_cpu(env);
> +    ctx.cpu = cpu;
>      ctx.pc = pc_start;
>      ctx.mem_idx = cpu_mmu_index(env);
> +    cs = CPU(ctx.cpu);
>  
>      /* ??? Every TB begins with unset rounding mode, to be initialized on
>         the first fp insn of the TB.  Alternately we could define a proper
> @@ -3453,7 +3457,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>                  || tcg_ctx.gen_opc_ptr >= gen_opc_end
>                  || num_insns >= max_insns
>                  || singlestep
> -                || env->singlestep_enabled)) {
> +                || cs->singlestep_enabled)) {

and this becomes tcg_ctx.singlestep_enabled, either here or in 24/.

>              ret = EXIT_PC_STALE;
>          }
>      } while (ret == NO_EXIT);
> @@ -3470,7 +3474,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>          tcg_gen_movi_i64(cpu_pc, ctx.pc);
>          /* FALLTHRU */
>      case EXIT_PC_UPDATED:
> -        if (env->singlestep_enabled) {
> +        if (cs->singlestep_enabled) {

Likewise.


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState
  2013-07-01 17:23   ` Richard Henderson
@ 2013-07-01 17:42     ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-01 17:42 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Jan Kiszka, qemu-devel

Am 01.07.2013 19:23, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> -    CPUAlphaState *env;
>> +    AlphaCPU *cpu;
> 
> Actually, I take this back.  I'd prefer that we simply pull out the two
> variables that we need and place them in the DisasContext.  That's the way it
> should have been in the first place.

Fine with me. Do you want to send a patch based on master right away, or
should I do that in v2?

>> @@ -3394,7 +3394,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>>      gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
>>  
>>      ctx.tb = tb;
>> -    ctx.env = env;
>> +    ctx.cpu = alpha_env_get_cpu(env);
> 
> This should have been ctx.cpu = cpu anyway, apparently fixed in the next patch.

Oops, I had done alpha first and then prepended the AlphaCPU propagation
alongside the other targets that needed it.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-07-01 17:16   ` Richard Henderson
@ 2013-07-01 17:51     ` Andreas Färber
  2013-07-01 18:03       ` Richard Henderson
  2013-07-02 21:13     ` Andreas Färber
  1 sibling, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-01 17:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mike Frysinger, Max Filippov, jan.kiszka, qemu-devel

Am 01.07.2013 19:16, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> Also use bool type while at it.
>>
>> Prepares for moving singlestep_enabled field to CPUState.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  target-xtensa/translate.c | 10 ++++++----
>>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> All of 10-23/41,
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

I wonder, all targets seem to implement the same pattern of passing a
hard-coded bool argument to their internal function.

Is there any reason not to have translate-all.c call the function with
that true/false directly?

That would then call for using CPUState *cs argument and leaving FooCPU
*cpu as local variable only where needed. In that case it would be a
central change covering all targets in one patch. :)

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-07-01 17:51     ` Andreas Färber
@ 2013-07-01 18:03       ` Richard Henderson
  2013-07-01 21:46         ` Andreas Färber
  0 siblings, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 18:03 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Mike Frysinger, Max Filippov, jan.kiszka, qemu-devel

On 07/01/2013 10:51 AM, Andreas Färber wrote:
> I wonder, all targets seem to implement the same pattern of passing a
> hard-coded bool argument to their internal function.
> 
> Is there any reason not to have translate-all.c call the function with
> that true/false directly?

The idea is to avoid runtime checks for the rare search_pc case.

Instead we pass constants to inline functions and transform what would be
runtime checks into compile-time optimized code paths.



r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register()
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register() Andreas Färber
@ 2013-07-01 18:07   ` Richard Henderson
  2013-07-06 19:18     ` Andreas Färber
  0 siblings, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 18:07 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, qemu-devel, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Aurelien Jarno

On 06/29/2013 01:01 PM, Andreas Färber wrote:
> Replace GET_REG*() macros by gdb_get_reg*() inline functions for
> clarity and drop breaks after return.
> 
> Allows to move target-specific code to new target-*/gdbstub.c files.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

This one's quite hard to read.

I wonder if there's value in splitting out functions one target at a time into
the new gdbstub.c files, and only afterward performing a few minor textual
changes to transform those functions into the CPUClass methods?


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  2013-07-01 17:25     ` Andreas Färber
@ 2013-07-01 19:03       ` Richard Henderson
  2013-07-01 19:41         ` Peter Maydell
  0 siblings, 1 reply; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 19:03 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, qemu-devel, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, Jan Kiszka, Aurelien Jarno

On 07/01/2013 10:25 AM, Andreas Färber wrote:
> This is the first case where I am proposing the use of uint64_t in place
> of target_ulong. In this case a gdb command using such a hook is not
> performance-sensitive. Do you see this as an acceptable path for adding
> further CPUClass hooks such as MMU fault handling?

I think that would be appropriate.  MMU faulting can't be much more performance
sensitive than device emulation, which is already standardizing on 64-bit
addresses.

> Should we introduce some ulong-target-max typedef similar to hwaddr or
> use plain uint64_t as done here?

I would think hwaddr wouldn't be appropriate, since that's supposed to be
talking about physical addresses, and that's not the case here.  The name (and
admittedly minimal documentation for) ram_addr_t sounds right, but it seems to
be sized wrong, so I don't know what it's actually supposed to be.

Unless someone has a better suggestion, I'd stay with uint64_t.


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  2013-07-01 19:03       ` Richard Henderson
@ 2013-07-01 19:41         ` Peter Maydell
  2013-07-01 20:20           ` Richard Henderson
  0 siblings, 1 reply; 85+ messages in thread
From: Peter Maydell @ 2013-07-01 19:41 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Alexander Graf, qemu-devel, Blue Swirl, Max Filippov,
	Michael Walle, qemu-ppc, Paul Brook, Edgar E. Iglesias,
	Jan Kiszka, Andreas Färber, Aurelien Jarno

On 1 July 2013 20:03, Richard Henderson <rth@twiddle.net> wrote:
> I would think hwaddr wouldn't be appropriate, since that's supposed to be
> talking about physical addresses, and that's not the case here.  The name (and
> admittedly minimal documentation for) ram_addr_t sounds right, but it seems to
> be sized wrong, so I don't know what it's actually supposed to be.

ram_addr_t is for indexes into guest RAM, ie into what you get by concatenating
all the RAMBlocks together. (This is why it's uintptr_t sized -- you know you
can't have more RAM total than will fit into the host's address space.)
It usually isn't what you want. Feel free to suggest improvements to
HACKING -- I tried to describe this in the bit that goes "ram_addr_t is
a QEMU internal address space ..." but since I already knew what it did
I probably failed to explain sufficiently.

Returning to the point, what we're after here is "a type which will hold
a guest virtual address but whose size doesn't depend on the target the
way target_ulong does", right? My inclination is to suggest that we have
a 'vaddr' typedef by analogy with 'hwaddr'; it seems like that might make
code dealing with guest addresses a little more self documenting. I don't
feel very strongly about it though so if people think it's pointless/will
cause problems that's fine.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
  2013-07-01 19:41         ` Peter Maydell
@ 2013-07-01 20:20           ` Richard Henderson
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 20:20 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Alexander Graf, qemu-devel, Blue Swirl, Max Filippov,
	Michael Walle, qemu-ppc, Paul Brook, Edgar E. Iglesias,
	Jan Kiszka, Andreas Färber, Aurelien Jarno

On 07/01/2013 12:41 PM, Peter Maydell wrote:
> Returning to the point, what we're after here is "a type which will hold
> a guest virtual address but whose size doesn't depend on the target the
> way target_ulong does", right? My inclination is to suggest that we have
> a 'vaddr' typedef by analogy with 'hwaddr'; it seems like that might make
> code dealing with guest addresses a little more self documenting. I don't
> feel very strongly about it though so if people think it's pointless/will
> cause problems that's fine.
> 

I agree that vaddr would probably be a good name.


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-07-01 17:21     ` Andreas Färber
@ 2013-07-01 20:22       ` Richard Henderson
  0 siblings, 0 replies; 85+ messages in thread
From: Richard Henderson @ 2013-07-01 20:22 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Green, Riku Voipio, qemu-devel,
	Alexander Graf, Blue Swirl, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, Jan Kiszka, Aurelien Jarno

On 07/01/2013 10:21 AM, Andreas Färber wrote:
> Thanks. If Blue or you don't have any further comments on the previous
> part 10 series v3, I will queue that on qom-cpu (rebasing right now).

Nothing further from me.


r~

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-07-01 18:03       ` Richard Henderson
@ 2013-07-01 21:46         ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-01 21:46 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mike Frysinger, Max Filippov, jan.kiszka, qemu-devel

Am 01.07.2013 20:03, schrieb Richard Henderson:
> On 07/01/2013 10:51 AM, Andreas Färber wrote:
>> I wonder, all targets seem to implement the same pattern of passing a
>> hard-coded bool argument to their internal function.
>>
>> Is there any reason not to have translate-all.c call the function with
>> that true/false directly?
> 
> The idea is to avoid runtime checks for the rare search_pc case.
> 
> Instead we pass constants to inline functions and transform what would be
> runtime checks into compile-time optimized code paths.

Thanks for the explanation!

Not every target seems to be aware of that, I'll put together a patch.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
  2013-07-01 17:03   ` Richard Henderson
@ 2013-07-02  1:26   ` Andreas Färber
  2013-07-02 21:17     ` Andreas Färber
  1 sibling, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-02  1:26 UTC (permalink / raw)
  To: Michael Walle, Richard Henderson
  Cc: Peter Maydell, Peter Crosthwaite, Anthony Green, Riku Voipio,
	qemu-devel, Alexander Graf, Blue Swirl, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, Jan Kiszka, Aurelien Jarno

Am 29.06.2013 22:01, schrieb Andreas Färber:
> diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
> index 01d4bbf..86aad6a 100644
> --- a/target-microblaze/helper.c
> +++ b/target-microblaze/helper.c
> @@ -152,7 +152,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>                            "hw exception at pc=%x ear=%x esr=%x iflags=%x\n",
>                            env->sregs[SR_PC], env->sregs[SR_EAR],
>                            env->sregs[SR_ESR], env->iflags);
> -            log_cpu_state_mask(CPU_LOG_INT, env, 0);
> +            log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
>              env->iflags &= ~(IMM_FLAG | D_FLAG);
>              env->sregs[SR_PC] = cpu->base_vectors + 0x20;
>              break;
> @@ -175,7 +175,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>                                    "bimm exception at pc=%x iflags=%x\n",
>                                    env->sregs[SR_PC], env->iflags);
>                      env->regs[17] -= 4;
> -                    log_cpu_state_mask(CPU_LOG_INT, env, 0);
> +                    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
>                  }
>              } else if (env->iflags & IMM_FLAG) {
>                  D(qemu_log("IMM_FLAG set at exception\n"));
> @@ -192,7 +192,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              qemu_log_mask(CPU_LOG_INT,
>                            "exception at pc=%x ear=%x iflags=%x\n",
>                            env->sregs[SR_PC], env->sregs[SR_EAR], env->iflags);
> -            log_cpu_state_mask(CPU_LOG_INT, env, 0);
> +            log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
>              env->iflags &= ~(IMM_FLAG | D_FLAG);
>              env->sregs[SR_PC] = cpu->base_vectors + 0x20;
>              break;
> @@ -222,7 +222,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>                           env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags,
>                           sym);
>  
> -                    log_cpu_state(env, 0);
> +                    log_cpu_state(CPU(cpu), 0);
>                  }
>              }
>  #endif
> @@ -236,7 +236,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>  
>              env->regs[14] = env->sregs[SR_PC];
>              env->sregs[SR_PC] = cpu->base_vectors + 0x10;
> -            //log_cpu_state_mask(CPU_LOG_INT, env, 0);
> +            //log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
>              break;
>  
>          case EXCP_BREAK:
> @@ -247,7 +247,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              qemu_log_mask(CPU_LOG_INT,
>                          "break at pc=%x msr=%x %x iflags=%x\n",
>                          env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);
> -            log_cpu_state_mask(CPU_LOG_INT, env, 0);
> +            log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), 0);
>              env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
>              env->sregs[SR_MSR] |= t;
>              env->sregs[SR_MSR] |= MSR_BIP;

Re-reviewing this patch for my X86CPU changes, I noticed all these could
use "cs" rather than "CPU(cpu)" - fixed and applied along with the
following one to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

> diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
> index 54f439f..f9acdb1 100644
> --- a/target-microblaze/translate.c
> +++ b/target-microblaze/translate.c
> @@ -1741,6 +1741,9 @@ static void
>  gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
>                                 int search_pc)
>  {
> +#if !SIM_COMPAT
> +    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
> +#endif
>      uint16_t *gen_opc_end;
>      uint32_t pc_start;
>      int j, lj;
[snip]

This hunk would benefit from the gen_intermediate_code_internal()
argument type change prompted by gdbstub later in this series, so I
intend to prepend those once v2 is done - inline is missing here.
Trying to avoid resending a 41-patch series. ;)

TBD: Follow up with patches for the x86 and ppc logging macros
respectively before I forget about them.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-07-01 17:16   ` Richard Henderson
  2013-07-01 17:51     ` Andreas Färber
@ 2013-07-02 21:13     ` Andreas Färber
  1 sibling, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-02 21:13 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Max Filippov, jan.kiszka, qemu-devel

Am 01.07.2013 19:16, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> Also use bool type while at it.
>>
>> Prepares for moving singlestep_enabled field to CPUState.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  target-xtensa/translate.c | 10 ++++++----
>>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> All of 10-23/41,
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

Thanks, rebased on inline additions and inserted into qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-07-02  1:26   ` Andreas Färber
@ 2013-07-02 21:17     ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-02 21:17 UTC (permalink / raw)
  To: Peter Crosthwaite, qemu-devel
  Cc: Peter Maydell, Jan Kiszka, Anthony Green, Riku Voipio,
	Alexander Graf, Blue Swirl, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, Aurelien Jarno, Richard Henderson

Am 02.07.2013 03:26, schrieb Andreas Färber:
> Am 29.06.2013 22:01, schrieb Andreas Färber:
>> diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
>> index 54f439f..f9acdb1 100644
>> --- a/target-microblaze/translate.c
>> +++ b/target-microblaze/translate.c
>> @@ -1741,6 +1741,9 @@ static void
>>  gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
>>                                 int search_pc)
>>  {
>> +#if !SIM_COMPAT
>> +    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
>> +#endif
>>      uint16_t *gen_opc_end;
>>      uint32_t pc_start;
>>      int j, lj;
> [snip]
> 
> This hunk would benefit from the gen_intermediate_code_internal()
> argument type change prompted by gdbstub later in this series, so I
> intend to prepend those once v2 is done - inline is missing here.

Missing inline was added separately to allow backporting to stable.

This hunk was dropped via rebase onto gen_intermediate_code_internal()
MicroBlazeCPU change:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu to CPUState
  2013-07-01 17:05   ` Richard Henderson
@ 2013-07-02 22:11     ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-02 22:11 UTC (permalink / raw)
  To: Richard Henderson; +Cc: jan.kiszka, qemu-devel

Am 01.07.2013 19:05, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> Since first_cpu/next_cpu are CPUState, CPUArchState is no longer needed.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  gdbstub.c | 9 ++++-----
>>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu()
  2013-07-01 17:14   ` Richard Henderson
@ 2013-07-06  0:42     ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-06  0:42 UTC (permalink / raw)
  To: Richard Henderson; +Cc: jan.kiszka, qemu-devel

Am 01.07.2013 19:14, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> Since commit cb446ecab714b2444a270be209e0533bcd2ee534 (kvm: Change
>> cpu_synchronize_state() argument to CPUState), one was no longer
>> accessing CPUArchState, the other was just checking existence.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  gdbstub.c | 10 +++++-----
>>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses Andreas Färber
@ 2013-07-06 12:55   ` Andreas Färber
  2013-07-06 18:01     ` Max Filippov
  0 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-06 12:55 UTC (permalink / raw)
  To: Max Filippov; +Cc: jan.kiszka, qemu-devel

Max,

Am 29.06.2013 22:01, schrieb Andreas Färber:
> Register a CPU type per core registered. Save the XtensaConfig in
> XtensaCPUClass instead of CPUXtensaState.
> 
> Prepares for storing per-class GDB register count.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Ping! Can you ack? (It did not seem to break your test image.)

Thanks,
Andreas

> ---
>  gdbstub.c                 |  17 ++++---
>  hw/xtensa/pic_cpu.c       |  47 ++++++++++++------
>  target-xtensa/cpu-qom.h   |   3 ++
>  target-xtensa/cpu.c       |  30 ++++++++++--
>  target-xtensa/cpu.h       |  22 +++++----
>  target-xtensa/helper.c    |  93 +++++++++++++++++++++++------------
>  target-xtensa/op_helper.c | 121 ++++++++++++++++++++++++++++++++--------------
>  target-xtensa/translate.c |  12 +++--
>  8 files changed, 236 insertions(+), 109 deletions(-)
> 
> diff --git a/gdbstub.c b/gdbstub.c
> index 4ebe9e0..d08cfd3 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -1692,14 +1692,16 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
>   * reset bit 0 in the 'flags' field of the registers definitions in the
>   * gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
>   */
> -#define NUM_CORE_REGS (env->config->gdb_regmap.num_regs)
> +#define NUM_CORE_REGS \
> +  (XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env))->config->gdb_regmap.num_regs)
>  #define num_g_regs NUM_CORE_REGS
>  
>  static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
>  {
> -    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
> +    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
>  
> -    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
> +    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
>          return 0;
>      }
>  
> @@ -1710,7 +1712,7 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
>  
>      case 1: /*ar*/
>          xtensa_sync_phys_from_window(env);
> -        GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]);
> +        GET_REG32(env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg]);
>          break;
>  
>      case 2: /*SR*/
> @@ -1738,10 +1740,11 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
>  
>  static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
>  {
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
>      uint32_t tmp;
> -    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
> +    const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n;
>  
> -    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
> +    if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) {
>          return 0;
>      }
>  
> @@ -1753,7 +1756,7 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
>          break;
>  
>      case 1: /*ar*/
> -        env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
> +        env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg] = tmp;
>          xtensa_sync_window_from_phys(env);
>          break;
>  
> diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c
> index 7f015ff..048038d 100644
> --- a/hw/xtensa/pic_cpu.c
> +++ b/hw/xtensa/pic_cpu.c
> @@ -31,13 +31,15 @@
>  
>  void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      uint32_t old_ccount = env->sregs[CCOUNT];
>  
>      env->sregs[CCOUNT] += d;
>  
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
>          int i;
> -        for (i = 0; i < env->config->nccompare; ++i) {
> +        for (i = 0; i < xcc->config->nccompare; ++i) {
>              if (env->sregs[CCOMPARE + i] - old_ccount <= d) {
>                  xtensa_timer_irq(env, i, 1);
>              }
> @@ -47,7 +49,9 @@ void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d)
>  
>  void check_interrupts(CPUXtensaState *env)
>  {
> -    CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    CPUState *cs = CPU(cpu);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      int minlevel = xtensa_get_cintlevel(env);
>      uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
>      int level;
> @@ -60,11 +64,11 @@ void check_interrupts(CPUXtensaState *env)
>  
>          xtensa_advance_ccount(env,
>                  muldiv64(now - env->halt_clock,
> -                    env->config->clock_freq_khz, 1000000));
> +                    xcc->config->clock_freq_khz, 1000000));
>          env->halt_clock = now;
>      }
> -    for (level = env->config->nlevel; level > minlevel; --level) {
> -        if (env->config->level_mask[level] & int_set_enabled) {
> +    for (level = xcc->config->nlevel; level > minlevel; --level) {
> +        if (xcc->config->level_mask[level] & int_set_enabled) {
>              env->pending_irq_level = level;
>              cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>              qemu_log_mask(CPU_LOG_INT,
> @@ -86,15 +90,17 @@ void check_interrupts(CPUXtensaState *env)
>  static void xtensa_set_irq(void *opaque, int irq, int active)
>  {
>      CPUXtensaState *env = opaque;
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>  
> -    if (irq >= env->config->ninterrupt) {
> +    if (irq >= xcc->config->ninterrupt) {
>          qemu_log("%s: bad IRQ %d\n", __func__, irq);
>      } else {
>          uint32_t irq_bit = 1 << irq;
>  
>          if (active) {
>              env->sregs[INTSET] |= irq_bit;
> -        } else if (env->config->interrupt[irq].inttype == INTTYPE_LEVEL) {
> +        } else if (xcc->config->interrupt[irq].inttype == INTTYPE_LEVEL) {
>              env->sregs[INTSET] &= ~irq_bit;
>          }
>  
> @@ -104,15 +110,20 @@ static void xtensa_set_irq(void *opaque, int irq, int active)
>  
>  void xtensa_timer_irq(CPUXtensaState *env, uint32_t id, uint32_t active)
>  {
> -    qemu_set_irq(env->irq_inputs[env->config->timerint[id]], active);
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    qemu_set_irq(env->irq_inputs[xcc->config->timerint[id]], active);
>  }
>  
>  void xtensa_rearm_ccompare_timer(CPUXtensaState *env)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      int i;
>      uint32_t wake_ccount = env->sregs[CCOUNT] - 1;
>  
> -    for (i = 0; i < env->config->nccompare; ++i) {
> +    for (i = 0; i < xcc->config->nccompare; ++i) {
>          if (env->sregs[CCOMPARE + i] - env->sregs[CCOUNT] <
>                  wake_ccount - env->sregs[CCOUNT]) {
>              wake_ccount = env->sregs[CCOMPARE + i];
> @@ -121,7 +132,7 @@ void xtensa_rearm_ccompare_timer(CPUXtensaState *env)
>      env->wake_ccount = wake_ccount;
>      qemu_mod_timer(env->ccompare_timer, env->halt_clock +
>              muldiv64(wake_ccount - env->sregs[CCOUNT],
> -                1000000, env->config->clock_freq_khz));
> +                1000000, xcc->config->clock_freq_khz));
>  }
>  
>  static void xtensa_ccompare_cb(void *opaque)
> @@ -143,11 +154,12 @@ static void xtensa_ccompare_cb(void *opaque)
>  void xtensa_irq_init(CPUXtensaState *env)
>  {
>      XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>  
>      env->irq_inputs = (void **)qemu_allocate_irqs(
> -            xtensa_set_irq, env, env->config->ninterrupt);
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT) &&
> -            env->config->nccompare > 0) {
> +            xtensa_set_irq, env, xcc->config->ninterrupt);
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT) &&
> +            xcc->config->nccompare > 0) {
>          env->ccompare_timer =
>              qemu_new_timer_ns(vm_clock, &xtensa_ccompare_cb, cpu);
>      }
> @@ -155,8 +167,11 @@ void xtensa_irq_init(CPUXtensaState *env)
>  
>  void *xtensa_get_extint(CPUXtensaState *env, unsigned extint)
>  {
> -    if (extint < env->config->nextint) {
> -        unsigned irq = env->config->extint[extint];
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (extint < xcc->config->nextint) {
> +        unsigned irq = xcc->config->extint[extint];
>          return env->irq_inputs[irq];
>      } else {
>          qemu_log("%s: trying to acquire invalid external interrupt %d\n",
> diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
> index 944d3cc..878eb15 100644
> --- a/target-xtensa/cpu-qom.h
> +++ b/target-xtensa/cpu-qom.h
> @@ -45,6 +45,7 @@
>   * XtensaCPUClass:
>   * @parent_realize: The parent class' realize handler.
>   * @parent_reset: The parent class' reset handler.
> + * @config: The CPU core configuration.
>   *
>   * An Xtensa CPU model.
>   */
> @@ -55,6 +56,8 @@ typedef struct XtensaCPUClass {
>  
>      DeviceRealize parent_realize;
>      void (*parent_reset)(CPUState *cpu);
> +
> +    const XtensaConfig *config;
>  } XtensaCPUClass;
>  
>  /**
> diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
> index 6556caa..75762ad 100644
> --- a/target-xtensa/cpu.c
> +++ b/target-xtensa/cpu.c
> @@ -50,20 +50,39 @@ static void xtensa_cpu_reset(CPUState *s)
>      xcc->parent_reset(s);
>  
>      env->exception_taken = 0;
> -    env->pc = env->config->exception_vector[EXC_RESET];
> +    env->pc = xcc->config->exception_vector[EXC_RESET];
>      env->sregs[LITBASE] &= ~1;
> -    env->sregs[PS] = xtensa_option_enabled(env->config,
> +    env->sregs[PS] = xtensa_option_enabled(xcc->config,
>              XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
> -    env->sregs[VECBASE] = env->config->vecbase;
> +    env->sregs[VECBASE] = xcc->config->vecbase;
>      env->sregs[IBREAKENABLE] = 0;
>      env->sregs[CACHEATTR] = 0x22222222;
> -    env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
> +    env->sregs[ATOMCTL] = xtensa_option_enabled(xcc->config,
>              XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
>  
>      env->pending_irq_level = 0;
>      reset_mmu(env);
>  }
>  
> +static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
> +{
> +    ObjectClass *oc;
> +    char *typename;
> +
> +    if (cpu_model == NULL) {
> +        return NULL;
> +    }
> +
> +    typename = g_strdup_printf("%s-" TYPE_XTENSA_CPU, cpu_model);
> +    oc = object_class_by_name(typename);
> +    g_free(typename);
> +    if (!oc || !object_class_dynamic_cast(oc, TYPE_XTENSA_CPU) ||
> +        object_class_is_abstract(oc)) {
> +        return NULL;
> +    }
> +    return oc;
> +}
> +
>  static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
>  {
>      XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
> @@ -105,6 +124,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
>      xcc->parent_reset = cc->reset;
>      cc->reset = xtensa_cpu_reset;
>  
> +    cc->class_by_name = xtensa_cpu_class_by_name;
>      cc->do_interrupt = xtensa_cpu_do_interrupt;
>      cc->dump_state = xtensa_cpu_dump_state;
>      cc->set_pc = xtensa_cpu_set_pc;
> @@ -119,7 +139,7 @@ static const TypeInfo xtensa_cpu_type_info = {
>      .parent = TYPE_CPU,
>      .instance_size = sizeof(XtensaCPU),
>      .instance_init = xtensa_cpu_initfn,
> -    .abstract = false,
> +    .abstract = true,
>      .class_size = sizeof(XtensaCPUClass),
>      .class_init = xtensa_cpu_class_init,
>  };
> diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
> index a8f02f6..9ad0ac6 100644
> --- a/target-xtensa/cpu.h
> +++ b/target-xtensa/cpu.h
> @@ -333,7 +333,6 @@ typedef struct XtensaConfigList {
>  } XtensaConfigList;
>  
>  typedef struct CPUXtensaState {
> -    const XtensaConfig *config;
>      uint32_t regs[16];
>      uint32_t pc;
>      uint32_t sregs[256];
> @@ -432,16 +431,18 @@ static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt)
>  
>  static inline int xtensa_get_cintlevel(const CPUXtensaState *env)
>  {
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
>      int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT;
> -    if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) {
> -        level = env->config->excm_level;
> +    if ((env->sregs[PS] & PS_EXCM) && xcc->config->excm_level > level) {
> +        level = xcc->config->excm_level;
>      }
>      return level;
>  }
>  
>  static inline int xtensa_get_ring(const CPUXtensaState *env)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
>      } else {
>          return 0;
> @@ -450,7 +451,8 @@ static inline int xtensa_get_ring(const CPUXtensaState *env)
>  
>  static inline int xtensa_get_cring(const CPUXtensaState *env)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) &&
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU) &&
>              (env->sregs[PS] & PS_EXCM) == 0) {
>          return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
>      } else {
> @@ -488,6 +490,8 @@ static inline int cpu_mmu_index(CPUXtensaState *env)
>  static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
>          target_ulong *cs_base, int *flags)
>  {
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env));
> +
>      *pc = env->pc;
>      *cs_base = 0;
>      *flags = 0;
> @@ -495,19 +499,19 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
>      if (env->sregs[PS] & PS_EXCM) {
>          *flags |= XTENSA_TBFLAG_EXCM;
>      }
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) &&
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_EXTENDED_L32R) &&
>              (env->sregs[LITBASE] & 1)) {
>          *flags |= XTENSA_TBFLAG_LITBASE;
>      }
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) {
> -        if (xtensa_get_cintlevel(env) < env->config->debug_level) {
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_DEBUG)) {
> +        if (xtensa_get_cintlevel(env) < xcc->config->debug_level) {
>              *flags |= XTENSA_TBFLAG_DEBUG;
>          }
>          if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) {
>              *flags |= XTENSA_TBFLAG_ICOUNT;
>          }
>      }
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_COPROCESSOR)) {
>          *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
>      }
>  }
> diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
> index a67c849..a1e524d 100644
> --- a/target-xtensa/helper.c
> +++ b/target-xtensa/helper.c
> @@ -35,17 +35,36 @@
>  
>  static struct XtensaConfigList *xtensa_cores;
>  
> +static void xtensa_core_class_init(ObjectClass *oc, void *data)
> +{
> +    XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
> +    const XtensaConfig *config = data;
> +
> +    xcc->config = config;
> +}
> +
>  void xtensa_register_core(XtensaConfigList *node)
>  {
> +    TypeInfo type = {
> +        .parent = TYPE_XTENSA_CPU,
> +        .class_init = xtensa_core_class_init,
> +        .class_data = (void *)node->config,
> +    };
> +
>      node->next = xtensa_cores;
>      xtensa_cores = node;
> +    type.name = g_strdup_printf("%s-" TYPE_XTENSA_CPU, node->config->name);
> +    type_register(&type);
> +    g_free((gpointer)type.name);
>  }
>  
>  static uint32_t check_hw_breakpoints(CPUXtensaState *env)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      unsigned i;
>  
> -    for (i = 0; i < env->config->ndbreak; ++i) {
> +    for (i = 0; i < xcc->config->ndbreak; ++i) {
>          if (env->cpu_watchpoint[i] &&
>                  env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) {
>              return DEBUGCAUSE_DB | (i << DEBUGCAUSE_DBNUM_SHIFT);
> @@ -72,24 +91,17 @@ void xtensa_breakpoint_handler(CPUXtensaState *env)
>  
>  XtensaCPU *cpu_xtensa_init(const char *cpu_model)
>  {
> +    ObjectClass *oc;
>      XtensaCPU *cpu;
>      CPUXtensaState *env;
> -    const XtensaConfig *config = NULL;
> -    XtensaConfigList *core = xtensa_cores;
>  
> -    for (; core; core = core->next)
> -        if (strcmp(core->config->name, cpu_model) == 0) {
> -            config = core->config;
> -            break;
> -        }
> -
> -    if (config == NULL) {
> +    oc = cpu_class_by_name(TYPE_XTENSA_CPU, cpu_model);
> +    if (oc == NULL) {
>          return NULL;
>      }
>  
> -    cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU));
> +    cpu = XTENSA_CPU(object_new(object_class_get_name(oc)));
>      env = &cpu->env;
> -    env->config = config;
>  
>      xtensa_irq_init(env);
>  
> @@ -128,9 +140,12 @@ hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, uint64_t addr)
>  
>  static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
>  {
> -    if (xtensa_option_enabled(env->config,
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config,
>                  XTENSA_OPTION_RELOCATABLE_VECTOR)) {
> -        return vector - env->config->vecbase + env->sregs[VECBASE];
> +        return vector - xcc->config->vecbase + env->sregs[VECBASE];
>      } else {
>          return vector;
>      }
> @@ -144,11 +159,13 @@ static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
>   */
>  static void handle_interrupt(CPUXtensaState *env)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      int level = env->pending_irq_level;
>  
>      if (level > xtensa_get_cintlevel(env) &&
> -            level <= env->config->nlevel &&
> -            (env->config->level_mask[level] &
> +            level <= xcc->config->nlevel &&
> +            (xcc->config->level_mask[level] &
>               env->sregs[INTSET] &
>               env->sregs[INTENABLE])) {
>          if (level > 1) {
> @@ -157,12 +174,12 @@ static void handle_interrupt(CPUXtensaState *env)
>              env->sregs[PS] =
>                  (env->sregs[PS] & ~PS_INTLEVEL) | level | PS_EXCM;
>              env->pc = relocated_vector(env,
> -                    env->config->interrupt_vector[level]);
> +                    xcc->config->interrupt_vector[level]);
>          } else {
>              env->sregs[EXCCAUSE] = LEVEL1_INTERRUPT_CAUSE;
>  
>              if (env->sregs[PS] & PS_EXCM) {
> -                if (env->config->ndepc) {
> +                if (xcc->config->ndepc) {
>                      env->sregs[DEPC] = env->pc;
>                  } else {
>                      env->sregs[EPC1] = env->pc;
> @@ -182,6 +199,7 @@ static void handle_interrupt(CPUXtensaState *env)
>  void xtensa_cpu_do_interrupt(CPUState *cs)
>  {
>      XtensaCPU *cpu = XTENSA_CPU(cs);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      CPUXtensaState *env = &cpu->env;
>  
>      if (env->exception_index == EXC_IRQ) {
> @@ -212,9 +230,9 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
>                  "pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n",
>                  __func__, env->exception_index,
>                  env->pc, env->regs[0], env->sregs[PS], env->sregs[CCOUNT]);
> -        if (env->config->exception_vector[env->exception_index]) {
> +        if (xcc->config->exception_vector[env->exception_index]) {
>              env->pc = relocated_vector(env,
> -                    env->config->exception_vector[env->exception_index]);
> +                    xcc->config->exception_vector[env->exception_index]);
>              env->exception_taken = 1;
>          } else {
>              qemu_log("%s(pc = %08x) bad exception_index: %d\n",
> @@ -309,15 +327,18 @@ static void reset_tlb_region_way0(CPUXtensaState *env,
>  
>  void reset_mmu(CPUXtensaState *env)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          env->sregs[RASID] = 0x04030201;
>          env->sregs[ITLBCFG] = 0;
>          env->sregs[DTLBCFG] = 0;
>          env->autorefill_idx = 0;
> -        reset_tlb_mmu_all_ways(env, &env->config->itlb, env->itlb);
> -        reset_tlb_mmu_all_ways(env, &env->config->dtlb, env->dtlb);
> -        reset_tlb_mmu_ways56(env, &env->config->itlb, env->itlb);
> -        reset_tlb_mmu_ways56(env, &env->config->dtlb, env->dtlb);
> +        reset_tlb_mmu_all_ways(env, &xcc->config->itlb, env->itlb);
> +        reset_tlb_mmu_all_ways(env, &xcc->config->dtlb, env->dtlb);
> +        reset_tlb_mmu_ways56(env, &xcc->config->itlb, env->itlb);
> +        reset_tlb_mmu_ways56(env, &xcc->config->dtlb, env->dtlb);
>      } else {
>          reset_tlb_region_way0(env, env->itlb);
>          reset_tlb_region_way0(env, env->dtlb);
> @@ -347,8 +368,10 @@ static unsigned get_ring(const CPUXtensaState *env, uint8_t asid)
>  int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
>          uint32_t *pwi, uint32_t *pei, uint8_t *pring)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      const xtensa_tlb *tlb = dtlb ?
> -        &env->config->dtlb : &env->config->itlb;
> +        &xcc->config->dtlb : &xcc->config->itlb;
>      const xtensa_tlb_entry (*entry)[MAX_TLB_WAY_SIZE] = dtlb ?
>          env->dtlb : env->itlb;
>  
> @@ -586,10 +609,13 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
>          uint32_t vaddr, int is_write, int mmu_idx,
>          uint32_t *paddr, uint32_t *page_size, unsigned *access)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          return get_physical_addr_mmu(env, update_tlb,
>                  vaddr, is_write, mmu_idx, paddr, page_size, access, true);
> -    } else if (xtensa_option_bits_enabled(env->config,
> +    } else if (xtensa_option_bits_enabled(xcc->config,
>                  XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
>                  XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) {
>          return get_physical_addr_region(env, vaddr, is_write, mmu_idx,
> @@ -606,11 +632,13 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
>  static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
>          CPUXtensaState *env, bool dtlb)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      unsigned wi, ei;
>      const xtensa_tlb *conf =
> -        dtlb ? &env->config->dtlb : &env->config->itlb;
> +        dtlb ? &xcc->config->dtlb : &xcc->config->itlb;
>      unsigned (*attr_to_access)(uint32_t) =
> -        xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) ?
> +        xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU) ?
>          mmu_attr_to_access : region_attr_to_access;
>  
>      for (wi = 0; wi < conf->nways; ++wi) {
> @@ -666,7 +694,10 @@ static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
>  
>  void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env)
>  {
> -    if (xtensa_option_bits_enabled(env->config,
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_bits_enabled(xcc->config,
>                  XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
>                  XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION) |
>                  XTENSA_OPTION_BIT(XTENSA_OPTION_MMU))) {
> diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
> index 4c41de0..2f08766 100644
> --- a/target-xtensa/op_helper.c
> +++ b/target-xtensa/op_helper.c
> @@ -50,8 +50,11 @@ static void do_unaligned_access(CPUXtensaState *env,
>  static void do_unaligned_access(CPUXtensaState *env,
>          target_ulong addr, int is_write, int is_user, uintptr_t retaddr)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
> -            !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
> +            !xtensa_option_enabled(xcc->config, XTENSA_OPTION_HW_ALIGNMENT)) {
>          cpu_restore_state(env, retaddr);
>          HELPER(exception_cause_vaddr)(env,
>                  env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
> @@ -101,11 +104,13 @@ void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
>  
>  void HELPER(exception_cause)(CPUXtensaState *env, uint32_t pc, uint32_t cause)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      uint32_t vector;
>  
>      env->pc = pc;
>      if (env->sregs[PS] & PS_EXCM) {
> -        if (env->config->ndepc) {
> +        if (xcc->config->ndepc) {
>              env->sregs[DEPC] = pc;
>          } else {
>              env->sregs[EPC1] = pc;
> @@ -131,14 +136,19 @@ void HELPER(exception_cause_vaddr)(CPUXtensaState *env,
>  
>  void debug_exception_env(CPUXtensaState *env, uint32_t cause)
>  {
> -    if (xtensa_get_cintlevel(env) < env->config->debug_level) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_get_cintlevel(env) < xcc->config->debug_level) {
>          HELPER(debug_exception)(env, env->pc, cause);
>      }
>  }
>  
>  void HELPER(debug_exception)(CPUXtensaState *env, uint32_t pc, uint32_t cause)
>  {
> -    unsigned level = env->config->debug_level;
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +    unsigned level = xcc->config->debug_level;
>  
>      env->pc = pc;
>      env->sregs[DEBUGCAUSE] = cause;
> @@ -165,12 +175,15 @@ uint32_t HELPER(nsau)(uint32_t v)
>  static void copy_window_from_phys(CPUXtensaState *env,
>          uint32_t window, uint32_t phys, uint32_t n)
>  {
> -    assert(phys < env->config->nareg);
> -    if (phys + n <= env->config->nareg) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    assert(phys < xcc->config->nareg);
> +    if (phys + n <= xcc->config->nareg) {
>          memcpy(env->regs + window, env->phys_regs + phys,
>                  n * sizeof(uint32_t));
>      } else {
> -        uint32_t n1 = env->config->nareg - phys;
> +        uint32_t n1 = xcc->config->nareg - phys;
>          memcpy(env->regs + window, env->phys_regs + phys,
>                  n1 * sizeof(uint32_t));
>          memcpy(env->regs + window + n1, env->phys_regs,
> @@ -181,12 +194,15 @@ static void copy_window_from_phys(CPUXtensaState *env,
>  static void copy_phys_from_window(CPUXtensaState *env,
>          uint32_t phys, uint32_t window, uint32_t n)
>  {
> -    assert(phys < env->config->nareg);
> -    if (phys + n <= env->config->nareg) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    assert(phys < xcc->config->nareg);
> +    if (phys + n <= xcc->config->nareg) {
>          memcpy(env->phys_regs + phys, env->regs + window,
>                  n * sizeof(uint32_t));
>      } else {
> -        uint32_t n1 = env->config->nareg - phys;
> +        uint32_t n1 = xcc->config->nareg - phys;
>          memcpy(env->phys_regs + phys, env->regs + window,
>                  n1 * sizeof(uint32_t));
>          memcpy(env->phys_regs, env->regs + window + n1,
> @@ -197,7 +213,10 @@ static void copy_phys_from_window(CPUXtensaState *env,
>  
>  static inline unsigned windowbase_bound(unsigned a, const CPUXtensaState *env)
>  {
> -    return a & (env->config->nareg / 4 - 1);
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    return a & (xcc->config->nareg / 4 - 1);
>  }
>  
>  static inline unsigned windowstart_bit(unsigned a, const CPUXtensaState *env)
> @@ -375,7 +394,9 @@ void HELPER(dump_state)(CPUXtensaState *env)
>  
>  void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
>  {
> -    CPUState *cpu;
> +    CPUState *cs;
> +    XtensaCPU *cpu;
> +    XtensaCPUClass *xcc;
>  
>      env->pc = pc;
>      env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) |
> @@ -386,10 +407,12 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
>          return;
>      }
>  
> -    cpu = CPU(xtensa_env_get_cpu(env));
> +    cpu = xtensa_env_get_cpu(env);
> +    cs = CPU(cpu);
> +    xcc = XTENSA_CPU_GET_CLASS(cpu);
>      env->halt_clock = qemu_get_clock_ns(vm_clock);
> -    cpu->halted = 1;
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
> +    cs->halted = 1;
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
>          xtensa_rearm_ccompare_timer(env);
>      }
>      HELPER(exception)(env, EXCP_HLT);
> @@ -418,6 +441,8 @@ void HELPER(check_interrupts)(CPUXtensaState *env)
>   */
>  void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      uint32_t paddr, page_size, access;
>      uint32_t atomctl = env->sregs[ATOMCTL];
>      int rc = xtensa_get_physical_addr(env, true, vaddr, 1,
> @@ -441,7 +466,7 @@ void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
>       * See ISA, 4.3.12.4 The Atomic Operation Control Register (ATOMCTL)
>       * under the Conditional Store Option.
>       */
> -    if (!xtensa_option_enabled(env->config, XTENSA_OPTION_DCACHE)) {
> +    if (!xtensa_option_enabled(xcc->config, XTENSA_OPTION_DCACHE)) {
>          access = PAGE_CACHE_BYPASS;
>      }
>  
> @@ -500,10 +525,13 @@ static uint32_t get_page_size(const CPUXtensaState *env, bool dtlb, uint32_t way
>   */
>  uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          bool varway56 = dtlb ?
> -            env->config->dtlb.varway56 :
> -            env->config->itlb.varway56;
> +            xcc->config->dtlb.varway56 :
> +            xcc->config->itlb.varway56;
>  
>          switch (way) {
>          case 4:
> @@ -537,18 +565,21 @@ uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t
>   */
>  static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
>      if (way < 4) {
>          bool is32 = (dtlb ?
> -                env->config->dtlb.nrefillentries :
> -                env->config->itlb.nrefillentries) == 32;
> +                xcc->config->dtlb.nrefillentries :
> +                xcc->config->itlb.nrefillentries) == 32;
>          return is32 ? 0xffff8000 : 0xffffc000;
>      } else if (way == 4) {
>          return xtensa_tlb_get_addr_mask(env, dtlb, way) << 2;
>      } else if (way <= 6) {
>          uint32_t mask = xtensa_tlb_get_addr_mask(env, dtlb, way);
>          bool varway56 = dtlb ?
> -            env->config->dtlb.varway56 :
> -            env->config->itlb.varway56;
> +            xcc->config->dtlb.varway56 :
> +            xcc->config->itlb.varway56;
>  
>          if (varway56) {
>              return mask << (way == 5 ? 2 : 3);
> @@ -567,9 +598,11 @@ static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
>  void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
>          uint32_t *vpn, uint32_t wi, uint32_t *ei)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      bool varway56 = dtlb ?
> -        env->config->dtlb.varway56 :
> -        env->config->itlb.varway56;
> +        xcc->config->dtlb.varway56 :
> +        xcc->config->itlb.varway56;
>  
>      if (!dtlb) {
>          wi &= 7;
> @@ -577,8 +610,8 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
>  
>      if (wi < 4) {
>          bool is32 = (dtlb ?
> -                env->config->dtlb.nrefillentries :
> -                env->config->itlb.nrefillentries) == 32;
> +                xcc->config->dtlb.nrefillentries :
> +                xcc->config->itlb.nrefillentries) == 32;
>          *ei = (v >> 12) & (is32 ? 0x7 : 0x3);
>      } else {
>          switch (wi) {
> @@ -622,7 +655,10 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
>  static void split_tlb_entry_spec(CPUXtensaState *env, uint32_t v, bool dtlb,
>          uint32_t *vpn, uint32_t *wi, uint32_t *ei)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          *wi = v & (dtlb ? 0xf : 0x7);
>          split_tlb_entry_spec_way(env, v, dtlb, vpn, *wi, ei);
>      } else {
> @@ -648,7 +684,10 @@ static xtensa_tlb_entry *get_tlb_entry(CPUXtensaState *env,
>  
>  uint32_t HELPER(rtlb0)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          uint32_t wi;
>          const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi);
>          return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid;
> @@ -665,7 +704,10 @@ uint32_t HELPER(rtlb1)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
>  
>  void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          uint32_t wi;
>          xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi);
>          if (entry->variable && entry->asid) {
> @@ -677,7 +719,10 @@ void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
>  
>  uint32_t HELPER(ptlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
>  {
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
> +
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          uint32_t wi;
>          uint32_t ei;
>          uint8_t ring;
> @@ -714,9 +759,11 @@ void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
>  void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
>          unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      xtensa_tlb_entry *entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);
>  
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_MMU)) {
>          if (entry->variable) {
>              if (entry->asid) {
>                  tlb_flush_page(env, entry->vaddr);
> @@ -729,7 +776,7 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
>          }
>      } else {
>          tlb_flush_page(env, entry->vaddr);
> -        if (xtensa_option_enabled(env->config,
> +        if (xtensa_option_enabled(xcc->config,
>                      XTENSA_OPTION_REGION_TRANSLATION)) {
>              entry->paddr = pte & REGION_PAGE_MASK;
>          }
> @@ -749,15 +796,17 @@ void HELPER(wtlb)(CPUXtensaState *env, uint32_t p, uint32_t v, uint32_t dtlb)
>  
>  void HELPER(wsr_ibreakenable)(CPUXtensaState *env, uint32_t v)
>  {
> +    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      uint32_t change = v ^ env->sregs[IBREAKENABLE];
>      unsigned i;
>  
> -    for (i = 0; i < env->config->nibreak; ++i) {
> +    for (i = 0; i < xcc->config->nibreak; ++i) {
>          if (change & (1 << i)) {
>              tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]);
>          }
>      }
> -    env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1);
> +    env->sregs[IBREAKENABLE] = v & ((1 << xcc->config->nibreak) - 1);
>  }
>  
>  void HELPER(wsr_ibreaka)(CPUXtensaState *env, uint32_t i, uint32_t v)
> diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
> index cc36fa4..c64b54e 100644
> --- a/target-xtensa/translate.c
> +++ b/target-xtensa/translate.c
> @@ -2881,6 +2881,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
>  {
>      CPUState *cs = CPU(cpu);
>      CPUXtensaState *env = &cpu->env;
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
>      DisasContext dc;
>      int insn_count = 0;
>      int j, lj = -1;
> @@ -2894,7 +2895,7 @@ static void gen_intermediate_code_internal(XtensaCPU *cpu,
>          max_insns = CF_COUNT_MASK;
>      }
>  
> -    dc.config = env->config;
> +    dc.config = xcc->config;
>      dc.singlestep_enabled = cs->singlestep_enabled;
>      dc.tb = tb;
>      dc.pc = pc_start;
> @@ -3021,13 +3022,14 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
>                             fprintf_function cpu_fprintf, int flags)
>  {
>      XtensaCPU *cpu = XTENSA_CPU(cs);
> +    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cs);
>      CPUXtensaState *env = &cpu->env;
>      int i, j;
>  
>      cpu_fprintf(f, "PC=%08x\n\n", env->pc);
>  
>      for (i = j = 0; i < 256; ++i) {
> -        if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
> +        if (xtensa_option_bits_enabled(xcc->config, sregnames[i].opt_bits)) {
>              cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
>                      (j++ % 4) == 3 ? '\n' : ' ');
>          }
> @@ -3036,7 +3038,7 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
>      cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
>  
>      for (i = j = 0; i < 256; ++i) {
> -        if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
> +        if (xtensa_option_bits_enabled(xcc->config, uregnames[i].opt_bits)) {
>              cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
>                      (j++ % 4) == 3 ? '\n' : ' ');
>          }
> @@ -3051,12 +3053,12 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
>  
>      cpu_fprintf(f, "\n");
>  
> -    for (i = 0; i < env->config->nareg; ++i) {
> +    for (i = 0; i < xcc->config->nareg; ++i) {
>          cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
>                  (i % 4) == 3 ? '\n' : ' ');
>      }
>  
> -    if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
> +    if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_FP_COPROCESSOR)) {
>          cpu_fprintf(f, "\n");
>  
>          for (i = 0; i < 16; ++i) {
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 12:55   ` Andreas Färber
@ 2013-07-06 18:01     ` Max Filippov
  2013-07-06 18:39       ` Max Filippov
                         ` (2 more replies)
  0 siblings, 3 replies; 85+ messages in thread
From: Max Filippov @ 2013-07-06 18:01 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
> Max,
>
> Am 29.06.2013 22:01, schrieb Andreas Färber:
>> Register a CPU type per core registered. Save the XtensaConfig in
>> XtensaCPUClass instead of CPUXtensaState.
>>
>> Prepares for storing per-class GDB register count.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>
> Ping! Can you ack? (It did not seem to break your test image.)

Hi Andreas,

I tried make check -C tests/tcg/xtensa with the branch you recommended
and it segfaults on elf loading:

#0  object_class_dynamic_cast_assert (class=0x0,
typename=typename@entry=0x55555573a85e "cpu",
file=file@entry=0x5555557349c8
"/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/include/qom/cpu.h",
line=line@entry=290, func=func@entry=
    0x555555735770 <__func__.17127> "cpu_get_phys_page_debug") at
/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/qom/object.c:535
#1  0x00005555556b884b in cpu_get_phys_page_debug (addr=3489660928,
cpu=0x555556275a30) at
/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/include/qom/cpu.h:290
#2  translate_phys_addr (env=0x555556275a30, addr=3489660928) at
/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/hw/xtensa/xtensa_sim.c:37
#3  0x0000555555602b9b in load_elf32 (clear_lsb=0, elf_machine=94,
highaddr=0x0, lowaddr=0x7fffffffd3b0, pentry=0x7fffffffd3a8,
must_swab=<optimized out>, translate_opaque=0x555556275a30,
translate_fn=
    0x5555556b8800 <translate_phys_addr>, fd=10, name=0x555556267df0
"./test_b.tst") at
/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/include/hw/elf_ops.h:269
#4  load_elf (filename=filename@entry=0x555556267df0 "./test_b.tst",
translate_fn=translate_fn@entry=0x5555556b8800 <translate_phys_addr>,
translate_opaque=translate_opaque@entry=0x555556275a30,
pentry=pentry@entry=
    0x7fffffffd3a8, lowaddr=lowaddr@entry=0x7fffffffd3b0,
highaddr=highaddr@entry=0x0, big_endian=big_endian@entry=0,
elf_machine=elf_machine@entry=94, clear_lsb=clear_lsb@entry=0)
    at /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/hw/core/loader.c:326
#5  0x00005555556b8a23 in xtensa_sim_init (args=<optimized out>) at
/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/hw/xtensa/xtensa_sim.c:94
#6  0x000055555559cf6f in main (argc=<optimized out>, argv=<optimized
out>, envp=<optimized out>) at
/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/vl.c:4286

The mainline is ok.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 18:01     ` Max Filippov
@ 2013-07-06 18:39       ` Max Filippov
  2013-07-06 19:12         ` Andreas Färber
  2013-07-06 18:45       ` Andreas Färber
  2013-07-06 19:45       ` Andreas Färber
  2 siblings, 1 reply; 85+ messages in thread
From: Max Filippov @ 2013-07-06 18:39 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On Sat, Jul 6, 2013 at 10:01 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Max,
>>
>> Am 29.06.2013 22:01, schrieb Andreas Färber:
>>> Register a CPU type per core registered. Save the XtensaConfig in
>>> XtensaCPUClass instead of CPUXtensaState.
>>>
>>> Prepares for storing per-class GDB register count.
>>>
>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>
>> Ping! Can you ack? (It did not seem to break your test image.)
>
> Hi Andreas,
>
> I tried make check -C tests/tcg/xtensa with the branch you recommended
> and it segfaults on elf loading

...and maybe a stupid question, but why moving configuration pointer away
from env and then changing every place that used to access it?

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 18:01     ` Max Filippov
  2013-07-06 18:39       ` Max Filippov
@ 2013-07-06 18:45       ` Andreas Färber
  2013-07-06 19:41         ` Max Filippov
  2013-07-06 19:45       ` Andreas Färber
  2 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-06 18:45 UTC (permalink / raw)
  To: Max Filippov; +Cc: jan.kiszka, qemu-devel

Hi Max,

Am 06.07.2013 20:01, schrieb Max Filippov:
> On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Am 29.06.2013 22:01, schrieb Andreas Färber:
>>> Register a CPU type per core registered. Save the XtensaConfig in
>>> XtensaCPUClass instead of CPUXtensaState.
>>>
>>> Prepares for storing per-class GDB register count.
>>>
>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>
>> Ping! Can you ack? (It did not seem to break your test image.)
> 
> I tried make check -C tests/tcg/xtensa with the branch you recommended
> and it segfaults on elf loading:

That's weird, I'm seeing a similar breakage with the test image on
today's qom-cpu-11 branch. It is not caused by this commit though, so
must be something I reordered last minute... sorry.

The make command above was not working, I've sent a patch for
out-of-tree builds and to update it to the current tree layout with tcg/
subdirectory.

Andreas

> #0  object_class_dynamic_cast_assert (class=0x0,
> typename=typename@entry=0x55555573a85e "cpu",
> file=file@entry=0x5555557349c8
> "/home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/include/qom/cpu.h",
> line=line@entry=290, func=func@entry=
>     0x555555735770 <__func__.17127> "cpu_get_phys_page_debug") at
> /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/qom/object.c:535
> #1  0x00005555556b884b in cpu_get_phys_page_debug (addr=3489660928,
> cpu=0x555556275a30) at
> /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/include/qom/cpu.h:290
> #2  translate_phys_addr (env=0x555556275a30, addr=3489660928) at
> /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/hw/xtensa/xtensa_sim.c:37
> #3  0x0000555555602b9b in load_elf32 (clear_lsb=0, elf_machine=94,
> highaddr=0x0, lowaddr=0x7fffffffd3b0, pentry=0x7fffffffd3a8,
> must_swab=<optimized out>, translate_opaque=0x555556275a30,
> translate_fn=
>     0x5555556b8800 <translate_phys_addr>, fd=10, name=0x555556267df0
> "./test_b.tst") at
> /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/include/hw/elf_ops.h:269
> #4  load_elf (filename=filename@entry=0x555556267df0 "./test_b.tst",
> translate_fn=translate_fn@entry=0x5555556b8800 <translate_phys_addr>,
> translate_opaque=translate_opaque@entry=0x555556275a30,
> pentry=pentry@entry=
>     0x7fffffffd3a8, lowaddr=lowaddr@entry=0x7fffffffd3b0,
> highaddr=highaddr@entry=0x0, big_endian=big_endian@entry=0,
> elf_machine=elf_machine@entry=94, clear_lsb=clear_lsb@entry=0)
>     at /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/hw/core/loader.c:326
> #5  0x00005555556b8a23 in xtensa_sim_init (args=<optimized out>) at
> /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/hw/xtensa/xtensa_sim.c:94
> #6  0x000055555559cf6f in main (argc=<optimized out>, argv=<optimized
> out>, envp=<optimized out>) at
> /home/jcmvbkbc/ws/m/awt/emu/xtensa/qemu/vl.c:4286
> 
> The mainline is ok.
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 18:39       ` Max Filippov
@ 2013-07-06 19:12         ` Andreas Färber
  2013-07-06 19:54           ` Max Filippov
  0 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-06 19:12 UTC (permalink / raw)
  To: Max Filippov; +Cc: jan.kiszka, qemu-devel

Am 06.07.2013 20:39, schrieb Max Filippov:
> On Sat, Jul 6, 2013 at 10:01 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>> On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
>>> Am 29.06.2013 22:01, schrieb Andreas Färber:
>>>> Register a CPU type per core registered. Save the XtensaConfig in
>>>> XtensaCPUClass instead of CPUXtensaState.
>>>>
>>>> Prepares for storing per-class GDB register count.
>>>>
>>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>>
>>> Ping! Can you ack? (It did not seem to break your test image.)
>>
>> Hi Andreas,
>>
>> I tried make check -C tests/tcg/xtensa with the branch you recommended
>> and it segfaults on elf loading
> 
> ...and maybe a stupid question, but why moving configuration pointer away
> from env and then changing every place that used to access it?

Xtensa is the only target trying to implicitly access an "env" variable
through a macro to obtain the number of registers for gdbstub. That's
what I'm trying to fix with 40/41 in order to get rid of the #ifdeffery.

The number of registers is not accessed by TCG, so it could go into
XtensaCPU instead of CPUXtensaState.
Further it does not change during vCPU runtime, so it no longer belongs
in CPUXtensaState nor XtensaCPU but in XtensaCPUClass, which is shared
among CPU cores and can be accessed statically.
However we only had one XtensaCPUClass but multiple XtensaConfigs.
Therefore this patch registers one XtensaCPUClass per XtensaConfig.

You might remember that I once tried to place the XtensaConfig fields
directly into XtensaCPUClass but that didn't work out nicely back then.
This is by comparison a slim/minimal conversion to subclasses, leaving
XtensaConfig and your custom registration mechanisms in place. Cleaning
that up to use type_init() and type_register_static() in the respective
source files and changing -cpu ? to iterate QOM types would be a nice
follow-up, but not needed for this gdbstub refactoring series.

Another background is that I'm trying to get rid of cpu_init() and
anything that blocks using -device or device_add with QOM CPUs.

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register()
  2013-07-01 18:07   ` Richard Henderson
@ 2013-07-06 19:18     ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-06 19:18 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, qemu-devel, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, jan.kiszka, Paul Brook,
	Edgar E. Iglesias, Aurelien Jarno

Am 01.07.2013 20:07, schrieb Richard Henderson:
> On 06/29/2013 01:01 PM, Andreas Färber wrote:
>> Replace GET_REG*() macros by gdb_get_reg*() inline functions for
>> clarity and drop breaks after return.
>>
>> Allows to move target-specific code to new target-*/gdbstub.c files.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
> 
> This one's quite hard to read.

True. Apart from the IMO too generically named GET_REG*() macros, I
needed to fix an awful number of Coding Style issues, which we might
want to do upfront. I could also do the GET_REG*() -> gdb_get_reg*()
sweep in place and split off the break cleanups, too.

> I wonder if there's value in splitting out functions one target at a time into
> the new gdbstub.c files, and only afterward performing a few minor textual
> changes to transform those functions into the CPUClass methods?

That's not so easy, but I'll think of something. #include'ing the C
files until the final change to CPUClass hooks might work...

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 18:45       ` Andreas Färber
@ 2013-07-06 19:41         ` Max Filippov
  0 siblings, 0 replies; 85+ messages in thread
From: Max Filippov @ 2013-07-06 19:41 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On Sat, Jul 6, 2013 at 10:45 PM, Andreas Färber <afaerber@suse.de> wrote:
> Hi Max,
>
> Am 06.07.2013 20:01, schrieb Max Filippov:
>> On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
>>> Am 29.06.2013 22:01, schrieb Andreas Färber:
>>>> Register a CPU type per core registered. Save the XtensaConfig in
>>>> XtensaCPUClass instead of CPUXtensaState.
>>>>
>>>> Prepares for storing per-class GDB register count.
>>>>
>>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>>
>>> Ping! Can you ack? (It did not seem to break your test image.)
>>
>> I tried make check -C tests/tcg/xtensa with the branch you recommended
>> and it segfaults on elf loading:
>
> That's weird, I'm seeing a similar breakage with the test image on
> today's qom-cpu-11 branch. It is not caused by this commit though, so
> must be something I reordered last minute... sorry.
>
> The make command above was not working, I've sent a patch for
> out-of-tree builds and to update it to the current tree layout with tcg/
> subdirectory.

I have actually always been using it in-tree, adjusting PATH to pick up
qemu-system-xtensa from the correct build tree... I've made a couple
more fixes to your patch so that it actually builds and runs tests
out-of-tree.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 18:01     ` Max Filippov
  2013-07-06 18:39       ` Max Filippov
  2013-07-06 18:45       ` Andreas Färber
@ 2013-07-06 19:45       ` Andreas Färber
  2 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-06 19:45 UTC (permalink / raw)
  To: Max Filippov; +Cc: jan.kiszka, qemu-devel

Am 06.07.2013 20:01, schrieb Max Filippov:
> On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Max,
>>
>> Am 29.06.2013 22:01, schrieb Andreas Färber:
>>> Register a CPU type per core registered. Save the XtensaConfig in
>>> XtensaCPUClass instead of CPUXtensaState.
>>>
>>> Prepares for storing per-class GDB register count.
>>>
>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>
>> Ping! Can you ack? (It did not seem to break your test image.)
> 
> Hi Andreas,
> 
> I tried make check -C tests/tcg/xtensa with the branch you recommended
> and it segfaults on elf loading:

First bad commit seems to be "cpu: Turn cpu_get_phys_page_debug() into a
CPUClass hook", investigating.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 19:12         ` Andreas Färber
@ 2013-07-06 19:54           ` Max Filippov
  2013-07-07 18:51             ` Andreas Färber
  0 siblings, 1 reply; 85+ messages in thread
From: Max Filippov @ 2013-07-06 19:54 UTC (permalink / raw)
  To: Andreas Färber; +Cc: jan.kiszka, qemu-devel

On Sat, Jul 6, 2013 at 11:12 PM, Andreas Färber <afaerber@suse.de> wrote:
> Am 06.07.2013 20:39, schrieb Max Filippov:
>> On Sat, Jul 6, 2013 at 10:01 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
>>> On Sat, Jul 6, 2013 at 4:55 PM, Andreas Färber <afaerber@suse.de> wrote:
>>>> Am 29.06.2013 22:01, schrieb Andreas Färber:
>>>>> Register a CPU type per core registered. Save the XtensaConfig in
>>>>> XtensaCPUClass instead of CPUXtensaState.
>>>>>
>>>>> Prepares for storing per-class GDB register count.
>>>>>
>>>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>>>
>>>> Ping! Can you ack? (It did not seem to break your test image.)
>>>
>>> Hi Andreas,
>>>
>>> I tried make check -C tests/tcg/xtensa with the branch you recommended
>>> and it segfaults on elf loading
>>
>> ...and maybe a stupid question, but why moving configuration pointer away
>> from env and then changing every place that used to access it?
>
> Xtensa is the only target trying to implicitly access an "env" variable
> through a macro to obtain the number of registers for gdbstub. That's
> what I'm trying to fix with 40/41 in order to get rid of the #ifdeffery.
>
> The number of registers is not accessed by TCG, so it could go into
> XtensaCPU instead of CPUXtensaState.
> Further it does not change during vCPU runtime, so it no longer belongs
> in CPUXtensaState nor XtensaCPU but in XtensaCPUClass, which is shared
> among CPU cores and can be accessed statically.

I'm concerned about two things here: adding boilerplate code to access
CPU class and doing more work at runtime than just following a pointer.
I mean that env->config is almost always used together with env itself,
could we consider env->config to be a cache for xcc->config?

> However we only had one XtensaCPUClass but multiple XtensaConfigs.
> Therefore this patch registers one XtensaCPUClass per XtensaConfig.
>
> You might remember that I once tried to place the XtensaConfig fields
> directly into XtensaCPUClass but that didn't work out nicely back then.
> This is by comparison a slim/minimal conversion to subclasses, leaving
> XtensaConfig and your custom registration mechanisms in place. Cleaning
> that up to use type_init() and type_register_static() in the respective
> source files and changing -cpu ? to iterate QOM types would be a nice
> follow-up, but not needed for this gdbstub refactoring series.
>
> Another background is that I'm trying to get rid of cpu_init() and
> anything that blocks using -device or device_add with QOM CPUs.


-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
  2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook Andreas Färber
@ 2013-07-06 20:19   ` Andreas Färber
  2013-07-06 22:42     ` Max Filippov
  0 siblings, 1 reply; 85+ messages in thread
From: Andreas Färber @ 2013-07-06 20:19 UTC (permalink / raw)
  To: Max Filippov
  Cc: Peter Maydell, Anthony Green, qemu-devel, Alexander Graf,
	Blue Swirl, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, jan.kiszka, Guan Xuetao, Aurelien Jarno,
	Richard Henderson

Am 29.06.2013 22:01, schrieb Andreas Färber:
> Since all targets now assign a softmmu-only field, we can drop helpers
> cpu_class_set_{do_unassigned_access,vmsd}() and device_class_set_vmsd().
> 
> Prepares for changing cpu_memory_rw_debug() argument to CPUState.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

The following fixup for xtensa is required. This demonstrates how
dangerous it is to pass void* arguments directly into functions - please
always use a typed local variable to enforce type checks.

Andreas

diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c
index 650dd31..a079774 100644
--- a/hw/xtensa/xtensa_lx60.c
+++ b/hw/xtensa/xtensa_lx60.c
@@ -144,9 +144,11 @@ static void lx60_net_init(MemoryRegion *address_space,
     memory_region_add_subregion(address_space, buffers, ram);
 }

-static uint64_t translate_phys_addr(void *env, uint64_t addr)
+static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
 {
-    return cpu_get_phys_page_debug(env, addr);
+    XtensaCPU *cpu = opaque;
+
+    return cpu_get_phys_page_debug(CPU(cpu), addr);
 }

 static void lx60_reset(void *opaque)
@@ -252,7 +254,7 @@ static void lx_init(const LxBoardDesc *board,
QEMUMachineInitArgs *args)
         }
         uint64_t elf_entry;
         uint64_t elf_lowaddr;
-        int success = load_elf(kernel_filename, translate_phys_addr, env,
+        int success = load_elf(kernel_filename, translate_phys_addr, cpu,
                 &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
         if (success > 0) {
             env->pc = elf_entry;
diff --git a/hw/xtensa/xtensa_sim.c b/hw/xtensa/xtensa_sim.c
index 5241f8d..a4194cfb 100644
--- a/hw/xtensa/xtensa_sim.c
+++ b/hw/xtensa/xtensa_sim.c
@@ -32,9 +32,11 @@
 #include "exec/memory.h"
 #include "exec/address-spaces.h"

-static uint64_t translate_phys_addr(void *env, uint64_t addr)
+static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
 {
-    return cpu_get_phys_page_debug(env, addr);
+    XtensaCPU *cpu = opaque;
+
+    return cpu_get_phys_page_debug(CPU(cpu), addr);
 }

 static void sim_reset(void *opaque)
@@ -88,10 +90,10 @@ static void xtensa_sim_init(QEMUMachineInitArgs *args)
         uint64_t elf_entry;
         uint64_t elf_lowaddr;
 #ifdef TARGET_WORDS_BIGENDIAN
-        int success = load_elf(kernel_filename, translate_phys_addr, env,
+        int success = load_elf(kernel_filename, translate_phys_addr, cpu,
                 &elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
 #else
-        int success = load_elf(kernel_filename, translate_phys_addr, env,
+        int success = load_elf(kernel_filename, translate_phys_addr, cpu,
                 &elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0);
 #endif
         if (success > 0) {

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply related	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
  2013-07-06 20:19   ` Andreas Färber
@ 2013-07-06 22:42     ` Max Filippov
  0 siblings, 0 replies; 85+ messages in thread
From: Max Filippov @ 2013-07-06 22:42 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Green, qemu-devel, Alexander Graf,
	Blue Swirl, Michael Walle, qemu-ppc, Paul Brook,
	Edgar E. Iglesias, jan.kiszka, Guan Xuetao, Aurelien Jarno,
	Richard Henderson

On Sun, Jul 7, 2013 at 12:19 AM, Andreas Färber <afaerber@suse.de> wrote:
> Am 29.06.2013 22:01, schrieb Andreas Färber:
>> Since all targets now assign a softmmu-only field, we can drop helpers
>> cpu_class_set_{do_unassigned_access,vmsd}() and device_class_set_vmsd().
>>
>> Prepares for changing cpu_memory_rw_debug() argument to CPUState.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>
> The following fixup for xtensa is required. This demonstrates how
> dangerous it is to pass void* arguments directly into functions - please
> always use a typed local variable to enforce type checks.

With this fix it works, so for xtensa part
Acked-by: Max Filippov <jcmvbkbc@gmail.com>

My question about having configuration pointer cached in the env
still remains though.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 85+ messages in thread

* Re: [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
  2013-07-06 19:54           ` Max Filippov
@ 2013-07-07 18:51             ` Andreas Färber
  0 siblings, 0 replies; 85+ messages in thread
From: Andreas Färber @ 2013-07-07 18:51 UTC (permalink / raw)
  To: Max Filippov; +Cc: jan.kiszka, qemu-devel

Am 06.07.2013 21:54, schrieb Max Filippov:
> On Sat, Jul 6, 2013 at 11:12 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Am 06.07.2013 20:39, schrieb Max Filippov:
>>> ...and maybe a stupid question, but why moving configuration pointer away
>>> from env and then changing every place that used to access it?
>>
>> Xtensa is the only target trying to implicitly access an "env" variable
>> through a macro to obtain the number of registers for gdbstub. That's
>> what I'm trying to fix with 40/41 in order to get rid of the #ifdeffery.
>>
>> The number of registers is not accessed by TCG, so it could go into
>> XtensaCPU instead of CPUXtensaState.
>> Further it does not change during vCPU runtime, so it no longer belongs
>> in CPUXtensaState nor XtensaCPU but in XtensaCPUClass, which is shared
>> among CPU cores and can be accessed statically.
> 
> I'm concerned about two things here: adding boilerplate code to access
> CPU class and doing more work at runtime than just following a pointer.
> I mean that env->config is almost always used together with env itself,
> could we consider env->config to be a cache for xcc->config?

xtensa_env_get_cpu() after the recent patch in my queue no longer does a
cast, thus it's dirt cheap to switch between CPUXtensaState and
XtensaCPU (and back via ->env).

The ObjectClass is a pointer in Object, just like your XtensaConfig in
CPUXtensaState. Anthony has added a cast cache for v1.5 and Paolo a
configure option to turn cast checks off.

That leaves declaring an extra variable.

But since this is orthogonal to my gdbstub cleanups, v2 just initializes
env->config in XtensaCPU's instance_init, to keep the patch small while
keeping cpu_init() free of non-QOM initializations.
Anything else can be done later in an xtensa-only series.

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 85+ messages in thread

end of thread, other threads:[~2013-07-07 18:51 UTC | newest]

Thread overview: 85+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-29 20:01 [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
2013-07-01 17:03   ` Richard Henderson
2013-07-01 17:21     ` Andreas Färber
2013-07-01 20:22       ` Richard Henderson
2013-07-02  1:26   ` Andreas Färber
2013-07-02 21:17     ` Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging " Andreas Färber
2013-07-01 17:04   ` Richard Henderson
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu " Andreas Färber
2013-07-01 17:05   ` Richard Henderson
2013-07-02 22:11     ` Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc() Andreas Färber
2013-07-01 17:09   ` Richard Henderson
2013-07-01 17:25     ` Andreas Färber
2013-07-01 19:03       ` Richard Henderson
2013-07-01 19:41         ` Peter Maydell
2013-07-01 20:20           ` Richard Henderson
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 05/41] target-m68k: Implement CPUClass::set_pc() Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 06/41] target-moxie: " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 07/41] target-unicore32: " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb() Andreas Färber
2013-07-01 17:13   ` Richard Henderson
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu() Andreas Färber
2013-07-01 17:14   ` Richard Henderson
2013-07-06  0:42     ` Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
2013-07-01 17:15   ` Richard Henderson
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 11/41] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 12/41] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 13/41] target-i386: Change gen_intermediate_code_internal() argument to X86CPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 14/41] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 15/41] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 16/41] target-microblaze: Change gen_intermediate_code_internal() argument types Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 17/41] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 18/41] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 19/41] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 20/41] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 21/41] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 22/41] target-unicore32: Change gen_intermediate_code_internal() signature Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
2013-07-01 17:16   ` Richard Henderson
2013-07-01 17:51     ` Andreas Färber
2013-07-01 18:03       ` Richard Henderson
2013-07-01 21:46         ` Andreas Färber
2013-07-02 21:13     ` Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState Andreas Färber
2013-07-01 17:18   ` Richard Henderson
2013-07-01 17:23   ` Richard Henderson
2013-07-01 17:42     ` Andreas Färber
2013-06-29 20:01 ` [PATCH RFC qom-cpu 25/41] cpu: Move singlestep_enabled field from CPU_COMMON " Andreas Färber
2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
2013-07-01 17:27   ` Richard Henderson
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 26/41] gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 27/41] cpu: Change cpu_single_step() argument to CPUState Andreas Färber
2013-06-29 20:01 ` [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert,remove}_breakpoint() " Andreas Färber
2013-06-29 20:01   ` [Qemu-devel] [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert, remove}_breakpoint() " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 29/41] gdbstub: Change syscall callback " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 30/41] gdbstub: Change gdb_handlesig() " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 31/41] gdbstub: Change GDBState::c_cpu " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 32/41] gdbstub: Change gdb_{read, write}_register() argument " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook Andreas Färber
2013-07-06 20:19   ` Andreas Färber
2013-07-06 22:42     ` Max Filippov
2013-06-29 20:01 ` [PATCH RFC qom-cpu 34/41] exec: Change cpu_memory_rw_debug() argument to CPUState Andreas Färber
2013-06-29 20:01   ` [Qemu-devel] " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 35/41] cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug() Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 36/41] gdbstub: Change GDBState::g_cpu to CPUState Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 37/41] cpu: Move gdb_regs field from CPU_COMMON " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 38/41] gdbstub: Change gdb_register_coprocessor() argument " Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses Andreas Färber
2013-07-06 12:55   ` Andreas Färber
2013-07-06 18:01     ` Max Filippov
2013-07-06 18:39       ` Max Filippov
2013-07-06 19:12         ` Andreas Färber
2013-07-06 19:54           ` Max Filippov
2013-07-07 18:51             ` Andreas Färber
2013-07-06 18:45       ` Andreas Färber
2013-07-06 19:41         ` Max Filippov
2013-07-06 19:45       ` Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 40/41] gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass Andreas Färber
2013-06-29 20:01 ` [Qemu-devel] [PATCH RFC qom-cpu 41/41] cpu: Introduce CPUClass::gdb_{read, write}_register() Andreas Färber
2013-07-01 18:07   ` Richard Henderson
2013-07-06 19:18     ` Andreas Färber
2013-06-30 12:23 ` [Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub Michael Walle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.