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
This commit is contained in:
		
							parent
							
								
									533e93f1cf
								
							
						
					
					
						commit
						3f208fd76b
					
				@ -1319,7 +1319,9 @@ typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 | 
				
			|||||||
typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
 | 
					typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
 | 
				
			||||||
                       uint64_t value);
 | 
					                       uint64_t value);
 | 
				
			||||||
/* Access permission check functions for coprocessor registers. */
 | 
					/* Access permission check functions for coprocessor registers. */
 | 
				
			||||||
typedef CPAccessResult CPAccessFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 | 
					typedef CPAccessResult CPAccessFn(CPUARMState *env,
 | 
				
			||||||
 | 
					                                  const ARMCPRegInfo *opaque,
 | 
				
			||||||
 | 
					                                  bool isread);
 | 
				
			||||||
/* Hook function for register reset */
 | 
					/* Hook function for register reset */
 | 
				
			||||||
typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 | 
					typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -344,7 +344,8 @@ void init_cpreg_list(ARMCPU *cpu)
 | 
				
			|||||||
 * access_el3_aa32ns_aa64any: Used to check both AArch32/64 register views.
 | 
					 * access_el3_aa32ns_aa64any: Used to check both AArch32/64 register views.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static CPAccessResult access_el3_aa32ns(CPUARMState *env,
 | 
					static CPAccessResult access_el3_aa32ns(CPUARMState *env,
 | 
				
			||||||
                                        const ARMCPRegInfo *ri)
 | 
					                                        const ARMCPRegInfo *ri,
 | 
				
			||||||
 | 
					                                        bool isread)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    bool secure = arm_is_secure_below_el3(env);
 | 
					    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,
 | 
					static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env,
 | 
				
			||||||
                                                const ARMCPRegInfo *ri)
 | 
					                                                const ARMCPRegInfo *ri,
 | 
				
			||||||
 | 
					                                                bool isread)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!arm_el_is_aa64(env, 3)) {
 | 
					    if (!arm_el_is_aa64(env, 3)) {
 | 
				
			||||||
        return access_el3_aa32ns(env, ri);
 | 
					        return access_el3_aa32ns(env, ri, isread);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return CP_ACCESS_OK;
 | 
					    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.
 | 
					 * We assume that the .access field is set to PL1_RW.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
 | 
					static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
 | 
				
			||||||
                                            const ARMCPRegInfo *ri)
 | 
					                                            const ARMCPRegInfo *ri,
 | 
				
			||||||
 | 
					                                            bool isread)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (arm_current_el(env) == 3) {
 | 
					    if (arm_current_el(env) == 3) {
 | 
				
			||||||
        return CP_ACCESS_OK;
 | 
					        return CP_ACCESS_OK;
 | 
				
			||||||
@ -652,7 +655,8 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
				
			|||||||
    env->cp15.cpacr_el1 = value;
 | 
					    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)) {
 | 
					    if (arm_feature(env, ARM_FEATURE_V8)) {
 | 
				
			||||||
        /* Check if CPACR accesses are to be trapped to EL2 */
 | 
					        /* 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;
 | 
					    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 */
 | 
					    /* Check if CPTR accesses are set to trap to EL3 */
 | 
				
			||||||
    if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
 | 
					    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
 | 
					    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
 | 
					    /* Performance monitor registers user accessibility is controlled
 | 
				
			||||||
     * by PMUSERENR.
 | 
					     * by PMUSERENR.
 | 
				
			||||||
@ -1155,7 +1161,8 @@ static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
				
			|||||||
    env->teecr = value;
 | 
					    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)) {
 | 
					    if (arm_current_el(env) == 0 && (env->teecr & 1)) {
 | 
				
			||||||
        return CP_ACCESS_TRAP;
 | 
					        return CP_ACCESS_TRAP;
 | 
				
			||||||
@ -1208,7 +1215,8 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#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 */
 | 
					    /* 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)) {
 | 
					    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;
 | 
					    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);
 | 
					    unsigned int cur_el = arm_current_el(env);
 | 
				
			||||||
    bool secure = arm_is_secure(env);
 | 
					    bool secure = arm_is_secure(env);
 | 
				
			||||||
@ -1236,7 +1245,8 @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx)
 | 
				
			|||||||
    return CP_ACCESS_OK;
 | 
					    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);
 | 
					    unsigned int cur_el = arm_current_el(env);
 | 
				
			||||||
    bool secure = arm_is_secure(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,
 | 
					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,
 | 
					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,
 | 
					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
 | 
					    /* The AArch64 register view of the secure physical timer is
 | 
				
			||||||
     * always accessible from EL3, and configurably accessible from
 | 
					     * 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
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
/* get_phys_addr() isn't present for user-mode-only targets */
 | 
					/* 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) {
 | 
					    if (ri->opc2 & 4) {
 | 
				
			||||||
        /* The ATS12NSO* operations must trap to EL3 if executed in
 | 
					        /* 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);
 | 
					    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)) {
 | 
					    if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) {
 | 
				
			||||||
        return CP_ACCESS_TRAP;
 | 
					        return CP_ACCESS_TRAP;
 | 
				
			||||||
@ -2576,7 +2593,8 @@ static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 | 
				
			|||||||
    vfp_set_fpsr(env, value);
 | 
					    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)) {
 | 
					    if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
 | 
				
			||||||
        return CP_ACCESS_TRAP;
 | 
					        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,
 | 
					static CPAccessResult aa64_cacheop_access(CPUARMState *env,
 | 
				
			||||||
                                          const ARMCPRegInfo *ri)
 | 
					                                          const ARMCPRegInfo *ri,
 | 
				
			||||||
 | 
					                                          bool isread)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
 | 
					    /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
 | 
				
			||||||
     * SCTLR_EL1.UCI is set.
 | 
					     * 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
 | 
					    /* We don't implement EL2, so the only control on DC ZVA is the
 | 
				
			||||||
     * bit in the SCTLR which can prohibit access for EL0.
 | 
					     * 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;
 | 
					    int dzp_bit = 1 << 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* DZP indicates whether DC ZVA access is allowed */
 | 
					    /* 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;
 | 
					        dzp_bit = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return cpu->dcz_blocksize | dzp_bit;
 | 
					    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)) {
 | 
					    if (!(env->pstate & PSTATE_SP)) {
 | 
				
			||||||
        /* Access to SP_EL0 is undefined if it's being used as
 | 
					        /* 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);
 | 
					    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) {
 | 
					    if ((env->cp15.cptr_el[2] & CPTR_TFP) && arm_current_el(env) == 2) {
 | 
				
			||||||
        return CP_ACCESS_TRAP_EL2;
 | 
					        return CP_ACCESS_TRAP_EL2;
 | 
				
			||||||
@ -3658,7 +3680,8 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
 | 
				
			|||||||
    REGINFO_SENTINEL
 | 
					    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,
 | 
					    /* Only accessible in EL0 if SCTLR.UCT is set (and only in AArch64,
 | 
				
			||||||
     * but the AArch32 CTR has its own reginfo struct)
 | 
					     * but the AArch32 CTR has its own reginfo struct)
 | 
				
			||||||
 | 
				
			|||||||
@ -62,7 +62,7 @@ DEF_HELPER_1(cpsr_read, i32, env)
 | 
				
			|||||||
DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 | 
					DEF_HELPER_3(v7m_msr, void, env, i32, i32)
 | 
				
			||||||
DEF_HELPER_2(v7m_mrs, i32, env, i32)
 | 
					DEF_HELPER_2(v7m_mrs, i32, env, i32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_HELPER_3(access_check_cp_reg, void, env, ptr, i32)
 | 
					DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
 | 
				
			||||||
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
 | 
					DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
 | 
				
			||||||
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
 | 
					DEF_HELPER_2(get_cp_reg, i32, env, ptr)
 | 
				
			||||||
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
 | 
					DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
 | 
				
			||||||
 | 
				
			|||||||
@ -457,7 +457,8 @@ void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
 | 
					void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
 | 
				
			||||||
 | 
					                                 uint32_t isread)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const ARMCPRegInfo *ri = rip;
 | 
					    const ARMCPRegInfo *ri = rip;
 | 
				
			||||||
    int target_el;
 | 
					    int target_el;
 | 
				
			||||||
@ -471,7 +472,7 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (ri->accessfn(env, ri)) {
 | 
					    switch (ri->accessfn(env, ri, isread)) {
 | 
				
			||||||
    case CP_ACCESS_OK:
 | 
					    case CP_ACCESS_OK:
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    case CP_ACCESS_TRAP:
 | 
					    case CP_ACCESS_TRAP:
 | 
				
			||||||
 | 
				
			|||||||
@ -1367,16 +1367,18 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
 | 
				
			|||||||
         * runtime; this may result in an exception.
 | 
					         * runtime; this may result in an exception.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        TCGv_ptr tmpptr;
 | 
					        TCGv_ptr tmpptr;
 | 
				
			||||||
        TCGv_i32 tcg_syn;
 | 
					        TCGv_i32 tcg_syn, tcg_isread;
 | 
				
			||||||
        uint32_t syndrome;
 | 
					        uint32_t syndrome;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        gen_a64_set_pc_im(s->pc - 4);
 | 
					        gen_a64_set_pc_im(s->pc - 4);
 | 
				
			||||||
        tmpptr = tcg_const_ptr(ri);
 | 
					        tmpptr = tcg_const_ptr(ri);
 | 
				
			||||||
        syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
 | 
					        syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
 | 
				
			||||||
        tcg_syn = tcg_const_i32(syndrome);
 | 
					        tcg_syn = tcg_const_i32(syndrome);
 | 
				
			||||||
        gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
 | 
					        tcg_isread = tcg_const_i32(isread);
 | 
				
			||||||
 | 
					        gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn, tcg_isread);
 | 
				
			||||||
        tcg_temp_free_ptr(tmpptr);
 | 
					        tcg_temp_free_ptr(tmpptr);
 | 
				
			||||||
        tcg_temp_free_i32(tcg_syn);
 | 
					        tcg_temp_free_i32(tcg_syn);
 | 
				
			||||||
 | 
					        tcg_temp_free_i32(tcg_isread);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Handle special cases first */
 | 
					    /* Handle special cases first */
 | 
				
			||||||
 | 
				
			|||||||
@ -7169,7 +7169,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
 | 
				
			|||||||
             * call in order to handle c15_cpar.
 | 
					             * call in order to handle c15_cpar.
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            TCGv_ptr tmpptr;
 | 
					            TCGv_ptr tmpptr;
 | 
				
			||||||
            TCGv_i32 tcg_syn;
 | 
					            TCGv_i32 tcg_syn, tcg_isread;
 | 
				
			||||||
            uint32_t syndrome;
 | 
					            uint32_t syndrome;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Note that since we are an implementation which takes an
 | 
					            /* Note that since we are an implementation which takes an
 | 
				
			||||||
@ -7214,9 +7214,12 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
 | 
				
			|||||||
            gen_set_pc_im(s, s->pc - 4);
 | 
					            gen_set_pc_im(s, s->pc - 4);
 | 
				
			||||||
            tmpptr = tcg_const_ptr(ri);
 | 
					            tmpptr = tcg_const_ptr(ri);
 | 
				
			||||||
            tcg_syn = tcg_const_i32(syndrome);
 | 
					            tcg_syn = tcg_const_i32(syndrome);
 | 
				
			||||||
            gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
 | 
					            tcg_isread = tcg_const_i32(isread);
 | 
				
			||||||
 | 
					            gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
 | 
				
			||||||
 | 
					                                           tcg_isread);
 | 
				
			||||||
            tcg_temp_free_ptr(tmpptr);
 | 
					            tcg_temp_free_ptr(tmpptr);
 | 
				
			||||||
            tcg_temp_free_i32(tcg_syn);
 | 
					            tcg_temp_free_i32(tcg_syn);
 | 
				
			||||||
 | 
					            tcg_temp_free_i32(tcg_isread);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Handle special cases first */
 | 
					        /* Handle special cases first */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user