Commit 703243a044c8b7d5c52fdf67e4c1aacf1d6c4d76

Authored by balrog
1 parent b7d35e65

Adds interrupt support to the sh specific timer code (Magnus Damm).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3812 c046a42c-6fe2-441c-8c8c-71466251a162
... ... @@ -2,6 +2,8 @@
2 2 #define QEMU_SH_H
3 3 /* Definitions for SH board emulation. */
4 4  
  5 +#include "sh_intc.h"
  6 +
5 7 /* sh7750.c */
6 8 struct SH7750State;
7 9  
... ... @@ -25,7 +27,10 @@ int sh7750_register_io_device(struct SH7750State *s,
25 27 #define TMU012_FEAT_TOCR (1 << 0)
26 28 #define TMU012_FEAT_3CHAN (1 << 1)
27 29 #define TMU012_FEAT_EXTCLK (1 << 2)
28   -void tmu012_init(uint32_t base, int feat, uint32_t freq);
  30 +void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
  31 + struct intc_source *ch0_irq, struct intc_source *ch1_irq,
  32 + struct intc_source *ch2_irq0, struct intc_source *ch2_irq1);
  33 +
29 34  
30 35 /* sh_serial.c */
31 36 #define SH_SERIAL_FEAT_SCIF (1 << 0)
... ...
hw/sh7750.c
... ... @@ -559,8 +559,11 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
559 559  
560 560 tmu012_init(0x1fd80000,
561 561 TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
562   - s->periph_freq);
563   -
  562 + s->periph_freq,
  563 + sh_intc_source(&s->intc, TMU0),
  564 + sh_intc_source(&s->intc, TMU1),
  565 + sh_intc_source(&s->intc, TMU2_TUNI),
  566 + sh_intc_source(&s->intc, TMU2_TICPI));
564 567  
565 568 if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
566 569 sh_intc_register_sources(&s->intc,
... ... @@ -578,7 +581,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
578 581 sh_intc_register_sources(&s->intc,
579 582 _INTC_ARRAY(vectors_tmu34),
580 583 NULL, 0);
581   - tmu012_init(0x1e100000, 0, s->periph_freq);
  584 + tmu012_init(0x1e100000, 0, s->periph_freq,
  585 + sh_intc_source(&s->intc, TMU3),
  586 + sh_intc_source(&s->intc, TMU4),
  587 + NULL, NULL);
582 588 }
583 589  
584 590 if (cpu_model & (SH_CPU_SH7751_ALL)) {
... ...
hw/sh_timer.c
... ... @@ -33,23 +33,23 @@ typedef struct {
33 33 uint32_t tcpr;
34 34 int freq;
35 35 int int_level;
  36 + int old_level;
36 37 int feat;
37 38 int enabled;
38   - qemu_irq irq;
  39 + struct intc_source *irq;
39 40 } sh_timer_state;
40 41  
41 42 /* Check all active timers, and schedule the next timer interrupt. */
42 43  
43 44 static void sh_timer_update(sh_timer_state *s)
44 45 {
45   -#if 0 /* not yet */
46   - /* Update interrupts. */
47   - if (s->int_level && (s->tcr & TIMER_TCR_UNIE)) {
48   - qemu_irq_raise(s->irq);
49   - } else {
50   - qemu_irq_lower(s->irq);
51   - }
52   -#endif
  46 + int new_level = s->int_level && (s->tcr & TIMER_TCR_UNIE);
  47 +
  48 + if (new_level != s->old_level)
  49 + sh_intc_toggle_source(s->irq, 0, new_level ? 1 : -1);
  50 +
  51 + s->old_level = s->int_level;
  52 + s->int_level = new_level;
53 53 }
54 54  
55 55 static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset)
... ... @@ -185,7 +185,7 @@ static void sh_timer_tick(void *opaque)
185 185 sh_timer_update(s);
186 186 }
187 187  
188   -static void *sh_timer_init(uint32_t freq, int feat)
  188 +static void *sh_timer_init(uint32_t freq, int feat, struct intc_source *irq)
189 189 {
190 190 sh_timer_state *s;
191 191 QEMUBH *bh;
... ... @@ -198,6 +198,7 @@ static void *sh_timer_init(uint32_t freq, int feat)
198 198 s->tcpr = 0xdeadbeef;
199 199 s->tcor = 0;
200 200 s->enabled = 0;
  201 + s->irq = irq;
201 202  
202 203 bh = qemu_bh_new(sh_timer_tick, s);
203 204 s->timer = ptimer_init(bh);
... ... @@ -305,7 +306,9 @@ static CPUWriteMemoryFunc *tmu012_writefn[] = {
305 306 tmu012_write
306 307 };
307 308  
308   -void tmu012_init(uint32_t base, int feat, uint32_t freq)
  309 +void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
  310 + struct intc_source *ch0_irq, struct intc_source *ch1_irq,
  311 + struct intc_source *ch2_irq0, struct intc_source *ch2_irq1)
309 312 {
310 313 int iomemtype;
311 314 tmu012_state *s;
... ... @@ -314,10 +317,11 @@ void tmu012_init(uint32_t base, int feat, uint32_t freq)
314 317 s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state));
315 318 s->base = base;
316 319 s->feat = feat;
317   - s->timer[0] = sh_timer_init(freq, timer_feat);
318   - s->timer[1] = sh_timer_init(freq, timer_feat);
  320 + s->timer[0] = sh_timer_init(freq, timer_feat, ch0_irq);
  321 + s->timer[1] = sh_timer_init(freq, timer_feat, ch1_irq);
319 322 if (feat & TMU012_FEAT_3CHAN)
320   - s->timer[2] = sh_timer_init(freq, timer_feat | TIMER_FEAT_CAPT);
  323 + s->timer[2] = sh_timer_init(freq, timer_feat | TIMER_FEAT_CAPT,
  324 + ch2_irq0); /* ch2_irq1 not supported */
321 325 iomemtype = cpu_register_io_memory(0, tmu012_readfn,
322 326 tmu012_writefn, s);
323 327 cpu_register_physical_memory(base, 0x00001000, iomemtype);
... ...