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,6 +2,8 @@
2 #define QEMU_SH_H 2 #define QEMU_SH_H
3 /* Definitions for SH board emulation. */ 3 /* Definitions for SH board emulation. */
4 4
  5 +#include "sh_intc.h"
  6 +
5 /* sh7750.c */ 7 /* sh7750.c */
6 struct SH7750State; 8 struct SH7750State;
7 9
@@ -25,7 +27,10 @@ int sh7750_register_io_device(struct SH7750State *s, @@ -25,7 +27,10 @@ int sh7750_register_io_device(struct SH7750State *s,
25 #define TMU012_FEAT_TOCR (1 << 0) 27 #define TMU012_FEAT_TOCR (1 << 0)
26 #define TMU012_FEAT_3CHAN (1 << 1) 28 #define TMU012_FEAT_3CHAN (1 << 1)
27 #define TMU012_FEAT_EXTCLK (1 << 2) 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 /* sh_serial.c */ 35 /* sh_serial.c */
31 #define SH_SERIAL_FEAT_SCIF (1 << 0) 36 #define SH_SERIAL_FEAT_SCIF (1 << 0)
hw/sh7750.c
@@ -559,8 +559,11 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -559,8 +559,11 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
559 559
560 tmu012_init(0x1fd80000, 560 tmu012_init(0x1fd80000,
561 TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK, 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 if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) { 568 if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
566 sh_intc_register_sources(&s->intc, 569 sh_intc_register_sources(&s->intc,
@@ -578,7 +581,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -578,7 +581,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
578 sh_intc_register_sources(&s->intc, 581 sh_intc_register_sources(&s->intc,
579 _INTC_ARRAY(vectors_tmu34), 582 _INTC_ARRAY(vectors_tmu34),
580 NULL, 0); 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 if (cpu_model & (SH_CPU_SH7751_ALL)) { 590 if (cpu_model & (SH_CPU_SH7751_ALL)) {
hw/sh_timer.c
@@ -33,23 +33,23 @@ typedef struct { @@ -33,23 +33,23 @@ typedef struct {
33 uint32_t tcpr; 33 uint32_t tcpr;
34 int freq; 34 int freq;
35 int int_level; 35 int int_level;
  36 + int old_level;
36 int feat; 37 int feat;
37 int enabled; 38 int enabled;
38 - qemu_irq irq; 39 + struct intc_source *irq;
39 } sh_timer_state; 40 } sh_timer_state;
40 41
41 /* Check all active timers, and schedule the next timer interrupt. */ 42 /* Check all active timers, and schedule the next timer interrupt. */
42 43
43 static void sh_timer_update(sh_timer_state *s) 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 static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset) 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,7 +185,7 @@ static void sh_timer_tick(void *opaque)
185 sh_timer_update(s); 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 sh_timer_state *s; 190 sh_timer_state *s;
191 QEMUBH *bh; 191 QEMUBH *bh;
@@ -198,6 +198,7 @@ static void *sh_timer_init(uint32_t freq, int feat) @@ -198,6 +198,7 @@ static void *sh_timer_init(uint32_t freq, int feat)
198 s->tcpr = 0xdeadbeef; 198 s->tcpr = 0xdeadbeef;
199 s->tcor = 0; 199 s->tcor = 0;
200 s->enabled = 0; 200 s->enabled = 0;
  201 + s->irq = irq;
201 202
202 bh = qemu_bh_new(sh_timer_tick, s); 203 bh = qemu_bh_new(sh_timer_tick, s);
203 s->timer = ptimer_init(bh); 204 s->timer = ptimer_init(bh);
@@ -305,7 +306,9 @@ static CPUWriteMemoryFunc *tmu012_writefn[] = { @@ -305,7 +306,9 @@ static CPUWriteMemoryFunc *tmu012_writefn[] = {
305 tmu012_write 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 int iomemtype; 313 int iomemtype;
311 tmu012_state *s; 314 tmu012_state *s;
@@ -314,10 +317,11 @@ void tmu012_init(uint32_t base, int feat, uint32_t freq) @@ -314,10 +317,11 @@ void tmu012_init(uint32_t base, int feat, uint32_t freq)
314 s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state)); 317 s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state));
315 s->base = base; 318 s->base = base;
316 s->feat = feat; 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 if (feat & TMU012_FEAT_3CHAN) 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 iomemtype = cpu_register_io_memory(0, tmu012_readfn, 325 iomemtype = cpu_register_io_memory(0, tmu012_readfn,
322 tmu012_writefn, s); 326 tmu012_writefn, s);
323 cpu_register_physical_memory(base, 0x00001000, iomemtype); 327 cpu_register_physical_memory(base, 0x00001000, iomemtype);