Prepare support for multi-arch. TCG core code will have to get the architecture specific variant of these definitions.
Signed-off-by: Peter Crosthwaite <crosthwaite.pe...@gmail.com> --- target-arm/cpu.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ target-arm/cpu.h | 89 ++++++----------------------------------------- target-arm/op_helper.c | 4 +-- target-arm/translate.c | 8 +++-- 4 files changed, 110 insertions(+), 84 deletions(-) diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 566deb9..2ed6390 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -1176,6 +1176,90 @@ static void arm_any_initfn(Object *obj) #endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */ +static int arm_cpu_mmu_index(CPUState *cpu) +{ + CPUARMState *env = cpu->env_ptr; + int el = arm_current_el(env); + + if (el < 2 && arm_is_secure_below_el3(env)) { + return ARMMMUIdx_S1SE0 + el; + } + return el; +} + +static void arm_cpu_get_tb_cpu_state(CPUState *cpu, void *pc_ptr, + void *cs_base_ptr, int *flags) +{ + CPUARMState *env = cpu->env_ptr; + int fpen; + target_ulong *pc = pc_ptr; + target_ulong *cs_base = cs_base_ptr; + + if (arm_feature(env, ARM_FEATURE_V6)) { + fpen = extract32(env->cp15.cpacr_el1, 20, 2); + } else { + /* CPACR doesn't exist before v6, so VFP is always accessible */ + fpen = 3; + } + + if (is_a64(env)) { + *pc = env->pc; + *flags = ARM_TBFLAG_AARCH64_STATE_MASK; + if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) { + *flags |= ARM_TBFLAG_AA64_FPEN_MASK; + } + /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine + * states defined in the ARM ARM for software singlestep: + * SS_ACTIVE PSTATE.SS State + * 0 x Inactive (the TB flag for SS is always 0) + * 1 0 Active-pending + * 1 1 Active-not-pending + */ + if (arm_singlestep_active(env)) { + *flags |= ARM_TBFLAG_AA64_SS_ACTIVE_MASK; + if (env->pstate & PSTATE_SS) { + *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK; + } + } + } else { + *pc = env->regs[15]; + *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT) + | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT) + | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT) + | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT) + | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT); + 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; + } + if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) { + *flags |= ARM_TBFLAG_CPACR_FPEN_MASK; + } + /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine + * states defined in the ARM ARM for software singlestep: + * SS_ACTIVE PSTATE.SS State + * 0 x Inactive (the TB flag for SS is always 0) + * 1 0 Active-pending + * 1 1 Active-not-pending + */ + if (arm_singlestep_active(env)) { + *flags |= ARM_TBFLAG_SS_ACTIVE_MASK; + if (env->uncached_cpsr & PSTATE_SS) { + *flags |= ARM_TBFLAG_PSTATE_SS_MASK; + } + } + *flags |= (extract32(env->cp15.c15_cpar, 0, 2) + << ARM_TBFLAG_XSCALE_CPAR_SHIFT); + } + + *flags |= (cpu_mmu_index(env) << ARM_TBFLAG_MMUIDX_SHIFT); + + *cs_base = 0; +} + typedef struct ARMCPUInfo { const char *name; void (*initfn)(Object *obj); @@ -1264,6 +1348,15 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->debug_excp_handler = arm_debug_excp_handler; cc->disas_set_info = arm_disas_set_info; + + cc->cpu_mmu_index = arm_cpu_mmu_index; + cc->cpu_get_tb_cpu_state = arm_cpu_get_tb_cpu_state; + cc->gen_intermediate_code = arm_gen_intermediate_code; + cc->gen_intermediate_code_pc = arm_gen_intermediate_code_pc; + cc->restore_state_to_opc = arm_restore_state_to_opc; +#ifndef CONFIG_USER_ONLY + cc->tlb_fill = arm_tlb_fill; +#endif } static void cpu_register(const ARMCPUInfo *info) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 61d0964..7833ff9 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1634,17 +1634,6 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx) return mmu_idx & 3; } -/* Determine the current mmu_idx to use for normal loads/stores */ -static inline int cpu_mmu_index(CPUARMState *env) -{ - int el = arm_current_el(env); - - if (el < 2 && arm_is_secure_below_el3(env)) { - return ARMMMUIdx_S1SE0 + el; - } - return el; -} - /* Return the Exception Level targeted by debug exceptions; * currently always EL1 since we don't implement EL2 or EL3. */ @@ -1788,79 +1777,21 @@ static inline bool arm_singlestep_active(CPUARMState *env) #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) -{ - int fpen; - - if (arm_feature(env, ARM_FEATURE_V6)) { - fpen = extract32(env->cp15.cpacr_el1, 20, 2); - } else { - /* CPACR doesn't exist before v6, so VFP is always accessible */ - fpen = 3; - } - - if (is_a64(env)) { - *pc = env->pc; - *flags = ARM_TBFLAG_AARCH64_STATE_MASK; - if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) { - *flags |= ARM_TBFLAG_AA64_FPEN_MASK; - } - /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine - * states defined in the ARM ARM for software singlestep: - * SS_ACTIVE PSTATE.SS State - * 0 x Inactive (the TB flag for SS is always 0) - * 1 0 Active-pending - * 1 1 Active-not-pending - */ - if (arm_singlestep_active(env)) { - *flags |= ARM_TBFLAG_AA64_SS_ACTIVE_MASK; - if (env->pstate & PSTATE_SS) { - *flags |= ARM_TBFLAG_AA64_PSTATE_SS_MASK; - } - } - } else { - *pc = env->regs[15]; - *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT) - | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT) - | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT) - | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT) - | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT); - 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; - } - if (fpen == 3 || (fpen == 1 && arm_current_el(env) != 0)) { - *flags |= ARM_TBFLAG_CPACR_FPEN_MASK; - } - /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine - * states defined in the ARM ARM for software singlestep: - * SS_ACTIVE PSTATE.SS State - * 0 x Inactive (the TB flag for SS is always 0) - * 1 0 Active-pending - * 1 1 Active-not-pending - */ - if (arm_singlestep_active(env)) { - *flags |= ARM_TBFLAG_SS_ACTIVE_MASK; - if (env->uncached_cpsr & PSTATE_SS) { - *flags |= ARM_TBFLAG_PSTATE_SS_MASK; - } - } - *flags |= (extract32(env->cp15.c15_cpar, 0, 2) - << ARM_TBFLAG_XSCALE_CPAR_SHIFT); - } - - *flags |= (cpu_mmu_index(env) << ARM_TBFLAG_MMUIDX_SHIFT); +#define cpu_get_tb_cpu_state(env, pc, cs_base, flags) \ + ((env)->container->cpu_get_tb_cpu_state((env)->container, (pc), \ + (cs_base), (flags))) - *cs_base = 0; -} +#define cpu_mmu_index(env) ((env)->container->cpu_mmu_index((env)->container)) #include "exec/cpu-all.h" #include "exec/exec-all.h" +void arm_gen_intermediate_code(void *env, struct TranslationBlock *tb); +void arm_gen_intermediate_code_pc(void *env, struct TranslationBlock *tb); +void arm_restore_state_to_opc(void *env_ptr, TranslationBlock *tb, int pc_pos); +void arm_tlb_fill(CPUState *cs, uint64_t addr, int is_write, int mmu_idx, + uintptr_t retaddr); + enum { QEMU_PSCI_CONDUIT_DISABLED = 0, QEMU_PSCI_CONDUIT_SMC = 1, diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 1893753..11f04f5 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -61,8 +61,8 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def, * NULL, it means that the function was called in C code (i.e. not * from generated code or from helper.c) */ -void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, - uintptr_t retaddr) +void arm_tlb_fill(CPUState *cs, uint64_t addr, int is_write, int mmu_idx, + uintptr_t retaddr) { int ret; diff --git a/target-arm/translate.c b/target-arm/translate.c index cf76a85..a33343d 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -11381,12 +11381,12 @@ done_generating: } } -void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) +void arm_gen_intermediate_code(void *env, TranslationBlock *tb) { gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false); } -void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb) +void arm_gen_intermediate_code_pc(void *env, TranslationBlock *tb) { gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true); } @@ -11445,8 +11445,10 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, } } -void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos) +void arm_restore_state_to_opc(void *env_ptr, TranslationBlock *tb, int pc_pos) { + CPUARMState *env = env_ptr; + if (is_a64(env)) { env->pc = tcg_ctx.gen_opc_pc[pc_pos]; env->condexec_bits = 0; -- 1.9.1