Statistics
| Branch: | Revision:

root / hw / pxa2xx_timer.c @ 43ad7e3e

History | View | Annotate | Download (13.2 kB)

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