Revision e62b5b13 hw/etraxfs_timer.c
b/hw/etraxfs_timer.c | ||
---|---|---|
1 | 1 |
/* |
2 |
* QEMU ETRAX System Emulator
|
|
2 |
* QEMU ETRAX Timers
|
|
3 | 3 |
* |
4 | 4 |
* Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB. |
5 | 5 |
* |
... | ... | |
28 | 28 |
|
29 | 29 |
#define D(x) |
30 | 30 |
|
31 |
void etrax_ack_irq(CPUState *env, uint32_t mask); |
|
32 |
|
|
33 | 31 |
#define R_TIME 0xb001e038 |
34 | 32 |
#define RW_TMR0_DIV 0xb001e000 |
35 | 33 |
#define R_TMR0_DATA 0xb001e004 |
... | ... | |
38 | 36 |
#define R_TMR1_DATA 0xb001e014 |
39 | 37 |
#define RW_TMR1_CTRL 0xb001e018 |
40 | 38 |
|
39 |
#define RW_WD_CTRL 0xb001e040 |
|
41 | 40 |
#define RW_INTR_MASK 0xb001e048 |
42 | 41 |
#define RW_ACK_INTR 0xb001e04c |
43 | 42 |
#define R_INTR 0xb001e050 |
44 | 43 |
#define R_MASKED_INTR 0xb001e054 |
45 | 44 |
|
46 |
|
|
47 |
uint32_t rw_intr_mask; |
|
48 |
uint32_t rw_ack_intr; |
|
49 |
uint32_t r_intr; |
|
50 |
|
|
51 | 45 |
struct fs_timer_t { |
52 | 46 |
QEMUBH *bh; |
53 | 47 |
unsigned int limit; |
... | ... | |
57 | 51 |
qemu_irq *irq; |
58 | 52 |
uint32_t mask; |
59 | 53 |
struct timeval last; |
54 |
|
|
55 |
uint32_t rw_intr_mask; |
|
56 |
uint32_t rw_ack_intr; |
|
57 |
uint32_t r_intr; |
|
60 | 58 |
}; |
61 | 59 |
|
62 | 60 |
static struct fs_timer_t timer[2]; |
... | ... | |
126 | 124 |
} |
127 | 125 |
|
128 | 126 |
case RW_INTR_MASK: |
129 |
r = rw_intr_mask; |
|
127 |
r = timer[t].rw_intr_mask;
|
|
130 | 128 |
break; |
131 | 129 |
case R_MASKED_INTR: |
132 |
r = r_intr & rw_intr_mask;
|
|
130 |
r = timer[t].r_intr & timer[t].rw_intr_mask;
|
|
133 | 131 |
break; |
134 | 132 |
default: |
135 |
printf ("%s %x p=%x\n", __func__, addr, env->pc);
|
|
133 |
D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
|
|
136 | 134 |
break; |
137 | 135 |
} |
138 | 136 |
return r; |
... | ... | |
167 | 165 |
{ |
168 | 166 |
case 0: |
169 | 167 |
case 1: |
170 |
printf ("extern or disabled timer clock?\n");
|
|
168 |
D(printf ("extern or disabled timer clock?\n"));
|
|
171 | 169 |
break; |
172 | 170 |
case 4: freq_hz = 29493000; break; |
173 | 171 |
case 5: freq_hz = 32000000; break; |
... | ... | |
178 | 176 |
break; |
179 | 177 |
} |
180 | 178 |
|
181 |
printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit);
|
|
179 |
D(printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit));
|
|
182 | 180 |
t->scale = 0; |
183 | 181 |
if (t->limit > 2048) |
184 | 182 |
{ |
... | ... | |
186 | 184 |
ptimer_set_period(t->ptimer, freq_hz / t->scale); |
187 | 185 |
} |
188 | 186 |
|
189 |
printf ("op=%d\n", op); |
|
190 | 187 |
switch (op) |
191 | 188 |
{ |
192 | 189 |
case 0: |
193 |
printf ("limit=%d %d\n", t->limit, t->limit/t->scale); |
|
190 |
D(printf ("limit=%d %d\n", |
|
191 |
t->limit, t->limit/t->scale)); |
|
194 | 192 |
ptimer_set_limit(t->ptimer, t->limit / t->scale, 1); |
195 | 193 |
break; |
196 | 194 |
case 1: |
... | ... | |
207 | 205 |
|
208 | 206 |
static void timer_ack_irq(struct fs_timer_t *t) |
209 | 207 |
{ |
210 |
if (!(r_intr & t->mask & rw_intr_mask)) {
|
|
208 |
if (!(t->r_intr & t->mask & t->rw_intr_mask))
|
|
211 | 209 |
qemu_irq_lower(t->irq[0]); |
212 |
etrax_ack_irq(t->env, 1 << 0x1b); |
|
213 |
} |
|
214 | 210 |
} |
215 | 211 |
|
216 | 212 |
static void |
... | ... | |
239 | 235 |
break; |
240 | 236 |
case RW_INTR_MASK: |
241 | 237 |
D(printf ("RW_INTR_MASK=%x\n", value)); |
242 |
rw_intr_mask = value; |
|
238 |
timer[t].rw_intr_mask = value; |
|
239 |
break; |
|
240 |
case RW_WD_CTRL: |
|
241 |
D(printf ("RW_WD_CTRL=%x\n", value)); |
|
243 | 242 |
break; |
244 | 243 |
case RW_ACK_INTR: |
245 |
r_intr &= ~value; |
|
244 |
timer[t].r_intr &= ~value;
|
|
246 | 245 |
timer_ack_irq(&timer[t]); |
247 | 246 |
break; |
248 | 247 |
default: |
... | ... | |
267 | 266 |
static void timer_irq(void *opaque) |
268 | 267 |
{ |
269 | 268 |
struct fs_timer_t *t = opaque; |
270 |
r_intr |= t->mask; |
|
271 |
if (t->mask & rw_intr_mask) { |
|
269 |
t->r_intr |= t->mask; |
|
270 |
if (t->mask & t->rw_intr_mask) { |
|
271 |
D(printf("%s raise\n", __func__)); |
|
272 | 272 |
qemu_irq_raise(t->irq[0]); |
273 | 273 |
} |
274 | 274 |
} |
... | ... | |
279 | 279 |
|
280 | 280 |
timer[0].bh = qemu_bh_new(timer_irq, &timer[0]); |
281 | 281 |
timer[0].ptimer = ptimer_init(timer[0].bh); |
282 |
timer[0].irq = irqs + 0x1b;
|
|
282 |
timer[0].irq = irqs + 26;
|
|
283 | 283 |
timer[0].mask = 1; |
284 | 284 |
timer[0].env = env; |
285 | 285 |
|
286 | 286 |
timer[1].bh = qemu_bh_new(timer_irq, &timer[1]); |
287 | 287 |
timer[1].ptimer = ptimer_init(timer[1].bh); |
288 |
timer[1].irq = irqs + 0x1b;
|
|
288 |
timer[1].irq = irqs + 26;
|
|
289 | 289 |
timer[1].mask = 1; |
290 | 290 |
timer[1].env = env; |
291 | 291 |
|
Also available in: Unified diff