84
82
#define TIMER_MAX_COUNT32 0x7ffffe00ULL
85
83
#define TIMER_REACHED 0x80000000
86
84
#define TIMER_PERIOD 500ULL // 500ns
87
#define LIMIT_TO_PERIODS(l) ((l) >> 9)
88
#define PERIODS_TO_LIMIT(l) ((l) << 9)
85
#define LIMIT_TO_PERIODS(l) (((l) >> 9) - 1)
86
#define PERIODS_TO_LIMIT(l) (((l) + 1) << 9)
90
static int slavio_timer_is_user(SLAVIO_TIMERState *s)
88
static int slavio_timer_is_user(TimerContext *tc)
92
return s->master && (s->master->slave_mode & (1 << s->slave_index));
90
SLAVIO_TIMERState *s = tc->s;
91
unsigned int timer_index = tc->timer_index;
93
return timer_index != 0 && (s->cputimer_mode & (1 << (timer_index - 1)));
95
96
// Update count, set irq, update expire_time
96
97
// Convert from ptimer countdown units
97
static void slavio_timer_get_out(SLAVIO_TIMERState *s)
98
static void slavio_timer_get_out(CPUTimerState *t)
99
100
uint64_t count, limit;
101
if (s->limit == 0) /* free-run processor or system counter */
102
if (t->limit == 0) { /* free-run system or processor counter */
102
103
limit = TIMER_MAX_COUNT32;
107
count = limit - PERIODS_TO_LIMIT(ptimer_get_count(s->timer));
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;
107
count = limit - PERIODS_TO_LIMIT(ptimer_get_count(t->timer));
109
trace_slavio_timer_get_out(t->limit, t->counthigh, t->count);
110
t->count = count & TIMER_COUNT_MASK32;
111
t->counthigh = count >> 32;
117
114
// timer callback
118
115
static void slavio_timer_irq(void *opaque)
120
SLAVIO_TIMERState *s = opaque;
117
TimerContext *tc = opaque;
118
SLAVIO_TIMERState *s = tc->s;
119
CPUTimerState *t = &s->cputimer[tc->timer_index];
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);
121
slavio_timer_get_out(t);
122
trace_slavio_timer_irq(t->counthigh, t->count);
123
/* if limit is 0 (free-run), there will be no match */
125
t->reached = TIMER_REACHED;
127
/* there is no interrupt if user timer or free-run */
128
if (!slavio_timer_is_user(tc) && t->limit != 0) {
129
qemu_irq_raise(t->irq);
129
static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
133
static uint64_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr,
131
SLAVIO_TIMERState *s = opaque;
136
TimerContext *tc = opaque;
137
SLAVIO_TIMERState *s = tc->s;
132
138
uint32_t saddr, ret;
139
unsigned int timer_index = tc->timer_index;
140
CPUTimerState *t = &s->cputimer[timer_index];
134
142
saddr = addr >> 2;
136
144
case TIMER_LIMIT:
137
145
// read limit (system counter mode) or read most signifying
138
146
// part of counter (user mode)
139
if (slavio_timer_is_user(s)) {
147
if (slavio_timer_is_user(tc)) {
140
148
// read user timer MSW
141
slavio_timer_get_out(s);
142
ret = s->counthigh | s->reached;
149
slavio_timer_get_out(t);
150
ret = t->counthigh | t->reached;
146
qemu_irq_lower(s->irq);
148
ret = s->limit & TIMER_LIMIT_MASK32;
154
qemu_irq_lower(t->irq);
156
ret = t->limit & TIMER_LIMIT_MASK32;
151
159
case TIMER_COUNTER:
152
160
// read counter and reached bit (system mode) or read lsbits
153
161
// 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;
158
ret = (s->count & TIMER_MAX_COUNT32) | s->reached;
162
slavio_timer_get_out(t);
163
if (slavio_timer_is_user(tc)) { // read user timer LSW
164
ret = t->count & TIMER_MAX_COUNT64;
165
} else { // read limit
166
ret = (t->count & TIMER_MAX_COUNT32) |
160
170
case TIMER_STATUS:
161
171
// only available in processor counter/timer
162
172
// read start/stop status
173
if (timer_index > 0) {
166
180
// only available in system counter
167
181
// read user/system mode
182
ret = s->cputimer_mode;
171
DPRINTF("invalid read address " TARGET_FMT_plx "\n", addr);
185
trace_slavio_timer_mem_readl_invalid(addr);
175
DPRINTF("read " TARGET_FMT_plx " = %08x\n", addr, ret);
189
trace_slavio_timer_mem_readl(addr, ret);
180
193
static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
194
uint64_t val, unsigned size)
183
SLAVIO_TIMERState *s = opaque;
196
TimerContext *tc = opaque;
197
SLAVIO_TIMERState *s = tc->s;
199
unsigned int timer_index = tc->timer_index;
200
CPUTimerState *t = &s->cputimer[timer_index];
186
DPRINTF("write " TARGET_FMT_plx " %08x\n", addr, val);
202
trace_slavio_timer_mem_writel(addr, val);
187
203
saddr = addr >> 2;
189
205
case TIMER_LIMIT:
190
if (slavio_timer_is_user(s)) {
206
if (slavio_timer_is_user(tc)) {
193
209
// set user counter MSW, reset counter
194
s->limit = TIMER_MAX_COUNT64;
195
s->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
197
count = ((uint64_t)s->counthigh << 32) | s->count;
198
DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
201
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
210
t->limit = TIMER_MAX_COUNT64;
211
t->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
213
count = ((uint64_t)t->counthigh << 32) | t->count;
214
trace_slavio_timer_mem_writel_limit(timer_index, count);
215
ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
203
217
// set limit, reset counter
204
qemu_irq_lower(s->irq);
205
s->limit = val & TIMER_MAX_COUNT32;
207
if (s->limit == 0) /* free-run */
208
ptimer_set_limit(s->timer,
218
qemu_irq_lower(t->irq);
219
t->limit = val & TIMER_MAX_COUNT32;
221
if (t->limit == 0) { /* free-run */
222
ptimer_set_limit(t->timer,
209
223
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
211
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1);
225
ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 1);
215
230
case TIMER_COUNTER:
216
if (slavio_timer_is_user(s)) {
231
if (slavio_timer_is_user(tc)) {
219
234
// set user counter LSW, reset counter
220
s->limit = TIMER_MAX_COUNT64;
221
s->count = val & TIMER_MAX_COUNT64;
223
count = ((uint64_t)s->counthigh) << 32 | s->count;
224
DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
227
ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
229
DPRINTF("not user timer\n");
235
t->limit = TIMER_MAX_COUNT64;
236
t->count = val & TIMER_MAX_COUNT64;
238
count = ((uint64_t)t->counthigh) << 32 | t->count;
239
trace_slavio_timer_mem_writel_limit(timer_index, count);
240
ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
242
trace_slavio_timer_mem_writel_counter_invalid();
231
245
case TIMER_COUNTER_NORST:
232
246
// set limit without resetting counter
233
s->limit = val & TIMER_MAX_COUNT32;
235
if (s->limit == 0) /* free-run */
236
ptimer_set_limit(s->timer,
237
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
239
ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 0);
247
t->limit = val & TIMER_MAX_COUNT32;
248
if (t->limit == 0) { /* free-run */
249
ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
251
ptimer_set_limit(t->timer, LIMIT_TO_PERIODS(t->limit), 0);
242
254
case TIMER_STATUS:
243
if (slavio_timer_is_user(s)) {
255
if (slavio_timer_is_user(tc)) {
244
256
// start/stop user counter
245
if ((val & 1) && !s->running) {
246
DPRINTF("processor %d user timer started\n", s->slave_index);
248
ptimer_run(s->timer, 0);
250
} else if (!(val & 1) && s->running) {
251
DPRINTF("processor %d user timer stopped\n", s->slave_index);
253
ptimer_stop(s->timer);
257
if ((val & 1) && !t->running) {
258
trace_slavio_timer_mem_writel_status_start(timer_index);
259
ptimer_run(t->timer, 0);
261
} else if (!(val & 1) && t->running) {
262
trace_slavio_timer_mem_writel_status_stop(timer_index);
263
ptimer_stop(t->timer);
259
if (s->master == NULL) {
269
if (timer_index == 0) {
262
for (i = 0; i < s->num_slaves; i++) {
272
for (i = 0; i < s->num_cpus; i++) {
263
273
unsigned int processor = 1 << i;
274
CPUTimerState *curr_timer = &s->cputimer[i + 1];
265
276
// check for a change in timer mode for this processor
266
if ((val & processor) != (s->slave_mode & processor)) {
277
if ((val & processor) != (s->cputimer_mode & processor)) {
267
278
if (val & processor) { // counter -> user timer
268
qemu_irq_lower(s->slave[i]->irq);
279
qemu_irq_lower(curr_timer->irq);
269
280
// counters are always running
270
ptimer_stop(s->slave[i]->timer);
271
s->slave[i]->running = 0;
281
ptimer_stop(curr_timer->timer);
282
curr_timer->running = 0;
272
283
// 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),
284
curr_timer->limit = TIMER_MAX_COUNT64;
285
ptimer_set_limit(curr_timer->timer,
286
LIMIT_TO_PERIODS(curr_timer->limit),
277
288
// set this processors user timer bit in config
279
s->slave_mode |= processor;
280
DPRINTF("processor %d changed from counter to user "
281
"timer\n", s->slave[i]->slave_index);
290
s->cputimer_mode |= processor;
291
trace_slavio_timer_mem_writel_mode_user(timer_index);
282
292
} else { // user timer -> counter
283
293
// stop the user timer if it is running
284
if (s->slave[i]->running)
285
ptimer_stop(s->slave[i]->timer);
294
if (curr_timer->running) {
295
ptimer_stop(curr_timer->timer);
286
297
// start the counter
287
ptimer_run(s->slave[i]->timer, 0);
288
s->slave[i]->running = 1;
298
ptimer_run(curr_timer->timer, 0);
299
curr_timer->running = 1;
289
300
// clear this processors user timer bit in config
291
s->slave_mode &= ~processor;
292
DPRINTF("processor %d changed from user timer to "
293
"counter\n", s->slave[i]->slave_index);
302
s->cputimer_mode &= ~processor;
303
trace_slavio_timer_mem_writel_mode_counter(timer_index);
298
DPRINTF("not system timer\n");
308
trace_slavio_timer_mem_writel_mode_invalid();
301
DPRINTF("invalid write address " TARGET_FMT_plx "\n", addr);
312
trace_slavio_timer_mem_writel_invalid(addr);
306
static CPUReadMemoryFunc *slavio_timer_mem_read[3] = {
309
slavio_timer_mem_readl,
312
static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
315
slavio_timer_mem_writel,
318
static void slavio_timer_save(QEMUFile *f, void *opaque)
317
static const MemoryRegionOps slavio_timer_mem_ops = {
318
.read = slavio_timer_mem_readl,
319
.write = slavio_timer_mem_writel,
320
.endianness = DEVICE_NATIVE_ENDIAN,
322
.min_access_size = 4,
323
.max_access_size = 4,
327
static const VMStateDescription vmstate_timer = {
330
.minimum_version_id = 3,
331
.minimum_version_id_old = 3,
332
.fields = (VMStateField []) {
333
VMSTATE_UINT64(limit, CPUTimerState),
334
VMSTATE_UINT32(count, CPUTimerState),
335
VMSTATE_UINT32(counthigh, CPUTimerState),
336
VMSTATE_UINT32(reached, CPUTimerState),
337
VMSTATE_UINT32(running, CPUTimerState),
338
VMSTATE_PTIMER(timer, CPUTimerState),
339
VMSTATE_END_OF_LIST()
343
static const VMStateDescription vmstate_slavio_timer = {
344
.name ="slavio_timer",
346
.minimum_version_id = 3,
347
.minimum_version_id_old = 3,
348
.fields = (VMStateField []) {
349
VMSTATE_STRUCT_ARRAY(cputimer, SLAVIO_TIMERState, MAX_CPUS + 1, 3,
350
vmstate_timer, CPUTimerState),
351
VMSTATE_END_OF_LIST()
355
static void slavio_timer_reset(DeviceState *d)
320
SLAVIO_TIMERState *s = opaque;
357
SLAVIO_TIMERState *s = container_of(d, SLAVIO_TIMERState, busdev.qdev);
359
CPUTimerState *curr_timer;
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);
328
qemu_put_ptimer(f, s->timer);
361
for (i = 0; i <= MAX_CPUS; i++) {
362
curr_timer = &s->cputimer[i];
363
curr_timer->limit = 0;
364
curr_timer->count = 0;
365
curr_timer->reached = 0;
366
if (i <= s->num_cpus) {
367
ptimer_set_limit(curr_timer->timer,
368
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
369
ptimer_run(curr_timer->timer, 0);
370
curr_timer->running = 1;
373
s->cputimer_mode = 0;
331
static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
376
static int slavio_timer_init1(SysBusDevice *dev)
333
SLAVIO_TIMERState *s = opaque;
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);
344
qemu_get_ptimer(f, s->timer);
378
SLAVIO_TIMERState *s = FROM_SYSBUS(SLAVIO_TIMERState, dev);
383
for (i = 0; i <= MAX_CPUS; i++) {
387
tc = g_malloc0(sizeof(TimerContext));
391
bh = qemu_bh_new(slavio_timer_irq, tc);
392
s->cputimer[i].timer = ptimer_init(bh);
393
ptimer_set_period(s->cputimer[i].timer, TIMER_PERIOD);
395
size = i == 0 ? SYS_TIMER_SIZE : CPU_TIMER_SIZE;
396
snprintf(timer_name, sizeof(timer_name), "timer-%i", i);
397
memory_region_init_io(&tc->iomem, &slavio_timer_mem_ops, tc,
399
sysbus_init_mmio(dev, &tc->iomem);
401
sysbus_init_irq(dev, &s->cputimer[i].irq);
349
static void slavio_timer_reset(void *opaque)
351
SLAVIO_TIMERState *s = opaque;
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);
362
qemu_irq_lower(s->irq);
365
static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr,
367
SLAVIO_TIMERState *master,
368
uint32_t slave_index)
370
int slavio_timer_io_memory;
371
SLAVIO_TIMERState *s;
374
s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
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);
384
slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
385
slavio_timer_mem_write, s);
387
cpu_register_physical_memory(addr, CPU_TIMER_SIZE,
388
slavio_timer_io_memory);
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, s);
395
slavio_timer_reset(s);
400
void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
401
qemu_irq *cpu_irqs, unsigned int num_cpus)
403
SLAVIO_TIMERState *master;
406
master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
408
master->num_slaves = num_cpus;
410
for (i = 0; i < MAX_CPUS; i++) {
411
master->slave[i] = slavio_timer_init(base + (target_phys_addr_t)
413
cpu_irqs[i], master, i);
407
static Property slavio_timer_properties[] = {
408
DEFINE_PROP_UINT32("num_cpus", SLAVIO_TIMERState, num_cpus, 0),
409
DEFINE_PROP_END_OF_LIST(),
412
static void slavio_timer_class_init(ObjectClass *klass, void *data)
414
DeviceClass *dc = DEVICE_CLASS(klass);
415
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
417
k->init = slavio_timer_init1;
418
dc->reset = slavio_timer_reset;
419
dc->vmsd = &vmstate_slavio_timer;
420
dc->props = slavio_timer_properties;
423
static TypeInfo slavio_timer_info = {
424
.name = "slavio_timer",
425
.parent = TYPE_SYS_BUS_DEVICE,
426
.instance_size = sizeof(SLAVIO_TIMERState),
427
.class_init = slavio_timer_class_init,
430
static void slavio_timer_register_types(void)
432
type_register_static(&slavio_timer_info);
435
type_init(slavio_timer_register_types)