aboutsummaryrefslogtreecommitdiff
path: root/target-arm/helper.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-02-11 11:17:31 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-02-11 11:17:31 +0000
commit3f208fd76bcc91a8506681bb8472f2398fe6f487 (patch)
treebc3d1894f35937be8e3c75a77e79d687fa7d8c21 /target-arm/helper.c
parent533e93f1cf12c570aab45f14663dab6fb8ea3ffc (diff)
downloadqemu-3f208fd76bcc91a8506681bb8472f2398fe6f487.zip
qemu-3f208fd76bcc91a8506681bb8472f2398fe6f487.tar.gz
qemu-3f208fd76bcc91a8506681bb8472f2398fe6f487.tar.bz2
target-arm: Add isread parameter to CPAccessFns
System registers might have access requirements which need to be described via a CPAccessFn and which differ for reads and writes. For this to be possible we need to pass the access function a parameter to tell it whether the access being checked is a read or a write. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Sergey Fedorov <serge.fdrv@gmail.com> Message-id: 1454506721-11843-6-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c81
1 files changed, 52 insertions, 29 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 98eccd6..1db8de3 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -344,7 +344,8 @@ void init_cpreg_list(ARMCPU *cpu)
* access_el3_aa32ns_aa64any: Used to check both AArch32/64 register views.
*/
static CPAccessResult access_el3_aa32ns(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
bool secure = arm_is_secure_below_el3(env);
@@ -356,10 +357,11 @@ static CPAccessResult access_el3_aa32ns(CPUARMState *env,
}
static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
if (!arm_el_is_aa64(env, 3)) {
- return access_el3_aa32ns(env, ri);
+ return access_el3_aa32ns(env, ri, isread);
}
return CP_ACCESS_OK;
}
@@ -370,7 +372,8 @@ static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env,
* We assume that the .access field is set to PL1_RW.
*/
static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
if (arm_current_el(env) == 3) {
return CP_ACCESS_OK;
@@ -652,7 +655,8 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->cp15.cpacr_el1 = value;
}
-static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (arm_feature(env, ARM_FEATURE_V8)) {
/* Check if CPACR accesses are to be trapped to EL2 */
@@ -669,7 +673,8 @@ static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri)
return CP_ACCESS_OK;
}
-static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
/* Check if CPTR accesses are set to trap to EL3 */
if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
@@ -711,7 +716,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
/* Performance monitor registers user accessibility is controlled
* by PMUSERENR.
@@ -1155,7 +1161,8 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
env->teecr = value;
}
-static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (arm_current_el(env) == 0 && (env->teecr & 1)) {
return CP_ACCESS_TRAP;
@@ -1208,7 +1215,8 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
#ifndef CONFIG_USER_ONLY
-static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
/* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
if (arm_current_el(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
@@ -1217,7 +1225,8 @@ static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri)
return CP_ACCESS_OK;
}
-static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
+static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
+ bool isread)
{
unsigned int cur_el = arm_current_el(env);
bool secure = arm_is_secure(env);
@@ -1236,7 +1245,8 @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
return CP_ACCESS_OK;
}
-static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
+static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
+ bool isread)
{
unsigned int cur_el = arm_current_el(env);
bool secure = arm_is_secure(env);
@@ -1258,29 +1268,34 @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx)
}
static CPAccessResult gt_pct_access(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
- return gt_counter_access(env, GTIMER_PHYS);
+ return gt_counter_access(env, GTIMER_PHYS, isread);
}
static CPAccessResult gt_vct_access(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
- return gt_counter_access(env, GTIMER_VIRT);
+ return gt_counter_access(env, GTIMER_VIRT, isread);
}
-static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
- return gt_timer_access(env, GTIMER_PHYS);
+ return gt_timer_access(env, GTIMER_PHYS, isread);
}
-static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
- return gt_timer_access(env, GTIMER_VIRT);
+ return gt_timer_access(env, GTIMER_VIRT, isread);
}
static CPAccessResult gt_stimer_access(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
/* The AArch64 register view of the secure physical timer is
* always accessible from EL3, and configurably accessible from
@@ -1777,7 +1792,8 @@ static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
#ifndef CONFIG_USER_ONLY
/* get_phys_addr() isn't present for user-mode-only targets */
-static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (ri->opc2 & 4) {
/* The ATS12NSO* operations must trap to EL3 if executed in
@@ -1922,7 +1938,8 @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
A32_BANKED_CURRENT_REG_SET(env, par, par64);
}
-static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) {
return CP_ACCESS_TRAP;
@@ -2576,7 +2593,8 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
vfp_set_fpsr(env, value);
}
-static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
return CP_ACCESS_TRAP;
@@ -2591,7 +2609,8 @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
static CPAccessResult aa64_cacheop_access(CPUARMState *env,
- const ARMCPRegInfo *ri)
+ const ARMCPRegInfo *ri,
+ bool isread)
{
/* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
* SCTLR_EL1.UCI is set.
@@ -2847,7 +2866,8 @@ static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
-static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
/* We don't implement EL2, so the only control on DC ZVA is the
* bit in the SCTLR which can prohibit access for EL0.
@@ -2864,13 +2884,14 @@ static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri)
int dzp_bit = 1 << 4;
/* DZP indicates whether DC ZVA access is allowed */
- if (aa64_zva_access(env, NULL) == CP_ACCESS_OK) {
+ if (aa64_zva_access(env, NULL, false) == CP_ACCESS_OK) {
dzp_bit = 0;
}
return cpu->dcz_blocksize | dzp_bit;
}
-static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if (!(env->pstate & PSTATE_SP)) {
/* Access to SP_EL0 is undefined if it's being used as
@@ -2909,7 +2930,8 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
tlb_flush(CPU(cpu), 1);
}
-static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
if ((env->cp15.cptr_el[2] & CPTR_TFP) && arm_current_el(env) == 2) {
return CP_ACCESS_TRAP_EL2;
@@ -3658,7 +3680,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri)
+static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
{
/* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
* but the AArch32 CTR has its own reginfo struct)