]> git.proxmox.com Git - qemu.git/blobdiff - target-m68k/helper.c
vnc: Make ledstate comparison before modifiers updated
[qemu.git] / target-m68k / helper.c
index 1feed9be6708c733d6483589a85f1ca0e0cac918..54fa419ace8e113612d3a36e5ad885ba879bfc4d 100644 (file)
  */
 
 #include "cpu.h"
-#include "gdbstub.h"
+#include "exec/gdbstub.h"
 
 #include "helpers.h"
 
 #define SIGNBIT (1u << 31)
 
-enum m68k_cpuid {
-    M68K_CPUID_M5206,
-    M68K_CPUID_M5208,
-    M68K_CPUID_CFV4E,
-    M68K_CPUID_ANY,
-};
+/* Sort alphabetically, except for "any". */
+static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b)
+{
+    ObjectClass *class_a = (ObjectClass *)a;
+    ObjectClass *class_b = (ObjectClass *)b;
+    const char *name_a, *name_b;
 
-typedef struct m68k_def_t m68k_def_t;
+    name_a = object_class_get_name(class_a);
+    name_b = object_class_get_name(class_b);
+    if (strcmp(name_a, "any-" TYPE_M68K_CPU) == 0) {
+        return 1;
+    } else if (strcmp(name_b, "any-" TYPE_M68K_CPU) == 0) {
+        return -1;
+    } else {
+        return strcasecmp(name_a, name_b);
+    }
+}
 
-struct m68k_def_t {
-    const char * name;
-    enum m68k_cpuid id;
-};
+static void m68k_cpu_list_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *c = data;
+    CPUListState *s = user_data;
+    const char *typename;
+    char *name;
 
-static m68k_def_t m68k_cpu_defs[] = {
-    {"m5206", M68K_CPUID_M5206},
-    {"m5208", M68K_CPUID_M5208},
-    {"cfv4e", M68K_CPUID_CFV4E},
-    {"any", M68K_CPUID_ANY},
-    {NULL, 0},
-};
+    typename = object_class_get_name(c);
+    name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_M68K_CPU));
+    (*s->cpu_fprintf)(s->file, "%s\n",
+                      name);
+    g_free(name);
+}
 
 void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
-    unsigned int i;
+    CPUListState s = {
+        .file = f,
+        .cpu_fprintf = cpu_fprintf,
+    };
+    GSList *list;
 
-    for (i = 0; m68k_cpu_defs[i].name; i++) {
-        (*cpu_fprintf)(f, "%s\n", m68k_cpu_defs[i].name);
-    }
+    list = object_class_get_list(TYPE_M68K_CPU, false);
+    list = g_slist_sort(list, m68k_cpu_list_compare);
+    g_slist_foreach(list, m68k_cpu_list_entry, &s);
+    g_slist_free(list);
 }
 
 static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
@@ -83,112 +98,36 @@ static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
     return 0;
 }
 
-static void m68k_set_feature(CPUM68KState *env, int feature)
-{
-    env->features |= (1u << feature);
-}
-
-static int cpu_m68k_set_model(CPUM68KState *env, const char *name)
+M68kCPU *cpu_m68k_init(const char *cpu_model)
 {
-    m68k_def_t *def;
-
-    for (def = m68k_cpu_defs; def->name; def++) {
-        if (strcmp(def->name, name) == 0)
-            break;
-    }
-    if (!def->name)
-        return -1;
+    M68kCPU *cpu;
+    CPUM68KState *env;
+    ObjectClass *oc;
 
-    switch (def->id) {
-    case M68K_CPUID_M5206:
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
-        break;
-    case M68K_CPUID_M5208:
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
-        m68k_set_feature(env, M68K_FEATURE_BRAL);
-        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
-        m68k_set_feature(env, M68K_FEATURE_USP);
-        break;
-    case M68K_CPUID_CFV4E:
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
-        m68k_set_feature(env, M68K_FEATURE_BRAL);
-        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
-        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
-        m68k_set_feature(env, M68K_FEATURE_USP);
-        break;
-    case M68K_CPUID_ANY:
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
-        m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
-        m68k_set_feature(env, M68K_FEATURE_BRAL);
-        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
-        /* MAC and EMAC are mututally exclusive, so pick EMAC.
-           It's mostly backwards compatible.  */
-        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
-        m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
-        m68k_set_feature(env, M68K_FEATURE_USP);
-        m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
-        m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
-        break;
+    oc = cpu_class_by_name(TYPE_M68K_CPU, cpu_model);
+    if (oc == NULL) {
+        return NULL;
     }
+    cpu = M68K_CPU(object_new(object_class_get_name(oc)));
+    env = &cpu->env;
+    env->cpu_model_str = cpu_model;
 
     register_m68k_insns(env);
-    if (m68k_feature (env, M68K_FEATURE_CF_FPU)) {
-        gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
-                                 11, "cf-fp.xml", 18);
-    }
-    /* TODO: Add [E]MAC registers.  */
-    return 0;
-}
 
-void cpu_state_reset(CPUM68KState *env)
-{
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
+    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
 
-    memset(env, 0, offsetof(CPUM68KState, breakpoints));
-#if !defined (CONFIG_USER_ONLY)
-    env->sr = 0x2700;
-#endif
-    m68k_switch_sp(env);
-    /* ??? FP regs should be initialized to NaN.  */
-    env->cc_op = CC_OP_FLAGS;
-    /* TODO: We should set PC from the interrupt vector.  */
-    env->pc = 0;
-    tlb_flush(env, 1);
+    return cpu;
 }
 
-CPUM68KState *cpu_m68k_init(const char *cpu_model)
+void m68k_cpu_init_gdb(M68kCPU *cpu)
 {
-    CPUM68KState *env;
-    static int inited;
-
-    env = g_malloc0(sizeof(CPUM68KState));
-    cpu_exec_init(env);
-    if (!inited) {
-        inited = 1;
-        m68k_tcg_init();
-    }
-
-    env->cpu_model_str = cpu_model;
+    CPUM68KState *env = &cpu->env;
 
-    if (cpu_m68k_set_model(env, cpu_model) < 0) {
-        cpu_m68k_close(env);
-        return NULL;
+    if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
+        gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
+                                 11, "cf-fp.xml", 18);
     }
-
-    cpu_state_reset(env);
-    qemu_init_vcpu(env);
-    return env;
-}
-
-void cpu_m68k_close(CPUM68KState *env)
-{
-    g_free(env);
+    /* TODO: Add [E]MAC registers.  */
 }
 
 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
@@ -351,7 +290,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
 /* MMU */
 
 /* TODO: This will need fixing once the MMU is implemented.  */
-target_phys_addr_t cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr)
 {
     return addr;
 }
@@ -371,14 +310,18 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
    be handled by the interrupt controller.  Real hardware only requests
    the vector when the interrupt is acknowledged by the CPU.  For
    simplicitly we calculate it when the interrupt is signalled.  */
-void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector)
+void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
 {
+    CPUState *cs = CPU(cpu);
+    CPUM68KState *env = &cpu->env;
+
     env->pending_level = level;
     env->pending_vector = vector;
-    if (level)
-        cpu_interrupt(env, CPU_INTERRUPT_HARD);
-    else
-        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+    if (level) {
+        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+    } else {
+        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+    }
 }
 
 #endif