diff options
Diffstat (limited to 'target-ppc/translate_init.c')
| -rw-r--r-- | target-ppc/translate_init.c | 1956 |
1 files changed, 1539 insertions, 417 deletions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 4d94015942..85581c9537 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -28,6 +28,8 @@ #include "mmu-hash32.h" #include "mmu-hash64.h" #include "qemu/error-report.h" +#include "qapi/visitor.h" +#include "hw/qdev-properties.h" //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR @@ -173,6 +175,13 @@ static void spr_read_ureg (void *opaque, int gprn, int sprn) gen_load_spr(cpu_gpr[gprn], sprn + 0x10); } +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) +static void spr_write_ureg(void *opaque, int sprn, int gprn) +{ + gen_store_spr(sprn + 0x10, cpu_gpr[gprn]); +} +#endif + /* SPR common to all non-embedded PowerPC */ /* DECR */ #if !defined(CONFIG_USER_ONLY) @@ -951,72 +960,72 @@ static void gen_spr_7xx (CPUPPCState *env) 0x00000000); /* Performance monitors */ /* XXX : not implemented */ - spr_register(env, SPR_MMCR0, "MMCR0", + spr_register(env, SPR_7XX_MMCR0, "MMCR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_MMCR1, "MMCR1", + spr_register(env, SPR_7XX_MMCR1, "MMCR1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC1, "PMC1", + spr_register(env, SPR_7XX_PMC1, "PMC1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC2, "PMC2", + spr_register(env, SPR_7XX_PMC2, "PMC2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC3, "PMC3", + spr_register(env, SPR_7XX_PMC3, "PMC3", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC4, "PMC4", + spr_register(env, SPR_7XX_PMC4, "PMC4", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_SIAR, "SIAR", + spr_register(env, SPR_7XX_SIAR, "SIAR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UMMCR0, "UMMCR0", + spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UMMCR1, "UMMCR1", + spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC1, "UPMC1", + spr_register(env, SPR_7XX_UPMC1, "UPMC1", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC2, "UPMC2", + spr_register(env, SPR_7XX_UPMC2, "UPMC2", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC3, "UPMC3", + spr_register(env, SPR_7XX_UPMC3, "UPMC3", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC4, "UPMC4", + spr_register(env, SPR_7XX_UPMC4, "UPMC4", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_USIAR, "USIAR", + spr_register(env, SPR_7XX_USIAR, "USIAR", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -1117,22 +1126,22 @@ static void gen_spr_604 (CPUPPCState *env) KVM_REG_PPC_DABR, 0x00000000); /* Performance counters */ /* XXX : not implemented */ - spr_register(env, SPR_MMCR0, "MMCR0", + spr_register(env, SPR_7XX_MMCR0, "MMCR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC1, "PMC1", + spr_register(env, SPR_7XX_PMC1, "PMC1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC2, "PMC2", + spr_register(env, SPR_7XX_PMC2, "PMC2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_SIAR, "SIAR", + spr_register(env, SPR_7XX_SIAR, "SIAR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); @@ -1352,12 +1361,12 @@ static void gen_spr_74xx (CPUPPCState *env) &spr_read_generic, &spr_write_pir, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_MMCR2, "MMCR2", + spr_register(env, SPR_74XX_MMCR2, "MMCR2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UMMCR2, "UMMCR2", + spr_register(env, SPR_74XX_UMMCR2, "UMMCR2", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -1448,16 +1457,23 @@ static void spr_write_e500_l1csr0 (void *opaque, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); - tcg_gen_andi_tl(t0, cpu_gpr[gprn], ~256); + tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE); + gen_store_spr(sprn, t0); + tcg_temp_free(t0); +} + +static void spr_write_e500_l1csr1(void *opaque, int sprn, int gprn) +{ + TCGv t0 = tcg_temp_new(); + + tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE); gen_store_spr(sprn, t0); tcg_temp_free(t0); } static void spr_write_booke206_mmucsr0 (void *opaque, int sprn, int gprn) { - TCGv_i32 t0 = tcg_const_i32(sprn); - gen_helper_booke206_tlbflush(cpu_env, t0); - tcg_temp_free_i32(t0); + gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]); } static void spr_write_booke_pid (void *opaque, int sprn, int gprn) @@ -3064,6 +3080,7 @@ static void init_excp_POWER7 (CPUPPCState *env) env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40; + env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60; env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; @@ -3102,6 +3119,18 @@ 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) +{ + return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE); +} +#endif + /*****************************************************************************/ /* PowerPC implementations definitions */ @@ -3156,7 +3185,15 @@ POWERPC_FAMILY(401)(ObjectClass *oc, void *data) PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_4xx_COMMON | PPC_40x_EXCP; - pcc->msr_mask = 0x00000000000FD201ULL; + pcc->msr_mask = (1ull << MSR_KEY) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_ME) | + (1ull << MSR_DE) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_REAL; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; @@ -3203,7 +3240,18 @@ POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | PPC_4xx_COMMON | PPC_40x_EXCP; - pcc->msr_mask = 0x00000000001FD231ULL; + pcc->msr_mask = (1ull << 20) | + (1ull << MSR_KEY) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_ME) | + (1ull << MSR_DE) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; @@ -3244,7 +3292,19 @@ POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | PPC_4xx_COMMON | PPC_40x_EXCP; - pcc->msr_mask = 0x00000000001FD631ULL; + pcc->msr_mask = (1ull << 20) | + (1ull << MSR_KEY) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_ME) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; @@ -3291,7 +3351,18 @@ POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | PPC_4xx_COMMON | PPC_40x_EXCP; - pcc->msr_mask = 0x00000000001FD231ULL; + pcc->msr_mask = (1ull << 20) | + (1ull << MSR_KEY) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_ME) | + (1ull << MSR_DE) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; @@ -3330,7 +3401,15 @@ POWERPC_FAMILY(403)(ObjectClass *oc, void *data) PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_4xx_COMMON | PPC_40x_EXCP; - pcc->msr_mask = 0x000000000007D00DULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_ME) | + (1ull << MSR_PE) | + (1ull << MSR_PX) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_REAL; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; @@ -3389,7 +3468,15 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | PPC_4xx_COMMON | PPC_40x_EXCP; - pcc->msr_mask = 0x000000000007D00DULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_ME) | + (1ull << MSR_PE) | + (1ull << MSR_PX) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; @@ -3447,7 +3534,15 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP; - pcc->msr_mask = 0x000000000006E630ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_SOFT_4xx; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_405; @@ -3540,7 +3635,18 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_MFTB | PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC; - pcc->msr_mask = 0x000000000006FF30ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -3612,7 +3718,18 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB | PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC; - pcc->msr_mask = 0x000000000006FF30ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -3684,7 +3801,18 @@ POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_MFTB | PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC; - pcc->msr_mask = 0x000000000006FF30ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -3774,7 +3902,18 @@ POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_MFTB | PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC; - pcc->msr_mask = 0x000000000006FF30ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -3870,7 +4009,18 @@ POWERPC_FAMILY(460)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC; - pcc->msr_mask = 0x000000000006FF30ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -3969,7 +4119,18 @@ POWERPC_FAMILY(460F)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC; - pcc->msr_mask = 0x000000000006FF30ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -4002,7 +4163,18 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data) PPC_MEM_EIEIO | PPC_MEM_SYNC | PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX | PPC_MFTB; - pcc->msr_mask = 0x000000000001FF43ULL; + pcc->msr_mask = (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_REAL; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_RCPU; @@ -4034,7 +4206,18 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data) pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MEM_EIEIO | PPC_MEM_SYNC | PPC_CACHE_ICBI | PPC_MFTB; - pcc->msr_mask = 0x000000000001F673ULL; + pcc->msr_mask = (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_MPC8xx; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_RCPU; @@ -4100,7 +4283,21 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000006FFF2ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_G2; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -4191,7 +4388,23 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000007FFF3ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_G2; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -4249,8 +4462,8 @@ static void init_proc_e200 (CPUPPCState *env) 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", @@ -4331,7 +4544,20 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, void *data) PPC_CACHE_DCBZ | PPC_CACHE_DCBA | PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_BOOKE; - pcc->msr_mask = 0x000000000606FF30ULL; + pcc->msr_mask = (1ull << MSR_UCLE) | + (1ull << MSR_SPE) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -4389,7 +4615,23 @@ POWERPC_FAMILY(e300)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000007FFF3ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -4438,6 +4680,8 @@ static void init_proc_e500 (CPUPPCState *env, int version) uint64_t ivpr_mask = 0xFFFF0000ULL; uint32_t l1cfg0 = 0x3800 /* 8 ways */ | 0x0020; /* 32 kb */ + uint32_t l1cfg1 = 0x3800 /* 8 ways */ + | 0x0020; /* 32 kb */ #if !defined(CONFIG_USER_ONLY) int i; #endif @@ -4506,6 +4750,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) env->dcache_line_size = 64; env->icache_line_size = 64; l1cfg0 |= 0x1000000; /* 64 byte cache block size */ + l1cfg1 |= 0x1000000; /* 64 byte cache block size */ break; default: cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); @@ -4553,18 +4798,20 @@ static void init_proc_e500 (CPUPPCState *env, int version) 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, l1cfg0); - /* XXX : not implemented */ + spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1", + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + l1cfg1); spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_e500_l1csr0, 0x00000000); - /* XXX : not implemented */ spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_e500_l1csr1, 0x00000000); spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", SPR_NOACCESS, SPR_NOACCESS, @@ -4628,7 +4875,20 @@ POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data) PPC_CACHE_DCBZ | PPC_CACHE_DCBA | PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; pcc->insns_flags2 = PPC2_BOOKE206; - pcc->msr_mask = 0x000000000606FF30ULL; + pcc->msr_mask = (1ull << MSR_UCLE) | + (1ull << MSR_SPE) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -4658,7 +4918,20 @@ POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data) PPC_CACHE_DCBZ | PPC_CACHE_DCBA | PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; pcc->insns_flags2 = PPC2_BOOKE206; - pcc->msr_mask = 0x000000000606FF30ULL; + pcc->msr_mask = (1ull << MSR_UCLE) | + (1ull << MSR_SPE) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -4690,7 +4963,20 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data) PPC_FLOAT_STFIWX | PPC_WAIT | PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL; - pcc->msr_mask = 0x000000001402FB36ULL; + pcc->msr_mask = (1ull << MSR_GS) | + (1ull << MSR_UCLE) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PX) | + (1ull << MSR_RI); pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -4724,7 +5010,21 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data) PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | PPC_64B | PPC_POPCNTB | PPC_POPCNTWD; pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206; - pcc->msr_mask = 0x000000009402FB36ULL; + pcc->msr_mask = (1ull << MSR_CM) | + (1ull << MSR_GS) | + (1ull << MSR_UCLE) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PX) | + (1ull << MSR_RI); pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; @@ -4746,7 +5046,17 @@ POWERPC_FAMILY(POWER)(ObjectClass *oc, void *data) dc->desc = "POWER"; /* pcc->insns_flags = XXX_TODO; */ /* POWER RSC (from RAD6000) */ - pcc->msr_mask = 0x00000000FEF0ULL; + pcc->msr_mask = (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR); } #define POWERPC_MSRR_601 (0x0000000000001040ULL) @@ -4801,7 +5111,16 @@ POWERPC_FAMILY(601)(ObjectClass *oc, void *data) PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000000FD70ULL; + pcc->msr_mask = (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_601; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -4837,7 +5156,16 @@ POWERPC_FAMILY(601v)(ObjectClass *oc, void *data) PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000000FD70ULL; + pcc->msr_mask = (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR); pcc->mmu_model = POWERPC_MMU_601; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -4889,7 +5217,24 @@ POWERPC_FAMILY(602)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_602_SPEC; - pcc->msr_mask = 0x0000000000C7FF73ULL; + pcc->msr_mask = (1ull << MSR_VSX) | + (1ull << MSR_SA) | + (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); /* XXX: 602 MMU is quite specific. Should add a special case */ pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_602; @@ -4941,7 +5286,22 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000007FF73ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -4992,7 +5352,22 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000007FF73ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_603E; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -5037,7 +5412,22 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5054,17 +5444,17 @@ static void init_proc_604E (CPUPPCState *env) gen_spr_ne_601(env); gen_spr_604(env); /* XXX : not implemented */ - spr_register(env, SPR_MMCR1, "MMCR1", + spr_register(env, SPR_7XX_MMCR1, "MMCR1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC3, "PMC3", + spr_register(env, SPR_7XX_PMC3, "PMC3", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC4, "PMC4", + spr_register(env, SPR_7XX_PMC4, "PMC4", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); @@ -5105,7 +5495,22 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5160,7 +5565,22 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5223,7 +5643,22 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5409,7 +5844,22 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5476,7 +5926,22 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5548,7 +6013,22 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5620,7 +6100,22 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5683,7 +6178,22 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_7x5; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -5754,7 +6264,22 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data) PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = 0x000000000005FF77ULL; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_7x5; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -5812,7 +6337,23 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5880,7 +6421,23 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -5926,22 +6483,22 @@ static void init_proc_7440 (CPUPPCState *env) 0x00000000); /* PMC */ /* XXX : not implemented */ - spr_register(env, SPR_PMC5, "PMC5", + spr_register(env, SPR_7XX_PMC5, "PMC5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC5, "UPMC5", + spr_register(env, SPR_7XX_UPMC5, "UPMC5", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC6, "PMC6", + spr_register(env, SPR_7XX_PMC6, "PMC6", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC6, "UPMC6", + spr_register(env, SPR_7XX_UPMC6, "UPMC6", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -5974,7 +6531,23 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_74xx_TLB | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -6043,22 +6616,22 @@ static void init_proc_7450 (CPUPPCState *env) 0x00000000); /* PMC */ /* XXX : not implemented */ - spr_register(env, SPR_PMC5, "PMC5", + spr_register(env, SPR_7XX_PMC5, "PMC5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC5, "UPMC5", + spr_register(env, SPR_7XX_UPMC5, "UPMC5", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC6, "PMC6", + spr_register(env, SPR_7XX_PMC6, "PMC6", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC6, "UPMC6", + spr_register(env, SPR_7XX_UPMC6, "UPMC6", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -6091,7 +6664,23 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_74xx_TLB | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -6129,22 +6718,22 @@ static void init_proc_7445 (CPUPPCState *env) 0x00000000); /* PMC */ /* XXX : not implemented */ - spr_register(env, SPR_PMC5, "PMC5", + spr_register(env, SPR_7XX_PMC5, "PMC5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC5, "UPMC5", + spr_register(env, SPR_7XX_UPMC5, "UPMC5", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC6, "PMC6", + spr_register(env, SPR_7XX_PMC6, "PMC6", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC6, "UPMC6", + spr_register(env, SPR_7XX_UPMC6, "UPMC6", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -6211,7 +6800,23 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_74xx_TLB | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -6251,22 +6856,22 @@ static void init_proc_7455 (CPUPPCState *env) 0x00000000); /* PMC */ /* XXX : not implemented */ - spr_register(env, SPR_PMC5, "PMC5", + spr_register(env, SPR_7XX_PMC5, "PMC5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC5, "UPMC5", + spr_register(env, SPR_7XX_UPMC5, "UPMC5", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC6, "PMC6", + spr_register(env, SPR_7XX_PMC6, "PMC6", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC6, "UPMC6", + spr_register(env, SPR_7XX_UPMC6, "UPMC6", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -6333,7 +6938,23 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_74xx_TLB | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -6397,22 +7018,22 @@ static void init_proc_7457 (CPUPPCState *env) 0x00000000); /* PMC */ /* XXX : not implemented */ - spr_register(env, SPR_PMC5, "PMC5", + spr_register(env, SPR_7XX_PMC5, "PMC5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC5, "UPMC5", + spr_register(env, SPR_7XX_UPMC5, "UPMC5", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC6, "PMC6", + spr_register(env, SPR_7XX_PMC6, "PMC6", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC6, "UPMC6", + spr_register(env, SPR_7XX_UPMC6, "UPMC6", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -6479,7 +7100,23 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data) PPC_MEM_TLBIA | PPC_74xx_TLB | PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; @@ -6518,22 +7155,22 @@ static void init_proc_e600 (CPUPPCState *env) &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC5, "PMC5", + spr_register(env, SPR_7XX_PMC5, "PMC5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC5, "UPMC5", + spr_register(env, SPR_7XX_UPMC5, "UPMC5", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_PMC6, "PMC6", + spr_register(env, SPR_7XX_PMC6, "PMC6", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ - spr_register(env, SPR_UPMC6, "UPMC6", + spr_register(env, SPR_7XX_UPMC6, "UPMC6", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); @@ -6601,7 +7238,23 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) PPC_SEGMENT | PPC_EXTERN | PPC_ALTIVEC; pcc->insns_flags2 = PPC_NONE; - pcc->msr_mask = 0x000000000205FF77ULL; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_32B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; @@ -6621,246 +7274,628 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) #define POWERPC970_HID5_INIT 0x00000000 #endif +enum BOOK3S_CPU_TYPE { + BOOK3S_CPU_970, + BOOK3S_CPU_POWER5PLUS, + BOOK3S_CPU_POWER6, + BOOK3S_CPU_POWER7, + BOOK3S_CPU_POWER8 +}; + +static void gen_fscr_facility_check(void *opaque, int facility_sprn, int bit, + int sprn, int cause) +{ + TCGv_i32 t1 = tcg_const_i32(bit); + TCGv_i32 t2 = tcg_const_i32(sprn); + TCGv_i32 t3 = tcg_const_i32(cause); + + gen_update_current_nip(opaque); + gen_helper_fscr_facility_check(cpu_env, t1, t2, t3); + + tcg_temp_free_i32(t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + +static void gen_msr_facility_check(void *opaque, int facility_sprn, int bit, + int sprn, int cause) +{ + TCGv_i32 t1 = tcg_const_i32(bit); + TCGv_i32 t2 = tcg_const_i32(sprn); + TCGv_i32 t3 = tcg_const_i32(cause); + + gen_update_current_nip(opaque); + gen_helper_msr_facility_check(cpu_env, t1, t2, t3); + + tcg_temp_free_i32(t3); + tcg_temp_free_i32(t2); + tcg_temp_free_i32(t1); +} + +static void spr_read_prev_upper32(void *opaque, int gprn, int sprn) +{ + TCGv spr_up = tcg_temp_new(); + TCGv spr = tcg_temp_new(); + + gen_load_spr(spr, sprn - 1); + tcg_gen_shri_tl(spr_up, spr, 32); + tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up); + + tcg_temp_free(spr); + tcg_temp_free(spr_up); +} + +static void spr_write_prev_upper32(void *opaque, int sprn, int gprn) +{ + TCGv spr = tcg_temp_new(); + + gen_load_spr(spr, sprn - 1); + tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32); + gen_store_spr(sprn - 1, spr); + + tcg_temp_free(spr); +} + static int check_pow_970 (CPUPPCState *env) { - if (env->spr[SPR_HID0] & 0x00600000) + if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) { return 1; + } return 0; } -static void init_proc_970 (CPUPPCState *env) +static void gen_spr_970_hid(CPUPPCState *env) { - gen_spr_ne_601(env); - gen_spr_7xx(env); - /* Time base */ - gen_tbl(env); /* Hardware implementation registers */ /* XXX : not implemented */ spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_clear, 0x60000000); - /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); - /* XXX : not implemented */ spr_register(env, SPR_970_HID5, "HID5", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, POWERPC970_HID5_INIT); - /* Memory management */ - /* XXX: not correct */ - gen_low_BATs(env); +} + +static void gen_spr_970_hior(CPUPPCState *env) +{ spr_register(env, SPR_HIOR, "SPR_HIOR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_hior, &spr_write_hior, 0x00000000); -#if !defined(CONFIG_USER_ONLY) - env->slb_nr = 32; -#endif - init_excp_970(env); - env->dcache_line_size = 128; - env->icache_line_size = 128; - /* Allocate hardware IRQ controller */ - ppc970_irq_init(env); +} + +static void gen_spr_970_lpar(CPUPPCState *env) +{ + /* Logical partitionning */ + /* PPC970: HID4 is effectively the LPCR */ + spr_register(env, SPR_970_HID4, "HID4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void gen_spr_book3s_common(CPUPPCState *env) +{ + spr_register(env, SPR_CTRL, "SPR_CTRL", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_UCTRL, "SPR_UCTRL", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); +} + +static void gen_spr_book3s_altivec(CPUPPCState *env) +{ + if (!(env->insns_flags & PPC_ALTIVEC)) { + return; + } + + spr_register_kvm(env, SPR_VRSAVE, "VRSAVE", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_VRSAVE, 0x00000000); + /* Can't find information on what this should be on reset. This * value is the one used by 74xx processors. */ vscr_init(env, 0x00010000); } -POWERPC_FAMILY(970)(ObjectClass *oc, void *data) +static void gen_spr_book3s_dbg(CPUPPCState *env) { - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + /* + * TODO: different specs define different scopes for these, + * will have to address this: + * 970: super/write and super/read + * powerisa 2.03..2.04: hypv/write and super/read. + * powerisa 2.05 and newer: hypv/write and hypv/read. + */ + spr_register_kvm(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABR, 0x00000000); + spr_register_kvm(env, SPR_DABRX, "DABRX", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABRX, 0x00000000); +} - dc->desc = "PowerPC 970"; - pcc->init_proc = init_proc_970; - pcc->check_pow = check_pow_970; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI; - pcc->msr_mask = 0x900000000204FF36ULL; - pcc->mmu_model = POWERPC_MMU_64B; -#if defined(CONFIG_SOFTMMU) - pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; -#endif - pcc->excp_model = POWERPC_EXCP_970; - pcc->bus_model = PPC_FLAGS_INPUT_970; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x10000; +static void gen_spr_970_dbg(CPUPPCState *env) +{ + /* Breakpoints */ + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); } -static int check_pow_970FX (CPUPPCState *env) +static void gen_spr_book3s_pmu_sup(CPUPPCState *env) { - if (env->spr[SPR_HID0] & 0x00600000) - return 1; + spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCR0, 0x00000000); + spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCR1, 0x00000000); + spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCRA, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC1, "PMC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC1, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC2, "PMC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC2, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC3, "PMC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC3, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC4, "PMC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC4, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC5, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC6, 0x00000000); + spr_register_kvm(env, SPR_POWER_SIAR, "SIAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SIAR, 0x00000000); + spr_register_kvm(env, SPR_POWER_SDAR, "SDAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SDAR, 0x00000000); +} - return 0; +static void gen_spr_book3s_pmu_user(CPUPPCState *env) +{ + spr_register(env, SPR_POWER_UMMCR0, "UMMCR0", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UMMCR1, "UMMCR1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UMMCRA, "UMMCRA", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC1, "UPMC1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC2, "UPMC2", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC3, "UPMC3", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC4, "UPMC4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_USIAR, "USIAR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_USDAR, "USDAR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); } -static void init_proc_970FX (CPUPPCState *env) +static void gen_spr_970_pmu_sup(CPUPPCState *env) { - gen_spr_ne_601(env); - gen_spr_7xx(env); - /* Time base */ - gen_tbl(env); - /* Hardware implementation registers */ - /* XXX : not implemented */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_clear, - 0x60000000); - /* XXX : not implemented */ - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + spr_register_kvm(env, SPR_970_PMC7, "PMC7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC7, 0x00000000); + spr_register_kvm(env, SPR_970_PMC8, "PMC8", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC8, 0x00000000); +} + +static void gen_spr_970_pmu_user(CPUPPCState *env) +{ + spr_register(env, SPR_970_UPMC7, "UPMC7", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, 0x00000000); - /* XXX : not implemented */ - spr_register(env, SPR_970_HID5, "HID5", + spr_register(env, SPR_970_UPMC8, "UPMC8", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); +} + +static void gen_spr_power8_pmu_sup(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCR2, 0x00000000); + spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCRS, 0x00000000); +} + +static void gen_spr_power8_pmu_user(CPUPPCState *env) +{ + spr_register(env, SPR_POWER_UMMCR2, "UMMCR2", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); +} + +static void gen_spr_power5p_ear(CPUPPCState *env) +{ + /* External access control */ + spr_register(env, SPR_EAR, "EAR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, - POWERPC970_HID5_INIT); - /* Memory management */ - /* XXX: not correct */ - gen_low_BATs(env); - spr_register(env, SPR_HIOR, "SPR_HIOR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_hior, &spr_write_hior, 0x00000000); - spr_register(env, SPR_CTRL, "SPR_CTRL", +} + +static void gen_spr_power5p_lpar(CPUPPCState *env) +{ + /* Logical partitionning */ + spr_register_kvm(env, SPR_LPCR, "LPCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_LPCR, 0x00000000); +} + +static void gen_spr_book3s_ids(CPUPPCState *env) +{ + /* Processor identification */ + spr_register(env, SPR_PIR, "PIR", SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, &spr_write_generic, + &spr_read_generic, &spr_write_pir, 0x00000000); - spr_register(env, SPR_UCTRL, "SPR_UCTRL", +} + +static void gen_spr_power8_ids(CPUPPCState *env) +{ + /* Thread identification */ + spr_register(env, SPR_TIR, "TIR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); - spr_register(env, SPR_VRSAVE, "SPR_VRSAVE", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); +} + +static void gen_spr_book3s_purr(CPUPPCState *env) +{ #if !defined(CONFIG_USER_ONLY) - env->slb_nr = 64; + /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ + spr_register_kvm(env, SPR_PURR, "PURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + KVM_REG_PPC_PURR, 0x00000000); + spr_register_kvm(env, SPR_SPURR, "SPURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + KVM_REG_PPC_SPURR, 0x00000000); #endif - init_excp_970(env); - env->dcache_line_size = 128; - env->icache_line_size = 128; - /* Allocate hardware IRQ controller */ - ppc970_irq_init(env); - /* Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. */ - vscr_init(env, 0x00010000); } -POWERPC_FAMILY(970FX)(ObjectClass *oc, void *data) +static void gen_spr_power6_dbg(CPUPPCState *env) { - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 970FX (aka G5)"; - pcc->init_proc = init_proc_970FX; - pcc->check_pow = check_pow_970FX; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI; - pcc->msr_mask = 0x800000000204FF36ULL; - pcc->mmu_model = POWERPC_MMU_64B; -#if defined(CONFIG_SOFTMMU) - pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; +#if !defined(CONFIG_USER_ONLY) + spr_register(env, SPR_CFAR, "SPR_CFAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_cfar, &spr_write_cfar, + 0x00000000); #endif - pcc->excp_model = POWERPC_EXCP_970; - pcc->bus_model = PPC_FLAGS_INPUT_970; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x10000; } -static int check_pow_970MP (CPUPPCState *env) +static void gen_spr_power5p_common(CPUPPCState *env) { - if (env->spr[SPR_HID0] & 0x01C00000) - return 1; - - return 0; + spr_register_kvm(env, SPR_PPR, "PPR", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PPR, 0x00000000); } -static void init_proc_970MP (CPUPPCState *env) +static void gen_spr_power6_common(CPUPPCState *env) { - gen_spr_ne_601(env); - gen_spr_7xx(env); - /* Time base */ - gen_tbl(env); - /* Hardware implementation registers */ - /* XXX : not implemented */ - spr_register(env, SPR_HID0, "HID0", +#if !defined(CONFIG_USER_ONLY) + spr_register_kvm(env, SPR_DSCR, "SPR_DSCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DSCR, 0x00000000); +#endif + /* + * Register PCR to report POWERPC_EXCP_PRIV_REG instead of + * POWERPC_EXCP_INVAL_SPR. + */ + spr_register(env, SPR_PCR, "PCR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_clear, - 0x60000000); - /* XXX : not implemented */ - spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, + 0x00000000); +} + +static void spr_read_tar(void *opaque, int gprn, int sprn) +{ + gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR); + spr_read_generic(opaque, gprn, sprn); +} + +static void spr_write_tar(void *opaque, int sprn, int gprn) +{ + gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR); + spr_write_generic(opaque, sprn, gprn); +} + +static void gen_spr_power8_tce_address_control(CPUPPCState *env) +{ + spr_register(env, SPR_TAR, "TAR", + &spr_read_tar, &spr_write_tar, &spr_read_generic, &spr_write_generic, 0x00000000); - /* XXX : not implemented */ - spr_register(env, SPR_970_HID5, "HID5", - SPR_NOACCESS, SPR_NOACCESS, +} + +static void spr_read_tm(void *opaque, int gprn, int sprn) +{ + gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); + spr_read_generic(opaque, gprn, sprn); +} + +static void spr_write_tm(void *opaque, int sprn, int gprn) +{ + gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); + spr_write_generic(opaque, sprn, gprn); +} + +static void spr_read_tm_upper32(void *opaque, int gprn, int sprn) +{ + gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); + spr_read_prev_upper32(opaque, gprn, sprn); +} + +static void spr_write_tm_upper32(void *opaque, int sprn, int gprn) +{ + gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); + spr_write_prev_upper32(opaque, sprn, gprn); +} + +static void gen_spr_power8_tm(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_TFHAR, "TFHAR", + &spr_read_tm, &spr_write_tm, + &spr_read_tm, &spr_write_tm, + KVM_REG_PPC_TFHAR, 0x00000000); + spr_register_kvm(env, SPR_TFIAR, "TFIAR", + &spr_read_tm, &spr_write_tm, + &spr_read_tm, &spr_write_tm, + KVM_REG_PPC_TFIAR, 0x00000000); + spr_register_kvm(env, SPR_TEXASR, "TEXASR", + &spr_read_tm, &spr_write_tm, + &spr_read_tm, &spr_write_tm, + KVM_REG_PPC_TEXASR, 0x00000000); + spr_register(env, SPR_TEXASRU, "TEXASRU", + &spr_read_tm_upper32, &spr_write_tm_upper32, + &spr_read_tm_upper32, &spr_write_tm_upper32, + 0x00000000); +} + +static void spr_read_ebb(void *opaque, int gprn, int sprn) +{ + gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); + spr_read_generic(opaque, gprn, sprn); +} + +static void spr_write_ebb(void *opaque, int sprn, int gprn) +{ + gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); + spr_write_generic(opaque, sprn, gprn); +} + +static void spr_read_ebb_upper32(void *opaque, int gprn, int sprn) +{ + gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); + spr_read_prev_upper32(opaque, gprn, sprn); +} + +static void spr_write_ebb_upper32(void *opaque, int sprn, int gprn) +{ + gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); + spr_write_prev_upper32(opaque, sprn, gprn); +} + +static void gen_spr_power8_ebb(CPUPPCState *env) +{ + spr_register(env, SPR_BESCRS, "BESCRS", + &spr_read_ebb, &spr_write_ebb, &spr_read_generic, &spr_write_generic, - POWERPC970_HID5_INIT); - /* XXX : not implemented */ - /* Memory management */ - /* XXX: not correct */ - gen_low_BATs(env); - spr_register(env, SPR_HIOR, "SPR_HIOR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_hior, &spr_write_hior, 0x00000000); - /* Logical partitionning */ - spr_register_kvm(env, SPR_LPCR, "LPCR", + spr_register(env, SPR_BESCRSU, "BESCRSU", + &spr_read_ebb_upper32, &spr_write_ebb_upper32, + &spr_read_prev_upper32, &spr_write_prev_upper32, + 0x00000000); + spr_register(env, SPR_BESCRR, "BESCRR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BESCRRU, "BESCRRU", + &spr_read_ebb_upper32, &spr_write_ebb_upper32, + &spr_read_prev_upper32, &spr_write_prev_upper32, + 0x00000000); + spr_register_kvm(env, SPR_EBBHR, "EBBHR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_EBBHR, 0x00000000); + spr_register_kvm(env, SPR_EBBRR, "EBBRR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_EBBRR, 0x00000000); + spr_register_kvm(env, SPR_BESCR, "BESCR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_BESCR, 0x00000000); +} + +static void gen_spr_power8_fscr(CPUPPCState *env) +{ +#if defined(CONFIG_USER_ONLY) + target_ulong initval = 1ULL << FSCR_TAR; +#else + target_ulong initval = 0; +#endif + spr_register_kvm(env, SPR_FSCR, "FSCR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_LPCR, 0x00000000); + KVM_REG_PPC_FSCR, initval); +} + +static void init_proc_book3s_64(CPUPPCState *env, int version) +{ + gen_spr_ne_601(env); + gen_tbl(env); + gen_spr_book3s_altivec(env); + gen_spr_book3s_pmu_sup(env); + gen_spr_book3s_pmu_user(env); + gen_spr_book3s_common(env); + + switch (version) { + case BOOK3S_CPU_970: + case BOOK3S_CPU_POWER5PLUS: + gen_spr_970_hid(env); + gen_spr_970_hior(env); + gen_low_BATs(env); + gen_spr_970_pmu_sup(env); + gen_spr_970_pmu_user(env); + break; + case BOOK3S_CPU_POWER7: + case BOOK3S_CPU_POWER8: + gen_spr_book3s_ids(env); + gen_spr_amr(env); + gen_spr_book3s_purr(env); + break; + default: + g_assert_not_reached(); + } + if (version >= BOOK3S_CPU_POWER5PLUS) { + gen_spr_power5p_common(env); + gen_spr_power5p_lpar(env); + gen_spr_power5p_ear(env); + } else { + gen_spr_970_lpar(env); + } + if (version == BOOK3S_CPU_970) { + gen_spr_970_dbg(env); + } + if (version >= BOOK3S_CPU_POWER6) { + gen_spr_power6_common(env); + gen_spr_power6_dbg(env); + } + if (version >= BOOK3S_CPU_POWER8) { + gen_spr_power8_tce_address_control(env); + gen_spr_power8_ids(env); + gen_spr_power8_ebb(env); + gen_spr_power8_fscr(env); + gen_spr_power8_pmu_sup(env); + gen_spr_power8_pmu_user(env); + gen_spr_power8_tm(env); + } + if (version < BOOK3S_CPU_POWER8) { + gen_spr_book3s_dbg(env); + } #if !defined(CONFIG_USER_ONLY) - env->slb_nr = 32; + switch (version) { + case BOOK3S_CPU_970: + case BOOK3S_CPU_POWER5PLUS: + env->slb_nr = 64; + break; + case BOOK3S_CPU_POWER7: + case BOOK3S_CPU_POWER8: + default: + env->slb_nr = 32; + break; + } #endif - init_excp_970(env); + /* Allocate hardware IRQ controller */ + switch (version) { + case BOOK3S_CPU_970: + case BOOK3S_CPU_POWER5PLUS: + init_excp_970(env); + ppc970_irq_init(env); + break; + case BOOK3S_CPU_POWER7: + case BOOK3S_CPU_POWER8: + init_excp_POWER7(env); + ppcPOWER7_irq_init(env); + break; + default: + g_assert_not_reached(); + } + env->dcache_line_size = 128; env->icache_line_size = 128; - /* Allocate hardware IRQ controller */ - ppc970_irq_init(env); - /* Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. */ - vscr_init(env, 0x00010000); } -POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data) +static void init_proc_970(CPUPPCState *env) +{ + init_proc_book3s_64(env, BOOK3S_CPU_970); +} + +POWERPC_FAMILY(970)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - dc->desc = "PowerPC 970 MP"; - pcc->init_proc = init_proc_970MP; - pcc->check_pow = check_pow_970MP; + dc->desc = "PowerPC 970"; + pcc->init_proc = init_proc_970; + pcc->check_pow = check_pow_970; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6870,7 +7905,21 @@ POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI; - pcc->msr_mask = 0x900000000204FF36ULL; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI); pcc->mmu_model = POWERPC_MMU_64B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; @@ -6887,61 +7936,7 @@ POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data) static void init_proc_power5plus(CPUPPCState *env) { - gen_spr_ne_601(env); - gen_spr_7xx(env); - /* Time base */ - gen_tbl(env); - /* Hardware implementation registers */ - /* XXX : not implemented */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_clear, - 0x60000000); - /* XXX : not implemented */ - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* XXX : not implemented */ - spr_register(env, SPR_970_HID5, "HID5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - POWERPC970_HID5_INIT); - /* Memory management */ - /* XXX: not correct */ - gen_low_BATs(env); - spr_register(env, SPR_HIOR, "SPR_HIOR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_hior, &spr_write_hior, - 0x00000000); - spr_register(env, SPR_CTRL, "SPR_CTRL", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_UCTRL, "SPR_UCTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_VRSAVE, "SPR_VRSAVE", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Logical partitionning */ - spr_register_kvm(env, SPR_LPCR, "LPCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_LPCR, 0x00000000); -#if !defined(CONFIG_USER_ONLY) - env->slb_nr = 64; -#endif - init_excp_970(env); - env->dcache_line_size = 128; - env->icache_line_size = 128; - /* Allocate hardware IRQ controller */ - ppc970_irq_init(env); - /* Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. */ - vscr_init(env, 0x00010000); + init_proc_book3s_64(env, BOOK3S_CPU_POWER5PLUS); } POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) @@ -6952,7 +7947,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER5"; dc->desc = "POWER5+"; pcc->init_proc = init_proc_power5plus; - pcc->check_pow = check_pow_970FX; + pcc->check_pow = check_pow_970; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6962,7 +7957,21 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_SEGMENT_64B | PPC_SLBI; - pcc->msr_mask = 0x800000000204FF36ULL; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI); pcc->mmu_model = POWERPC_MMU_64B; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; @@ -6977,83 +7986,79 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) pcc->l1_icache_size = 0x10000; } -static void init_proc_POWER7 (CPUPPCState *env) +static void powerpc_get_compat(Object *obj, Visitor *v, + void *opaque, const char *name, Error **errp) { - gen_spr_ne_601(env); - gen_spr_7xx(env); - /* Time base */ - gen_tbl(env); - /* Processor identification */ - spr_register(env, SPR_PIR, "PIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pir, - 0x00000000); -#if !defined(CONFIG_USER_ONLY) - /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ - spr_register_kvm(env, SPR_PURR, "PURR", - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, SPR_NOACCESS, - KVM_REG_PPC_PURR, 0x00000000); - spr_register_kvm(env, SPR_SPURR, "SPURR", - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, SPR_NOACCESS, - KVM_REG_PPC_SPURR, 0x00000000); - spr_register(env, SPR_CFAR, "SPR_CFAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_cfar, &spr_write_cfar, - 0x00000000); - spr_register_kvm(env, SPR_DSCR, "SPR_DSCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DSCR, 0x00000000); - spr_register_kvm(env, SPR_MMCRA, "SPR_MMCRA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_MMCRA, 0x00000000); - spr_register_kvm(env, SPR_PMC5, "SPR_PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_PMC5, 0x00000000); - spr_register_kvm(env, SPR_PMC6, "SPR_PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_PMC6, 0x00000000); -#endif /* !CONFIG_USER_ONLY */ - gen_spr_amr(env); - /* XXX : not implemented */ - spr_register(env, SPR_CTRL, "SPR_CTRLT", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, &spr_write_generic, - 0x80800000); - spr_register(env, SPR_UCTRL, "SPR_CTRLF", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x80800000); - spr_register(env, SPR_VRSAVE, "SPR_VRSAVE", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_PPR, "PPR", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Logical partitionning */ - spr_register_kvm(env, SPR_LPCR, "LPCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_LPCR, 0x00000000); -#if !defined(CONFIG_USER_ONLY) - env->slb_nr = 32; -#endif - init_excp_POWER7(env); - env->dcache_line_size = 128; - env->icache_line_size = 128; + char *value = (char *)""; + Property *prop = opaque; + uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop); - /* Allocate hardware IRQ controller */ - ppcPOWER7_irq_init(env); - /* Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. */ - vscr_init(env, 0x00010000); + switch (*max_compat) { + case CPU_POWERPC_LOGICAL_2_05: + value = (char *)"power6"; + break; + case CPU_POWERPC_LOGICAL_2_06: + value = (char *)"power7"; + break; + case CPU_POWERPC_LOGICAL_2_07: + value = (char *)"power8"; + break; + case 0: + break; + default: + error_setg(errp, "Internal error: compat is set to %x", + max_compat ? *max_compat : -1); + break; + } + + visit_type_str(v, &value, name, errp); +} + +static void powerpc_set_compat(Object *obj, Visitor *v, + void *opaque, const char *name, Error **errp) +{ + Error *error = NULL; + char *value = NULL; + Property *prop = opaque; + uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop); + + visit_type_str(v, &value, name, &error); + if (error) { + error_propagate(errp, error); + return; + } + + if (strcmp(value, "power6") == 0) { + *max_compat = CPU_POWERPC_LOGICAL_2_05; + } else if (strcmp(value, "power7") == 0) { + *max_compat = CPU_POWERPC_LOGICAL_2_06; + } else if (strcmp(value, "power8") == 0) { + *max_compat = CPU_POWERPC_LOGICAL_2_07; + } else { + error_setg(errp, "Invalid compatibility mode \"%s\"", value); + } + + g_free(value); +} + +static PropertyInfo powerpc_compat_propinfo = { + .name = "str", + .legacy_name = "powerpc-server-compat", + .get = powerpc_get_compat, + .set = powerpc_set_compat, +}; + +#define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t) + +static Property powerpc_servercpu_properties[] = { + DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU, max_compat), + DEFINE_PROP_END_OF_LIST(), +}; + +static void init_proc_POWER7 (CPUPPCState *env) +{ + init_proc_book3s_64(env, BOOK3S_CPU_POWER7); } POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) @@ -7063,8 +8068,10 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER7"; dc->desc = "POWER7"; + dc->props = powerpc_servercpu_properties; pcc->pvr = CPU_POWERPC_POWER7_BASE; pcc->pvr_mask = CPU_POWERPC_POWER7_MASK; + pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | @@ -7083,7 +8090,22 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206; - pcc->msr_mask = 0x800000000280FF37ULL; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; @@ -7097,6 +8119,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) POWERPC_FLAG_VSX; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; + pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; } POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) @@ -7106,8 +8129,10 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER7+"; dc->desc = "POWER7+"; + dc->props = powerpc_servercpu_properties; pcc->pvr = CPU_POWERPC_POWER7P_BASE; pcc->pvr_mask = CPU_POWERPC_POWER7P_MASK; + pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | @@ -7126,7 +8151,22 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206; - pcc->msr_mask = 0x800000000280FF37ULL; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; @@ -7140,18 +8180,12 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) POWERPC_FLAG_VSX; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; + pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; } static void init_proc_POWER8(CPUPPCState *env) { - /* inherit P7 */ - init_proc_POWER7(env); - - /* P8 supports the TAR */ - spr_register(env, SPR_TAR, "TAR", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); + init_proc_book3s_64(env, BOOK3S_CPU_POWER8); } POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) @@ -7161,8 +8195,10 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER8"; dc->desc = "POWER8"; + dc->props = powerpc_servercpu_properties; pcc->pvr = CPU_POWERPC_POWER8_BASE; pcc->pvr_mask = CPU_POWERPC_POWER8_MASK; + pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; pcc->init_proc = init_proc_POWER8; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | @@ -7183,7 +8219,23 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 | PPC2_ISA207S; - pcc->msr_mask = 0x800000000280FF37ULL; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_TM) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; @@ -7197,6 +8249,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) POWERPC_FLAG_VSX; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; + pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; } #endif /* defined (TARGET_PPC64) */ @@ -8083,6 +9136,63 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp) } } +int ppc_get_compat_smt_threads(PowerPCCPU *cpu) +{ + int ret = smp_threads; + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + + switch (cpu->cpu_version) { + case CPU_POWERPC_LOGICAL_2_05: + ret = 2; + break; + case CPU_POWERPC_LOGICAL_2_06: + ret = 4; + break; + case CPU_POWERPC_LOGICAL_2_07: + ret = 8; + break; + default: + if (pcc->pcr_mask & PCR_COMPAT_2_06) { + ret = 4; + } else if (pcc->pcr_mask & PCR_COMPAT_2_05) { + ret = 2; + } + break; + } + + return MIN(ret, smp_threads); +} + +int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version) +{ + int ret = 0; + CPUPPCState *env = &cpu->env; + + cpu->cpu_version = cpu_version; + + switch (cpu_version) { + case CPU_POWERPC_LOGICAL_2_05: + env->spr[SPR_PCR] = PCR_COMPAT_2_05; + break; + case CPU_POWERPC_LOGICAL_2_06: + env->spr[SPR_PCR] = PCR_COMPAT_2_06; + break; + case CPU_POWERPC_LOGICAL_2_06_PLUS: + env->spr[SPR_PCR] = PCR_COMPAT_2_06; + break; + default: + env->spr[SPR_PCR] = 0; + break; + } + + if (kvm_enabled() && kvmppc_set_compat(cpu, cpu->max_compat) < 0) { + error_report("Unable to set compatibility mode in KVM"); + ret = -1; + } + + return ret; +} + static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) { ObjectClass *oc = (ObjectClass *)a; @@ -8218,12 +9328,6 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) } } - for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { - if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) { - return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]); - } - } - list = object_class_get_list(TYPE_POWERPC_CPU, false); item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name); if (item != NULL) { @@ -8231,7 +9335,17 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) } g_slist_free(list); - return ret; + if (ret) { + return ret; + } + + for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) { + if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) { + return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]); + } + } + + return NULL; } PowerPCCPU *cpu_ppc_init(const char *cpu_model) @@ -8416,8 +9530,15 @@ static void ppc_cpu_reset(CPUState *s) #if defined(CONFIG_USER_ONLY) msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */ 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 */ +#endif #endif #if defined(TARGET_PPC64) @@ -8519,6 +9640,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) pcc->parent_realize = dc->realize; pcc->pvr = CPU_POWERPC_DEFAULT_MASK; pcc->pvr_mask = CPU_POWERPC_DEFAULT_MASK; + pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always; dc->realize = ppc_cpu_realizefn; dc->unrealize = ppc_cpu_unrealizefn; |