Răsfoiți Sursa

cpu: Introduce CPUState::gdb_num_regs and CPUClass::gdb_num_core_regs

CPUState::gdb_num_regs replaces num_g_regs.
CPUClass::gdb_num_core_regs replaces NUM_CORE_REGS.

Allows building gdb_register_coprocessor() for xtensa, too.

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

Acked-by: Michael Walle <michael@walle.cc> (for lm32)
Acked-by: Max Filippov <jcmvbkbc@gmail.com> (for xtensa)
Signed-off-by: Andreas Färber <afaerber@suse.de>
Andreas Färber 12 ani în urmă
părinte
comite
a0e372f0c4

+ 19 - 64
gdbstub.c

@@ -530,8 +530,6 @@ static const int gpr_map[16] = {
 #endif
 #endif
 static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
 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_IP_REG      CPU_NB_REGS
 #define IDX_FLAGS_REG   (IDX_IP_REG + 1)
 #define IDX_FLAGS_REG   (IDX_IP_REG + 1)
 #define IDX_SEG_REGS    (IDX_FLAGS_REG + 1)
 #define IDX_SEG_REGS    (IDX_FLAGS_REG + 1)
@@ -732,7 +730,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
    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
    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.  */
    FP regs zero size when talking to a newer gdb.  */
-#define NUM_CORE_REGS 71
 #if defined (TARGET_PPC64)
 #if defined (TARGET_PPC64)
 #define GDB_CORE_XML "power64-core.xml"
 #define GDB_CORE_XML "power64-core.xml"
 #else
 #else
@@ -837,12 +834,6 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
 
 
 #elif defined (TARGET_SPARC)
 #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
 #ifdef TARGET_ABI32
 #define GET_REGA(val) GET_REG32(val)
 #define GET_REGA(val) GET_REG32(val)
 #else
 #else
@@ -1030,7 +1021,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.
    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
    We hack round this by giving the FPA regs zero size when talking to a
    newer gdb.  */
    newer gdb.  */
-#define NUM_CORE_REGS 26
 #define GDB_CORE_XML "arm-core.xml"
 #define GDB_CORE_XML "arm-core.xml"
 
 
 static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
@@ -1104,8 +1094,6 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n)
 
 
 #elif defined (TARGET_M68K)
 #elif defined (TARGET_M68K)
 
 
-#define NUM_CORE_REGS 18
-
 #define GDB_CORE_XML "cf-core.xml"
 #define GDB_CORE_XML "cf-core.xml"
 
 
 static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
@@ -1157,8 +1145,6 @@ static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined (TARGET_MIPS)
 #elif defined (TARGET_MIPS)
 
 
