From 29e4bcb26b80f975920508c83a9f24f29eb6bc1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 2 Apr 2012 11:39:23 +0200 Subject: target-s390x: QOM'ify CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embed CPUS390XState as first member of S390CPU. Since -cpu is being ignored, make TYPE_S390_CPU non-abstract. Signed-off-by: Andreas Färber Tested-by: Christian Borntraeger --- Makefile.target | 1 + target-s390x/cpu-qom.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ target-s390x/cpu.c | 60 ++++++++++++++++++++++++++++++++++++++++++ target-s390x/cpu.h | 2 ++ target-s390x/helper.c | 4 ++- 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 target-s390x/cpu-qom.h create mode 100644 target-s390x/cpu.c diff --git a/Makefile.target b/Makefile.target index cff15f0..999a968 100644 --- a/Makefile.target +++ b/Makefile.target @@ -93,6 +93,7 @@ libobj-$(TARGET_SPARC64) += vis_helper.o libobj-$(CONFIG_NEED_MMU) += mmu.o libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o libobj-$(TARGET_ARM) += cpu.o +libobj-$(TARGET_S390X) += cpu.o ifeq ($(TARGET_BASE_ARCH), sparc) libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o libobj-y += cpu_init.o diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h new file mode 100644 index 0000000..6fa55a8 --- /dev/null +++ b/target-s390x/cpu-qom.h @@ -0,0 +1,71 @@ +/* + * QEMU S/390 CPU + * + * Copyright (c) 2012 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * + */ +#ifndef QEMU_S390_CPU_QOM_H +#define QEMU_S390_CPU_QOM_H + +#include "qemu/cpu.h" +#include "cpu.h" + +#define TYPE_S390_CPU "s390-cpu" + +#define S390_CPU_CLASS(klass) \ + OBJECT_CLASS_CHECK(S390CPUClass, (klass), TYPE_S390_CPU) +#define S390_CPU(obj) \ + OBJECT_CHECK(S390CPU, (obj), TYPE_S390_CPU) +#define S390_CPU_GET_CLASS(obj) \ + OBJECT_GET_CLASS(S390CPUClass, (obj), TYPE_S390_CPU) + +/** + * S390CPUClass: + * @parent_reset: The parent class' reset handler. + * + * An S/390 CPU model. + */ +typedef struct S390CPUClass { + /*< private >*/ + CPUClass parent_class; + /*< public >*/ + + void (*parent_reset)(CPUState *cpu); +} S390CPUClass; + +/** + * S390CPU: + * @env: #CPUS390XState. + * + * An S/390 CPU. + */ +typedef struct S390CPU { + /*< private >*/ + CPUState parent_obj; + /*< public >*/ + + CPUS390XState env; +} S390CPU; + +static inline S390CPU *s390_env_get_cpu(CPUS390XState *env) +{ + return S390_CPU(container_of(env, S390CPU, env)); +} + +#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e)) + + +#endif diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c new file mode 100644 index 0000000..94320f2 --- /dev/null +++ b/target-s390x/cpu.c @@ -0,0 +1,60 @@ +/* + * QEMU S/390 CPU + * + * Copyright (c) 2012 SUSE LINUX Products GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * + */ + +#include "cpu-qom.h" +#include "qemu-common.h" +#include "qemu-timer.h" + + +static void s390_cpu_reset(CPUState *s) +{ + S390CPU *cpu = S390_CPU(s); + S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); + CPUS390XState *env = &cpu->env; + + scc->parent_reset(s); + + cpu_state_reset(env); +} + +static void s390_cpu_class_init(ObjectClass *oc, void *data) +{ + S390CPUClass *scc = S390_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(scc); + + scc->parent_reset = cc->reset; + cc->reset = s390_cpu_reset; +} + +static const TypeInfo s390_cpu_type_info = { + .name = TYPE_S390_CPU, + .parent = TYPE_CPU, + .instance_size = sizeof(S390CPU), + .abstract = false, + .class_size = sizeof(S390CPUClass), + .class_init = s390_cpu_class_init, +}; + +static void s390_cpu_register_types(void) +{ + type_register_static(&s390_cpu_type_info); +} + +type_init(s390_cpu_register_types) diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index ea849fc..c6ee959 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -991,4 +991,6 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb) env->psw.addr = tb->pc; } +#include "cpu-qom.h" + #endif diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 44d5048..ae57ab3 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -70,6 +70,7 @@ static void s390x_cpu_timer(void *opaque) CPUS390XState *cpu_s390x_init(const char *cpu_model) { + S390CPU *cpu; CPUS390XState *env; #if !defined (CONFIG_USER_ONLY) struct tm tm; @@ -77,7 +78,8 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) static int inited = 0; static int cpu_num = 0; - env = g_malloc0(sizeof(CPUS390XState)); + cpu = S390_CPU(object_new(TYPE_S390_CPU)); + env = &cpu->env; cpu_exec_init(env); if (tcg_enabled() && !inited) { inited = 1; -- cgit v1.1 From 1ac1a7499bcb44174735780e0bd0421a1ac7a323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 2 Apr 2012 13:31:59 +0200 Subject: target-s390x: QOM'ify CPU reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move code from cpu_state_reset() to s390_cpu_reset(). Signed-off-by: Andreas Färber Tested-by: Christian Borntraeger --- target-s390x/cpu.c | 13 ++++++++++++- target-s390x/helper.c | 12 ++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 94320f2..cae0b18 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -1,6 +1,8 @@ /* * QEMU S/390 CPU * + * Copyright (c) 2009 Ulrich Hecht + * Copyright (c) 2011 Alexander Graf * Copyright (c) 2012 SUSE LINUX Products GmbH * * This library is free software; you can redistribute it and/or @@ -23,15 +25,24 @@ #include "qemu-timer.h" +/* CPUClass::reset() */ static void s390_cpu_reset(CPUState *s) { S390CPU *cpu = S390_CPU(s); S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); CPUS390XState *env = &cpu->env; + if (qemu_loglevel_mask(CPU_LOG_RESET)) { + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); + log_cpu_state(env, 0); + } + scc->parent_reset(s); - cpu_state_reset(env); + memset(env, 0, offsetof(CPUS390XState, breakpoints)); + /* FIXME: reset vector? */ + tlb_flush(env, 1); + s390_add_running_cpu(env); } static void s390_cpu_class_init(ObjectClass *oc, void *data) diff --git a/target-s390x/helper.c b/target-s390x/helper.c index ae57ab3..cd3e8f5 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -97,7 +97,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) env->cpu_model_str = cpu_model; env->cpu_num = cpu_num++; env->ext_index = -1; - cpu_state_reset(env); + cpu_reset(CPU(cpu)); qemu_init_vcpu(env); return env; } @@ -123,15 +123,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw void cpu_state_reset(CPUS390XState *env) { - if (qemu_loglevel_mask(CPU_LOG_RESET)) { - qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); - log_cpu_state(env, 0); - } - - memset(env, 0, offsetof(CPUS390XState, breakpoints)); - /* FIXME: reset vector? */ - tlb_flush(env, 1); - s390_add_running_cpu(env); + cpu_reset(ENV_GET_CPU(env)); } #ifndef CONFIG_USER_ONLY -- cgit v1.1 From 8f22e0df803697c11e8b10c90cc2e67df6e42884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 2 Apr 2012 13:56:29 +0200 Subject: target-s390x: QOM'ify CPU init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move code from cpu_s390x_init() into an initfn. Signed-off-by: Andreas Färber Tested-by: Christian Borntraeger --- target-s390x/cpu.c | 25 +++++++++++++++++++++++++ target-s390x/cpu.h | 3 +++ target-s390x/helper.c | 21 +++------------------ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index cae0b18..72ec349 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -45,6 +45,30 @@ static void s390_cpu_reset(CPUState *s) s390_add_running_cpu(env); } +static void s390_cpu_initfn(Object *obj) +{ + S390CPU *cpu = S390_CPU(obj); + CPUS390XState *env = &cpu->env; + static int cpu_num = 0; +#if !defined(CONFIG_USER_ONLY) + struct tm tm; +#endif + + cpu_exec_init(env); +#if !defined(CONFIG_USER_ONLY) + qemu_get_timedate(&tm, 0); + env->tod_offset = TOD_UNIX_EPOCH + + (time2tod(mktimegm(&tm)) * 1000000000ULL); + env->tod_basetime = 0; + env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env); + env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env); +#endif + env->cpu_num = cpu_num++; + env->ext_index = -1; + + cpu_reset(CPU(cpu)); +} + static void s390_cpu_class_init(ObjectClass *oc, void *data) { S390CPUClass *scc = S390_CPU_CLASS(oc); @@ -58,6 +82,7 @@ static const TypeInfo s390_cpu_type_info = { .name = TYPE_S390_CPU, .parent = TYPE_CPU, .instance_size = sizeof(S390CPU), + .instance_init = s390_cpu_initfn, .abstract = false, .class_size = sizeof(S390CPUClass), .class_init = s390_cpu_class_init, diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index c6ee959..2f3f394 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -288,6 +288,9 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw #ifndef CONFIG_USER_ONLY +void s390x_tod_timer(void *opaque); +void s390x_cpu_timer(void *opaque); + int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall); #ifdef CONFIG_KVM diff --git a/target-s390x/helper.c b/target-s390x/helper.c index cd3e8f5..6233f9a 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -51,7 +51,7 @@ #endif #ifndef CONFIG_USER_ONLY -static void s390x_tod_timer(void *opaque) +void s390x_tod_timer(void *opaque) { CPUS390XState *env = opaque; @@ -59,7 +59,7 @@ static void s390x_tod_timer(void *opaque) cpu_interrupt(env, CPU_INTERRUPT_HARD); } -static void s390x_cpu_timer(void *opaque) +void s390x_cpu_timer(void *opaque) { CPUS390XState *env = opaque; @@ -72,32 +72,17 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) { S390CPU *cpu; CPUS390XState *env; -#if !defined (CONFIG_USER_ONLY) - struct tm tm; -#endif static int inited = 0; - static int cpu_num = 0; cpu = S390_CPU(object_new(TYPE_S390_CPU)); env = &cpu->env; - cpu_exec_init(env); + if (tcg_enabled() && !inited) { inited = 1; s390x_translate_init(); } -#if !defined(CONFIG_USER_ONLY) - qemu_get_timedate(&tm, 0); - env->tod_offset = TOD_UNIX_EPOCH + - (time2tod(mktimegm(&tm)) * 1000000000ULL); - env->tod_basetime = 0; - env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env); - env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env); -#endif env->cpu_model_str = cpu_model; - env->cpu_num = cpu_num++; - env->ext_index = -1; - cpu_reset(CPU(cpu)); qemu_init_vcpu(env); return env; } -- cgit v1.1 From b8ba6799f41cccd1e81ec2986f2f80fc916ef86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 2 Apr 2012 14:00:43 +0200 Subject: target-s390x: Update s390x_{tod,cpu}_timer() to use S390CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In place of CPUS390XState pass S390CPU as opaque from the new initfn. cpu_interrupt() is anticipated to take a CPUState in the future. Signed-off-by: Andreas Färber Tested-by: Christian Borntraeger --- target-s390x/cpu.c | 4 ++-- target-s390x/helper.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index 72ec349..f183213 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -60,8 +60,8 @@ static void s390_cpu_initfn(Object *obj) env->tod_offset = TOD_UNIX_EPOCH + (time2tod(mktimegm(&tm)) * 1000000000ULL); env->tod_basetime = 0; - env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env); - env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env); + env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu); + env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu); #endif env->cpu_num = cpu_num++; env->ext_index = -1; diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 6233f9a..209a696 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -53,7 +53,8 @@ #ifndef CONFIG_USER_ONLY void s390x_tod_timer(void *opaque) { - CPUS390XState *env = opaque; + S390CPU *cpu = opaque; + CPUS390XState *env = &cpu->env; env->pending_int |= INTERRUPT_TOD; cpu_interrupt(env, CPU_INTERRUPT_HARD); @@ -61,7 +62,8 @@ void s390x_tod_timer(void *opaque) void s390x_cpu_timer(void *opaque) { - CPUS390XState *env = opaque; + S390CPU *cpu = opaque; + CPUS390XState *env = &cpu->env; env->pending_int |= INTERRUPT_CPUTIMER; cpu_interrupt(env, CPU_INTERRUPT_HARD); -- cgit v1.1