diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-03-18 20:25:23 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-03-18 20:25:23 +0000 |
commit | 9214813489eb29de71d37f57e1bcabf5facecc8f (patch) | |
tree | 4a7317768744cda3fa35cd08a6615bfdce13ee79 /target | |
parent | cf4b64406c0e7542b4e1852f5e5a743ad63cf36e (diff) | |
parent | 3bc2609d478779be600fd66744eb4e3730ec5e33 (diff) |
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-and-gdbstub-170320-1' into staging
Testing and gdbstub updates:
- docker updates for VirGL
- re-factor gdbstub for static GDBState
- re-factor gdbstub for dynamic arrays
- add SVE support to arm gdbstub
- add some guest debug tests to check-tcg
- add aarch64 userspace register tests
- remove packet size limit to gdbstub
- simplify gdbstub monitor code
- report vContSupported in gdbstub to use proper single-step
# gpg: Signature made Tue 17 Mar 2020 17:47:46 GMT
# gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44
* remotes/stsquad/tags/pull-testing-and-gdbstub-170320-1: (28 commits)
gdbstub: Fix single-step issue by confirming 'vContSupported+' feature to gdb
gdbstub: do not split gdb_monitor_write payload
gdbstub: change GDBState.last_packet to GByteArray
tests/tcg/aarch64: add test-sve-ioctl guest-debug test
tests/tcg/aarch64: add SVE iotcl test
tests/tcg/aarch64: add a gdbstub testcase for SVE registers
tests/guest-debug: add a simple test runner
configure: allow user to specify what gdb to use
tests/tcg/aarch64: userspace system register test
target/arm: don't bother with id_aa64pfr0_read for USER_ONLY
target/arm: generate xml description of our SVE registers
target/arm: default SVE length to 64 bytes for linux-user
target/arm: explicitly encode regnum in our XML
target/arm: prepare for multiple dynamic XMLs
gdbstub: extend GByteArray to read register helpers
target/i386: use gdb_get_reg helpers
target/m68k: use gdb_get_reg helpers
target/arm: use gdb_get_reg helpers
gdbstub: add helper for 128 bit registers
gdbstub: move mem_buf to GDBState and use GByteArray
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
38 files changed, 471 insertions, 202 deletions
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index 3f782c0efe..be29bdd530 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -280,7 +280,7 @@ void alpha_cpu_do_interrupt(CPUState *cpu); bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, diff --git a/target/alpha/gdbstub.c b/target/alpha/gdbstub.c index 7f9cc092a9..0cd76ddaa9 100644 --- a/target/alpha/gdbstub.c +++ b/target/alpha/gdbstub.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int alpha_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int alpha_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { AlphaCPU *cpu = ALPHA_CPU(cs); CPUAlphaState *env = &cpu->env; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 7fe367078c..3a5d1379cf 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -195,9 +195,10 @@ static void arm_cpu_reset(CPUState *s) env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3); /* and to the SVE instructions */ env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3); - /* with maximum vector length */ - env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ? - cpu->sve_max_vq - 1 : 0; + /* with reasonable vector length */ + if (cpu_isar_feature(aa64_sve, cpu)) { + env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3); + } /* * Enable TBI0 and TBI1. While the real kernel only enables TBI0, * turning on both here will produce smaller code and otherwise diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 4ffd991b6f..8b9f2961ba 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -128,14 +128,20 @@ enum { /** * DynamicGDBXMLInfo: * @desc: Contains the XML descriptions. - * @num_cpregs: Number of the Coprocessor registers seen by GDB. - * @cpregs_keys: Array that contains the corresponding Key of - * a given cpreg with the same order of the cpreg in the XML description. + * @num: Number of the registers in this XML seen by GDB. + * @data: A union with data specific to the set of registers + * @cpregs_keys: Array that contains the corresponding Key of + * a given cpreg with the same order of the cpreg + * in the XML description. */ typedef struct DynamicGDBXMLInfo { char *desc; - int num_cpregs; - uint32_t *cpregs_keys; + int num; + union { + struct { + uint32_t *keys; + } cpregs; + } data; } DynamicGDBXMLInfo; /* CPU state for each instance of a generic timer (in cp15 c14) */ @@ -749,7 +755,8 @@ struct ARMCPU { uint64_t *cpreg_vmstate_values; int32_t cpreg_vmstate_array_len; - DynamicGDBXMLInfo dyn_xml; + DynamicGDBXMLInfo dyn_sysreg_xml; + DynamicGDBXMLInfo dyn_svereg_xml; /* Timers used by the generic (architected) timer */ QEMUTimer *gt_timer[NUM_GTIMERS]; @@ -968,13 +975,15 @@ bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req); hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, MemTxAttrs *attrs); -int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int arm_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -/* Dynamically generates for gdb stub an XML description of the sysregs from - * the cp_regs hashtable. Returns the registered sysregs number. +/* + * Helpers to dynamically generates XML descriptions of the sysregs + * and SVE registers. Returns the number of registers in each set. */ -int arm_gen_dynamic_xml(CPUState *cpu); +int arm_gen_dynamic_sysreg_xml(CPUState *cpu, int base_reg); +int arm_gen_dynamic_svereg_xml(CPUState *cpu, int base_reg); /* Returns the dynamically generated XML for the gdb stub. * Returns a pointer to the XML contents for the specified XML file or NULL @@ -988,7 +997,7 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, int cpuid, void *opaque); #ifdef TARGET_AARCH64 -int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int aarch64_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq); void aarch64_sve_change_el(CPUARMState *env, int old_el, diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 1239abd984..d9ef7d2187 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -24,6 +24,7 @@ typedef struct RegisterSysregXmlParam { CPUState *cs; GString *s; + int n; } RegisterSysregXmlParam; /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect @@ -32,7 +33,7 @@ typedef struct RegisterSysregXmlParam { 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) +int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; @@ -106,15 +107,16 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) return 0; } -static void arm_gen_one_xml_reg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, - ARMCPRegInfo *ri, uint32_t ri_key, - int bitsize) +static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, + ARMCPRegInfo *ri, uint32_t ri_key, + int bitsize, int regnum) { g_string_append_printf(s, "<reg name=\"%s\"", ri->name); g_string_append_printf(s, " bitsize=\"%d\"", bitsize); + g_string_append_printf(s, " regnum=\"%d\"", regnum); g_string_append_printf(s, " group=\"cp_regs\"/>"); - dyn_xml->num_cpregs++; - dyn_xml->cpregs_keys[dyn_xml->num_cpregs - 1] = ri_key; + dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key; + dyn_xml->num++; } static void arm_register_sysreg_for_xml(gpointer key, gpointer value, @@ -126,12 +128,13 @@ static void arm_register_sysreg_for_xml(gpointer key, gpointer value, GString *s = param->s; ARMCPU *cpu = ARM_CPU(param->cs); CPUARMState *env = &cpu->env; - DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_xml; + DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_sysreg_xml; if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) { if (arm_feature(env, ARM_FEATURE_AARCH64)) { if (ri->state == ARM_CP_STATE_AA64) { - arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 64); + arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, + param->n++); } } else { if (ri->state == ARM_CP_STATE_AA32) { @@ -140,38 +143,174 @@ static void arm_register_sysreg_for_xml(gpointer key, gpointer value, return; } if (ri->type & ARM_CP_64BIT) { - arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 64); + arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, + param->n++); } else { - arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 32); + arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32, + param->n++); } } } } } -int arm_gen_dynamic_xml(CPUState *cs) +int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) { ARMCPU *cpu = ARM_CPU(cs); GString *s = g_string_new(NULL); - RegisterSysregXmlParam param = {cs, s}; + RegisterSysregXmlParam param = {cs, s, base_reg}; - cpu->dyn_xml.num_cpregs = 0; - cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs)); + cpu->dyn_sysreg_xml.num = 0; + cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs)); g_string_printf(s, "<?xml version=\"1.0\"?>"); g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">"); g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_xml, ¶m); g_string_append_printf(s, "</feature>"); - cpu->dyn_xml.desc = g_string_free(s, false); - return cpu->dyn_xml.num_cpregs; + cpu->dyn_sysreg_xml.desc = g_string_free(s, false); + return cpu->dyn_sysreg_xml.num; } +struct TypeSize { + const char *gdb_type; + int size; + const char sz, suffix; +}; + +static const struct TypeSize vec_lanes[] = { + /* quads */ + { "uint128", 128, 'q', 'u' }, + { "int128", 128, 'q', 's' }, + /* 64 bit */ + { "uint64", 64, 'd', 'u' }, + { "int64", 64, 'd', 's' }, + { "ieee_double", 64, 'd', 'f' }, + /* 32 bit */ + { "uint32", 32, 's', 'u' }, + { "int32", 32, 's', 's' }, + { "ieee_single", 32, 's', 'f' }, + /* 16 bit */ + { "uint16", 16, 'h', 'u' }, + { "int16", 16, 'h', 's' }, + { "ieee_half", 16, 'h', 'f' }, + /* bytes */ + { "uint8", 8, 'b', 'u' }, + { "int8", 8, 'b', 's' }, +}; + + +int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg) +{ + ARMCPU *cpu = ARM_CPU(cs); + GString *s = g_string_new(NULL); + DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml; + g_autoptr(GString) ts = g_string_new(""); + int i, bits, reg_width = (cpu->sve_max_vq * 128); + info->num = 0; + g_string_printf(s, "<?xml version=\"1.0\"?>"); + g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); + g_string_append_printf(s, "<feature name=\"org.qemu.gdb.aarch64.sve\">"); + + /* First define types and totals in a whole VL */ + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { + int count = reg_width / vec_lanes[i].size; + g_string_printf(ts, "vq%d%c%c", count, + vec_lanes[i].sz, vec_lanes[i].suffix); + g_string_append_printf(s, + "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>", + ts->str, vec_lanes[i].gdb_type, count); + } + /* + * Now define a union for each size group containing unsigned and + * signed and potentially float versions of each size from 128 to + * 8 bits. + */ + for (bits = 128; bits >= 8; bits /= 2) { + int count = reg_width / bits; + g_string_append_printf(s, "<union id=\"vq%dn\">", count); + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { + if (vec_lanes[i].size == bits) { + g_string_append_printf(s, "<field name=\"%c\" type=\"vq%d%c%c\"/>", + vec_lanes[i].suffix, + count, + vec_lanes[i].sz, vec_lanes[i].suffix); + } + } + g_string_append(s, "</union>"); + } + /* And now the final union of unions */ + g_string_append(s, "<union id=\"vq\">"); + for (bits = 128; bits >= 8; bits /= 2) { + int count = reg_width / bits; + for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { + if (vec_lanes[i].size == bits) { + g_string_append_printf(s, "<field name=\"%c\" type=\"vq%dn\"/>", + vec_lanes[i].sz, count); + break; + } + } + } + g_string_append(s, "</union>"); + + /* Then define each register in parts for each vq */ + for (i = 0; i < 32; i++) { + g_string_append_printf(s, + "<reg name=\"z%d\" bitsize=\"%d\"" + " regnum=\"%d\" group=\"vector\"" + " type=\"vq\"/>", + i, reg_width, base_reg++); + info->num++; + } + /* fpscr & status registers */ + g_string_append_printf(s, "<reg name=\"fpsr\" bitsize=\"32\"" + " regnum=\"%d\" group=\"float\"" + " type=\"int\"/>", base_reg++); + g_string_append_printf(s, "<reg name=\"fpcr\" bitsize=\"32\"" + " regnum=\"%d\" group=\"float\"" + " type=\"int\"/>", base_reg++); + info->num += 2; + /* + * Predicate registers aren't so big they are worth splitting up + * but we do need to define a type to hold the array of quad + * references. + */ + g_string_append_printf(s, + "<vector id=\"vqp\" type=\"uint16\" count=\"%d\"/>", + cpu->sve_max_vq); + for (i = 0; i < 16; i++) { + g_string_append_printf(s, + "<reg name=\"p%d\" bitsize=\"%d\"" + " regnum=\"%d\" group=\"vector\"" + " type=\"vqp\"/>", + i, cpu->sve_max_vq * 16, base_reg++); + info->num++; + } + g_string_append_printf(s, + "<reg name=\"ffr\" bitsize=\"%d\"" + " regnum=\"%d\" group=\"vector\"" + " type=\"vqp\"/>", + cpu->sve_max_vq * 16, base_reg++); + g_string_append_printf(s, + "<reg name=\"vg\" bitsize=\"64\"" + " regnum=\"%d\" group=\"vector\"" + " type=\"uint32\"/>", + base_reg++); + info->num += 2; + g_string_append_printf(s, "</feature>"); + cpu->dyn_svereg_xml.desc = g_string_free(s, false); + + return cpu->dyn_svereg_xml.num; +} + + const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) { ARMCPU *cpu = ARM_CPU(cs); if (strcmp(xmlname, "system-registers.xml") == 0) { - return cpu->dyn_xml.desc; + return cpu->dyn_sysreg_xml.desc; + } else if (strcmp(xmlname, "sve-registers.xml") == 0) { + return cpu->dyn_svereg_xml.desc; } return NULL; } diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c index 665ebb3ef6..35d0b80c2d 100644 --- a/target/arm/gdbstub64.c +++ b/target/arm/gdbstub64.c @@ -20,7 +20,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int aarch64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int aarch64_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; diff --git a/target/arm/helper.c b/target/arm/helper.c index b61ee73d18..d2ec2c5351 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -48,30 +48,27 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, static void switch_mode(CPUARMState *env, int mode); -static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) +static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg) { ARMCPU *cpu = env_archcpu(env); int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; /* VFP data registers are always little-endian. */ if (reg < nregs) { - stq_le_p(buf, *aa32_vfp_dreg(env, reg)); - return 8; + return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg)); } if (arm_feature(env, ARM_FEATURE_NEON)) { /* Aliases for Q regs. */ nregs += 16; if (reg < nregs) { uint64_t *q = aa32_vfp_qreg(env, reg - 32); - stq_le_p(buf, q[0]); - stq_le_p(buf + 8, q[1]); - return 16; + return gdb_get_reg128(buf, q[0], q[1]); } } switch (reg - nregs) { - case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4; - case 1: stl_p(buf, vfp_get_fpscr(env)); return 4; - case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4; + case 0: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); break; + case 1: return gdb_get_reg32(buf, vfp_get_fpscr(env)); break; + case 2: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); break; } return 0; } @@ -102,25 +99,21 @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg) return 0; } -static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) +static int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg) { switch (reg) { case 0 ... 31: - /* 128 bit FP register */ - { - uint64_t *q = aa64_vfp_qreg(env, reg); - stq_le_p(buf, q[0]); - stq_le_p(buf + 8, q[1]); - return 16; - } + { + /* 128 bit FP register - quads are in LE order */ + uint64_t *q = aa64_vfp_qreg(env, reg); + return gdb_get_reg128(buf, q[1], q[0]); + } case 32: /* FPSR */ - stl_p(buf, vfp_get_fpsr(env)); - return 4; + return gdb_get_reg32(buf, vfp_get_fpsr(env)); case 33: /* FPCR */ - stl_p(buf, vfp_get_fpcr(env)); - return 4; + return gdb_get_reg32(buf,vfp_get_fpcr(env)); default: return 0; } @@ -209,13 +202,22 @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, } } -static int arm_gdb_get_sysreg(CPUARMState *env, uint8_t *buf, int reg) +/** + * arm_get/set_gdb_*: get/set a gdb register + * @env: the CPU state + * @buf: a buffer to copy to/from + * @reg: register number (offset from start of group) + * + * We return the number of bytes copied + */ + +static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg) { ARMCPU *cpu = env_archcpu(env); const ARMCPRegInfo *ri; uint32_t key; - key = cpu->dyn_xml.cpregs_keys[reg]; + key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg]; ri = get_arm_cp_reginfo(cpu->cp_regs, key); if (ri) { if (cpreg_field_is_64bit(ri)) { @@ -232,6 +234,102 @@ static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg) return 0; } +#ifdef TARGET_AARCH64 +static int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg) +{ + ARMCPU *cpu = env_archcpu(env); + + switch (reg) { + /* The first 32 registers are the zregs */ + case 0 ... 31: + { + int vq, len = 0; + for (vq = 0; vq < cpu->sve_max_vq; vq++) { + len += gdb_get_reg128(buf, + env->vfp.zregs[reg].d[vq * 2 + 1], + env->vfp.zregs[reg].d[vq * 2]); + } + return len; + } + case 32: + return gdb_get_reg32(buf, vfp_get_fpsr(env)); + case 33: + return gdb_get_reg32(buf, vfp_get_fpcr(env)); + /* then 16 predicates and the ffr */ + case 34 ... 50: + { + int preg = reg - 34; + int vq, len = 0; + for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) { + len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]); + } + return len; + } + case 51: + { + /* + * We report in Vector Granules (VG) which is 64bit in a Z reg + * while the ZCR works in Vector Quads (VQ) which is 128bit chunks. + */ + int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1; + return gdb_get_reg32(buf, vq * 2); + } + default: + /* gdbstub asked for something out our range */ + qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg); + break; + } + + return 0; +} + +static int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg) +{ + ARMCPU *cpu = env_archcpu(env); + + /* The first 32 registers are the zregs */ + switch (reg) { + /* The first 32 registers are the zregs */ + case 0 ... 31: + { + int vq, len = 0; + uint64_t *p = (uint64_t *) buf; + for (vq = 0; vq < cpu->sve_max_vq; vq++) { + env->vfp.zregs[reg].d[vq * 2 + 1] = *p++; + env->vfp.zregs[reg].d[vq * 2] = *p++; + len += 16; + } + return len; + } + case 32: + vfp_set_fpsr(env, *(uint32_t *)buf); + return 4; + case 33: + vfp_set_fpcr(env, *(uint32_t *)buf); + return 4; + case 34 ... 50: + { + int preg = reg - 34; + int vq, len = 0; + uint64_t *p = (uint64_t *) buf; + for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) { + env->vfp.pregs[preg].p[vq / 4] = *p++; + len += 8; + } + return len; + } + case 51: + /* cannot set vg via gdbstub */ + return 0; + default: + /* gdbstub asked for something out our range */ + break; + } + + return 0; +} +#endif /* TARGET_AARCH64 */ + static bool raw_accessors_invalid(const ARMCPRegInfo *ri) { /* Return true if the regdef would cause an assertion if you called @@ -6599,6 +6697,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) return pfr1; } +#ifndef CONFIG_USER_ONLY static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) { ARMCPU *cpu = env_archcpu(env); @@ -6609,6 +6708,7 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) } return pfr0; } +#endif /* Shared logic between LORID and the rest of the LOR* registers. * Secure state has already been delt with. @@ -7182,16 +7282,24 @@ void register_cp_regs_for_features(ARMCPU *cpu) * define new registers here. */ ARMCPRegInfo v8_idregs[] = { - /* ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST because we don't - * know the right value for the GIC field until after we - * define these regs. + /* + * ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST in system + * emulation because we don't know the right value for the + * GIC field until after we define these regs. */ { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_NO_RAW, + .access = PL1_R, +#ifdef CONFIG_USER_ONLY + .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64pfr0 +#else + .type = ARM_CP_NO_RAW, .accessfn = access_aa64_tid3, .readfn = id_aa64pfr0_read, - .writefn = arm_cp_write_ignore }, + .writefn = arm_cp_write_ignore +#endif + }, { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, @@ -7966,9 +8074,22 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) CPUARMState *env = &cpu->env; if (arm_feature(env, ARM_FEATURE_AARCH64)) { - gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg, - aarch64_fpu_gdb_set_reg, - 34, "aarch64-fpu.xml", 0); + /* + * The lower part of each SVE register aliases to the FPU + * registers so we don't need to include both. + */ +#ifdef TARGET_AARCH64 + if (isar_feature_aa64_sve(&cpu->isar)) { + gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg, + arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs), + "sve-registers.xml", 0); + } else +#endif + { + gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg, + aarch64_fpu_gdb_set_reg, + 34, "aarch64-fpu.xml", 0); + } } else if (arm_feature(env, ARM_FEATURE_NEON)) { gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 51, "arm-neon.xml", 0); @@ -7980,8 +8101,9 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) 19, "arm-vfp.xml", 0); } gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg, - arm_gen_dynamic_xml(cs), + arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs), "system-registers.xml", 0); + } /* Sort alphabetically by type name, except for "any". */ diff --git a/target/cris/cpu.h b/target/cris/cpu.h index ca240bc788..8f08d7628b 100644 --- a/target/cris/cpu.h +++ b/target/cris/cpu.h @@ -195,8 +195,8 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags); hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr 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 crisv10_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); +int cris_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); /* you can call this signal handler from your SIGBUS and SIGSEGV diff --git a/target/cris/gdbstub.c b/target/cris/gdbstub.c index a3d76d2e8c..b01b2aa081 100644 --- a/target/cris/gdbstub.c +++ b/target/cris/gdbstub.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int crisv10_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int crisv10_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { CRISCPU *cpu = CRIS_CPU(cs); CPUCRISState *env = &cpu->env; @@ -53,7 +53,7 @@ int crisv10_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return 0; } -int cris_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int cris_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { CRISCPU *cpu = CRIS_CPU(cs); CPUCRISState *env = &cpu->env; diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 6713d04f11..801a4fb1ba 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -321,7 +321,7 @@ void cpu_hppa_change_prot_id(CPUHPPAState *env); int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc); hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr); -int hppa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void hppa_cpu_do_interrupt(CPUState *cpu); bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req); diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c index 341888a9da..a6428a2893 100644 --- a/target/hppa/gdbstub.c +++ b/target/hppa/gdbstub.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int hppa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { HPPACPU *cpu = HPPA_CPU(cs); CPUHPPAState *env = &cpu->env; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 576f309bbf..c2d89315b9 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1766,7 +1766,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags); hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, MemTxAttrs *attrs); -int x86_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int x86_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void x86_cpu_exec_enter(CPUState *cpu); diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c index 572ead641c..f3d23b614e 100644 --- a/target/i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -79,7 +79,7 @@ static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; #endif -int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; @@ -98,26 +98,22 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]] & 0xffffffffUL); } else { - memset(mem_buf, 0, sizeof(target_ulong)); - return sizeof(target_ulong); + return gdb_get_regl(mem_buf, 0); } } else { 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; + floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS]; + int len = gdb_get_reg64(mem_buf, cpu_to_le64(fp->low)); + len += gdb_get_reg16(mem_buf + len, cpu_to_le16(fp->high)); + return len; } 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) { - stq_p(mem_buf, env->xmm_regs[n].ZMM_Q(0)); - stq_p(mem_buf + 8, env->xmm_regs[n].ZMM_Q(1)); - return 16; + return gdb_get_reg128(mem_buf, + env->xmm_regs[n].ZMM_Q(0), + env->xmm_regs[n].ZMM_Q(1)); } } else { switch (n) { @@ -290,10 +286,9 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 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 + floatx80 *fp = (floatx80 *) &env->fpregs[n - IDX_FP_REGS]; + fp->low = le64_to_cpu(* (uint64_t *) mem_buf); + fp->high = le16_to_cpu(* (uint16_t *) (mem_buf + 8)); return 10; } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { n -= IDX_XMM_REGS; diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h index 064c6b1267..01d408eb55 100644 --- a/target/lm32/cpu.h +++ b/target/lm32/cpu.h @@ -202,7 +202,7 @@ void lm32_cpu_do_interrupt(CPUState *cpu); bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req); void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int lm32_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); typedef enum { diff --git a/target/lm32/gdbstub.c b/target/lm32/gdbstub.c index 82ede436e1..b6fe12e1d6 100644 --- a/target/lm32/gdbstub.c +++ b/target/lm32/gdbstub.c @@ -22,7 +22,7 @@ #include "exec/gdbstub.h" #include "hw/lm32/lm32_pic.h" -int lm32_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int lm32_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { LM32CPU *cpu = LM32_CPU(cs); CPULM32State *env = &cpu->env; diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 3de8e06dfe..521ac67cdd 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -168,7 +168,7 @@ void m68k_cpu_do_interrupt(CPUState *cpu); bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req); void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void m68k_tcg_init(void); diff --git a/target/m68k/gdbstub.c b/target/m68k/gdbstub.c index fdc96f57ff..eb2d030e14 100644 --- a/target/m68k/gdbstub.c +++ b/target/m68k/gdbstub.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int m68k_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int m68k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { M68kCPU *cpu = M68K_CPU(cs); CPUM68KState *env = &cpu->env; diff --git a/target/m68k/helper.c b/target/m68k/helper.c index baf7729af0..014657c637 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -68,23 +68,19 @@ void m68k_cpu_list(void) g_slist_free(list); } -static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) +static int cf_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n) { if (n < 8) { float_status s; - stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, &s)); - return 8; + return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s)); } switch (n) { case 8: /* fpcontrol */ - stl_be_p(mem_buf, env->fpcr); - return 4; + return gdb_get_reg32(mem_buf, env->fpcr); case 9: /* fpstatus */ - stl_be_p(mem_buf, env->fpsr); - return 4; + return gdb_get_reg32(mem_buf, env->fpsr); case 10: /* fpiar, not implemented */ - memset(mem_buf, 0, 4); - return 4; + return gdb_get_reg32(mem_buf, 0); } return 0; } @@ -109,24 +105,21 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) return 0; } -static int m68k_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) +static int m68k_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n) { if (n < 8) { - stw_be_p(mem_buf, env->fregs[n].l.upper); - memset(mem_buf + 2, 0, 2); - stq_be_p(mem_buf + 4, env->fregs[n].l.lower); - return 12; + int len = gdb_get_reg16(mem_buf, env->fregs[n].l.upper); + len += gdb_get_reg16(mem_buf + len, 0); + len += gdb_get_reg64(mem_buf + len, env->fregs[n].l.lower); + return len; } switch (n) { case 8: /* fpcontrol */ - stl_be_p(mem_buf, env->fpcr); - return 4; + return gdb_get_reg32(mem_buf, env->fpcr); case 9: /* fpstatus */ - stl_be_p(mem_buf, env->fpsr); - return 4; + return gdb_get_reg32(mem_buf, env->fpsr); case 10: /* fpiar, not implemented */ - memset(mem_buf, 0, 4); - return 4; + return gdb_get_reg32(mem_buf, 0); } return 0; } diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 32522f606b..1a700a880c 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -313,7 +313,7 @@ void mb_cpu_do_interrupt(CPUState *cs); bool mb_cpu_exec_interrupt(CPUState *cs, int int_req); void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int mb_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void mb_tcg_init(void); diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c index 30677b6d1f..f41ebf1f33 100644 --- a/target/microblaze/gdbstub.c +++ b/target/microblaze/gdbstub.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int mb_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); CPUMBState *env = &cpu->env; diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index bbb2544939..98f56e660d 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -22,7 +22,7 @@ #include "internal.h" #include "exec/gdbstub.h" -int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int mips_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { MIPSCPU *cpu = MIPS_CPU(cs); CPUMIPSState *env = &cpu->env; diff --git a/target/mips/internal.h b/target/mips/internal.h index df55f845ba..1bf274b3ef 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -82,7 +82,7 @@ void mips_cpu_do_interrupt(CPUState *cpu); bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req); void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int mips_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int mips_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c index 1c0c855a6f..1856b7fcc7 100644 --- a/target/nios2/cpu.c +++ b/target/nios2/cpu.c @@ -124,7 +124,7 @@ static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) #endif } -static int nios2_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +static int nios2_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { Nios2CPU *cpu = NIOS2_CPU(cs); CPUClass *cc = CPU_GET_CLASS(cs); diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 0ad02eab79..d9484b802f 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -320,7 +320,7 @@ void openrisc_cpu_do_interrupt(CPUState *cpu); bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void openrisc_translate_init(void); bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, diff --git a/target/openrisc/gdbstub.c b/target/openrisc/gdbstub.c index 0fcdb79668..095bf76c12 100644 --- a/target/openrisc/gdbstub.c +++ b/target/openrisc/gdbstub.c @@ -21,7 +21,7 @@ #include "cpu.h" #include "exec/gdbstub.h" -int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int openrisc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { OpenRISCCPU *cpu = OPENRISC_CPU(cs); CPUOpenRISCState *env = &cpu->env; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index f8c7d6f19c..88d9449555 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1207,8 +1207,8 @@ bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req); void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void ppc_cpu_dump_statistics(CPUState *cpu, int flags); hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); -int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg); +int ppc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); +int ppc_cpu_gdb_read_register_apple(CPUState *cpu, GByteArray *buf, int reg); int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg); #ifndef CONFIG_USER_ONLY diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index 823759c92e..eb362dd9ae 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c @@ -114,10 +114,11 @@ void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len) * 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; + uint8_t *mem_buf; int r = ppc_gdb_register_len(n); if (!r) { @@ -126,17 +127,17 @@ 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]); + gdb_get_regl(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 { 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: { @@ -145,31 +146,33 @@ int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) for (i = 0; i < 8; i++) { cr |= env->crf[i] << (32 - ((i + 1) * 4)); } - gdb_get_reg32(mem_buf, cr); + 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); + gdb_get_reg32(buf, env->xer); break; case 70: - gdb_get_reg32(mem_buf, env->fpscr); + gdb_get_reg32(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_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; + uint8_t *mem_buf; int r = ppc_gdb_register_len_apple(n); if (!r) { @@ -178,21 +181,21 @@ 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: { @@ -201,23 +204,24 @@ int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n) for (i = 0; i < 8; i++) { cr |= env->crf[i] << (32 - ((i + 1) * 4)); } - gdb_get_reg32(mem_buf, cr); + 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, env->xer); 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; } diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 0ae145e18d..997c8b0b4b 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9843,7 +9843,7 @@ static int gdb_find_spr_idx(CPUPPCState *env, int n) return -1; } -static int gdb_get_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n) { int reg; int len; @@ -9854,8 +9854,8 @@ static int gdb_get_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) } len = TARGET_LONG_SIZE; - stn_p(mem_buf, len, env->spr[reg]); - ppc_maybe_bswap_register(env, mem_buf, len); + gdb_get_regl(buf, env->spr[reg]); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len); return len; } @@ -9877,15 +9877,18 @@ static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) } #endif -static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) { + uint8_t *mem_buf; if (n < 32) { - stfq_p(mem_buf, *cpu_fpr_ptr(env, n)); + 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) { - stl_p(mem_buf, env->fpscr); + gdb_get_reg32(buf, env->fpscr); + mem_buf = gdb_get_reg_ptr(buf, 4); ppc_maybe_bswap_register(env, mem_buf, 4); return 4; } @@ -9907,28 +9910,31 @@ static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n) { + uint8_t *mem_buf; + if (n < 32) { ppc_avr_t *avr = cpu_avr_ptr(env, n); if (!avr_need_swap(env)) { - stq_p(mem_buf, avr->u64[0]); - stq_p(mem_buf + 8, avr->u64[1]); + gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]); } else { - stq_p(mem_buf, avr->u64[1]); - stq_p(mem_buf + 8, avr->u64[0]); + gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]); } + mem_buf = gdb_get_reg_ptr(buf, 16); ppc_maybe_bswap_register(env, mem_buf, 8); ppc_maybe_bswap_register(env, mem_buf + 8, 8); return 16; } if (n == 32) { - stl_p(mem_buf, helper_mfvscr(env)); + gdb_get_reg32(buf, helper_mfvscr(env)); + mem_buf = gdb_get_reg_ptr(buf, 4); ppc_maybe_bswap_register(env, mem_buf, 4); return 4; } if (n == 33) { - stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]); + 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; } @@ -9963,25 +9969,25 @@ static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n) { if (n < 32) { #if defined(TARGET_PPC64) - stl_p(mem_buf, env->gpr[n] >> 32); - ppc_maybe_bswap_register(env, mem_buf, 4); + gdb_get_reg32(buf, env->gpr[n] >> 32); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); #else - stl_p(mem_buf, env->gprh[n]); + gdb_get_reg32(buf, env->gprh[n]); #endif return 4; } if (n == 32) { - stq_p(mem_buf, env->spe_acc); - ppc_maybe_bswap_register(env, mem_buf, 8); + gdb_get_reg64(buf, env->spe_acc); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); return 8; } if (n == 33) { - stl_p(mem_buf, env->spe_fscr); - ppc_maybe_bswap_register(env, mem_buf, 4); + gdb_get_reg32(buf, env->spe_fscr); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); return 4; } return 0; @@ -10016,11 +10022,11 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_get_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n) { if (n < 32) { - stq_p(mem_buf, *cpu_vsrl_ptr(env, n)); - ppc_maybe_bswap_register(env, mem_buf, 8); + 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; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 3dcdf92227..31458c5b4a 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -293,7 +293,7 @@ extern const char * const riscv_excp_names[]; extern const char * const riscv_intr_names[]; void riscv_cpu_do_interrupt(CPUState *cpu); -int riscv_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request); bool riscv_cpu_fp_enabled(CPURISCVState *env); diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c index 2f32750f2f..eba12a86f2 100644 --- a/target/riscv/gdbstub.c +++ b/target/riscv/gdbstub.c @@ -270,7 +270,7 @@ static int csr_register_map[] = { CSR_MHCOUNTEREN, }; -int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; @@ -301,14 +301,14 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) return 0; } -static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) +static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n) { if (n < 32) { if (env->misa & RVD) { - return gdb_get_reg64(mem_buf, env->fpr[n]); + return gdb_get_reg64(buf, env->fpr[n]); } if (env->misa & RVF) { - return gdb_get_reg32(mem_buf, env->fpr[n]); + return gdb_get_reg32(buf, env->fpr[n]); } /* there is hole between ft11 and fflags in fpu.xml */ } else if (n < 36 && n > 32) { @@ -322,7 +322,7 @@ static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], &val, 0, 0); if (result == 0) { - return gdb_get_regl(mem_buf, val); + return gdb_get_regl(buf, val); } } return 0; @@ -351,7 +351,7 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) return 0; } -static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n) +static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n) { if (n < ARRAY_SIZE(csr_register_map)) { target_ulong val = 0; @@ -359,7 +359,7 @@ static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n) result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0); if (result == 0) { - return gdb_get_regl(mem_buf, val); + return gdb_get_regl(buf, val); } } return 0; @@ -379,13 +379,13 @@ static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n) return 0; } -static int riscv_gdb_get_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) +static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n) { if (n == 0) { #ifdef CONFIG_USER_ONLY - return gdb_get_regl(mem_buf, 0); + return gdb_get_regl(buf, 0); #else - return gdb_get_regl(mem_buf, cs->priv); + return gdb_get_regl(buf, cs->priv); #endif } return 0; diff --git a/target/s390x/gdbstub.c b/target/s390x/gdbstub.c index e24a49f4a9..d6fce5ff1e 100644 --- a/target/s390x/gdbstub.c +++ b/target/s390x/gdbstub.c @@ -27,7 +27,7 @@ #include "sysemu/hw_accel.h" #include "sysemu/tcg.h" -int s390_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int s390_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { S390CPU *cpu = S390_CPU(cs); CPUS390XState *env = &cpu->env; @@ -82,11 +82,11 @@ int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) /* total number of registers in s390-acr.xml */ #define S390_NUM_AC_REGS 16 -static int cpu_read_ac_reg(CPUS390XState *env, uint8_t *mem_buf, int n) +static int cpu_read_ac_reg(CPUS390XState *env, GByteArray *buf, int n) { switch (n) { case S390_A0_REGNUM ... S390_A15_REGNUM: - return gdb_get_reg32(mem_buf, env->aregs[n]); + return gdb_get_reg32(buf, env->aregs[n]); default: return 0; } @@ -111,13 +111,13 @@ static int cpu_write_ac_reg(CPUS390XState *env, uint8_t *mem_buf, int n) /* total number of registers in s390-fpr.xml */ #define S390_NUM_FP_REGS 17 -static int cpu_read_fp_reg(CPUS390XState *env, uint8_t *mem_buf, int n) +static int cpu_read_fp_reg(CPUS390XState *env, GByteArray *buf, int n) { switch (n) { case S390_FPC_REGNUM: - return gdb_get_reg32(mem_buf, env->fpc); + return gdb_get_reg32(buf, env->fpc); case S390_F0_REGNUM ... S390_F15_REGNUM: - return gdb_get_reg64(mem_buf, *get_freg(env, n - S390_F0_REGNUM)); + return gdb_get_reg64(buf, *get_freg(env, n - S390_F0_REGNUM)); default: return 0; } @@ -145,17 +145,17 @@ static int cpu_write_fp_reg(CPUS390XState *env, uint8_t *mem_buf, int n) /* total number of registers in s390-vx.xml */ #define S390_NUM_VREGS 32 -static int cpu_read_vreg(CPUS390XState *env, uint8_t *mem_buf, int n) +static int cpu_read_vreg(CPUS390XState *env, GByteArray *buf, int n) { int ret; switch (n) { case S390_V0L_REGNUM ... S390_V15L_REGNUM: - ret = gdb_get_reg64(mem_buf, env->vregs[n][1]); + ret = gdb_get_reg64(buf, env->vregs[n][1]); break; case S390_V16_REGNUM ... S390_V31_REGNUM: - ret = gdb_get_reg64(mem_buf, env->vregs[n][0]); - ret += gdb_get_reg64(mem_buf + 8, env->vregs[n][1]); + ret = gdb_get_reg64(buf, env->vregs[n][0]); + ret += gdb_get_reg64(buf, env->vregs[n][1]); break; default: ret = 0; @@ -186,11 +186,11 @@ static int cpu_write_vreg(CPUS390XState *env, uint8_t *mem_buf, int n) #define S390_NUM_C_REGS 16 #ifndef CONFIG_USER_ONLY -static int cpu_read_c_reg(CPUS390XState *env, uint8_t *mem_buf, int n) +static int cpu_read_c_reg(CPUS390XState *env, GByteArray *buf, int n) { switch (n) { case S390_C0_REGNUM ... S390_C15_REGNUM: - return gdb_get_regl(mem_buf, env->cregs[n]); + return gdb_get_regl(buf, env->cregs[n]); default: return 0; } @@ -223,7 +223,7 @@ static int cpu_write_c_reg(CPUS390XState *env, uint8_t *mem_buf, int n) /* total number of registers in s390-virt.xml */ #define S390_NUM_VIRT_REGS 8 -static int cpu_read_virt_reg(CPUS390XState *env, uint8_t *mem_buf, int n) +static int cpu_read_virt_reg(CPUS390XState *env, GByteArray *mem_buf, int n) { switch (n) { case S390_VIRT_CKC_REGNUM: @@ -296,9 +296,9 @@ static int cpu_write_virt_reg(CPUS390XState *env, uint8_t *mem_buf, int n) /* total number of registers in s390-gs.xml */ #define S390_NUM_GS_REGS 4 -static int cpu_read_gs_reg(CPUS390XState *env, uint8_t *mem_buf, int n) +static int cpu_read_gs_reg(CPUS390XState *env, GByteArray *buf, int n) { - return gdb_get_regl(mem_buf, env->gscb[n]); + return gdb_get_regl(buf, env->gscb[n]); } static int cpu_write_gs_reg(CPUS390XState *env, uint8_t *mem_buf, int n) diff --git a/target/s390x/internal.h b/target/s390x/internal.h index d37816104d..8c95c734db 100644 --- a/target/s390x/internal.h +++ b/target/s390x/internal.h @@ -292,7 +292,7 @@ uint16_t float128_dcmask(CPUS390XState *env, float128 f1); /* gdbstub.c */ -int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int s390_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void s390_cpu_gdb_init(CPUState *cs); diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 452a596e67..dbe58c7888 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -208,7 +208,7 @@ void superh_cpu_do_interrupt(CPUState *cpu); bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req); void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int superh_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, diff --git a/target/sh4/gdbstub.c b/target/sh4/gdbstub.c index 44c1679e9d..49fc4a0cc6 100644 --- a/target/sh4/gdbstub.c +++ b/target/sh4/gdbstub.c @@ -24,7 +24,7 @@ /* 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) +int superh_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { SuperHCPU *cpu = SUPERH_CPU(cs); CPUSH4State *env = &cpu->env; diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index ae97c7d9f7..b9369398f2 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -571,7 +571,7 @@ extern const VMStateDescription vmstate_sparc_cpu; void sparc_cpu_do_interrupt(CPUState *cpu); void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int sparc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c index 8be742b5a3..78dc8dcc98 100644 --- a/target/sparc/gdbstub.c +++ b/target/sparc/gdbstub.c @@ -27,7 +27,7 @@ #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) +int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { SPARCCPU *cpu = SPARC_CPU(cs); CPUSPARCState *env = &cpu->env; diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 493f4fc80c..c0d69fad96 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -569,7 +569,7 @@ void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); void xtensa_count_regs(const XtensaConfig *config, unsigned *n_regs, unsigned *n_core_regs); -int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); +int xtensa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, diff --git a/target/xtensa/gdbstub.c b/target/xtensa/gdbstub.c index 54727881f3..0ee3feabe5 100644 --- a/target/xtensa/gdbstub.c +++ b/target/xtensa/gdbstub.c @@ -63,7 +63,7 @@ void xtensa_count_regs(const XtensaConfig *config, } } -int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) +int xtensa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; |