Message ID | 1264521604-2020-5-git-send-email-riku.voipio@iki.fi |
---|---|
State | New |
Headers | show |
On Tue, Jan 26, 2010 at 5:00 PM, Riku Voipio <riku.voipio@iki.fi> wrote: > From: Riku Voipio <riku.voipio@nokia.com> > > If you compile applications with gcc -mtp=cp15, __thread > access's will generate an abort. Implement accessing allowed > cp15.c13 registers on ARMv6K+ in linux-user. > > Signed-off-by: Riku Voipio <riku.voipio@nokia.com> > --- > target-arm/helper.c | 27 ++++++++++++++++++++++++++- > 1 files changed, 26 insertions(+), 1 deletions(-) > > diff --git a/target-arm/helper.c b/target-arm/helper.c > index b3aec99..68578ce 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -505,13 +505,38 @@ uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn) > > void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) > { > + int op2; > + > + op2 = (insn >> 5) & 7; > + /* Allow write access to CP15 User RW Thread ID Register */ > + if (arm_feature (env, ARM_FEATURE_V6K) && ((insn >> 16) & 0xf) == 13) { > + switch (op2) { > + case 2: > + env->cp15.c13_tls1 = val; > + return; > + } > + } > cpu_abort(env, "cp15 insn %08x\n", insn); > } > > uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) > { > + int op2; > + /* Allow read access to CP15 User RW and RO Thread ID Registers */ > + > + op2 = (insn >> 5) & 7; > + if (arm_feature (env, ARM_FEATURE_V6K) && ((insn >> 16) & 0xf) == 13) { > + switch (op2) { > + case 2: > + return env->cp15.c13_tls1; > + case 3: > + return env->cp15.c13_tls2; > + default: > + goto bad_reg; > + } > + } > +bad_reg: > cpu_abort(env, "cp15 insn %08x\n", insn); > - return 0; > } > > /* These should probably raise undefined insn exceptions. */ Most of the checks you do here could be done in translate.c. Wouldn't it be better to do them there? Laurent
On Tue, Jan 26, 2010 at 05:27:27PM +0100, Laurent Desnogues wrote: > On Tue, Jan 26, 2010 at 5:00 PM, Riku Voipio <riku.voipio@iki.fi> wrote: > > From: Riku Voipio <riku.voipio@nokia.com> > > > > If you compile applications with gcc -mtp=cp15, __thread > > access's will generate an abort. Implement accessing allowed > > cp15.c13 registers on ARMv6K+ in linux-user. > > > > Signed-off-by: Riku Voipio <riku.voipio@nokia.com> > > --- > > target-arm/helper.c | 27 ++++++++++++++++++++++++++- > > 1 files changed, 26 insertions(+), 1 deletions(-) > > > > diff --git a/target-arm/helper.c b/target-arm/helper.c > > index b3aec99..68578ce 100644 > > --- a/target-arm/helper.c > > +++ b/target-arm/helper.c > > @@ -505,13 +505,38 @@ uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn) > > > > void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) > > { > > + int op2; > > + > > + op2 = (insn >> 5) & 7; > > + /* Allow write access to CP15 User RW Thread ID Register */ > > + if (arm_feature (env, ARM_FEATURE_V6K) && ((insn >> 16) & 0xf) == 13) { > > + switch (op2) { > > + case 2: > > + env->cp15.c13_tls1 = val; > > + return; > > + } > > + } > > cpu_abort(env, "cp15 insn %08x\n", insn); > > } > > > > uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) > > { > > + int op2; > > + /* Allow read access to CP15 User RW and RO Thread ID Registers */ > > + > > + op2 = (insn >> 5) & 7; > > + if (arm_feature (env, ARM_FEATURE_V6K) && ((insn >> 16) & 0xf) == 13) { > > + switch (op2) { > > + case 2: > > + return env->cp15.c13_tls1; > > + case 3: > > + return env->cp15.c13_tls2; > > + default: > > + goto bad_reg; > > + } > > + } > > +bad_reg: > > cpu_abort(env, "cp15 insn %08x\n", insn); > > - return 0; > > } > > > > /* These should probably raise undefined insn exceptions. */ > Most of the checks you do here could be done in translate.c. > Wouldn't it be better to do them there? Indeed, thus we could even avoid the helper completly. I just followed the the cp15 implementation of system-qemu here.
diff --git a/target-arm/helper.c b/target-arm/helper.c index b3aec99..68578ce 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -505,13 +505,38 @@ uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn) void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) { + int op2; + + op2 = (insn >> 5) & 7; + /* Allow write access to CP15 User RW Thread ID Register */ + if (arm_feature (env, ARM_FEATURE_V6K) && ((insn >> 16) & 0xf) == 13) { + switch (op2) { + case 2: + env->cp15.c13_tls1 = val; + return; + } + } cpu_abort(env, "cp15 insn %08x\n", insn); } uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) { + int op2; + /* Allow read access to CP15 User RW and RO Thread ID Registers */ + + op2 = (insn >> 5) & 7; + if (arm_feature (env, ARM_FEATURE_V6K) && ((insn >> 16) & 0xf) == 13) { + switch (op2) { + case 2: + return env->cp15.c13_tls1; + case 3: + return env->cp15.c13_tls2; + default: + goto bad_reg; + } + } +bad_reg: cpu_abort(env, "cp15 insn %08x\n", insn); - return 0; } /* These should probably raise undefined insn exceptions. */