Commit e7786f27c39f9bb9f75c71246d4993e4a8778758
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 | 25 | #define TIMER_FEAT_CAPT (1 << 0) |
| 26 | 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 | 33 | typedef struct { |
| 29 | 34 | ptimer_state *timer; |
| 30 | 35 | uint32_t tcnt; |
| ... | ... | @@ -57,13 +62,13 @@ static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset) |
| 57 | 62 | sh_timer_state *s = (sh_timer_state *)opaque; |
| 58 | 63 | |
| 59 | 64 | switch (offset >> 2) { |
| 60 | - case 0: | |
| 65 | + case OFFSET_TCOR: | |
| 61 | 66 | return s->tcor; |
| 62 | - case 1: | |
| 67 | + case OFFSET_TCNT: | |
| 63 | 68 | return ptimer_get_count(s->timer); |
| 64 | - case 2: | |
| 69 | + case OFFSET_TCR: | |
| 65 | 70 | return s->tcr | (s->int_level ? TIMER_TCR_UNF : 0); |
| 66 | - case 3: | |
| 71 | + case OFFSET_TCPR: | |
| 67 | 72 | if (s->feat & TIMER_FEAT_CAPT) |
| 68 | 73 | return s->tcpr; |
| 69 | 74 | default: |
| ... | ... | @@ -80,15 +85,15 @@ static void sh_timer_write(void *opaque, target_phys_addr_t offset, |
| 80 | 85 | int freq; |
| 81 | 86 | |
| 82 | 87 | switch (offset >> 2) { |
| 83 | - case 0: | |
| 88 | + case OFFSET_TCOR: | |
| 84 | 89 | s->tcor = value; |
| 85 | 90 | ptimer_set_limit(s->timer, s->tcor, 0); |
| 86 | 91 | break; |
| 87 | - case 1: | |
| 92 | + case OFFSET_TCNT: | |
| 88 | 93 | s->tcnt = value; |
| 89 | 94 | ptimer_set_count(s->timer, s->tcnt); |
| 90 | 95 | break; |
| 91 | - case 2: | |
| 96 | + case OFFSET_TCR: | |
| 92 | 97 | if (s->enabled) { |
| 93 | 98 | /* Pause the timer if it is running. This may cause some |
| 94 | 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 | 150 | ptimer_run(s->timer, 0); |
| 146 | 151 | } |
| 147 | 152 | break; |
| 148 | - case 3: | |
| 153 | + case OFFSET_TCPR: | |
| 149 | 154 | if (s->feat & TIMER_FEAT_CAPT) { |
| 150 | 155 | s->tcpr = value; |
| 151 | 156 | break; |
| ... | ... | @@ -196,12 +201,17 @@ static void *sh_timer_init(uint32_t freq, int feat, qemu_irq irq) |
| 196 | 201 | s->tcor = 0xffffffff; |
| 197 | 202 | s->tcnt = 0xffffffff; |
| 198 | 203 | s->tcpr = 0xdeadbeef; |
| 199 | - s->tcor = 0; | |
| 204 | + s->tcr = 0; | |
| 200 | 205 | s->enabled = 0; |
| 201 | 206 | s->irq = irq; |
| 202 | 207 | |
| 203 | 208 | bh = qemu_bh_new(sh_timer_tick, s); |
| 204 | 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 | 215 | /* ??? Save/restore. */ |
| 206 | 216 | return s; |
| 207 | 217 | } | ... | ... |