qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] target/ppc: add disable-tcg option
@ 2021-04-09 15:19 Bruno Larsen (billionai)
  2021-04-09 15:19 ` [PATCH 1/4] target/ppc: Code motion required to build disabling tcg Bruno Larsen (billionai)
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Bruno Larsen (billionai) @ 2021-04-09 15:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: lucas.araujo, lagarcia, luis.pires, fernando.valle, qemu-ppc,
	andre.silva, Bruno Larsen (billionai),
	matheus.ferst

This patch series aims to add the option to build without TCG for the
powerpc target. This RFC shows mostly the strategies employed when
dealing with compilation problems, and ask for input on the bits
we don't quite understand yet.

The first patch mostly code motion, as referenced in 2021-04/msg0717.
The second patch shows the 2 strategies we've considered, and hope to
get feedback on. The third patch contains the stubs we haven't decided
on how to deal with yet, but needed to exist to compile the project.
The final patch just changes the meson.build rules

Bruno Larsen (billionai) (4):
  target/ppc: Code motion required to build disabling tcg
  target/ppc: added solutions for problems encountered when building
    with disable-tcg
  target/ppc: Add stubs for tcg functions, so it build with disable-tcg
  target/ppc: updated build rules for disable-tcg option

 target/ppc/arch_dump.c          |   17 +
 target/ppc/cpu.c                |  859 +++++++++++++++++++++++
 target/ppc/cpu.h                |   15 +
 target/ppc/gdbstub.c            |  253 +++++++
 target/ppc/kvm.c                |   30 +
 target/ppc/kvm_ppc.h            |   11 +
 target/ppc/machine.c            |   33 +-
 target/ppc/meson.build          |   22 +-
 target/ppc/tcg-stub.c           |  139 ++++
 target/ppc/translate_init.c.inc | 1148 +------------------------------
 10 files changed, 1407 insertions(+), 1120 deletions(-)
 create mode 100644 target/ppc/tcg-stub.c

-- 
2.17.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/4] target/ppc: Code motion required to build disabling tcg
  2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
@ 2021-04-09 15:19 ` Bruno Larsen (billionai)
  2021-04-09 19:48   ` Fabiano Rosas
  2021-04-09 15:19 ` [PATCH 2/4] target/ppc: added solutions for building with disable-tcg Bruno Larsen (billionai)
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Bruno Larsen (billionai) @ 2021-04-09 15:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: lucas.araujo, lagarcia, luis.pires, fernando.valle, qemu-ppc,
	andre.silva, Bruno Larsen (billionai),
	matheus.ferst

This commit does the necessary code motion from translate_init.c.inc
This moves all functions that start with gdb_* into target/ppc/gdbstub.c
and creates a new function that calls those and is called by ppc_cpu_realize
All functions related to realizing the cpu have been moved to cpu.c, which
may call functions from gdbstub or translate_init

Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
---
 target/ppc/cpu.c                |  859 +++++++++++++++++++++++
 target/ppc/cpu.h                |   15 +
 target/ppc/gdbstub.c            |  253 +++++++
 target/ppc/translate_init.c.inc | 1148 +------------------------------
 4 files changed, 1163 insertions(+), 1112 deletions(-)

diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c
index e501a7ff6f..b77ea1c943 100644
--- a/target/ppc/cpu.c
+++ b/target/ppc/cpu.c
@@ -20,6 +20,21 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "cpu-models.h"
+#include "kvm_ppc.h"
+#include "qemu/qemu-print.h"
+#include "qemu/cutils.h"
+#include "qapi/qapi-commands-machine-target.h"
+
+#include "qapi/error.h"
+#include "sysemu/tcg.h"
+#include "helper_regs.h"
+#include "hw/ppc/ppc.h"
+#include "fpu/softfloat-helpers.h"
+#include "sysemu/hw_accel.h"
+#include "disas/capstone.h"
+#include "hw/qdev-properties.h"
+#include "internal.h"
+#include "mmu-hash64.h"
 
 target_ulong cpu_read_xer(CPUPPCState *env)
 {
@@ -45,3 +60,847 @@ void cpu_write_xer(CPUPPCState *env, target_ulong xer)
                        (1ul << XER_OV) | (1ul << XER_CA) |
                        (1ul << XER_OV32) | (1ul << XER_CA32));
 }
+
+
+static const char *ppc_cpu_lookup_alias(const char *alias)
+{
+    int ai;
+
+    for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
+        if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
+            return ppc_cpu_aliases[ai].model;
+        }
+    }
+
+    return NULL;
+}
+
+static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
+{
+    ObjectClass *oc = (ObjectClass *)a;
+    uint32_t pvr = *(uint32_t *)b;
+    PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
+
+    /* -cpu host does a PVR lookup during construction */
+    if (unlikely(strcmp(object_class_get_name(oc),
+                        TYPE_HOST_POWERPC_CPU) == 0)) {
+        return -1;
+    }
+
+    return pcc->pvr == pvr ? 0 : -1;
+}
+
+static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
+{
+    ObjectClass *oc = (ObjectClass *)a;
+    uint32_t pvr = *(uint32_t *)b;
+    PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
+
+    /* -cpu host does a PVR lookup during construction */
+    if (unlikely(strcmp(object_class_get_name(oc),
+                        TYPE_HOST_POWERPC_CPU) == 0)) {
+        return -1;
+    }
+
+    if (pcc->pvr_match(pcc, pvr)) {
+        return 0;
+    }
+
+    return -1;
+}
+
+PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
+{
+    GSList *list, *item;
+    PowerPCCPUClass *pcc = NULL;
+
+    list = object_class_get_list(TYPE_POWERPC_CPU, false);
+    item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
+    if (item != NULL) {
+        pcc = POWERPC_CPU_CLASS(item->data);
+    }
+    g_slist_free(list);
+
+    return pcc;
+}
+
+PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
+{
+    GSList *list, *item;
+    PowerPCCPUClass *pcc = NULL;
+
+    list = object_class_get_list(TYPE_POWERPC_CPU, true);
+    item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
+    if (item != NULL) {
+        pcc = POWERPC_CPU_CLASS(item->data);
+    }
+    g_slist_free(list);
+
+    return pcc;
+}
+
+PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
+{
+    ObjectClass *oc = OBJECT_CLASS(pcc);
+
+    while (oc && !object_class_is_abstract(oc)) {
+        oc = object_class_get_parent(oc);
+    }
+    assert(oc);
+
+    return POWERPC_CPU_CLASS(oc);
+}
+
+/* Sort by PVR, ordering special case "host" last. */
+static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
+{
+    ObjectClass *oc_a = (ObjectClass *)a;
+    ObjectClass *oc_b = (ObjectClass *)b;
+    PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
+    PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
+    const char *name_a = object_class_get_name(oc_a);
+    const char *name_b = object_class_get_name(oc_b);
+
+    if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
+        return 1;
+    } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
+        return -1;
+    } else {
+        /* Avoid an integer overflow during subtraction */
+        if (pcc_a->pvr < pcc_b->pvr) {
+            return -1;
+        } else if (pcc_a->pvr > pcc_b->pvr) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+}
+#ifndef CONFIG_USER_ONLY
+static const TypeInfo ppc_vhyp_type_info = {
+    .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(PPCVirtualHypervisorClass),
+};
+#endif
+
+static ObjectClass *ppc_cpu_class_by_name(const char *name)
+{
+    char *cpu_model, *typename;
+    ObjectClass *oc;
+    const char *p;
+    unsigned long pvr;
+
+    /*
+     * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
+     * 0x prefix if present)
+     */
+    if (!qemu_strtoul(name, &p, 16, &pvr)) {
+        int len = p - name;
+        len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
+        if ((len == 8) && (*p == '\0')) {
+            return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
+        }
+    }
+
+    cpu_model = g_ascii_strdown(name, -1);
+    p = ppc_cpu_lookup_alias(cpu_model);
+    if (p) {
+        g_free(cpu_model);
+        cpu_model = g_strdup(p);
+    }
+
+    typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    g_free(cpu_model);
+
+    return oc;
+}
+
+static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
+{
+    return true;
+}
+
+static int ppc_fixup_cpu(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    /*
+     * TCG doesn't (yet) emulate some groups of instructions that are
+     * implemented on some otherwise supported CPUs (e.g. VSX and
+     * decimal floating point instructions on POWER7).  We remove
+     * unsupported instruction groups from the cpu state's instruction
+     * masks and hope the guest can cope.  For at least the pseries
+     * machine, the unavailability of these instructions can be
+     * advertised to the guest via the device tree.
+     */
+    if ((env->insns_flags & ~PPC_TCG_INSNS)
+        || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
+        warn_report("Disabling some instructions which are not "
+                    "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
+                    env->insns_flags & ~PPC_TCG_INSNS,
+                    env->insns_flags2 & ~PPC_TCG_INSNS2);
+    }
+    env->insns_flags &= PPC_TCG_INSNS;
+    env->insns_flags2 &= PPC_TCG_INSNS2;
+    return 0;
+}
+
+static void ppc_cpu_realize(DeviceState *dev, Error **errp)
+{
+    CPUState *cs = CPU(dev);
+    PowerPCCPU *cpu = POWERPC_CPU(dev);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+    Error *local_err = NULL;
+
+    cpu_exec_realizefn(cs, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
+        cpu->vcpu_id = cs->cpu_index;
+    }
+
+    if (tcg_enabled()) {
+        if (ppc_fixup_cpu(cpu) != 0) {
+            error_setg(errp, "Unable to emulate selected CPU with TCG");
+            goto unrealize;
+        }
+    }
+
+    create_ppc_opcodes(cpu, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        goto unrealize;
+    }
+    init_ppc_proc(cpu);
+
+    ppc_cpu_gdb_init(cs, pcc);
+
+    qemu_init_vcpu(cs);
+
+    pcc->parent_realize(dev, errp);
+
+#if defined(PPC_DUMP_CPU)
+    {
+        CPUPPCState *env = &cpu->env;
+        const char *mmu_model, *excp_model, *bus_model;
+        switch (env->mmu_model) {
+        case POWERPC_MMU_32B:
+            mmu_model = "PowerPC 32";
+            break;
+        case POWERPC_MMU_SOFT_6xx:
+            mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
+            break;
+        case POWERPC_MMU_SOFT_74xx:
+            mmu_model = "PowerPC 74xx with software driven TLBs";
+            break;
+        case POWERPC_MMU_SOFT_4xx:
+            mmu_model = "PowerPC 4xx with software driven TLBs";
+            break;
+        case POWERPC_MMU_SOFT_4xx_Z:
+            mmu_model = "PowerPC 4xx with software driven TLBs "
+                "and zones protections";
+            break;
+        case POWERPC_MMU_REAL:
+            mmu_model = "PowerPC real mode only";
+            break;
+        case POWERPC_MMU_MPC8xx:
+            mmu_model = "PowerPC MPC8xx";
+            break;
+        case POWERPC_MMU_BOOKE:
+            mmu_model = "PowerPC BookE";
+            break;
+        case POWERPC_MMU_BOOKE206:
+            mmu_model = "PowerPC BookE 2.06";
+            break;
+        case POWERPC_MMU_601:
+            mmu_model = "PowerPC 601";
+            break;
+#if defined(TARGET_PPC64)
+        case POWERPC_MMU_64B:
+            mmu_model = "PowerPC 64";
+            break;
+#endif
+        default:
+            mmu_model = "Unknown or invalid";
+            break;
+        }
+        switch (env->excp_model) {
+        case POWERPC_EXCP_STD:
+            excp_model = "PowerPC";
+            break;
+        case POWERPC_EXCP_40x:
+            excp_model = "PowerPC 40x";
+            break;
+        case POWERPC_EXCP_601:
+            excp_model = "PowerPC 601";
+            break;
+        case POWERPC_EXCP_602:
+            excp_model = "PowerPC 602";
+            break;
+        case POWERPC_EXCP_603:
+            excp_model = "PowerPC 603";
+            break;
+        case POWERPC_EXCP_603E:
+            excp_model = "PowerPC 603e";
+            break;
+        case POWERPC_EXCP_604:
+            excp_model = "PowerPC 604";
+            break;
+        case POWERPC_EXCP_7x0:
+            excp_model = "PowerPC 740/750";
+            break;
+        case POWERPC_EXCP_7x5:
+            excp_model = "PowerPC 745/755";
+            break;
+        case POWERPC_EXCP_74xx:
+            excp_model = "PowerPC 74xx";
+            break;
+        case POWERPC_EXCP_BOOKE:
+            excp_model = "PowerPC BookE";
+            break;
+#if defined(TARGET_PPC64)
+        case POWERPC_EXCP_970:
+            excp_model = "PowerPC 970";
+            break;
+#endif
+        default:
+            excp_model = "Unknown or invalid";
+            break;
+        }
+        switch (env->bus_model) {
+        case PPC_FLAGS_INPUT_6xx:
+            bus_model = "PowerPC 6xx";
+            break;
+        case PPC_FLAGS_INPUT_BookE:
+            bus_model = "PowerPC BookE";
+            break;
+        case PPC_FLAGS_INPUT_405:
+            bus_model = "PowerPC 405";
+            break;
+        case PPC_FLAGS_INPUT_401:
+            bus_model = "PowerPC 401/403";
+            break;
+        case PPC_FLAGS_INPUT_RCPU:
+            bus_model = "RCPU / MPC8xx";
+            break;
+#if defined(TARGET_PPC64)
+        case PPC_FLAGS_INPUT_970:
+            bus_model = "PowerPC 970";
+            break;
+#endif
+        default:
+            bus_model = "Unknown or invalid";
+            break;
+        }
+        printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
+               "    MMU model        : %s\n",
+               object_class_get_name(OBJECT_CLASS(pcc)),
+               pcc->pvr, pcc->msr_mask, mmu_model);
+#if !defined(CONFIG_USER_ONLY)
+        if (env->tlb.tlb6) {
+            printf("                       %d %s TLB in %d ways\n",
+                   env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
+                   env->nb_ways);
+        }
+#endif
+        printf("    Exceptions model : %s\n"
+               "    Bus model        : %s\n",
+               excp_model, bus_model);
+        printf("    MSR features     :\n");
+        if (env->flags & POWERPC_FLAG_SPE) {
+            printf("                        signal processing engine enable"
+                   "\n");
+        } else if (env->flags & POWERPC_FLAG_VRE) {
+            printf("                        vector processor enable\n");
+        }
+        if (env->flags & POWERPC_FLAG_TGPR) {
+            printf("                        temporary GPRs\n");
+        } else if (env->flags & POWERPC_FLAG_CE) {
+            printf("                        critical input enable\n");
+        }
+        if (env->flags & POWERPC_FLAG_SE) {
+            printf("                        single-step trace mode\n");
+        } else if (env->flags & POWERPC_FLAG_DWE) {
+            printf("                        debug wait enable\n");
+        } else if (env->flags & POWERPC_FLAG_UBLE) {
+            printf("                        user BTB lock enable\n");
+        }
+        if (env->flags & POWERPC_FLAG_BE) {
+            printf("                        branch-step trace mode\n");
+        } else if (env->flags & POWERPC_FLAG_DE) {
+            printf("                        debug interrupt enable\n");
+        }
+        if (env->flags & POWERPC_FLAG_PX) {
+            printf("                        inclusive protection\n");
+        } else if (env->flags & POWERPC_FLAG_PMM) {
+            printf("                        performance monitor mark\n");
+        }
+        if (env->flags == POWERPC_FLAG_NONE) {
+            printf("                        none\n");
+        }
+        printf("    Time-base/decrementer clock source: %s\n",
+               env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
+        dump_ppc_insns(env);
+        dump_ppc_sprs(env);
+        fflush(stdout);
+    }
+#endif
+    return;
+
+unrealize:
+    cpu_exec_unrealizefn(cs);
+}
+
+static void ppc_cpu_unrealize(DeviceState *dev)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(dev);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+
+    pcc->parent_unrealize(dev);
+
+    cpu_remove_sync(CPU(cpu));
+
+    destroy_ppc_opcodes(cpu);
+}
+
+static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+    cpu->env.nip = value;
+}
+
+static bool ppc_cpu_has_work(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+}
+
+static void ppc_cpu_reset(DeviceState *dev)
+{
+    CPUState *s = CPU(dev);
+    PowerPCCPU *cpu = POWERPC_CPU(s);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+    CPUPPCState *env = &cpu->env;
+    target_ulong msr;
+    int i;
+
+    pcc->parent_reset(dev);
+
+    msr = (target_ulong)0;
+    msr |= (target_ulong)MSR_HVB;
+    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
+    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
+    msr |= (target_ulong)1 << MSR_EP;
+#if defined(DO_SINGLE_STEP) && 0
+    /* Single step trace mode */
+    msr |= (target_ulong)1 << MSR_SE;
+    msr |= (target_ulong)1 << MSR_BE;
+#endif
+#if defined(CONFIG_USER_ONLY)
+    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
+    msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
+    msr |= (target_ulong)1 << MSR_FE1;
+    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
+    msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
+    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
+    msr |= (target_ulong)1 << MSR_PR;
+#if defined(TARGET_PPC64)
+    msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
+#endif
+#if !defined(TARGET_WORDS_BIGENDIAN)
+    msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
+    if (!((env->msr_mask >> MSR_LE) & 1)) {
+        fprintf(stderr, "Selected CPU does not support little-endian.\n");
+        exit(1);
+    }
+#endif
+#endif
+
+#if defined(TARGET_PPC64)
+    if (mmu_is_64bit(env->mmu_model)) {
+        msr |= (1ULL << MSR_SF);
+    }
+#endif
+
+    hreg_store_msr(env, msr, 1);
+
+#if !defined(CONFIG_USER_ONLY)
+    env->nip = env->hreset_vector | env->excp_prefix;
+    if (env->mmu_model != POWERPC_MMU_REAL) {
+        ppc_tlb_invalidate_all(env);
+    }
+#endif
+
+    hreg_compute_hflags(env);
+    env->reserve_addr = (target_ulong)-1ULL;
+    /* Be sure no exception or interrupt is pending */
+    env->pending_interrupts = 0;
+    s->exception_index = POWERPC_EXCP_NONE;
+    env->error_code = 0;
+    ppc_irq_reset(cpu);
+
+    /* tininess for underflow is detected before rounding */
+    set_float_detect_tininess(float_tininess_before_rounding,
+                              &env->fp_status);
+
+    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+        ppc_spr_t *spr = &env->spr_cb[i];
+
+        if (!spr->name) {
+            continue;
+        }
+        env->spr[i] = spr->default_value;
+    }
+}
+
+#ifndef CONFIG_USER_ONLY
+
+static bool ppc_cpu_is_big_endian(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    cpu_synchronize_state(cs);
+
+    return !msr_le;
+}
+
+#ifdef CONFIG_TCG
+static void ppc_cpu_exec_enter(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+    if (cpu->vhyp) {
+        PPCVirtualHypervisorClass *vhc =
+            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+        vhc->cpu_exec_enter(cpu->vhyp, cpu);
+    }
+}
+
+static void ppc_cpu_exec_exit(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+    if (cpu->vhyp) {
+        PPCVirtualHypervisorClass *vhc =
+            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+        vhc->cpu_exec_exit(cpu->vhyp, cpu);
+    }
+}
+#endif /* CONFIG_TCG */
+
+#endif /* !CONFIG_USER_ONLY */
+
+static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
+{
+    return pcc->pvr == pvr;
+}
+
+static gchar *ppc_gdb_arch_name(CPUState *cs)
+{
+#if defined(TARGET_PPC64)
+    return g_strdup("powerpc:common64");
+#else
+    return g_strdup("powerpc:common");
+#endif
+}
+
+static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if ((env->hflags >> MSR_LE) & 1) {
+        info->endian = BFD_ENDIAN_LITTLE;
+    }
+    info->mach = env->bfd_mach;
+    if (!env->bfd_mach) {
+#ifdef TARGET_PPC64
+        info->mach = bfd_mach_ppc64;
+#else
+        info->mach = bfd_mach_ppc;
+#endif
+    }
+    info->disassembler_options = (char *)"any";
+    info->print_insn = print_insn_ppc;
+
+    info->cap_arch = CS_ARCH_PPC;
+#ifdef TARGET_PPC64
+    info->cap_mode = CS_MODE_64;
+#endif
+}
+
+static Property ppc_cpu_properties[] = {
+    DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
+    DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
+                     false),
+    DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
+                     false),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+#ifdef CONFIG_TCG
+#include "hw/core/tcg-cpu-ops.h"
+
+static struct TCGCPUOps ppc_tcg_ops = {
+  .initialize = ppc_translate_init,
+  .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
+  .tlb_fill = ppc_cpu_tlb_fill,
+
+#ifndef CONFIG_USER_ONLY
+  .do_interrupt = ppc_cpu_do_interrupt,
+  .cpu_exec_enter = ppc_cpu_exec_enter,
+  .cpu_exec_exit = ppc_cpu_exec_exit,
+  .do_unaligned_access = ppc_cpu_do_unaligned_access,
+#endif /* !CONFIG_USER_ONLY */
+};
+#endif /* CONFIG_TCG */
+
+static void ppc_cpu_class_init(ObjectClass *oc, void *data)
+{
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    device_class_set_parent_realize(dc, ppc_cpu_realize,
+                                    &pcc->parent_realize);
+    device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
+                                      &pcc->parent_unrealize);
+    pcc->pvr_match = ppc_pvr_match_default;
+    pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
+    device_class_set_props(dc, ppc_cpu_properties);
+
+    device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
+
+    cc->class_by_name = ppc_cpu_class_by_name;
+    cc->has_work = ppc_cpu_has_work;
+    cc->dump_state = ppc_cpu_dump_state;
+    cc->dump_statistics = ppc_cpu_dump_statistics;
+    cc->set_pc = ppc_cpu_set_pc;
+    cc->gdb_read_register = ppc_cpu_gdb_read_register;
+    cc->gdb_write_register = ppc_cpu_gdb_write_register;
+#ifndef CONFIG_USER_ONLY
+    cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
+    cc->vmsd = &vmstate_ppc_cpu;
+#endif
+#if defined(CONFIG_SOFTMMU)
+    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
+    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
+#endif
+
+    cc->gdb_num_core_regs = 71;
+#ifndef CONFIG_USER_ONLY
+    cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
+#endif
+#ifdef USE_APPLE_GDB
+    cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
+    cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
+    cc->gdb_num_core_regs = 71 + 32;
+#endif
+
+    cc->gdb_arch_name = ppc_gdb_arch_name;
+#if defined(TARGET_PPC64)
+    cc->gdb_core_xml_file = "power64-core.xml";
+#else
+    cc->gdb_core_xml_file = "power-core.xml";
+#endif
+#ifndef CONFIG_USER_ONLY
+    cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
+#endif
+    cc->disas_set_info = ppc_disas_set_info;
+
+    dc->fw_name = "PowerPC,UNKNOWN";
+
+#ifdef CONFIG_TCG
+    cc->tcg_ops = &ppc_tcg_ops;
+#endif /* CONFIG_TCG */
+}
+
+static void ppc_cpu_instance_init(Object *obj)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(obj);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+    CPUPPCState *env = &cpu->env;
+
+    cpu_set_cpustate_pointers(cpu);
+    cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
+
+    env->msr_mask = pcc->msr_mask;
+    env->mmu_model = pcc->mmu_model;
+    env->excp_model = pcc->excp_model;
+    env->bus_model = pcc->bus_model;
+    env->insns_flags = pcc->insns_flags;
+    env->insns_flags2 = pcc->insns_flags2;
+    env->flags = pcc->flags;
+    env->bfd_mach = pcc->bfd_mach;
+    env->check_pow = pcc->check_pow;
+
+    /*
+     * Mark HV mode as supported if the CPU has an MSR_HV bit in the
+     * msr_mask. The mask can later be cleared by PAPR mode but the hv
+     * mode support will remain, thus enforcing that we cannot use
+     * priv. instructions in guest in PAPR mode. For 970 we currently
+     * simply don't set HV in msr_mask thus simulating an "Apple mode"
+     * 970. If we ever want to support 970 HV mode, we'll have to add
+     * a processor attribute of some sort.
+     */
+#if !defined(CONFIG_USER_ONLY)
+    env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
+#endif
+
+#ifdef CONFIG_TCG
+    ppc_hash64_init(cpu);
+#endif
+}
+
+static void ppc_cpu_instance_finalize(Object *obj)
+{
+#ifdef CONFIG_TCG
+    PowerPCCPU *cpu = POWERPC_CPU(obj);
+
+    ppc_hash64_finalize(cpu);
+#endif
+}
+
+static const TypeInfo ppc_cpu_type_info = {
+    .name = TYPE_POWERPC_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(PowerPCCPU),
+    .instance_align = __alignof__(PowerPCCPU),
+    .instance_init = ppc_cpu_instance_init,
+    .instance_finalize = ppc_cpu_instance_finalize,
+    .abstract = true,
+    .class_size = sizeof(PowerPCCPUClass),
+    .class_init = ppc_cpu_class_init,
+};
+
+static void ppc_cpu_register_types(void)
+{
+    type_register_static(&ppc_cpu_type_info);
+#ifndef CONFIG_USER_ONLY
+    type_register_static(&ppc_vhyp_type_info);
+#endif
+}
+
+type_init(ppc_cpu_register_types)
+
+static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *oc = data;
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
+    const char *typename = object_class_get_name(oc);
+    char *name;
+    int i;
+
+    if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
+        return;
+    }
+
+    name = g_strndup(typename,
+                     strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
+    qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
+    for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+        PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+        ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
+
+        if (alias_oc != oc) {
+            continue;
+        }
+        /*
+         * If running with KVM, we might update the family alias later, so
+         * avoid printing the wrong alias here and use "preferred" instead
+         */
+        if (strcmp(alias->alias, family->desc) == 0) {
+            qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
+                        alias->alias, family->desc);
+        } else {
+            qemu_printf("PowerPC %-16s (alias for %s)\n",
+                        alias->alias, name);
+        }
+    }
+    g_free(name);
+}
+
+void ppc_cpu_list(void)
+{
+    GSList *list;
+
+    list = object_class_get_list(TYPE_POWERPC_CPU, false);
+    list = g_slist_sort(list, ppc_cpu_list_compare);
+    g_slist_foreach(list, ppc_cpu_list_entry, NULL);
+    g_slist_free(list);
+
+#ifdef CONFIG_KVM
+    qemu_printf("\n");
+    qemu_printf("PowerPC %-16s\n", "host");
+#endif
+}
+
+static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *oc = data;
+    CpuDefinitionInfoList **first = user_data;
+    const char *typename;
+    CpuDefinitionInfo *info;
+
+    typename = object_class_get_name(oc);
+    info = g_malloc0(sizeof(*info));
+    info->name = g_strndup(typename,
+                           strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
+
+    QAPI_LIST_PREPEND(*first, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+    CpuDefinitionInfoList *cpu_list = NULL;
+    GSList *list;
+    int i;
+
+    list = object_class_get_list(TYPE_POWERPC_CPU, false);
+    g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
+    g_slist_free(list);
+
+    for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+        PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+        ObjectClass *oc;
+        CpuDefinitionInfo *info;
+
+        oc = ppc_cpu_class_by_name(alias->model);
+        if (oc == NULL) {
+            continue;
+        }
+
+        info = g_malloc0(sizeof(*info));
+        info->name = g_strdup(alias->alias);
+        info->q_typename = g_strdup(object_class_get_name(oc));
+
+        QAPI_LIST_PREPEND(cpu_list, info);
+    }
+
+    return cpu_list;
+}
+#if !defined(CONFIG_USER_ONLY)
+void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
+{
+    CPUPPCState *env = &cpu->env;
+
+    cpu->vhyp = vhyp;
+
+    /*
+     * With a virtual hypervisor mode we never allow the CPU to go
+     * hypervisor mode itself
+     */
+    env->msr_mask &= ~MSR_HVB;
+}
+
+#endif /* !defined(CONFIG_USER_ONLY) */
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e73416da68..031b04ee40 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2612,4 +2612,19 @@ static inline ppc_avr_t *cpu_avr_ptr(CPUPPCState *env, int i)
 void dump_mmu(CPUPPCState *env);
 
 void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