-#define NUM_CORE_REGS 73
-
 static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
 {
 {
     if (n < 32) {
     if (n < 32) {
@@ -1285,8 +1271,6 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_OPENRISC)
 
 
-#define NUM_CORE_REGS (32 + 3)
-
 static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
 {
 {
     if (n < 32) {
     if (n < 32) {
@@ -1312,9 +1296,11 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_write_register(CPUOpenRISCState *env,
 static int cpu_gdb_write_register(CPUOpenRISCState *env,
                                   uint8_t *mem_buf, int n)
                                   uint8_t *mem_buf, int n)
 {
 {
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     uint32_t tmp;
     uint32_t tmp;
 
 
-    if (n > NUM_CORE_REGS) {
+    if (n > cc->gdb_num_core_regs) {
         return 0;
         return 0;
     }
     }
 
 
@@ -1347,8 +1333,6 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env,
 /* Hint: Use "set architecture sh4" in GDB to see fpu registers */
 /* Hint: Use "set architecture sh4" in GDB to see fpu registers */
 /* FIXME: We should use XML for this.  */
 /* 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)
 static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
 {
 {
     switch (n) {
     switch (n) {
@@ -1465,8 +1449,6 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined (TARGET_MICROBLAZE)
 #elif defined (TARGET_MICROBLAZE)
 
 
-#define NUM_CORE_REGS (32 + 5)
-
 static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
 {
 {
     if (n < 32) {
     if (n < 32) {
@@ -1479,9 +1461,11 @@ 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)
 static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
 {
 {
+    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     uint32_t tmp;
     uint32_t tmp;
 
 
-    if (n > NUM_CORE_REGS) {
+    if (n > cc->gdb_num_core_regs) {
         return 0;
         return 0;
     }
     }
 
 
@@ -1496,8 +1480,6 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined (TARGET_CRIS)
 #elif defined (TARGET_CRIS)
 
 
-#define NUM_CORE_REGS 49
-
 static int
 static int
 read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
 read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
 {
 {
@@ -1605,8 +1587,6 @@ static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined (TARGET_ALPHA)
 #elif defined (TARGET_ALPHA)
 
 
-#define NUM_CORE_REGS 67
-
 static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
 {
 {
     uint64_t val;
     uint64_t val;
@@ -1675,8 +1655,6 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined (TARGET_S390X)
 #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)
 static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n)
 {
 {
     uint64_t val;
     uint64_t val;
@@ -1740,7 +1718,6 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
 #elif defined (TARGET_LM32)
 #elif defined (TARGET_LM32)
 
 
 #include "hw/lm32/lm32_pic.h"
 #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)
 static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
 {
 {
@@ -1770,9 +1747,11 @@ 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)
 static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
 {
 {
+    LM32CPU *cpu = lm32_env_get_cpu(env);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     uint32_t tmp;
     uint32_t tmp;
 
 
-    if (n > NUM_CORE_REGS) {
+    if (n > cc->gdb_num_core_regs) {
         return 0;
         return 0;
     }
     }
 
 
@@ -1806,14 +1785,6 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
 }
 }
 #elif defined(TARGET_XTENSA)
 #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 (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)
 static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 {
 {
     const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
     const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
@@ -1896,8 +1867,6 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
 }
 }
 #else
 #else
 
 
-#define NUM_CORE_REGS 0
-
 static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
 static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
 {
 {
     return 0;
     return 0;
@@ -1910,10 +1879,6 @@ static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
 
 
 #endif
 #endif
 
 
-#if !defined(TARGET_XTENSA)
-static int num_g_regs = NUM_CORE_REGS;
-#endif
-
 #ifdef GDB_CORE_XML
 #ifdef GDB_CORE_XML
 /* Encode data using the encoding for 'x' packets.  */
 /* Encode data using the encoding for 'x' packets.  */
 static int memtox(char *buf, const char *mem, int len)
 static int memtox(char *buf, const char *mem, int len)
@@ -1982,11 +1947,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)
 static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUArchState *env = cpu->env_ptr;
     CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
     GDBRegisterState *r;
 
 
-    if (reg < NUM_CORE_REGS)
+    if (reg < cc->gdb_num_core_regs) {
         return cpu_gdb_read_register(env, mem_buf, reg);
         return cpu_gdb_read_register(env, mem_buf, reg);
+    }
 
 
     for (r = cpu->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) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
@@ -1998,11 +1965,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)
 static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
     CPUArchState *env = cpu->env_ptr;
     CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
     GDBRegisterState *r;
 
 
-    if (reg < NUM_CORE_REGS)
+    if (reg < cc->gdb_num_core_regs) {
         return cpu_gdb_write_register(env, mem_buf, reg);
         return cpu_gdb_write_register(env, mem_buf, reg);
+    }
 
 
     for (r = cpu->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) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
@@ -2012,7 +1981,6 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     return 0;
     return 0;
 }
 }
 
 
-#if !defined(TARGET_XTENSA)
 /* Register a supplemental set of CPU registers.  If g_pos is nonzero it
 /* Register a supplemental set of CPU registers.  If g_pos is nonzero it
    specifies the first register number and these registers are included in
    specifies the first register number and these registers are included in
    a standard "g" packet.  Direction is relative to gdb, i.e. get_reg is
    a standard "g" packet.  Direction is relative to gdb, i.e. get_reg is
@@ -2025,7 +1993,6 @@ void gdb_register_coprocessor(CPUState *cpu,
 {
 {
     GDBRegisterState *s;
     GDBRegisterState *s;
     GDBRegisterState **p;
     GDBRegisterState **p;
-    static int last_reg = NUM_CORE_REGS;
 
 
     p = &cpu->gdb_regs;
     p = &cpu->gdb_regs;
     while (*p) {
     while (*p) {
@@ -2036,25 +2003,22 @@ void gdb_register_coprocessor(CPUState *cpu,
     }
     }
 
 
     s = g_new0(GDBRegisterState, 1);
     s = g_new0(GDBRegisterState, 1);
-    s->base_reg = last_reg;
+    s->base_reg = cpu->gdb_num_regs;
     s->num_regs = num_regs;
     s->num_regs = num_regs;
     s->get_reg = get_reg;
     s->get_reg = get_reg;
     s->set_reg = set_reg;
     s->set_reg = set_reg;
     s->xml = xml;
     s->xml = xml;
 
 
     /* Add to end of list.  */
     /* Add to end of list.  */
-    last_reg += num_regs;
+    cpu->gdb_num_regs += num_regs;
     *p = s;
     *p = s;
     if (g_pos) {
     if (g_pos) {
         if (g_pos != s->base_reg) {
         if (g_pos != s->base_reg) {
             fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
             fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
                     "Expected %d got %d\n", xml, g_pos, s->base_reg);
                     "Expected %d got %d\n", xml, g_pos, s->base_reg);
-        } else {
-            num_g_regs = last_reg;
         }
         }
     }
     }
 }
 }
-#endif
 
 
 #ifndef CONFIG_USER_ONLY
 #ifndef CONFIG_USER_ONLY
 static const int xlat_gdb_type[] = {
 static const int xlat_gdb_type[] = {
@@ -2184,9 +2148,6 @@ static CPUState *find_cpu(uint32_t thread_id)
 
 
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
 {
-#ifdef TARGET_XTENSA
-    CPUArchState *env;
-#endif
     CPUState *cpu;
     CPUState *cpu;
     const char *p;
     const char *p;
     uint32_t thread;
     uint32_t thread;
@@ -2334,11 +2295,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
         break;
     case 'g':
     case 'g':
         cpu_synchronize_state(s->g_cpu);
         cpu_synchronize_state(s->g_cpu);
-#ifdef TARGET_XTENSA
-        env = s->g_cpu->env_ptr;
-#endif
         len = 0;
         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);
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
             len += reg_size;
             len += reg_size;
         }
         }
@@ -2347,13 +2305,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
         break;
     case 'G':
     case 'G':
         cpu_synchronize_state(s->g_cpu);
         cpu_synchronize_state(s->g_cpu);
-#ifdef TARGET_XTENSA
-        env = s->g_cpu->env_ptr;
-#endif
         registers = mem_buf;
         registers = mem_buf;
         len = strlen(p) / 2;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
         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);
             reg_size = gdb_write_register(s->g_cpu, registers, addr);
             len -= reg_size;
             len -= reg_size;
             registers += reg_size;
             registers += reg_size;

