diff options
-rw-r--r-- | hw/ppc.c | 102 | ||||
-rw-r--r-- | hw/ppc_chrp.c | 8 | ||||
-rw-r--r-- | hw/ppc_prep.c | 2 | ||||
-rw-r--r-- | target-ppc/cpu.h | 35 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 10 |
5 files changed, 133 insertions, 24 deletions
@@ -56,23 +56,23 @@ static void ppc6xx_set_irq (void *opaque, int pin, int level) #endif cur_level = (env->irq_input_state >> pin) & 1; /* Don't generate spurious events */ - if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0) || 0) { + if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { switch (pin) { - case PPC_INPUT_INT: - /* Level sensitive - asserted high */ + case PPC6xx_INPUT_INT: + /* Level sensitive - active high */ #if defined(PPC_DEBUG_IRQ) printf("%s: set the external IRQ state to %d\n", __func__, level); #endif ppc_set_irq(env, PPC_INTERRUPT_EXT, level); break; - case PPC_INPUT_SMI: + case PPC6xx_INPUT_SMI: /* Level sensitive - active high */ #if defined(PPC_DEBUG_IRQ) printf("%s: set the SMI IRQ state to %d\n", __func__, level); #endif ppc_set_irq(env, PPC_INTERRUPT_SMI, level); break; - case PPC_INPUT_MCP: + case PPC6xx_INPUT_MCP: /* Negative edge sensitive */ /* XXX: TODO: actual reaction may depends on HID0 status * 603/604/740/750: check HID0[EMCP] @@ -84,7 +84,7 @@ static void ppc6xx_set_irq (void *opaque, int pin, int level) ppc_set_irq(env, PPC_INTERRUPT_MCK, 1); } break; - case PPC_INPUT_CKSTP_IN: + case PPC6xx_INPUT_CKSTP_IN: /* Level sensitive - active low */ /* XXX: TODO: relay the signal to CKSTP_OUT pin */ if (level) { @@ -99,7 +99,7 @@ static void ppc6xx_set_irq (void *opaque, int pin, int level) env->halted = 0; } break; - case PPC_INPUT_HRESET: + case PPC6xx_INPUT_HRESET: /* Level sensitive - active low */ if (level) { #if 0 // XXX: TOFIX @@ -110,7 +110,7 @@ static void ppc6xx_set_irq (void *opaque, int pin, int level) #endif } break; - case PPC_INPUT_SRESET: + case PPC6xx_INPUT_SRESET: #if defined(PPC_DEBUG_IRQ) printf("%s: set the RESET IRQ state to %d\n", __func__, level); #endif @@ -135,6 +135,92 @@ void ppc6xx_irq_init (CPUState *env) env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6); } +/* PowerPC 405 internal IRQ controller */ +static void ppc405_set_irq (void *opaque, int pin, int level) +{ + CPUState *env = opaque; + int cur_level; + +#if defined(PPC_DEBUG_IRQ) + printf("%s: env %p pin %d level %d\n", __func__, env, pin, level); +#endif + cur_level = (env->irq_input_state >> pin) & 1; + /* Don't generate spurious events */ + if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { + switch (pin) { + case PPC405_INPUT_RESET_SYS: + /* XXX: TODO: reset all peripherals */ + /* No break here */ + case PPC405_INPUT_RESET_CHIP: + /* XXX: TODO: reset on-chip peripherals */ + /* No break here */ + case PPC405_INPUT_RESET_CORE: + /* XXX: TODO: update DBSR[MRR] */ + if (level) { +#if 0 // XXX: TOFIX +#if defined(PPC_DEBUG_IRQ) + printf("%s: reset the CPU\n", __func__); +#endif + cpu_reset(env); +#endif + } + break; + case PPC405_INPUT_CINT: + /* Level sensitive - active high */ +#if defined(PPC_DEBUG_IRQ) + printf("%s: set the critical IRQ state to %d\n", __func__, level); +#endif + /* XXX: TOFIX */ + ppc_set_irq(env, PPC_INTERRUPT_RESET, level); + break; + case PPC405_INPUT_INT: + /* Level sensitive - active high */ +#if defined(PPC_DEBUG_IRQ) + printf("%s: set the external IRQ state to %d\n", __func__, level); +#endif + ppc_set_irq(env, PPC_INTERRUPT_EXT, level); + break; + case PPC405_INPUT_HALT: + /* Level sensitive - active low */ + if (level) { +#if defined(PPC_DEBUG_IRQ) + printf("%s: stop the CPU\n", __func__); +#endif + env->halted = 1; + } else { +#if defined(PPC_DEBUG_IRQ) + printf("%s: restart the CPU\n", __func__); +#endif + env->halted = 0; + } + break; + case PPC405_INPUT_DEBUG: + /* Level sensitive - active high */ +#if defined(PPC_DEBUG_IRQ) + printf("%s: set the external IRQ state to %d\n", __func__, level); +#endif + ppc_set_irq(env, EXCP_40x_DEBUG, level); + break; + default: + /* Unknown pin - do nothing */ +#if defined(PPC_DEBUG_IRQ) + printf("%s: unknown IRQ pin %d\n", __func__, pin); +#endif + return; + } + if (level) + env->irq_input_state |= 1 << pin; + else + env->irq_input_state &= ~(1 << pin); + } +} + +void ppc405_irq_init (CPUState *env) +{ + printf("%s\n", __func__); + env->irq_inputs = (void **)qemu_allocate_irqs(&ppc405_set_irq, env, 7); +} + /*****************************************************************************/ /* PowerPC time base and decrementer emulation */ //#define DEBUG_TB diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c index c418cd1b4a..70571fd4e0 100644 --- a/hw/ppc_chrp.c +++ b/hw/ppc_chrp.c @@ -470,14 +470,14 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device, */ openpic_irqs[i] = openpic_irqs[0] + (i * OPENPIC_OUTPUT_NB); openpic_irqs[i][OPENPIC_OUTPUT_INT] = - ((qemu_irq *)env->irq_inputs)[PPC_INPUT_INT]; + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_CINT] = - ((qemu_irq *)env->irq_inputs)[PPC_INPUT_INT]; + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; openpic_irqs[i][OPENPIC_OUTPUT_MCK] = - ((qemu_irq *)env->irq_inputs)[PPC_INPUT_MCP]; + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP]; openpic_irqs[i][OPENPIC_OUTPUT_DEBUG] = NULL; /* Not connected ? */ openpic_irqs[i][OPENPIC_OUTPUT_RESET] = - ((qemu_irq *)env->irq_inputs)[PPC_INPUT_HRESET]; /* Check this */ + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET]; /* Check this */ } pic = openpic_init(NULL, &openpic_mem_index, smp_cpus, openpic_irqs, NULL); diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 8b53ef30a8..421d189209 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -598,7 +598,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device, } isa_mem_base = 0xc0000000; - i8259 = i8259_init(first_cpu->irq_inputs[PPC_INPUT_INT]); + i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]); pci_bus = pci_prep_init(i8259); // pci_bus = i440fx_init(); /* Register 8 MB of ISA IO space (needed for non-contiguous map) */ diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 2a2c4409d3..4b67f1a25c 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1315,15 +1315,34 @@ enum { /* 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, + PPC6xx_INPUT_HRESET = 0, + PPC6xx_INPUT_SRESET = 1, + PPC6xx_INPUT_CKSTP_IN = 2, + PPC6xx_INPUT_MCP = 3, + PPC6xx_INPUT_SMI = 4, + PPC6xx_INPUT_INT = 5, +}; + +enum { /* Embedded PowerPC input pins */ - PPC_INPUT_CINT = 6, - PPC_INPUT_NB, + PPCBookE_INPUT_HRESET = 0, + PPCBookE_INPUT_SRESET = 1, + PPCBookE_INPUT_CKSTP_IN = 2, + PPCBookE_INPUT_MCP = 3, + PPCBookE_INPUT_SMI = 4, + PPCBookE_INPUT_INT = 5, + PPCBookE_INPUT_CINT = 6, +}; + +enum { + /* PowerPC 405 input pins */ + PPC405_INPUT_RESET_CORE = 0, + PPC405_INPUT_RESET_CHIP = 1, + PPC405_INPUT_RESET_SYS = 2, + PPC405_INPUT_CINT = 3, + PPC405_INPUT_INT = 4, + PPC405_INPUT_HALT = 5, + PPC405_INPUT_DEBUG = 6, }; /* Hardware exceptions definitions */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 805c897248..72e577dc27 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -45,6 +45,7 @@ static inline void glue(glue(ppc, name),_irq_init) (CPUPPCState *env) \ #define PPC_IRQ_INIT_FN(name) \ void glue(glue(ppc, name),_irq_init) (CPUPPCState *env); #endif +PPC_IRQ_INIT_FN(405); PPC_IRQ_INIT_FN(6xx); /* Generic callbacks: @@ -1909,7 +1910,8 @@ 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 */ + /* Allocate hardware IRQ controller */ + ppc405_irq_init(env); break; case CPU_PPC_NPE405H: /* NPe405 H family */ @@ -1924,7 +1926,8 @@ 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 */ + /* Allocate hardware IRQ controller */ + ppc405_irq_init(env); break; #if defined (TODO) @@ -1956,7 +1959,8 @@ 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 */ + /* Allocate hardware IRQ controller */ + ppc405_irq_init(env); break; case CPU_PPC_440EP: /* 440 EP family */ |