+
+/*
+ * functions used by cpu_ppc_realize, but that dont necessarily make sense
+ * to be added to cpu.c, because they seem very related to TCG or gdb
+ */
+
+/* gdbstub.c */
+void ppc_cpu_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
+
+/* translate_init.c.inc */
+void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp);
+void destroy_ppc_opcodes(PowerPCCPU *cpu);
+void gen_spr_generic(CPUPPCState *env);
+void init_ppc_proc(PowerPCCPU *cpu);
+
 #endif /* PPC_CPU_H */
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index c28319fb97..e6a6c0a6a0 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -20,6 +20,10 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/gdbstub.h"
+#ifdef CONFIG_TCG
+#include "exec/helper-proto.h"
+#endif
+#include "kvm_ppc.h"
 
 static int ppc_gdb_register_len_apple(int n)
 {
@@ -387,3 +391,252 @@ const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
     return NULL;
 }
 #endif
+
+static bool avr_need_swap(CPUPPCState *env)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+    return msr_le;
+#else
+    return !msr_le;
+#endif
+}
+
+#if !defined(CONFIG_USER_ONLY)
+static int gdb_find_spr_idx(CPUPPCState *env, int n)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+        ppc_spr_t *spr = &env->spr_cb[i];
+
+        if (spr->name && spr->gdb_id == n) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    int reg;
+    int len;
+
+    reg = gdb_find_spr_idx(env, n);
+    if (reg < 0) {
+        return 0;
+    }
+
+    len = TARGET_LONG_SIZE;
+    gdb_get_regl(buf, env->spr[reg]);
+    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
+    return len;
+}
+
+static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    int reg;
+    int len;
+
+    reg = gdb_find_spr_idx(env, n);
+    if (reg < 0) {
+        return 0;
+    }
+
+    len = TARGET_LONG_SIZE;
+    ppc_maybe_bswap_register(env, mem_buf, len);
+    env->spr[reg] = ldn_p(mem_buf, len);
+
+    return len;
+}
+#endif
+
+static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    uint8_t *mem_buf;
+    if (n < 32) {
+        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
+        mem_buf = gdb_get_reg_ptr(buf, 8);
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        return 8;
+    }
+    if (n == 32) {
+        gdb_get_reg32(buf, env->fpscr);
+        mem_buf = gdb_get_reg_ptr(buf, 4);
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
+        return 8;
+    }
+    if (n == 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    uint8_t *mem_buf;
+
+    if (n < 32) {
+        ppc_avr_t *avr = cpu_avr_ptr(env, n);
+        if (!avr_need_swap(env)) {
+            gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
+        } else {
+            gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
+        }
+        mem_buf = gdb_get_reg_ptr(buf, 16);
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
+        return 16;
+    }
+    if (n == 32) {
+        gdb_get_reg32(buf, helper_mfvscr(env));
+        mem_buf = gdb_get_reg_ptr(buf, 4);
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        return 4;
+    }
+    if (n == 33) {
+        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
+        mem_buf = gdb_get_reg_ptr(buf, 4);
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        ppc_avr_t *avr = cpu_avr_ptr(env, n);
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
+        if (!avr_need_swap(env)) {
+            avr->u64[0] = ldq_p(mem_buf);
+            avr->u64[1] = ldq_p(mem_buf + 8);
+        } else {
+            avr->u64[1] = ldq_p(mem_buf);
+            avr->u64[0] = ldq_p(mem_buf + 8);
+        }
+        return 16;
+    }
+    if (n == 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        helper_mtvscr(env, ldl_p(mem_buf));
+        return 4;
+    }
+    if (n == 33) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    if (n < 32) {
+#if defined(TARGET_PPC64)
+        gdb_get_reg32(buf, env->gpr[n] >> 32);
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
+#else
+        gdb_get_reg32(buf, env->gprh[n]);
+#endif
+        return 4;
+    }
+    if (n == 32) {
+        gdb_get_reg64(buf, env->spe_acc);
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
+        return 8;
+    }
+    if (n == 33) {
+        gdb_get_reg32(buf, env->spe_fscr);
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+#if defined(TARGET_PPC64)
+        target_ulong lo = (uint32_t)env->gpr[n];
+        target_ulong hi;
+
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+
+        hi = (target_ulong)ldl_p(mem_buf) << 32;
+        env->gpr[n] = lo | hi;
+#else
+        env->gprh[n] = ldl_p(mem_buf);
+#endif
+        return 4;
+    }
+    if (n == 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        env->spe_acc = ldq_p(mem_buf);
+        return 8;
+    }
+    if (n == 33) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        env->spe_fscr = ldl_p(mem_buf);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    if (n < 32) {
+        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
+        return 8;
+    }
+    return 0;
+}
+
+static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
+        return 8;
+    }
+    return 0;
+}
+
+
+void ppc_cpu_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
+{
+
+    if (pcc->insns_flags & PPC_FLOAT) {
+        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
+                                 33, "power-fpu.xml", 0);
+    }
+    if (pcc->insns_flags & PPC_ALTIVEC) {
+        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
+                                 34, "power-altivec.xml", 0);
+    }
+    if (pcc->insns_flags & PPC_SPE) {
+        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
+                                 34, "power-spe.xml", 0);
+    }
+    if (pcc->insns_flags2 & PPC2_VSX) {
+        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
+                                 32, "power-vsx.xml", 0);
+    }
+#ifndef CONFIG_USER_ONLY
+    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
+                             pcc->gdb_num_sprs, "power-spr.xml", 0);
+#endif
+}
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index c03a7c4f52..e1228a4b92 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -820,7 +820,7 @@ static inline void _spr_register(CPUPPCState *env, int num,
 }
 
 /* Generic PowerPC SPRs */
