aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/translate_init.c
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-09-29 13:06:16 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-09-29 13:06:16 +0000
commite1833e1f96456fd8fc17463246fe0b2050e68efb (patch)
tree5d50859e3cb0a1c2628811d7255f112a9f87cdca /target-ppc/translate_init.c
parentf93732914e0b06539170e84f046f01ebe99980f3 (diff)
Rework PowerPC exceptions model to make it more versatile:
* don't use exception vectors as the exception number. Use vectors numbers as defined in the PowerPC embedded specification instead and extend this model to cover all emulated PowerPC variants exceptions. * add some missing exceptions definitions, from PowerPC 2.04 specification and actual PowerPC implementations. * add code provision for hypervisor exceptions handling. * define exception vectors and prefix in CPUPPCState to emulate BookE exception vectors without any hacks. * define per CPU model valid exception vectors. * handle all known exceptions in user-mode only emulations. * fix hardware interrupts priorities in most cases. * change RET_EXCP macros name into GEN_EXCP as they don't return. * do not stop translation on most instructions that are not defined as context-synchronizing in PowerPC specification. * fix PowerPC 64 jump targets and link register update when in 32 bits mode. * Fix PowerPC 464 and 464F definitions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3261 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc/translate_init.c')
-rw-r--r--target-ppc/translate_init.c421
1 files changed, 404 insertions, 17 deletions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e3cb183609..109dcdc256 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -192,7 +192,7 @@ static void spr_write_ibatu (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_ibatu((sprn - SPR_IBAT0U) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_ibatu_h (void *opaque, int sprn)
@@ -200,7 +200,7 @@ static void spr_write_ibatu_h (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_ibatu((sprn - SPR_IBAT4U) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_ibatl (void *opaque, int sprn)
@@ -208,7 +208,7 @@ static void spr_write_ibatl (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_ibatl((sprn - SPR_IBAT0L) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_ibatl_h (void *opaque, int sprn)
@@ -216,7 +216,7 @@ static void spr_write_ibatl_h (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_ibatl((sprn - SPR_IBAT4L) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
/* DBAT0U...DBAT7U */
@@ -236,7 +236,7 @@ static void spr_write_dbatu (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_dbatu((sprn - SPR_DBAT0U) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_dbatu_h (void *opaque, int sprn)
@@ -244,7 +244,7 @@ static void spr_write_dbatu_h (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_dbatu((sprn - SPR_DBAT4U) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_dbatl (void *opaque, int sprn)
@@ -252,7 +252,7 @@ static void spr_write_dbatl (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_dbatl((sprn - SPR_DBAT0L) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_dbatl_h (void *opaque, int sprn)
@@ -260,7 +260,7 @@ static void spr_write_dbatl_h (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_dbatl((sprn - SPR_DBAT4L) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
/* SDR1 */
@@ -274,7 +274,7 @@ static void spr_write_sdr1 (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_sdr1();
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
/* 64 bits PowerPC specific SPRs */
@@ -291,7 +291,7 @@ static void spr_write_asr (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_asr();
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
#endif
#endif
@@ -332,7 +332,7 @@ static void spr_write_601_ubatu (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_601_batu((sprn - SPR_IBAT0U) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_601_ubatl (void *opaque, int sprn)
@@ -340,7 +340,7 @@ static void spr_write_601_ubatl (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_601_batl((sprn - SPR_IBAT0L) / 2);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
#endif
@@ -362,7 +362,7 @@ static void spr_write_40x_dbcr0 (void *opaque, int sprn)
gen_op_store_40x_dbcr0();
/* We must stop translation as we may have rebooted */
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_40x_sler (void *opaque, int sprn)
@@ -373,7 +373,7 @@ static void spr_write_40x_sler (void *opaque, int sprn)
/* We must stop the translation as we may have changed
* some regions endianness
*/
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_booke_tcr (void *opaque, int sprn)
@@ -400,7 +400,7 @@ static void spr_write_403_pbr (void *opaque, int sprn)
DisasContext *ctx = opaque;
gen_op_store_403_pb(sprn - SPR_403_PBL1);
- RET_STOP(ctx);
+ GEN_STOP(ctx);
}
static void spr_write_pir (void *opaque, int sprn)
@@ -2153,6 +2153,323 @@ static void gen_spr_620 (CPUPPCState *env)
*/
/*****************************************************************************/
+/* Exception vectors models */
+static void init_excp_4xx_real (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
+ env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
+ env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
+ env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
+#endif
+}
+
+static void init_excp_4xx_softmmu (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
+ env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
+ env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
+ env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
+ env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
+ env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
+#endif
+}
+
+static void init_excp_BookE (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
+ env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
+ env->excp_prefix = 0x00000000;
+ env->ivor_mask = 0x0000FFE0;
+ env->ivpr_mask = 0xFFFF0000;
+#endif
+}
+
+static void init_excp_601 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
+ env->excp_prefix = 0xFFF00000;
+#endif
+}
+
+static void init_excp_602 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
+ env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
+ env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
+ env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+ env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
+ env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
+ env->excp_prefix = 0xFFF00000;
+#endif
+}
+
+static void init_excp_603 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
+ env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
+ env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+#endif
+}
+
+static void init_excp_G2 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
+ env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
+ env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+#endif
+}
+
+static void init_excp_604 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+#endif
+}
+
+#if defined (TODO)
+static void init_excp_620 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+#endif
+}
+#endif /* defined (TODO) */
+
+static void init_excp_7x0 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
+#endif
+}
+
+static void init_excp_750FX (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+ env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
+#endif
+}
+
+static void init_excp_7400 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+ env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
+ env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
+#endif
+}
+
+#if defined (TODO)
+static void init_excp_7450 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
+ env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
+ env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
+ env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
+ env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
+#endif
+}
+#endif /* defined (TODO) */
+
+#if defined (TARGET_PPC64)
+static void init_excp_970 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
+ env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
+ env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
+ env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
+#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
+ env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
+#endif
+ env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
+ env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
+ env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
+ env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
+ env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
+ env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
+ env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
+ env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
+#endif
+}
+#endif
+
+/*****************************************************************************/
/* PowerPC implementations definitions */
/* PowerPC 40x instruction set */
@@ -2183,6 +2500,7 @@ static void init_proc_401 (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ init_excp_4xx_real(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2218,6 +2536,7 @@ static void init_proc_401x2 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_4xx_softmmu(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2234,8 +2553,9 @@ static void init_proc_401x2 (CPUPPCState *env)
#define POWERPC_INPUT_401x3 (PPC_FLAGS_INPUT_401)
#define POWERPC_BFDM_401x3 (bfd_mach_ppc_403)
-static void init_proc_401x2 (CPUPPCState *env)
+static void init_proc_401x3 (CPUPPCState *env)
{
+ init_excp_4xx_softmmu(env);
}
#endif /* TODO */
@@ -2271,6 +2591,7 @@ static void init_proc_IOP480 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_4xx_softmmu(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2291,6 +2612,7 @@ static void init_proc_403 (CPUPPCState *env)
gen_spr_401_403(env);
gen_spr_403(env);
gen_spr_403_real(env);
+ init_excp_4xx_real(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2326,6 +2648,7 @@ static void init_proc_403GCX (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_4xx_softmmu(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2361,6 +2684,7 @@ static void init_proc_405 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_4xx_softmmu(env);
/* Allocate hardware IRQ controller */
ppc405_irq_init(env);
}
@@ -2402,6 +2726,7 @@ static void init_proc_440EP (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_BookE(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2426,6 +2751,7 @@ static void init_proc_440GP (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_BookE(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2451,6 +2777,7 @@ static void init_proc_440x4 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_BookE(env);
/* XXX: TODO: allocate internal IRQ controller */
}
#endif /* TODO */
@@ -2492,6 +2819,7 @@ static void init_proc_440x5 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_BookE(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2509,6 +2837,36 @@ static void init_proc_440x5 (CPUPPCState *env)
static void init_proc_460 (CPUPPCState *env)
{
+ /* Time base */
+ gen_tbl(env);
+ gen_spr_BookE(env);
+ gen_spr_440(env);
+ spr_register(env, SPR_BOOKE_MCSR, "MCSR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_440_CCR1, "CCR1",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
+ &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* Memory management */
+ env->nb_tlb = 64;
+ env->nb_ways = 1;
+ env->id_tlbs = 0;
+ init_excp_BookE(env);
+ /* XXX: TODO: allocate internal IRQ controller */
}
#endif /* TODO */
@@ -2527,7 +2885,7 @@ static void init_proc_460 (CPUPPCState *env)
#define POWERPC_INPUT_460F (PPC_FLAGS_INPUT_BookE)
#define POWERPC_BFDM_460F (bfd_mach_ppc_403)
-static void init_proc_460 (CPUPPCState *env)
+static void init_proc_460F (CPUPPCState *env)
{
/* Time base */
gen_tbl(env);
@@ -2557,6 +2915,7 @@ static void init_proc_460 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_BookE(env);
/* XXX: TODO: allocate internal IRQ controller */
}
#endif /* TODO */
@@ -2578,6 +2937,7 @@ static void init_proc_460 (CPUPPCState *env)
static void init_proc_BookE (CPUPPCState *env)
{
+ init_excp_BookE(env);
}
#endif /* TODO */
@@ -2610,6 +2970,7 @@ static void init_proc_e500 (CPUPPCState *env)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ init_excp_BookE(env);
/* XXX: TODO: allocate internal IRQ controller */
}
#endif /* TODO */
@@ -2678,6 +3039,7 @@ static void init_proc_601 (CPUPPCState *env)
env->nb_ways = 2;
env->id_tlbs = 0;
env->id_tlbs = 0;
+ init_excp_601(env);
/* XXX: TODO: allocate internal IRQ controller */
}
@@ -2712,6 +3074,7 @@ static void init_proc_602 (CPUPPCState *env)
/* Memory management */
gen_low_BATs(env);
gen_6xx_7xx_soft_tlb(env, 64, 2);
+ init_excp_602(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2744,6 +3107,7 @@ static void init_proc_603 (CPUPPCState *env)
/* Memory management */
gen_low_BATs(env);
gen_6xx_7xx_soft_tlb(env, 64, 2);
+ init_excp_603(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2781,6 +3145,7 @@ static void init_proc_603E (CPUPPCState *env)
/* Memory management */
gen_low_BATs(env);
gen_6xx_7xx_soft_tlb(env, 64, 2);
+ init_excp_603(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2820,6 +3185,7 @@ static void init_proc_G2 (CPUPPCState *env)
gen_low_BATs(env);
gen_high_BATs(env);
gen_6xx_7xx_soft_tlb(env, 64, 2);
+ init_excp_G2(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2859,6 +3225,7 @@ static void init_proc_G2LE (CPUPPCState *env)
gen_low_BATs(env);
gen_high_BATs(env);
gen_6xx_7xx_soft_tlb(env, 64, 2);
+ init_excp_G2(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2890,6 +3257,7 @@ static void init_proc_604 (CPUPPCState *env)
0x00000000);
/* Memory management */
gen_low_BATs(env);
+ init_excp_604(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2923,6 +3291,7 @@ static void init_proc_7x0 (CPUPPCState *env)
0x00000000);
/* Memory management */
gen_low_BATs(env);
+ init_excp_7x0(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -2963,6 +3332,7 @@ static void init_proc_750fx (CPUPPCState *env)
gen_low_BATs(env);
/* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
gen_high_BATs(env);
+ init_excp_750FX(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -3038,6 +3408,7 @@ static void init_proc_7400 (CPUPPCState *env)
gen_spr_thrm(env);
/* Memory management */
gen_low_BATs(env);
+ init_excp_7400(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -3076,6 +3447,7 @@ static void init_proc_7410 (CPUPPCState *env)
0x00000000);
/* Memory management */
gen_low_BATs(env);
+ init_excp_7400(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -3201,6 +3573,7 @@ static void init_proc_7450 (CPUPPCState *env)
/* Memory management */
gen_low_BATs(env);
gen_74xx_soft_tlb(env);
+ init_excp_7450(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -3297,6 +3670,7 @@ static void init_proc_7445 (CPUPPCState *env)
gen_low_BATs(env);
gen_high_BATs(env);
gen_74xx_soft_tlb(env);
+ init_excp_7450(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -3395,6 +3769,7 @@ static void init_proc_7455 (CPUPPCState *env)
gen_low_BATs(env);
gen_high_BATs(env);
gen_74xx_soft_tlb(env);
+ init_excp_7450(env);
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
@@ -3439,6 +3814,7 @@ static void init_proc_970 (CPUPPCState *env)
#if 0 // TODO
env->slb_nr = 32;
#endif
+ init_excp_970(env);
/* Allocate hardware IRQ controller */
ppc970_irq_init(env);
}
@@ -3481,6 +3857,7 @@ static void init_proc_970FX (CPUPPCState *env)
#if 0 // TODO
env->slb_nr = 32;
#endif
+ init_excp_970(env);
/* Allocate hardware IRQ controller */
ppc970_irq_init(env);
}
@@ -3523,6 +3900,7 @@ static void init_proc_970GX (CPUPPCState *env)
#if 0 // TODO
env->slb_nr = 32;
#endif
+ init_excp_970(env);
/* Allocate hardware IRQ controller */
ppc970_irq_init(env);
}
@@ -3552,6 +3930,7 @@ static void init_proc_620 (CPUPPCState *env)
/* Memory management */
gen_low_BATs(env);
gen_high_BATs(env);
+ init_excp_620(env);
/* XXX: TODO: initialize internal interrupt controller */
}
#endif /* TODO */
@@ -5046,7 +5425,15 @@ static ppc_def_t ppc_defs[] = {
static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
{
#if !defined(CONFIG_USER_ONLY)
+ int i;
+
env->irq_inputs = NULL;
+ /* Set all exception vectors to an invalid address */
+ for (i = 0; i < POWERPC_EXCP_NB; i++)
+ env->excp_vectors[i] = (target_ulong)(-1ULL);
+ env->excp_prefix = 0x00000000;
+ env->ivor_mask = 0x00000000;
+ env->ivpr_mask = 0x00000000;
#endif
/* Default MMU definitions */
env->nb_BATs = 0;