Let's move the resets into one function and switch by type, so we can use fallthroughs for shared reset actions.
Signed-off-by: Janosch Frank <fran...@linux.ibm.com> --- target/s390x/cpu.c | 110 ++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 62 deletions(-) diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 3abe7e80fd..556afecbc1 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -82,67 +82,52 @@ static void s390_cpu_load_normal(CPUState *s) } #endif -/* S390CPUClass::cpu_reset() */ -static void s390_cpu_reset(CPUState *s) +typedef enum cpu_reset_type { + S390_CPU_RESET_NORMAL, + S390_CPU_RESET_INITIAL, + S390_CPU_RESET_CLEAR, +} cpu_reset_type; + +static void s390_cpu_reset(CPUState *s, cpu_reset_type type) { S390CPU *cpu = S390_CPU(s); S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); CPUS390XState *env = &cpu->env; - env->pfault_token = -1UL; - env->bpbc = false; scc->parent_reset(s); cpu->env.sigp_order = 0; s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); -} -/* S390CPUClass::initial_reset() */ -static void s390_cpu_initial_reset(CPUState *s) -{ - S390CPU *cpu = S390_CPU(s); - CPUS390XState *env = &cpu->env; + /* Set initial values after clearing */ + switch (type) { + case S390_CPU_RESET_CLEAR: + memset(env, 0, offsetof(CPUS390XState, start_initial_reset_fields)); + /* Fallthrough */ + case S390_CPU_RESET_INITIAL: + memset(&env->start_initial_reset_fields, 0, + offsetof(CPUS390XState, end_reset_fields) - + offsetof(CPUS390XState, start_initial_reset_fields)); + /* architectured initial values for CR 0 and 14 */ + env->cregs[0] = CR0_RESET; + env->cregs[14] = CR14_RESET; - s390_cpu_reset(s); - /* initial reset does not clear everything! */ - memset(&env->start_initial_reset_fields, 0, - offsetof(CPUS390XState, end_reset_fields) - - offsetof(CPUS390XState, start_initial_reset_fields)); - - /* architectured initial values for CR 0 and 14 */ - env->cregs[0] = CR0_RESET; - env->cregs[14] = CR14_RESET; - - /* architectured initial value for Breaking-Event-Address register */ - env->gbea = 1; - - env->pfault_token = -1UL; - - /* tininess for underflow is detected before rounding */ - set_float_detect_tininess(float_tininess_before_rounding, - &env->fpu_status); + /* architectured initial value for Breaking-Event-Address register */ + env->gbea = 1; + /* tininess for underflow is detected before rounding */ + set_float_detect_tininess(float_tininess_before_rounding, + &env->fpu_status); + /* Fallthrough */ + case S390_CPU_RESET_NORMAL: + env->pfault_token = -1UL; + env->bpbc = false; + break; + } /* Reset state inside the kernel that we cannot access yet from QEMU. */ - if (kvm_enabled()) { - kvm_s390_reset_vcpu(cpu); + if (kvm_enabled() && (type == S390_CPU_RESET_CLEAR || + type == S390_CPU_RESET_INITIAL)) { + kvm_s390_reset_vcpu(cpu); } -} - -/* CPUClass:reset() */ -static void s390_cpu_full_reset(CPUState *s) -{ - S390CPU *cpu = S390_CPU(s); - S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); - CPUS390XState *env = &cpu->env; - - scc->parent_reset(s); - cpu->env.sigp_order = 0; - s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); - - memset(env, 0, offsetof(CPUS390XState, end_reset_fields)); - - /* architectured initial values for CR 0 and 14 */ - env->cregs[0] = CR0_RESET; - env->cregs[14] = CR14_RESET; #if defined(CONFIG_USER_ONLY) /* user mode should always be allowed to use the full FPU */ @@ -151,20 +136,21 @@ static void s390_cpu_full_reset(CPUState *s) env->cregs[0] |= CR0_VECTOR; } #endif +} - /* architectured initial value for Breaking-Event-Address register */ - env->gbea = 1; +static void s390_cpu_reset_normal(CPUState *s) +{ + return s390_cpu_reset(s, S390_CPU_RESET_NORMAL); +} - env->pfault_token = -1UL; +static void s390_cpu_reset_initial(CPUState *s) +{ + return s390_cpu_reset(s, S390_CPU_RESET_INITIAL); +} - /* tininess for underflow is detected before rounding */ - set_float_detect_tininess(float_tininess_before_rounding, - &env->fpu_status); - - /* Reset state inside the kernel that we cannot access yet from QEMU. */ - if (kvm_enabled()) { - kvm_s390_reset_vcpu(cpu); - } +static void s390_cpu_reset_clear(CPUState *s) +{ + return s390_cpu_reset(s, S390_CPU_RESET_CLEAR); } #if !defined(CONFIG_USER_ONLY) @@ -473,9 +459,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) #if !defined(CONFIG_USER_ONLY) scc->load_normal = s390_cpu_load_normal; #endif - scc->cpu_reset = s390_cpu_reset; - scc->initial_cpu_reset = s390_cpu_initial_reset; - cc->reset = s390_cpu_full_reset; + scc->cpu_reset = s390_cpu_reset_normal; + scc->initial_cpu_reset = s390_cpu_reset_initial; + cc->reset = s390_cpu_reset_clear; cc->class_by_name = s390_cpu_class_by_name, cc->has_work = s390_cpu_has_work; #ifdef CONFIG_TCG -- 2.20.1