summaryrefslogtreecommitdiff
path: root/target-arm/cpu.h
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-20 10:35:52 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-20 10:35:52 +0000
commitf59df3f2354982ee0381b87d1ce561f1eb0ed505 (patch)
treedb6f983aec846a0a8a6856b7453c12f2c4997fcb /target-arm/cpu.h
parente508a92b621c7160122e99d3754e568f2b8e255e (diff)
downloadqemu-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/cpu.h')
-rw-r--r--target-arm/cpu.h29
1 files changed, 25 insertions, 4 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ab57f554a0..cc3d0ac9f2 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -811,14 +811,29 @@ static inline int arm_current_pl(CPUARMState *env)
typedef struct ARMCPRegInfo ARMCPRegInfo;
-/* Access functions for coprocessor registers. These should return
- * 0 on success, or one of the EXCP_* constants if access should cause
- * an exception (in which case *value is not written).
- */
+typedef enum CPAccessResult {
+ /* Access is permitted */
+ CP_ACCESS_OK = 0,
+ /* Access fails due to a configurable trap or enable which would
+ * result in a categorized exception syndrome giving information about
+ * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
+ * 0xc or 0x18).
+ */
+ CP_ACCESS_TRAP = 1,
+ /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
+ * Note that this is not a catch-all case -- the set of cases which may
+ * result in this failure is specifically defined by the architecture.
+ */
+ CP_ACCESS_TRAP_UNCATEGORIZED = 2,
+} CPAccessResult;
+
+/* Access functions for coprocessor registers. These should always succeed. */
typedef int CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque,
uint64_t *value);
typedef int CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
uint64_t value);
+/* Access permission check functions for coprocessor registers. */
+typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
/* Hook function for register reset */
typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
@@ -872,6 +887,12 @@ struct ARMCPRegInfo {
* 2. both readfn and writefn are specified
*/
ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
+ /* Function for making any access checks for this register in addition to
+ * those specified by the 'access' permissions bits. If NULL, no extra
+ * checks required. The access check is performed at runtime, not at
+ * translate time.
+ */
+ CPAccessFn *accessfn;
/* Function for handling reads of this register. If NULL, then reads
* will be done by loading from the offset into CPUARMState specified
* by fieldoffset.