Initialize
[sdk/emulator/qemu.git] / 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
25 #include "sun4m.h"
26 #include "qemu-timer.h"
27 #include "sysbus.h"
28 #include "trace.h"
29
30 /*
31  * Registers of hardware timer in sun4m.
32  *
33  * This is the timer/counter part of chip STP2001 (Slave I/O), also
34  * produced as NCR89C105. See
35  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
36  *
37  * The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0
38  * are zero. Bit 31 is 1 when count has been reached.
39  *
40  * Per-CPU timers interrupt local CPU, system timer uses normal
41  * interrupt routing.
42  *
43  */
44
45 #define MAX_CPUS 16
46
47 typedef struct CPUTimerState {
48     qemu_irq irq;
49     ptimer_state *timer;
50     uint32_t count, counthigh, reached;
51     uint64_t limit;
52     // processor only
53     uint32_t running;
54 } CPUTimerState;
55
56 typedef struct SLAVIO_TIMERState {
57     SysBusDevice busdev;
58     uint32_t num_cpus;
59     CPUTimerState cputimer[MAX_CPUS + 1];
60     uint32_t cputimer_mode;
61 } SLAVIO_TIMERState;
62
63 typedef struct TimerContext {
64     SLAVIO_TIMERState *s;
65     unsigned int timer_index; /* 0 for system, 1 ... MAX_CPUS for CPU timers */
66 } TimerContext;
67
68 #define SYS_TIMER_SIZE 0x14
69 #define CPU_TIMER_SIZE 0x10
70
71 #define TIMER_LIMIT         0
72 #define TIMER_COUNTER       1
73 #define TIMER_COUNTER_NORST 2
74 #define TIMER_STATUS        3
75 #define TIMER_MODE          4
76
77 #define TIMER_COUNT_MASK32 0xfffffe00
78 #define TIMER_LIMIT_MASK32 0x7fffffff
79 #define TIMER_MAX_COUNT64  0x7ffffffffffffe00ULL
80 #define TIMER_MAX_COUNT32  0x7ffffe00ULL
81 #define TIMER_REACHED      0x80000000
82 #define TIMER_PERIOD       500ULL // 500ns
83 #define LIMIT_TO_PERIODS(l) (((l) >> 9) - 1)
84 #define PERIODS_TO_LIMIT(l) (((l) + 1) << 9)
85
86 static int slavio_timer_is_user(TimerContext *tc)
87 {
88     SLAVIO_TIMERState *s = tc->s;
89     unsigned int timer_index = tc->timer_index;
90
91     return timer_index != 0 && (s->cputimer_mode & (1 << (timer_index - 1)));
92 }
93
94 // Update count, set irq, update expire_time
95 // Convert from ptimer countdown units
96 static void slavio_timer_get_out(CPUTimerState *t)
97 {
98     uint64_t count, limit;
99
100     if (t->limit == 0) { /* free-run system or processor counter */
101         limit = TIMER_MAX_COUNT32;
102     } else {
103         limit = t->limit;
104     }
105     count = limit - PERIODS_TO_LIMIT(ptimer_get_count(t->timer));
106
107     trace_slavio_timer_get_out(t->limit, t->counthigh, t->count);
108     t->count = count & TIMER_COUNT_MASK32;
109     t->counthigh = count >> 32;
110 }
111
112 // timer callback
113 static void slavio_timer_irq(void *opaque)
114 {
115     TimerContext *tc = opaque;
116     SLAVIO_TIMERState *s = tc->s;
117     CPUTimerState *t = &s->cputimer[tc->timer_index];
118
119     slavio_timer_get_out(t);
120     trace_slavio_timer_irq(t->counthigh, t->count);
121     /* if limit is 0 (free-run), there will be no match */
122     if (t->limit != 0) {
123         t->reached = TIMER_REACHED;
124     }
125     /* there is no interrupt if user timer or free-run */
126     if (!slavio_timer_is_user(tc) && t->limit != 0) {
127         qemu_irq_raise(t->irq);
128     }
129 }
130
131 static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
132 {
133     TimerContext *tc = opaque;
134     SLAVIO_TIMERState *s = tc->s;
135     uint32_t saddr, ret;
136     unsigned int timer_index = tc->timer_index;
137     CPUTimerState *t = &s->cputimer[timer_index];
138
139     saddr = addr >> 2;
140     switch (saddr) {
141     case TIMER_LIMIT:
142         // read limit (system counter mode) or read most signifying
143         // part of counter (user mode)
144         if (slavio_timer_is_user(tc)) {
145             // read user timer MSW
146             slavio_timer_get_out(t);
147             ret = t->counthigh | t->reached;
148         } else {
149             // read limit
150             // clear irq
151             qemu_irq_lower(t->irq);
152             t->reached = 0;
153             ret = t->limit & TIMER_LIMIT_MASK32;
154         }
155         break;
156     case TIMER_COUNTER:
157         // read counter and reached bit (system mode) or read lsbits
158         // of counter (user mode)
159         slavio_timer_get_out(t);
160         if (slavio_timer_is_user(tc)) { // read user timer LSW
161             ret = t->count & TIMER_MAX_COUNT64;
162         } else { // read limit
163             ret = (t->count & TIMER_MAX_COUNT32) |
164                 t->reached;
165         }
166         break;
167     case TIMER_STATUS:
168         // only available in processor counter/timer
169         // read start/stop status
170         if (timer_index > 0) {
171             ret = t->running;
172         } else {
173             ret = 0;
174         }
175         break;
176     case TIMER_MODE:
177         // only available in system counter
178         // read user/system mode
179         ret = s->cputimer_mode;
180         break;
181     default:
182         trace_slavio_timer_mem_readl_invalid(addr);
183         ret = 0;
184         break;
185     }
186     trace_slavio_timer_mem_readl(addr, ret);
187     return ret;
188 }
189
190 static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
191                                     uint32_t val)
192 {
193     TimerContext *tc = opaque;
194     SLAVIO_TIMERState *s = tc->s;
195     uint32_t saddr;
196     unsigned int timer_index = tc->timer_index;
197     CPUTimerState *t = &s->cputimer[timer_index];
198
199     trace_slavio_timer_mem_writel(addr, val);
200     saddr = addr >> 2;
201     switch (saddr) {
202     case TIMER_LIMIT:
203         if (slavio_timer_is_user(tc)) {
204             uint64_t count;
205
206             // set user counter MSW, reset counter
207             t->limit = TIMER_MAX_COUNT64;
208             t->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
209             t->reached = 0;
210             count = ((uint64_t)t->counthigh << 32) | t->count;
211             trace_slavio_timer_mem_writel_limit(timer_index, count);
212             ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
213         } else {
214             // set limit, reset counter
215             qemu_irq_lower(t->irq);
216             t->limit = val & TIMER_MAX_COUNT32;
217             if (t->timer) {
218                 if (t->limit == 0) { /* free-run */
219                     ptimer_set_limit(t->timer,
220                                      LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
221                 } else {
222                     ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 1);
223                 }
224             }
225         }
226         break;
227     case TIMER_COUNTER:
228         if (slavio_timer_is_user(tc)) {
229             uint64_t count;
230
231             // set user counter LSW, reset counter
232             t->limit = TIMER_MAX_COUNT64;
233             t->count = val & TIMER_MAX_COUNT64;
234             t->reached = 0;
235             count = ((uint64_t)t->counthigh) << 32 | t->count;
236             trace_slavio_timer_mem_writel_limit(timer_index, count);
237             ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
238         } else {
239             trace_slavio_timer_mem_writel_counter_invalid();
240         }
241         break;
242     case TIMER_COUNTER_NORST:
243         // set limit without resetting counter
244         t->limit = val & TIMER_MAX_COUNT32;
245         if (t->limit == 0) { /* free-run */
246             ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
247         } else {
248             ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 0);
249         }
250         break;
251     case TIMER_STATUS:
252         if (slavio_timer_is_user(tc)) {
253             // start/stop user counter
254             if ((val & 1) && !t->running) {
255                 trace_slavio_timer_mem_writel_status_start(timer_index);
256                 ptimer_run(t->timer, 0);
257                 t->running = 1;
258             } else if (!(val & 1) && t->running) {
259                 trace_slavio_timer_mem_writel_status_stop(timer_index);
260                 ptimer_stop(t->timer);
261                 t->running = 0;
262             }
263         }
264         break;
265     case TIMER_MODE:
266         if (timer_index == 0) {
267             unsigned int i;
268
269             for (i = 0; i < s->num_cpus; i++) {
270                 unsigned int processor = 1 << i;
271                 CPUTimerState *curr_timer = &s->cputimer[i + 1];
272
273                 // check for a change in timer mode for this processor
274                 if ((val & processor) != (s->cputimer_mode & processor)) {
275                     if (val & processor) { // counter -> user timer
276                         qemu_irq_lower(curr_timer->irq);
277                         // counters are always running
278                         ptimer_stop(curr_timer->timer);
279                         curr_timer->running = 0;
280                         // user timer limit is always the same
281                         curr_timer->limit = TIMER_MAX_COUNT64;
282                         ptimer_set_limit(curr_timer->timer,
283                                          LIMIT_TO_PERIODS(curr_timer->limit),
284                                          1);
285                         // set this processors user timer bit in config
286                         // register
287                         s->cputimer_mode |= processor;
288                         trace_slavio_timer_mem_writel_mode_user(timer_index);
289                     } else { // user timer -> counter
290                         // stop the user timer if it is running
291                         if (curr_timer->running) {
292                             ptimer_stop(curr_timer->timer);
293                         }
294                         // start the counter
295                         ptimer_run(curr_timer->timer, 0);
296                         curr_timer->running = 1;
297                         // clear this processors user timer bit in config
298                         // register
299                         s->cputimer_mode &= ~processor;
300                         trace_slavio_timer_mem_writel_mode_counter(timer_index);
301                     }
302                 }
303             }
304         } else {
305             trace_slavio_timer_mem_writel_mode_invalid();
306         }
307         break;
308     default:
309         trace_slavio_timer_mem_writel_invalid(addr);
310         break;
311     }
312 }
313
314 static CPUReadMemoryFunc * const slavio_timer_mem_read[3] = {
315     NULL,
316     NULL,
317     slavio_timer_mem_readl,
318 };
319
320 static CPUWriteMemoryFunc * const slavio_timer_mem_write[3] = {
321     NULL,
322     NULL,
323     slavio_timer_mem_writel,
324 };
325
326 static const VMStateDescription vmstate_timer = {
327     .name ="timer",
328     .version_id = 3,
329     .minimum_version_id = 3,
330     .minimum_version_id_old = 3,
331     .fields      = (VMStateField []) {
332         VMSTATE_UINT64(limit, CPUTimerState),
333         VMSTATE_UINT32(count, CPUTimerState),
334         VMSTATE_UINT32(counthigh, CPUTimerState),
335         VMSTATE_UINT32(reached, CPUTimerState),
336         VMSTATE_UINT32(running, CPUTimerState),
337         VMSTATE_PTIMER(timer, CPUTimerState),
338         VMSTATE_END_OF_LIST()
339     }
340 };
341
342 static const VMStateDescription vmstate_slavio_timer = {
343     .name ="slavio_timer",
344     .version_id = 3,
345     .minimum_version_id = 3,
346     .minimum_version_id_old = 3,
347     .fields      = (VMStateField []) {
348         VMSTATE_STRUCT_ARRAY(cputimer, SLAVIO_TIMERState, MAX_CPUS + 1, 3,
349                              vmstate_timer, CPUTimerState),
350         VMSTATE_END_OF_LIST()
351     }
352 };
353
354 static void slavio_timer_reset(DeviceState *d)
355 {
356     SLAVIO_TIMERState *s = container_of(d, SLAVIO_TIMERState, busdev.qdev);
357     unsigned int i;
358     CPUTimerState *curr_timer;
359
360     for (i = 0; i <= MAX_CPUS; i++) {
361         curr_timer = &s->cputimer[i];
362         curr_timer->limit = 0;
363         curr_timer->count = 0;
364         curr_timer->reached = 0;
365         if (i <= s->num_cpus) {
366             ptimer_set_limit(curr_timer->timer,
367                              LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
368             ptimer_run(curr_timer->timer, 0);
369             curr_timer->running = 1;
370         }
371     }
372     s->cputimer_mode = 0;
373 }
374
375 static int slavio_timer_init1(SysBusDevice *dev)
376 {
377     int io;
378     SLAVIO_TIMERState *s = FROM_SYSBUS(SLAVIO_TIMERState, dev);
379     QEMUBH *bh;
380     unsigned int i;
381     TimerContext *tc;
382
383     for (i = 0; i <= MAX_CPUS; i++) {
384         tc = qemu_mallocz(sizeof(TimerContext));
385         tc->s = s;
386         tc->timer_index = i;
387
388         bh = qemu_bh_new(slavio_timer_irq, tc);
389         s->cputimer[i].timer = ptimer_init(bh);
390         ptimer_set_period(s->cputimer[i].timer, TIMER_PERIOD);
391
392         io = cpu_register_io_memory(slavio_timer_mem_read,
393                                     slavio_timer_mem_write, tc,
394                                     DEVICE_NATIVE_ENDIAN);
395         if (i == 0) {
396             sysbus_init_mmio(dev, SYS_TIMER_SIZE, io);
397         } else {
398             sysbus_init_mmio(dev, CPU_TIMER_SIZE, io);
399         }
400
401         sysbus_init_irq(dev, &s->cputimer[i].irq);
402     }
403
404     return 0;
405 }
406
407 static SysBusDeviceInfo slavio_timer_info = {
408     .init = slavio_timer_init1,
409     .qdev.name  = "slavio_timer",
410     .qdev.size  = sizeof(SLAVIO_TIMERState),
411     .qdev.vmsd  = &vmstate_slavio_timer,
412     .qdev.reset = slavio_timer_reset,
413     .qdev.props = (Property[]) {
414         DEFINE_PROP_UINT32("num_cpus",  SLAVIO_TIMERState, num_cpus,  0),
415         DEFINE_PROP_END_OF_LIST(),
416     }
417 };
418
419 static void slavio_timer_register_devices(void)
420 {
421     sysbus_register_withprop(&slavio_timer_info);
422 }
423
424 device_init(slavio_timer_register_devices)