diff options
-rw-r--r-- | target-arm/cpu.c | 94 | ||||
-rw-r--r-- | target-arm/helper.c | 97 |
2 files changed, 92 insertions, 99 deletions
diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 8259a0df43..cc67d4d9f4 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -20,18 +20,106 @@ #include "cpu-qom.h" #include "qemu-common.h" +#if !defined(CONFIG_USER_ONLY) +#include "hw/loader.h" +#endif /* CPUClass::reset() */ static void arm_cpu_reset(CPUState *s) { ARMCPU *cpu = ARM_CPU(s); ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); + CPUARMState *env = &cpu->env; + uint32_t tmp = 0; + + if (qemu_loglevel_mask(CPU_LOG_RESET)) { + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); + log_cpu_state(env, 0); + } acc->parent_reset(s); - /* TODO Inline the current contents of cpu_state_reset(), - once cpu_reset_model_id() is eliminated. */ - cpu_state_reset(&cpu->env); + tmp = env->cp15.c15_config_base_address; + memset(env, 0, offsetof(CPUARMState, breakpoints)); + env->cp15.c15_config_base_address = tmp; + env->cp15.c0_cpuid = cpu->midr; + env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; + env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; + env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; + env->cp15.c0_cachetype = cpu->ctr; + env->cp15.c1_sys = cpu->reset_sctlr; + env->cp15.c0_c1[0] = cpu->id_pfr0; + env->cp15.c0_c1[1] = cpu->id_pfr1; + env->cp15.c0_c1[2] = cpu->id_dfr0; + env->cp15.c0_c1[3] = cpu->id_afr0; + env->cp15.c0_c1[4] = cpu->id_mmfr0; + env->cp15.c0_c1[5] = cpu->id_mmfr1; + env->cp15.c0_c1[6] = cpu->id_mmfr2; + env->cp15.c0_c1[7] = cpu->id_mmfr3; + env->cp15.c0_c2[0] = cpu->id_isar0; + env->cp15.c0_c2[1] = cpu->id_isar1; + env->cp15.c0_c2[2] = cpu->id_isar2; + env->cp15.c0_c2[3] = cpu->id_isar3; + env->cp15.c0_c2[4] = cpu->id_isar4; + env->cp15.c0_c2[5] = cpu->id_isar5; + env->cp15.c15_i_min = 0xff0; + env->cp15.c0_clid = cpu->clidr; + memcpy(env->cp15.c0_ccsid, cpu->ccsidr, ARRAY_SIZE(cpu->ccsidr)); + + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; + } + +#if defined(CONFIG_USER_ONLY) + env->uncached_cpsr = ARM_CPU_MODE_USR; + /* For user mode we must enable access to coprocessors */ + env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { + env->cp15.c15_cpar = 3; + } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { + env->cp15.c15_cpar = 1; + } +#else + /* SVC mode with interrupts disabled. */ + env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; + /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is + clear at reset. Initial SP and PC are loaded from ROM. */ + if (IS_M(env)) { + uint32_t pc; + uint8_t *rom; + env->uncached_cpsr &= ~CPSR_I; + rom = rom_ptr(0); + if (rom) { + /* We should really use ldl_phys here, in case the guest + modified flash and reset itself. However images + loaded via -kernel have not been copied yet, so load the + values directly from there. */ + env->regs[13] = ldl_p(rom); + pc = ldl_p(rom + 4); + env->thumb = pc & 1; + env->regs[15] = pc & ~1; + } + } + env->vfp.xregs[ARM_VFP_FPEXC] = 0; + env->cp15.c2_base_mask = 0xffffc000u; + /* v7 performance monitor control register: same implementor + * field as main ID register, and we implement no event counters. + */ + env->cp15.c9_pmcr = (cpu->midr & 0xff000000); +#endif + set_flush_to_zero(1, &env->vfp.standard_fp_status); + set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); + set_default_nan_mode(1, &env->vfp.standard_fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.standard_fp_status); + tlb_flush(env, 1); + /* Reset is a state change for some CPUARMState fields which we + * bake assumptions about into translated code, so we need to + * tb_flush(). + */ + tb_flush(env); } static inline void set_feature(CPUARMState *env, int feature) diff --git a/target-arm/helper.c b/target-arm/helper.c index 653885a418..101031dd75 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2,106 +2,11 @@ #include "gdbstub.h" #include "helper.h" #include "host-utils.h" -#if !defined(CONFIG_USER_ONLY) -#include "hw/loader.h" -#endif #include "sysemu.h" -/* TODO Move contents into arm_cpu_reset() in cpu.c, - * once cpu_reset_model_id() is eliminated, - * and then forward to cpu_reset() here. - */ void cpu_state_reset(CPUARMState *env) { - uint32_t tmp = 0; - ARMCPU *cpu = arm_env_get_cpu(env); - - if (qemu_loglevel_mask(CPU_LOG_RESET)) { - qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); - log_cpu_state(env, 0); - } - - tmp = env->cp15.c15_config_base_address; - memset(env, 0, offsetof(CPUARMState, breakpoints)); - env->cp15.c15_config_base_address = tmp; - env->cp15.c0_cpuid = cpu->midr; - env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; - env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; - env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; - env->cp15.c0_cachetype = cpu->ctr; - env->cp15.c1_sys = cpu->reset_sctlr; - env->cp15.c0_c1[0] = cpu->id_pfr0; - env->cp15.c0_c1[1] = cpu->id_pfr1; - env->cp15.c0_c1[2] = cpu->id_dfr0; - env->cp15.c0_c1[3] = cpu->id_afr0; - env->cp15.c0_c1[4] = cpu->id_mmfr0; - env->cp15.c0_c1[5] = cpu->id_mmfr1; - env->cp15.c0_c1[6] = cpu->id_mmfr2; - env->cp15.c0_c1[7] = cpu->id_mmfr3; - env->cp15.c0_c2[0] = cpu->id_isar0; - env->cp15.c0_c2[1] = cpu->id_isar1; - env->cp15.c0_c2[2] = cpu->id_isar2; - env->cp15.c0_c2[3] = cpu->id_isar3; - env->cp15.c0_c2[4] = cpu->id_isar4; - env->cp15.c0_c2[5] = cpu->id_isar5; - env->cp15.c15_i_min = 0xff0; - env->cp15.c0_clid = cpu->clidr; - memcpy(env->cp15.c0_ccsid, cpu->ccsidr, ARRAY_SIZE(cpu->ccsidr)); - - if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; - } - -#if defined (CONFIG_USER_ONLY) - env->uncached_cpsr = ARM_CPU_MODE_USR; - /* For user mode we must enable access to coprocessors */ - env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; - if (arm_feature(env, ARM_FEATURE_IWMMXT)) { - env->cp15.c15_cpar = 3; - } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { - env->cp15.c15_cpar = 1; - } -#else - /* SVC mode with interrupts disabled. */ - env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; - /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is - clear at reset. Initial SP and PC are loaded from ROM. */ - if (IS_M(env)) { - uint32_t pc; - uint8_t *rom; - env->uncached_cpsr &= ~CPSR_I; - rom = rom_ptr(0); - if (rom) { - /* We should really use ldl_phys here, in case the guest - modified flash and reset itself. However images - loaded via -kernel have not been copied yet, so load the - values directly from there. */ - env->regs[13] = ldl_p(rom); - pc = ldl_p(rom + 4); - env->thumb = pc & 1; - env->regs[15] = pc & ~1; - } - } - env->vfp.xregs[ARM_VFP_FPEXC] = 0; - env->cp15.c2_base_mask = 0xffffc000u; - /* v7 performance monitor control register: same implementor - * field as main ID register, and we implement no event counters. - */ - env->cp15.c9_pmcr = (cpu->midr & 0xff000000); -#endif - set_flush_to_zero(1, &env->vfp.standard_fp_status); - set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); - set_default_nan_mode(1, &env->vfp.standard_fp_status); - set_float_detect_tininess(float_tininess_before_rounding, - &env->vfp.fp_status); - set_float_detect_tininess(float_tininess_before_rounding, - &env->vfp.standard_fp_status); - tlb_flush(env, 1); - /* Reset is a state change for some CPUARMState fields which we - * bake assumptions about into translated code, so we need to - * tb_flush(). - */ - tb_flush(env); + cpu_reset(ENV_GET_CPU(env)); } static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg) |