xref: /openbmc/qemu/hw/timer/sse-counter.c (revision 59964b4f)
1 /*
2  * Arm SSE Subsystem System Counter
3  *
4  * Copyright (c) 2020 Linaro Limited
5  * Written by Peter Maydell
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 or
9  * (at your option) any later version.
10  */
11 
12 /*
13  * This is a model of the "System counter" which is documented in
14  * the Arm SSE-123 Example Subsystem Technical Reference Manual:
15  * https://developer.arm.com/documentation/101370/latest/
16  *
17  * The system counter is a non-stop 64-bit up-counter. It provides
18  * this count value to other devices like the SSE system timer,
19  * which are driven by this system timestamp rather than directly
20  * from a clock. Internally to the counter the count is actually
21  * 88-bit precision (64.24 fixed point), with a programmable scale factor.
22  *
23  * The hardware has the optional feature that it supports dynamic
24  * clock switching, where two clock inputs are connected, and which
25  * one is used is selected via a CLKSEL input signal. Since the
26  * users of this device in QEMU don't use this feature, we only model
27  * the HWCLKSW=0 configuration.
28  */
29 #include "qemu/osdep.h"
30 #include "qemu/log.h"
31 #include "qemu/timer.h"
32 #include "qapi/error.h"
33 #include "trace.h"
34 #include "hw/timer/sse-counter.h"
35 #include "hw/sysbus.h"
36 #include "hw/irq.h"
37 #include "hw/registerfields.h"
38 #include "hw/clock.h"
39 #include "hw/qdev-clock.h"
40 #include "migration/vmstate.h"
41 
42 /* Registers in the control frame */
43 REG32(CNTCR, 0x0)
44     FIELD(CNTCR, EN, 0, 1)
45     FIELD(CNTCR, HDBG, 1, 1)
46     FIELD(CNTCR, SCEN, 2, 1)
47     FIELD(CNTCR, INTRMASK, 3, 1)
48     FIELD(CNTCR, PSLVERRDIS, 4, 1)
49     FIELD(CNTCR, INTRCLR, 5, 1)
50 /*
51  * Although CNTCR defines interrupt-related bits, the counter doesn't
52  * appear to actually have an interrupt output. So INTRCLR is
53  * effectively a RAZ/WI bit, as are the reserved bits [31:6].
54  */
55 #define CNTCR_VALID_MASK (R_CNTCR_EN_MASK | R_CNTCR_HDBG_MASK | \
56                           R_CNTCR_SCEN_MASK | R_CNTCR_INTRMASK_MASK | \
57                           R_CNTCR_PSLVERRDIS_MASK)
58 REG32(CNTSR, 0x4)
59 REG32(CNTCV_LO, 0x8)
60 REG32(CNTCV_HI, 0xc)
61 REG32(CNTSCR, 0x10) /* Aliased with CNTSCR0 */
62 REG32(CNTID, 0x1c)
63     FIELD(CNTID, CNTSC, 0, 4)
64     FIELD(CNTID, CNTCS, 16, 1)
65     FIELD(CNTID, CNTSELCLK, 17, 2)
66     FIELD(CNTID, CNTSCR_OVR, 19, 1)
67 REG32(CNTSCR0, 0xd0)
68 REG32(CNTSCR1, 0xd4)
69 
70 /* Registers in the status frame */
71 REG32(STATUS_CNTCV_LO, 0x0)
72 REG32(STATUS_CNTCV_HI, 0x4)
73 
74 /* Standard ID registers, present in both frames */
75 REG32(PID4, 0xFD0)
76 REG32(PID5, 0xFD4)
77 REG32(PID6, 0xFD8)
78 REG32(PID7, 0xFDC)
79 REG32(PID0, 0xFE0)
80 REG32(PID1, 0xFE4)
81 REG32(PID2, 0xFE8)
82 REG32(PID3, 0xFEC)
83 REG32(CID0, 0xFF0)
84 REG32(CID1, 0xFF4)
85 REG32(CID2, 0xFF8)
86 REG32(CID3, 0xFFC)
87 
88 /* PID/CID values */
89 static const int control_id[] = {
90     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
91     0xba, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
92     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
93 };
94 
95 static const int status_id[] = {
96     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
97     0xbb, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
98     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
99 };
100 
101 static void sse_counter_notify_users(SSECounter *s)
102 {
103     /*
104      * Notify users of the count timestamp that they may
105      * need to recalculate.
106      */
107     notifier_list_notify(&s->notifier_list, NULL);
108 }
109 
110 static bool sse_counter_enabled(SSECounter *s)
111 {
112     return (s->cntcr & R_CNTCR_EN_MASK) != 0;
113 }
114 
115 uint64_t sse_counter_tick_to_time(SSECounter *s, uint64_t tick)
116 {
117     if (!sse_counter_enabled(s)) {
118         return UINT64_MAX;
119     }
120 
121     tick -= s->ticks_then;
122 
123     if (s->cntcr & R_CNTCR_SCEN_MASK) {
124         /* Adjust the tick count to account for the scale factor */
125         tick = muldiv64(tick, 0x01000000, s->cntscr0);
126     }
127 
128     return s->ns_then + clock_ticks_to_ns(s->clk, tick);
129 }
130 
131 void sse_counter_register_consumer(SSECounter *s, Notifier *notifier)
132 {
133     /*
134      * For the moment we assume that both we and the devices
135      * which consume us last for the life of the simulation,
136      * and so there is no mechanism for removing a notifier.
137      */
138     notifier_list_add(&s->notifier_list, notifier);
139 }
140 
141 uint64_t sse_counter_for_timestamp(SSECounter *s, uint64_t now)
142 {
143     /* Return the CNTCV value for a particular timestamp (clock ns value). */
144     uint64_t ticks;
145 
146     if (!sse_counter_enabled(s)) {
147         /* Counter is disabled and does not increment */
148         return s->ticks_then;
149     }
150 
151     ticks = clock_ns_to_ticks(s->clk, now - s->ns_then);
152     if (s->cntcr & R_CNTCR_SCEN_MASK) {
153         /*
154          * Scaling is enabled. The CNTSCR value is the amount added to
155          * the underlying 88-bit counter for every tick of the
156          * underlying clock; CNTCV is the top 64 bits of that full
157          * 88-bit value. Multiplying the tick count by CNTSCR tells us
158          * how much the full 88-bit counter has moved on; we then
159          * divide that by 0x01000000 to find out how much the 64-bit
160          * visible portion has advanced. muldiv64() gives us the
161          * necessary at-least-88-bit precision for the intermediate
162          * result.
163          */
164         ticks = muldiv64(ticks, s->cntscr0, 0x01000000);
165     }
166     return s->ticks_then + ticks;
167 }
168 
169 static uint64_t sse_cntcv(SSECounter *s)
170 {
171     /* Return the CNTCV value for the current time */
172     return sse_counter_for_timestamp(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
173 }
174 
175 static void sse_write_cntcv(SSECounter *s, uint32_t value, unsigned startbit)
176 {
177     /*
178      * Write one 32-bit half of the counter value; startbit is the
179      * bit position of this half in the 64-bit word, either 0 or 32.
180      */
181     uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
182     uint64_t cntcv = sse_counter_for_timestamp(s, now);
183 
184     cntcv = deposit64(cntcv, startbit, 32, value);
185     s->ticks_then = cntcv;
186     s->ns_then = now;
187     sse_counter_notify_users(s);
188 }
189 
190 static uint64_t sse_counter_control_read(void *opaque, hwaddr offset,
191                                          unsigned size)
192 {
193     SSECounter *s = SSE_COUNTER(opaque);
194     uint64_t r;
195 
196     switch (offset) {
197     case A_CNTCR:
198         r = s->cntcr;
199         break;
200     case A_CNTSR:
201         /*
202          * The only bit here is DBGH, indicating that the counter has been
203          * halted via the Halt-on-Debug signal. We don't implement halting
204          * debug, so the whole register always reads as zero.
205          */
206         r = 0;
207         break;
208     case A_CNTCV_LO:
209         r = extract64(sse_cntcv(s), 0, 32);
210         break;
211     case A_CNTCV_HI:
212         r = extract64(sse_cntcv(s), 32, 32);
213         break;
214     case A_CNTID:
215         /*
216          * For our implementation:
217          *  - CNTSCR can only be written when CNTCR.EN == 0
218          *  - HWCLKSW=0, so selected clock is always CLK0
219          *  - counter scaling is implemented
220          */
221         r = (1 << R_CNTID_CNTSELCLK_SHIFT) | (1 << R_CNTID_CNTSC_SHIFT);
222         break;
223     case A_CNTSCR:
224     case A_CNTSCR0:
225         r = s->cntscr0;
226         break;
227     case A_CNTSCR1:
228         /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
229         r = 0;
230         break;
231     case A_PID4 ... A_CID3:
232         r = control_id[(offset - A_PID4) / 4];
233         break;
234     default:
235         qemu_log_mask(LOG_GUEST_ERROR,
236                       "SSE System Counter control frame read: bad offset 0x%x",
237                       (unsigned)offset);
238         r = 0;
239         break;
240     }
241 
242     trace_sse_counter_control_read(offset, r, size);
243     return r;
244 }
245 
246 static void sse_counter_control_write(void *opaque, hwaddr offset,
247                                       uint64_t value, unsigned size)
248 {
249     SSECounter *s = SSE_COUNTER(opaque);
250 
251     trace_sse_counter_control_write(offset, value, size);
252 
253     switch (offset) {
254     case A_CNTCR:
255         /*
256          * Although CNTCR defines interrupt-related bits, the counter doesn't
257          * appear to actually have an interrupt output. So INTRCLR is
258          * effectively a RAZ/WI bit, as are the reserved bits [31:6].
259          * The documentation does not explicitly say so, but we assume
260          * that changing the scale factor while the counter is enabled
261          * by toggling CNTCR.SCEN has the same behaviour (making the counter
262          * value UNKNOWN) as changing it by writing to CNTSCR, and so we
263          * don't need to try to recalculate for that case.
264          */
265         value &= CNTCR_VALID_MASK;
266         if ((value ^ s->cntcr) & R_CNTCR_EN_MASK) {
267             /*
268              * Whether the counter is being enabled or disabled, the
269              * required action is the same: sync the (ns_then, ticks_then)
270              * tuple.
271              */
272             uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
273             s->ticks_then = sse_counter_for_timestamp(s, now);
274             s->ns_then = now;
275             sse_counter_notify_users(s);
276         }
277         s->cntcr = value;
278         break;
279     case A_CNTCV_LO:
280         sse_write_cntcv(s, value, 0);
281         break;
282     case A_CNTCV_HI:
283         sse_write_cntcv(s, value, 32);
284         break;
285     case A_CNTSCR:
286     case A_CNTSCR0:
287         /*
288          * If the scale registers are changed when the counter is enabled,
289          * the count value becomes UNKNOWN. So we don't try to recalculate
290          * anything here but only do it on a write to CNTCR.EN.
291          */
292         s->cntscr0 = value;
293         break;
294     case A_CNTSCR1:
295         /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
296         break;
297     case A_CNTSR:
298     case A_CNTID:
299     case A_PID4 ... A_CID3:
300         qemu_log_mask(LOG_GUEST_ERROR,
301                       "SSE System Counter control frame: write to RO offset 0x%x\n",
302                       (unsigned)offset);
303         break;
304     default:
305         qemu_log_mask(LOG_GUEST_ERROR,
306                       "SSE System Counter control frame: write to bad offset 0x%x\n",
307                       (unsigned)offset);
308         break;
309     }
310 }
311 
312 static uint64_t sse_counter_status_read(void *opaque, hwaddr offset,
313                                         unsigned size)
314 {
315     SSECounter *s = SSE_COUNTER(opaque);
316     uint64_t r;
317 
318     switch (offset) {
319     case A_STATUS_CNTCV_LO:
320         r = extract64(sse_cntcv(s), 0, 32);
321         break;
322     case A_STATUS_CNTCV_HI:
323         r = extract64(sse_cntcv(s), 32, 32);
324         break;
325     case A_PID4 ... A_CID3:
326         r = status_id[(offset - A_PID4) / 4];
327         break;
328     default:
329         qemu_log_mask(LOG_GUEST_ERROR,
330                       "SSE System Counter status frame read: bad offset 0x%x",
331                       (unsigned)offset);
332         r = 0;
333         break;
334     }
335 
336     trace_sse_counter_status_read(offset, r, size);
337     return r;
338 }
339 
340 static void sse_counter_status_write(void *opaque, hwaddr offset,
341                                      uint64_t value, unsigned size)
342 {
343     trace_sse_counter_status_write(offset, value, size);
344 
345     switch (offset) {
346     case A_STATUS_CNTCV_LO:
347     case A_STATUS_CNTCV_HI:
348     case A_PID4 ... A_CID3:
349         qemu_log_mask(LOG_GUEST_ERROR,
350                       "SSE System Counter status frame: write to RO offset 0x%x\n",
351                       (unsigned)offset);
352         break;
353     default:
354         qemu_log_mask(LOG_GUEST_ERROR,
355                       "SSE System Counter status frame: write to bad offset 0x%x\n",
356                       (unsigned)offset);
357         break;
358     }
359 }
360 
361 static const MemoryRegionOps sse_counter_control_ops = {
362     .read = sse_counter_control_read,
363     .write = sse_counter_control_write,
364     .endianness = DEVICE_LITTLE_ENDIAN,
365     .valid.min_access_size = 4,
366     .valid.max_access_size = 4,
367 };
368 
369 static const MemoryRegionOps sse_counter_status_ops = {
370     .read = sse_counter_status_read,
371     .write = sse_counter_status_write,
372     .endianness = DEVICE_LITTLE_ENDIAN,
373     .valid.min_access_size = 4,
374     .valid.max_access_size = 4,
375 };
376 
377 static void sse_counter_reset(DeviceState *dev)
378 {
379     SSECounter *s = SSE_COUNTER(dev);
380 
381     trace_sse_counter_reset();
382 
383     s->cntcr = 0;
384     s->cntscr0 = 0x01000000;
385     s->ns_then = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
386     s->ticks_then = 0;
387 }
388 
389 static void sse_clk_callback(void *opaque, ClockEvent event)
390 {
391     SSECounter *s = SSE_COUNTER(opaque);
392     uint64_t now;
393 
394     switch (event) {
395     case ClockPreUpdate:
396         /*
397          * Before the clock period updates, set (ticks_then, ns_then)
398          * to the current time and tick count (as calculated with
399          * the old clock period).
400          */
401         if (sse_counter_enabled(s)) {
402             now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
403             s->ticks_then = sse_counter_for_timestamp(s, now);
404             s->ns_then = now;
405         }
406         break;
407     case ClockUpdate:
408         sse_counter_notify_users(s);
409         break;
410     default:
411         break;
412     }
413 }
414 
415 static void sse_counter_init(Object *obj)
416 {
417     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
418     SSECounter *s = SSE_COUNTER(obj);
419 
420     notifier_list_init(&s->notifier_list);
421 
422     s->clk = qdev_init_clock_in(DEVICE(obj), "CLK", sse_clk_callback, s,
423                                 ClockPreUpdate | ClockUpdate);
424     memory_region_init_io(&s->control_mr, obj, &sse_counter_control_ops,
425                           s, "sse-counter-control", 0x1000);
426     memory_region_init_io(&s->status_mr, obj, &sse_counter_status_ops,
427                           s, "sse-counter-status", 0x1000);
428     sysbus_init_mmio(sbd, &s->control_mr);
429     sysbus_init_mmio(sbd, &s->status_mr);
430 }
431 
432 static void sse_counter_realize(DeviceState *dev, Error **errp)
433 {
434     SSECounter *s = SSE_COUNTER(dev);
435 
436     if (!clock_has_source(s->clk)) {
437         error_setg(errp, "SSE system counter: CLK must be connected");
438         return;
439     }
440 }
441 
442 static const VMStateDescription sse_counter_vmstate = {
443     .name = "sse-counter",
444     .version_id = 1,
445     .minimum_version_id = 1,
446     .fields = (VMStateField[]) {
447         VMSTATE_CLOCK(clk, SSECounter),
448         VMSTATE_END_OF_LIST()
449     }
450 };
451 
452 static void sse_counter_class_init(ObjectClass *klass, void *data)
453 {
454     DeviceClass *dc = DEVICE_CLASS(klass);
455 
456     dc->realize = sse_counter_realize;
457     dc->vmsd = &sse_counter_vmstate;
458     dc->reset = sse_counter_reset;
459 }
460 
461 static const TypeInfo sse_counter_info = {
462     .name = TYPE_SSE_COUNTER,
463     .parent = TYPE_SYS_BUS_DEVICE,
464     .instance_size = sizeof(SSECounter),
465     .instance_init = sse_counter_init,
466     .class_init = sse_counter_class_init,
467 };
468 
469 static void sse_counter_register_types(void)
470 {
471     type_register_static(&sse_counter_info);
472 }
473 
474 type_init(sse_counter_register_types);
475