|
|
1.1 root 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: target_phys_addr_t base;
82: int32_t clock;
83: int32_t oldclock;
84: uint64_t lastload;
85: uint32_t freq;
86: struct pxa2xx_timer0_s timer[4];
87: struct pxa2xx_timer4_s *tm4;
88: uint32_t events;
89: uint32_t irq_enabled;
90: uint32_t reset3;
91: uint32_t snapshot;
92: } pxa2xx_timer_info;
93:
94: static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
95: {
96: pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
97: int i;
98: uint32_t now_vm;
99: uint64_t new_qemu;
100:
101: now_vm = s->clock +
102: muldiv64(now_qemu - s->lastload, s->freq, ticks_per_sec);
103:
104: for (i = 0; i < 4; i ++) {
105: new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
106: ticks_per_sec, s->freq);
107: qemu_mod_timer(s->timer[i].qtimer, new_qemu);
108: }
109: }
110:
111: static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
112: {
113: pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
114: uint32_t now_vm;
115: uint64_t new_qemu;
116: static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
117: int counter;
118:
119: if (s->tm4[n].control & (1 << 7))
120: counter = n;
121: else
122: counter = counters[n];
123:
124: if (!s->tm4[counter].freq) {
125: qemu_del_timer(s->tm4[n].tm.qtimer);
126: return;
127: }
128:
129: now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
130: s->tm4[counter].lastload,
131: s->tm4[counter].freq, ticks_per_sec);
132:
133: new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
134: ticks_per_sec, s->tm4[counter].freq);
135: qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
136: }
137:
138: static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
139: {
140: pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
141: int tm = 0;
142:
143: offset -= s->base;
144:
145: switch (offset) {
146: case OSMR3: tm ++;
147: case OSMR2: tm ++;
148: case OSMR1: tm ++;
149: case OSMR0:
150: return s->timer[tm].value;
151: case OSMR11: tm ++;
152: case OSMR10: tm ++;
153: case OSMR9: tm ++;
154: case OSMR8: tm ++;
155: case OSMR7: tm ++;
156: case OSMR6: tm ++;
157: case OSMR5: tm ++;
158: case OSMR4:
159: if (!s->tm4)
160: goto badreg;
161: return s->tm4[tm].tm.value;
162: case OSCR:
163: return s->clock + muldiv64(qemu_get_clock(vm_clock) -
164: s->lastload, s->freq, ticks_per_sec);
165: case OSCR11: tm ++;
166: case OSCR10: tm ++;
167: case OSCR9: tm ++;
168: case OSCR8: tm ++;
169: case OSCR7: tm ++;
170: case OSCR6: tm ++;
171: case OSCR5: tm ++;
172: case OSCR4:
173: if (!s->tm4)
174: goto badreg;
175:
176: if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
177: if (s->tm4[tm - 1].freq)
178: s->snapshot = s->tm4[tm - 1].clock + muldiv64(
179: qemu_get_clock(vm_clock) -
180: s->tm4[tm - 1].lastload,
181: s->tm4[tm - 1].freq, ticks_per_sec);
182: else
183: s->snapshot = s->tm4[tm - 1].clock;
184: }
185:
186: if (!s->tm4[tm].freq)
187: return s->tm4[tm].clock;
188: return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
189: s->tm4[tm].lastload, s->tm4[tm].freq, ticks_per_sec);
190: case OIER:
191: return s->irq_enabled;
192: case OSSR: /* Status register */
193: return s->events;
194: case OWER:
195: return s->reset3;
196: case OMCR11: tm ++;
197: case OMCR10: tm ++;
198: case OMCR9: tm ++;
199: case OMCR8: tm ++;
200: case OMCR7: tm ++;
201: case OMCR6: tm ++;
202: case OMCR5: tm ++;
203: case OMCR4:
204: if (!s->tm4)
205: goto badreg;
206: return s->tm4[tm].control;
207: case OSNR:
208: return s->snapshot;
209: default:
210: badreg:
211: cpu_abort(cpu_single_env, "pxa2xx_timer_read: Bad offset "
212: REG_FMT "\n", offset);
213: }
214:
215: return 0;
216: }
217:
218: static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
219: uint32_t value)
220: {
221: int i, tm = 0;
222: pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
223:
224: offset -= s->base;
225:
226: switch (offset) {
227: case OSMR3: tm ++;
228: case OSMR2: tm ++;
229: case OSMR1: tm ++;
230: case OSMR0:
231: s->timer[tm].value = value;
232: pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
233: break;
234: case OSMR11: tm ++;
235: case OSMR10: tm ++;
236: case OSMR9: tm ++;
237: case OSMR8: tm ++;
238: case OSMR7: tm ++;
239: case OSMR6: tm ++;
240: case OSMR5: tm ++;
241: case OSMR4:
242: if (!s->tm4)
243: goto badreg;
244: s->tm4[tm].tm.value = value;
245: pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
246: break;
247: case OSCR:
248: s->oldclock = s->clock;
249: s->lastload = qemu_get_clock(vm_clock);
250: s->clock = value;
251: pxa2xx_timer_update(s, s->lastload);
252: break;
253: case OSCR11: tm ++;
254: case OSCR10: tm ++;
255: case OSCR9: tm ++;
256: case OSCR8: tm ++;
257: case OSCR7: tm ++;
258: case OSCR6: tm ++;
259: case OSCR5: tm ++;
260: case OSCR4:
261: if (!s->tm4)
262: goto badreg;
263: s->tm4[tm].oldclock = s->tm4[tm].clock;
264: s->tm4[tm].lastload = qemu_get_clock(vm_clock);
265: s->tm4[tm].clock = value;
266: pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
267: break;
268: case OIER:
269: s->irq_enabled = value & 0xfff;
270: break;
271: case OSSR: /* Status register */
272: s->events &= ~value;
273: for (i = 0; i < 4; i ++, value >>= 1) {
274: if (s->timer[i].level && (value & 1)) {
275: s->timer[i].level = 0;
276: qemu_irq_lower(s->timer[i].irq);
277: }
278: }
279: if (s->tm4) {
280: for (i = 0; i < 8; i ++, value >>= 1)
281: if (s->tm4[i].tm.level && (value & 1))
282: s->tm4[i].tm.level = 0;
283: if (!(s->events & 0xff0))
284: qemu_irq_lower(s->tm4->tm.irq);
285: }
286: break;
287: case OWER: /* XXX: Reset on OSMR3 match? */
288: s->reset3 = value;
289: break;
290: case OMCR7: tm ++;
291: case OMCR6: tm ++;
292: case OMCR5: tm ++;
293: case OMCR4:
294: if (!s->tm4)
295: goto badreg;
296: s->tm4[tm].control = value & 0x0ff;
297: /* XXX Stop if running (shouldn't happen) */
298: if ((value & (1 << 7)) || tm == 0)
299: s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
300: else {
301: s->tm4[tm].freq = 0;
302: pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
303: }
304: break;
305: case OMCR11: tm ++;
306: case OMCR10: tm ++;
307: case OMCR9: tm ++;
308: case OMCR8: tm += 4;
309: if (!s->tm4)
310: goto badreg;
311: s->tm4[tm].control = value & 0x3ff;
312: /* XXX Stop if running (shouldn't happen) */
313: if ((value & (1 << 7)) || !(tm & 1))
314: s->tm4[tm].freq =
315: pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)];
316: else {
317: s->tm4[tm].freq = 0;
318: pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
319: }
320: break;
321: default:
322: badreg:
323: cpu_abort(cpu_single_env, "pxa2xx_timer_write: Bad offset "
324: REG_FMT "\n", offset);
325: }
326: }
327:
328: static CPUReadMemoryFunc *pxa2xx_timer_readfn[] = {
329: pxa2xx_timer_read,
330: pxa2xx_timer_read,
331: pxa2xx_timer_read,
332: };
333:
334: static CPUWriteMemoryFunc *pxa2xx_timer_writefn[] = {
335: pxa2xx_timer_write,
336: pxa2xx_timer_write,
337: pxa2xx_timer_write,
338: };
339:
340: static void pxa2xx_timer_tick(void *opaque)
341: {
342: struct pxa2xx_timer0_s *t = (struct pxa2xx_timer0_s *) opaque;
343: pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
344:
345: if (i->irq_enabled & (1 << t->num)) {
346: t->level = 1;
347: i->events |= 1 << t->num;
348: qemu_irq_raise(t->irq);
349: }
350:
351: if (t->num == 3)
352: if (i->reset3 & 1) {
353: i->reset3 = 0;
354: qemu_system_reset_request();
355: }
356: }
357:
358: static void pxa2xx_timer_tick4(void *opaque)
359: {
360: struct pxa2xx_timer4_s *t = (struct pxa2xx_timer4_s *) opaque;
361: pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info;
362:
363: pxa2xx_timer_tick(&t->tm);
364: if (t->control & (1 << 3))
365: t->clock = 0;
366: if (t->control & (1 << 6))
367: pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
368: }
369:
370: static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
371: {
372: pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
373: int i;
374:
375: qemu_put_be32s(f, &s->clock);
376: qemu_put_be32s(f, &s->oldclock);
377: qemu_put_be64s(f, &s->lastload);
378:
379: for (i = 0; i < 4; i ++) {
380: qemu_put_be32s(f, &s->timer[i].value);
381: qemu_put_be32(f, s->timer[i].level);
382: }
383: if (s->tm4)
384: for (i = 0; i < 8; i ++) {
385: qemu_put_be32s(f, &s->tm4[i].tm.value);
386: qemu_put_be32(f, s->tm4[i].tm.level);
387: qemu_put_be32s(f, &s->tm4[i].oldclock);
388: qemu_put_be32s(f, &s->tm4[i].clock);
389: qemu_put_be64s(f, &s->tm4[i].lastload);
390: qemu_put_be32s(f, &s->tm4[i].freq);
391: qemu_put_be32s(f, &s->tm4[i].control);
392: }
393:
394: qemu_put_be32s(f, &s->events);
395: qemu_put_be32s(f, &s->irq_enabled);
396: qemu_put_be32s(f, &s->reset3);
397: qemu_put_be32s(f, &s->snapshot);
398: }
399:
400: static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
401: {
402: pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
403: int64_t now;
404: int i;
405:
406: qemu_get_be32s(f, &s->clock);
407: qemu_get_be32s(f, &s->oldclock);
408: qemu_get_be64s(f, &s->lastload);
409:
410: now = qemu_get_clock(vm_clock);
411: for (i = 0; i < 4; i ++) {
412: qemu_get_be32s(f, &s->timer[i].value);
413: s->timer[i].level = qemu_get_be32(f);
414: }
415: pxa2xx_timer_update(s, now);
416:
417: if (s->tm4)
418: for (i = 0; i < 8; i ++) {
419: qemu_get_be32s(f, &s->tm4[i].tm.value);
420: s->tm4[i].tm.level = qemu_get_be32(f);
421: qemu_get_be32s(f, &s->tm4[i].oldclock);
422: qemu_get_be32s(f, &s->tm4[i].clock);
423: qemu_get_be64s(f, &s->tm4[i].lastload);
424: qemu_get_be32s(f, &s->tm4[i].freq);
425: qemu_get_be32s(f, &s->tm4[i].control);
426: pxa2xx_timer_update4(s, now, i);
427: }
428:
429: qemu_get_be32s(f, &s->events);
430: qemu_get_be32s(f, &s->irq_enabled);
431: qemu_get_be32s(f, &s->reset3);
432: qemu_get_be32s(f, &s->snapshot);
433:
434: return 0;
435: }
436:
437: static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
438: qemu_irq *irqs)
439: {
440: int i;
441: int iomemtype;
442: pxa2xx_timer_info *s;
443:
444: s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));
445: s->base = base;
446: s->irq_enabled = 0;
447: s->oldclock = 0;
448: s->clock = 0;
449: s->lastload = qemu_get_clock(vm_clock);
450: s->reset3 = 0;
451:
452: for (i = 0; i < 4; i ++) {
453: s->timer[i].value = 0;
454: s->timer[i].irq = irqs[i];
455: s->timer[i].info = s;
456: s->timer[i].num = i;
457: s->timer[i].level = 0;
458: s->timer[i].qtimer = qemu_new_timer(vm_clock,
459: pxa2xx_timer_tick, &s->timer[i]);
460: }
461:
462: iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
463: pxa2xx_timer_writefn, s);
464: cpu_register_physical_memory(base, 0x00001000, iomemtype);
465:
466: register_savevm("pxa2xx_timer", 0, 0,
467: pxa2xx_timer_save, pxa2xx_timer_load, s);
468:
469: return s;
470: }
471:
472: void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs)
473: {
474: pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
475: s->freq = PXA25X_FREQ;
476: s->tm4 = 0;
477: }
478:
479: void pxa27x_timer_init(target_phys_addr_t base,
480: qemu_irq *irqs, qemu_irq irq4)
481: {
482: pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
483: int i;
484: s->freq = PXA27X_FREQ;
485: s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 *
486: sizeof(struct pxa2xx_timer4_s));
487: for (i = 0; i < 8; i ++) {
488: s->tm4[i].tm.value = 0;
489: s->tm4[i].tm.irq = irq4;
490: s->tm4[i].tm.info = s;
491: s->tm4[i].tm.num = i + 4;
492: s->tm4[i].tm.level = 0;
493: s->tm4[i].freq = 0;
494: s->tm4[i].control = 0x0;
495: s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
496: pxa2xx_timer_tick4, &s->tm4[i]);
497: }
498: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.