]> Git Repo - qemu.git/blobdiff - target/hppa/cpu.c
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-3.0-pull-request...
[qemu.git] / target / hppa / cpu.c
index 9e7b0d4ccbd9b26d1acd8d125e17b26405be5c03..00bf4446206dbdebafcb577e42bdc06fe1d946b9 100644 (file)
@@ -23,6 +23,7 @@
 #include "cpu.h"
 #include "qemu-common.h"
 #include "exec/exec-all.h"
+#include "fpu/softfloat.h"
 
 
 static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
@@ -37,9 +38,29 @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
 {
     HPPACPU *cpu = HPPA_CPU(cs);
 
+#ifdef CONFIG_USER_ONLY
     cpu->env.iaoq_f = tb->pc;
     cpu->env.iaoq_b = tb->cs_base;
-    cpu->env.psw_n = tb->flags & 1;
+#else
+    /* Recover the IAOQ values from the GVA + PRIV.  */
+    uint32_t priv = (tb->flags >> TB_FLAG_PRIV_SHIFT) & 3;
+    target_ulong cs_base = tb->cs_base;
+    target_ulong iasq_f = cs_base & ~0xffffffffull;
+    int32_t diff = cs_base;
+
+    cpu->env.iasq_f = iasq_f;
+    cpu->env.iaoq_f = (tb->pc & ~iasq_f) + priv;
+    if (diff) {
+        cpu->env.iaoq_b = cpu->env.iaoq_f + diff;
+    }
+#endif
+
+    cpu->env.psw_n = (tb->flags & PSW_N) != 0;
+}
+
+static bool hppa_cpu_has_work(CPUState *cs)
+{
+    return cs->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
 static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
@@ -48,6 +69,23 @@ static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
     info->print_insn = print_insn_hppa;
 }
 
+static void hppa_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+                                         MMUAccessType access_type,
+                                         int mmu_idx, uintptr_t retaddr)
+{
+    HPPACPU *cpu = HPPA_CPU(cs);
+    CPUHPPAState *env = &cpu->env;
+
+    cs->exception_index = EXCP_UNALIGN;
+    if (env->psw & PSW_Q) {
+        /* ??? Needs tweaking for hppa64.  */
+        env->cr[CR_IOR] = addr;
+        env->cr[CR_ISR] = addr >> 32;
+    }
+
+    cpu_loop_exit_restore(cs, retaddr);
+}
+
 static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
@@ -62,18 +100,14 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
 
     qemu_init_vcpu(cs);
     acc->parent_realize(dev, errp);
-}
-
-/* Sort hppabetically by type name. */
-static gint hppa_cpu_list_compare(gconstpointer a, gconstpointer b)
-{
-    ObjectClass *class_a = (ObjectClass *)a;
-    ObjectClass *class_b = (ObjectClass *)b;
-    const char *name_a, *name_b;
 
-    name_a = object_class_get_name(class_a);
-    name_b = object_class_get_name(class_b);
-    return strcmp(name_a, name_b);
+#ifndef CONFIG_USER_ONLY
+    {
+        HPPACPU *cpu = HPPA_CPU(cs);
+        cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                        hppa_cpu_alarm_timer, cpu);
+    }
+#endif
 }
 
 static void hppa_cpu_list_entry(gpointer data, gpointer user_data)
@@ -92,8 +126,7 @@ void hppa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
     };
     GSList *list;
 
-    list = object_class_get_list(TYPE_HPPA_CPU, false);
-    list = g_slist_sort(list, hppa_cpu_list_compare);
+    list = object_class_get_list_sorted(TYPE_HPPA_CPU, false);
     (*cpu_fprintf)(f, "Available CPUs:\n");
     g_slist_foreach(list, hppa_cpu_list_entry, &s);
     g_slist_free(list);
@@ -106,8 +139,9 @@ static void hppa_cpu_initfn(Object *obj)
     CPUHPPAState *env = &cpu->env;
 
     cs->env_ptr = env;
+    cs->exception_index = -1;
     cpu_hppa_loaded_fr0(env);
-    set_snan_bit_is_one(true, &env->fp_status);
+    cpu_hppa_put_psw(env, PSW_W);
 }
 
 static ObjectClass *hppa_cpu_class_by_name(const char *cpu_model)
@@ -121,10 +155,11 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
     CPUClass *cc = CPU_CLASS(oc);
     HPPACPUClass *acc = HPPA_CPU_CLASS(oc);
 
-    acc->parent_realize = dc->realize;
-    dc->realize = hppa_cpu_realizefn;
+    device_class_set_parent_realize(dc, hppa_cpu_realizefn,
+                                    &acc->parent_realize);
 
     cc->class_by_name = hppa_cpu_class_by_name;
+    cc->has_work = hppa_cpu_has_work;
     cc->do_interrupt = hppa_cpu_do_interrupt;
     cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
     cc->dump_state = hppa_cpu_dump_state;
@@ -132,7 +167,13 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
     cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
     cc->gdb_read_register = hppa_cpu_gdb_read_register;
     cc->gdb_write_register = hppa_cpu_gdb_write_register;
+#ifdef CONFIG_USER_ONLY
     cc->handle_mmu_fault = hppa_cpu_handle_mmu_fault;
+#else
+    cc->get_phys_page_debug = hppa_cpu_get_phys_page_debug;
+    dc->vmsd = &vmstate_hppa_cpu;
+#endif
+    cc->do_unaligned_access = hppa_cpu_do_unaligned_access;
     cc->disas_set_info = hppa_cpu_disas_set_info;
     cc->tcg_initialize = hppa_translate_init;
 
This page took 0.0245 seconds and 4 git commands to generate.