54
50
typedef struct SLAVIO_TIMERState {
57
uint32_t count, counthigh, reached;
61
struct SLAVIO_TIMERState *master;
65
struct SLAVIO_TIMERState *slave[MAX_CPUS];
51
uint32_t limit, count, counthigh;
52
int64_t count_load_time;
54
int64_t stop_time, tick_offset;
58
int mode; // 0 = processor, 1 = user, 2 = system
67
60
} SLAVIO_TIMERState;
69
62
#define TIMER_MAXADDR 0x1f
70
#define SYS_TIMER_SIZE 0x14
71
#define CPU_TIMER_SIZE 0x10
73
#define SYS_TIMER_OFFSET 0x10000ULL
74
#define CPU_TIMER_OFFSET(cpu) (0x1000ULL * cpu)
77
#define TIMER_COUNTER 1
78
#define TIMER_COUNTER_NORST 2
79
#define TIMER_STATUS 3
82
#define TIMER_COUNT_MASK32 0xfffffe00
83
#define TIMER_LIMIT_MASK32 0x7fffffff
84
#define TIMER_MAX_COUNT64 0x7ffffffffffffe00ULL
85
#define TIMER_MAX_COUNT32 0x7ffffe00ULL
86
#define TIMER_REACHED 0x80000000
87
#define TIMER_PERIOD 500ULL // 500ns
88
#define LIMIT_TO_PERIODS(l) ((l) >> 9)
89
#define PERIODS_TO_LIMIT(l) ((l) << 9)
91
static int slavio_timer_is_user(SLAVIO_TIMERState *s)
93
return s->master && (s->master->slave_mode & (1 << s->slave_index));
63
#define CNT_FREQ 2000000
96
65
// Update count, set irq, update expire_time
97
// Convert from ptimer countdown units
98
66
static void slavio_timer_get_out(SLAVIO_TIMERState *s)
100
uint64_t count, limit;
102
if (s->limit == 0) /* free-run processor or system counter */
103
limit = TIMER_MAX_COUNT32;
108
count = limit - PERIODS_TO_LIMIT(ptimer_get_count(s->timer));
112
DPRINTF("get_out: limit %" PRIx64 " count %x%08x\n", s->limit,
113
s->counthigh, s->count);
114
s->count = count & TIMER_COUNT_MASK32;
115
s->counthigh = count >> 32;
69
int64_t diff, ticks, count;
72
// There are three clock tick units: CPU ticks, register units
73
// (nanoseconds), and counter ticks (500 ns).
74
if (s->mode == 1 && s->stopped)
77
ticks = qemu_get_clock(vm_clock) - s->tick_offset;
79
out = (ticks > s->expire_time);
81
s->reached = 0x80000000;
87
// Convert register units to counter ticks
90
// Convert cpu ticks to counter ticks
91
diff = muldiv64(ticks - s->count_load_time, CNT_FREQ, ticks_per_sec);
93
// Calculate what the counter should be, convert to register
96
s->count = count << 9;
97
s->counthigh = count >> 22;
99
// Expire time: CPU ticks left to next interrupt
100
// Convert remaining counter ticks to CPU ticks
101
s->expire_time = ticks + muldiv64(limit - count, ticks_per_sec, CNT_FREQ);
103
DPRINTF("irq %d limit %d reached %d d %" PRId64 " count %d s->c %x diff %" PRId64 " stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode);
106
pic_set_irq_cpu(s->irq, out, s->cpu);
118
109
// timer callback
121
112
SLAVIO_TIMERState *s = opaque;
123
116
slavio_timer_get_out(s);
124
DPRINTF("callback: count %x%08x\n", s->counthigh, s->count);
125
s->reached = TIMER_REACHED;
126
if (!slavio_timer_is_user(s))
127
qemu_irq_raise(s->irq);
118
qemu_mod_timer(s->irq_timer, s->expire_time);
130
121
static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
132
123
SLAVIO_TIMERState *s = opaque;
135
126
saddr = (addr & TIMER_MAXADDR) >> 2;
138
// read limit (system counter mode) or read most signifying
139
// part of counter (user mode)
140
if (slavio_timer_is_user(s)) {
141
// read user timer MSW
142
slavio_timer_get_out(s);
143
ret = s->counthigh | s->reached;
147
qemu_irq_lower(s->irq);
149
ret = s->limit & TIMER_LIMIT_MASK32;
153
// read counter and reached bit (system mode) or read lsbits
154
// of counter (user mode)
155
slavio_timer_get_out(s);
156
if (slavio_timer_is_user(s)) // read user timer LSW
157
ret = s->count & TIMER_MAX_COUNT64;
159
ret = (s->count & TIMER_MAX_COUNT32) | s->reached;
162
// only available in processor counter/timer
163
// read start/stop status
167
// only available in system counter
168
// read user/system mode
129
// read limit (system counter mode) or read most signifying
130
// part of counter (user mode)
133
pic_set_irq_cpu(s->irq, 0, s->cpu);
134
s->count_load_time = qemu_get_clock(vm_clock);
139
slavio_timer_get_out(s);
140
return s->counthigh & 0x7fffffff;
143
// read counter and reached bit (system mode) or read lsbits
144
// of counter (user mode)
145
slavio_timer_get_out(s);
147
return (s->count & 0x7fffffff) | s->reached;
151
// read start/stop status
154
// read user/system mode
172
DPRINTF("invalid read address " TARGET_FMT_plx "\n", addr);
176
DPRINTF("read " TARGET_FMT_plx " = %08x\n", addr, ret);
181
static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
161
static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
184
163
SLAVIO_TIMERState *s = opaque;
187
DPRINTF("write " TARGET_FMT_plx " %08x\n", addr, val);
188
166
saddr = (addr & TIMER_MAXADDR) >> 2;
191
if (slavio_timer_is_user(s)) {
194
// set user counter MSW, reset counter
195
s->limit = TIMER_MAX_COUNT64;
196
s->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
198
count = ((uint64_t)s->counthigh << 32) | s->count;
199
DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
202
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
204
// set limit, reset counter
205
qemu_irq_lower(s->irq);
206
s->limit = val & TIMER_MAX_COUNT32;
208
if (s->limit == 0) /* free-run */
209
ptimer_set_limit(s->timer,
210
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
212
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1);
217
if (slavio_timer_is_user(s)) {
220
// set user counter LSW, reset counter
221
s->limit = TIMER_MAX_COUNT64;
222
s->count = val & TIMER_MAX_COUNT64;
224
count = ((uint64_t)s->counthigh) << 32 | s->count;
225
DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
228
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
230
DPRINTF("not user timer\n");
232
case TIMER_COUNTER_NORST:
233
// set limit without resetting counter
234
s->limit = val & TIMER_MAX_COUNT32;
236
if (s->limit == 0) /* free-run */
237
ptimer_set_limit(s->timer,
238
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
240
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0);
244
if (slavio_timer_is_user(s)) {
245
// start/stop user counter
246
if ((val & 1) && !s->running) {
247
DPRINTF("processor %d user timer started\n", s->slave_index);
249
ptimer_run(s->timer, 0);
251
} else if (!(val & 1) && s->running) {
252
DPRINTF("processor %d user timer stopped\n", s->slave_index);
254
ptimer_stop(s->timer);
260
if (s->master == NULL) {
263
for (i = 0; i < s->num_slaves; i++) {
264
unsigned int processor = 1 << i;
266
// check for a change in timer mode for this processor
267
if ((val & processor) != (s->slave_mode & processor)) {
268
if (val & processor) { // counter -> user timer
269
qemu_irq_lower(s->slave[i]->irq);
270
// counters are always running
271
ptimer_stop(s->slave[i]->timer);
272
s->slave[i]->running = 0;
273
// user timer limit is always the same
274
s->slave[i]->limit = TIMER_MAX_COUNT64;
275
ptimer_set_limit(s->slave[i]->timer,
276
LIMIT_TO_PERIODS(s->slave[i]->limit),
278
// set this processors user timer bit in config
280
s->slave_mode |= processor;
281
DPRINTF("processor %d changed from counter to user "
282
"timer\n", s->slave[i]->slave_index);
283
} else { // user timer -> counter
284
// stop the user timer if it is running
285
if (s->slave[i]->running)
286
ptimer_stop(s->slave[i]->timer);
288
ptimer_run(s->slave[i]->timer, 0);
289
s->slave[i]->running = 1;
290
// clear this processors user timer bit in config
292
s->slave_mode &= ~processor;
293
DPRINTF("processor %d changed from user timer to "
294
"counter\n", s->slave[i]->slave_index);
299
DPRINTF("not system timer\n");
169
// set limit, reset counter
170
s->count_load_time = qemu_get_clock(vm_clock);
173
// set limit without resetting counter
175
s->limit = 0x7fffffff;
177
s->limit = val & 0x7fffffff;
181
// start/stop user counter
184
s->stop_time = qemu_get_clock(vm_clock);
189
s->tick_offset += qemu_get_clock(vm_clock) - s->stop_time;
195
// bit 0: user (1) or system (0) counter mode
196
if (s->mode == 0 || s->mode == 1)
302
DPRINTF("invalid write address " TARGET_FMT_plx "\n", addr);
307
204
static CPUReadMemoryFunc *slavio_timer_mem_read[3] = {
205
slavio_timer_mem_readl,
206
slavio_timer_mem_readl,
310
207
slavio_timer_mem_readl,
313
210
static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
211
slavio_timer_mem_writel,
212
slavio_timer_mem_writel,
316
213
slavio_timer_mem_writel,
321
218
SLAVIO_TIMERState *s = opaque;
323
qemu_put_be64s(f, &s->limit);
220
qemu_put_be32s(f, &s->limit);
324
221
qemu_put_be32s(f, &s->count);
325
222
qemu_put_be32s(f, &s->counthigh);
223
qemu_put_be64s(f, &s->count_load_time);
224
qemu_put_be64s(f, &s->expire_time);
225
qemu_put_be64s(f, &s->stop_time);
226
qemu_put_be64s(f, &s->tick_offset);
227
qemu_put_be32s(f, &s->irq);
326
228
qemu_put_be32s(f, &s->reached);
327
qemu_put_be32s(f, &s->running);
329
qemu_put_ptimer(f, s->timer);
229
qemu_put_be32s(f, &s->stopped);
230
qemu_put_be32s(f, &s->mode);
332
233
static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
334
235
SLAVIO_TIMERState *s = opaque;
339
qemu_get_be64s(f, &s->limit);
240
qemu_get_be32s(f, &s->limit);
340
241
qemu_get_be32s(f, &s->count);
341
242
qemu_get_be32s(f, &s->counthigh);
243
qemu_get_be64s(f, &s->count_load_time);
244
qemu_get_be64s(f, &s->expire_time);
245
qemu_get_be64s(f, &s->stop_time);
246
qemu_get_be64s(f, &s->tick_offset);
247
qemu_get_be32s(f, &s->irq);
342
248
qemu_get_be32s(f, &s->reached);
343
qemu_get_be32s(f, &s->running);
345
qemu_get_ptimer(f, s->timer);
249
qemu_get_be32s(f, &s->stopped);
250
qemu_get_be32s(f, &s->mode);
260
s->count_load_time = qemu_get_clock(vm_clock);;
261
s->stop_time = s->count_load_time;
358
if (!s->master || s->slave_index < s->master->num_slaves) {
359
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
360
ptimer_run(s->timer, 0);
363
qemu_irq_lower(s->irq);
266
slavio_timer_get_out(s);
366
static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr,
368
SLAVIO_TIMERState *master,
369
uint32_t slave_index)
269
void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu)
371
271
int slavio_timer_io_memory;
372
272
SLAVIO_TIMERState *s;
375
274
s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
380
s->slave_index = slave_index;
381
if (!master || slave_index < master->num_slaves) {
382
bh = qemu_bh_new(slavio_timer_irq, s);
383
s->timer = ptimer_init(bh);
384
ptimer_set_period(s->timer, TIMER_PERIOD);
280
s->irq_timer = qemu_new_timer(vm_clock, slavio_timer_irq, s);
387
282
slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
388
slavio_timer_mem_write, s);
390
cpu_register_physical_memory(addr, CPU_TIMER_SIZE,
391
slavio_timer_io_memory);
393
cpu_register_physical_memory(addr, SYS_TIMER_SIZE,
394
slavio_timer_io_memory);
395
register_savevm("slavio_timer", addr, 3, slavio_timer_save,
396
slavio_timer_load, s);
283
slavio_timer_mem_write, s);
284
cpu_register_physical_memory(addr, TIMER_MAXADDR, slavio_timer_io_memory);
285
register_savevm("slavio_timer", addr, 1, slavio_timer_save, slavio_timer_load, s);
397
286
qemu_register_reset(slavio_timer_reset, s);
398
287
slavio_timer_reset(s);
403
void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
404
qemu_irq *cpu_irqs, unsigned int num_cpus)
406
SLAVIO_TIMERState *master;
409
master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
411
master->num_slaves = num_cpus;
413
for (i = 0; i < MAX_CPUS; i++) {
414
master->slave[i] = slavio_timer_init(base + (target_phys_addr_t)
416
cpu_irqs[i], master, i);