diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2023-03-07 09:58:43 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2023-03-07 09:58:43 +0000 |
| commit | c29a2f40cd5d1fdad4632b48343cd968db041a44 (patch) | |
| tree | ee30a898f0d168bde15112f78430ee7f978ee67c /target/arm/gdbstub.c | |
| parent | c1feaf76833f5b29f887fd64371512731cbf7086 (diff) | |
| parent | 2ddc45954f97cd1d7ee5cbca0def05e980d1da9f (diff) | |
| download | focaccia-qemu-c29a2f40cd5d1fdad4632b48343cd968db041a44.tar.gz focaccia-qemu-c29a2f40cd5d1fdad4632b48343cd968db041a44.zip | |
Merge tag 'pull-target-arm-20230306' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * allwinner-h3: Fix I2C controller model for Sun6i SoCs * allwinner-h3: Add missing i2c controllers * Expose M-profile system registers to gdbstub * Expose pauth information to gdbstub * Support direct boot for Linux/arm64 EFI zboot images * Fix incorrect stage 2 MMU setup validation # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmQGB+wZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3gdQEACVfgbs77mxbOb6u8yWHKGZ # tVnQr9KZMv2lmwt5H3ROJPXznchrIIAwdMeRgKnbI+lC5jTq9L+Q8RJch3t/EbAd # f0VMyiPe3DzCbCrAR9cW6EWzbYnEVo3Ioj4k7qjxK6u1BIKhXz99DLYd1KRdTxnx # BAYmcl857Uir1q2FrBVMZ/ItCLbk4ejn+YaDIawNue2/s1oGa+we473x9rosCFvp # L9bzT3R46e0o+Mfkn1OYRmgCmURTalWPpWAxyOUFR9YbrzXleLgAKEB3o3PPcvls # u26uxztyRMqje1q06VjUzwaLw7zN9XPhmir+NXX7KXp2/x9PZjApOpPtt0kl+6qe # FbByKfl24O9w/OKewsJw+udCBYdYrRPm6tWv2D71iAwjBUzBJgNGe5VPRdPFtPDn # uSRO65o34w1nPzRpAheUciZueiabYrVmIgVltFxj0JlrKGfgiYHPLVyU0Uu0K/A7 # F2kUEQIzIcWdo+c8SlvlWOEA2ojVd/KoLVLgndqr40Tk5pbc65TRS08kkVVl4cMT # jUGscl7Dyxe+yo8+nHdycAJpnKYDllJOh2JbGv3r2FqCy5FMuIqW4hHeuUxwpE+O # nxm7lzjnaVHSAFHdzhk9x4E4uH/GTcdWzX1EsmpgGqe5oejLJOrCINb+Dj44+Y8h # 8aGRvE7kxMs11upxc7BcAw== # =KIMt # -----END PGP SIGNATURE----- # gpg: Signature made Mon 06 Mar 2023 15:34:04 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20230306' of https://git.linaro.org/people/pmaydell/qemu-arm: (21 commits) hw: arm: allwinner-h3: Fix and complete H3 i2c devices hw: allwinner-i2c: Fix TWI_CNTR_INT_FLAG on SUN6i SoCs hw: arm: Support direct boot for Linux/arm64 EFI zboot images target/arm: Rewrite check_s2_mmu_setup target/arm: Diagnose incorrect usage of arm_is_secure subroutines target/arm: Stub arm_hcr_el2_eff for m-profile target/arm: Handle m-profile in arm_is_secure target/arm: Implement gdbstub m-profile systemreg and secext target/arm: Export arm_v7m_get_sp_ptr target/arm: Export arm_v7m_mrs_control target/arm: Implement gdbstub pauth extension target/arm: Create pauth_ptr_mask target/arm: Simplify iteration over bit widths target/arm: Add name argument to output_vector_union_type target/arm: Fix svep width in arm_gen_dynamic_svereg_xml target/arm: Hoist pred_width in arm_gen_dynamic_svereg_xml target/arm: Simplify register counting in arm_gen_dynamic_svereg_xml target/arm: Split out output_vector_union_type target/arm: Move arm_gen_dynamic_svereg_xml to gdbstub64.c target/arm: Unexport arm_gen_dynamic_sysreg_xml ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/gdbstub.c')
| -rw-r--r-- | target/arm/gdbstub.c | 272 |
1 files changed, 168 insertions, 104 deletions
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 2f806512d0..3f799f5d05 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -305,7 +305,7 @@ static void arm_register_sysreg_for_xml(gpointer key, gpointer value, } } -int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) +static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) { ARMCPU *cpu = ARM_CPU(cs); GString *s = g_string_new(NULL); @@ -322,125 +322,163 @@ int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) return cpu->dyn_sysreg_xml.num; } -struct TypeSize { - const char *gdb_type; - int size; - const char sz, suffix; +typedef enum { + M_SYSREG_MSP, + M_SYSREG_PSP, + M_SYSREG_PRIMASK, + M_SYSREG_CONTROL, + M_SYSREG_BASEPRI, + M_SYSREG_FAULTMASK, + M_SYSREG_MSPLIM, + M_SYSREG_PSPLIM, +} MProfileSysreg; + +static const struct { + const char *name; + int feature; +} m_sysreg_def[] = { + [M_SYSREG_MSP] = { "msp", ARM_FEATURE_M }, + [M_SYSREG_PSP] = { "psp", ARM_FEATURE_M }, + [M_SYSREG_PRIMASK] = { "primask", ARM_FEATURE_M }, + [M_SYSREG_CONTROL] = { "control", ARM_FEATURE_M }, + [M_SYSREG_BASEPRI] = { "basepri", ARM_FEATURE_M_MAIN }, + [M_SYSREG_FAULTMASK] = { "faultmask", ARM_FEATURE_M_MAIN }, + [M_SYSREG_MSPLIM] = { "msplim", ARM_FEATURE_V8 }, + [M_SYSREG_PSPLIM] = { "psplim", ARM_FEATURE_V8 }, }; -static const struct TypeSize vec_lanes[] = { - /* quads */ - { "uint128", 128, 'q', 'u' }, - { "int128", 128, 'q', 's' }, - /* 64 bit */ - { "ieee_double", 64, 'd', 'f' }, - { "uint64", 64, 'd', 'u' }, - { "int64", 64, 'd', 's' }, - /* 32 bit */ - { "ieee_single", 32, 's', 'f' }, - { "uint32", 32, 's', 'u' }, - { "int32", 32, 's', 's' }, - /* 16 bit */ - { "ieee_half", 16, 'h', 'f' }, - { "uint16", 16, 'h', 'u' }, - { "int16", 16, 'h', 's' }, - /* bytes */ - { "uint8", 8, 'b', 'u' }, - { "int8", 8, 'b', 's' }, -}; +static uint32_t *m_sysreg_ptr(CPUARMState *env, MProfileSysreg reg, bool sec) +{ + uint32_t *ptr; + + switch (reg) { + case M_SYSREG_MSP: + ptr = arm_v7m_get_sp_ptr(env, sec, false, true); + break; + case M_SYSREG_PSP: + ptr = arm_v7m_get_sp_ptr(env, sec, true, true); + break; + case M_SYSREG_MSPLIM: + ptr = &env->v7m.msplim[sec]; + break; + case M_SYSREG_PSPLIM: + ptr = &env->v7m.psplim[sec]; + break; + case M_SYSREG_PRIMASK: + ptr = &env->v7m.primask[sec]; + break; + case M_SYSREG_BASEPRI: + ptr = &env->v7m.basepri[sec]; + break; + case M_SYSREG_FAULTMASK: + ptr = &env->v7m.faultmask[sec]; + break; + case M_SYSREG_CONTROL: + ptr = &env->v7m.control[sec]; + break; + default: + return NULL; + } + return arm_feature(env, m_sysreg_def[reg].feature) ? ptr : NULL; +} + +static int m_sysreg_get(CPUARMState *env, GByteArray *buf, + MProfileSysreg reg, bool secure) +{ + uint32_t *ptr = m_sysreg_ptr(env, reg, secure); + + if (ptr == NULL) { + return 0; + } + return gdb_get_reg32(buf, *ptr); +} + +static int arm_gdb_get_m_systemreg(CPUARMState *env, GByteArray *buf, int reg) +{ + /* + * Here, we emulate MRS instruction, where CONTROL has a mix of + * banked and non-banked bits. + */ + if (reg == M_SYSREG_CONTROL) { + return gdb_get_reg32(buf, arm_v7m_mrs_control(env, env->v7m.secure)); + } + return m_sysreg_get(env, buf, reg, env->v7m.secure); +} +static int arm_gdb_set_m_systemreg(CPUARMState *env, uint8_t *buf, int reg) +{ + return 0; /* TODO */ +} -int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg) +static int arm_gen_dynamic_m_systemreg_xml(CPUState *cs, int orig_base_reg) { ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; GString *s = g_string_new(NULL); - DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml; - g_autoptr(GString) ts = g_string_new(""); - int i, j, bits, reg_width = (cpu->sve_max_vq * 128); - info->num = 0; + int base_reg = orig_base_reg; + int i; + 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.gnu.gdb.aarch64.sve\">"); + g_string_append_printf(s, "<feature name=\"org.gnu.gdb.arm.m-system\">\n"); - /* 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, "svev%c%c", 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, i = 0; bits >= 8; bits /= 2, i++) { - const char suf[] = { 'q', 'd', 's', 'h', 'b' }; - g_string_append_printf(s, "<union id=\"svevn%c\">", suf[i]); - for (j = 0; j < ARRAY_SIZE(vec_lanes); j++) { - if (vec_lanes[j].size == bits) { - g_string_append_printf(s, "<field name=\"%c\" type=\"svev%c%c\"/>", - vec_lanes[j].suffix, - vec_lanes[j].sz, vec_lanes[j].suffix); - } + for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) { + if (arm_feature(env, m_sysreg_def[i].feature)) { + g_string_append_printf(s, + "<reg name=\"%s\" bitsize=\"32\" regnum=\"%d\"/>\n", + m_sysreg_def[i].name, base_reg++); } - g_string_append(s, "</union>"); } - /* And now the final union of unions */ - g_string_append(s, "<union id=\"svev\">"); - for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) { - const char suf[] = { 'q', 'd', 's', 'h', 'b' }; - g_string_append_printf(s, "<field name=\"%c\" type=\"svevn%c\"/>", - suf[i], suf[i]); - } - g_string_append(s, "</union>"); - /* Finally the sve prefix type */ - g_string_append_printf(s, - "<vector id=\"svep\" type=\"uint8\" count=\"%d\"/>", - reg_width / 8); + g_string_append_printf(s, "</feature>"); + cpu->dyn_m_systemreg_xml.desc = g_string_free(s, false); + cpu->dyn_m_systemreg_xml.num = base_reg - orig_base_reg; + + return cpu->dyn_m_systemreg_xml.num; +} + +#ifndef CONFIG_USER_ONLY +/* + * For user-only, we see the non-secure registers via m_systemreg above. + * For secext, encode the non-secure view as even and secure view as odd. + */ +static int arm_gdb_get_m_secextreg(CPUARMState *env, GByteArray *buf, int reg) +{ + return m_sysreg_get(env, buf, reg >> 1, reg & 1); +} + +static int arm_gdb_set_m_secextreg(CPUARMState *env, uint8_t *buf, int reg) +{ + return 0; /* TODO */ +} + +static int arm_gen_dynamic_m_secextreg_xml(CPUState *cs, int orig_base_reg) +{ + ARMCPU *cpu = ARM_CPU(cs); + GString *s = g_string_new(NULL); + int base_reg = orig_base_reg; + int i; + + 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.gnu.gdb.arm.secext\">\n"); - /* Then define each register in parts for each vq */ - for (i = 0; i < 32; i++) { + for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) { g_string_append_printf(s, - "<reg name=\"z%d\" bitsize=\"%d\"" - " regnum=\"%d\" type=\"svev\"/>", - 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; - - for (i = 0; i < 16; i++) { + "<reg name=\"%s_ns\" bitsize=\"32\" regnum=\"%d\"/>\n", + m_sysreg_def[i].name, base_reg++); g_string_append_printf(s, - "<reg name=\"p%d\" bitsize=\"%d\"" - " regnum=\"%d\" type=\"svep\"/>", - i, cpu->sve_max_vq * 16, base_reg++); - info->num++; + "<reg name=\"%s_s\" bitsize=\"32\" regnum=\"%d\"/>\n", + m_sysreg_def[i].name, base_reg++); } - g_string_append_printf(s, - "<reg name=\"ffr\" bitsize=\"%d\"" - " regnum=\"%d\" group=\"vector\"" - " type=\"svep\"/>", - cpu->sve_max_vq * 16, base_reg++); - g_string_append_printf(s, - "<reg name=\"vg\" bitsize=\"64\"" - " regnum=\"%d\" type=\"int\"/>", - base_reg++); - info->num += 2; + g_string_append_printf(s, "</feature>"); - cpu->dyn_svereg_xml.desc = g_string_free(s, false); + cpu->dyn_m_secextreg_xml.desc = g_string_free(s, false); + cpu->dyn_m_secextreg_xml.num = base_reg - orig_base_reg; - return cpu->dyn_svereg_xml.num; + return cpu->dyn_m_secextreg_xml.num; } - +#endif const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) { @@ -450,6 +488,12 @@ const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) return cpu->dyn_sysreg_xml.desc; } else if (strcmp(xmlname, "sve-registers.xml") == 0) { return cpu->dyn_svereg_xml.desc; + } else if (strcmp(xmlname, "arm-m-system.xml") == 0) { + return cpu->dyn_m_systemreg_xml.desc; +#ifndef CONFIG_USER_ONLY + } else if (strcmp(xmlname, "arm-m-secext.xml") == 0) { + return cpu->dyn_m_secextreg_xml.desc; +#endif } return NULL; } @@ -466,14 +510,20 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) */ #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), + int nreg = arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs); + gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg, + aarch64_gdb_set_sve_reg, nreg, "sve-registers.xml", 0); } else { - gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg, - aarch64_fpu_gdb_set_reg, + gdb_register_coprocessor(cs, aarch64_gdb_get_fpu_reg, + aarch64_gdb_set_fpu_reg, 34, "aarch64-fpu.xml", 0); } + if (isar_feature_aa64_pauth(&cpu->isar)) { + gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg, + aarch64_gdb_set_pauth_reg, + 4, "aarch64-pauth.xml", 0); + } #endif } else { if (arm_feature(env, ARM_FEATURE_NEON)) { @@ -503,4 +553,18 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs), "system-registers.xml", 0); + if (arm_feature(env, ARM_FEATURE_M)) { + gdb_register_coprocessor(cs, + arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg, + arm_gen_dynamic_m_systemreg_xml(cs, cs->gdb_num_regs), + "arm-m-system.xml", 0); +#ifndef CONFIG_USER_ONLY + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + gdb_register_coprocessor(cs, + arm_gdb_get_m_secextreg, arm_gdb_set_m_secextreg, + arm_gen_dynamic_m_secextreg_xml(cs, cs->gdb_num_regs), + "arm-m-secext.xml", 0); + } +#endif + } } |