diff options
author | Abdallah Bouassida <abdallah.bouassida@lauterbach.com> | 2018-05-18 17:48:07 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-05-18 17:48:07 +0100 |
commit | 200bf5b7ffea635079cc05fdfb363372b9544ce7 (patch) | |
tree | 1b485d5f1d8668ae0cd12da251dfc0fc583e04ef /target/arm/gdbstub.c | |
parent | 9c513e786d85cc58b8ba56a482566f759e0835b6 (diff) | |
download | qemu-200bf5b7ffea635079cc05fdfb363372b9544ce7.zip qemu-200bf5b7ffea635079cc05fdfb363372b9544ce7.tar.gz qemu-200bf5b7ffea635079cc05fdfb363372b9544ce7.tar.bz2 |
target/arm: Add the XML dynamic generation
Generate an XML description for the cp-regs.
Register these regs with the gdb_register_coprocessor().
Add arm_gdb_get_sysreg() to use it as a callback to read those regs.
Add a dummy arm_gdb_set_sysreg().
Signed-off-by: Abdallah Bouassida <abdallah.bouassida@lauterbach.com>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 1524153386-3550-4-git-send-email-abdallah.bouassida@lauterbach.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/gdbstub.c')
-rw-r--r-- | target/arm/gdbstub.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 04c1208..e80cfb4 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -22,6 +22,11 @@ #include "cpu.h" #include "exec/gdbstub.h" +typedef struct RegisterSysregXmlParam { + CPUState *cs; + GString *s; +} RegisterSysregXmlParam; + /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect whatever the target description contains. Due to a historical mishap the FPA registers appear in between core integer regs and the CPSR. @@ -101,3 +106,74 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) /* Unknown register. */ return 0; } + +static void arm_gen_one_xml_reg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, + ARMCPRegInfo *ri, uint32_t ri_key, + int bitsize) +{ + g_string_append_printf(s, "<reg name=\"%s\"", ri->name); + g_string_append_printf(s, " bitsize=\"%d\"", bitsize); + g_string_append_printf(s, " group=\"cp_regs\"/>"); + dyn_xml->num_cpregs++; + dyn_xml->cpregs_keys[dyn_xml->num_cpregs - 1] = ri_key; +} + +static void arm_register_sysreg_for_xml(gpointer key, gpointer value, + gpointer p) +{ + uint32_t ri_key = *(uint32_t *)key; + ARMCPRegInfo *ri = value; + RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p; + GString *s = param->s; + ARMCPU *cpu = ARM_CPU(param->cs); + CPUARMState *env = &cpu->env; + DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_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); + } + } else { + if (ri->state == ARM_CP_STATE_AA32) { + if (!arm_feature(env, ARM_FEATURE_EL3) && + (ri->secure & ARM_CP_SECSTATE_S)) { + return; + } + if (ri->type & ARM_CP_64BIT) { + arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 64); + } else { + arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 32); + } + } + } + } +} + +int arm_gen_dynamic_xml(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + GString *s = g_string_new(NULL); + RegisterSysregXmlParam param = {cs, s}; + + cpu->dyn_xml.num_cpregs = 0; + cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(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; +} + +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 NULL; +} |