[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 14/21] target/arm: Implement gdbstub m-profile systemreg and secex
From: |
Peter Maydell |
Subject: |
[PULL 14/21] target/arm: Implement gdbstub m-profile systemreg and secext |
Date: |
Mon, 6 Mar 2023 15:34:28 +0000 |
From: Richard Henderson <richard.henderson@linaro.org>
The upstream gdb xml only implements {MSP,PSP}{,_NS,S}, but
go ahead and implement the other system registers as well.
Since there is significant overlap between the two, implement
them with common code. The only exception is the systemreg
view of CONTROL, which merges the banked bits as per MRS.
Signed-off-by: David Reiss <dreiss@meta.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230227213329.793795-15-richard.henderson@linaro.org
[rth: Substatial rewrite using enumerator and shared code.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.h | 2 +
target/arm/gdbstub.c | 178 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 180 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 379e74d1f99..c4bd22808ce 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -869,6 +869,8 @@ struct ArchCPU {
DynamicGDBXMLInfo dyn_sysreg_xml;
DynamicGDBXMLInfo dyn_svereg_xml;
+ DynamicGDBXMLInfo dyn_m_systemreg_xml;
+ DynamicGDBXMLInfo dyn_m_secextreg_xml;
/* Timers used by the generic (architected) timer */
QEMUTimer *gt_timer[NUM_GTIMERS];
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 062c8d447a0..3f799f5d058 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -322,6 +322,164 @@ static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int
base_reg)
return cpu->dyn_sysreg_xml.num;
}
+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 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 */
+}
+
+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);
+ 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.m-system\">\n");
+
+ 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_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");
+
+ for (i = 0; i < ARRAY_SIZE(m_sysreg_def); i++) {
+ g_string_append_printf(s,
+ "<reg name=\"%s_ns\" bitsize=\"32\" regnum=\"%d\"/>\n",
+ m_sysreg_def[i].name, base_reg++);
+ g_string_append_printf(s,
+ "<reg name=\"%s_s\" bitsize=\"32\" regnum=\"%d\"/>\n",
+ m_sysreg_def[i].name, base_reg++);
+ }
+
+ g_string_append_printf(s, "</feature>");
+ 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_m_secextreg_xml.num;
+}
+#endif
+
const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
{
ARMCPU *cpu = ARM_CPU(cs);
@@ -330,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;
}
@@ -389,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
+ }
}
--
2.34.1
- [PULL 03/21] target/arm: Move arm_gen_dynamic_svereg_xml to gdbstub64.c, (continued)
- [PULL 03/21] target/arm: Move arm_gen_dynamic_svereg_xml to gdbstub64.c, Peter Maydell, 2023/03/06
- [PULL 07/21] target/arm: Fix svep width in arm_gen_dynamic_svereg_xml, Peter Maydell, 2023/03/06
- [PULL 08/21] target/arm: Add name argument to output_vector_union_type, Peter Maydell, 2023/03/06
- [PULL 10/21] target/arm: Create pauth_ptr_mask, Peter Maydell, 2023/03/06
- [PULL 06/21] target/arm: Hoist pred_width in arm_gen_dynamic_svereg_xml, Peter Maydell, 2023/03/06
- [PULL 12/21] target/arm: Export arm_v7m_mrs_control, Peter Maydell, 2023/03/06
- [PULL 15/21] target/arm: Handle m-profile in arm_is_secure, Peter Maydell, 2023/03/06
- [PULL 13/21] target/arm: Export arm_v7m_get_sp_ptr, Peter Maydell, 2023/03/06
- [PULL 17/21] target/arm: Diagnose incorrect usage of arm_is_secure subroutines, Peter Maydell, 2023/03/06
- [PULL 11/21] target/arm: Implement gdbstub pauth extension, Peter Maydell, 2023/03/06
- [PULL 14/21] target/arm: Implement gdbstub m-profile systemreg and secext,
Peter Maydell <=
- [PULL 16/21] target/arm: Stub arm_hcr_el2_eff for m-profile, Peter Maydell, 2023/03/06
- [PULL 21/21] hw: arm: allwinner-h3: Fix and complete H3 i2c devices, Peter Maydell, 2023/03/06
- [PULL 18/21] target/arm: Rewrite check_s2_mmu_setup, Peter Maydell, 2023/03/06
- [PULL 19/21] hw: arm: Support direct boot for Linux/arm64 EFI zboot images, Peter Maydell, 2023/03/06
- [PULL 20/21] hw: allwinner-i2c: Fix TWI_CNTR_INT_FLAG on SUN6i SoCs, Peter Maydell, 2023/03/06
- Re: [PULL 00/21] target-arm queue, Peter Maydell, 2023/03/07