From nobody Thu May 16 06:31:43 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=git.sr.ht Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1673991347962595.9812059859072; Tue, 17 Jan 2023 13:35:47 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pHrsR-0000DC-FM; Tue, 17 Jan 2023 14:44:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pHrsP-0000Bg-1b; Tue, 17 Jan 2023 14:44:09 -0500 Received: from mail-b.sr.ht ([173.195.146.151]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pHrsN-0001HF-Fe; Tue, 17 Jan 2023 14:44:08 -0500 Received: from git.sr.ht (unknown [173.195.146.142]) by mail-b.sr.ht (Postfix) with ESMTPSA id 60BA511EF96; Tue, 17 Jan 2023 19:44:06 +0000 (UTC) Authentication-Results: mail-b.sr.ht; dkim=none From: ~dreiss-meta Date: Mon, 09 Jan 2023 15:05:19 -0800 Subject: [PATCH qemu v2 1/3] target/arm: Unify checking for M Main Extension in MRS/MSR Message-ID: <167398464577.10345.18365355650640365165-1@git.sr.ht> X-Mailer: git.sr.ht In-Reply-To: <167398464577.10345.18365355650640365165-0@git.sr.ht> To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org, Peter Maydell Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.195.146.151; envelope-from=outgoing@sr.ht; helo=mail-b.sr.ht X-Spam_score_int: 15 X-Spam_score: 1.5 X-Spam_bar: + X-Spam_report: (1.5 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_96_XX=3.405, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: ~dreiss-meta Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1673991349682100003 From: David Reiss BASEPRI, FAULTMASK, and their _NS equivalents only exist on devices with the Main Extension. However, the MRS instruction did not check this, and the MSR instruction handled it inconsistently (warning BASEPRI, but silently ignoring writes to BASEPRI_NS). Unify this behavior and always warn when reading or writing any of these registers if the extension is not present. Signed-off-by: David Reiss --- target/arm/m_helper.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c index 033a4d9261..d87b9ecd12 100644 --- a/target/arm/m_helper.c +++ b/target/arm/m_helper.c @@ -2465,11 +2465,17 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t= reg) } return env->v7m.primask[M_REG_NS]; case 0x91: /* BASEPRI_NS */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + goto bad_reg; + } if (!env->v7m.secure) { return 0; } return env->v7m.basepri[M_REG_NS]; case 0x93: /* FAULTMASK_NS */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + goto bad_reg; + } if (!env->v7m.secure) { return 0; } @@ -2515,8 +2521,14 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t = reg) return env->v7m.primask[env->v7m.secure]; case 17: /* BASEPRI */ case 18: /* BASEPRI_MAX */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + goto bad_reg; + } return env->v7m.basepri[env->v7m.secure]; case 19: /* FAULTMASK */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + goto bad_reg; + } return env->v7m.faultmask[env->v7m.secure]; default: bad_reg: @@ -2581,13 +2593,19 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t mas= kreg, uint32_t val) env->v7m.primask[M_REG_NS] =3D val & 1; return; case 0x91: /* BASEPRI_NS */ - if (!env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_MAIN))= { + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + goto bad_reg; + } + if (!env->v7m.secure) { return; } env->v7m.basepri[M_REG_NS] =3D val & 0xff; return; case 0x93: /* FAULTMASK_NS */ - if (!env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_MAIN))= { + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + goto bad_reg; + } + if (!env->v7m.secure) { return; } env->v7m.faultmask[M_REG_NS] =3D val & 1; --=20 2.34.5 From nobody Thu May 16 06:31:43 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=git.sr.ht Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1673991342381792.6885541605287; Tue, 17 Jan 2023 13:35:42 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pHrsR-0000D6-B1; Tue, 17 Jan 2023 14:44:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pHrsP-0000C5-Kj; Tue, 17 Jan 2023 14:44:09 -0500 Received: from mail-b.sr.ht ([173.195.146.151]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pHrsN-0001HJ-Mt; Tue, 17 Jan 2023 14:44:09 -0500 Received: from git.sr.ht (unknown [173.195.146.142]) by mail-b.sr.ht (Postfix) with ESMTPSA id 961CD11EF99; Tue, 17 Jan 2023 19:44:06 +0000 (UTC) Authentication-Results: mail-b.sr.ht; dkim=none From: ~dreiss-meta Date: Mon, 09 Jan 2023 15:05:21 -0800 Subject: [PATCH qemu v2 2/3] target/arm/gdbstub: Support reading M system registers from GDB Message-ID: <167398464577.10345.18365355650640365165-2@git.sr.ht> X-Mailer: git.sr.ht In-Reply-To: <167398464577.10345.18365355650640365165-0@git.sr.ht> To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org, Peter Maydell Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.195.146.151; envelope-from=outgoing@sr.ht; helo=mail-b.sr.ht X-Spam_score_int: 15 X-Spam_score: 1.5 X-Spam_bar: + X-Spam_report: (1.5 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_96_XX=3.405, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: ~dreiss-meta Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1673991343693100003 From: David Reiss Follows a fairly similar pattern to the existing special register debug support. Only reading is implemented, but it should be possible to implement writes. `v7m_mrs_control` was renamed `arm_v7m_mrs_control` and made non-static so this logic could be shared between the MRS instruction and the GDB stub. Signed-off-by: David Reiss --- target/arm/cpu.h | 12 +++- target/arm/gdbstub.c | 125 ++++++++++++++++++++++++++++++++++++++++++ target/arm/m_helper.c | 6 +- 3 files changed, 138 insertions(+), 5 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index bf2bce046d..fdbb0d9107 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -856,6 +856,7 @@ struct ArchCPU { =20 DynamicGDBXMLInfo dyn_sysreg_xml; DynamicGDBXMLInfo dyn_svereg_xml; + DynamicGDBXMLInfo dyn_m_systemreg_xml; =20 /* Timers used by the generic (architected) timer */ QEMUTimer *gt_timer[NUM_GTIMERS]; @@ -1100,11 +1101,13 @@ int arm_cpu_gdb_read_register(CPUState *cpu, GByteA= rray *buf, int reg); int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); =20 /* - * Helpers to dynamically generates XML descriptions of the sysregs - * and SVE registers. Returns the number of registers in each set. + * Helpers to dynamically generate XML descriptions of the sysregs, + * SVE registers, and M-profile system registers. + * Returns the number of registers in each set. */ int arm_gen_dynamic_sysreg_xml(CPUState *cpu, int base_reg); int arm_gen_dynamic_svereg_xml(CPUState *cpu, int base_reg); +int arm_gen_dynamic_m_systemreg_xml(CPUState *cpu, int base_reg); =20 /* Returns the dynamically generated XML for the gdb stub. * Returns a pointer to the XML contents for the specified XML file or NULL @@ -1496,6 +1499,11 @@ FIELD(SVCR, ZA, 1, 1) FIELD(SMCR, LEN, 0, 4) FIELD(SMCR, FA64, 31, 1) =20 +/* + * Read the CONTROL register as the MRS instruction would. + */ +uint32_t arm_v7m_mrs_control(CPUARMState *env, uint32_t secure); + /* Write a new value to v7m.exception, thus transitioning into or out * of Handler mode; this may result in a change of active stack pointer. */ diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 2f806512d0..ae7fe2c800 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -322,6 +322,121 @@ int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base= _reg) return cpu->dyn_sysreg_xml.num; } =20 +/* + * Helper required because g_array_append_val is a macro + * that cannot handle string literals. + */ +static inline void g_array_append_str_literal(GArray *array, const char *s= tr) +{ + g_array_append_val(array, str); +} + +static int arm_gdb_get_m_systemreg(CPUARMState *env, GByteArray *buf, int = reg) +{ + /* NOTE: This implementation shares a lot of logic with v7m_mrs. */ + switch (reg) { + + /* + * NOTE: MSP and PSP technically don't exist if the secure extension + * is present (replaced by MSP_S, MSP_NS, PSP_S, PSP_NS). Similar for + * MSPLIM and PSPLIM. + * However, the MRS instruction is still allowed to read from MSP and = PSP, + * and will return the value associated with the current security stat= e. + * We replicate this behavior for the convenience of users, who will s= ee + * GDB behave similarly to their assembly code, even if they are obliv= ious + * to the security extension. + */ + case 0: /* MSP */ + return gdb_get_reg32(buf, + v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13]); + case 1: /* PSP */ + return gdb_get_reg32(buf, + v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp); + case 6: /* MSPLIM */ + if (!arm_feature(env, ARM_FEATURE_V8)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.msplim[env->v7m.secure]); + case 7: /* PSPLIM */ + if (!arm_feature(env, ARM_FEATURE_V8)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.psplim[env->v7m.secure]); + + /* + * NOTE: PRIMASK, BASEPRI, and FAULTMASK are defined a bit differently + * from the SP family, but have similar banking behavior. + */ + case 2: /* PRIMASK */ + return gdb_get_reg32(buf, env->v7m.primask[env->v7m.secure]); + case 3: /* BASEPRI */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.basepri[env->v7m.secure]); + case 4: /* FAULTMASK */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.faultmask[env->v7m.secure]); + + /* + * NOTE: CONTROL has a mix of banked and non-banked bits. We continue + * to emulate the MRS instruction. Unfortunately, this gives GDB no w= ay + * to read the SFPA bit when the CPU is in a non-secure state. + */ + case 5: /* CONTROL */ + return gdb_get_reg32(buf, arm_v7m_mrs_control(env, env->v7m.secure= )); + } + + return 0; +} + +static int arm_gdb_set_m_systemreg(CPUARMState *env, uint8_t *buf, int reg) +{ + /* TODO: Implement. */ + return 0; +} + +int arm_gen_dynamic_m_systemreg_xml(CPUState *cs, int base_reg) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + CPUARMState *env =3D &cpu->env; + GString *s =3D g_string_new(NULL); + DynamicGDBXMLInfo *info =3D &cpu->dyn_m_systemreg_xml; + bool is_v8 =3D arm_feature(env, ARM_FEATURE_V8); + bool is_main =3D arm_feature(env, ARM_FEATURE_M_MAIN); + + g_string_printf(s, ""); + g_string_append_printf(s, "= "); + g_string_append_printf(s, "\n"); + + g_autoptr(GArray) regs =3D g_array_new(false, true, sizeof(const char = *)); + /* 0 */ g_array_append_str_literal(regs, "msp"); + /* 1 */ g_array_append_str_literal(regs, "psp"); + /* 2 */ g_array_append_str_literal(regs, "primask"); + /* 3 */ g_array_append_str_literal(regs, is_main ? "basepri" : ""); + /* 4 */ g_array_append_str_literal(regs, is_main ? "faultmask" : ""); + /* 5 */ g_array_append_str_literal(regs, "control"); + /* 6 */ g_array_append_str_literal(regs, is_v8 ? "msplim" : ""); + /* 7 */ g_array_append_str_literal(regs, is_v8 ? "psplim" : ""); + + for (int idx =3D 0; idx < regs->len; idx++) { + const char *name =3D g_array_index(regs, const char *, idx); + if (*name !=3D '\0') { + g_string_append_printf(s, + "\n", + name, base_reg); + } + base_reg++; + } + info->num =3D regs->len; + + g_string_append_printf(s, ""); + info->desc =3D g_string_free(s, false); + return info->num; +} + struct TypeSize { const char *gdb_type; int size; @@ -450,6 +565,8 @@ 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") =3D=3D 0) { return cpu->dyn_svereg_xml.desc; + } else if (strcmp(xmlname, "arm-m-system.xml") =3D=3D 0) { + return cpu->dyn_m_systemreg_xml.desc; } return NULL; } @@ -493,6 +610,14 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cp= u) */ gdb_register_coprocessor(cs, vfp_gdb_get_sysreg, vfp_gdb_set_s= ysreg, 2, "arm-vfp-sysregs.xml", 0); + } else { + /* M-profile coprocessors. */ + 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); } } if (cpu_isar_feature(aa32_mve, cpu)) { diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c index d87b9ecd12..e8fbe1599a 100644 --- a/target/arm/m_helper.c +++ b/target/arm/m_helper.c @@ -53,7 +53,7 @@ static uint32_t v7m_mrs_xpsr(CPUARMState *env, uint32_t r= eg, unsigned el) return xpsr_read(env) & mask; } =20 -static uint32_t v7m_mrs_control(CPUARMState *env, uint32_t secure) +uint32_t arm_v7m_mrs_control(CPUARMState *env, uint32_t secure) { uint32_t value =3D env->v7m.control[secure]; =20 @@ -90,7 +90,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) case 0 ... 7: /* xPSR sub-fields */ return v7m_mrs_xpsr(env, reg, 0); case 20: /* CONTROL */ - return v7m_mrs_control(env, 0); + return arm_v7m_mrs_control(env, 0); default: /* Unprivileged reads others as zero. */ return 0; @@ -2420,7 +2420,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t r= eg) case 0 ... 7: /* xPSR sub-fields */ return v7m_mrs_xpsr(env, reg, el); case 20: /* CONTROL */ - return v7m_mrs_control(env, env->v7m.secure); + return arm_v7m_mrs_control(env, env->v7m.secure); case 0x94: /* CONTROL_NS */ /* * We have to handle this here because unprivileged Secure code --=20 2.34.5 From nobody Thu May 16 06:31:43 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=git.sr.ht Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1673991376145786.8522798226833; Tue, 17 Jan 2023 13:36:16 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pHrsS-0000Dj-GG; Tue, 17 Jan 2023 14:44:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pHrsQ-0000Ch-Qp; Tue, 17 Jan 2023 14:44:10 -0500 Received: from mail-b.sr.ht ([173.195.146.151]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pHrsN-0001HN-Rc; Tue, 17 Jan 2023 14:44:10 -0500 Received: from git.sr.ht (unknown [173.195.146.142]) by mail-b.sr.ht (Postfix) with ESMTPSA id C2A7E11EFCD; Tue, 17 Jan 2023 19:44:06 +0000 (UTC) Authentication-Results: mail-b.sr.ht; dkim=none From: ~dreiss-meta Date: Mon, 09 Jan 2023 15:05:24 -0800 Subject: [PATCH qemu v2 3/3] target/arm/gdbstub: Support reading M security extension registers from GDB Message-ID: <167398464577.10345.18365355650640365165-3@git.sr.ht> X-Mailer: git.sr.ht In-Reply-To: <167398464577.10345.18365355650640365165-0@git.sr.ht> To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org, Peter Maydell Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.195.146.151; envelope-from=outgoing@sr.ht; helo=mail-b.sr.ht X-Spam_score_int: 15 X-Spam_score: 1.5 X-Spam_bar: + X-Spam_report: (1.5 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_96_XX=3.405, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: ~dreiss-meta Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1673991377842100003 From: David Reiss Follows a fairly similar pattern to the existing special register debug support. Only reading is implemented, but it should be possible to implement writes. Signed-off-by: David Reiss --- target/arm/cpu.h | 15 +++++- target/arm/gdbstub.c | 116 ++++++++++++++++++++++++++++++++++++++++++ target/arm/m_helper.c | 23 ++++----- 3 files changed, 139 insertions(+), 15 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index fdbb0d9107..661ca832bf 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -857,6 +857,7 @@ struct ArchCPU { DynamicGDBXMLInfo dyn_sysreg_xml; DynamicGDBXMLInfo dyn_svereg_xml; DynamicGDBXMLInfo dyn_m_systemreg_xml; + DynamicGDBXMLInfo dyn_m_securereg_xml; =20 /* Timers used by the generic (architected) timer */ QEMUTimer *gt_timer[NUM_GTIMERS]; @@ -1102,12 +1103,13 @@ int arm_cpu_gdb_write_register(CPUState *cpu, uint8= _t *buf, int reg); =20 /* * Helpers to dynamically generate XML descriptions of the sysregs, - * SVE registers, and M-profile system registers. + * SVE registers, M-profile system, and M-profile secure extension registe= rs. * Returns the number of registers in each set. */ int arm_gen_dynamic_sysreg_xml(CPUState *cpu, int base_reg); int arm_gen_dynamic_svereg_xml(CPUState *cpu, int base_reg); int arm_gen_dynamic_m_systemreg_xml(CPUState *cpu, int base_reg); +int arm_gen_dynamic_m_securereg_xml(CPUState *cpu, int base_reg); =20 /* Returns the dynamically generated XML for the gdb stub. * Returns a pointer to the XML contents for the specified XML file or NULL @@ -1607,6 +1609,17 @@ static inline void xpsr_write(CPUARMState *env, uint= 32_t val, uint32_t mask) #endif } =20 +/* + * Return a pointer to the location where we currently store the + * stack pointer for the requested security state and thread mode. + * This pointer will become invalid if the CPU state is updated + * such that the stack pointers are switched around (eg changing + * the SPSEL control bit). + */ +uint32_t *arm_v7m_get_sp_ptr(CPUARMState *env, bool secure, bool threadmod= e, + bool spsel); + + #define HCR_VM (1ULL << 0) #define HCR_SWIO (1ULL << 1) #define HCR_PTW (1ULL << 2) diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index ae7fe2c800..cbccd4aa2c 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -437,6 +437,110 @@ int arm_gen_dynamic_m_systemreg_xml(CPUState *cs, int= base_reg) return info->num; } =20 +static int arm_gdb_get_m_secextreg(CPUARMState *env, GByteArray *buf, int = reg) +{ + switch (reg) { + case 0: /* MSP_S */ + return gdb_get_reg32(buf, *arm_v7m_get_sp_ptr(env, true, false, tr= ue)); + case 1: /* PSP_S */ + return gdb_get_reg32(buf, *arm_v7m_get_sp_ptr(env, true, true, tru= e)); + case 2: /* MSPLIM_S */ + return gdb_get_reg32(buf, env->v7m.msplim[M_REG_S]); + case 3: /* PSPLIM_S */ + return gdb_get_reg32(buf, env->v7m.psplim[M_REG_S]); + case 4: /* PRIMASK_S */ + return gdb_get_reg32(buf, env->v7m.primask[M_REG_S]); + case 5: /* BASEPRI_S */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.basepri[M_REG_S]); + case 6: /* FAULTMASK_S */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.faultmask[M_REG_S]); + case 7: /* CONTROL_S */ + return gdb_get_reg32(buf, env->v7m.control[M_REG_S]); + case 8: /* MSP_NS */ + return gdb_get_reg32(buf, *arm_v7m_get_sp_ptr(env, false, false, t= rue)); + case 9: /* PSP_NS */ + return gdb_get_reg32(buf, *arm_v7m_get_sp_ptr(env, false, true, tr= ue)); + case 10: /* MSPLIM_NS */ + return gdb_get_reg32(buf, env->v7m.msplim[M_REG_NS]); + case 11: /* PSPLIM_NS */ + return gdb_get_reg32(buf, env->v7m.psplim[M_REG_NS]); + case 12: /* PRIMASK_NS */ + return gdb_get_reg32(buf, env->v7m.primask[M_REG_NS]); + case 13: /* BASEPRI_NS */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.basepri[M_REG_NS]); + case 14: /* FAULTMASK_NS */ + if (!arm_feature(env, ARM_FEATURE_M_MAIN)) { + return 0; + } + return gdb_get_reg32(buf, env->v7m.faultmask[M_REG_NS]); + case 15: /* CONTROL_NS */ + return gdb_get_reg32(buf, env->v7m.control[M_REG_NS]); + } + + return 0; +} + +static int arm_gdb_set_m_secextreg(CPUARMState *env, uint8_t *buf, int reg) +{ + /* TODO: Implement. */ + return 0; +} + +int arm_gen_dynamic_m_securereg_xml(CPUState *cs, int base_reg) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + CPUARMState *env =3D &cpu->env; + GString *s =3D g_string_new(NULL); + DynamicGDBXMLInfo *info =3D &cpu->dyn_m_securereg_xml; + bool is_main =3D arm_feature(env, ARM_FEATURE_M_MAIN); + + g_string_printf(s, ""); + g_string_append_printf(s, "= "); + g_string_append_printf(s, "= \n"); + + g_autoptr(GArray) regs =3D g_array_new(false, true, sizeof(const char = *)); + /* 0 */ g_array_append_str_literal(regs, "msp_s"); + /* 1 */ g_array_append_str_literal(regs, "psp_s"); + /* 2 */ g_array_append_str_literal(regs, "msplim_s"); + /* 3 */ g_array_append_str_literal(regs, "psplim_s"); + /* 4 */ g_array_append_str_literal(regs, "primask_s"); + /* 5 */ g_array_append_str_literal(regs, is_main ? "basepri_s" : ""); + /* 6 */ g_array_append_str_literal(regs, is_main ? "faultmask_s" : ""= ); + /* 7 */ g_array_append_str_literal(regs, "control_s"); + /* 8 */ g_array_append_str_literal(regs, "msp_ns"); + /* 9 */ g_array_append_str_literal(regs, "psp_ns"); + /* 10 */ g_array_append_str_literal(regs, "msplim_ns"); + /* 11 */ g_array_append_str_literal(regs, "psplim_ns"); + /* 12 */ g_array_append_str_literal(regs, "primask_ns"); + /* 13 */ g_array_append_str_literal(regs, is_main ? "basepri_ns" : ""); + /* 14 */ g_array_append_str_literal(regs, is_main ? "faultmask_ns" : "= "); + /* 15 */ g_array_append_str_literal(regs, "control_ns"); + + for (int idx =3D 0; idx < regs->len; idx++) { + const char *name =3D g_array_index(regs, const char *, idx); + if (*name !=3D '\0') { + g_string_append_printf(s, + "\n", + name, base_reg); + } + base_reg++; + } + info->num =3D regs->len; + + g_string_append_printf(s, ""); + info->desc =3D g_string_free(s, false); + return info->num; +} + struct TypeSize { const char *gdb_type; int size; @@ -567,6 +671,8 @@ const char *arm_gdb_get_dynamic_xml(CPUState *cs, const= char *xmlname) return cpu->dyn_svereg_xml.desc; } else if (strcmp(xmlname, "arm-m-system.xml") =3D=3D 0) { return cpu->dyn_m_systemreg_xml.desc; + } else if (strcmp(xmlname, "arm-m-secext.xml") =3D=3D 0) { + return cpu->dyn_m_securereg_xml.desc; } return NULL; } @@ -618,6 +724,16 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cp= u) arm_gen_dynamic_m_systemreg_xml( cs, cs->gdb_num_regs), "arm-m-system.xml", 0); + if (arm_feature(env, ARM_FEATURE_V8) && + 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_securereg_xml( + cs, cs->gdb_num_regs), + "arm-m-secext.xml", 0); + + } } } if (cpu_isar_feature(aa32_mve, cpu)) { diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c index e8fbe1599a..a9b27ad060 100644 --- a/target/arm/m_helper.c +++ b/target/arm/m_helper.c @@ -605,15 +605,10 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t des= t) arm_rebuild_hflags(env); } =20 -static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool thread= mode, - bool spsel) +uint32_t *arm_v7m_get_sp_ptr(CPUARMState *env, bool secure, bool threadmod= e, + bool spsel) { /* - * Return a pointer to the location where we currently store the - * stack pointer for the requested security state and thread mode. - * This pointer will become invalid if the CPU state is updated - * such that the stack pointers are switched around (eg changing - * the SPSEL control bit). * Compare the v8M ARM ARM pseudocode LookUpSP_with_security_mode(). * Unlike that pseudocode, we require the caller to pass us in the * SPSEL control bit value; this is because we also use this @@ -765,8 +760,8 @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t= lr, bool dotailchain, !mode; =20 mmu_idx =3D arm_v7m_mmu_idx_for_secstate_and_priv(env, M_REG_S, pr= iv); - frame_sp_p =3D get_v7m_sp_ptr(env, M_REG_S, mode, - lr & R_V7M_EXCRET_SPSEL_MASK); + frame_sp_p =3D arm_v7m_get_sp_ptr(env, M_REG_S, mode, + lr & R_V7M_EXCRET_SPSEL_MASK); want_psp =3D mode && (lr & R_V7M_EXCRET_SPSEL_MASK); if (want_psp) { limit =3D env->v7m.psplim[M_REG_S]; @@ -1611,10 +1606,10 @@ static void do_v7m_exception_exit(ARMCPU *cpu) * use 'frame_sp_p' after we do something that makes it invalid. */ bool spsel =3D env->v7m.control[return_to_secure] & R_V7M_CONTROL_= SPSEL_MASK; - uint32_t *frame_sp_p =3D get_v7m_sp_ptr(env, - return_to_secure, - !return_to_handler, - spsel); + uint32_t *frame_sp_p =3D arm_v7m_get_sp_ptr(env, + return_to_secure, + !return_to_handler, + spsel); uint32_t frameptr =3D *frame_sp_p; bool pop_ok =3D true; ARMMMUIdx mmu_idx; @@ -1920,7 +1915,7 @@ static bool do_v7m_function_return(ARMCPU *cpu) threadmode =3D !arm_v7m_is_handler_mode(env); spsel =3D env->v7m.control[M_REG_S] & R_V7M_CONTROL_SPSEL_MASK; =20 - frame_sp_p =3D get_v7m_sp_ptr(env, true, threadmode, spsel); + frame_sp_p =3D arm_v7m_get_sp_ptr(env, true, threadmode, spsel); frameptr =3D *frame_sp_p; =20 /* --=20 2.34.5