+ 6 - 1
include/qom/cpu.h

@@ -81,6 +81,7 @@ struct TranslationBlock;
  * #TranslationBlock.
  * #TranslationBlock.
  * @get_phys_page_debug: Callback for obtaining a physical address.
  * @get_phys_page_debug: Callback for obtaining a physical address.
  * @vmsd: State description for migration.
  * @vmsd: State description for migration.
+ * @gdb_num_core_regs: Number of core registers accessible to GDB.
  *
  *
  * Represents a CPU family or model.
  * Represents a CPU family or model.
  */
  */
@@ -109,7 +110,6 @@ typedef struct CPUClass {
     void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
     void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
     hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
     hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
 
 
-    const struct VMStateDescription *vmsd;
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
     int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
                             int cpuid, void *opaque);
                             int cpuid, void *opaque);
     int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
     int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
@@ -118,6 +118,9 @@ typedef struct CPUClass {
                             int cpuid, void *opaque);
                             int cpuid, void *opaque);
     int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
     int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
                                 void *opaque);
                                 void *opaque);
+
+    const struct VMStateDescription *vmsd;
+    int gdb_num_core_regs;
 } CPUClass;
 } CPUClass;
 
 
 struct KVMState;
 struct KVMState;
@@ -142,6 +145,7 @@ struct kvm_run;
  * @env_ptr: Pointer to subclass-specific CPUArchState field.
  * @env_ptr: Pointer to subclass-specific CPUArchState field.
  * @current_tb: Currently executing TB.
  * @current_tb: Currently executing TB.
  * @gdb_regs: Additional GDB registers.
  * @gdb_regs: Additional GDB registers.
