microblaze: linux-user support.
[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 typedef struct {
63     uint32_t value;
64     int level;
65     qemu_irq irq;
66     QEMUTimer *qtimer;
67     int num;
68     void *info;
69 } PXA2xxTimer0;
70
71 typedef struct {
72     PXA2xxTimer0 tm;
73     int32_t oldclock;
74     int32_t clock;
75     uint64_t lastload;
76     uint32_t freq;
77     uint32_t control;
78 } PXA2xxTimer4;
79
80 typedef struct {
81     int32_t clock;
82     int32_t oldclock;
83     uint64_t lastload;
84     uint32_t freq;
85     PXA2xxTimer0 timer[4];
86     PXA2xxTimer4 *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         hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
209     }
210
211     return 0;
212 }
213
214 static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
215                 uint32_t value)
216 {
217     int i, tm = 0;
218     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
219
220     switch (offset) {
221     case OSMR3:  tm ++;
222     case OSMR2:  tm ++;
223     case OSMR1:  tm ++;
224     case OSMR0:
225         s->timer[tm].value = value;
226         pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
227         break;
228     case OSMR11: tm ++;
229     case OSMR10: tm ++;
230     case OSMR9:  tm ++;
231     case OSMR8:  tm ++;
232     case OSMR7:  tm ++;
233     case OSMR6:  tm ++;
234     case OSMR5:  tm ++;
235     case OSMR4:
236         if (!s->tm4)
237             goto badreg;
238         s->tm4[tm].tm.value = value;
239         pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
240         break;
241     case OSCR:
242         s->oldclock = s->clock;
243         s->lastload = qemu_get_clock(vm_clock);
244         s->clock = value;
245         pxa2xx_timer_update(s, s->lastload);
246         break;
247     case OSCR11: tm ++;
248     case OSCR10: tm ++;
249     case OSCR9:  tm ++;
250     case OSCR8:  tm ++;
251     case OSCR7:  tm ++;
252     case OSCR6:  tm ++;
253     case OSCR5:  tm ++;
254     case OSCR4:
255         if (!s->tm4)
256             goto badreg;
257         s->tm4[tm].oldclock = s->tm4[tm].clock;
258         s->tm4[tm].lastload = qemu_get_clock(vm_clock);
259         s->tm4[tm].clock = value;
260         pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
261         break;
262     case OIER:
263         s->irq_enabled = value & 0xfff;
264         break;
265     case OSSR:  /* Status register */
266         s->events &= ~value;
267         for (i = 0; i < 4; i ++, value >>= 1) {
268             if (s->timer[i].level && (value & 1)) {
269                 s->timer[i].level = 0;
270                 qemu_irq_lower(s->timer[i].irq);
271             }
272         }
273         if (s->tm4) {
274             for (i = 0; i < 8; i ++, value >>= 1)
275                 if (s->tm4[i].tm.level && (value & 1))
276                     s->tm4[i].tm.level = 0;
277             if (!(s->events & 0xff0))
278                 qemu_irq_lower(s->tm4->tm.irq);
279         }
280         break;
281     case OWER:  /* XXX: Reset on OSMR3 match? */
282         s->reset3 = value;
283         break;
284     case OMCR7:  tm ++;
285     case OMCR6:  tm ++;
286     case OMCR5:  tm ++;
287     case OMCR4:
288         if (!s->tm4)
289             goto badreg;
290         s->tm4[tm].control = value & 0x0ff;
291         /* XXX Stop if running (shouldn't happen) */
292         if ((value & (1 << 7)) || tm == 0)
293             s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
294         else {
295             s->tm4[tm].freq = 0;
296             pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
297         }
298         break;
299     case OMCR11: tm ++;
300     case OMCR10: tm ++;
301     case OMCR9:  tm ++;
302     case OMCR8:  tm += 4;
303         if (!s->tm4)
304             goto badreg;
305         s->tm4[tm].control = value & 0x3ff;
306         /* XXX Stop if running (shouldn't happen) */
307         if ((value & (1 << 7)) || !(tm & 1))
308             s->tm4[tm].freq =
309                     pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
310         else {
311             s->tm4[tm].freq = 0;
312             pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
313         }
314         break;
315     default:
316     badreg:
317         hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
318     }
319 }
320
321 static CPUReadMemoryFunc *pxa2xx_timer_readfn[] = {
322     pxa2xx_timer_read,
323     pxa2xx_timer_read,
324     pxa2xx_timer_read,
325 };
326
327 static CPUWriteMemoryFunc *pxa2xx_timer_writefn[] = {
328     pxa2xx_timer_write,
329     pxa2xx_timer_write,
330     pxa2xx_timer_write,
331 };
332
333 static void pxa2xx_timer_tick(void *opaque)
334 {
335     PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
336     pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
337
338     if (i->irq_enabled & (1 << t->num)) {
339         t->level = 1;
340         i->events |= 1 << t->num;
341         qemu_irq_raise(t->irq);
342     }
343
344     if (t->num == 3)
345         if (i->reset3 & 1) {
346             i->reset3 = 0;
347             qemu_system_reset_request();
348         }
349 }
350
351 static void pxa2xx_timer_tick4(void *opaque)
352 {
353     PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
354     pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info;
355
356     pxa2xx_timer_tick(&t->tm);
357     if (t->control & (1 << 3))
358         t->clock = 0;
359     if (t->control & (1 << 6))
360         pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
361 }
362
363 static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
364 {
365     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
366     int i;
367
368     qemu_put_be32s(f, (uint32_t *) &s->clock);
369     qemu_put_be32s(f, (uint32_t *) &s->oldclock);
370     qemu_put_be64s(f, &s->lastload);
371
372     for (i = 0; i < 4; i ++) {
373         qemu_put_be32s(f, &s->timer[i].value);
374         qemu_put_be32(f, s->timer[i].level);
375     }
376     if (s->tm4)
377         for (i = 0; i < 8; i ++) {
378             qemu_put_be32s(f, &s->tm4[i].tm.value);
379             qemu_put_be32(f, s->tm4[i].tm.level);
380             qemu_put_sbe32s(f, &s->tm4[i].oldclock);
381             qemu_put_sbe32s(f, &s->tm4[i].clock);
382             qemu_put_be64s(f, &s->tm4[i].lastload);
383             qemu_put_be32s(f, &s->tm4[i].freq);
384             qemu_put_be32s(f, &s->tm4[i].control);
385         }
386
387     qemu_put_be32s(f, &s->events);
388     qemu_put_be32s(f, &s->irq_enabled);
389     qemu_put_be32s(f, &s->reset3);
390     qemu_put_be32s(f, &s->snapshot);
391 }
392
393 static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
394 {
395     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
396     int64_t now;
397     int i;
398
399     qemu_get_be32s(f, (uint32_t *) &s->clock);
400     qemu_get_be32s(f, (uint32_t *) &s->oldclock);
401     qemu_get_be64s(f, &s->lastload);
402
403     now = qemu_get_clock(vm_clock);
404     for (i = 0; i < 4; i ++) {
405         qemu_get_be32s(f, &s->timer[i].value);
406         s->timer[i].level = qemu_get_be32(f);
407     }
408     pxa2xx_timer_update(s, now);
409
410     if (s->tm4)
411         for (i = 0; i < 8; i ++) {
412             qemu_get_be32s(f, &s->tm4[i].tm.value);
413             s->tm4[i].tm.level = qemu_get_be32(f);
414             qemu_get_sbe32s(f, &s->tm4[i].oldclock);
415             qemu_get_sbe32s(f, &s->tm4[i].clock);
416             qemu_get_be64s(f, &s->tm4[i].lastload);
417             qemu_get_be32s(f, &s->tm4[i].freq);
418             qemu_get_be32s(f, &s->tm4[i].control);
419             pxa2xx_timer_update4(s, now, i);
420         }
421
422     qemu_get_be32s(f, &s->events);
423     qemu_get_be32s(f, &s->irq_enabled);
424     qemu_get_be32s(f, &s->reset3);
425     qemu_get_be32s(f, &s->snapshot);
426
427     return 0;
428 }
429
430 static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
431                 qemu_irq *irqs)
432 {
433     int i;
434     int iomemtype;
435     pxa2xx_timer_info *s;
436
437     s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));
438     s->irq_enabled = 0;
439     s->oldclock = 0;
440     s->clock = 0;
441     s->lastload = qemu_get_clock(vm_clock);
442     s->reset3 = 0;
443
444     for (i = 0; i < 4; i ++) {
445         s->timer[i].value = 0;
446         s->timer[i].irq = irqs[i];
447         s->timer[i].info = s;
448         s->timer[i].num = i;
449         s->timer[i].level = 0;
450         s->timer[i].qtimer = qemu_new_timer(vm_clock,
451                         pxa2xx_timer_tick, &s->timer[i]);
452     }
453
454     iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
455                     pxa2xx_timer_writefn, s);
456     cpu_register_physical_memory(base, 0x00001000, iomemtype);
457
458     register_savevm("pxa2xx_timer", 0, 0,
459                     pxa2xx_timer_save, pxa2xx_timer_load, s);
460
461     return s;
462 }
463
464 void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs)
465 {
466     pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
467     s->freq = PXA25X_FREQ;
468     s->tm4 = 0;
469 }
470
471 void pxa27x_timer_init(target_phys_addr_t base,
472                 qemu_irq *irqs, qemu_irq irq4)
473 {
474     pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
475     int i;
476     s->freq = PXA27X_FREQ;
477     s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 *
478                     sizeof(PXA2xxTimer4));
479     for (i = 0; i < 8; i ++) {
480         s->tm4[i].tm.value = 0;
481         s->tm4[i].tm.irq = irq4;
482         s->tm4[i].tm.info = s;
483         s->tm4[i].tm.num = i + 4;
484         s->tm4[i].tm.level = 0;
485         s->tm4[i].freq = 0;
486         s->tm4[i].control = 0x0;
487         s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
488                         pxa2xx_timer_tick4, &s->tm4[i]);
489     }
490 }