-static void gen_spr_generic(CPUPPCState *env)
+void gen_spr_generic(CPUPPCState *env)
 {
     /* Integer processing */
     spr_register(env, SPR_XER, "XER",
@@ -3498,11 +3498,6 @@ static int check_pow_hid0_74xx(CPUPPCState *env)
     return 0;
 }
 
-static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
-{
-    return true;
-}
-
 #ifdef TARGET_PPC64
 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
 {
@@ -9329,27 +9324,12 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
     pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
 }
 
-#if !defined(CONFIG_USER_ONLY)
-void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
-{
-    CPUPPCState *env = &cpu->env;
-
-    cpu->vhyp = vhyp;
-
-    /*
-     * With a virtual hypervisor mode we never allow the CPU to go
-     * hypervisor mode itself
-     */
-    env->msr_mask &= ~MSR_HVB;
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
 
 #endif /* defined(TARGET_PPC64) */
 
 /*****************************************************************************/
 /* Generic CPU instantiation routine                                         */
-static void init_ppc_proc(PowerPCCPU *cpu)
+void init_ppc_proc(PowerPCCPU *cpu)
 {
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     CPUPPCState *env = &cpu->env;
@@ -9783,7 +9763,7 @@ static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
 }
 
 /*****************************************************************************/
-static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
+void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
 {
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     opcode_t *opc;
@@ -9805,6 +9785,39 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
     fflush(stderr);
 }
 
+void destroy_ppc_opcodes(PowerPCCPU *cpu) {
+    opc_handler_t **table, **table_2;
+    int i, j, k;
+
+    for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
+        if (cpu->opcodes[i] == &invalid_handler) {
+            continue;
+        }
+        if (is_indirect_opcode(cpu->opcodes[i])) {
+            table = ind_table(cpu->opcodes[i]);
+            for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
+                if (table[j] == &invalid_handler) {
+                    continue;
+                }
+                if (is_indirect_opcode(table[j])) {
+                    table_2 = ind_table(table[j]);
+                    for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
+                        if (table_2[k] != &invalid_handler &&
+                            is_indirect_opcode(table_2[k])) {
+                            g_free((opc_handler_t *)((uintptr_t)table_2[k] &
+                                                     ~PPC_INDIRECT));
+                        }
+                    }
+                    g_free((opc_handler_t *)((uintptr_t)table[j] &
+                                             ~PPC_INDIRECT));
+                }
+            }
+            g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
+                ~PPC_INDIRECT));
+        }
+    }
+}
+
 #if defined(PPC_DUMP_CPU)
 static void dump_ppc_insns(CPUPPCState *env)
 {
@@ -9895,1092 +9908,3 @@ static void dump_ppc_insns(CPUPPCState *env)
     }
 }
 #endif
