Add PowerPC 405 input pins (IRQ, resets, ...) model.
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 12 Apr 2007 21:24:29 +0000 (21:24 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 12 Apr 2007 21:24:29 +0000 (21:24 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2654 c046a42c-6fe2-441c-8c8c-71466251a162

hw/ppc.c
hw/ppc_chrp.c
hw/ppc_prep.c
target-ppc/cpu.h
target-ppc/translate_init.c

index f502271..8438bc6 100644 (file)
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -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
index c418cd1..70571fd 100644 (file)
@@ -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);
index 8b53ef3..421d189 100644 (file)
@@ -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) */
index 2a2c440..4b67f1a 100644 (file)
@@ -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 */
index 805c897..72e577d 100644 (file)
@@ -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                 */