* [PATCH 0/2] target/arm: Implement remaining HSTR functionality
@ 2021-08-16 18:03 Peter Maydell
2021-08-16 18:03 ` [PATCH 1/2] target/arm: Implement HSTR.TTEE Peter Maydell
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Peter Maydell @ 2021-08-16 18:03 UTC (permalink / raw)
To: qemu-arm, qemu-devel
I was going through some old todo items from years back, and one of
them was "implement HSTR traps". We actually already do the
interesting part of this (traps of coprocessor register access), but
there are a couple of small loose ends: v7A (but not v8A!) defines
HSTR.TTEE and HSTR.TJDBX trap bits for trapping various bits of the
trivial Thumb2EE and Jazelle implementation.
The documentation for this is in the v7A Arm ARM DDI0406C.d, section
B1.14.10 and B1.14.11, but the summary is that these bits trap from
NS EL0/EL1 to Hyp mode for:
* TEECR and TEEHBR accesses
* JOSCR or JMCR sysreg accesses
* execution of the BXJ insn
This patchset implements the last of the HSTR functionality,
just so I can cross it off my todo list. I don't expect anybody
to actually be using this :-)
thanks
-- PMM
Peter Maydell (2):
target/arm: Implement HSTR.TTEE
target/arm: Implement HSTR.TJDBX
target/arm/cpu.h | 3 +++
target/arm/helper.h | 2 ++
target/arm/syndrome.h | 7 +++++++
target/arm/helper.c | 35 +++++++++++++++++++++++++++++++++--
target/arm/op_helper.c | 16 ++++++++++++++++
target/arm/translate.c | 12 ++++++++++++
6 files changed, 73 insertions(+), 2 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] target/arm: Implement HSTR.TTEE
2021-08-16 18:03 [PATCH 0/2] target/arm: Implement remaining HSTR functionality Peter Maydell
@ 2021-08-16 18:03 ` Peter Maydell
2021-08-16 18:03 ` [PATCH 2/2] target/arm: Implement HSTR.TJDBX Peter Maydell
2021-08-17 22:17 ` [PATCH 0/2] target/arm: Implement remaining HSTR functionality Richard Henderson
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2021-08-16 18:03 UTC (permalink / raw)
To: qemu-arm, qemu-devel
In v7, the HSTR register has a TTEE bit which allows EL0/EL1 accesses
to the Thumb2EE TEECR and TEEHBR registers to be trapped to the
hypervisor. Implement these traps.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.h | 2 ++
target/arm/helper.c | 18 ++++++++++++++++--
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9f0a5f84d50..cf3c90f768a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1536,6 +1536,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
#define SCR_ENSCXT (1U << 25)
#define SCR_ATA (1U << 26)
+#define HSTR_TTEE (1 << 16)
+
/* Return the current FPSCR value. */
uint32_t vfp_get_fpscr(CPUARMState *env);
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 155d8bf2399..262e787f690 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2446,20 +2446,34 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->teecr = value;
}
+static CPAccessResult teecr_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+ /*
+ * HSTR.TTEE only exists in v7A, not v8A, but v8A doesn't have T2EE
+ * at all, so we don't need to check whether we're v8A.
+ */
+ if (arm_current_el(env) < 2 && !arm_is_secure_below_el3(env) &&
+ (env->cp15.hstr_el2 & HSTR_TTEE)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
if (arm_current_el(env) == 0 && (env->teecr & 1)) {
return CP_ACCESS_TRAP;
}
- return CP_ACCESS_OK;
+ return teecr_access(env, ri, isread);
}
static const ARMCPRegInfo t2ee_cp_reginfo[] = {
{ .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr),
.resetvalue = 0,
- .writefn = teecr_write },
+ .writefn = teecr_write, .accessfn = teecr_access },
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
.accessfn = teehbr_access, .resetvalue = 0 },
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] target/arm: Implement HSTR.TJDBX
2021-08-16 18:03 [PATCH 0/2] target/arm: Implement remaining HSTR functionality Peter Maydell
2021-08-16 18:03 ` [PATCH 1/2] target/arm: Implement HSTR.TTEE Peter Maydell
@ 2021-08-16 18:03 ` Peter Maydell
2021-08-17 22:17 ` [PATCH 0/2] target/arm: Implement remaining HSTR functionality Richard Henderson
2 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2021-08-16 18:03 UTC (permalink / raw)
To: qemu-arm, qemu-devel
In v7A, the HSTR register has a TJDBX bit which traps NS EL0/EL1
access to the JOSCR and JMCR trivial Jazelle registers, and also BXJ.
Implement these traps. In v8A this HSTR bit doesn't exist, so don't
trap for v8A CPUs.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.h | 1 +
target/arm/helper.h | 2 ++
target/arm/syndrome.h | 7 +++++++
target/arm/helper.c | 17 +++++++++++++++++
target/arm/op_helper.c | 16 ++++++++++++++++
target/arm/translate.c | 12 ++++++++++++
6 files changed, 55 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index cf3c90f768a..fe47a652e3f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1537,6 +1537,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
#define SCR_ATA (1U << 26)
#define HSTR_TTEE (1 << 16)
+#define HSTR_TJDBX (1 << 17)
/* Return the current FPSCR value. */
uint32_t vfp_get_fpscr(CPUARMState *env);
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 248569b0cd8..b2050d41755 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -73,6 +73,8 @@ DEF_HELPER_2(v7m_vlldm, void, env, i32)
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
+DEF_HELPER_FLAGS_2(check_bxj_trap, TCG_CALL_NO_WG, void, env, i32)
+
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 39a31260f2d..8dd88a0cb17 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -36,6 +36,7 @@ enum arm_exception_class {
EC_ADVSIMDFPACCESSTRAP = 0x07,
EC_FPIDTRAP = 0x08,
EC_PACTRAP = 0x09,
+ EC_BXJTRAP = 0x0a,
EC_CP14RRTTRAP = 0x0c,
EC_BTITRAP = 0x0d,
EC_ILLEGALSTATE = 0x0e,
@@ -215,6 +216,12 @@ static inline uint32_t syn_btitrap(int btype)
return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
}
+static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
+{
+ return (EC_BXJTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL |
+ (cv << 24) | (cond << 20) | rm;
+}
+
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
{
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 262e787f690..97a971bebdb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7602,6 +7602,21 @@ static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
return CP_ACCESS_OK;
}
+static CPAccessResult access_joscr_jmcr(CPUARMState *env,
+ const ARMCPRegInfo *ri, bool isread)
+{
+ /*
+ * HSTR.TJDBX traps JOSCR and JMCR accesses, but it exists only
+ * in v7A, not in v8A.
+ */
+ if (!arm_feature(env, ARM_FEATURE_V8) &&
+ arm_current_el(env) < 2 && !arm_is_secure_below_el3(env) &&
+ (env->cp15.hstr_el2 & HSTR_TJDBX)) {
+ return CP_ACCESS_TRAP_EL2;
+ }
+ return CP_ACCESS_OK;
+}
+
static const ARMCPRegInfo jazelle_regs[] = {
{ .name = "JIDR",
.cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
@@ -7609,9 +7624,11 @@ static const ARMCPRegInfo jazelle_regs[] = {
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "JOSCR",
.cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
+ .accessfn = access_joscr_jmcr,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "JMCR",
.cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
+ .accessfn = access_joscr_jmcr,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index e98fd863057..70b42b55fd0 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -224,6 +224,22 @@ void HELPER(setend)(CPUARMState *env)
arm_rebuild_hflags(env);
}
+void HELPER(check_bxj_trap)(CPUARMState *env, uint32_t rm)
+{
+ /*
+ * Only called if in NS EL0 or EL1 for a BXJ for a v7A CPU;
+ * check if HSTR.TJDBX means we need to trap to EL2.
+ */
+ if (env->cp15.hstr_el2 & HSTR_TJDBX) {
+ /*
+ * We know the condition code check passed, so take the IMPDEF
+ * choice to always report CV=1 COND 0xe
+ */
+ uint32_t syn = syn_bxjtrap(1, 0xe, rm);
+ raise_exception_ra(env, EXCP_HYP_TRAP, syn, 2, GETPC());
+ }
+}
+
#ifndef CONFIG_USER_ONLY
/* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
* The function returns the target EL (1-3) if the instruction is to be trapped;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 80c282669f0..80eb1b7eae9 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6440,6 +6440,18 @@ static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
return false;
}
+ /*
+ * v7A allows BXJ to be trapped via HSTR.TJDBX. We don't waste a
+ * TBFLAGS bit on a basically-never-happens case, so call a helper
+ * function to check for the trap and raise the exception if needed
+ * (passing it the register number for the syndrome value).
+ * v8A doesn't have this HSTR bit.
+ */
+ if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
+ arm_dc_feature(s, ARM_FEATURE_EL2) &&
+ s->current_el < 2 && s->ns) {
+ gen_helper_check_bxj_trap(cpu_env, tcg_constant_i32(a->rm));
+ }
/* Trivial implementation equivalent to bx. */
gen_bx(s, load_reg(s, a->rm));
return true;
--
2.20.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] target/arm: Implement remaining HSTR functionality
2021-08-16 18:03 [PATCH 0/2] target/arm: Implement remaining HSTR functionality Peter Maydell
2021-08-16 18:03 ` [PATCH 1/2] target/arm: Implement HSTR.TTEE Peter Maydell
2021-08-16 18:03 ` [PATCH 2/2] target/arm: Implement HSTR.TJDBX Peter Maydell
@ 2021-08-17 22:17 ` Richard Henderson
2 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2021-08-17 22:17 UTC (permalink / raw)
To: Peter Maydell, qemu-arm, qemu-devel
On 8/16/21 8:03 AM, Peter Maydell wrote:
> Peter Maydell (2):
> target/arm: Implement HSTR.TTEE
> target/arm: Implement HSTR.TJDBX
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-08-17 22:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-08-16 18:03 [PATCH 0/2] target/arm: Implement remaining HSTR functionality Peter Maydell
2021-08-16 18:03 ` [PATCH 1/2] target/arm: Implement HSTR.TTEE Peter Maydell
2021-08-16 18:03 ` [PATCH 2/2] target/arm: Implement HSTR.TJDBX Peter Maydell
2021-08-17 22:17 ` [PATCH 0/2] target/arm: Implement remaining HSTR functionality Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).