Commit e7786f27c39f9bb9f75c71246d4993e4a8778758

Authored by aurel32
1 parent c2432a42

SH4: fix TMU init

Init the TMU and the ptimer with the correct cpu reset value

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6549 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 19 additions and 9 deletions
hw/sh_timer.c
@@ -25,6 +25,11 @@ @@ -25,6 +25,11 @@
25 #define TIMER_FEAT_CAPT (1 << 0) 25 #define TIMER_FEAT_CAPT (1 << 0)
26 #define TIMER_FEAT_EXTCLK (1 << 1) 26 #define TIMER_FEAT_EXTCLK (1 << 1)
27 27
  28 +#define OFFSET_TCOR 0
  29 +#define OFFSET_TCNT 1
  30 +#define OFFSET_TCR 2
  31 +#define OFFSET_TCPR 3
  32 +
28 typedef struct { 33 typedef struct {
29 ptimer_state *timer; 34 ptimer_state *timer;
30 uint32_t tcnt; 35 uint32_t tcnt;
@@ -57,13 +62,13 @@ static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset) @@ -57,13 +62,13 @@ static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset)
57 sh_timer_state *s = (sh_timer_state *)opaque; 62 sh_timer_state *s = (sh_timer_state *)opaque;
58 63
59 switch (offset >> 2) { 64 switch (offset >> 2) {
60 - case 0: 65 + case OFFSET_TCOR:
61 return s->tcor; 66 return s->tcor;
62 - case 1: 67 + case OFFSET_TCNT:
63 return ptimer_get_count(s->timer); 68 return ptimer_get_count(s->timer);
64 - case 2: 69 + case OFFSET_TCR:
65 return s->tcr | (s->int_level ? TIMER_TCR_UNF : 0); 70 return s->tcr | (s->int_level ? TIMER_TCR_UNF : 0);
66 - case 3: 71 + case OFFSET_TCPR:
67 if (s->feat & TIMER_FEAT_CAPT) 72 if (s->feat & TIMER_FEAT_CAPT)
68 return s->tcpr; 73 return s->tcpr;
69 default: 74 default:
@@ -80,15 +85,15 @@ static void sh_timer_write(void *opaque, target_phys_addr_t offset, @@ -80,15 +85,15 @@ static void sh_timer_write(void *opaque, target_phys_addr_t offset,
80 int freq; 85 int freq;
81 86
82 switch (offset >> 2) { 87 switch (offset >> 2) {
83 - case 0: 88 + case OFFSET_TCOR:
84 s->tcor = value; 89 s->tcor = value;
85 ptimer_set_limit(s->timer, s->tcor, 0); 90 ptimer_set_limit(s->timer, s->tcor, 0);
86 break; 91 break;
87 - case 1: 92 + case OFFSET_TCNT:
88 s->tcnt = value; 93 s->tcnt = value;
89 ptimer_set_count(s->timer, s->tcnt); 94 ptimer_set_count(s->timer, s->tcnt);
90 break; 95 break;
91 - case 2: 96 + case OFFSET_TCR:
92 if (s->enabled) { 97 if (s->enabled) {
93 /* Pause the timer if it is running. This may cause some 98 /* Pause the timer if it is running. This may cause some
94 inaccuracy dure to rounding, but avoids a whole lot of other 99 inaccuracy dure to rounding, but avoids a whole lot of other
@@ -145,7 +150,7 @@ static void sh_timer_write(void *opaque, target_phys_addr_t offset, @@ -145,7 +150,7 @@ static void sh_timer_write(void *opaque, target_phys_addr_t offset,
145 ptimer_run(s->timer, 0); 150 ptimer_run(s->timer, 0);
146 } 151 }
147 break; 152 break;
148 - case 3: 153 + case OFFSET_TCPR:
149 if (s->feat & TIMER_FEAT_CAPT) { 154 if (s->feat & TIMER_FEAT_CAPT) {
150 s->tcpr = value; 155 s->tcpr = value;
151 break; 156 break;
@@ -196,12 +201,17 @@ static void *sh_timer_init(uint32_t freq, int feat, qemu_irq irq) @@ -196,12 +201,17 @@ static void *sh_timer_init(uint32_t freq, int feat, qemu_irq irq)
196 s->tcor = 0xffffffff; 201 s->tcor = 0xffffffff;
197 s->tcnt = 0xffffffff; 202 s->tcnt = 0xffffffff;
198 s->tcpr = 0xdeadbeef; 203 s->tcpr = 0xdeadbeef;
199 - s->tcor = 0; 204 + s->tcr = 0;
200 s->enabled = 0; 205 s->enabled = 0;
201 s->irq = irq; 206 s->irq = irq;
202 207
203 bh = qemu_bh_new(sh_timer_tick, s); 208 bh = qemu_bh_new(sh_timer_tick, s);
204 s->timer = ptimer_init(bh); 209 s->timer = ptimer_init(bh);
  210 +
  211 + sh_timer_write(s, OFFSET_TCOR >> 2, s->tcor);
  212 + sh_timer_write(s, OFFSET_TCNT >> 2, s->tcnt);
  213 + sh_timer_write(s, OFFSET_TCPR >> 2, s->tcpr);
  214 + sh_timer_write(s, OFFSET_TCR >> 2, s->tcpr);
205 /* ??? Save/restore. */ 215 /* ??? Save/restore. */
206 return s; 216 return s;
207 } 217 }