target-arm: add non-secure Translation Block flag
This patch is based on idea found in patch at git://github.com/jowinter/qemu-trustzone.git f3d955c6c0ed8c46bc0eb10b634201032a651dd2 by Johannes Winter <johannes.winter@iaik.tugraz.at>. The TBFLAG captures the SCR NS secure state at the time when a TB is created so the correct bank is accessed on system register accesses. Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com> Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch> Signed-off-by: Greg Bellows <greg.bellows@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1416242878-876-5-git-send-email-greg.bellows@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									ea30a4b824
								
							
						
					
					
						commit
						3f342b9e0e
					
				| 
						 | 
				
			
			@ -817,6 +817,22 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
 | 
			
		|||
    return arm_feature(env, ARM_FEATURE_AARCH64);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Function for determing whether guest cp register reads and writes should
 | 
			
		||||
 * access the secure or non-secure bank of a cp register.  When EL3 is
 | 
			
		||||
 * operating in AArch32 state, the NS-bit determines whether the secure
 | 
			
		||||
 * instance of a cp register should be used. When EL3 is AArch64 (or if
 | 
			
		||||
 * it doesn't exist at all) then there is no register banking, and all
 | 
			
		||||
 * accesses are to the non-secure version.
 | 
			
		||||
 */
 | 
			
		||||
static inline bool access_secure_reg(CPUARMState *env)
 | 
			
		||||
{
 | 
			
		||||
    bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
 | 
			
		||||
                !arm_el_is_aa64(env, 3) &&
 | 
			
		||||
                !(env->cp15.scr_el3 & SCR_NS));
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Macros for accessing a specified CP register bank */
 | 
			
		||||
#define A32_BANKED_REG_GET(_env, _regname, _secure)    \
 | 
			
		||||
    ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
 | 
			
		||||
| 
						 | 
				
			
			@ -1467,6 +1483,12 @@ static inline bool arm_singlestep_active(CPUARMState *env)
 | 
			
		|||
 */
 | 
			
		||||
#define ARM_TBFLAG_XSCALE_CPAR_SHIFT 20
 | 
			
		||||
#define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
 | 
			
		||||
/* Indicates whether cp register reads and writes by guest code should access
 | 
			
		||||
 * the secure or nonsecure bank of banked registers; note that this is not
 | 
			
		||||
 * the same thing as the current security state of the processor!
 | 
			
		||||
 */
 | 
			
		||||
#define ARM_TBFLAG_NS_SHIFT         22
 | 
			
		||||
#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
 | 
			
		||||
 | 
			
		||||
/* Bit usage when in AArch64 state */
 | 
			
		||||
#define ARM_TBFLAG_AA64_EL_SHIFT    0
 | 
			
		||||
| 
						 | 
				
			
			@ -1511,6 +1533,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
 | 
			
		|||
    (((F) & ARM_TBFLAG_AA64_SS_ACTIVE_MASK) >> ARM_TBFLAG_AA64_SS_ACTIVE_SHIFT)
 | 
			
		||||
#define ARM_TBFLAG_AA64_PSTATE_SS(F) \
 | 
			
		||||
    (((F) & ARM_TBFLAG_AA64_PSTATE_SS_MASK) >> ARM_TBFLAG_AA64_PSTATE_SS_SHIFT)
 | 
			
		||||
#define ARM_TBFLAG_NS(F) \
 | 
			
		||||
    (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
 | 
			
		||||
 | 
			
		||||
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 | 
			
		||||
                                        target_ulong *cs_base, int *flags)
 | 
			
		||||
| 
						 | 
				
			
			@ -1560,6 +1584,9 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 | 
			
		|||
        if (privmode) {
 | 
			
		||||
            *flags |= ARM_TBFLAG_PRIV_MASK;
 | 
			
		||||
        }
 | 
			
		||||
        if (!(access_secure_reg(env))) {
 | 
			
		||||
            *flags |= ARM_TBFLAG_NS_MASK;
 | 
			
		||||
        }
 | 
			
		||||
        if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
 | 
			
		||||
            || arm_el_is_aa64(env, 1)) {
 | 
			
		||||
            *flags |= ARM_TBFLAG_VFPEN_MASK;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11031,6 +11031,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 | 
			
		|||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
 | 
			
		||||
#endif
 | 
			
		||||
    dc->ns = ARM_TBFLAG_NS(tb->flags);
 | 
			
		||||
    dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
 | 
			
		||||
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
 | 
			
		||||
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ typedef struct DisasContext {
 | 
			
		|||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    int user;
 | 
			
		||||
#endif
 | 
			
		||||
    bool ns;        /* Use non-secure CPREG bank on access */
 | 
			
		||||
    bool cpacr_fpen; /* FP enabled via CPACR.FPEN */
 | 
			
		||||
    bool vfp_enabled; /* FP enabled via FPSCR.EN */
 | 
			
		||||
    int vec_len;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue