test-arm-mptimer.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. /*
  2. * QTest testcase for the ARM MPTimer
  3. *
  4. * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
  5. *
  6. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  7. * See the COPYING file in the top-level directory.
  8. */
  9. #include "qemu/osdep.h"
  10. #include "qemu/timer.h"
  11. #include "libqtest-single.h"
  12. #define TIMER_BLOCK_SCALE(s) ((((s) & 0xff) + 1) * 10)
  13. #define TIMER_BLOCK_STEP(scaler, steps_nb) \
  14. clock_step(TIMER_BLOCK_SCALE(scaler) * (int64_t)(steps_nb) + 1)
  15. #define TIMER_BASE_PHYS 0x1e000600
  16. #define TIMER_LOAD 0x00
  17. #define TIMER_COUNTER 0x04
  18. #define TIMER_CONTROL 0x08
  19. #define TIMER_INTSTAT 0x0C
  20. #define TIMER_CONTROL_ENABLE (1 << 0)
  21. #define TIMER_CONTROL_PERIODIC (1 << 1)
  22. #define TIMER_CONTROL_IT_ENABLE (1 << 2)
  23. #define TIMER_CONTROL_PRESCALER(p) (((p) & 0xff) << 8)
  24. #define PERIODIC 1
  25. #define ONESHOT 0
  26. #define NOSCALE 0
  27. static int nonscaled = NOSCALE;
  28. static int scaled = 122;
  29. static void timer_load(uint32_t load)
  30. {
  31. writel(TIMER_BASE_PHYS + TIMER_LOAD, load);
  32. }
  33. static void timer_start(int periodic, uint32_t scale)
  34. {
  35. uint32_t ctl = TIMER_CONTROL_ENABLE | TIMER_CONTROL_PRESCALER(scale);
  36. if (periodic) {
  37. ctl |= TIMER_CONTROL_PERIODIC;
  38. }
  39. writel(TIMER_BASE_PHYS + TIMER_CONTROL, ctl);
  40. }
  41. static void timer_stop(void)
  42. {
  43. writel(TIMER_BASE_PHYS + TIMER_CONTROL, 0);
  44. }
  45. static void timer_int_clr(void)
  46. {
  47. writel(TIMER_BASE_PHYS + TIMER_INTSTAT, 1);
  48. }
  49. static void timer_reset(void)
  50. {
  51. timer_stop();
  52. timer_load(0);
  53. timer_int_clr();
  54. }
  55. static uint32_t timer_get_and_clr_int_sts(void)
  56. {
  57. uint32_t int_sts = readl(TIMER_BASE_PHYS + TIMER_INTSTAT);
  58. if (int_sts) {
  59. timer_int_clr();
  60. }
  61. return int_sts;
  62. }
  63. static uint32_t timer_counter(void)
  64. {
  65. return readl(TIMER_BASE_PHYS + TIMER_COUNTER);
  66. }
  67. static void timer_set_counter(uint32_t value)
  68. {
  69. writel(TIMER_BASE_PHYS + TIMER_COUNTER, value);
  70. }
  71. static void test_timer_oneshot(gconstpointer arg)
  72. {
  73. int scaler = *((int *) arg);
  74. timer_reset();
  75. timer_load(9999999);
  76. timer_start(ONESHOT, scaler);
  77. TIMER_BLOCK_STEP(scaler, 9999);
  78. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  79. g_assert_cmpuint(timer_counter(), ==, 9990000);
  80. TIMER_BLOCK_STEP(scaler, 9990000);
  81. g_assert_cmpuint(timer_counter(), ==, 0);
  82. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  83. TIMER_BLOCK_STEP(scaler, 9990000);
  84. g_assert_cmpuint(timer_counter(), ==, 0);
  85. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  86. }
  87. static void test_timer_pause(gconstpointer arg)
  88. {
  89. int scaler = *((int *) arg);
  90. timer_reset();
  91. timer_load(999999999);
  92. timer_start(ONESHOT, scaler);
  93. TIMER_BLOCK_STEP(scaler, 999);
  94. g_assert_cmpuint(timer_counter(), ==, 999999000);
  95. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  96. TIMER_BLOCK_STEP(scaler, 9000);
  97. g_assert_cmpuint(timer_counter(), ==, 999990000);
  98. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  99. timer_stop();
  100. g_assert_cmpuint(timer_counter(), ==, 999990000);
  101. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  102. TIMER_BLOCK_STEP(scaler, 90000);
  103. g_assert_cmpuint(timer_counter(), ==, 999990000);
  104. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  105. timer_start(ONESHOT, scaler);
  106. TIMER_BLOCK_STEP(scaler, 999990000);
  107. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  108. g_assert_cmpuint(timer_counter(), ==, 0);
  109. TIMER_BLOCK_STEP(scaler, 999990000);
  110. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  111. g_assert_cmpuint(timer_counter(), ==, 0);
  112. }
  113. static void test_timer_reload(gconstpointer arg)
  114. {
  115. int scaler = *((int *) arg);
  116. timer_reset();
  117. timer_load(UINT32_MAX);
  118. timer_start(ONESHOT, scaler);
  119. TIMER_BLOCK_STEP(scaler, 90000);
  120. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000);
  121. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  122. timer_load(UINT32_MAX);
  123. TIMER_BLOCK_STEP(scaler, 90000);
  124. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000);
  125. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  126. }
  127. static void test_timer_periodic(gconstpointer arg)
  128. {
  129. int scaler = *((int *) arg);
  130. int repeat = 10;
  131. timer_reset();
  132. timer_load(100);
  133. timer_start(PERIODIC, scaler);
  134. while (repeat--) {
  135. clock_step(TIMER_BLOCK_SCALE(scaler) * (101 + repeat) + 1);
  136. g_assert_cmpuint(timer_counter(), ==, 100 - repeat);
  137. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  138. clock_step(TIMER_BLOCK_SCALE(scaler) * (101 - repeat) - 1);
  139. }
  140. }
  141. static void test_timer_oneshot_to_periodic(gconstpointer arg)
  142. {
  143. int scaler = *((int *) arg);
  144. timer_reset();
  145. timer_load(10000);
  146. timer_start(ONESHOT, scaler);
  147. TIMER_BLOCK_STEP(scaler, 1000);
  148. g_assert_cmpuint(timer_counter(), ==, 9000);
  149. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  150. timer_start(PERIODIC, scaler);
  151. TIMER_BLOCK_STEP(scaler, 14001);
  152. g_assert_cmpuint(timer_counter(), ==, 5000);
  153. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  154. }
  155. static void test_timer_periodic_to_oneshot(gconstpointer arg)
  156. {
  157. int scaler = *((int *) arg);
  158. timer_reset();
  159. timer_load(99999999);
  160. timer_start(PERIODIC, scaler);
  161. TIMER_BLOCK_STEP(scaler, 999);
  162. g_assert_cmpuint(timer_counter(), ==, 99999000);
  163. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  164. timer_start(ONESHOT, scaler);
  165. TIMER_BLOCK_STEP(scaler, 99999009);
  166. g_assert_cmpuint(timer_counter(), ==, 0);
  167. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  168. }
  169. static void test_timer_prescaler(void)
  170. {
  171. timer_reset();
  172. timer_load(9999999);
  173. timer_start(ONESHOT, NOSCALE);
  174. TIMER_BLOCK_STEP(NOSCALE, 9999998);
  175. g_assert_cmpuint(timer_counter(), ==, 1);
  176. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  177. TIMER_BLOCK_STEP(NOSCALE, 1);
  178. g_assert_cmpuint(timer_counter(), ==, 0);
  179. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  180. timer_reset();
  181. timer_load(9999999);
  182. timer_start(ONESHOT, 0xAB);
  183. TIMER_BLOCK_STEP(0xAB, 9999998);
  184. g_assert_cmpuint(timer_counter(), ==, 1);
  185. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  186. TIMER_BLOCK_STEP(0xAB, 1);
  187. g_assert_cmpuint(timer_counter(), ==, 0);
  188. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  189. }
  190. static void test_timer_prescaler_on_the_fly(void)
  191. {
  192. timer_reset();
  193. timer_load(9999999);
  194. timer_start(ONESHOT, NOSCALE);
  195. TIMER_BLOCK_STEP(NOSCALE, 999);
  196. g_assert_cmpuint(timer_counter(), ==, 9999000);
  197. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  198. timer_start(ONESHOT, 0xAB);
  199. TIMER_BLOCK_STEP(0xAB, 9000);
  200. g_assert_cmpuint(timer_counter(), ==, 9990000);
  201. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  202. }
  203. static void test_timer_set_oneshot_counter_to_0(gconstpointer arg)
  204. {
  205. int scaler = *((int *) arg);
  206. timer_reset();
  207. timer_load(UINT32_MAX);
  208. timer_start(ONESHOT, scaler);
  209. TIMER_BLOCK_STEP(scaler, 1);
  210. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1);
  211. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  212. timer_set_counter(0);
  213. TIMER_BLOCK_STEP(scaler, 10);
  214. g_assert_cmpuint(timer_counter(), ==, 0);
  215. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  216. }
  217. static void test_timer_set_periodic_counter_to_0(gconstpointer arg)
  218. {
  219. int scaler = *((int *) arg);
  220. timer_reset();
  221. timer_load(UINT32_MAX);
  222. timer_start(PERIODIC, scaler);
  223. TIMER_BLOCK_STEP(scaler, 1);
  224. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1);
  225. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  226. timer_set_counter(0);
  227. TIMER_BLOCK_STEP(scaler, 1);
  228. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - (scaler ? 0 : 1));
  229. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  230. timer_reset();
  231. timer_set_counter(UINT32_MAX);
  232. timer_start(PERIODIC, scaler);
  233. TIMER_BLOCK_STEP(scaler, 1);
  234. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1);
  235. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  236. timer_set_counter(0);
  237. TIMER_BLOCK_STEP(scaler, 1);
  238. g_assert_cmpuint(timer_counter(), ==, 0);
  239. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  240. }
  241. static void test_timer_noload_oneshot(gconstpointer arg)
  242. {
  243. int scaler = *((int *) arg);
  244. timer_reset();
  245. timer_start(ONESHOT, scaler);
  246. TIMER_BLOCK_STEP(scaler, 1);
  247. g_assert_cmpuint(timer_counter(), ==, 0);
  248. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  249. TIMER_BLOCK_STEP(scaler, 1);
  250. g_assert_cmpuint(timer_counter(), ==, 0);
  251. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  252. }
  253. static void test_timer_noload_periodic(gconstpointer arg)
  254. {
  255. int scaler = *((int *) arg);
  256. timer_reset();
  257. timer_start(PERIODIC, scaler);
  258. TIMER_BLOCK_STEP(scaler, 1);
  259. g_assert_cmpuint(timer_counter(), ==, 0);
  260. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  261. TIMER_BLOCK_STEP(scaler, 1);
  262. g_assert_cmpuint(timer_counter(), ==, 0);
  263. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  264. }
  265. static void test_timer_zero_load_oneshot(gconstpointer arg)
  266. {
  267. int scaler = *((int *) arg);
  268. timer_reset();
  269. timer_start(ONESHOT, scaler);
  270. TIMER_BLOCK_STEP(scaler, 1);
  271. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  272. g_assert_cmpuint(timer_counter(), ==, 0);
  273. timer_load(0);
  274. TIMER_BLOCK_STEP(scaler, 1);
  275. g_assert_cmpuint(timer_counter(), ==, 0);
  276. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  277. TIMER_BLOCK_STEP(scaler, 1);
  278. g_assert_cmpuint(timer_counter(), ==, 0);
  279. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  280. }
  281. static void test_timer_zero_load_periodic(gconstpointer arg)
  282. {
  283. int scaler = *((int *) arg);
  284. timer_reset();
  285. timer_start(PERIODIC, scaler);
  286. TIMER_BLOCK_STEP(scaler, 1);
  287. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  288. g_assert_cmpuint(timer_counter(), ==, 0);
  289. timer_load(0);
  290. TIMER_BLOCK_STEP(scaler, 1);
  291. g_assert_cmpuint(timer_counter(), ==, 0);
  292. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  293. TIMER_BLOCK_STEP(scaler, 1);
  294. g_assert_cmpuint(timer_counter(), ==, 0);
  295. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  296. }
  297. static void test_timer_zero_load_oneshot_to_nonzero(gconstpointer arg)
  298. {
  299. int scaler = *((int *) arg);
  300. timer_reset();
  301. timer_start(ONESHOT, scaler);
  302. TIMER_BLOCK_STEP(scaler, 1);
  303. g_assert_cmpuint(timer_counter(), ==, 0);
  304. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  305. timer_load(0);
  306. TIMER_BLOCK_STEP(scaler, 1);
  307. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  308. g_assert_cmpuint(timer_counter(), ==, 0);
  309. timer_load(999);
  310. TIMER_BLOCK_STEP(scaler, 1001);
  311. g_assert_cmpuint(timer_counter(), ==, 0);
  312. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  313. }
  314. static void test_timer_zero_load_periodic_to_nonzero(gconstpointer arg)
  315. {
  316. int scaler = *((int *) arg);
  317. int i;
  318. timer_reset();
  319. timer_start(PERIODIC, scaler);
  320. TIMER_BLOCK_STEP(scaler, 1);
  321. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  322. g_assert_cmpuint(timer_counter(), ==, 0);
  323. timer_load(0);
  324. TIMER_BLOCK_STEP(scaler, 1);
  325. g_assert_cmpuint(timer_counter(), ==, 0);
  326. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  327. timer_load(1999999);
  328. for (i = 1; i < 10; i++) {
  329. TIMER_BLOCK_STEP(scaler, 2000001);
  330. g_assert_cmpuint(timer_counter(), ==, 1999999 - i);
  331. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  332. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  333. }
  334. }
  335. static void test_timer_nonzero_load_oneshot_to_zero(gconstpointer arg)
  336. {
  337. int scaler = *((int *) arg);
  338. timer_reset();
  339. timer_start(ONESHOT, scaler);
  340. TIMER_BLOCK_STEP(scaler, 1);
  341. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  342. g_assert_cmpuint(timer_counter(), ==, 0);
  343. timer_load(UINT32_MAX);
  344. timer_load(0);
  345. TIMER_BLOCK_STEP(scaler, 100);
  346. g_assert_cmpuint(timer_counter(), ==, 0);
  347. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  348. }
  349. static void test_timer_nonzero_load_periodic_to_zero(gconstpointer arg)
  350. {
  351. int scaler = *((int *) arg);
  352. timer_reset();
  353. timer_start(PERIODIC, scaler);
  354. TIMER_BLOCK_STEP(scaler, 1);
  355. g_assert_cmpuint(timer_counter(), ==, 0);
  356. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  357. timer_load(UINT32_MAX);
  358. timer_load(0);
  359. TIMER_BLOCK_STEP(scaler, 100);
  360. g_assert_cmpuint(timer_counter(), ==, 0);
  361. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  362. }
  363. static void test_timer_set_periodic_counter_on_the_fly(gconstpointer arg)
  364. {
  365. int scaler = *((int *) arg);
  366. timer_reset();
  367. timer_load(UINT32_MAX / 2);
  368. timer_start(PERIODIC, scaler);
  369. TIMER_BLOCK_STEP(scaler, 100);
  370. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX / 2 - 100);
  371. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  372. timer_set_counter(UINT32_MAX);
  373. TIMER_BLOCK_STEP(scaler, 100);
  374. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
  375. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  376. }
  377. static void test_timer_enable_and_set_counter(gconstpointer arg)
  378. {
  379. int scaler = *((int *) arg);
  380. timer_reset();
  381. timer_start(ONESHOT, scaler);
  382. TIMER_BLOCK_STEP(scaler, 1);
  383. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  384. timer_set_counter(UINT32_MAX);
  385. TIMER_BLOCK_STEP(scaler, 100);
  386. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
  387. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  388. }
  389. static void test_timer_set_counter_and_enable(gconstpointer arg)
  390. {
  391. int scaler = *((int *) arg);
  392. timer_reset();
  393. timer_set_counter(UINT32_MAX);
  394. timer_start(ONESHOT, scaler);
  395. TIMER_BLOCK_STEP(scaler, 100);
  396. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
  397. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  398. }
  399. static void test_timer_set_counter_disabled(void)
  400. {
  401. timer_reset();
  402. timer_set_counter(999999999);
  403. TIMER_BLOCK_STEP(NOSCALE, 100);
  404. g_assert_cmpuint(timer_counter(), ==, 999999999);
  405. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  406. }
  407. static void test_timer_load_disabled(void)
  408. {
  409. timer_reset();
  410. timer_load(999999999);
  411. TIMER_BLOCK_STEP(NOSCALE, 100);
  412. g_assert_cmpuint(timer_counter(), ==, 999999999);
  413. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  414. }
  415. static void test_timer_oneshot_with_counter_0_on_start(gconstpointer arg)
  416. {
  417. int scaler = *((int *) arg);
  418. timer_reset();
  419. timer_load(999);
  420. timer_set_counter(0);
  421. timer_start(ONESHOT, scaler);
  422. TIMER_BLOCK_STEP(scaler, 100);
  423. g_assert_cmpuint(timer_counter(), ==, 0);
  424. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  425. TIMER_BLOCK_STEP(scaler, 100);
  426. g_assert_cmpuint(timer_counter(), ==, 0);
  427. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  428. }
  429. static void test_timer_periodic_with_counter_0_on_start(gconstpointer arg)
  430. {
  431. int scaler = *((int *) arg);
  432. int i;
  433. timer_reset();
  434. timer_load(UINT32_MAX);
  435. timer_set_counter(0);
  436. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  437. g_assert_cmpuint(timer_counter(), ==, 0);
  438. timer_start(PERIODIC, scaler);
  439. TIMER_BLOCK_STEP(scaler, 100);
  440. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  441. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 100);
  442. TIMER_BLOCK_STEP(scaler, 100);
  443. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 200);
  444. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  445. timer_reset();
  446. timer_load(1999999);
  447. timer_set_counter(0);
  448. g_assert_cmpuint(timer_counter(), ==, 0);
  449. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  450. TIMER_BLOCK_STEP(scaler, 1);
  451. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  452. timer_start(PERIODIC, scaler);
  453. TIMER_BLOCK_STEP(scaler, 1);
  454. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  455. for (i = 2 - (!!scaler ? 1 : 0); i < 10; i++) {
  456. TIMER_BLOCK_STEP(scaler, 2000001);
  457. g_assert_cmpuint(timer_counter(), ==, 1999999 - i);
  458. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  459. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  460. }
  461. }
  462. static void test_periodic_counter(gconstpointer arg)
  463. {
  464. const int test_load = 10;
  465. int scaler = *((int *) arg);
  466. int test_val;
  467. timer_reset();
  468. timer_load(test_load);
  469. timer_start(PERIODIC, scaler);
  470. clock_step(1);
  471. for (test_val = 0; test_val <= test_load; test_val++) {
  472. clock_step(TIMER_BLOCK_SCALE(scaler) * test_load);
  473. g_assert_cmpint(timer_counter(), ==, test_val);
  474. }
  475. }
  476. static void test_timer_set_counter_periodic_with_zero_load(gconstpointer arg)
  477. {
  478. int scaler = *((int *) arg);
  479. timer_reset();
  480. timer_start(PERIODIC, scaler);
  481. timer_load(0);
  482. TIMER_BLOCK_STEP(scaler, 1);
  483. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  484. TIMER_BLOCK_STEP(scaler, 1);
  485. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  486. timer_set_counter(999);
  487. TIMER_BLOCK_STEP(scaler, 999);
  488. g_assert_cmpuint(timer_counter(), ==, 0);
  489. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  490. TIMER_BLOCK_STEP(scaler, 1);
  491. g_assert_cmpuint(timer_counter(), ==, 0);
  492. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  493. }
  494. static void test_timer_set_oneshot_load_to_0(gconstpointer arg)
  495. {
  496. int scaler = *((int *) arg);
  497. timer_reset();
  498. timer_load(UINT32_MAX);
  499. timer_start(ONESHOT, scaler);
  500. TIMER_BLOCK_STEP(scaler, 100);
  501. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
  502. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  503. timer_load(0);
  504. TIMER_BLOCK_STEP(scaler, 100);
  505. g_assert_cmpuint(timer_counter(), ==, 0);
  506. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  507. TIMER_BLOCK_STEP(scaler, 100);
  508. g_assert_cmpuint(timer_counter(), ==, 0);
  509. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  510. }
  511. static void test_timer_set_periodic_load_to_0(gconstpointer arg)
  512. {
  513. int scaler = *((int *) arg);
  514. timer_reset();
  515. timer_load(UINT32_MAX);
  516. timer_start(PERIODIC, scaler);
  517. TIMER_BLOCK_STEP(scaler, 100);
  518. g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
  519. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  520. timer_load(0);
  521. TIMER_BLOCK_STEP(scaler, 100);
  522. g_assert_cmpuint(timer_counter(), ==, 0);
  523. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  524. TIMER_BLOCK_STEP(scaler, 100);
  525. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  526. g_assert_cmpuint(timer_counter(), ==, 0);
  527. }
  528. static void test_deferred_trigger(void)
  529. {
  530. int mode = ONESHOT;
  531. again:
  532. timer_reset();
  533. timer_start(mode, 255);
  534. clock_step(100);
  535. g_assert_cmpuint(timer_counter(), ==, 0);
  536. TIMER_BLOCK_STEP(255, 1);
  537. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  538. timer_reset();
  539. timer_load(2);
  540. timer_start(mode, 255);
  541. clock_step(100);
  542. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  543. TIMER_BLOCK_STEP(255, 1);
  544. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  545. TIMER_BLOCK_STEP(255, 1);
  546. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  547. timer_reset();
  548. timer_load(UINT32_MAX);
  549. timer_start(mode, 255);
  550. clock_step(100);
  551. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  552. timer_set_counter(0);
  553. clock_step(100);
  554. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  555. TIMER_BLOCK_STEP(255, 1);
  556. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  557. timer_reset();
  558. timer_load(UINT32_MAX);
  559. timer_start(mode, 255);
  560. clock_step(100);
  561. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  562. timer_load(0);
  563. clock_step(100);
  564. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  565. TIMER_BLOCK_STEP(255, 1);
  566. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  567. if (mode == ONESHOT) {
  568. mode = PERIODIC;
  569. goto again;
  570. }
  571. }
  572. static void test_timer_zero_load_mode_switch(gconstpointer arg)
  573. {
  574. int scaler = *((int *) arg);
  575. timer_reset();
  576. timer_load(0);
  577. timer_start(PERIODIC, scaler);
  578. TIMER_BLOCK_STEP(scaler, 1);
  579. g_assert_cmpuint(timer_counter(), ==, 0);
  580. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  581. TIMER_BLOCK_STEP(scaler, 1);
  582. timer_start(ONESHOT, scaler);
  583. TIMER_BLOCK_STEP(scaler, 1);
  584. g_assert_cmpuint(timer_counter(), ==, 0);
  585. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  586. TIMER_BLOCK_STEP(scaler, 1);
  587. g_assert_cmpuint(timer_counter(), ==, 0);
  588. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  589. TIMER_BLOCK_STEP(scaler, 1);
  590. timer_start(PERIODIC, scaler);
  591. TIMER_BLOCK_STEP(scaler, 1);
  592. g_assert_cmpuint(timer_counter(), ==, 0);
  593. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
  594. }
  595. static void test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot(void)
  596. {
  597. timer_reset();
  598. timer_load(0);
  599. timer_start(PERIODIC, 255);
  600. TIMER_BLOCK_STEP(255, 1);
  601. g_assert_cmpuint(timer_counter(), ==, 0);
  602. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  603. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  604. TIMER_BLOCK_STEP(255, 1);
  605. g_assert_cmpuint(timer_counter(), ==, 0);
  606. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  607. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  608. TIMER_BLOCK_STEP(255, 1);
  609. timer_start(ONESHOT, NOSCALE);
  610. TIMER_BLOCK_STEP(NOSCALE, 1);
  611. g_assert_cmpuint(timer_counter(), ==, 0);
  612. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  613. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  614. TIMER_BLOCK_STEP(NOSCALE, 1);
  615. g_assert_cmpuint(timer_counter(), ==, 0);
  616. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  617. }
  618. static void test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic(void)
  619. {
  620. timer_reset();
  621. timer_load(0);
  622. timer_start(ONESHOT, 255);
  623. TIMER_BLOCK_STEP(255, 1);
  624. g_assert_cmpuint(timer_counter(), ==, 0);
  625. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  626. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  627. timer_start(PERIODIC, NOSCALE);
  628. TIMER_BLOCK_STEP(NOSCALE, 1);
  629. g_assert_cmpuint(timer_counter(), ==, 0);
  630. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  631. }
  632. static void test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic(void)
  633. {
  634. timer_reset();
  635. timer_load(0);
  636. timer_start(ONESHOT, NOSCALE);
  637. TIMER_BLOCK_STEP(NOSCALE, 1);
  638. g_assert_cmpuint(timer_counter(), ==, 0);
  639. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  640. timer_start(PERIODIC, 255);
  641. TIMER_BLOCK_STEP(255, 1);
  642. g_assert_cmpuint(timer_counter(), ==, 0);
  643. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  644. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  645. TIMER_BLOCK_STEP(255, 1);
  646. g_assert_cmpuint(timer_counter(), ==, 0);
  647. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  648. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  649. }
  650. static void test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot(void)
  651. {
  652. timer_reset();
  653. timer_load(0);
  654. timer_start(PERIODIC, NOSCALE);
  655. TIMER_BLOCK_STEP(NOSCALE, 1);
  656. g_assert_cmpuint(timer_counter(), ==, 0);
  657. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  658. timer_start(ONESHOT, 255);
  659. TIMER_BLOCK_STEP(255, 1);
  660. g_assert_cmpuint(timer_counter(), ==, 0);
  661. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
  662. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  663. TIMER_BLOCK_STEP(255, 1);
  664. g_assert_cmpuint(timer_counter(), ==, 0);
  665. g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
  666. }
  667. /*
  668. * Add a qtest test that comes in two versions: one with
  669. * a timer scaler setting, and one with the timer nonscaled.
  670. */
  671. static void add_scaler_test(const char *str, bool scale,
  672. void (*fn)(const void *))
  673. {
  674. char *name;
  675. int *scaler = scale ? &scaled : &nonscaled;
  676. name = g_strdup_printf("%s=%d", str, *scaler);
  677. qtest_add_data_func(name, scaler, fn);
  678. g_free(name);
  679. }
  680. int main(int argc, char **argv)
  681. {
  682. int ret;
  683. int scale;
  684. g_test_init(&argc, &argv, NULL);
  685. qtest_add_func("mptimer/deferred_trigger", test_deferred_trigger);
  686. qtest_add_func("mptimer/load_disabled", test_timer_load_disabled);
  687. qtest_add_func("mptimer/set_counter_disabled", test_timer_set_counter_disabled);
  688. qtest_add_func("mptimer/zero_load_prescaled_periodic_to_nonscaled_oneshot",
  689. test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot);
  690. qtest_add_func("mptimer/zero_load_prescaled_oneshot_to_nonscaled_periodic",
  691. test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic);
  692. qtest_add_func("mptimer/zero_load_nonscaled_oneshot_to_prescaled_periodic",
  693. test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic);
  694. qtest_add_func("mptimer/zero_load_nonscaled_periodic_to_prescaled_oneshot",
  695. test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot);
  696. qtest_add_func("mptimer/prescaler", test_timer_prescaler);
  697. qtest_add_func("mptimer/prescaler_on_the_fly", test_timer_prescaler_on_the_fly);
  698. for (scale = 0; scale < 2; scale++) {
  699. add_scaler_test("mptimer/oneshot scaler",
  700. scale, test_timer_oneshot);
  701. add_scaler_test("mptimer/pause scaler",
  702. scale, test_timer_pause);
  703. add_scaler_test("mptimer/reload scaler",
  704. scale, test_timer_reload);
  705. add_scaler_test("mptimer/periodic scaler",
  706. scale, test_timer_periodic);
  707. add_scaler_test("mptimer/oneshot_to_periodic scaler",
  708. scale, test_timer_oneshot_to_periodic);
  709. add_scaler_test("mptimer/periodic_to_oneshot scaler",
  710. scale, test_timer_periodic_to_oneshot);
  711. add_scaler_test("mptimer/set_oneshot_counter_to_0 scaler",
  712. scale, test_timer_set_oneshot_counter_to_0);
  713. add_scaler_test("mptimer/set_periodic_counter_to_0 scaler",
  714. scale, test_timer_set_periodic_counter_to_0);
  715. add_scaler_test("mptimer/noload_oneshot scaler",
  716. scale, test_timer_noload_oneshot);
  717. add_scaler_test("mptimer/noload_periodic scaler",
  718. scale, test_timer_noload_periodic);
  719. add_scaler_test("mptimer/zero_load_oneshot scaler",
  720. scale, test_timer_zero_load_oneshot);
  721. add_scaler_test("mptimer/zero_load_periodic scaler",
  722. scale, test_timer_zero_load_periodic);
  723. add_scaler_test("mptimer/zero_load_oneshot_to_nonzero scaler",
  724. scale, test_timer_zero_load_oneshot_to_nonzero);
  725. add_scaler_test("mptimer/zero_load_periodic_to_nonzero scaler",
  726. scale, test_timer_zero_load_periodic_to_nonzero);
  727. add_scaler_test("mptimer/nonzero_load_oneshot_to_zero scaler",
  728. scale, test_timer_nonzero_load_oneshot_to_zero);
  729. add_scaler_test("mptimer/nonzero_load_periodic_to_zero scaler",
  730. scale, test_timer_nonzero_load_periodic_to_zero);
  731. add_scaler_test("mptimer/set_periodic_counter_on_the_fly scaler",
  732. scale, test_timer_set_periodic_counter_on_the_fly);
  733. add_scaler_test("mptimer/enable_and_set_counter scaler",
  734. scale, test_timer_enable_and_set_counter);
  735. add_scaler_test("mptimer/set_counter_and_enable scaler",
  736. scale, test_timer_set_counter_and_enable);
  737. add_scaler_test("mptimer/oneshot_with_counter_0_on_start scaler",
  738. scale, test_timer_oneshot_with_counter_0_on_start);
  739. add_scaler_test("mptimer/periodic_with_counter_0_on_start scaler",
  740. scale, test_timer_periodic_with_counter_0_on_start);
  741. add_scaler_test("mptimer/periodic_counter scaler",
  742. scale, test_periodic_counter);
  743. add_scaler_test("mptimer/set_counter_periodic_with_zero_load scaler",
  744. scale, test_timer_set_counter_periodic_with_zero_load);
  745. add_scaler_test("mptimer/set_oneshot_load_to_0 scaler",
  746. scale, test_timer_set_oneshot_load_to_0);
  747. add_scaler_test("mptimer/set_periodic_load_to_0 scaler",
  748. scale, test_timer_set_periodic_load_to_0);
  749. add_scaler_test("mptimer/zero_load_mode_switch scaler",
  750. scale, test_timer_zero_load_mode_switch);
  751. }
  752. qtest_start("-machine vexpress-a9");
  753. ret = g_test_run();
  754. qtest_end();
  755. return ret;
  756. }