aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/cpu.h46
-rw-r--r--target-ppc/helper.c16
-rw-r--r--target-ppc/translate_init.c35
3 files changed, 81 insertions, 16 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1515af9..0560a38 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -758,7 +758,13 @@ struct CPUPPCState {
int error_code;
int interrupt_request;
uint32_t pending_interrupts;
- void *irq[32];
+#if !defined(CONFIG_USER_ONLY)
+ /* This is the IRQ controller, which is implementation dependant
+ * and only relevant when emulating a complete machine.
+ */
+ uint32_t irq_input_state;
+ void **irq_inputs;
+#endif
/* Those resources are used only during code translation */
/* Next instruction pointer */
@@ -801,6 +807,7 @@ int cpu_ppc_signal_handler(int host_signum, void *pinfo,
void *puc);
void do_interrupt (CPUPPCState *env);
+void ppc_hw_interrupt (CPUPPCState *env);
void cpu_loop_exit(void);
void dump_stack (CPUPPCState *env);
@@ -1303,16 +1310,35 @@ enum {
/* Hardware interruption sources:
* all those exception can be raised simulteaneously
*/
+/* Input pins definitions */
+enum {
+ /* 6xx bus input pins */
+ PPC_INPUT_HRESET = 0,
+ PPC_INPUT_SRESET = 1,
+ PPC_INPUT_CKSTP_IN = 2,
+ PPC_INPUT_MCP = 3,
+ PPC_INPUT_SMI = 4,
+ PPC_INPUT_INT = 5,
+ /* Embedded PowerPC input pins */
+ PPC_INPUT_CINT = 6,
+ PPC_INPUT_NB,
+};
+
+/* Hardware exceptions definitions */
enum {
- PPC_INTERRUPT_RESET = 0, /* Reset / critical input */
- PPC_INTERRUPT_MCK = 1, /* Machine check exception */
- PPC_INTERRUPT_EXT = 2, /* External interrupt */
- PPC_INTERRUPT_DECR = 3, /* Decrementer exception */
- PPC_INTERRUPT_HDECR = 4, /* Hypervisor decrementer exception */
- PPC_INTERRUPT_PIT = 5, /* Programmable inteval timer interrupt */
- PPC_INTERRUPT_FIT = 6, /* Fixed interval timer interrupt */
- PPC_INTERRUPT_WDT = 7, /* Watchdog timer interrupt */
- PPC_INTERRUPT_DEBUG = 8, /* External debug exception */
+ /* External hardware exception sources */
+ PPC_INTERRUPT_RESET = 0, /* Reset exception */
+ PPC_INTERRUPT_MCK = 1, /* Machine check exception */
+ PPC_INTERRUPT_EXT = 2, /* External interrupt */
+ PPC_INTERRUPT_SMI = 3, /* System management interrupt */
+ PPC_INTERRUPT_CEXT = 4, /* Critical external interrupt */
+ PPC_INTERRUPT_DEBUG = 5, /* External debug exception */
+ /* Internal hardware exception sources */
+ PPC_INTERRUPT_DECR = 6, /* Decrementer exception */
+ PPC_INTERRUPT_HDECR = 7, /* Hypervisor decrementer exception */
+ PPC_INTERRUPT_PIT = 8, /* Programmable inteval timer interrupt */
+ PPC_INTERRUPT_FIT = 9, /* Fixed interval timer interrupt */
+ PPC_INTERRUPT_WDT = 10, /* Watchdog timer interrupt */
};
/*****************************************************************************/
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 69ed260..b9a55b1 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1358,11 +1358,9 @@ void do_interrupt (CPUState *env)
env->exception_index = -1;
}
-int ppc_hw_interrupt (CPUState *env)
+void ppc_hw_interrupt (CPUState *env)
{
env->exception_index = -1;
-
- return 0;
}
#else /* defined (CONFIG_USER_ONLY) */
static void dump_syscall(CPUState *env)
@@ -1927,7 +1925,7 @@ void do_interrupt (CPUState *env)
env->exception_index = EXCP_NONE;
}
-int ppc_hw_interrupt (CPUState *env)
+void ppc_hw_interrupt (CPUPPCState *env)
{
int raised = 0;
@@ -1940,6 +1938,9 @@ int ppc_hw_interrupt (CPUState *env)
/* Raise it */
if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
/* External reset / critical input */
+ /* XXX: critical input should be handled another way.
+ * This code is not correct !
+ */
env->exception_index = EXCP_RESET;
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
raised = 1;
@@ -1984,7 +1985,12 @@ int ppc_hw_interrupt (CPUState *env)
/* External interrupt */
} else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
env->exception_index = EXCP_EXTERNAL;
+ /* Taking an external interrupt does not clear the external
+ * interrupt status
+ */
+#if 0
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
+#endif
raised = 1;
}
#if 0 // TODO
@@ -1999,7 +2005,5 @@ int ppc_hw_interrupt (CPUState *env)
env->error_code = 0;
do_interrupt(env);
}
-
- return raised;
}
#endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index d562631..805c897 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -35,6 +35,18 @@ struct ppc_def_t {
uint64_t msr_mask;
};
+/* For user-mode emulation, we don't emulate any IRQ controller */
+#if defined(CONFIG_USER_ONLY)
+#define PPC_IRQ_INIT_FN(name) \
+static inline void glue(glue(ppc, name),_irq_init) (CPUPPCState *env) \
+{ \
+}
+#else
+#define PPC_IRQ_INIT_FN(name) \
+void glue(glue(ppc, name),_irq_init) (CPUPPCState *env);
+#endif
+PPC_IRQ_INIT_FN(6xx);
+
/* Generic callbacks:
* do nothing but store/retrieve spr value
*/
@@ -1865,6 +1877,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
case CPU_PPC_403GA: /* 403 GA family */
@@ -1879,6 +1892,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
case CPU_PPC_405CR: /* 405 GP/CR family */
@@ -1895,6 +1909,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
case CPU_PPC_NPE405H: /* NPe405 H family */
@@ -1909,6 +1924,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
#if defined (TODO)
@@ -1940,6 +1956,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
case CPU_PPC_440EP: /* 440 EP family */
@@ -1959,6 +1976,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
/* Embedded PowerPC from Freescale */
@@ -1994,6 +2012,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_tlb = 64;
env->nb_ways = 1;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
#if defined (TODO)
@@ -2038,6 +2057,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
env->nb_ways = 2;
env->id_tlbs = 0;
env->id_tlbs = 0;
+ /* XXX: TODO: allocate internal IRQ controller */
break;
case CPU_PPC_602: /* PowerPC 602 */
@@ -2060,6 +2080,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
case CPU_PPC_603: /* PowerPC 603 */
@@ -2087,6 +2109,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
case CPU_PPC_G2: /* PowerPC G2 family */
@@ -2123,6 +2147,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
case CPU_PPC_604: /* PowerPC 604 */
@@ -2146,6 +2172,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
case CPU_PPC_74x: /* PowerPC 740 / 750 */
@@ -2178,6 +2206,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
case CPU_PPC_750FX10: /* IBM PowerPC 750 FX */
@@ -2213,6 +2243,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
case CPU_PPC_755_10: /* PowerPC 755 */
@@ -2257,6 +2289,8 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
break;
#if defined (TODO)
@@ -2326,6 +2360,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
default:
gen_spr_generic(env);
+ /* XXX: TODO: allocate internal IRQ controller */
break;
}
if (env->nb_BATs == -1)