aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/cpu_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc/cpu_init.c')
-rw-r--r--target/ppc/cpu_init.c452
1 files changed, 238 insertions, 214 deletions
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index b0973b6..86ead74 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -45,7 +45,6 @@
#include "internal.h"
#include "spr_common.h"
#include "power8-pmu.h"
-
#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
#include "hw/intc/intc.h"
@@ -851,6 +850,13 @@ static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask,
SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
};
+ const char *tlbcfg_names[4] = {
+ "TLB0CFG", "TLB1CFG", "TLB2CFG", "TLB3CFG",
+ };
+ const int tlbcfg_sprn[4] = {
+ SPR_BOOKE_TLB0CFG, SPR_BOOKE_TLB1CFG,
+ SPR_BOOKE_TLB2CFG, SPR_BOOKE_TLB3CFG,
+ };
int i;
/* TLB assist registers */
@@ -890,34 +896,13 @@ static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask,
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, SPR_NOACCESS,
mmucfg);
- switch (env->nb_ways) {
- case 4:
- spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[3]);
- /* Fallthru */
- case 3:
- spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[2]);
- /* Fallthru */
- case 2:
- spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[1]);
- /* Fallthru */
- case 1:
- spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
+
+ assert(env->nb_ways <= ARRAY_SIZE(tlbcfg_names));
+ for (i = 0; i < env->nb_ways; i++) {
+ spr_register(env, tlbcfg_sprn[i], tlbcfg_names[i],
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, SPR_NOACCESS,
- tlbncfg[0]);
- /* Fallthru */
- case 0:
- default:
- break;
+ tlbncfg[i]);
}
#endif
}
@@ -1654,6 +1639,47 @@ static void register_8xx_sprs(CPUPPCState *env)
* ... and more (thermal management, performance counters, ...)
*/
+static void register_ppe42_sprs(CPUPPCState *env)
+{
+ spr_register(env, SPR_PPE42_EDR, "EDR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_ISR, "ISR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_IVPR, "IVPR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, SPR_NOACCESS,
+ 0xfff80000);
+ spr_register(env, SPR_PPE42_PIR, "PIR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_pir,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_DBCR, "DBCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_40x_dbcr0,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_DACR, "DACR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* Timer */
+ spr_register(env, SPR_DECR, "DECR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_decr, &spr_write_decr,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_TSR, "TSR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_booke_tsr,
+ 0x00000000);
+ spr_register(env, SPR_BOOKE_TCR, "TCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_booke_tcr,
+ 0x00000000);
+}
+
/*****************************************************************************/
/* Exception vectors models */
static void init_excp_4xx(CPUPPCState *env)
@@ -1680,6 +1706,30 @@ static void init_excp_4xx(CPUPPCState *env)
#endif
}
+static void init_excp_ppe42(CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ /* Machine Check vector changed after version 0 */
+ if (((env->spr[SPR_PVR] & 0xf00000ul) >> 20) == 0) {
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
+ } else {
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000020;
+ }
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000040;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000060;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000080;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x000000A0;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x000000C0;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x000000E0;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000120;
+ env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000140;
+ env->ivpr_mask = 0xFFFFFE00UL;
+ /* Hardware reset vector */
+ env->hreset_vector = 0x00000040UL;
+#endif
+}
+
static void init_excp_MPC5xx(CPUPPCState *env)
{
#if !defined(CONFIG_USER_ONLY)
@@ -1761,7 +1811,7 @@ static void init_excp_G2(CPUPPCState *env)
#endif
}
-static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
+static void init_excp_e500(CPUPPCState *env, target_ulong ivpr_mask)
{
#if !defined(CONFIG_USER_ONLY)
env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
@@ -2201,6 +2251,80 @@ POWERPC_FAMILY(405)(ObjectClass *oc, const void *data)
POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
}
+static void init_proc_ppe42(CPUPPCState *env)
+{
+ register_ppe42_sprs(env);
+
+ init_excp_ppe42(env);
+ env->dcache_line_size = 32;
+ env->icache_line_size = 32;
+ /* Allocate hardware IRQ controller */
+ ppc40x_irq_init(env_archcpu(env));
+
+ SET_FIT_PERIOD(8, 12, 16, 20);
+ SET_WDT_PERIOD(16, 20, 24, 28);
+}
+
+static void ppe42_class_common_init(PowerPCCPUClass *pcc)
+{
+ pcc->init_proc = init_proc_ppe42;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->check_attn = check_attn_none;
+ pcc->insns_flags = PPC_INSNS_BASE |
+ PPC_WRTEE |
+ PPC_CACHE |
+ PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC;
+ pcc->msr_mask = R_MSR_SEM_MASK |
+ (1ull << MSR_IS0) |
+ R_MSR_SIBRC_MASK |
+ (1ull << MSR_LP) |
+ (1ull << MSR_WE) |
+ (1ull << MSR_IS1) |
+ (1ull << MSR_UIE) |
+ (1ull << MSR_EE) |
+ (1ull << MSR_ME) |
+ (1ull << MSR_IS2) |
+ (1ull << MSR_IS3) |
+ (1ull << MSR_IPE) |
+ R_MSR_SIBRCA_MASK;
+ pcc->mmu_model = POWERPC_MMU_REAL;
+ pcc->excp_model = POWERPC_EXCP_PPE42;
+ pcc->bus_model = PPC_FLAGS_INPUT_PPE42;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_PPE42 | POWERPC_FLAG_BUS_CLK;
+}
+
+POWERPC_FAMILY(ppe42)(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PPE 42";
+ pcc->insns_flags2 = PPC2_PPE42;
+ ppe42_class_common_init(pcc);
+}
+
+POWERPC_FAMILY(ppe42x)(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PPE 42X";
+ pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X;
+ ppe42_class_common_init(pcc);
+}
+
+POWERPC_FAMILY(ppe42xm)(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PPE 42XM";
+ pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X | PPC2_PPE42XM;
+ ppe42_class_common_init(pcc);
+}
+
static void init_proc_440EP(CPUPPCState *env)
{
register_BookE_sprs(env, 0x000000000000FFFFULL);
@@ -2658,149 +2782,6 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, const void *data)
POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
}
-static void init_proc_e200(CPUPPCState *env)
-{
- register_BookE_sprs(env, 0x000000070000FFFFULL);
-
- spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
- &spr_read_spefscr, &spr_write_spefscr,
- &spr_read_spefscr, &spr_write_spefscr,
- 0x00000000);
- /* Memory management */
- register_BookE206_sprs(env, 0x0000005D, NULL, 0);
- register_usprgh_sprs(env);
-
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- spr_register(env, SPR_MMUCSR0, "MMUCSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000); /* TOFIX */
-
- init_tlbs_emb(env);
- init_excp_e200(env, 0xFFFF0000UL);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-}
-
-POWERPC_FAMILY(e200)(ObjectClass *oc, const void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e200 core";
- pcc->init_proc = init_proc_e200;
- pcc->check_pow = check_pow_hid0;
- pcc->check_attn = check_attn_none;
- /*
- * XXX: unimplemented instructions:
- * dcblc
- * dcbtlst
- * dcbtstls
- * icblc
- * icbtls
- * tlbivax
- * all SPE multiply-accumulate instructions
- */
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
- PPC_SPE | PPC_SPE_SINGLE |
- PPC_WRTEE | PPC_RFDI |
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVAX |
- PPC_BOOKE;
- 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;
- pcc->bfd_mach = bfd_mach_ppc_860;
- pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
enum fsl_e500_version {
fsl_e500v1,
fsl_e500v2,
@@ -3035,7 +3016,7 @@ static void init_proc_e500(CPUPPCState *env, int version)
}
#endif
- init_excp_e200(env, ivpr_mask);
+ init_excp_e500(env, ivpr_mask);
/* Allocate hardware IRQ controller */
ppce500_irq_init(env_archcpu(env));
}
@@ -6803,53 +6784,64 @@ static void init_ppc_proc(PowerPCCPU *cpu)
/* MSR bits & flags consistency checks */
if (env->msr_mask & (1 << 25)) {
- switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
+ switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE |
+ POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_SPE:
case POWERPC_FLAG_VRE:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
+ "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n"
+ "or POWERPC_FLAG_PPE42\n");
exit(1);
}
- } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
+ } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE |
+ POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
+ "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n"
+ "nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if (env->msr_mask & (1 << 17)) {
- switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
+ switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
+ POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_TGPR:
case POWERPC_FLAG_CE:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
+ "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n"
+ "or POWERPC_FLAG_PPE42\n");
exit(1);
}
- } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
+ } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
+ POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
+ "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n"
+ "nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if (env->msr_mask & (1 << 10)) {
switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_UBLE)) {
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_SE:
case POWERPC_FLAG_DWE:
case POWERPC_FLAG_UBLE:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
"Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
- "POWERPC_FLAG_UBLE\n");
+ "POWERPC_FLAG_UBLE or POWERPC_FLAG_PPE42\n");
exit(1);
}
} else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_UBLE)) {
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
"Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
- "POWERPC_FLAG_UBLE\n");
+ "POWERPC_FLAG_UBLE nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if (env->msr_mask & (1 << 9)) {
@@ -6868,18 +6860,23 @@ static void init_ppc_proc(PowerPCCPU *cpu)
exit(1);
}
if (env->msr_mask & (1 << 2)) {
- switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
+ switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_PX:
case POWERPC_FLAG_PMM:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
+ "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n"
+ "or POWERPC_FLAG_PPE42\n");
exit(1);
}
- } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
+ } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
+ "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n"
+ "nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if ((env->flags & POWERPC_FLAG_BUS_CLK) == 0) {
@@ -7115,7 +7112,7 @@ PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
}
/* Sort by PVR, ordering special case "host" last. */
-static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
+static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b, gpointer d)
{
ObjectClass *oc_a = (ObjectClass *)a;
ObjectClass *oc_b = (ObjectClass *)b;
@@ -7144,6 +7141,7 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
const char *typename = object_class_get_name(oc);
char *name;
@@ -7154,7 +7152,11 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
}
name = cpu_model_from_type(typename);
- qemu_printf(" %-16s PVR %08x\n", name, pcc->pvr);
+ if (cc->deprecation_note) {
+ qemu_printf(" %-16s PVR %08x (deprecated)\n", name, pcc->pvr);
+ } else {
+ qemu_printf(" %-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);
@@ -7183,7 +7185,7 @@ static void ppc_cpu_list(void)
qemu_printf("Available CPUs:\n");
list = object_class_get_list(TYPE_POWERPC_CPU, false);
- list = g_slist_sort(list, ppc_cpu_list_compare);
+ list = g_slist_sort_with_data(list, ppc_cpu_list_compare, NULL);
g_slist_foreach(list, ppc_cpu_list_entry, NULL);
g_slist_free(list);
@@ -7226,7 +7228,7 @@ static int ppc_cpu_mmu_index(CPUState *cs, bool ifetch)
#ifndef CONFIG_USER_ONLY
static bool ppc_cpu_has_work(CPUState *cs)
{
- return cs->interrupt_request & CPU_INTERRUPT_HARD;
+ return cpu_test_interrupt(cs, CPU_INTERRUPT_HARD);
}
#endif /* !CONFIG_USER_ONLY */
@@ -7244,39 +7246,40 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
}
msr = (target_ulong)0;
- msr |= (target_ulong)MSR_HVB;
- msr |= (target_ulong)1 << MSR_EP;
+ if (!(env->flags & POWERPC_FLAG_PPE42)) {
+ msr |= (target_ulong)MSR_HVB;
+ 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;
+ /* 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;
+ 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 */
+ msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
#endif
#if !TARGET_BIG_ENDIAN
- 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);
- }
+ 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);
- }
+ if (mmu_is_64bit(env->mmu_model)) {
+ msr |= (1ULL << MSR_SF);
+ }
#endif
-
+ }
hreg_store_msr(env, msr, 1);
#if !defined(CONFIG_USER_ONLY)
@@ -7387,6 +7390,12 @@ static void ppc_cpu_exec_exit(CPUState *cs)
cpu->vhyp_class->cpu_exec_exit(cpu->vhyp, cpu);
}
}
+
+static vaddr ppc_pointer_wrap(CPUState *cs, int mmu_idx,
+ vaddr result, vaddr base)
+{
+ return (cpu_env(cs)->hflags >> HFLAGS_64) & 1 ? result : (uint32_t)result;
+}
#endif /* CONFIG_TCG */
#endif /* !CONFIG_USER_ONLY */
@@ -7483,6 +7492,7 @@ static const TCGCPUOps ppc_tcg_ops = {
.guest_default_memory_order = 0,
.initialize = ppc_translate_init,
.translate_code = ppc_translate_code,
+ .get_tb_cpu_state = ppc_get_tb_cpu_state,
.restore_state_to_opc = ppc_restore_state_to_opc,
.mmu_index = ppc_cpu_mmu_index,
@@ -7490,8 +7500,10 @@ static const TCGCPUOps ppc_tcg_ops = {
.record_sigsegv = ppc_cpu_record_sigsegv,
#else
.tlb_fill = ppc_cpu_tlb_fill,
+ .pointer_wrap = ppc_pointer_wrap,
.cpu_exec_interrupt = ppc_cpu_exec_interrupt,
.cpu_exec_halt = ppc_cpu_has_work,
+ .cpu_exec_reset = cpu_reset,
.do_interrupt = ppc_cpu_do_interrupt,
.cpu_exec_enter = ppc_cpu_exec_enter,
.cpu_exec_exit = ppc_cpu_exec_exit,
@@ -7717,6 +7729,18 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
* they can be read with "p $ivor0", "p $ivor1", etc.
*/
break;
+ case POWERPC_EXCP_PPE42:
+ qemu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx "\n",
+ env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
+
+ qemu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx
+ " ISR " TARGET_FMT_lx " EDR " TARGET_FMT_lx "\n",
+ env->spr[SPR_PPE42_TCR], env->spr[SPR_PPE42_TSR],
+ env->spr[SPR_PPE42_ISR], env->spr[SPR_PPE42_EDR]);
+
+ qemu_fprintf(f, " PIR " TARGET_FMT_lx " IVPR " TARGET_FMT_lx "\n",
+ env->spr[SPR_PPE42_PIR], env->spr[SPR_PPE42_IVPR]);
+ break;
case POWERPC_EXCP_40x:
qemu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx
" ESR " TARGET_FMT_lx " DEAR " TARGET_FMT_lx "\n",