Statistics
| Branch: | Revision:

root / hw / pxa2xx_timer.c @ 87ecb68b

History | View | Annotate | Download (13.3 kB)

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
}