migration: Fix analyze-migration.py when ignore-shared is used
[qemu/kevin.git] / hw / timer / nrf51_timer.c
blob50c6772383eec6d582aca5b4f5913917d4c91ac9
1 /*
2 * nRF51 System-on-Chip Timer peripheral
4 * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
5 * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
7 * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
8 * Copyright (c) 2019 Red Hat, Inc.
10 * This code is licensed under the GPL version 2 or later. See
11 * the COPYING file in the top-level directory.
14 #include "qemu/osdep.h"
15 #include "qemu/log.h"
16 #include "qemu/module.h"
17 #include "hw/arm/nrf51.h"
18 #include "hw/irq.h"
19 #include "hw/timer/nrf51_timer.h"
20 #include "hw/qdev-properties.h"
21 #include "migration/vmstate.h"
22 #include "trace.h"
24 #define TIMER_CLK_FREQ 16000000UL
26 static uint32_t const bitwidths[] = {16, 8, 24, 32};
28 static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns)
30 uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
32 return muldiv64(ns, freq, NANOSECONDS_PER_SECOND);
35 static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks)
37 uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
39 return muldiv64(ticks, NANOSECONDS_PER_SECOND, freq);
42 /* Returns number of ticks since last call */
43 static uint32_t update_counter(NRF51TimerState *s, int64_t now)
45 uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
47 s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
49 * Only advance the sync time to the timestamp of the last tick,
50 * not all the way to 'now', so we don't lose time if we do
51 * multiple resyncs in a single tick.
53 s->update_counter_ns += ticks_to_ns(s, ticks);
54 return ticks;
57 /* Assumes s->counter is up-to-date */
58 static void rearm_timer(NRF51TimerState *s, int64_t now)
60 int64_t min_ns = INT64_MAX;
61 size_t i;
63 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
64 int64_t delta_ns;
66 if (s->events_compare[i]) {
67 continue; /* already expired, ignore it for now */
70 if (s->cc[i] <= s->counter) {
71 delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) -
72 s->counter + s->cc[i]);
73 } else {
74 delta_ns = ticks_to_ns(s, s->cc[i] - s->counter);
77 if (delta_ns < min_ns) {
78 min_ns = delta_ns;
82 if (min_ns != INT64_MAX) {
83 timer_mod_ns(&s->timer, now + min_ns);
87 static void update_irq(NRF51TimerState *s)
89 bool flag = false;
90 size_t i;
92 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
93 flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1);
95 qemu_set_irq(s->irq, flag);
98 static void timer_expire(void *opaque)
100 NRF51TimerState *s = NRF51_TIMER(opaque);
101 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
102 uint32_t cc_remaining[NRF51_TIMER_REG_COUNT];
103 bool should_stop = false;
104 uint32_t ticks;
105 size_t i;
107 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
108 if (s->cc[i] > s->counter) {
109 cc_remaining[i] = s->cc[i] - s->counter;
110 } else {
111 cc_remaining[i] = BIT(bitwidths[s->bitmode]) -
112 s->counter + s->cc[i];
116 ticks = update_counter(s, now);
118 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
119 if (cc_remaining[i] <= ticks) {
120 s->events_compare[i] = 1;
122 if (s->shorts & BIT(i)) {
123 s->timer_start_ns = now;
124 s->update_counter_ns = s->timer_start_ns;
125 s->counter = 0;
128 should_stop |= s->shorts & BIT(i + 8);
132 update_irq(s);
134 if (should_stop) {
135 s->running = false;
136 timer_del(&s->timer);
137 } else {
138 rearm_timer(s, now);
142 static void counter_compare(NRF51TimerState *s)
144 uint32_t counter = s->counter;
145 size_t i;
147 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
148 if (counter == s->cc[i]) {
149 s->events_compare[i] = 1;
151 if (s->shorts & BIT(i)) {
152 s->counter = 0;
158 static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size)
160 NRF51TimerState *s = NRF51_TIMER(opaque);
161 uint64_t r = 0;
163 switch (offset) {
164 case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
165 r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4];
166 break;
167 case NRF51_TIMER_REG_SHORTS:
168 r = s->shorts;
169 break;
170 case NRF51_TIMER_REG_INTENSET:
171 r = s->inten;
172 break;
173 case NRF51_TIMER_REG_INTENCLR:
174 r = s->inten;
175 break;
176 case NRF51_TIMER_REG_MODE:
177 r = s->mode;
178 break;
179 case NRF51_TIMER_REG_BITMODE:
180 r = s->bitmode;
181 break;
182 case NRF51_TIMER_REG_PRESCALER:
183 r = s->prescaler;
184 break;
185 case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
186 r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4];
187 break;
188 default:
189 qemu_log_mask(LOG_GUEST_ERROR,
190 "%s: bad read offset 0x%" HWADDR_PRIx "\n",
191 __func__, offset);
194 trace_nrf51_timer_read(s->id, offset, r, size);
196 return r;
199 static void nrf51_timer_write(void *opaque, hwaddr offset,
200 uint64_t value, unsigned int size)
202 NRF51TimerState *s = NRF51_TIMER(opaque);
203 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
204 size_t idx;
206 trace_nrf51_timer_write(s->id, offset, value, size);
208 switch (offset) {
209 case NRF51_TIMER_TASK_START:
210 if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) {
211 s->running = true;
212 s->timer_start_ns = now - ticks_to_ns(s, s->counter);
213 s->update_counter_ns = s->timer_start_ns;
214 rearm_timer(s, now);
216 break;
217 case NRF51_TIMER_TASK_STOP:
218 case NRF51_TIMER_TASK_SHUTDOWN:
219 if (value == NRF51_TRIGGER_TASK) {
220 s->running = false;
221 timer_del(&s->timer);
223 break;
224 case NRF51_TIMER_TASK_COUNT:
225 if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) {
226 s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]);
227 counter_compare(s);
229 break;
230 case NRF51_TIMER_TASK_CLEAR:
231 if (value == NRF51_TRIGGER_TASK) {
232 s->timer_start_ns = now;
233 s->update_counter_ns = s->timer_start_ns;
234 s->counter = 0;
235 if (s->running) {
236 rearm_timer(s, now);
239 break;
240 case NRF51_TIMER_TASK_CAPTURE_0 ... NRF51_TIMER_TASK_CAPTURE_3:
241 if (value == NRF51_TRIGGER_TASK) {
242 if (s->running) {
243 timer_expire(s); /* update counter and all state */
246 idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4;
247 s->cc[idx] = s->counter;
248 trace_nrf51_timer_set_count(s->id, idx, s->counter);
250 break;
251 case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
252 if (value == NRF51_EVENT_CLEAR) {
253 s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0;
255 if (s->running) {
256 timer_expire(s); /* update counter and all state */
259 break;
260 case NRF51_TIMER_REG_SHORTS:
261 s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK;
262 break;
263 case NRF51_TIMER_REG_INTENSET:
264 s->inten |= value & NRF51_TIMER_REG_INTEN_MASK;
265 break;
266 case NRF51_TIMER_REG_INTENCLR:
267 s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK);
268 break;
269 case NRF51_TIMER_REG_MODE:
270 s->mode = value;
271 break;
272 case NRF51_TIMER_REG_BITMODE:
273 if (s->mode == NRF51_TIMER_TIMER && s->running) {
274 qemu_log_mask(LOG_GUEST_ERROR,
275 "%s: erroneous change of BITMODE while timer is running\n",
276 __func__);
278 s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK;
279 break;
280 case NRF51_TIMER_REG_PRESCALER:
281 if (s->mode == NRF51_TIMER_TIMER && s->running) {
282 qemu_log_mask(LOG_GUEST_ERROR,
283 "%s: erroneous change of PRESCALER while timer is running\n",
284 __func__);
286 s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK;
287 break;
288 case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
289 if (s->running) {
290 timer_expire(s); /* update counter */
293 idx = (offset - NRF51_TIMER_REG_CC0) / 4;
294 s->cc[idx] = value % BIT(bitwidths[s->bitmode]);
296 if (s->running) {
297 rearm_timer(s, now);
299 break;
300 default:
301 qemu_log_mask(LOG_GUEST_ERROR,
302 "%s: bad write offset 0x%" HWADDR_PRIx "\n",
303 __func__, offset);
306 update_irq(s);
309 static const MemoryRegionOps rng_ops = {
310 .read = nrf51_timer_read,
311 .write = nrf51_timer_write,
312 .endianness = DEVICE_LITTLE_ENDIAN,
313 .impl.min_access_size = 4,
314 .impl.max_access_size = 4,
317 static void nrf51_timer_init(Object *obj)
319 NRF51TimerState *s = NRF51_TIMER(obj);
320 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
322 memory_region_init_io(&s->iomem, obj, &rng_ops, s,
323 TYPE_NRF51_TIMER, NRF51_PERIPHERAL_SIZE);
324 sysbus_init_mmio(sbd, &s->iomem);
325 sysbus_init_irq(sbd, &s->irq);
327 timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s);
330 static void nrf51_timer_reset(DeviceState *dev)
332 NRF51TimerState *s = NRF51_TIMER(dev);
334 timer_del(&s->timer);
335 s->timer_start_ns = 0x00;
336 s->update_counter_ns = 0x00;
337 s->counter = 0x00;
338 s->running = false;
340 memset(s->events_compare, 0x00, sizeof(s->events_compare));
341 memset(s->cc, 0x00, sizeof(s->cc));
343 s->shorts = 0x00;
344 s->inten = 0x00;
345 s->mode = 0x00;
346 s->bitmode = 0x00;
347 s->prescaler = 0x00;
350 static int nrf51_timer_post_load(void *opaque, int version_id)
352 NRF51TimerState *s = NRF51_TIMER(opaque);
354 if (s->running && s->mode == NRF51_TIMER_TIMER) {
355 timer_expire(s);
357 return 0;
360 static const VMStateDescription vmstate_nrf51_timer = {
361 .name = TYPE_NRF51_TIMER,
362 .version_id = 1,
363 .post_load = nrf51_timer_post_load,
364 .fields = (VMStateField[]) {
365 VMSTATE_TIMER(timer, NRF51TimerState),
366 VMSTATE_INT64(timer_start_ns, NRF51TimerState),
367 VMSTATE_INT64(update_counter_ns, NRF51TimerState),
368 VMSTATE_UINT32(counter, NRF51TimerState),
369 VMSTATE_BOOL(running, NRF51TimerState),
370 VMSTATE_UINT8_ARRAY(events_compare, NRF51TimerState,
371 NRF51_TIMER_REG_COUNT),
372 VMSTATE_UINT32_ARRAY(cc, NRF51TimerState, NRF51_TIMER_REG_COUNT),
373 VMSTATE_UINT32(shorts, NRF51TimerState),
374 VMSTATE_UINT32(inten, NRF51TimerState),
375 VMSTATE_UINT32(mode, NRF51TimerState),
376 VMSTATE_UINT32(bitmode, NRF51TimerState),
377 VMSTATE_UINT32(prescaler, NRF51TimerState),
378 VMSTATE_END_OF_LIST()
382 static Property nrf51_timer_properties[] = {
383 DEFINE_PROP_UINT8("id", NRF51TimerState, id, 0),
384 DEFINE_PROP_END_OF_LIST(),
387 static void nrf51_timer_class_init(ObjectClass *klass, void *data)
389 DeviceClass *dc = DEVICE_CLASS(klass);
391 dc->reset = nrf51_timer_reset;
392 dc->vmsd = &vmstate_nrf51_timer;
393 device_class_set_props(dc, nrf51_timer_properties);
396 static const TypeInfo nrf51_timer_info = {
397 .name = TYPE_NRF51_TIMER,
398 .parent = TYPE_SYS_BUS_DEVICE,
399 .instance_size = sizeof(NRF51TimerState),
400 .instance_init = nrf51_timer_init,
401 .class_init = nrf51_timer_class_init
404 static void nrf51_timer_register_types(void)
406 type_register_static(&nrf51_timer_info);
409 type_init(nrf51_timer_register_types)