-
-static bool avr_need_swap(CPUPPCState *env)
-{
-#ifdef HOST_WORDS_BIGENDIAN
-    return msr_le;
-#else
-    return !msr_le;
-#endif
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static int gdb_find_spr_idx(CPUPPCState *env, int n)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
-        ppc_spr_t *spr = &env->spr_cb[i];
-
-        if (spr->name && spr->gdb_id == n) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    int reg;
-    int len;
-
-    reg = gdb_find_spr_idx(env, n);
-    if (reg < 0) {
-        return 0;
-    }
-
-    len = TARGET_LONG_SIZE;
-    gdb_get_regl(buf, env->spr[reg]);
-    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
-    return len;
-}
-
-static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    int reg;
-    int len;
-
-    reg = gdb_find_spr_idx(env, n);
-    if (reg < 0) {
-        return 0;
-    }
-
-    len = TARGET_LONG_SIZE;
-    ppc_maybe_bswap_register(env, mem_buf, len);
-    env->spr[reg] = ldn_p(mem_buf, len);
-
-    return len;
-}
-#endif
-
-static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    uint8_t *mem_buf;
-    if (n < 32) {
-        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
-        mem_buf = gdb_get_reg_ptr(buf, 8);
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        return 8;
-    }
-    if (n == 32) {
-        gdb_get_reg32(buf, env->fpscr);
-        mem_buf = gdb_get_reg_ptr(buf, 4);
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
-        return 8;
-    }
-    if (n == 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    uint8_t *mem_buf;
-
-    if (n < 32) {
-        ppc_avr_t *avr = cpu_avr_ptr(env, n);
-        if (!avr_need_swap(env)) {
-            gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
-        } else {
-            gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
-        }
-        mem_buf = gdb_get_reg_ptr(buf, 16);
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
-        return 16;
-    }
-    if (n == 32) {
-        gdb_get_reg32(buf, helper_mfvscr(env));
-        mem_buf = gdb_get_reg_ptr(buf, 4);
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        return 4;
-    }
-    if (n == 33) {
-        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
-        mem_buf = gdb_get_reg_ptr(buf, 4);
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        ppc_avr_t *avr = cpu_avr_ptr(env, n);
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
-        if (!avr_need_swap(env)) {
-            avr->u64[0] = ldq_p(mem_buf);
-            avr->u64[1] = ldq_p(mem_buf + 8);
-        } else {
-            avr->u64[1] = ldq_p(mem_buf);
-            avr->u64[0] = ldq_p(mem_buf + 8);
-        }
-        return 16;
-    }
-    if (n == 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        helper_mtvscr(env, ldl_p(mem_buf));
-        return 4;
-    }
-    if (n == 33) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    if (n < 32) {
-#if defined(TARGET_PPC64)
-        gdb_get_reg32(buf, env->gpr[n] >> 32);
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
-#else
-        gdb_get_reg32(buf, env->gprh[n]);
-#endif
-        return 4;
-    }
-    if (n == 32) {
-        gdb_get_reg64(buf, env->spe_acc);
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
-        return 8;
-    }
-    if (n == 33) {
-        gdb_get_reg32(buf, env->spe_fscr);
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-#if defined(TARGET_PPC64)
-        target_ulong lo = (uint32_t)env->gpr[n];
-        target_ulong hi;
-
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-
-        hi = (target_ulong)ldl_p(mem_buf) << 32;
-        env->gpr[n] = lo | hi;
-#else
-        env->gprh[n] = ldl_p(mem_buf);
-#endif
-        return 4;
-    }
-    if (n == 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        env->spe_acc = ldq_p(mem_buf);
-        return 8;
-    }
-    if (n == 33) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        env->spe_fscr = ldl_p(mem_buf);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    if (n < 32) {
-        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
-        return 8;
-    }
-    return 0;
-}
-
-static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
-        return 8;
-    }
-    return 0;
-}
-
-static int ppc_fixup_cpu(PowerPCCPU *cpu)
-{
-    CPUPPCState *env = &cpu->env;
-
-    /*
-     * TCG doesn't (yet) emulate some groups of instructions that are
-     * implemented on some otherwise supported CPUs (e.g. VSX and
-     * decimal floating point instructions on POWER7).  We remove
-     * unsupported instruction groups from the cpu state's instruction
-     * masks and hope the guest can cope.  For at least the pseries
-     * machine, the unavailability of these instructions can be
-     * advertised to the guest via the device tree.
-     */
-    if ((env->insns_flags & ~PPC_TCG_INSNS)
-        || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
-        warn_report("Disabling some instructions which are not "
-                    "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
-                    env->insns_flags & ~PPC_TCG_INSNS,
-                    env->insns_flags2 & ~PPC_TCG_INSNS2);
-    }
-    env->insns_flags &= PPC_TCG_INSNS;
-    env->insns_flags2 &= PPC_TCG_INSNS2;
-    return 0;
-}
-
-static void ppc_cpu_realize(DeviceState *dev, Error **errp)
-{
-    CPUState *cs = CPU(dev);
-    PowerPCCPU *cpu = POWERPC_CPU(dev);
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-    Error *local_err = NULL;
-
-    cpu_exec_realizefn(cs, &local_err);
-    if (local_err != NULL) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
-        cpu->vcpu_id = cs->cpu_index;
-    }
-
-    if (tcg_enabled()) {
-        if (ppc_fixup_cpu(cpu) != 0) {
-            error_setg(errp, "Unable to emulate selected CPU with TCG");
-            goto unrealize;
-        }
-    }
-
-    create_ppc_opcodes(cpu, &local_err);
-    if (local_err != NULL) {
-        error_propagate(errp, local_err);
-        goto unrealize;
-    }
-    init_ppc_proc(cpu);
-
-    if (pcc->insns_flags & PPC_FLOAT) {
-        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
-                                 33, "power-fpu.xml", 0);
-    }
-    if (pcc->insns_flags & PPC_ALTIVEC) {
-        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
-                                 34, "power-altivec.xml", 0);
-    }
-    if (pcc->insns_flags & PPC_SPE) {
-        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
-                                 34, "power-spe.xml", 0);
-    }
-    if (pcc->insns_flags2 & PPC2_VSX) {
-        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
-                                 32, "power-vsx.xml", 0);
-    }
-#ifndef CONFIG_USER_ONLY
-    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
-                             pcc->gdb_num_sprs, "power-spr.xml", 0);
-#endif
-    qemu_init_vcpu(cs);
-
-    pcc->parent_realize(dev, errp);
-
-#if defined(PPC_DUMP_CPU)
-    {
-        CPUPPCState *env = &cpu->env;
-        const char *mmu_model, *excp_model, *bus_model;
-        switch (env->mmu_model) {
-        case POWERPC_MMU_32B:
-            mmu_model = "PowerPC 32";
-            break;
-        case POWERPC_MMU_SOFT_6xx:
-            mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
-            break;
-        case POWERPC_MMU_SOFT_74xx:
-            mmu_model = "PowerPC 74xx with software driven TLBs";
-            break;
-        case POWERPC_MMU_SOFT_4xx:
-            mmu_model = "PowerPC 4xx with software driven TLBs";
-            break;
-        case POWERPC_MMU_SOFT_4xx_Z:
-            mmu_model = "PowerPC 4xx with software driven TLBs "
-                "and zones protections";
-            break;
-        case POWERPC_MMU_REAL:
-            mmu_model = "PowerPC real mode only";
-            break;
-        case POWERPC_MMU_MPC8xx:
-            mmu_model = "PowerPC MPC8xx";
-            break;
-        case POWERPC_MMU_BOOKE:
-            mmu_model = "PowerPC BookE";
-            break;
-        case POWERPC_MMU_BOOKE206:
-            mmu_model = "PowerPC BookE 2.06";
-            break;
-        case POWERPC_MMU_601:
-            mmu_model = "PowerPC 601";
-            break;
-#if defined(TARGET_PPC64)
-        case POWERPC_MMU_64B:
-            mmu_model = "PowerPC 64";
-            break;
-#endif
-        default:
-            mmu_model = "Unknown or invalid";
-            break;
-        }
-        switch (env->excp_model) {
-        case POWERPC_EXCP_STD:
-            excp_model = "PowerPC";
-            break;
-        case POWERPC_EXCP_40x:
-            excp_model = "PowerPC 40x";
-            break;
-        case POWERPC_EXCP_601:
-            excp_model = "PowerPC 601";
-            break;
-        case POWERPC_EXCP_602:
-            excp_model = "PowerPC 602";
-            break;
-        case POWERPC_EXCP_603:
-            excp_model = "PowerPC 603";
-            break;
-        case POWERPC_EXCP_603E:
-            excp_model = "PowerPC 603e";
-            break;
-        case POWERPC_EXCP_604:
-            excp_model = "PowerPC 604";
-            break;
-        case POWERPC_EXCP_7x0:
-            excp_model = "PowerPC 740/750";
-            break;
-        case POWERPC_EXCP_7x5:
-            excp_model = "PowerPC 745/755";
-            break;
-        case POWERPC_EXCP_74xx:
-            excp_model = "PowerPC 74xx";
-            break;
-        case POWERPC_EXCP_BOOKE:
-            excp_model = "PowerPC BookE";
-            break;
-#if defined(TARGET_PPC64)
-        case POWERPC_EXCP_970:
-            excp_model = "PowerPC 970";
-            break;
-#endif
-        default:
-            excp_model = "Unknown or invalid";
-            break;
-        }
-        switch (env->bus_model) {
-        case PPC_FLAGS_INPUT_6xx:
-            bus_model = "PowerPC 6xx";
-            break;
-        case PPC_FLAGS_INPUT_BookE:
-            bus_model = "PowerPC BookE";
-            break;
-        case PPC_FLAGS_INPUT_405:
-            bus_model = "PowerPC 405";
-            break;
-        case PPC_FLAGS_INPUT_401:
-            bus_model = "PowerPC 401/403";
-            break;
-        case PPC_FLAGS_INPUT_RCPU:
-            bus_model = "RCPU / MPC8xx";
-            break;
-#if defined(TARGET_PPC64)
-        case PPC_FLAGS_INPUT_970:
-            bus_model = "PowerPC 970";
-            break;
-#endif
-        default:
-            bus_model = "Unknown or invalid";
-            break;
-        }
-        printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
-               "    MMU model        : %s\n",
-               object_class_get_name(OBJECT_CLASS(pcc)),
-               pcc->pvr, pcc->msr_mask, mmu_model);
-#if !defined(CONFIG_USER_ONLY)
-        if (env->tlb.tlb6) {
-            printf("                       %d %s TLB in %d ways\n",
-                   env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
-                   env->nb_ways);
-        }
-#endif
-        printf("    Exceptions model : %s\n"
-               "    Bus model        : %s\n",
-               excp_model, bus_model);
-        printf("    MSR features     :\n");
-        if (env->flags & POWERPC_FLAG_SPE) {
-            printf("                        signal processing engine enable"
-                   "\n");
-        } else if (env->flags & POWERPC_FLAG_VRE) {
-            printf("                        vector processor enable\n");
-        }
-        if (env->flags & POWERPC_FLAG_TGPR) {
-            printf("                        temporary GPRs\n");
-        } else if (env->flags & POWERPC_FLAG_CE) {
-            printf("                        critical input enable\n");
-        }
-        if (env->flags & POWERPC_FLAG_SE) {
-            printf("                        single-step trace mode\n");
-        } else if (env->flags & POWERPC_FLAG_DWE) {
-            printf("                        debug wait enable\n");
-        } else if (env->flags & POWERPC_FLAG_UBLE) {
-            printf("                        user BTB lock enable\n");
-        }
-        if (env->flags & POWERPC_FLAG_BE) {
-            printf("                        branch-step trace mode\n");
-        } else if (env->flags & POWERPC_FLAG_DE) {
-            printf("                        debug interrupt enable\n");
-        }
-        if (env->flags & POWERPC_FLAG_PX) {
-            printf("                        inclusive protection\n");
-        } else if (env->flags & POWERPC_FLAG_PMM) {
-            printf("                        performance monitor mark\n");
-        }
-        if (env->flags == POWERPC_FLAG_NONE) {
-            printf("                        none\n");
-        }
-        printf("    Time-base/decrementer clock source: %s\n",
-               env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
-        dump_ppc_insns(env);
-        dump_ppc_sprs(env);
-        fflush(stdout);
-    }
-#endif
-    return;
-
-unrealize:
-    cpu_exec_unrealizefn(cs);
-}
-
-static void ppc_cpu_unrealize(DeviceState *dev)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(dev);
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-    opc_handler_t **table, **table_2;
-    int i, j, k;
-
-    pcc->parent_unrealize(dev);
-
-    cpu_remove_sync(CPU(cpu));
-
-    for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
-        if (cpu->opcodes[i] == &invalid_handler) {
-            continue;
-        }
-        if (is_indirect_opcode(cpu->opcodes[i])) {
-            table = ind_table(cpu->opcodes[i]);
-            for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
-                if (table[j] == &invalid_handler) {
-                    continue;
-                }
-                if (is_indirect_opcode(table[j])) {
-                    table_2 = ind_table(table[j]);
-                    for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
-                        if (table_2[k] != &invalid_handler &&
-                            is_indirect_opcode(table_2[k])) {
-                            g_free((opc_handler_t *)((uintptr_t)table_2[k] &
-                                                     ~PPC_INDIRECT));
-                        }
-                    }
-                    g_free((opc_handler_t *)((uintptr_t)table[j] &
-                                             ~PPC_INDIRECT));
-                }
-            }
-            g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
-                ~PPC_INDIRECT));
-        }
-    }
-}
-
-static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
-{
-    ObjectClass *oc = (ObjectClass *)a;
-    uint32_t pvr = *(uint32_t *)b;
-    PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
-
-    /* -cpu host does a PVR lookup during construction */
-    if (unlikely(strcmp(object_class_get_name(oc),
-                        TYPE_HOST_POWERPC_CPU) == 0)) {
-        return -1;
-    }
-
-    return pcc->pvr == pvr ? 0 : -1;
-}
-
-PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
-{
-    GSList *list, *item;
-    PowerPCCPUClass *pcc = NULL;
-
-    list = object_class_get_list(TYPE_POWERPC_CPU, false);
-    item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
-    if (item != NULL) {
-        pcc = POWERPC_CPU_CLASS(item->data);
-    }
-    g_slist_free(list);
-
-    return pcc;
-}
-
-static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
-{
-    ObjectClass *oc = (ObjectClass *)a;
-    uint32_t pvr = *(uint32_t *)b;
-    PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
-
-    /* -cpu host does a PVR lookup during construction */
-    if (unlikely(strcmp(object_class_get_name(oc),
-                        TYPE_HOST_POWERPC_CPU) == 0)) {
-        return -1;
-    }
-
-    if (pcc->pvr_match(pcc, pvr)) {
-        return 0;
-    }
-
-    return -1;
-}
-
-PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
-{
-    GSList *list, *item;
-    PowerPCCPUClass *pcc = NULL;
-
-    list = object_class_get_list(TYPE_POWERPC_CPU, true);
-    item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
-    if (item != NULL) {
-        pcc = POWERPC_CPU_CLASS(item->data);
-    }
-    g_slist_free(list);
-
-    return pcc;
-}
-
-static const char *ppc_cpu_lookup_alias(const char *alias)
-{
-    int ai;
-
-    for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
-        if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
-            return ppc_cpu_aliases[ai].model;
-        }
-    }
-
-    return NULL;
-}
-
-static ObjectClass *ppc_cpu_class_by_name(const char *name)
-{
-    char *cpu_model, *typename;
-    ObjectClass *oc;
-    const char *p;
-    unsigned long pvr;
-
-    /*
-     * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
-     * 0x prefix if present)
-     */
-    if (!qemu_strtoul(name, &p, 16, &pvr)) {
-        int len = p - name;
-        len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
-        if ((len == 8) && (*p == '\0')) {
-            return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
-        }
-    }
-
-    cpu_model = g_ascii_strdown(name, -1);
-    p = ppc_cpu_lookup_alias(cpu_model);
-    if (p) {
-        g_free(cpu_model);
-        cpu_model = g_strdup(p);
-    }
-
-    typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
-    oc = object_class_by_name(typename);
-    g_free(typename);
-    g_free(cpu_model);
-
-    return oc;
-}
-
-PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
-{
-    ObjectClass *oc = OBJECT_CLASS(pcc);
-
-    while (oc && !object_class_is_abstract(oc)) {
-        oc = object_class_get_parent(oc);
-    }
-    assert(oc);
-
-    return POWERPC_CPU_CLASS(oc);
-}
-
-/* Sort by PVR, ordering special case "host" last. */
-static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
-{
-    ObjectClass *oc_a = (ObjectClass *)a;
-    ObjectClass *oc_b = (ObjectClass *)b;
-    PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
-    PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
-    const char *name_a = object_class_get_name(oc_a);
-    const char *name_b = object_class_get_name(oc_b);
-
-    if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
-        return 1;
-    } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
-        return -1;
-    } else {
-        /* Avoid an integer overflow during subtraction */
-        if (pcc_a->pvr < pcc_b->pvr) {
-            return -1;
-        } else if (pcc_a->pvr > pcc_b->pvr) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-}
-
-static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
-{
-    ObjectClass *oc = data;
-    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-    DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
-    const char *typename = object_class_get_name(oc);
-    char *name;
-    int i;
-
-    if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
-        return;
-    }
-
-    name = g_strndup(typename,
-                     strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
-    qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
-    for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-        PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
-        ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
-
-        if (alias_oc != oc) {
-            continue;
-        }
-        /*
-         * If running with KVM, we might update the family alias later, so
-         * avoid printing the wrong alias here and use "preferred" instead
-         */
-        if (strcmp(alias->alias, family->desc) == 0) {
-            qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
-                        alias->alias, family->desc);
-        } else {
-            qemu_printf("PowerPC %-16s (alias for %s)\n",
-                        alias->alias, name);
-        }
-    }
-    g_free(name);
-}
-
-void ppc_cpu_list(void)
-{
-    GSList *list;
-
-    list = object_class_get_list(TYPE_POWERPC_CPU, false);
-    list = g_slist_sort(list, ppc_cpu_list_compare);
-    g_slist_foreach(list, ppc_cpu_list_entry, NULL);
-    g_slist_free(list);
-
-#ifdef CONFIG_KVM
-    qemu_printf("\n");
-    qemu_printf("PowerPC %-16s\n", "host");
-#endif
-}
-
-static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
-{
-    ObjectClass *oc = data;
-    CpuDefinitionInfoList **first = user_data;
-    const char *typename;
-    CpuDefinitionInfo *info;
-
-    typename = object_class_get_name(oc);
-    info = g_malloc0(sizeof(*info));
-    info->name = g_strndup(typename,
-                           strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
-
-    QAPI_LIST_PREPEND(*first, info);
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
-    CpuDefinitionInfoList *cpu_list = NULL;
-    GSList *list;
-    int i;
-
-    list = object_class_get_list(TYPE_POWERPC_CPU, false);
-    g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
-    g_slist_free(list);
-
-    for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-        PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
-        ObjectClass *oc;
-        CpuDefinitionInfo *info;
-
-        oc = ppc_cpu_class_by_name(alias->model);
-        if (oc == NULL) {
-            continue;
-        }
-
-        info = g_malloc0(sizeof(*info));
-        info->name = g_strdup(alias->alias);
-        info->q_typename = g_strdup(object_class_get_name(oc));
-
-        QAPI_LIST_PREPEND(cpu_list, info);
-    }
-
-    return cpu_list;
-}
-
-static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-    cpu->env.nip = value;
-}
-
-static bool ppc_cpu_has_work(CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    CPUPPCState *env = &cpu->env;
-
-    return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
-}
-
-static void ppc_cpu_reset(DeviceState *dev)
-{
-    CPUState *s = CPU(dev);
-    PowerPCCPU *cpu = POWERPC_CPU(s);
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-    CPUPPCState *env = &cpu->env;
-    target_ulong msr;
-    int i;
-
-    pcc->parent_reset(dev);
-
-    msr = (target_ulong)0;
-    msr |= (target_ulong)MSR_HVB;
-    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
-    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
-    msr |= (target_ulong)1 << MSR_EP;
-#if defined(DO_SINGLE_STEP) && 0
-    /* Single step trace mode */
-    msr |= (target_ulong)1 << MSR_SE;
-    msr |= (target_ulong)1 << MSR_BE;
-#endif
-#if defined(CONFIG_USER_ONLY)
-    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
-    msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
-    msr |= (target_ulong)1 << MSR_FE1;
-    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
-    msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
-    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
-    msr |= (target_ulong)1 << MSR_PR;
-#if defined(TARGET_PPC64)
-    msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
-#endif
-#if !defined(TARGET_WORDS_BIGENDIAN)
-    msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
-    if (!((env->msr_mask >> MSR_LE) & 1)) {
-        fprintf(stderr, "Selected CPU does not support little-endian.\n");
-        exit(1);
-    }
-#endif
-#endif
-
-#if defined(TARGET_PPC64)
-    if (mmu_is_64bit(env->mmu_model)) {
-        msr |= (1ULL << MSR_SF);
-    }
-#endif
-
-    hreg_store_msr(env, msr, 1);
-
-#if !defined(CONFIG_USER_ONLY)
-    env->nip = env->hreset_vector | env->excp_prefix;
-    if (env->mmu_model != POWERPC_MMU_REAL) {
-        ppc_tlb_invalidate_all(env);
-    }
-#endif
-
-    hreg_compute_hflags(env);
-    env->reserve_addr = (target_ulong)-1ULL;
-    /* Be sure no exception or interrupt is pending */
-    env->pending_interrupts = 0;
-    s->exception_index = POWERPC_EXCP_NONE;
-    env->error_code = 0;
-    ppc_irq_reset(cpu);
-
-    /* tininess for underflow is detected before rounding */
-    set_float_detect_tininess(float_tininess_before_rounding,
-                              &env->fp_status);
-
-    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
-        ppc_spr_t *spr = &env->spr_cb[i];
-
-        if (!spr->name) {
-            continue;
-        }
-        env->spr[i] = spr->default_value;
-    }
-}
-
-#ifndef CONFIG_USER_ONLY
-
-static bool ppc_cpu_is_big_endian(CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    CPUPPCState *env = &cpu->env;
-
-    cpu_synchronize_state(cs);
-
-    return !msr_le;
-}
-
-#ifdef CONFIG_TCG
-static void ppc_cpu_exec_enter(CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-    if (cpu->vhyp) {
-        PPCVirtualHypervisorClass *vhc =
-            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
-        vhc->cpu_exec_enter(cpu->vhyp, cpu);
-    }
-}
-
-static void ppc_cpu_exec_exit(CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-    if (cpu->vhyp) {
-        PPCVirtualHypervisorClass *vhc =
-            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
-        vhc->cpu_exec_exit(cpu->vhyp, cpu);
-    }
-}
-#endif /* CONFIG_TCG */
-
-#endif /* !CONFIG_USER_ONLY */
-
-static void ppc_cpu_instance_init(Object *obj)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(obj);
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-    CPUPPCState *env = &cpu->env;
-
-    cpu_set_cpustate_pointers(cpu);
-    cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
-
-    env->msr_mask = pcc->msr_mask;
-    env->mmu_model = pcc->mmu_model;
-    env->excp_model = pcc->excp_model;
-    env->bus_model = pcc->bus_model;
-    env->insns_flags = pcc->insns_flags;
-    env->insns_flags2 = pcc->insns_flags2;
-    env->flags = pcc->flags;
-    env->bfd_mach = pcc->bfd_mach;
-    env->check_pow = pcc->check_pow;
-
-    /*
-     * Mark HV mode as supported if the CPU has an MSR_HV bit in the
-     * msr_mask. The mask can later be cleared by PAPR mode but the hv
-     * mode support will remain, thus enforcing that we cannot use
-     * priv. instructions in guest in PAPR mode. For 970 we currently
-     * simply don't set HV in msr_mask thus simulating an "Apple mode"
-     * 970. If we ever want to support 970 HV mode, we'll have to add
-     * a processor attribute of some sort.
-     */
-#if !defined(CONFIG_USER_ONLY)
-    env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
-#endif
-
-    ppc_hash64_init(cpu);
-}
-
-static void ppc_cpu_instance_finalize(Object *obj)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(obj);
-
-    ppc_hash64_finalize(cpu);
-}
-
-static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
-{
-    return pcc->pvr == pvr;
-}
-
-static gchar *ppc_gdb_arch_name(CPUState *cs)
-{
-#if defined(TARGET_PPC64)
-    return g_strdup("powerpc:common64");
-#else
-    return g_strdup("powerpc:common");
-#endif
-}
-
-static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    CPUPPCState *env = &cpu->env;
-
-    if ((env->hflags >> MSR_LE) & 1) {
-        info->endian = BFD_ENDIAN_LITTLE;
-    }
-    info->mach = env->bfd_mach;
-    if (!env->bfd_mach) {
-#ifdef TARGET_PPC64
-        info->mach = bfd_mach_ppc64;
-#else
-        info->mach = bfd_mach_ppc;
-#endif
-    }
-    info->disassembler_options = (char *)"any";
-    info->print_insn = print_insn_ppc;
-
-    info->cap_arch = CS_ARCH_PPC;
-#ifdef TARGET_PPC64
-    info->cap_mode = CS_MODE_64;
-#endif
-}
-
-static Property ppc_cpu_properties[] = {
-    DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
-    DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
-                     false),
-    DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
-                     false),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-#ifdef CONFIG_TCG
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps ppc_tcg_ops = {
-  .initialize = ppc_translate_init,
-  .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
-  .tlb_fill = ppc_cpu_tlb_fill,
-
-#ifndef CONFIG_USER_ONLY
-  .do_interrupt = ppc_cpu_do_interrupt,
-  .cpu_exec_enter = ppc_cpu_exec_enter,
-  .cpu_exec_exit = ppc_cpu_exec_exit,
-  .do_unaligned_access = ppc_cpu_do_unaligned_access,
-#endif /* !CONFIG_USER_ONLY */
-};
-#endif /* CONFIG_TCG */
-
-static void ppc_cpu_class_init(ObjectClass *oc, void *data)
-{
-    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-    CPUClass *cc = CPU_CLASS(oc);
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    device_class_set_parent_realize(dc, ppc_cpu_realize,
-                                    &pcc->parent_realize);
-    device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
-                                      &pcc->parent_unrealize);
-    pcc->pvr_match = ppc_pvr_match_default;
-    pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
-    device_class_set_props(dc, ppc_cpu_properties);
-
-    device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
-
-    cc->class_by_name = ppc_cpu_class_by_name;
-    cc->has_work = ppc_cpu_has_work;
-    cc->dump_state = ppc_cpu_dump_state;
-    cc->dump_statistics = ppc_cpu_dump_statistics;
-    cc->set_pc = ppc_cpu_set_pc;
-    cc->gdb_read_register = ppc_cpu_gdb_read_register;
-    cc->gdb_write_register = ppc_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
-    cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
-    cc->vmsd = &vmstate_ppc_cpu;
-#endif
-#if defined(CONFIG_SOFTMMU)
-    cc->write_elf64_note = ppc64_cpu_write_elf64_note;
-    cc->write_elf32_note = ppc32_cpu_write_elf32_note;
-#endif
-
-    cc->gdb_num_core_regs = 71;
-#ifndef CONFIG_USER_ONLY
-    cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
-#endif
-#ifdef USE_APPLE_GDB
-    cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
-    cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
-    cc->gdb_num_core_regs = 71 + 32;
-#endif
-
-    cc->gdb_arch_name = ppc_gdb_arch_name;
-#if defined(TARGET_PPC64)
-    cc->gdb_core_xml_file = "power64-core.xml";
-#else
-    cc->gdb_core_xml_file = "power-core.xml";
-#endif
-#ifndef CONFIG_USER_ONLY
-    cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
-#endif
-    cc->disas_set_info = ppc_disas_set_info;
-
-    dc->fw_name = "PowerPC,UNKNOWN";
-
-#ifdef CONFIG_TCG
-    cc->tcg_ops = &ppc_tcg_ops;
-#endif /* CONFIG_TCG */
-}
-
-static const TypeInfo ppc_cpu_type_info = {
-    .name = TYPE_POWERPC_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(PowerPCCPU),
-    .instance_align = __alignof__(PowerPCCPU),
-    .instance_init = ppc_cpu_instance_init,
-    .instance_finalize = ppc_cpu_instance_finalize,
-    .abstract = true,
-    .class_size = sizeof(PowerPCCPUClass),
-    .class_init = ppc_cpu_class_init,
-};
-
-#ifndef CONFIG_USER_ONLY
-static const TypeInfo ppc_vhyp_type_info = {
-    .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
-    .parent = TYPE_INTERFACE,
-    .class_size = sizeof(PPCVirtualHypervisorClass),
-};
-#endif
-
-static void ppc_cpu_register_types(void)
-{
-    type_register_static(&ppc_cpu_type_info);
-#ifndef CONFIG_USER_ONLY
-    type_register_static(&ppc_vhyp_type_info);
-#endif
-}
-
-type_init(ppc_cpu_register_types)
-- 
2.17.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/4] target/ppc: added solutions for building with disable-tcg
  2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
  2021-04-09 15:19 ` [PATCH 1/4] target/ppc: Code motion required to build disabling tcg Bruno Larsen (billionai)
@ 2021-04-09 15:19 ` Bruno Larsen (billionai)
  2021-04-09 20:40   ` Fabiano Rosas
  2021-04-12  5:08   ` David Gibson
  2021-04-09 15:19 ` [PATCH 3/4] target/ppc: Add stubs for tcg functions, so it builds Bruno Larsen (billionai)
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 15+ messages in thread
From: Bruno Larsen (billionai) @ 2021-04-09 15:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: lucas.araujo, lagarcia, luis.pires, fernando.valle, qemu-ppc,
	andre.silva, Bruno Larsen (billionai),
	matheus.ferst

this commit presents 2 possible solutions for substituting TCG emulation
with KVM calls. One - used in machine.c and arch_dump.c - explicitly
adds the KVM function and has the possibility of adding the TCG one
for more generic compilation, prioritizing te KVM option. The second
option, implemented in kvm_ppc.h, transparently changes the helper
into the KVM call, if TCG is not enabled. I believe the first solution
is better, but it is less readable, so I wanted to have some feedback

Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
---
 target/ppc/arch_dump.c | 17 +++++++++++++++++
 target/ppc/kvm.c       | 30 ++++++++++++++++++++++++++++++
 target/ppc/kvm_ppc.h   | 11 +++++++++++
 target/ppc/machine.c   | 33 ++++++++++++++++++++++++++++++++-
 4 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index 9ab04b2c38..c53e01011a 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -17,7 +17,10 @@
 #include "elf.h"
 #include "sysemu/dump.h"
 #include "sysemu/kvm.h"
+#include "kvm_ppc.h"
+#if defined(CONFIG_TCG)
 #include "exec/helper-proto.h"
+#endif /* CONFIG_TCG */
 
 #ifdef TARGET_PPC64
 #define ELFCLASS ELFCLASS64
@@ -176,7 +179,21 @@ static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
             vmxregset->avr[i].u64[1] = avr->u64[1];
         }
     }
+    /* This is the first solution implemented. My personal favorite as it
+     * allows for explicit error handling, however it is much less readable */
+#if defined(CONFIG_KVM)
+    if(kvm_enabled()){
+        vmxregset->vscr.u32[3] = cpu_to_dump32(s, kvmppc_mfvscr(cpu));
+    }else
+#endif
+
+#if defined(CONFIG_TCG)
     vmxregset->vscr.u32[3] = cpu_to_dump32(s, helper_mfvscr(&cpu->env));
+#else
+    {
+        /* TODO: add proper error handling, even tough this should never be reached */
+    }
+#endif
 }
 
 static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 104a308abb..8ed54d12d8 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -51,6 +51,7 @@
 #include "elf.h"
 #include "sysemu/kvm_int.h"
 
+
 #define PROC_DEVTREE_CPU      "/proc/device-tree/cpus/"
 
 #define DEBUG_RETURN_GUEST 0
@@ -2947,3 +2948,32 @@ bool kvm_arch_cpu_check_are_resettable(void)
 {
     return true;
 }
+
+/* Functions added to replace helper_m(t|f)vscr from int_helper.c */
+int kvmppc_mtvscr(PowerPCCPU *cpu, uint32_t val){
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
+    struct kvm_one_reg reg;
+    int ret;
+    reg.id = KVM_REG_PPC_VSCR;
+    reg.addr = (uintptr_t) &env->vscr;
+    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+    if(ret < 0){
+        fprintf(stderr, "Unable to set VSCR to KVM: %s", strerror(errno));
+    }
+    return ret;
+}
+
+int kvmppc_mfvscr(PowerPCCPU *cpu){
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
+    struct kvm_one_reg reg;
+    int ret;
+    reg.id = KVM_REG_PPC_VSCR;
+    reg.addr = (uintptr_t) &env->vscr;
+    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+    if(ret < 0){
+        fprintf(stderr, "Unable to get VSCR to KVM: %s", strerror(errno));
+    }
+    return ret;
+}
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 989f61ace0..f618cb28b1 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -86,6 +86,17 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset);
 
 int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run);
 
+int kvmppc_mtvscr(PowerPCCPU*, uint32_t);
+int kvmppc_mfvscr(PowerPCCPU*);
+
+/* This is the second (quick and dirty) solution. Not my personal favorite
+ * as it hides what is actually happening from the user and doesn't allow
+ * for error checking. but it requires less change in other files */
+#ifndef CONFIG_TCG
+#define helper_mtvscr(env, val) kvmppc_mtvscr(env_archcpu(env),val)
+#define helper_mfvscr(env) kvmppc_mfvscr(env_archcpu(env))
+#endif
+
 #else
 
 static inline uint32_t kvmppc_get_tbfreq(void)
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 283db1d28a..d92bc18859 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -8,7 +8,9 @@
 #include "qapi/error.h"
 #include "qemu/main-loop.h"
 #include "kvm_ppc.h"
+#ifdef CONFIG_TCG
 #include "exec/helper-proto.h"
+#endif /*CONFIG_TCG*/
 
 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
 {
@@ -95,7 +97,18 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
         ppc_store_sdr1(env, sdr1);
     }
     qemu_get_be32s(f, &vscr);
-    helper_mtvscr(env, vscr);
+#if defined(CONFIG_KVM)
+    if(kvm_enabled()){
+        kvmppc_mtvscr(cpu, vscr);
+    }else
+#endif
+#if defined(CONFIG_TCG)
+        helper_mtvscr(env, vscr);
+#else
+    {
+        /* TODO: Add correct error handling, even though this should never be reached */
+    }
+#endif
     qemu_get_be64s(f, &env->spe_acc);
     qemu_get_be32s(f, &env->spe_fscr);
     qemu_get_betls(f, &env->msr_mask);
@@ -450,7 +463,16 @@ static int get_vscr(QEMUFile *f, void *opaque, size_t size,
                     const VMStateField *field)
 {
     PowerPCCPU *cpu = opaque;
+#if defined(CONFIG_KVM)
+    if(kvm_enabled()){
+        kvmppc_mtvscr(cpu, qemu_get_be32(f));
+        return 0;
+    }
+#endif /*CONFIG_KVM*/
+
+#if defined(CONFIG_TCG)
     helper_mtvscr(&cpu->env, qemu_get_be32(f));
+#endif /*CONFIG_TCG*/
     return 0;
 }
 
@@ -458,7 +480,16 @@ static int put_vscr(QEMUFile *f, void *opaque, size_t size,
                     const VMStateField *field, JSONWriter *vmdesc)
 {
     PowerPCCPU *cpu = opaque;
+#if defined(CONFIG_KVM)
+    if(kvm_enabled()){
+        qemu_put_be32(f, kvmppc_mfvscr(cpu));
+        return 0;
+    }
+#endif /*CONFIG_KVM*/
+
+#if defined(CONFIG_TCG)
     qemu_put_be32(f, helper_mfvscr(&cpu->env));
+#endif /*CONFIG_TCG*/
     return 0;
 }
 
-- 
2.17.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 3/4] target/ppc: Add stubs for tcg functions, so it builds
  2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
  2021-04-09 15:19 ` [PATCH 1/4] target/ppc: Code motion required to build disabling tcg Bruno Larsen (billionai)
  2021-04-09 15:19 ` [PATCH 2/4] target/ppc: added solutions for building with disable-tcg Bruno Larsen (billionai)
@ 2021-04-09 15:19 ` Bruno Larsen (billionai)
  2021-04-19  5:28   ` David Gibson
  2021-04-09 15:19 ` [PATCH 4/4] target/ppc: updated build rules for disable-tcg option Bruno Larsen (billionai)
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Bruno Larsen (billionai) @ 2021-04-09 15:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: lucas.araujo, lagarcia, luis.pires, fernando.valle, qemu-ppc,
	andre.silva, Bruno Larsen (billionai),
	matheus.ferst

