diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/cpu.h | 46 | ||||
-rw-r--r-- | target-ppc/helper.c | 16 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 35 |
3 files changed, 81 insertions, 16 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 1515af9930..0560a38a1e 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 69ed260f75..b9a55b1f2b 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 d5626316c9..805c897248 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) |