]> git.proxmox.com Git - mirror_qemu.git/blobdiff - target-s390x/helper.c
pseries: Move construction of /interrupt-controller fdt node
[mirror_qemu.git] / target-s390x / helper.c
index e541d6972436fcaa2fe5dfbd857c46cb08470ea0..68bd2f978413cc3f70d1d8d81f15a6a790a48212 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "cpu.h"
 #include "exec/gdbstub.h"
 #include "qemu/timer.h"
+#include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "hw/s390x/ioinst.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/sysemu.h"
 #endif
@@ -64,14 +68,78 @@ void s390x_cpu_timer(void *opaque)
 }
 #endif
 
-S390CPU *cpu_s390x_init(const char *cpu_model)
+S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp)
+{
+    static bool features_parsed;
+    char *name, *features;
+    const char *typename;
+    ObjectClass *oc;
+    CPUClass *cc;
+
+    name = g_strdup(cpu_model);
+    features = strchr(name, ',');
+    if (features) {
+        features[0] = 0;
+        features++;
+    }
+
+    oc = cpu_class_by_name(TYPE_S390_CPU, name);
+    if (!oc) {
+        error_setg(errp, "Unknown CPU definition \'%s\'", name);
+        g_free(name);
+        return NULL;
+    }
+    typename = object_class_get_name(oc);
+
+    if (!features_parsed) {
+        features_parsed = true;
+        cc = CPU_CLASS(oc);
+        cc->parse_features(typename, features, errp);
+    }
+    g_free(name);
+
+    if (*errp) {
+        return NULL;
+    }
+    return S390_CPU(CPU(object_new(typename)));
+}
+
+S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp)
 {
     S390CPU *cpu;
+    Error *err = NULL;
 
-    cpu = S390_CPU(object_new(TYPE_S390_CPU));
+    cpu = cpu_s390x_create(cpu_model, &err);
+    if (err != NULL) {
+        goto out;
+    }
 
-    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+    object_property_set_int(OBJECT(cpu), id, "id", &err);
+    if (err != NULL) {
+        goto out;
+    }
+    object_property_set_bool(OBJECT(cpu), true, "realized", &err);
+
+out:
+    if (err) {
+        error_propagate(errp, err);
+        object_unref(OBJECT(cpu));
+        cpu = NULL;
+    }
+    return cpu;
+}
+
+S390CPU *cpu_s390x_init(const char *cpu_model)
+{
+    Error *err = NULL;
+    S390CPU *cpu;
+    /* Use to track CPU ID for linux-user only */
+    static int64_t next_cpu_id;
 
+    cpu = s390x_new_cpu(cpu_model, next_cpu_id++, &err);
+    if (err) {
+        error_report_err(err);
+    }
     return cpu;
 }
 
@@ -162,8 +230,9 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
         vaddr &= 0x7fffffff;
     }
 
-    mmu_translate(env, vaddr, MMU_INST_FETCH, asc, &raddr, &prot, false);
-
+    if (mmu_translate(env, vaddr, MMU_INST_FETCH, asc, &raddr, &prot, false)) {
+        return -1;
+    }
     return raddr;
 }
 
@@ -646,7 +715,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs)
            will be triggered, it will call load_psw which will recompute
            the watchpoints.  */
         cpu_watchpoint_remove_all(cs, BP_CPU);
-        cpu_resume_from_signal(cs, NULL);
+        cpu_loop_exit_noexc(cs);
     }
 }
 #endif /* CONFIG_USER_ONLY */