|
|
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:
1.1.1.3 root 62: typedef struct {
1.1 root 63: uint32_t value;
64: int level;
65: qemu_irq irq;
66: QEMUTimer *qtimer;
67: int num;
68: void *info;
1.1.1.3 root 69: } PXA2xxTimer0;
1.1 root 70:
1.1.1.3 root 71: typedef struct {
72: PXA2xxTimer0 tm;
1.1 root 73: int32_t oldclock;
74: int32_t clock;
75: uint64_t lastload;
76: uint32_t freq;
77: uint32_t control;
1.1.1.3 root 78: } PXA2xxTimer4;
1.1 root 79:
80: typedef struct {
81: int32_t clock;
82: int32_t oldclock;
83: uint64_t lastload;
84: uint32_t freq;
1.1.1.3 root 85: PXA2xxTimer0 timer[4];
86: PXA2xxTimer4 *tm4;
1.1 root 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 +
1.1.1.4 ! root 101: muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec());
1.1 root 102:
103: for (i = 0; i < 4; i ++) {
104: new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
1.1.1.4 ! root 105: get_ticks_per_sec(), s->freq);
1.1 root 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,
1.1.1.4 ! root 130: s->tm4[counter].freq, get_ticks_per_sec());
1.1 root 131:
132: new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
1.1.1.4 ! root 133: get_ticks_per_sec(), s->tm4[counter].freq);
1.1 root 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) -
1.1.1.4 ! root 161: s->lastload, s->freq, get_ticks_per_sec());
1.1 root 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,
1.1.1.4 ! root 178: s->tm4[tm - 1].freq, get_ticks_per_sec());
1.1 root 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) -
1.1.1.4 ! root 186: s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
1.1 root 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:
1.1.1.3 root 208: hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
1.1 root 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:
1.1.1.3 root 317: hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
1.1 root 318: }
319: }
320:
1.1.1.4 ! root 321: static CPUReadMemoryFunc * const pxa2xx_timer_readfn[] = {
1.1 root 322: pxa2xx_timer_read,
323: pxa2xx_timer_read,
324: pxa2xx_timer_read,
325: };
326:
1.1.1.4 ! root 327: static CPUWriteMemoryFunc * const pxa2xx_timer_writefn[] = {
1.1 root 328: pxa2xx_timer_write,
329: pxa2xx_timer_write,
330: pxa2xx_timer_write,
331: };
332:
333: static void pxa2xx_timer_tick(void *opaque)
334: {
1.1.1.3 root 335: PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
1.1 root 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: {
1.1.1.3 root 353: PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
1.1 root 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:
1.1.1.2 root 368: qemu_put_be32s(f, (uint32_t *) &s->clock);
369: qemu_put_be32s(f, (uint32_t *) &s->oldclock);
1.1 root 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);
1.1.1.2 root 380: qemu_put_sbe32s(f, &s->tm4[i].oldclock);
381: qemu_put_sbe32s(f, &s->tm4[i].clock);
1.1 root 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:
1.1.1.2 root 399: qemu_get_be32s(f, (uint32_t *) &s->clock);
400: qemu_get_be32s(f, (uint32_t *) &s->oldclock);
1.1 root 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);
1.1.1.2 root 414: qemu_get_sbe32s(f, &s->tm4[i].oldclock);
415: qemu_get_sbe32s(f, &s->tm4[i].clock);
1.1 root 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:
1.1.1.3 root 454: iomemtype = cpu_register_io_memory(pxa2xx_timer_readfn,
1.1 root 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;
1.1.1.4 ! root 468: s->tm4 = NULL;
1.1 root 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;
1.1.1.3 root 477: s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 *
478: sizeof(PXA2xxTimer4));
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.