+ * @gdb_num_regs: Number of total registers accessible to GDB.
  * @next_cpu: Next CPU sharing TB cache.
  * @next_cpu: Next CPU sharing TB cache.
  * @kvm_fd: vCPU file descriptor for KVM.
  * @kvm_fd: vCPU file descriptor for KVM.
  *
  *
@@ -177,6 +181,7 @@ struct CPUState {
     void *env_ptr; /* CPUArchState */
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
     struct TranslationBlock *current_tb;
     struct GDBRegisterState *gdb_regs;
     struct GDBRegisterState *gdb_regs;
+    int gdb_num_regs;
     CPUState *next_cpu;
     CPUState *next_cpu;
 
 
     int kvm_fd;
     int kvm_fd;

+ 9 - 0
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)
 static int64_t cpu_common_get_arch_id(CPUState *cpu)
 {
 {
     return cpu->cpu_index;
     return cpu->cpu_index;
@@ -253,6 +261,7 @@ static const TypeInfo cpu_type_info = {
     .name = TYPE_CPU,
     .name = TYPE_CPU,
     .parent = TYPE_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(CPUState),
     .instance_size = sizeof(CPUState),
+    .instance_init = cpu_common_initfn,
     .abstract = true,
     .abstract = true,
     .class_size = sizeof(CPUClass),
     .class_size = sizeof(CPUClass),
     .class_init = cpu_class_init,
     .class_init = cpu_class_init,

+ 1 - 0
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;
     cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_alpha_cpu;
     dc->vmsd = &vmstate_alpha_cpu;
 #endif
 #endif
+    cc->gdb_num_core_regs = 67;
 }
 }
 
 
 static const TypeInfo alpha_cpu_type_info = {
 static const TypeInfo alpha_cpu_type_info = {

+ 1 - 0
target-arm/cpu.c

@@ -828,6 +828,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_arm_cpu;
     cc->vmsd = &vmstate_arm_cpu;
 #endif
 #endif
+    cc->gdb_num_core_regs = 26;
 }
 }
 
 
 static void cpu_register(const ARMCPUInfo *info)
 static void cpu_register(const ARMCPUInfo *info)

+ 2 - 0
target-cris/cpu.c

@@ -258,6 +258,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 #ifndef CONFIG_USER_ONLY
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
     cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
 #endif
 #endif
+
+    cc->gdb_num_core_regs = 49;
 }
 }
 
 
 static const TypeInfo cris_cpu_type_info = {
 static const TypeInfo cris_cpu_type_info = {

+ 1 - 0
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->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
     cc->vmsd = &vmstate_x86_cpu;
     cc->vmsd = &vmstate_x86_cpu;
 #endif
 #endif
+    cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
 }
 }
 
 
 static const TypeInfo x86_cpu_type_info = {
 static const TypeInfo x86_cpu_type_info = {

+ 1 - 0
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->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_lm32_cpu;
     cc->vmsd = &vmstate_lm32_cpu;
 #endif
 #endif
+    cc->gdb_num_core_regs = 32 + 7;
 }
 }
 
 
 static const TypeInfo lm32_cpu_type_info = {
 static const TypeInfo lm32_cpu_type_info = {

+ 1 - 0
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;
     cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
 #endif
 #endif
     dc->vmsd = &vmstate_m68k_cpu;
     dc->vmsd = &vmstate_m68k_cpu;
+    cc->gdb_num_core_regs = 18;
 }
 }
 
 
 static void register_cpu_type(const M68kCPUInfo *info)
 static void register_cpu_type(const M68kCPUInfo *info)

