Set OOK when OON is set in OSCC register (thanks to BobOfDoom). Correct a fatal...
[qemu] / hw / pxa2xx_timer.c
1 /*
2  * Intel XScale PXA255/270 OS Timers.
3  *
4  * Copyright (c) 2006 Openedhand Ltd.
5  * Copyright (c) 2006 Thorsten Zitterell
6  *
7  * This code is licenced under the GPL.
8  */
9
10 #include "vl.h"
11
12 #define OSMR0   0x00
13 #define OSMR1   0x04
14 #define OSMR2   0x08
15 #define OSMR3   0x0c
16 #define OSMR4   0x80
17 #define OSMR5   0x84
18 #define OSMR6   0x88
19 #define OSMR7   0x8c
20 #define OSMR8   0x90
21 #define OSMR9   0x94
22 #define OSMR10  0x98
23 #define OSMR11  0x9c
24 #define OSCR    0x10    /* OS Timer Count */
25 #define OSCR4   0x40
26 #define OSCR5   0x44
27 #define OSCR6   0x48
28 #define OSCR7   0x4c
29 #define OSCR8   0x50
30 #define OSCR9   0x54
31 #define OSCR10  0x58
32 #define OSCR11  0x5c
33 #define OSSR    0x14    /* Timer status register */
34 #define OWER    0x18
35 #define OIER    0x1c    /* Interrupt enable register  3-0 to E3-E0 */
36 #define OMCR4   0xc0    /* OS Match Control registers */
37 #define OMCR5   0xc4
38 #define OMCR6   0xc8
39 #define OMCR7   0xcc
40 #define OMCR8   0xd0
41 #define OMCR9   0xd4
42 #define OMCR10  0xd8
43 #define OMCR11  0xdc
44 #define OSNR    0x20
45
46 #define PXA25X_FREQ     3686400 /* 3.6864 MHz */
47 #define PXA27X_FREQ     3250000 /* 3.25 MHz */
48
49 static int pxa2xx_timer4_freq[8] = {
50     [0] = 0,
51     [1] = 32768,
52     [2] = 1000,
53     [3] = 1,
54     [4] = 1000000,
55     /* [5] is the "Externally supplied clock".  Assign if necessary.  */
56     [5 ... 7] = 0,
57 };
58
59 struct pxa2xx_timer0_s {
60     uint32_t value;
61     int level;
62     qemu_irq irq;
63     QEMUTimer *qtimer;
64     int num;
65     void *info;
66 };
67
68 struct pxa2xx_timer4_s {
69     uint32_t value;
70     int level;
71     qemu_irq irq;
72     QEMUTimer *qtimer;
73     int num;
74     void *info;
75     int32_t oldclock;
76     int32_t clock;
77     uint64_t lastload;
78     uint32_t freq;
79     uint32_t control;
80 };
81
82 typedef struct {
83     uint32_t base;
84     int32_t clock;
85     int32_t oldclock;
86     uint64_t lastload;
87     uint32_t freq;
88     struct pxa2xx_timer0_s timer[4];
89     struct pxa2xx_timer4_s *tm4;
90     uint32_t events;
91     uint32_t irq_enabled;
92     uint32_t reset3;
93     CPUState *cpustate;
94     int64_t qemu_ticks;
95     uint32_t snapshot;
96 } pxa2xx_timer_info;
97
98 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
99 {
100     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
101     int i;
102     uint32_t now_vm;
103     uint64_t new_qemu;
104
105     now_vm = s->clock +
106             muldiv64(now_qemu - s->lastload, s->freq, ticks_per_sec);
107
108     for (i = 0; i < 4; i ++) {
109         new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
110                         ticks_per_sec, s->freq);
111         qemu_mod_timer(s->timer[i].qtimer, new_qemu);
112     }
113 }
114
115 static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
116 {
117     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
118     uint32_t now_vm;
119     uint64_t new_qemu;
120     static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
121     int counter;
122
123     if (s->tm4[n].control & (1 << 7))
124         counter = n;
125     else
126         counter = counters[n];
127
128     if (!s->tm4[counter].freq) {
129         qemu_del_timer(s->timer[n].qtimer);
130         return;
131     }
132
133     now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
134                     s->tm4[counter].lastload,
135                     s->tm4[counter].freq, ticks_per_sec);
136
137     new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].value - now_vm),
138                     ticks_per_sec, s->tm4[counter].freq);
139     qemu_mod_timer(s->timer[n].qtimer, new_qemu);
140 }
141
142 static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
143 {
144     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
145     int tm = 0;
146
147     offset -= s->base;
148
149     switch (offset) {
150     case OSMR3:  tm ++;
151     case OSMR2:  tm ++;
152     case OSMR1:  tm ++;
153     case OSMR0:
154         return s->timer[tm].value;
155     case OSMR11: tm ++;
156     case OSMR10: tm ++;
157     case OSMR9:  tm ++;
158     case OSMR8:  tm ++;
159     case OSMR7:  tm ++;
160     case OSMR6:  tm ++;
161     case OSMR5:  tm ++;
162     case OSMR4:
163         if (!s->tm4)
164             goto badreg;
165         return s->tm4[tm].value;
166     case OSCR:
167         return s->clock + muldiv64(qemu_get_clock(vm_clock) -
168                         s->lastload, s->freq, ticks_per_sec);
169     case OSCR11: tm ++;
170     case OSCR10: tm ++;
171     case OSCR9:  tm ++;
172     case OSCR8:  tm ++;
173     case OSCR7:  tm ++;
174     case OSCR6:  tm ++;
175     case OSCR5:  tm ++;
176     case OSCR4:
177         if (!s->tm4)
178             goto badreg;
179
180         if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
181             if (s->tm4[tm - 1].freq)
182                 s->snapshot = s->tm4[tm - 1].clock + muldiv64(
183                                 qemu_get_clock(vm_clock) -
184                                 s->tm4[tm - 1].lastload,
185                                 s->tm4[tm - 1].freq, ticks_per_sec);
186             else
187                 s->snapshot = s->tm4[tm - 1].clock;
188         }
189
190         if (!s->tm4[tm].freq)
191             return s->tm4[tm].clock;
192         return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
193                         s->tm4[tm].lastload, s->tm4[tm].freq, ticks_per_sec);
194     case OIER:
195         return s->irq_enabled;
196     case OSSR:  /* Status register */
197         return s->events;
198     case OWER:
199         return s->reset3;
200     case OMCR11: tm ++;
201     case OMCR10: tm ++;
202     case OMCR9:  tm ++;
203     case OMCR8:  tm ++;
204     case OMCR7:  tm ++;
205     case OMCR6:  tm ++;
206     case OMCR5:  tm ++;
207     case OMCR4:
208         if (!s->tm4)
209             goto badreg;
210         return s->tm4[tm].control;
211     case OSNR:
212         return s->snapshot;
213     default:
214     badreg:
215         cpu_abort(cpu_single_env, "pxa2xx_timer_read: Bad offset "
216                         REG_FMT "\n", offset);
217     }
218
219     return 0;
220 }
221
222 static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
223                 uint32_t value)
224 {
225     int i, tm = 0;
226     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
227
228     offset -= s->base;
229
230     switch (offset) {
231     case OSMR3:  tm ++;
232     case OSMR2:  tm ++;
233     case OSMR1:  tm ++;
234     case OSMR0:
235         s->timer[tm].value = value;
236         pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
237         break;
238     case OSMR11: tm ++;
239     case OSMR10: tm ++;
240     case OSMR9:  tm ++;
241     case OSMR8:  tm ++;
242     case OSMR7:  tm ++;
243     case OSMR6:  tm ++;
244     case OSMR5:  tm ++;
245     case OSMR4:
246         if (!s->tm4)
247             goto badreg;
248         s->tm4[tm].value = value;
249         pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
250         break;
251     case OSCR:
252         s->oldclock = s->clock;
253         s->lastload = qemu_get_clock(vm_clock);
254         s->clock = value;
255         pxa2xx_timer_update(s, s->lastload);
256         break;
257     case OSCR11: tm ++;
258     case OSCR10: tm ++;
259     case OSCR9:  tm ++;
260     case OSCR8:  tm ++;
261     case OSCR7:  tm ++;
262     case OSCR6:  tm ++;
263     case OSCR5:  tm ++;
264     case OSCR4:
265         if (!s->tm4)
266             goto badreg;
267         s->tm4[tm].oldclock = s->tm4[tm].clock;
268         s->tm4[tm].lastload = qemu_get_clock(vm_clock);
269         s->tm4[tm].clock = value;
270         pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
271         break;
272     case OIER:
273         s->irq_enabled = value & 0xfff;
274         break;
275     case OSSR:  /* Status register */
276         s->events &= ~value;
277         for (i = 0; i < 4; i ++, value >>= 1) {
278             if (s->timer[i].level && (value & 1)) {
279                 s->timer[i].level = 0;
280                 qemu_irq_lower(s->timer[i].irq);
281             }
282         }
283         if (s->tm4) {
284             for (i = 0; i < 8; i ++, value >>= 1)
285                 if (s->tm4[i].level && (value & 1))
286                     s->tm4[i].level = 0;
287             if (!(s->events & 0xff0))
288                 qemu_irq_lower(s->tm4->irq);
289         }
290         break;
291     case OWER:  /* XXX: Reset on OSMR3 match? */
292         s->reset3 = value;
293         break;
294     case OMCR7:  tm ++;
295     case OMCR6:  tm ++;
296     case OMCR5:  tm ++;
297     case OMCR4:
298         if (!s->tm4)
299             goto badreg;
300         s->tm4[tm].control = value & 0x0ff;
301         /* XXX Stop if running (shouldn't happen) */
302         if ((value & (1 << 7)) || tm == 0)
303             s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
304         else {
305             s->tm4[tm].freq = 0;
306             pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
307         }
308         break;
309     case OMCR11: tm ++;
310     case OMCR10: tm ++;
311     case OMCR9:  tm ++;
312     case OMCR8:  tm += 4;
313         if (!s->tm4)
314             goto badreg;
315         s->tm4[tm].control = value & 0x3ff;
316         /* XXX Stop if running (shouldn't happen) */
317         if ((value & (1 << 7)) || !(tm & 1))
318             s->tm4[tm].freq =
319                     pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
320         else {
321             s->tm4[tm].freq = 0;
322             pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
323         }
324         break;
325     default:
326     badreg:
327         cpu_abort(cpu_single_env, "pxa2xx_timer_write: Bad offset "
328                         REG_FMT "\n", offset);
329     }
330 }
331
332 static CPUReadMemoryFunc *pxa2xx_timer_readfn[] = {
333     pxa2xx_timer_read,
334     pxa2xx_timer_read,
335     pxa2xx_timer_read,
336 };
337
338 static CPUWriteMemoryFunc *pxa2xx_timer_writefn[] = {
339     pxa2xx_timer_write,
340     pxa2xx_timer_write,
341     pxa2xx_timer_write,
342 };
343
344 static void pxa2xx_timer_tick(void *opaque)
345 {
346     struct pxa2xx_timer0_s *t = (struct pxa2xx_timer0_s *) opaque;
347     pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
348
349     if (i->irq_enabled & (1 << t->num)) {
350         t->level = 1;
351         i->events |= 1 << t->num;
352         qemu_irq_raise(t->irq);
353     }
354
355     if (t->num == 3)
356         if (i->reset3 & 1) {
357             i->reset3 = 0;
358             cpu_reset(i->cpustate);
359         }
360 }
361
362 static void pxa2xx_timer_tick4(void *opaque)
363 {
364     struct pxa2xx_timer4_s *t = (struct pxa2xx_timer4_s *) opaque;
365     pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
366
367     pxa2xx_timer_tick(opaque);
368     if (t->control & (1 << 3))
369         t->clock = 0;
370     if (t->control & (1 << 6))
371         pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->num - 4);
372 }
373
374 static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
375                 qemu_irq *irqs, CPUState *cpustate)
376 {
377     int i;
378     int iomemtype;
379     pxa2xx_timer_info *s;
380
381     s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));
382     s->base = base;
383     s->irq_enabled = 0;
384     s->oldclock = 0;
385     s->clock = 0;
386     s->lastload = qemu_get_clock(vm_clock);
387     s->reset3 = 0;
388     s->cpustate = cpustate;
389
390     for (i = 0; i < 4; i ++) {
391         s->timer[i].value = 0;
392         s->timer[i].irq = irqs[i];
393         s->timer[i].info = s;
394         s->timer[i].num = i;
395         s->timer[i].level = 0;
396         s->timer[i].qtimer = qemu_new_timer(vm_clock,
397                         pxa2xx_timer_tick, &s->timer[i]);
398     }
399
400     iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
401                     pxa2xx_timer_writefn, s);
402     cpu_register_physical_memory(base, 0x00000fff, iomemtype);
403     return s;
404 }
405
406 void pxa25x_timer_init(target_phys_addr_t base,
407                 qemu_irq *irqs, CPUState *cpustate)
408 {
409     pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs, cpustate);
410     s->freq = PXA25X_FREQ;
411     s->tm4 = 0;
412 }
413
414 void pxa27x_timer_init(target_phys_addr_t base,
415                 qemu_irq *irqs, qemu_irq irq4, CPUState *cpustate)
416 {
417     pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs, cpustate);
418     int i;
419     s->freq = PXA27X_FREQ;
420     s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 *
421                     sizeof(struct pxa2xx_timer4_s));
422     for (i = 0; i < 8; i ++) {
423         s->tm4[i].value = 0;
424         s->tm4[i].irq = irq4;
425         s->tm4[i].info = s;
426         s->tm4[i].num = i + 4;
427         s->tm4[i].level = 0;
428         s->tm4[i].freq = 0;
429         s->tm4[i].control = 0x0;
430         s->tm4[i].qtimer = qemu_new_timer(vm_clock,
431                         pxa2xx_timer_tick4, &s->tm4[i]);
432     }
433 }