2
0

nrf51_timer.c 11 KB

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