+ 1 - 0
target-microblaze/cpu.c

@@ -147,6 +147,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 #endif
 #endif
     dc->vmsd = &vmstate_mb_cpu;
     dc->vmsd = &vmstate_mb_cpu;
     dc->props = mb_properties;
     dc->props = mb_properties;
+    cc->gdb_num_core_regs = 32 + 5;
 }
 }
 
 
 static const TypeInfo mb_cpu_type_info = {
 static const TypeInfo mb_cpu_type_info = {

+ 2 - 0
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->do_unassigned_access = mips_cpu_unassigned_access;
     cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
     cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
 #endif
 #endif
+
+    cc->gdb_num_core_regs = 73;
 }
 }
 
 
 static const TypeInfo mips_cpu_type_info = {
 static const TypeInfo mips_cpu_type_info = {

+ 1 - 0
target-openrisc/cpu.c

@@ -159,6 +159,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
     cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
     dc->vmsd = &vmstate_openrisc_cpu;
     dc->vmsd = &vmstate_openrisc_cpu;
 #endif
 #endif
+    cc->gdb_num_core_regs = 32 + 3;
 }
 }
 
 
 static void cpu_register(const OpenRISCCPUInfo *info)
 static void cpu_register(const OpenRISCCPUInfo *info)

+ 2 - 0
target-ppc/translate_init.c

@@ -8461,6 +8461,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 #ifndef CONFIG_USER_ONLY
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
     cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
 #endif
 #endif
+
+    cc->gdb_num_core_regs = 71;
 }
 }
 
 
 static const TypeInfo ppc_cpu_type_info = {
 static const TypeInfo ppc_cpu_type_info = {

+ 1 - 0
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;
     cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
 #endif
 #endif
     dc->vmsd = &vmstate_s390_cpu;
     dc->vmsd = &vmstate_s390_cpu;
+    cc->gdb_num_core_regs = S390_NUM_REGS;
 }
 }
 
 
 static const TypeInfo s390_cpu_type_info = {
 static const TypeInfo s390_cpu_type_info = {

+ 1 - 0
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;
     cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
 #endif
 #endif
     dc->vmsd = &vmstate_sh_cpu;
     dc->vmsd = &vmstate_sh_cpu;
+    cc->gdb_num_core_regs = 59;
 }
 }
 
 
 static const TypeInfo superh_cpu_type_info = {
 static const TypeInfo superh_cpu_type_info = {

+ 6 - 0
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->do_unassigned_access = sparc_cpu_unassigned_access;
     cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
     cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
 #endif
 #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 = {
 static const TypeInfo sparc_cpu_type_info = {

+ 3 - 0
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)
 static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
 {
 {
+    CPUState *cs = CPU(dev);
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
 
 
+    cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
+
     xcc->parent_realize(dev, errp);
     xcc->parent_realize(dev, errp);
 }
 }
 
 

+ 8 - 0
target-xtensa/helper.c

@@ -37,10 +37,18 @@ static struct XtensaConfigList *xtensa_cores;
 
 
 static void xtensa_core_class_init(ObjectClass *oc, void *data)
 static void xtensa_core_class_init(ObjectClass *oc, void *data)
 {
 {
+    CPUClass *cc = CPU_CLASS(oc);
     XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
     XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
     const XtensaConfig *config = data;
     const XtensaConfig *config = data;
 
 
     xcc->config = config;
     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)
 void xtensa_register_core(XtensaConfigList *node)