sse-counter.c 14 KB

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