]> git.proxmox.com Git - mirror_qemu.git/commitdiff
powerpc: Make the decr interrupt type overridable
authorEdgar E. Iglesias <edgar.iglesias@gmail.com>
Mon, 20 Sep 2010 17:08:42 +0000 (19:08 +0200)
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>
Fri, 24 Sep 2010 20:01:24 +0000 (22:01 +0200)
Make it possible for boards to override the kind of interrupt
to be signaled when the decr timer hits. The 405's signal PIT
interrupts while the 440's signal DECR.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
hw/ppc.c
hw/ppc.h
hw/ppc4xx_devs.c

index 55e380844c005064814fba5828da6dd280341dc0..968aec1b16cdc039f81f1450762b4946b2364447 100644 (file)
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -769,6 +769,9 @@ struct ppcemb_timer_t {
     struct QEMUTimer *fit_timer;
     uint64_t wdt_next;    /* Tick for next WDT interrupt  */
     struct QEMUTimer *wdt_timer;
+
+    /* 405 have the PIT, 440 have a DECR.  */
+    unsigned int decr_excp;
 };
 
 /* Fixed interval timer */
@@ -851,7 +854,7 @@ static void cpu_4xx_pit_cb (void *opaque)
     ppcemb_timer = tb_env->opaque;
     env->spr[SPR_40x_TSR] |= 1 << 27;
     if ((env->spr[SPR_40x_TCR] >> 26) & 0x1)
-        ppc_set_irq(env, PPC_INTERRUPT_PIT, 1);
+        ppc_set_irq(env, ppcemb_timer->decr_excp, 1);
     start_stop_pit(env, tb_env, 1);
     LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " "
            "%016" PRIx64 "\n", __func__,
@@ -948,10 +951,15 @@ target_ulong load_40x_pit (CPUState *env)
 
 void store_booke_tsr (CPUState *env, target_ulong val)
 {
+    ppc_tb_t *tb_env = env->tb_env;
+    ppcemb_timer_t *ppcemb_timer;
+
+    ppcemb_timer = tb_env->opaque;
+
     LOG_TB("%s: val " TARGET_FMT_lx "\n", __func__, val);
     env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000);
     if (val & 0x80000000)
-        ppc_set_irq(env, PPC_INTERRUPT_PIT, 0);
+        ppc_set_irq(env, ppcemb_timer->decr_excp, 0);
 }
 
 void store_booke_tcr (CPUState *env, target_ulong val)
@@ -977,7 +985,8 @@ static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq)
     /* XXX: we should also update all timers */
 }
 
-clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
+clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq,
+                                  unsigned int decr_excp)
 {
     ppc_tb_t *tb_env;
     ppcemb_timer_t *ppcemb_timer;
@@ -996,6 +1005,7 @@ clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq)
             qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env);
         ppcemb_timer->wdt_timer =
             qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env);
+        ppcemb_timer->decr_excp = decr_excp;
     }
 
     return &ppc_emb_set_tb_clk;
index 125193210387121541bd6117168614543a1d1059..34f54cf5da42bddc02d902670b689f12a68e29f8 100644 (file)
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -19,7 +19,9 @@ int ppc_dcr_init (CPUState *env, int (*dcr_read_error)(int dcrn),
                   int (*dcr_write_error)(int dcrn));
 int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
                       dcr_read_cb drc_read, dcr_write_cb dcr_write);
-clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq);
+clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq,
+                                  unsigned int decr_excp);
+
 /* Embedded PowerPC reset */
 void ppc40x_core_reset (CPUState *env);
 void ppc40x_chip_reset (CPUState *env);
index 7f698b8267dbba43303de1257c28a968c126610c..5f581fe2c4eaee80c4b44fd05febc333e2863c72 100644 (file)
@@ -56,7 +56,7 @@ CPUState *ppc4xx_init (const char *cpu_model,
     cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */
     cpu_clk->opaque = env;
     /* Set time-base frequency to sysclk */
-    tb_clk->cb = ppc_emb_timers_init(env, sysclk);
+    tb_clk->cb = ppc_emb_timers_init(env, sysclk, PPC_INTERRUPT_PIT);
     tb_clk->opaque = env;
     ppc_dcr_init(env, NULL, NULL);
     /* Register qemu callbacks */