aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/gdbstub.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc/gdbstub.c')
-rw-r--r--target/ppc/gdbstub.c504
1 files changed, 416 insertions, 88 deletions
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index 19565b584d..3b28d4e21c 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -7,7 +7,7 @@
* 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.
+ * version 2.1 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
@@ -18,9 +18,10 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "cpu.h"
#include "exec/gdbstub.h"
+#include "gdbstub/helpers.h"
+#include "internal.h"
static int ppc_gdb_register_len_apple(int n)
{
@@ -33,14 +34,14 @@ static int ppc_gdb_register_len_apple(int n)
return 8;
case 64 ... 95:
return 16;
- case 64+32: /* nip */
- case 65+32: /* msr */
- case 67+32: /* lr */
- case 68+32: /* ctr */
- case 70+32: /* fpscr */
+ case 64 + 32: /* nip */
+ case 65 + 32: /* msr */
+ case 67 + 32: /* lr */
+ case 68 + 32: /* ctr */
+ case 70 + 32: /* fpscr */
return 8;
- case 66+32: /* cr */
- case 69+32: /* xer */
+ case 66 + 32: /* cr */
+ case 69 + 32: /* xer */
return 4;
default:
return 0;
@@ -53,12 +54,6 @@ static int ppc_gdb_register_len(int n)
case 0 ... 31:
/* gprs */
return sizeof(target_ulong);
- case 32 ... 63:
- /* fprs */
- if (gdb_has_xml) {
- return 0;
- }
- return 8;
case 66:
/* cr */
case 69:
@@ -73,48 +68,48 @@ static int ppc_gdb_register_len(int n)
case 68:
/* ctr */
return sizeof(target_ulong);
- case 70:
- /* fpscr */
- if (gdb_has_xml) {
- return 0;
- }
- return sizeof(target_ulong);
default:
return 0;
}
}
-/* We need to present the registers to gdb in the "current" memory ordering.
- For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to
- the proper ordering for the binary, and cannot be changed.
- For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
- the current mode of the chip to see if we're running in little-endian. */
+/*
+ * We need to present the registers to gdb in the "current" memory
+ * ordering. For user-only mode we get this for free;
+ * TARGET_BIG_ENDIAN is set to the proper ordering for the
+ * binary, and cannot be changed. For system mode,
+ * TARGET_BIG_ENDIAN is always set, and we must check the current
+ * mode of the chip to see if we're running in little-endian.
+ */
void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
{
#ifndef CONFIG_USER_ONLY
- if (!msr_le) {
+ if (!FIELD_EX64(env->msr, MSR, LE)) {
/* do nothing */
} else if (len == 4) {
bswap32s((uint32_t *)mem_buf);
} else if (len == 8) {
bswap64s((uint64_t *)mem_buf);
+ } else if (len == 16) {
+ bswap128s((Int128 *)mem_buf);
} else {
g_assert_not_reached();
}
#endif
}
-/* Old gdb always expects FP registers. Newer (xml-aware) gdb only
+/*
+ * 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.
+ * 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)
+int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
+ CPUPPCState *env = cpu_env(cs);
+ uint8_t *mem_buf;
int r = ppc_gdb_register_len(n);
if (!r) {
@@ -123,50 +118,41 @@ int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
if (n < 32) {
/* gprs */
- gdb_get_regl(mem_buf, env->gpr[n]);
- } else if (n < 64) {
- /* fprs */
- stfq_p(mem_buf, *cpu_fpr_ptr(env, n - 32));
+ gdb_get_regl(buf, env->gpr[n]);
} else {
switch (n) {
case 64:
- gdb_get_regl(mem_buf, env->nip);
+ gdb_get_regl(buf, env->nip);
break;
case 65:
- gdb_get_regl(mem_buf, env->msr);
+ gdb_get_regl(buf, env->msr);
break;
case 66:
{
- uint32_t cr = 0;
- int i;
- for (i = 0; i < 8; i++) {
- cr |= env->crf[i] << (32 - ((i + 1) * 4));
- }
- gdb_get_reg32(mem_buf, cr);
+ uint32_t cr = ppc_get_cr(env);
+ gdb_get_reg32(buf, cr);
break;
}
case 67:
- gdb_get_regl(mem_buf, env->lr);
+ gdb_get_regl(buf, env->lr);
break;
case 68:
- gdb_get_regl(mem_buf, env->ctr);
+ gdb_get_regl(buf, env->ctr);
break;
case 69:
- gdb_get_reg32(mem_buf, env->xer);
- break;
- case 70:
- gdb_get_reg32(mem_buf, env->fpscr);
+ gdb_get_reg32(buf, cpu_read_xer(env));
break;
}
}
+ mem_buf = buf->data + buf->len - r;
ppc_maybe_bswap_register(env, mem_buf, r);
return r;
}
-int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
+int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
+ CPUPPCState *env = cpu_env(cs);
+ uint8_t *mem_buf;
int r = ppc_gdb_register_len_apple(n);
if (!r) {
@@ -175,54 +161,50 @@ int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
if (n < 32) {
/* gprs */
- gdb_get_reg64(mem_buf, env->gpr[n]);
+ gdb_get_reg64(buf, env->gpr[n]);
} else if (n < 64) {
/* fprs */
- stfq_p(mem_buf, *cpu_fpr_ptr(env, n - 32));
+ gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
} else if (n < 96) {
/* Altivec */
- stq_p(mem_buf, n - 64);
- stq_p(mem_buf + 8, 0);
+ gdb_get_reg64(buf, n - 64);
+ gdb_get_reg64(buf, 0);
} else {
switch (n) {
case 64 + 32:
- gdb_get_reg64(mem_buf, env->nip);
+ gdb_get_reg64(buf, env->nip);
break;
case 65 + 32:
- gdb_get_reg64(mem_buf, env->msr);
+ gdb_get_reg64(buf, env->msr);
break;
case 66 + 32:
{
- uint32_t cr = 0;
- int i;
- for (i = 0; i < 8; i++) {
- cr |= env->crf[i] << (32 - ((i + 1) * 4));
- }
- gdb_get_reg32(mem_buf, cr);
+ uint32_t cr = ppc_get_cr(env);
+ gdb_get_reg32(buf, cr);
break;
}
case 67 + 32:
- gdb_get_reg64(mem_buf, env->lr);
+ gdb_get_reg64(buf, env->lr);
break;
case 68 + 32:
- gdb_get_reg64(mem_buf, env->ctr);
+ gdb_get_reg64(buf, env->ctr);
break;
case 69 + 32:
- gdb_get_reg32(mem_buf, env->xer);
+ gdb_get_reg32(buf, cpu_read_xer(env));
break;
case 70 + 32:
- gdb_get_reg64(mem_buf, env->fpscr);
+ gdb_get_reg64(buf, env->fpscr);
break;
}
}
+ mem_buf = buf->data + buf->len - r;
ppc_maybe_bswap_register(env, mem_buf, r);
return r;
}
int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
+ CPUPPCState *env = cpu_env(cs);
int r = ppc_gdb_register_len(n);
if (!r) {
@@ -234,7 +216,7 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->gpr[n] = ldtul_p(mem_buf);
} else if (n < 64) {
/* fprs */
- *cpu_fpr_ptr(env, n - 32) = ldfq_p(mem_buf);
+ *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
} else {
switch (n) {
case 64:
@@ -246,10 +228,7 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
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;
- }
+ ppc_set_cr(env, cr);
break;
}
case 67:
@@ -259,11 +238,11 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->ctr = ldtul_p(mem_buf);
break;
case 69:
- env->xer = ldl_p(mem_buf);
+ cpu_write_xer(env, ldl_p(mem_buf));
break;
case 70:
/* fpscr */
- store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
+ ppc_store_fpscr(env, ldtul_p(mem_buf));
break;
}
}
@@ -271,8 +250,7 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
}
int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
+ CPUPPCState *env = cpu_env(cs);
int r = ppc_gdb_register_len_apple(n);
if (!r) {
@@ -284,7 +262,7 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
env->gpr[n] = ldq_p(mem_buf);
} else if (n < 64) {
/* fprs */
- *cpu_fpr_ptr(env, n - 32) = ldfq_p(mem_buf);
+ *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
} else {
switch (n) {
case 64 + 32:
@@ -296,10 +274,7 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
case 66 + 32:
{
uint32_t cr = ldl_p(mem_buf);
- int i;
- for (i = 0; i < 8; i++) {
- env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
- }
+ ppc_set_cr(env, cr);
break;
}
case 67 + 32:
@@ -309,13 +284,366 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
env->ctr = ldq_p(mem_buf);
break;
case 69 + 32:
- env->xer = ldl_p(mem_buf);
+ cpu_write_xer(env, ldl_p(mem_buf));
break;
case 70 + 32:
/* fpscr */
- store_fpscr(env, ldq_p(mem_buf), 0xffffffff);
+ ppc_store_fpscr(env, ldq_p(mem_buf));
break;
}
}
return r;
}
+
+#ifndef CONFIG_USER_ONLY
+static void gdb_gen_spr_feature(CPUState *cs)
+{
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ GDBFeatureBuilder builder;
+ unsigned int num_regs = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+ ppc_spr_t *spr = &env->spr_cb[i];
+
+ if (!spr->name) {
+ continue;
+ }
+
+ /*
+ * GDB identifies registers based on the order they are
+ * presented in the XML. These ids will not match QEMU's
+ * representation (which follows the PowerISA).
+ *
+ * Store the position of the current register description so
+ * we can make the correspondence later.
+ */
+ spr->gdb_id = num_regs;
+ num_regs++;
+ }
+
+ if (pcc->gdb_spr.xml) {
+ return;
+ }
+
+ gdb_feature_builder_init(&builder, &pcc->gdb_spr,
+ "org.qemu.power.spr", "power-spr.xml",
+ cs->gdb_num_regs);
+
+ for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+ ppc_spr_t *spr = &env->spr_cb[i];
+
+ if (!spr->name) {
+ continue;
+ }
+
+ gdb_feature_builder_append_reg(&builder, g_ascii_strdown(spr->name, -1),
+ TARGET_LONG_BITS, spr->gdb_id,
+ "int", "spr");
+ }
+
+ gdb_feature_builder_end(&builder);
+}
+#endif
+
+#if !defined(CONFIG_USER_ONLY)
+static int gdb_find_spr_idx(CPUPPCState *env, int n)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+ ppc_spr_t *spr = &env->spr_cb[i];
+
+ if (spr->name && spr->gdb_id == n) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int gdb_get_spr_reg(CPUState *cs, GByteArray *buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ int reg;
+ int len;
+
+ reg = gdb_find_spr_idx(env, n);
+ if (reg < 0) {
+ return 0;
+ }
+
+ len = TARGET_LONG_SIZE;
+
+ /* Handle those SPRs that are not part of the env->spr[] array */
+ target_ulong val;
+ switch (reg) {
+#if defined(TARGET_PPC64)
+ case SPR_CFAR:
+ val = env->cfar;
+ break;
+#endif
+ case SPR_HDEC:
+ val = cpu_ppc_load_hdecr(env);
+ break;
+ case SPR_TBL:
+ val = cpu_ppc_load_tbl(env);
+ break;
+ case SPR_TBU:
+ val = cpu_ppc_load_tbu(env);
+ break;
+ case SPR_DECR:
+ val = cpu_ppc_load_decr(env);
+ break;
+ default:
+ val = env->spr[reg];
+ }
+ gdb_get_regl(buf, val);
+
+ ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
+ return len;
+}
+
+static int gdb_set_spr_reg(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ int reg;
+ int len;
+
+ reg = gdb_find_spr_idx(env, n);
+ if (reg < 0) {
+ return 0;
+ }
+
+ len = TARGET_LONG_SIZE;
+ ppc_maybe_bswap_register(env, mem_buf, len);
+
+ /* Handle those SPRs that are not part of the env->spr[] array */
+ target_ulong val = ldn_p(mem_buf, len);
+ switch (reg) {
+#if defined(TARGET_PPC64)
+ case SPR_CFAR:
+ env->cfar = val;
+ break;
+#endif
+ default:
+ env->spr[reg] = val;
+ }
+
+ return len;
+}
+#endif
+
+static int gdb_get_float_reg(CPUState *cs, GByteArray *buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ uint8_t *mem_buf;
+ if (n < 32) {
+ gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
+ mem_buf = gdb_get_reg_ptr(buf, 8);
+ ppc_maybe_bswap_register(env, mem_buf, 8);
+ return 8;
+ }
+ if (n == 32) {
+ gdb_get_reg32(buf, env->fpscr);
+ mem_buf = gdb_get_reg_ptr(buf, 4);
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ return 4;
+ }
+ return 0;
+}
+
+static int gdb_set_float_reg(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+ ppc_maybe_bswap_register(env, mem_buf, 8);
+ *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
+ return 8;
+ }
+ if (n == 32) {
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ ppc_store_fpscr(env, ldl_p(mem_buf));
+ return 4;
+ }
+ return 0;
+}
+
+static int gdb_get_avr_reg(CPUState *cs, GByteArray *buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ uint8_t *mem_buf;
+
+ if (n < 32) {
+ ppc_avr_t *avr = cpu_avr_ptr(env, n);
+ gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
+ mem_buf = gdb_get_reg_ptr(buf, 16);
+ ppc_maybe_bswap_register(env, mem_buf, 16);
+ return 16;
+ }
+ if (n == 32) {
+ gdb_get_reg32(buf, ppc_get_vscr(env));
+ mem_buf = gdb_get_reg_ptr(buf, 4);
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ return 4;
+ }
+ if (n == 33) {
+ gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
+ mem_buf = gdb_get_reg_ptr(buf, 4);
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ return 4;
+ }
+ return 0;
+}
+
+static int gdb_set_avr_reg(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+ ppc_avr_t *avr = cpu_avr_ptr(env, n);
+ ppc_maybe_bswap_register(env, mem_buf, 16);
+ avr->VsrD(0) = ldq_p(mem_buf);
+ avr->VsrD(1) = ldq_p(mem_buf + 8);
+ return 16;
+ }
+ if (n == 32) {
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ ppc_store_vscr(env, ldl_p(mem_buf));
+ return 4;
+ }
+ if (n == 33) {
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
+ return 4;
+ }
+ return 0;
+}
+
+static int gdb_get_spe_reg(CPUState *cs, GByteArray *buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+#if defined(TARGET_PPC64)
+ gdb_get_reg32(buf, env->gpr[n] >> 32);
+ ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
+#else
+ gdb_get_reg32(buf, env->gprh[n]);
+#endif
+ return 4;
+ }
+ if (n == 32) {
+ gdb_get_reg64(buf, env->spe_acc);
+ ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
+ return 8;
+ }
+ if (n == 33) {
+ gdb_get_reg32(buf, env->spe_fscr);
+ ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
+ return 4;
+ }
+ return 0;
+}
+
+static int gdb_set_spe_reg(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+#if defined(TARGET_PPC64)
+ target_ulong lo = (uint32_t)env->gpr[n];
+ target_ulong hi;
+
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+
+ hi = (target_ulong)ldl_p(mem_buf) << 32;
+ env->gpr[n] = lo | hi;
+#else
+ env->gprh[n] = ldl_p(mem_buf);
+#endif
+ return 4;
+ }
+ if (n == 32) {
+ ppc_maybe_bswap_register(env, mem_buf, 8);
+ env->spe_acc = ldq_p(mem_buf);
+ return 8;
+ }
+ if (n == 33) {
+ ppc_maybe_bswap_register(env, mem_buf, 4);
+ env->spe_fscr = ldl_p(mem_buf);
+ return 4;
+ }
+ return 0;
+}
+
+static int gdb_get_vsx_reg(CPUState *cs, GByteArray *buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+ gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
+ ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
+ return 8;
+ }
+ return 0;
+}
+
+static int gdb_set_vsx_reg(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+ ppc_maybe_bswap_register(env, mem_buf, 8);
+ *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
+ return 8;
+ }
+ return 0;
+}
+
+const gchar *ppc_gdb_arch_name(CPUState *cs)
+{
+#if defined(TARGET_PPC64)
+ return "powerpc:common64";
+#else
+ return "powerpc:common";
+#endif
+}
+
+void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
+{
+ if (pcc->insns_flags & PPC_FLOAT) {
+ gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
+ gdb_find_static_feature("power-fpu.xml"), 0);
+ }
+ if (pcc->insns_flags & PPC_ALTIVEC) {
+ gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
+ gdb_find_static_feature("power-altivec.xml"),
+ 0);
+ }
+ if (pcc->insns_flags & PPC_SPE) {
+ gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
+ gdb_find_static_feature("power-spe.xml"), 0);
+ }
+ if (pcc->insns_flags2 & PPC2_VSX) {
+ gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
+ gdb_find_static_feature("power-vsx.xml"), 0);
+ }
+#ifndef CONFIG_USER_ONLY
+ gdb_gen_spr_feature(cs);
+ gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
+ &pcc->gdb_spr, 0);
+#endif
+}