2
0

nrf51_timer.c 11 KB

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