diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-02-20 10:35:52 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-02-20 10:35:52 +0000 |
commit | f59df3f2354982ee0381b87d1ce561f1eb0ed505 (patch) | |
tree | db6f983aec846a0a8a6856b7453c12f2c4997fcb /target-arm/translate.c | |
parent | e508a92b621c7160122e99d3754e568f2b8e255e (diff) | |
download | qemu-f59df3f2354982ee0381b87d1ce561f1eb0ed505.tar.gz qemu-f59df3f2354982ee0381b87d1ce561f1eb0ed505.tar.bz2 qemu-f59df3f2354982ee0381b87d1ce561f1eb0ed505.zip |
target-arm: Split cpreg access checks out from read/write functions
Several of the system registers handled via the ARMCPRegInfo
mechanism have access trap control bits controlling whether the
registers are accessible to lower privilege levels. Replace
the existing mechanism (allowing the read and write functions
to return EXCP_UDEF if access is denied) with a dedicated
"check access rights" function pointer in the ARMCPRegInfo.
This will allow us to simplify some of the register definitions,
which no longer need read/write functions purely to handle
the access checks.
We take the opportunity to define the return value from the
access checking function in a way that allows us to set the
correct exception syndrome information for exceptions taken
to AArch64 (which may need to distinguish access failures due
to a configurable trap or enable from other kinds of access
failure).
This commit defines the new mechanism but does not move any
of the registers across to use it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Diffstat (limited to 'target-arm/translate.c')
-rw-r--r-- | target-arm/translate.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c index 6d822c60b5..0805053aaf 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -6837,6 +6837,17 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn) return 1; } + if (ri->accessfn) { + /* Emit code to perform further access permissions checks at + * runtime; this may result in an exception. + */ + TCGv_ptr tmpptr; + gen_set_pc_im(s, s->pc); + tmpptr = tcg_const_ptr(ri); + gen_helper_access_check_cp_reg(cpu_env, tmpptr); + tcg_temp_free_ptr(tmpptr); + } + /* Handle special cases first */ switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) { case ARM_CP_NOP: |