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