This file basically adds all stubs required to build the project
with disable-tcg. most of these are not going to remain stubs by the
end, but this part is where it got complicated, and I wanted to get
an RFC ASAP. Most of these have to do with mmu emulation, so they'll
probably be replaced by a KVM implementation in the final product,
but I'm not sure which ones have to be replace, which can remain
stubs, and which should not be called at all. Input in general is
very much welcome.

Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
---
 target/ppc/tcg-stub.c | 139 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 target/ppc/tcg-stub.c

diff --git a/target/ppc/tcg-stub.c b/target/ppc/tcg-stub.c
new file mode 100644
index 0000000000..5dc8cf8911
--- /dev/null
+++ b/target/ppc/tcg-stub.c
@@ -0,0 +1,139 @@
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "mmu-hash64.h"
+
+/* STUFF FOR FIRST LINKER ERROR */
+/* This stuff happens in target/ppc files */
+
+#if !defined(CONFIG_USER_ONLY)
+
+void ppc_store_sdr1(CPUPPCState *env, target_ulong value) {
+    /* stub to make things compile */
+    return;
+}
+
+void ppc_store_ptcr(CPUPPCState *env, target_ulong value) {
+    /* stub to make things compile */
+    return;
+}
+
+#endif /* !defined(CONFIG_USER_ONLY) */
+void ppc_store_msr(CPUPPCState *env, target_ulong value) {
+    /* stub to make things compile */
+    return;
+}
+
+void dump_mmu(CPUPPCState *env){
+    /* stub to make things compile */
+    return;
+}
+
+void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) {
+    /* stub to make things compile */
+    return;
+}
+
+void ppc_cpu_do_interrupt(CPUState *cpu) {
+    /* stub to make things compile */
+    return;
+}
+
+/* STUFF FOR SECOND LINKER ERROR*/
+/* these errors happen mostly in hw/ppc */
+
+#ifdef TARGET_PPC64
+int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
+                  target_ulong esid, target_ulong vsid) {
+    /* rquired by kvm.c and machine.c */
+    return 0;
+}
+
+void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu,
+                                 bool (*cb)(void *, uint32_t, uint32_t),
+                                 void *opaque) {
+    /* required by spapr_caps.c */
+    return; 
+}
+
+void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) {
+    /* required by spapr_* */
+    return;
+}
+
+const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
+                                             hwaddr ptex, int n) {
+    /* used by spapr_hcall a bunch */
+    return NULL;
+}
+
+void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes,
+                            hwaddr ptex, int n) {
+    /* used a bunch by spapr_hcall */
+    return; 
+}
+
+void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
+                               target_ulong pte_index,
+                               target_ulong pte0, target_ulong pte1){
+    return; 
+}
+
+unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
+                                          uint64_t pte0, uint64_t pte1) {
+    return 0;
+}
+#endif
+
+void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) {
+    /* required by spapr_events spapr_mce_dispatch_elog */
+    return;
+}
+#ifndef CONFIG_USER_ONLY
+void ppc_cpu_do_system_reset(CPUState *cs){
+    /* required by pnv and spapr */
+    return;
+}
+#endif
+
+bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid,
+                       ppc_v3_pate_t *entry);
+
+bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid,
+                       ppc_v3_pate_t *entry) {
+    /* used by spapr_hcall: ppc_hash64_hpt_mask */
+    return true;
+}
+
+/* THIRD BATCH OF ERRORS, AFTER MOVING STUFF FROM TRANSLATE TO CPU.C */
+
+/* they are all coming from cpu.c, probably */
+
+void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) {
+    return;
+}
+
+void init_ppc_proc(PowerPCCPU *cpu) {
+    return;
+}
+
+void destroy_ppc_opcodes(PowerPCCPU *cpu) {
+    return;
+}
+
+void ppc_tlb_invalidate_all(CPUPPCState *env) {
+    return;
+}
+
+void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags) {
+    return;
+}
+
+void ppc_cpu_dump_statistics(CPUState *cpu, int flags) {
+    return;
+}
+
+#include "exec/hwaddr.h"
+
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) {
+    return 0;
+}
-- 
2.17.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 4/4] target/ppc: updated build rules for disable-tcg option
  2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
                   ` (2 preceding siblings ...)
  2021-04-09 15:19 ` [PATCH 3/4] target/ppc: Add stubs for tcg functions, so it builds Bruno Larsen (billionai)
@ 2021-04-09 15:19 ` Bruno Larsen (billionai)
  2021-04-09 15:57 ` [RFC PATCH 0/4] target/ppc: add " no-reply
  2021-04-12  4:32 ` David Gibson
  5 siblings, 0 replies; 15+ messages in thread
From: Bruno Larsen (billionai) @ 2021-04-09 15:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: lucas.araujo, lagarcia, luis.pires, fernando.valle, qemu-ppc,
	andre.silva, Bruno Larsen (billionai),
	matheus.ferst

updated the meson file to respect the disable-tcg option and only add
relevant files to the build process

Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
---
 target/ppc/meson.build | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/target/ppc/meson.build b/target/ppc/meson.build
index bbfef90e08..23f9346a6e 100644
--- a/target/ppc/meson.build
+++ b/target/ppc/meson.build
@@ -2,32 +2,40 @@ ppc_ss = ss.source_set()
 ppc_ss.add(files(
   'cpu-models.c',
   'cpu.c',
+  'gdbstub.c',
+))
+
+ppc_ss.add(libdecnumber)
+
+ppc_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
+ppc_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user_only_helper.c'))
+ppc_ss.add(when: 'CONFIG_TCG', if_true: files(
   'dfp_helper.c',
   'excp_helper.c',
   'fpu_helper.c',
-  'gdbstub.c',
   'int_helper.c',
   'mem_helper.c',
   'misc_helper.c',
   'timebase_helper.c',
   'translate.c',
-))
+), if_false: files('tcg-stub.c'))
 
-ppc_ss.add(libdecnumber)
-
-ppc_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
-ppc_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user_only_helper.c'))
 
 ppc_softmmu_ss = ss.source_set()
 ppc_softmmu_ss.add(files(
   'arch_dump.c',
   'machine.c',
+  'monitor.c',
+))
+ppc_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files(
   'mmu-hash32.c',
   'mmu_helper.c',
-  'monitor.c',
 ))
+
 ppc_softmmu_ss.add(when: 'TARGET_PPC64', if_true: files(
   'compat.c',
+))
+ppc_softmmu_ss.add(when: ['TARGET_PPC64', 'CONFIG_TCG'], if_true: files(
   'mmu-book3s-v3.c',
   'mmu-hash64.c',
   'mmu-radix64.c',
-- 
2.17.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 0/4] target/ppc: add disable-tcg option
  2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
                   ` (3 preceding siblings ...)
  2021-04-09 15:19 ` [PATCH 4/4] target/ppc: updated build rules for disable-tcg option Bruno Larsen (billionai)
@ 2021-04-09 15:57 ` no-reply
  2021-04-12  5:13   ` David Gibson
  2021-04-12  4:32 ` David Gibson
  5 siblings, 1 reply; 15+ messages in thread
From: no-reply @ 2021-04-09 15:57 UTC (permalink / raw)
  To: bruno.larsen
  Cc: qemu-devel, andre.silva, lucas.araujo, fernando.valle, qemu-ppc,
	lagarcia, bruno.larsen, matheus.ferst, luis.pires

Patchew URL: https://patchew.org/QEMU/20210409151916.97326-1-bruno.larsen@eldorado.org.br/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210409151916.97326-1-bruno.larsen@eldorado.org.br
Subject: [RFC PATCH 0/4] target/ppc: add disable-tcg option

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/161786467973.295167.5612704777283969903.stgit@bahia.lan -> patchew/161786467973.295167.5612704777283969903.stgit@bahia.lan
 - [tag update]      patchew/20210409150527.15053-1-peter.maydell@linaro.org -> patchew/20210409150527.15053-1-peter.maydell@linaro.org
 * [new tag]         patchew/20210409151916.97326-1-bruno.larsen@eldorado.org.br -> patchew/20210409151916.97326-1-bruno.larsen@eldorado.org.br
Switched to a new branch 'test'
0250bc9 target/ppc: updated build rules for disable-tcg option
e36c2a7 target/ppc: Add stubs for tcg functions, so it builds
4e6d44d target/ppc: added solutions for building with disable-tcg
38ccad3 target/ppc: Code motion required to build disabling tcg

