Merge branch 'master' of /home/nchip/public_html/qemu into garage-push
[qemu] / hw / slavio_timer.c
1 /*
2  * QEMU Sparc SLAVIO timer controller emulation
3  *
4  * Copyright (c) 2003-2005 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "hw.h"
25 #include "sun4m.h"
26 #include "qemu-timer.h"
27
28 //#define DEBUG_TIMER
29
30 #ifdef DEBUG_TIMER
31 #define DPRINTF(fmt, ...)                                       \
32     do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
33 #else
34 #define DPRINTF(fmt, ...) do {} while (0)
35 #endif
36
37 /*
38  * Registers of hardware timer in sun4m.
39  *
40  * This is the timer/counter part of chip STP2001 (Slave I/O), also
41  * produced as NCR89C105. See
42  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
43  *
44  * The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0
45  * are zero. Bit 31 is 1 when count has been reached.
46  *
47  * Per-CPU timers interrupt local CPU, system timer uses normal
48  * interrupt routing.
49  *
50  */
51
52 #define MAX_CPUS 16
53
54 typedef struct SLAVIO_TIMERState {
55     qemu_irq irq;
56     ptimer_state *timer;
57     uint32_t count, counthigh, reached;
58     uint64_t limit;
59     // processor only
60     uint32_t running;
61     struct SLAVIO_TIMERState *master;
62     uint32_t slave_index;
63     // system only
64     uint32_t num_slaves;
65     struct SLAVIO_TIMERState *slave[MAX_CPUS];
66     uint32_t slave_mode;
67 } SLAVIO_TIMERState;
68
69 #define SYS_TIMER_SIZE 0x14
70 #define CPU_TIMER_SIZE 0x10
71
72 #define SYS_TIMER_OFFSET      0x10000ULL
73 #define CPU_TIMER_OFFSET(cpu) (0x1000ULL * cpu)
74
75 #define TIMER_LIMIT         0
76 #define TIMER_COUNTER       1
77 #define TIMER_COUNTER_NORST 2
78 #define TIMER_STATUS        3
79 #define TIMER_MODE          4
80
81 #define TIMER_COUNT_MASK32 0xfffffe00
82 #define TIMER_LIMIT_MASK32 0x7fffffff
83 #define TIMER_MAX_COUNT64  0x7ffffffffffffe00ULL
84 #define TIMER_MAX_COUNT32  0x7ffffe00ULL
85 #define TIMER_REACHED      0x80000000
86 #define TIMER_PERIOD       500ULL // 500ns
87 #define LIMIT_TO_PERIODS(l) ((l) >> 9)
88 #define PERIODS_TO_LIMIT(l) ((l) << 9)
89
90 static int slavio_timer_is_user(SLAVIO_TIMERState *s)
91 {
92     return s->master && (s->master->slave_mode & (1 << s->slave_index));
93 }
94
95 // Update count, set irq, update expire_time
96 // Convert from ptimer countdown units
97 static void slavio_timer_get_out(SLAVIO_TIMERState *s)
98 {
99     uint64_t count, limit;
100
101     if (s->limit == 0) /* free-run processor or system counter */
102         limit = TIMER_MAX_COUNT32;
103     else
104         limit = s->limit;
105
106     if (s->timer)
107         count = limit - PERIODS_TO_LIMIT(ptimer_get_count(s->timer));
108     else
109         count = 0;
110
111     DPRINTF("get_out: limit %" PRIx64 " count %x%08x\n", s->limit,
112             s->counthigh, s->count);
113     s->count = count & TIMER_COUNT_MASK32;
114     s->counthigh = count >> 32;
115 }
116
117 // timer callback
118 static void slavio_timer_irq(void *opaque)
119 {
120     SLAVIO_TIMERState *s = opaque;
121
122     slavio_timer_get_out(s);
123     DPRINTF("callback: count %x%08x\n", s->counthigh, s->count);
124     s->reached = TIMER_REACHED;
125     if (!slavio_timer_is_user(s))
126         qemu_irq_raise(s->irq);
127 }
128
129 static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
130 {
131     SLAVIO_TIMERState *s = opaque;
132     uint32_t saddr, ret;
133
134     saddr = addr >> 2;
135     switch (saddr) {
136     case TIMER_LIMIT:
137         // read limit (system counter mode) or read most signifying
138         // part of counter (user mode)
139         if (slavio_timer_is_user(s)) {
140             // read user timer MSW
141             slavio_timer_get_out(s);
142             ret = s->counthigh | s->reached;
143         } else {
144             // read limit
145             // clear irq
146             qemu_irq_lower(s->irq);
147             s->reached = 0;
148             ret = s->limit & TIMER_LIMIT_MASK32;
149         }
150         break;
151     case TIMER_COUNTER:
152         // read counter and reached bit (system mode) or read lsbits
153         // of counter (user mode)
154         slavio_timer_get_out(s);
155         if (slavio_timer_is_user(s)) // read user timer LSW
156             ret = s->count & TIMER_MAX_COUNT64;
157         else // read limit
158             ret = (s->count & TIMER_MAX_COUNT32) | s->reached;
159         break;
160     case TIMER_STATUS:
161         // only available in processor counter/timer
162         // read start/stop status
163         ret = s->running;
164         break;
165     case TIMER_MODE:
166         // only available in system counter
167         // read user/system mode
168         ret = s->slave_mode;
169         break;
170     default:
171         DPRINTF("invalid read address " TARGET_FMT_plx "\n", addr);
172         ret = 0;
173         break;
174     }
175     DPRINTF("read " TARGET_FMT_plx " = %08x\n", addr, ret);
176
177     return ret;
178 }
179
180 static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
181                                     uint32_t val)
182 {
183     SLAVIO_TIMERState *s = opaque;
184     uint32_t saddr;
185
186     DPRINTF("write " TARGET_FMT_plx " %08x\n", addr, val);
187     saddr = addr >> 2;
188     switch (saddr) {
189     case TIMER_LIMIT:
190         if (slavio_timer_is_user(s)) {
191             uint64_t count;
192
193             // set user counter MSW, reset counter
194             s->limit = TIMER_MAX_COUNT64;
195             s->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
196             s->reached = 0;
197             count = ((uint64_t)s->counthigh << 32) | s->count;
198             DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
199                     count);
200             if (s->timer)
201                 ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
202         } else {
203             // set limit, reset counter
204             qemu_irq_lower(s->irq);
205             s->limit = val & TIMER_MAX_COUNT32;
206             if (s->timer) {
207                 if (s->limit == 0) /* free-run */
208                     ptimer_set_limit(s->timer,
209                                      LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
210                 else
211                     ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1);
212             }
213         }
214         break;
215     case TIMER_COUNTER:
216         if (slavio_timer_is_user(s)) {
217             uint64_t count;
218
219             // set user counter LSW, reset counter
220             s->limit = TIMER_MAX_COUNT64;
221             s->count = val & TIMER_MAX_COUNT64;
222             s->reached = 0;
223             count = ((uint64_t)s->counthigh) << 32 | s->count;
224             DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
225                     count);
226             if (s->timer)
227                 ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
228         } else
229             DPRINTF("not user timer\n");
230         break;
231     case TIMER_COUNTER_NORST:
232         // set limit without resetting counter
233         s->limit = val & TIMER_MAX_COUNT32;
234         if (s->timer) {
235             if (s->limit == 0)  /* free-run */
236                 ptimer_set_limit(s->timer,
237                                  LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
238             else
239                 ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0);
240         }
241         break;
242     case TIMER_STATUS:
243         if (slavio_timer_is_user(s)) {
244             // start/stop user counter
245             if ((val & 1) && !s->running) {
246                 DPRINTF("processor %d user timer started\n", s->slave_index);
247                 if (s->timer)
248                     ptimer_run(s->timer, 0);
249                 s->running = 1;
250             } else if (!(val & 1) && s->running) {
251                 DPRINTF("processor %d user timer stopped\n", s->slave_index);
252                 if (s->timer)
253                     ptimer_stop(s->timer);
254                 s->running = 0;
255             }
256         }
257         break;
258     case TIMER_MODE:
259         if (s->master == NULL) {
260             unsigned int i;
261
262             for (i = 0; i < s->num_slaves; i++) {
263                 unsigned int processor = 1 << i;
264
265                 // check for a change in timer mode for this processor
266                 if ((val & processor) != (s->slave_mode & processor)) {
267                     if (val & processor) { // counter -> user timer
268                         qemu_irq_lower(s->slave[i]->irq);
269                         // counters are always running
270                         ptimer_stop(s->slave[i]->timer);
271                         s->slave[i]->running = 0;
272                         // user timer limit is always the same
273                         s->slave[i]->limit = TIMER_MAX_COUNT64;
274                         ptimer_set_limit(s->slave[i]->timer,
275                                          LIMIT_TO_PERIODS(s->slave[i]->limit),
276                                          1);
277                         // set this processors user timer bit in config
278                         // register
279                         s->slave_mode |= processor;
280                         DPRINTF("processor %d changed from counter to user "
281                                 "timer\n", s->slave[i]->slave_index);
282                     } else { // user timer -> counter
283                         // stop the user timer if it is running
284                         if (s->slave[i]->running)
285                             ptimer_stop(s->slave[i]->timer);
286                         // start the counter
287                         ptimer_run(s->slave[i]->timer, 0);
288                         s->slave[i]->running = 1;
289                         // clear this processors user timer bit in config
290                         // register
291                         s->slave_mode &= ~processor;
292                         DPRINTF("processor %d changed from user timer to "
293                                 "counter\n", s->slave[i]->slave_index);
294                     }
295                 }
296             }
297         } else
298             DPRINTF("not system timer\n");
299         break;
300     default:
301         DPRINTF("invalid write address " TARGET_FMT_plx "\n", addr);
302         break;
303     }
304 }
305
306 static CPUReadMemoryFunc *slavio_timer_mem_read[3] = {
307     NULL,
308     NULL,
309     slavio_timer_mem_readl,
310 };
311
312 static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
313     NULL,
314     NULL,
315     slavio_timer_mem_writel,
316 };
317
318 static void slavio_timer_save(QEMUFile *f, void *opaque)
319 {
320     SLAVIO_TIMERState *s = opaque;
321
322     qemu_put_be64s(f, &s->limit);
323     qemu_put_be32s(f, &s->count);
324     qemu_put_be32s(f, &s->counthigh);
325     qemu_put_be32s(f, &s->reached);
326     qemu_put_be32s(f, &s->running);
327     if (s->timer)
328         qemu_put_ptimer(f, s->timer);
329 }
330
331 static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
332 {
333     SLAVIO_TIMERState *s = opaque;
334
335     if (version_id != 3)
336         return -EINVAL;
337
338     qemu_get_be64s(f, &s->limit);
339     qemu_get_be32s(f, &s->count);
340     qemu_get_be32s(f, &s->counthigh);
341     qemu_get_be32s(f, &s->reached);
342     qemu_get_be32s(f, &s->running);
343     if (s->timer)
344         qemu_get_ptimer(f, s->timer);
345
346     return 0;
347 }
348
349 static void slavio_timer_reset(void *opaque)
350 {
351     SLAVIO_TIMERState *s = opaque;
352
353     s->limit = 0;
354     s->count = 0;
355     s->reached = 0;
356     s->slave_mode = 0;
357     if (!s->master || s->slave_index < s->master->num_slaves) {
358         ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
359         ptimer_run(s->timer, 0);
360     }
361     s->running = 1;
362     qemu_irq_lower(s->irq);
363 }
364
365 static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr,
366                                             qemu_irq irq,
367                                             SLAVIO_TIMERState *master,
368                                             uint32_t slave_index)
369 {
370     int slavio_timer_io_memory;
371     SLAVIO_TIMERState *s;
372     QEMUBH *bh;
373
374     s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
375     s->irq = irq;
376     s->master = master;
377     s->slave_index = slave_index;
378     if (!master || slave_index < master->num_slaves) {
379         bh = qemu_bh_new(slavio_timer_irq, s);
380         s->timer = ptimer_init(bh);
381         ptimer_set_period(s->timer, TIMER_PERIOD);
382     }
383
384     slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
385                                                     slavio_timer_mem_write, s);
386     if (master)
387         cpu_register_physical_memory(addr, CPU_TIMER_SIZE,
388                                      slavio_timer_io_memory);
389     else
390         cpu_register_physical_memory(addr, SYS_TIMER_SIZE,
391                                      slavio_timer_io_memory);
392     register_savevm("slavio_timer", addr, 3, slavio_timer_save,
393                     slavio_timer_load, s);
394     qemu_register_reset(slavio_timer_reset, 0, s);
395     slavio_timer_reset(s);
396
397     return s;
398 }
399
400 void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
401                            qemu_irq *cpu_irqs, unsigned int num_cpus)
402 {
403     SLAVIO_TIMERState *master;
404     unsigned int i;
405
406     master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
407
408     master->num_slaves = num_cpus;
409
410     for (i = 0; i < MAX_CPUS; i++) {
411         master->slave[i] = slavio_timer_init(base + (target_phys_addr_t)
412                                              CPU_TIMER_OFFSET(i),
413                                              cpu_irqs[i], master, i);
414     }
415 }