On Tue, May 13, 2014 at 4:15 PM, Fabian Aggeler <aggel...@ethz.ch> wrote: > From: Sergey Fedorov <s.fedo...@samsung.com> > > CPACR register allows to control access rights to coprocessor 0-13 > interfaces. Bits corresponding to unimplemented coprocessors should be > RAZ/WI. QEMU implements only VFP coprocessor on ARMv6+ targets. So only > cp10 & cp11 bits are writable. >
Is this patch sec-ext specific? It looks to have no deps on EL3/MON so is it candidate for more immediate merge? > Signed-off-by: Sergey Fedorov <s.fedo...@samsung.com> > Signed-off-by: Fabian Aggeler <aggel...@ethz.ch> > --- > target-arm/helper.c | 6 ++++++ > target-arm/translate.c | 26 +++++++++++++++++++++++--- > 2 files changed, 29 insertions(+), 3 deletions(-) > > diff --git a/target-arm/helper.c b/target-arm/helper.c > index cf1f88c..4e82259 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -477,6 +477,12 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = { > static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, > uint64_t value) > { > + uint32_t mask = 0; > + > + if (arm_feature(env, ARM_FEATURE_VFP)) { > + mask |= 0x00f00000; /* VFP coprocessor: cp10 & cp11 */ > + } > + value &= mask; > if (env->cp15.c1_coproc != value) { > env->cp15.c1_coproc = value; > /* ??? Is this safe when called from within a TB? */ > diff --git a/target-arm/translate.c b/target-arm/translate.c > index 87d0918..c815fb3 100644 > --- a/target-arm/translate.c > +++ b/target-arm/translate.c > @@ -6866,9 +6866,29 @@ static int disas_coproc_insn(CPUARMState * env, > DisasContext *s, uint32_t insn) > const ARMCPRegInfo *ri; > > cpnum = (insn >> 8) & 0xf; > - if (arm_feature(env, ARM_FEATURE_XSCALE) > - && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum))) > - return 1; > + if (cpnum < 14) { > + if (arm_feature(env, ARM_FEATURE_XSCALE)) { > + if (~env->cp15.c15_cpar & (1 << cpnum)) { > + return 1; > + } > + } else { > + /* Bits [20:21] of CPACR control access to cp10 > + * Bits [23:22] of CPACR control access to cp11 */ Newline before */ > + switch ((env->cp15.c1_coproc >> (cpnum * 2)) & 3) { > + case 0: /* access denied */ > + return 1; > + case 1: /* privileged mode access only */ > + if (IS_USER(s)) { > + return 1; > + } > + break; > + case 2: /* reserved */ > + return 1; This looks like a guest error and probably should get a qemu_log(LOG_GUEST_ERROR, Regards, Peter > + case 3: /* privileged and user mode access */ > + break; > + } > + } > + } > > /* First check for coprocessor space used for actual instructions */ > switch (cpnum) { > -- > 1.8.3.2 > >