diff options
Diffstat (limited to 'target-ppc/translate_init.c')
| -rw-r--r-- | target-ppc/translate_init.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 3eafbb0d1a..7f53c33eaf 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -631,7 +631,7 @@ static inline void _spr_register(CPUPPCState *env, int num, #if defined(CONFIG_KVM) spr->one_reg_id = one_reg_id, #endif - env->spr[num] = initial_value; + env->spr[num] = spr->default_value = initial_value; } /* Generic PowerPC SPRs */ @@ -4432,6 +4432,7 @@ enum fsl_e500_version { static void init_proc_e500 (CPUPPCState *env, int version) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg[2]; uint64_t ivor_mask; uint64_t ivpr_mask = 0xFFFF0000ULL; @@ -4490,7 +4491,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64); break; default: - cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); + cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); } #endif /* Cache sizes */ @@ -4507,7 +4508,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) l1cfg0 |= 0x1000000; /* 64 byte cache block size */ break; default: - cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); + cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); } gen_spr_BookE206(env, 0x000000DF, tlbncfg); /* XXX : not implemented */ @@ -7172,7 +7173,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | - PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207; + PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | + PPC2_ISA205 | PPC2_ISA207S; pcc->msr_mask = 0x800000000284FF36ULL; pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) @@ -7433,7 +7435,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx) { opc_handler_t **tmp; - tmp = g_malloc(0x20 * sizeof(opc_handler_t)); + tmp = g_new(opc_handler_t *, 0x20); fill_new_table(tmp, 0x20); table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); @@ -7847,6 +7849,12 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) max_smt, kvm_enabled() ? "KVM" : "TCG"); return; } + if (!is_power_of_2(smp_threads)) { + error_setg(errp, "Cannot support %d threads on PPC with %s, " + "threads count must be a power of 2.", + smp_threads, kvm_enabled() ? "KVM" : "TCG"); + return; + } cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt + (cs->cpu_index % smp_threads); @@ -8220,26 +8228,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) PowerPCCPU *cpu_ppc_init(const char *cpu_model) { - PowerPCCPU *cpu; - ObjectClass *oc; - Error *err = NULL; - - oc = ppc_cpu_class_by_name(cpu_model); - if (oc == NULL) { - return NULL; - } - - cpu = POWERPC_CPU(object_new(object_class_get_name(oc))); - - object_property_set_bool(OBJECT(cpu), true, "realized", &err); - if (err != NULL) { - error_report("%s", error_get_pretty(err)); - error_free(err); - object_unref(OBJECT(cpu)); - return NULL; - } - - return cpu; + return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model)); } /* Sort by PVR, ordering special case "host" last. */ @@ -8384,6 +8373,14 @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value) 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); +} + /* CPUClass::reset() */ static void ppc_cpu_reset(CPUState *s) { @@ -8391,6 +8388,7 @@ static void ppc_cpu_reset(CPUState *s) PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); CPUPPCState *env = &cpu->env; target_ulong msr; + int i; pcc->parent_reset(s); @@ -8433,7 +8431,7 @@ static void ppc_cpu_reset(CPUState *s) env->reserve_addr = (target_ulong)-1ULL; /* Be sure no exception or interrupt is pending */ env->pending_interrupts = 0; - env->exception_index = POWERPC_EXCP_NONE; + s->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) @@ -8444,8 +8442,17 @@ static void ppc_cpu_reset(CPUState *s) env->dtl_size = 0; #endif /* TARGET_PPC64 */ + 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; + } + /* Flush all TLBs */ - tlb_flush(env, 1); + tlb_flush(s, 1); } static void ppc_cpu_initfn(Object *obj) @@ -8511,13 +8518,16 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->reset = ppc_cpu_reset; cc->class_by_name = ppc_cpu_class_by_name; + cc->has_work = ppc_cpu_has_work; cc->do_interrupt = ppc_cpu_do_interrupt; 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 +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; cc->vmsd = &vmstate_ppc_cpu; #if defined(TARGET_PPC64) |