=== OUTPUT BEGIN ===
1/4 Checking commit 38ccad308a44 (target/ppc: Code motion required to build disabling tcg)
2/4 Checking commit 4e6d44d2a68a (target/ppc: added solutions for building with disable-tcg)
WARNING: Block comments use a leading /* on a separate line
#43: FILE: target/ppc/arch_dump.c:182:
+    /* This is the first solution implemented. My personal favorite as it

WARNING: Block comments use a trailing */ on a separate line
#44: FILE: target/ppc/arch_dump.c:183:
+     * allows for explicit error handling, however it is much less readable */

ERROR: space required before the open brace '{'
#46: FILE: target/ppc/arch_dump.c:185:
+    if(kvm_enabled()){

ERROR: space required before the open parenthesis '('
#46: FILE: target/ppc/arch_dump.c:185:
+    if(kvm_enabled()){

ERROR: space required after that close brace '}'
#48: FILE: target/ppc/arch_dump.c:187:
+    }else

WARNING: line over 80 characters
#55: FILE: target/ppc/arch_dump.c:194:
+        /* TODO: add proper error handling, even tough this should never be reached */

ERROR: space required before the open brace '{'
#79: FILE: target/ppc/kvm.c:2953:
+int kvmppc_mtvscr(PowerPCCPU *cpu, uint32_t val){

ERROR: space required before the open brace '{'
#87: FILE: target/ppc/kvm.c:2961:
+    if(ret < 0){

ERROR: space required before the open parenthesis '('
#87: FILE: target/ppc/kvm.c:2961:
+    if(ret < 0){

ERROR: space required before the open brace '{'
#93: FILE: target/ppc/kvm.c:2967:
+int kvmppc_mfvscr(PowerPCCPU *cpu){

ERROR: space required before the open brace '{'
#101: FILE: target/ppc/kvm.c:2975:
+    if(ret < 0){

ERROR: space required before the open parenthesis '('
#101: FILE: target/ppc/kvm.c:2975:
+    if(ret < 0){

ERROR: "(foo*)" should be "(foo *)"
#115: FILE: target/ppc/kvm_ppc.h:90:
+int kvmppc_mfvscr(PowerPCCPU*);

WARNING: Block comments use a leading /* on a separate line
#117: FILE: target/ppc/kvm_ppc.h:92:
+/* This is the second (quick and dirty) solution. Not my personal favorite

WARNING: Block comments use a trailing */ on a separate line
#119: FILE: target/ppc/kvm_ppc.h:94:
+ * for error checking. but it requires less change in other files */

ERROR: space required after that ',' (ctx:VxV)
#121: FILE: target/ppc/kvm_ppc.h:96:
+#define helper_mtvscr(env, val) kvmppc_mtvscr(env_archcpu(env),val)
                                                               ^

ERROR: space required before the open brace '{'
#148: FILE: target/ppc/machine.c:101:
+    if(kvm_enabled()){

ERROR: space required before the open parenthesis '('
#148: FILE: target/ppc/machine.c:101:
+    if(kvm_enabled()){

ERROR: space required after that close brace '}'
#150: FILE: target/ppc/machine.c:103:
+    }else

WARNING: line over 80 characters
#156: FILE: target/ppc/machine.c:109:
+        /* TODO: Add correct error handling, even though this should never be reached */

ERROR: space required before the open brace '{'
#167: FILE: target/ppc/machine.c:467:
+    if(kvm_enabled()){

ERROR: space required before the open parenthesis '('
#167: FILE: target/ppc/machine.c:467:
+    if(kvm_enabled()){

ERROR: space required before the open brace '{'
#184: FILE: target/ppc/machine.c:484:
+    if(kvm_enabled()){

ERROR: space required before the open parenthesis '('
#184: FILE: target/ppc/machine.c:484:
+    if(kvm_enabled()){

total: 18 errors, 6 warnings, 147 lines checked

Patch 2/4 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

3/4 Checking commit e36c2a70087a (target/ppc: Add stubs for tcg functions, so it builds)
Use of uninitialized value $acpi_testexpected in string eq at ./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#23: 
new file mode 100644

ERROR: open brace '{' following function declarations go on the next line
#37: FILE: target/ppc/tcg-stub.c:10:
+void ppc_store_sdr1(CPUPPCState *env, target_ulong value) {

ERROR: open brace '{' following function declarations go on the next line
#42: FILE: target/ppc/tcg-stub.c:15:
+void ppc_store_ptcr(CPUPPCState *env, target_ulong value) {

ERROR: open brace '{' following function declarations go on the next line
#48: FILE: target/ppc/tcg-stub.c:21:
+void ppc_store_msr(CPUPPCState *env, target_ulong value) {

ERROR: space required before the open brace '{'
#53: FILE: target/ppc/tcg-stub.c:26:
+void dump_mmu(CPUPPCState *env){

ERROR: open brace '{' following function declarations go on the next line
#58: FILE: target/ppc/tcg-stub.c:31:
+void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) {

ERROR: open brace '{' following function declarations go on the next line
#63: FILE: target/ppc/tcg-stub.c:36:
+void ppc_cpu_do_interrupt(CPUState *cpu) {

ERROR: trailing whitespace
#82: FILE: target/ppc/tcg-stub.c:55:
+    return; $

ERROR: open brace '{' following function declarations go on the next line
#85: FILE: target/ppc/tcg-stub.c:58:
+void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) {

ERROR: trailing whitespace
#99: FILE: target/ppc/tcg-stub.c:72:
+    return; $

ERROR: trailing whitespace
#105: FILE: target/ppc/tcg-stub.c:78:
+    return; $

ERROR: open brace '{' following function declarations go on the next line
#114: FILE: target/ppc/tcg-stub.c:87:
+void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) {

ERROR: space required before the open brace '{'
#119: FILE: target/ppc/tcg-stub.c:92:
+void ppc_cpu_do_system_reset(CPUState *cs){

ERROR: externs should be avoided in .c files
#125: FILE: target/ppc/tcg-stub.c:98:
+bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid,

ERROR: open brace '{' following function declarations go on the next line
#138: FILE: target/ppc/tcg-stub.c:111:
+void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) {

ERROR: open brace '{' following function declarations go on the next line
#142: FILE: target/ppc/tcg-stub.c:115:
+void init_ppc_proc(PowerPCCPU *cpu) {

ERROR: open brace '{' following function declarations go on the next line
#146: FILE: target/ppc/tcg-stub.c:119:
+void destroy_ppc_opcodes(PowerPCCPU *cpu) {

ERROR: open brace '{' following function declarations go on the next line
#150: FILE: target/ppc/tcg-stub.c:123:
+void ppc_tlb_invalidate_all(CPUPPCState *env) {

ERROR: open brace '{' following function declarations go on the next line
#154: FILE: target/ppc/tcg-stub.c:127:
+void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags) {

ERROR: open brace '{' following function declarations go on the next line
#158: FILE: target/ppc/tcg-stub.c:131:
+void ppc_cpu_dump_statistics(CPUState *cpu, int flags) {

ERROR: open brace '{' following function declarations go on the next line
#164: FILE: target/ppc/tcg-stub.c:137:
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) {

total: 20 errors, 1 warnings, 139 lines checked

Patch 3/4 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

4/4 Checking commit 0250bc923e4d (target/ppc: updated build rules for disable-tcg option)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210409151916.97326-1-bruno.larsen@eldorado.org.br/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/4] target/ppc: Code motion required to build disabling tcg
  2021-04-09 15:19 ` [PATCH 1/4] target/ppc: Code motion required to build disabling tcg Bruno Larsen (billionai)
@ 2021-04-09 19:48   ` Fabiano Rosas
  2021-04-12  4:34     ` David Gibson
  0 siblings, 1 reply; 15+ messages in thread
From: Fabiano Rosas @ 2021-04-09 19:48 UTC (permalink / raw)
  To: Bruno Larsen (billionai), qemu-devel
  Cc: luis.pires, andre.silva, lucas.araujo, fernando.valle, qemu-ppc,
	lagarcia, Bruno Larsen (billionai),
	matheus.ferst

"Bruno Larsen (billionai)" <bruno.larsen@eldorado.org.br> writes:

A general advice for this whole series is: make sure you add in some
words explaining why you decided to make a particular change. It will be
much easier to review if we know what were the logical steps leading to
the change.

> This commit does the necessary code motion from translate_init.c.inc

For instance, I don't immediately see why these changes are necessary. I
see that translate_init.c.inc already has some `#ifdef CONFIG_TCG`, so
why do we need to move a bunch of code into cpu.c instead of just adding
more code under ifdef CONFIG_TCG? (I'm not saying it's wrong, just trying to
understand the reasoning).

Is translate_init.c.inc intended to be TCG only? But then I see you
moved TCG-only functions out of it (ppc_fixup_cpu) and left not TCG-only
functions (gen_spr_generic).

> This moves all functions that start with gdb_* into target/ppc/gdbstub.c
> and creates a new function that calls those and is called by ppc_cpu_realize

This looks like it makes sense regardless of disable-tcg, could we have
it in a standalone patch?

> All functions related to realizing the cpu have been moved to cpu.c, which
> may call functions from gdbstub or translate_init

Again, I don't disagree with this, but at first sight it doesn't seem
entirely related to disabling TCG.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/4] target/ppc: added solutions for building with disable-tcg
  2021-04-09 15:19 ` [PATCH 2/4] target/ppc: added solutions for building with disable-tcg Bruno Larsen (billionai)
@ 2021-04-09 20:40   ` Fabiano Rosas
  2021-04-12  5:08   ` David Gibson
  1 sibling, 0 replies; 15+ messages in thread
From: Fabiano Rosas @ 2021-04-09 20:40 UTC (permalink / raw)
  To: Bruno Larsen (billionai), qemu-devel
  Cc: luis.pires, andre.silva, lucas.araujo, fernando.valle, qemu-ppc,
	lagarcia, Bruno Larsen (billionai),
	matheus.ferst

"Bruno Larsen (billionai)" <bruno.larsen@eldorado.org.br> writes:

> this commit presents 2 possible solutions for substituting TCG emulation
> with KVM calls. One - used in machine.c and arch_dump.c - explicitly

As I mentioned in my reply to your introductory email I don't think we
should be replacing TCG routines with calls into KVM. Because that would
mean we have been up until now running KVM-supporting code but relying
on TCG routines which would (aside the most simple functions) be
wrong. The whole KVM runs natively, TCG is translated deal.

I don't see what in the vscr helpers makes them TCG-only. They seem like
they would work just fine with KVM code. The kvm_arch_get/put_registers
functions should already take care of synchronizing the CPUPPCState with
KVM.

Does that make sense? Tell me if I'm missing something. =)

> adds the KVM function and has the possibility of adding the TCG one
> for more generic compilation, prioritizing te KVM option. The second
> option, implemented in kvm_ppc.h, transparently changes the helper
> into the KVM call, if TCG is not enabled. I believe the first solution
> is better, but it is less readable, so I wanted to have some feedback
>
> Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> ---
>  target/ppc/arch_dump.c | 17 +++++++++++++++++
>  target/ppc/kvm.c       | 30 ++++++++++++++++++++++++++++++
>  target/ppc/kvm_ppc.h   | 11 +++++++++++
>  target/ppc/machine.c   | 33 ++++++++++++++++++++++++++++++++-
>  4 files changed, 90 insertions(+), 1 deletion(-)
>
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 9ab04b2c38..c53e01011a 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -17,7 +17,10 @@
>  #include "elf.h"
>  #include "sysemu/dump.h"
>  #include "sysemu/kvm.h"
> +#include "kvm_ppc.h"
> +#if defined(CONFIG_TCG)
>  #include "exec/helper-proto.h"
> +#endif /* CONFIG_TCG */
>  
>  #ifdef TARGET_PPC64
>  #define ELFCLASS ELFCLASS64
> @@ -176,7 +179,21 @@ static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>              vmxregset->avr[i].u64[1] = avr->u64[1];
>          }
>      }
> +    /* This is the first solution implemented. My personal favorite as it
> +     * allows for explicit error handling, however it is much less readable */
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        vmxregset->vscr.u32[3] = cpu_to_dump32(s, kvmppc_mfvscr(cpu));
> +    }else
> +#endif
> +
> +#if defined(CONFIG_TCG)
>      vmxregset->vscr.u32[3] = cpu_to_dump32(s, helper_mfvscr(&cpu->env));
> +#else
> +    {
> +        /* TODO: add proper error handling, even tough this should never be reached */
> +    }
> +#endif
>  }
>  
>  static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 104a308abb..8ed54d12d8 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -51,6 +51,7 @@
>  #include "elf.h"
>  #include "sysemu/kvm_int.h"
>  
> +
>  #define PROC_DEVTREE_CPU      "/proc/device-tree/cpus/"
>  
>  #define DEBUG_RETURN_GUEST 0
> @@ -2947,3 +2948,32 @@ bool kvm_arch_cpu_check_are_resettable(void)
>  {
>      return true;
>  }
> +
> +/* Functions added to replace helper_m(t|f)vscr from int_helper.c */
> +int kvmppc_mtvscr(PowerPCCPU *cpu, uint32_t val){
> +    CPUState *cs = CPU(cpu);
> +    CPUPPCState *env = &cpu->env;
> +    struct kvm_one_reg reg;
> +    int ret;
> +    reg.id = KVM_REG_PPC_VSCR;
> +    reg.addr = (uintptr_t) &env->vscr;
> +    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
> +    if(ret < 0){
> +        fprintf(stderr, "Unable to set VSCR to KVM: %s", strerror(errno));
> +    }
> +    return ret;
> +}
> +
> +int kvmppc_mfvscr(PowerPCCPU *cpu){
> +    CPUState *cs = CPU(cpu);
> +    CPUPPCState *env = &cpu->env;
> +    struct kvm_one_reg reg;
> +    int ret;
> +    reg.id = KVM_REG_PPC_VSCR;
> +    reg.addr = (uintptr_t) &env->vscr;
> +    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
> +    if(ret < 0){
> +        fprintf(stderr, "Unable to get VSCR to KVM: %s", strerror(errno));
> +    }
> +    return ret;
> +}
> diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
> index 989f61ace0..f618cb28b1 100644
> --- a/target/ppc/kvm_ppc.h
> +++ b/target/ppc/kvm_ppc.h
> @@ -86,6 +86,17 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset);
>  
>  int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run);
>  
> +int kvmppc_mtvscr(PowerPCCPU*, uint32_t);
> +int kvmppc_mfvscr(PowerPCCPU*);
> +
> +/* This is the second (quick and dirty) solution. Not my personal favorite
> + * as it hides what is actually happening from the user and doesn't allow
> + * for error checking. but it requires less change in other files */
> +#ifndef CONFIG_TCG
> +#define helper_mtvscr(env, val) kvmppc_mtvscr(env_archcpu(env),val)
> +#define helper_mfvscr(env) kvmppc_mfvscr(env_archcpu(env))
> +#endif
> +
>  #else
>  
>  static inline uint32_t kvmppc_get_tbfreq(void)
> diff --git a/target/ppc/machine.c b/target/ppc/machine.c
> index 283db1d28a..d92bc18859 100644
> --- a/target/ppc/machine.c
> +++ b/target/ppc/machine.c
> @@ -8,7 +8,9 @@
>  #include "qapi/error.h"
>  #include "qemu/main-loop.h"
>  #include "kvm_ppc.h"
> +#ifdef CONFIG_TCG
>  #include "exec/helper-proto.h"
> +#endif /*CONFIG_TCG*/
>  
>  static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
>  {
> @@ -95,7 +97,18 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
>          ppc_store_sdr1(env, sdr1);
>      }
>      qemu_get_be32s(f, &vscr);
> -    helper_mtvscr(env, vscr);
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        kvmppc_mtvscr(cpu, vscr);
> +    }else
> +#endif
> +#if defined(CONFIG_TCG)
> +        helper_mtvscr(env, vscr);
> +#else
> +    {
> +        /* TODO: Add correct error handling, even though this should never be reached */
> +    }
> +#endif
>      qemu_get_be64s(f, &env->spe_acc);
>      qemu_get_be32s(f, &env->spe_fscr);
>      qemu_get_betls(f, &env->msr_mask);
> @@ -450,7 +463,16 @@ static int get_vscr(QEMUFile *f, void *opaque, size_t size,
>                      const VMStateField *field)
>  {
>      PowerPCCPU *cpu = opaque;
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        kvmppc_mtvscr(cpu, qemu_get_be32(f));
> +        return 0;
> +    }
> +#endif /*CONFIG_KVM*/
> +
> +#if defined(CONFIG_TCG)
>      helper_mtvscr(&cpu->env, qemu_get_be32(f));
> +#endif /*CONFIG_TCG*/
>      return 0;
>  }
>  
> @@ -458,7 +480,16 @@ static int put_vscr(QEMUFile *f, void *opaque, size_t size,
>                      const VMStateField *field, JSONWriter *vmdesc)
>  {
>      PowerPCCPU *cpu = opaque;
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        qemu_put_be32(f, kvmppc_mfvscr(cpu));
> +        return 0;
> +    }
> +#endif /*CONFIG_KVM*/
> +
> +#if defined(CONFIG_TCG)
>      qemu_put_be32(f, helper_mfvscr(&cpu->env));
> +#endif /*CONFIG_TCG*/
>      return 0;
>  }


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 0/4] target/ppc: add disable-tcg option
  2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
                   ` (4 preceding siblings ...)
  2021-04-09 15:57 ` [RFC PATCH 0/4] target/ppc: add " no-reply
@ 2021-04-12  4:32 ` David Gibson
  5 siblings, 0 replies; 15+ messages in thread
From: David Gibson @ 2021-04-12  4:32 UTC (permalink / raw)
  To: Bruno Larsen (billionai)
  Cc: qemu-devel, andre.silva, lucas.araujo, fernando.valle, qemu-ppc,
	lagarcia, matheus.ferst, luis.pires

[-- Attachment #1: Type: text/plain, Size: 2067 bytes --]

For future reference, please CC me explicitly on things you'd like me
to review.  I do scan the qemu-ppc@nongnu.org list, but it makes it
easier for me to find (and less likely that I'll accidentally overlook
it) if I'm also CCed directly.

On Fri, Apr 09, 2021 at 12:19:12PM -0300, Bruno Larsen (billionai) wrote:
> This patch series aims to add the option to build without TCG for the
> powerpc target. This RFC shows mostly the strategies employed when
> dealing with compilation problems, and ask for input on the bits
> we don't quite understand yet.
> 
> The first patch mostly code motion, as referenced in 2021-04/msg0717.
> The second patch shows the 2 strategies we've considered, and hope to
> get feedback on. The third patch contains the stubs we haven't decided
> on how to deal with yet, but needed to exist to compile the project.
> The final patch just changes the meson.build rules
> 
> Bruno Larsen (billionai) (4):
>   target/ppc: Code motion required to build disabling tcg
>   target/ppc: added solutions for problems encountered when building
>     with disable-tcg
>   target/ppc: Add stubs for tcg functions, so it build with disable-tcg
>   target/ppc: updated build rules for disable-tcg option
> 
>  target/ppc/arch_dump.c          |   17 +
>  target/ppc/cpu.c                |  859 +++++++++++++++++++++++
>  target/ppc/cpu.h                |   15 +
>  target/ppc/gdbstub.c            |  253 +++++++
>  target/ppc/kvm.c                |   30 +
>  target/ppc/kvm_ppc.h            |   11 +
>  target/ppc/machine.c            |   33 +-
>  target/ppc/meson.build          |   22 +-
>  target/ppc/tcg-stub.c           |  139 ++++
>  target/ppc/translate_init.c.inc | 1148 +------------------------------
>  10 files changed, 1407 insertions(+), 1120 deletions(-)
>  create mode 100644 target/ppc/tcg-stub.c
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1/4] target/ppc: Code motion required to build disabling tcg
  2021-04-09 19:48   ` Fabiano Rosas
@ 2021-04-12  4:34     ` David Gibson
  0 siblings, 0 replies; 15+ messages in thread
From: David Gibson @ 2021-04-12  4:34 UTC (permalink / raw)
  To: Fabiano Rosas
  Cc: lucas.araujo, qemu-devel, lagarcia, luis.pires, fernando.valle,
	qemu-ppc, andre.silva, Bruno Larsen (billionai),
	matheus.ferst

[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]

On Fri, Apr 09, 2021 at 04:48:41PM -0300, Fabiano Rosas wrote:
> "Bruno Larsen (billionai)" <bruno.larsen@eldorado.org.br> writes:
> 
> A general advice for this whole series is: make sure you add in some
> words explaining why you decided to make a particular change. It will be
> much easier to review if we know what were the logical steps leading to
> the change.
> 
> > This commit does the necessary code motion from translate_init.c.inc
> 
> For instance, I don't immediately see why these changes are necessary. I
> see that translate_init.c.inc already has some `#ifdef CONFIG_TCG`, so
> why do we need to move a bunch of code into cpu.c instead of just adding
> more code under ifdef CONFIG_TCG? (I'm not saying it's wrong, just trying to
> understand the reasoning).
> 
> Is translate_init.c.inc intended to be TCG only? But then I see you
> moved TCG-only functions out of it (ppc_fixup_cpu) and left not TCG-only
> functions (gen_spr_generic).
> 
> > This moves all functions that start with gdb_* into target/ppc/gdbstub.c
> > and creates a new function that calls those and is called by ppc_cpu_realize
> 
> This looks like it makes sense regardless of disable-tcg, could we have
> it in a standalone patch?
> 
> > All functions related to realizing the cpu have been moved to cpu.c, which
> > may call functions from gdbstub or translate_init
> 
> Again, I don't disagree with this, but at first sight it doesn't seem
> entirely related to disabling TCG.

Fabioano's points seconded.  This isn't necessarily a bad idea, but a
rationale would really help.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/4] target/ppc: added solutions for building with disable-tcg
  2021-04-09 15:19 ` [PATCH 2/4] target/ppc: added solutions for building with disable-tcg Bruno Larsen (billionai)
  2021-04-09 20:40   ` Fabiano Rosas
@ 2021-04-12  5:08   ` David Gibson
  2021-04-12 15:40     ` Richard Henderson
  1 sibling, 1 reply; 15+ messages in thread
From: David Gibson @ 2021-04-12  5:08 UTC (permalink / raw)
  To: Bruno Larsen (billionai)
  Cc: qemu-devel, andre.silva, lucas.araujo, fernando.valle, qemu-ppc,
	lagarcia, matheus.ferst, luis.pires

[-- Attachment #1: Type: text/plain, Size: 7413 bytes --]

On Fri, Apr 09, 2021 at 12:19:14PM -0300, Bruno Larsen (billionai) wrote:
> this commit presents 2 possible solutions for substituting TCG emulation
> with KVM calls. One - used in machine.c and arch_dump.c - explicitly
> adds the KVM function and has the possibility of adding the TCG one
> for more generic compilation, prioritizing te KVM option. The second
> option, implemented in kvm_ppc.h, transparently changes the helper
> into the KVM call, if TCG is not enabled. I believe the first solution
> is better, but it is less readable, so I wanted to have some feedback
> 
> Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> ---
>  target/ppc/arch_dump.c | 17 +++++++++++++++++
>  target/ppc/kvm.c       | 30 ++++++++++++++++++++++++++++++
>  target/ppc/kvm_ppc.h   | 11 +++++++++++
>  target/ppc/machine.c   | 33 ++++++++++++++++++++++++++++++++-
>  4 files changed, 90 insertions(+), 1 deletion(-)
> 
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 9ab04b2c38..c53e01011a 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -17,7 +17,10 @@
>  #include "elf.h"
>  #include "sysemu/dump.h"
>  #include "sysemu/kvm.h"
> +#include "kvm_ppc.h"
> +#if defined(CONFIG_TCG)
>  #include "exec/helper-proto.h"
> +#endif /* CONFIG_TCG */
>  
>  #ifdef TARGET_PPC64
>  #define ELFCLASS ELFCLASS64
> @@ -176,7 +179,21 @@ static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
>              vmxregset->avr[i].u64[1] = avr->u64[1];
>          }
>      }
> +    /* This is the first solution implemented. My personal favorite as it
> +     * allows for explicit error handling, however it is much less readable */
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        vmxregset->vscr.u32[3] = cpu_to_dump32(s, kvmppc_mfvscr(cpu));
> +    }else
> +#endif
> +
> +#if defined(CONFIG_TCG)
>      vmxregset->vscr.u32[3] = cpu_to_dump32(s, helper_mfvscr(&cpu->env));
> +#else
> +    {
> +        /* TODO: add proper error handling, even tough this should never be reached */
> +    }
> +#endif

I think this is more complex than you need.  AFAICT, the logic in
helper_mfcsvr() is still valid even without TCG (we still have a copy
of the state in 'env' with KVM).

You could move helper_mfvscr() to a file that isn't going to get
excluded for !TCG builds.

Not directly related to what you're trying to accomplish here, but the
whole vscr_sat thing looks really weird.  I have no idea why we're
splitting out the storage of VSCR[SAT] for the TCG case at all.  If
you wanted to clean that up as a preliminary, I'd be grateful.

>  }
>  
>  static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 104a308abb..8ed54d12d8 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -51,6 +51,7 @@
>  #include "elf.h"
>  #include "sysemu/kvm_int.h"
>  
> +
>  #define PROC_DEVTREE_CPU      "/proc/device-tree/cpus/"
>  
>  #define DEBUG_RETURN_GUEST 0
> @@ -2947,3 +2948,32 @@ bool kvm_arch_cpu_check_are_resettable(void)
>  {
>      return true;
>  }
> +
> +/* Functions added to replace helper_m(t|f)vscr from int_helper.c */
> +int kvmppc_mtvscr(PowerPCCPU *cpu, uint32_t val){
> +    CPUState *cs = CPU(cpu);
> +    CPUPPCState *env = &cpu->env;
> +    struct kvm_one_reg reg;
> +    int ret;
> +    reg.id = KVM_REG_PPC_VSCR;
> +    reg.addr = (uintptr_t) &env->vscr;
> +    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
> +    if(ret < 0){
> +        fprintf(stderr, "Unable to set VSCR to KVM: %s", strerror(errno));
> +    }
> +    return ret;
> +}
> +
> +int kvmppc_mfvscr(PowerPCCPU *cpu){
> +    CPUState *cs = CPU(cpu);
> +    CPUPPCState *env = &cpu->env;
> +    struct kvm_one_reg reg;
> +    int ret;
> +    reg.id = KVM_REG_PPC_VSCR;
> +    reg.addr = (uintptr_t) &env->vscr;
> +    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
> +    if(ret < 0){
> +        fprintf(stderr, "Unable to get VSCR to KVM: %s", strerror(errno));
> +    }
> +    return ret;
> +}
> diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
> index 989f61ace0..f618cb28b1 100644
> --- a/target/ppc/kvm_ppc.h
> +++ b/target/ppc/kvm_ppc.h
> @@ -86,6 +86,17 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset);
>  
>  int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run);
>  
> +int kvmppc_mtvscr(PowerPCCPU*, uint32_t);
> +int kvmppc_mfvscr(PowerPCCPU*);
> +
> +/* This is the second (quick and dirty) solution. Not my personal favorite
> + * as it hides what is actually happening from the user and doesn't allow
> + * for error checking. but it requires less change in other files */
> +#ifndef CONFIG_TCG
> +#define helper_mtvscr(env, val) kvmppc_mtvscr(env_archcpu(env),val)
> +#define helper_mfvscr(env) kvmppc_mfvscr(env_archcpu(env))
> +#endif
> +
>  #else
>  
>  static inline uint32_t kvmppc_get_tbfreq(void)
> diff --git a/target/ppc/machine.c b/target/ppc/machine.c
> index 283db1d28a..d92bc18859 100644
> --- a/target/ppc/machine.c
> +++ b/target/ppc/machine.c
> @@ -8,7 +8,9 @@
>  #include "qapi/error.h"
>  #include "qemu/main-loop.h"
>  #include "kvm_ppc.h"
> +#ifdef CONFIG_TCG
>  #include "exec/helper-proto.h"
> +#endif /*CONFIG_TCG*/
>  
>  static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
>  {
> @@ -95,7 +97,18 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
>          ppc_store_sdr1(env, sdr1);
>      }
>      qemu_get_be32s(f, &vscr);
> -    helper_mtvscr(env, vscr);

Likewise here, the existing helper_mtvscr() is fine (if perhaps more
complex than necessary), so you don't need separate paths here.

> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        kvmppc_mtvscr(cpu, vscr);
> +    }else
> +#endif
> +#if defined(CONFIG_TCG)
> +        helper_mtvscr(env, vscr);
> +#else
> +    {
> +        /* TODO: Add correct error handling, even though this should never be reached */
> +    }
> +#endif
>      qemu_get_be64s(f, &env->spe_acc);
>      qemu_get_be32s(f, &env->spe_fscr);
>      qemu_get_betls(f, &env->msr_mask);
> @@ -450,7 +463,16 @@ static int get_vscr(QEMUFile *f, void *opaque, size_t size,
>                      const VMStateField *field)
>  {
>      PowerPCCPU *cpu = opaque;
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        kvmppc_mtvscr(cpu, qemu_get_be32(f));
> +        return 0;
> +    }
> +#endif /*CONFIG_KVM*/
> +
> +#if defined(CONFIG_TCG)
>      helper_mtvscr(&cpu->env, qemu_get_be32(f));
> +#endif /*CONFIG_TCG*/
>      return 0;
>  }
>  
> @@ -458,7 +480,16 @@ static int put_vscr(QEMUFile *f, void *opaque, size_t size,
>                      const VMStateField *field, JSONWriter *vmdesc)
>  {
>      PowerPCCPU *cpu = opaque;
> +#if defined(CONFIG_KVM)
> +    if(kvm_enabled()){
> +        qemu_put_be32(f, kvmppc_mfvscr(cpu));
> +        return 0;
> +    }
> +#endif /*CONFIG_KVM*/
> +
> +#if defined(CONFIG_TCG)
>      qemu_put_be32(f, helper_mfvscr(&cpu->env));
> +#endif /*CONFIG_TCG*/
>      return 0;
>  }
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 0/4] target/ppc: add disable-tcg option
  2021-04-09 15:57 ` [RFC PATCH 0/4] target/ppc: add " no-reply
@ 2021-04-12  5:13   ` David Gibson
  0 siblings, 0 replies; 15+ messages in thread
From: David Gibson @ 2021-04-12  5:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: luis.pires, lagarcia, lucas.araujo, fernando.valle, qemu-ppc,
	andre.silva, bruno.larsen, matheus.ferst

[-- Attachment #1: Type: text/plain, Size: 10166 bytes --]

On Fri, Apr 09, 2021 at 08:57:48AM -0700, no-reply@patchew.org wrote:
> Patchew URL: https://patchew.org/QEMU/20210409151916.97326-1-bruno.larsen@eldorado.org.br/
> 
> 
> 
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:
> 
> Type: series
> Message-id: 20210409151916.97326-1-bruno.larsen@eldorado.org.br
> Subject: [RFC PATCH 0/4] target/ppc: add disable-tcg option

You will need to fix these style errors.

Note that there's quite a bit of existing code in target-ppc which
doesn't have current-correct qemu style.  Despite this, please make
any changes in a checkpatch happy style - the hope is that we'll
gradually convert the legacy pieces to updated style.

> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> git rev-parse base > /dev/null || exit 0
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
> ./scripts/checkpatch.pl --mailback base..
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
>  - [tag update]      patchew/161786467973.295167.5612704777283969903.stgit@bahia.lan -> patchew/161786467973.295167.5612704777283969903.stgit@bahia.lan
>  - [tag update]      patchew/20210409150527.15053-1-peter.maydell@linaro.org -> patchew/20210409150527.15053-1-peter.maydell@linaro.org
>  * [new tag]         patchew/20210409151916.97326-1-bruno.larsen@eldorado.org.br -> patchew/20210409151916.97326-1-bruno.larsen@eldorado.org.br
> Switched to a new branch 'test'
> 0250bc9 target/ppc: updated build rules for disable-tcg option
> e36c2a7 target/ppc: Add stubs for tcg functions, so it builds
> 4e6d44d target/ppc: added solutions for building with disable-tcg
> 38ccad3 target/ppc: Code motion required to build disabling tcg
> 
> === OUTPUT BEGIN ===
> 1/4 Checking commit 38ccad308a44 (target/ppc: Code motion required to build disabling tcg)
> 2/4 Checking commit 4e6d44d2a68a (target/ppc: added solutions for building with disable-tcg)
> WARNING: Block comments use a leading /* on a separate line
> #43: FILE: target/ppc/arch_dump.c:182:
> +    /* This is the first solution implemented. My personal favorite as it
> 
> WARNING: Block comments use a trailing */ on a separate line
> #44: FILE: target/ppc/arch_dump.c:183:
> +     * allows for explicit error handling, however it is much less readable */
> 
> ERROR: space required before the open brace '{'
> #46: FILE: target/ppc/arch_dump.c:185:
> +    if(kvm_enabled()){
> 
> ERROR: space required before the open parenthesis '('
> #46: FILE: target/ppc/arch_dump.c:185:
> +    if(kvm_enabled()){
> 
> ERROR: space required after that close brace '}'
> #48: FILE: target/ppc/arch_dump.c:187:
> +    }else
> 
> WARNING: line over 80 characters
> #55: FILE: target/ppc/arch_dump.c:194:
> +        /* TODO: add proper error handling, even tough this should never be reached */
> 
> ERROR: space required before the open brace '{'
> #79: FILE: target/ppc/kvm.c:2953:
> +int kvmppc_mtvscr(PowerPCCPU *cpu, uint32_t val){
> 
> ERROR: space required before the open brace '{'
> #87: FILE: target/ppc/kvm.c:2961:
> +    if(ret < 0){
> 
> ERROR: space required before the open parenthesis '('
> #87: FILE: target/ppc/kvm.c:2961:
> +    if(ret < 0){
> 
> ERROR: space required before the open brace '{'
> #93: FILE: target/ppc/kvm.c:2967:
> +int kvmppc_mfvscr(PowerPCCPU *cpu){
> 
> ERROR: space required before the open brace '{'
> #101: FILE: target/ppc/kvm.c:2975:
> +    if(ret < 0){
> 
> ERROR: space required before the open parenthesis '('
> #101: FILE: target/ppc/kvm.c:2975:
> +    if(ret < 0){
> 
> ERROR: "(foo*)" should be "(foo *)"
> #115: FILE: target/ppc/kvm_ppc.h:90:
> +int kvmppc_mfvscr(PowerPCCPU*);
> 
> WARNING: Block comments use a leading /* on a separate line
> #117: FILE: target/ppc/kvm_ppc.h:92:
> +/* This is the second (quick and dirty) solution. Not my personal favorite
> 
> WARNING: Block comments use a trailing */ on a separate line
> #119: FILE: target/ppc/kvm_ppc.h:94:
> + * for error checking. but it requires less change in other files */
> 
> ERROR: space required after that ',' (ctx:VxV)
> #121: FILE: target/ppc/kvm_ppc.h:96:
> +#define helper_mtvscr(env, val) kvmppc_mtvscr(env_archcpu(env),val)
>                                                                ^
> 
> ERROR: space required before the open brace '{'
> #148: FILE: target/ppc/machine.c:101:
> +    if(kvm_enabled()){
> 
> ERROR: space required before the open parenthesis '('
> #148: FILE: target/ppc/machine.c:101:
> +    if(kvm_enabled()){
> 
> ERROR: space required after that close brace '}'
> #150: FILE: target/ppc/machine.c:103:
> +    }else
> 
> WARNING: line over 80 characters
> #156: FILE: target/ppc/machine.c:109:
> +        /* TODO: Add correct error handling, even though this should never be reached */
> 
> ERROR: space required before the open brace '{'
> #167: FILE: target/ppc/machine.c:467:
> +    if(kvm_enabled()){
> 
> ERROR: space required before the open parenthesis '('
> #167: FILE: target/ppc/machine.c:467:
> +    if(kvm_enabled()){
> 
> ERROR: space required before the open brace '{'
> #184: FILE: target/ppc/machine.c:484:
> +    if(kvm_enabled()){
> 
> ERROR: space required before the open parenthesis '('
> #184: FILE: target/ppc/machine.c:484:
> +    if(kvm_enabled()){
> 
> total: 18 errors, 6 warnings, 147 lines checked
> 
> Patch 2/4 has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> 3/4 Checking commit e36c2a70087a (target/ppc: Add stubs for tcg functions, so it builds)
> Use of uninitialized value $acpi_testexpected in string eq at ./scripts/checkpatch.pl line 1529.
> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
> #23: 
> new file mode 100644
> 
> ERROR: open brace '{' following function declarations go on the next line
> #37: FILE: target/ppc/tcg-stub.c:10:
> +void ppc_store_sdr1(CPUPPCState *env, target_ulong value) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #42: FILE: target/ppc/tcg-stub.c:15:
> +void ppc_store_ptcr(CPUPPCState *env, target_ulong value) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #48: FILE: target/ppc/tcg-stub.c:21:
> +void ppc_store_msr(CPUPPCState *env, target_ulong value) {
> 
> ERROR: space required before the open brace '{'
> #53: FILE: target/ppc/tcg-stub.c:26:
> +void dump_mmu(CPUPPCState *env){
> 
> ERROR: open brace '{' following function declarations go on the next line
> #58: FILE: target/ppc/tcg-stub.c:31:
> +void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #63: FILE: target/ppc/tcg-stub.c:36:
> +void ppc_cpu_do_interrupt(CPUState *cpu) {
> 
> ERROR: trailing whitespace
> #82: FILE: target/ppc/tcg-stub.c:55:
> +    return; $
> 
> ERROR: open brace '{' following function declarations go on the next line
> #85: FILE: target/ppc/tcg-stub.c:58:
> +void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) {
> 
> ERROR: trailing whitespace
> #99: FILE: target/ppc/tcg-stub.c:72:
> +    return; $
> 
> ERROR: trailing whitespace
> #105: FILE: target/ppc/tcg-stub.c:78:
> +    return; $
> 
> ERROR: open brace '{' following function declarations go on the next line
> #114: FILE: target/ppc/tcg-stub.c:87:
> +void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) {
> 
> ERROR: space required before the open brace '{'
> #119: FILE: target/ppc/tcg-stub.c:92:
> +void ppc_cpu_do_system_reset(CPUState *cs){
> 
> ERROR: externs should be avoided in .c files
> #125: FILE: target/ppc/tcg-stub.c:98:
> +bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid,
> 
> ERROR: open brace '{' following function declarations go on the next line
> #138: FILE: target/ppc/tcg-stub.c:111:
> +void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #142: FILE: target/ppc/tcg-stub.c:115:
> +void init_ppc_proc(PowerPCCPU *cpu) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #146: FILE: target/ppc/tcg-stub.c:119:
> +void destroy_ppc_opcodes(PowerPCCPU *cpu) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #150: FILE: target/ppc/tcg-stub.c:123:
> +void ppc_tlb_invalidate_all(CPUPPCState *env) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #154: FILE: target/ppc/tcg-stub.c:127:
> +void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #158: FILE: target/ppc/tcg-stub.c:131:
> +void ppc_cpu_dump_statistics(CPUState *cpu, int flags) {
> 
> ERROR: open brace '{' following function declarations go on the next line
> #164: FILE: target/ppc/tcg-stub.c:137:
> +hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) {
> 
> total: 20 errors, 1 warnings, 139 lines checked
> 
> Patch 3/4 has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> 4/4 Checking commit 0250bc923e4d (target/ppc: updated build rules for disable-tcg option)
> === OUTPUT END ===
> 
> Test command exited with code: 1
> 
> 
> The full log is available at
> http://patchew.org/logs/20210409151916.97326-1-bruno.larsen@eldorado.org.br/testing.checkpatch/?type=message.
> ---
> Email generated automatically by Patchew [https://patchew.org/].
> Please send your feedback to patchew-devel@redhat.com

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/4] target/ppc: added solutions for building with disable-tcg
  2021-04-12  5:08   ` David Gibson
@ 2021-04-12 15:40     ` Richard Henderson
  2021-04-13  6:42       ` David Gibson
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Henderson @ 2021-04-12 15:40 UTC (permalink / raw)
  To: David Gibson, Bruno Larsen (billionai)
  Cc: qemu-devel, lagarcia, lucas.araujo, fernando.valle, qemu-ppc,
	andre.silva, matheus.ferst, luis.pires

On 4/11/21 10:08 PM, David Gibson wrote:
> Not directly related to what you're trying to accomplish here, but the
> whole vscr_sat thing looks really weird.  I have no idea why we're
> splitting out the storage of VSCR[SAT] for the TCG case at all.  If
> you wanted to clean that up as a preliminary, I'd be grateful.

That's about efficiently implementing the vector saturation instructions in 
TCG.  See GEN_VXFORM_SAT in translate/vmx-impl.c.inc.

The SAT bit is represented as a vector that e.g. compares the result of 
addition with the result of saturating addition.  We don't need to resolve that 
to a single bit until the VSCR register is read.


r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/4] target/ppc: added solutions for building with disable-tcg
  2021-04-12 15:40     ` Richard Henderson
@ 2021-04-13  6:42       ` David Gibson
  0 siblings, 0 replies; 15+ messages in thread
From: David Gibson @ 2021-04-13  6:42 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, lagarcia, lucas.araujo, fernando.valle, qemu-ppc,
	andre.silva, Bruno Larsen (billionai),
	matheus.ferst, luis.pires

[-- Attachment #1: Type: text/plain, Size: 1200 bytes --]

On Mon, Apr 12, 2021 at 08:40:47AM -0700, Richard Henderson wrote:
> On 4/11/21 10:08 PM, David Gibson wrote:
> > Not directly related to what you're trying to accomplish here, but the
> > whole vscr_sat thing looks really weird.  I have no idea why we're
> > splitting out the storage of VSCR[SAT] for the TCG case at all.  If
> > you wanted to clean that up as a preliminary, I'd be grateful.
> 
> That's about efficiently implementing the vector saturation instructions in
> TCG.  See GEN_VXFORM_SAT in translate/vmx-impl.c.inc.
> 
> The SAT bit is represented as a vector that e.g. compares the result of
> addition with the result of saturating addition.  We don't need to resolve
> that to a single bit until the VSCR register is read.

Aha, thanks for the input.

Long term, that might benefit from KVM specific code paths that don't
bother with this then.  However, for the first cut, it's simpler to
just keep the current representation, even though it's pretty odd for
KVM.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3/4] target/ppc: Add stubs for tcg functions, so it builds
  2021-04-09 15:19 ` [PATCH 3/4] target/ppc: Add stubs for tcg functions, so it builds Bruno Larsen (billionai)
@ 2021-04-19  5:28   ` David Gibson
  0 siblings, 0 replies; 15+ messages in thread
From: David Gibson @ 2021-04-19  5:28 UTC (permalink / raw)
  To: Bruno Larsen (billionai)
  Cc: qemu-devel, andre.silva, lucas.araujo, fernando.valle, qemu-ppc,
	lagarcia, matheus.ferst, luis.pires

[-- Attachment #1: Type: text/plain, Size: 5559 bytes --]

On Fri, Apr 09, 2021 at 12:19:15PM -0300, Bruno Larsen (billionai) wrote:
> This file basically adds all stubs required to build the project
> with disable-tcg. most of these are not going to remain stubs by the
> end, but this part is where it got complicated, and I wanted to get
> an RFC ASAP. Most of these have to do with mmu emulation, so they'll
> probably be replaced by a KVM implementation in the final product,
> but I'm not sure which ones have to be replace, which can remain
> stubs, and which should not be called at all. Input in general is
> very much welcome.
> 
> Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> ---
>  target/ppc/tcg-stub.c | 139 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 139 insertions(+)
>  create mode 100644 target/ppc/tcg-stub.c
> 
> diff --git a/target/ppc/tcg-stub.c b/target/ppc/tcg-stub.c
> new file mode 100644
> index 0000000000..5dc8cf8911
> --- /dev/null
> +++ b/target/ppc/tcg-stub.c
> @@ -0,0 +1,139 @@
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#include "mmu-hash64.h"
> +
> +/* STUFF FOR FIRST LINKER ERROR */
> +/* This stuff happens in target/ppc files */
> +
> +#if !defined(CONFIG_USER_ONLY)
> +
> +void ppc_store_sdr1(CPUPPCState *env, target_ulong value) {

In general stubbing ppc_store_*() functions doesn't look seem like a
good idea.  At the very least the KVM code will need to update the
register in env so that it gets synced with KVM later.  I think you're
going to be better off moving those ppc_store_*() functions used from
KVM code into somewhere common, then #ifdefing to remove any TCG
specific operations from them (or else providing KVM stubs for the TCG
things they call).

> +    /* stub to make things compile */
> +    return;
> +}
> +
> +void ppc_store_ptcr(CPUPPCState *env, target_ulong value) {
> +    /* stub to make things compile */
> +    return;
> +}
> +
> +#endif /* !defined(CONFIG_USER_ONLY) */
> +void ppc_store_msr(CPUPPCState *env, target_ulong value) {
> +    /* stub to make things compile */
> +    return;
> +}
> +
> +void dump_mmu(CPUPPCState *env){
> +    /* stub to make things compile */
> +    return;
> +}
> +
> +void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) {
> +    /* stub to make things compile */
> +    return;
> +}
> +
> +void ppc_cpu_do_interrupt(CPUState *cpu) {
> +    /* stub to make things compile */
> +    return;
> +}
> +
> +/* STUFF FOR SECOND LINKER ERROR*/
> +/* these errors happen mostly in hw/ppc */
> +
> +#ifdef TARGET_PPC64
> +int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
> +                  target_ulong esid, target_ulong vsid) {
> +    /* rquired by kvm.c and machine.c */
> +    return 0;
> +}
> +
> +void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu,
> +                                 bool (*cb)(void *, uint32_t, uint32_t),
> +                                 void *opaque) {
> +    /* required by spapr_caps.c */
> +    return; 
> +}
> +
> +void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) {
> +    /* required by spapr_* */
> +    return;
> +}
> +
> +const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
> +                                             hwaddr ptex, int n) {
> +    /* used by spapr_hcall a bunch */
> +    return NULL;
> +}
> +
> +void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes,
> +                            hwaddr ptex, int n) {
> +    /* used a bunch by spapr_hcall */
> +    return; 
> +}
> +
> +void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
> +                               target_ulong pte_index,
> +                               target_ulong pte0, target_ulong pte1){
> +    return; 
> +}
> +
> +unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
> +                                          uint64_t pte0, uint64_t pte1) {
> +    return 0;
> +}
> +#endif
> +
> +void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) {
> +    /* required by spapr_events spapr_mce_dispatch_elog */
> +    return;
> +}
> +#ifndef CONFIG_USER_ONLY
> +void ppc_cpu_do_system_reset(CPUState *cs){
> +    /* required by pnv and spapr */
> +    return;
> +}
> +#endif
> +
> +bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid,
> +                       ppc_v3_pate_t *entry);
> +
> +bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid,
> +                       ppc_v3_pate_t *entry) {
> +    /* used by spapr_hcall: ppc_hash64_hpt_mask */
> +    return true;
> +}
> +
> +/* THIRD BATCH OF ERRORS, AFTER MOVING STUFF FROM TRANSLATE TO CPU.C */
> +
> +/* they are all coming from cpu.c, probably */
> +
> +void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) {
> +    return;
> +}
> +
> +void init_ppc_proc(PowerPCCPU *cpu) {
> +    return;
> +}
> +
> +void destroy_ppc_opcodes(PowerPCCPU *cpu) {
> +    return;
> +}
> +
> +void ppc_tlb_invalidate_all(CPUPPCState *env) {
> +    return;
> +}
> +
> +void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags) {
> +    return;
> +}
> +
> +void ppc_cpu_dump_statistics(CPUState *cpu, int flags) {
> +    return;
> +}
> +
> +#include "exec/hwaddr.h"
> +
> +hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) {
> +    return 0;
> +}

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2021-04-19  5:29 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-09 15:19 [RFC PATCH 0/4] target/ppc: add disable-tcg option Bruno Larsen (billionai)
2021-04-09 15:19 ` [PATCH 1/4] target/ppc: Code motion required to build disabling tcg Bruno Larsen (billionai)
2021-04-09 19:48   ` Fabiano Rosas
2021-04-12  4:34     ` David Gibson
2021-04-09 15:19 ` [PATCH 2/4] target/ppc: added solutions for building with disable-tcg Bruno Larsen (billionai)
2021-04-09 20:40   ` Fabiano Rosas
2021-04-12  5:08   ` David Gibson
2021-04-12 15:40     ` Richard Henderson
2021-04-13  6:42       ` David Gibson
2021-04-09 15:19 ` [PATCH 3/4] target/ppc: Add stubs for tcg functions, so it builds Bruno Larsen (billionai)
2021-04-19  5:28   ` David Gibson
2021-04-09 15:19 ` [PATCH 4/4] target/ppc: updated build rules for disable-tcg option Bruno Larsen (billionai)
2021-04-09 15:57 ` [RFC PATCH 0/4] target/ppc: add " no-reply
2021-04-12  5:13   ` David Gibson
2021-04-12  4:32 ` David Gibson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).