1 /* 2 * nRF51 System-on-Chip Timer peripheral 3 * 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 6 * 7 * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de> 8 * Copyright (c) 2019 Red Hat, Inc. 9 * 10 * This code is licensed under the GPL version 2 or later. See 11 * the COPYING file in the top-level directory. 12 */ 13 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 "migration/vmstate.h" 21 #include "trace.h" 22 23 #define TIMER_CLK_FREQ 16000000UL 24 25 static uint32_t const bitwidths[] = {16, 8, 24, 32}; 26 27 static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns) 28 { 29 uint32_t freq = TIMER_CLK_FREQ >> s->prescaler; 30 31 return muldiv64(ns, freq, NANOSECONDS_PER_SECOND); 32 } 33 34 static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks) 35 { 36 uint32_t freq = TIMER_CLK_FREQ >> s->prescaler; 37 38 return muldiv64(ticks, NANOSECONDS_PER_SECOND, freq); 39 } 40 41 /* Returns number of ticks since last call */ 42 static uint32_t update_counter(NRF51TimerState *s, int64_t now) 43 { 44 uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns); 45 46 s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]); 47 s->update_counter_ns = now; 48 return ticks; 49 } 50 51 /* Assumes s->counter is up-to-date */ 52 static void rearm_timer(NRF51TimerState *s, int64_t now) 53 { 54 int64_t min_ns = INT64_MAX; 55 size_t i; 56 57 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) { 58 int64_t delta_ns; 59 60 if (s->events_compare[i]) { 61 continue; /* already expired, ignore it for now */ 62 } 63 64 if (s->cc[i] <= s->counter) { 65 delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) - 66 s->counter + s->cc[i]); 67 } else { 68 delta_ns = ticks_to_ns(s, s->cc[i] - s->counter); 69 } 70 71 if (delta_ns < min_ns) { 72 min_ns = delta_ns; 73 } 74 } 75 76 if (min_ns != INT64_MAX) { 77 timer_mod_ns(&s->timer, now + min_ns); 78 } 79 } 80 81 static void update_irq(NRF51TimerState *s) 82 { 83 bool flag = false; 84 size_t i; 85 86 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) { 87 flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1); 88 } 89 qemu_set_irq(s->irq, flag); 90 } 91 92 static void timer_expire(void *opaque) 93 { 94 NRF51TimerState *s = NRF51_TIMER(opaque); 95 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 96 uint32_t cc_remaining[NRF51_TIMER_REG_COUNT]; 97 bool should_stop = false; 98 uint32_t ticks; 99 size_t i; 100 101 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) { 102 if (s->cc[i] > s->counter) { 103 cc_remaining[i] = s->cc[i] - s->counter; 104 } else { 105 cc_remaining[i] = BIT(bitwidths[s->bitmode]) - 106 s->counter + s->cc[i]; 107 } 108 } 109 110 ticks = update_counter(s, now); 111 112 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) { 113 if (cc_remaining[i] <= ticks) { 114 s->events_compare[i] = 1; 115 116 if (s->shorts & BIT(i)) { 117 s->timer_start_ns = now; 118 s->update_counter_ns = s->timer_start_ns; 119 s->counter = 0; 120 } 121 122 should_stop |= s->shorts & BIT(i + 8); 123 } 124 } 125 126 update_irq(s); 127 128 if (should_stop) { 129 s->running = false; 130 timer_del(&s->timer); 131 } else { 132 rearm_timer(s, now); 133 } 134 } 135 136 static void counter_compare(NRF51TimerState *s) 137 { 138 uint32_t counter = s->counter; 139 size_t i; 140 141 for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) { 142 if (counter == s->cc[i]) { 143 s->events_compare[i] = 1; 144 145 if (s->shorts & BIT(i)) { 146 s->counter = 0; 147 } 148 } 149 } 150 } 151 152 static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size) 153 { 154 NRF51TimerState *s = NRF51_TIMER(opaque); 155 uint64_t r = 0; 156 157 switch (offset) { 158 case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3: 159 r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4]; 160 break; 161 case NRF51_TIMER_REG_SHORTS: 162 r = s->shorts; 163 break; 164 case NRF51_TIMER_REG_INTENSET: 165 r = s->inten; 166 break; 167 case NRF51_TIMER_REG_INTENCLR: 168 r = s->inten; 169 break; 170 case NRF51_TIMER_REG_MODE: 171 r = s->mode; 172 break; 173 case NRF51_TIMER_REG_BITMODE: 174 r = s->bitmode; 175 break; 176 case NRF51_TIMER_REG_PRESCALER: 177 r = s->prescaler; 178 break; 179 case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3: 180 r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4]; 181 break; 182 default: 183 qemu_log_mask(LOG_GUEST_ERROR, 184 "%s: bad read offset 0x%" HWADDR_PRIx "\n", 185 __func__, offset); 186 } 187 188 trace_nrf51_timer_read(offset, r, size); 189 190 return r; 191 } 192 193 static void nrf51_timer_write(void *opaque, hwaddr offset, 194 uint64_t value, unsigned int size) 195 { 196 NRF51TimerState *s = NRF51_TIMER(opaque); 197 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 198 size_t idx; 199 200 trace_nrf51_timer_write(offset, value, size); 201 202 switch (offset) { 203 case NRF51_TIMER_TASK_START: 204 if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) { 205 s->running = true; 206 s->timer_start_ns = now - ticks_to_ns(s, s->counter); 207 s->update_counter_ns = s->timer_start_ns; 208 rearm_timer(s, now); 209 } 210 break; 211 case NRF51_TIMER_TASK_STOP: 212 case NRF51_TIMER_TASK_SHUTDOWN: 213 if (value == NRF51_TRIGGER_TASK) { 214 s->running = false; 215 timer_del(&s->timer); 216 } 217 break; 218 case NRF51_TIMER_TASK_COUNT: 219 if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) { 220 s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]); 221 counter_compare(s); 222 } 223 break; 224 case NRF51_TIMER_TASK_CLEAR: 225 if (value == NRF51_TRIGGER_TASK) { 226 s->timer_start_ns = now; 227 s->update_counter_ns = s->timer_start_ns; 228 s->counter = 0; 229 if (s->running) { 230 rearm_timer(s, now); 231 } 232 } 233 break; 234 case NRF51_TIMER_TASK_CAPTURE_0 ... NRF51_TIMER_TASK_CAPTURE_3: 235 if (value == NRF51_TRIGGER_TASK) { 236 if (s->running) { 237 timer_expire(s); /* update counter and all state */ 238 } 239 240 idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4; 241 s->cc[idx] = s->counter; 242 } 243 break; 244 case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3: 245 if (value == NRF51_EVENT_CLEAR) { 246 s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0; 247 248 if (s->running) { 249 timer_expire(s); /* update counter and all state */ 250 } 251 } 252 break; 253 case NRF51_TIMER_REG_SHORTS: 254 s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK; 255 break; 256 case NRF51_TIMER_REG_INTENSET: 257 s->inten |= value & NRF51_TIMER_REG_INTEN_MASK; 258 break; 259 case NRF51_TIMER_REG_INTENCLR: 260 s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK); 261 break; 262 case NRF51_TIMER_REG_MODE: 263 s->mode = value; 264 break; 265 case NRF51_TIMER_REG_BITMODE: 266 if (s->mode == NRF51_TIMER_TIMER && s->running) { 267 qemu_log_mask(LOG_GUEST_ERROR, 268 "%s: erroneous change of BITMODE while timer is running\n", 269 __func__); 270 } 271 s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK; 272 break; 273 case NRF51_TIMER_REG_PRESCALER: 274 if (s->mode == NRF51_TIMER_TIMER && s->running) { 275 qemu_log_mask(LOG_GUEST_ERROR, 276 "%s: erroneous change of PRESCALER while timer is running\n", 277 __func__); 278 } 279 s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK; 280 break; 281 case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3: 282 if (s->running) { 283 timer_expire(s); /* update counter */ 284 } 285 286 idx = (offset - NRF51_TIMER_REG_CC0) / 4; 287 s->cc[idx] = value % BIT(bitwidths[s->bitmode]); 288 289 if (s->running) { 290 rearm_timer(s, now); 291 } 292 break; 293 default: 294 qemu_log_mask(LOG_GUEST_ERROR, 295 "%s: bad write offset 0x%" HWADDR_PRIx "\n", 296 __func__, offset); 297 } 298 299 update_irq(s); 300 } 301 302 static const MemoryRegionOps rng_ops = { 303 .read = nrf51_timer_read, 304 .write = nrf51_timer_write, 305 .endianness = DEVICE_LITTLE_ENDIAN, 306 .impl.min_access_size = 4, 307 .impl.max_access_size = 4, 308 }; 309 310 static void nrf51_timer_init(Object *obj) 311 { 312 NRF51TimerState *s = NRF51_TIMER(obj); 313 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 314 315 memory_region_init_io(&s->iomem, obj, &rng_ops, s, 316 TYPE_NRF51_TIMER, NRF51_TIMER_SIZE); 317 sysbus_init_mmio(sbd, &s->iomem); 318 sysbus_init_irq(sbd, &s->irq); 319 320 timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s); 321 } 322 323 static void nrf51_timer_reset(DeviceState *dev) 324 { 325 NRF51TimerState *s = NRF51_TIMER(dev); 326 327 timer_del(&s->timer); 328 s->timer_start_ns = 0x00; 329 s->update_counter_ns = 0x00; 330 s->counter = 0x00; 331 s->running = false; 332 333 memset(s->events_compare, 0x00, sizeof(s->events_compare)); 334 memset(s->cc, 0x00, sizeof(s->cc)); 335 336 s->shorts = 0x00; 337 s->inten = 0x00; 338 s->mode = 0x00; 339 s->bitmode = 0x00; 340 s->prescaler = 0x00; 341 } 342 343 static int nrf51_timer_post_load(void *opaque, int version_id) 344 { 345 NRF51TimerState *s = NRF51_TIMER(opaque); 346 347 if (s->running && s->mode == NRF51_TIMER_TIMER) { 348 timer_expire(s); 349 } 350 return 0; 351 } 352 353 static const VMStateDescription vmstate_nrf51_timer = { 354 .name = TYPE_NRF51_TIMER, 355 .version_id = 1, 356 .post_load = nrf51_timer_post_load, 357 .fields = (VMStateField[]) { 358 VMSTATE_TIMER(timer, NRF51TimerState), 359 VMSTATE_INT64(timer_start_ns, NRF51TimerState), 360 VMSTATE_INT64(update_counter_ns, NRF51TimerState), 361 VMSTATE_UINT32(counter, NRF51TimerState), 362 VMSTATE_BOOL(running, NRF51TimerState), 363 VMSTATE_UINT8_ARRAY(events_compare, NRF51TimerState, 364 NRF51_TIMER_REG_COUNT), 365 VMSTATE_UINT32_ARRAY(cc, NRF51TimerState, NRF51_TIMER_REG_COUNT), 366 VMSTATE_UINT32(shorts, NRF51TimerState), 367 VMSTATE_UINT32(inten, NRF51TimerState), 368 VMSTATE_UINT32(mode, NRF51TimerState), 369 VMSTATE_UINT32(bitmode, NRF51TimerState), 370 VMSTATE_UINT32(prescaler, NRF51TimerState), 371 VMSTATE_END_OF_LIST() 372 } 373 }; 374 375 static void nrf51_timer_class_init(ObjectClass *klass, void *data) 376 { 377 DeviceClass *dc = DEVICE_CLASS(klass); 378 379 dc->reset = nrf51_timer_reset; 380 dc->vmsd = &vmstate_nrf51_timer; 381 } 382 383 static const TypeInfo nrf51_timer_info = { 384 .name = TYPE_NRF51_TIMER, 385 .parent = TYPE_SYS_BUS_DEVICE, 386 .instance_size = sizeof(NRF51TimerState), 387 .instance_init = nrf51_timer_init, 388 .class_init = nrf51_timer_class_init 389 }; 390 391 static void nrf51_timer_register_types(void) 392 { 393 type_register_static(&nrf51_timer_info); 394 } 395 396 type_init(nrf51_timer_register_types) 397