ipclite_test.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include <linux/kthread.h>
  6. #include <linux/string.h>
  7. #include <linux/bits.h>
  8. #include <linux/jiffies.h>
  9. #include <linux/delay.h>
  10. #include "ipclite_test.h"
  11. struct kobject *sysfs_dir;
  12. static int threads_started, threads_completed, cores_completed;
  13. static bool ssr_complete;
  14. /* data_lock spinlock is used to increment ping counters in thread safe manner.
  15. * core_wq to ensure all the cores have completed the test before next step.
  16. * ssr_wq to wait during ssr operation.
  17. * reply_wq to wait on replies to ping sent.
  18. * thread_wq to wait on all threads local to APPS to complete
  19. * test_done is a completion barrier which ensures test case is completed
  20. * crash_done is a completion barrier which ensures ssr crash is completed
  21. */
  22. DEFINE_SPINLOCK(data_lock);
  23. DECLARE_WAIT_QUEUE_HEAD(core_wq);
  24. DECLARE_WAIT_QUEUE_HEAD(ssr_wq);
  25. DECLARE_WAIT_QUEUE_HEAD(reply_wq);
  26. DECLARE_WAIT_QUEUE_HEAD(thread_wq);
  27. DECLARE_COMPLETION(test_done);
  28. DECLARE_COMPLETION(crash_done);
  29. static struct ipclite_thread_data wakeup_check, bg_pings;
  30. static struct ipclite_thread_data thread_data;
  31. struct handle_t *handle_ptr;
  32. static int handle_data[512];
  33. static struct ipclite_test_data *data;
  34. static void init_test_params(void)
  35. {
  36. data->test_params.wait = 1;
  37. data->test_params.num_pings = 1000;
  38. data->test_params.num_itr = 1;
  39. data->test_params.selected_senders = 1;
  40. data->test_params.selected_receivers = 1;
  41. data->test_params.enabled_cores = IPCLITE_TEST_ALL_CORES;
  42. data->test_params.selected_test_case = 0;
  43. data->test_params.num_thread = 1;
  44. data->test_params.num_senders = 1;
  45. data->test_params.num_receivers = 1;
  46. }
  47. /* Function to pack the different fields into one 64 bit message value
  48. * 1 byte header of constant patter 01010101
  49. * 1 byte to store the parameter type
  50. * 1 byte to store the test case id
  51. * 3 bytes to store the value of parameter in payload
  52. * 1 byte to store test start/stop information
  53. * 1 byte to store test pass/fail information
  54. */
  55. static uint64_t get_param_macro(uint64_t parameter_info, uint64_t test_info,
  56. uint64_t payload_info, uint64_t start_stop_info,
  57. uint64_t pass_fail_info)
  58. {
  59. uint64_t param_macro = 0;
  60. parameter_info &= GENMASK_ULL(7, 0);
  61. test_info &= GENMASK_ULL(7, 0);
  62. payload_info &= GENMASK_ULL(23, 0);
  63. start_stop_info &= GENMASK_ULL(7, 0);
  64. pass_fail_info &= GENMASK_ULL(7, 0);
  65. param_macro = ((uint64_t)IPCLITE_TEST_HEADER) << 56;
  66. param_macro |= parameter_info << 48;
  67. param_macro |= test_info << 40;
  68. param_macro |= payload_info << 16;
  69. param_macro |= start_stop_info << 8;
  70. param_macro |= pass_fail_info;
  71. return param_macro;
  72. }
  73. static inline bool is_enabled_core(int core_id)
  74. {
  75. return (data->test_params.enabled_cores & BIT(core_id)) ? true : false;
  76. }
  77. static inline bool is_selected_receiver(int core_id)
  78. {
  79. return (data->test_params.selected_receivers & BIT(core_id)) ? true : false;
  80. }
  81. static inline bool is_selected_sender(int core_id)
  82. {
  83. return (data->test_params.selected_senders & BIT(core_id)) ? true : false;
  84. }
  85. static void ping_receive(struct ipclite_test_data *data)
  86. {
  87. pr_debug("Successfully received a ping\n");
  88. data->pings_received[data->client_id]++;
  89. wake_up_interruptible(&reply_wq);
  90. }
  91. static int check_pings(struct ipclite_test_data *data)
  92. {
  93. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  94. if (!is_selected_receiver(i))
  95. continue;
  96. if (data->pings_sent[i] != data->pings_received[i])
  97. return -IPCLITE_TEST_FAIL;
  98. }
  99. return 0;
  100. }
  101. static void ping_all_enabled_cores(u64 msg)
  102. {
  103. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  104. if (i == IPCMEM_APPS || !is_enabled_core(i))
  105. continue;
  106. ipclite_test_msg_send(i, msg);
  107. }
  108. }
  109. static void ping_sel_senders(uint64_t msg)
  110. {
  111. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  112. if (i == IPCMEM_APPS || !(data->test_params.selected_senders & BIT(i)))
  113. continue;
  114. ipclite_test_msg_send(i, msg);
  115. }
  116. }
  117. static int thread_init(struct ipclite_thread_data *th_data, void *data_ptr, void *fptr)
  118. {
  119. th_data->data = data_ptr;
  120. th_data->run = false;
  121. init_waitqueue_head(&th_data->wq);
  122. th_data->thread = kthread_run(fptr, th_data, "test thread");
  123. if (IS_ERR(th_data->thread)) {
  124. pr_err("Thread creation failed\n");
  125. return -EINVAL;
  126. }
  127. return 0;
  128. }
  129. static int ping_selected_receivers(void *data_ptr)
  130. {
  131. struct ipclite_thread_data *t_data = data_ptr;
  132. struct ipclite_test_data *data = t_data->data;
  133. int ret = 0;
  134. uint64_t macro_to_ping = get_param_macro(TEST_CASE,
  135. data->test_params.selected_test_case,
  136. PING_SEND, 0, 0);
  137. bool fail = false;
  138. while (!kthread_should_stop()) {
  139. wait_event_interruptible(t_data->wq, t_data->run);
  140. if (kthread_should_stop())
  141. break;
  142. t_data->run = false;
  143. for (int i = 0; i < data->test_params.num_pings/data->test_params.num_thread; ++i) {
  144. for (int j = 0; j < IPCMEM_NUM_HOSTS; ++j) {
  145. if (!is_selected_receiver(j))
  146. continue;
  147. ret = ipclite_test_msg_send(j, macro_to_ping);
  148. if (ret == 0) {
  149. spin_lock(&data_lock);
  150. data->pings_sent[j]++;
  151. spin_unlock(&data_lock);
  152. } else
  153. fail = true;
  154. /* If wait is enabled and number of pings to wait on is sent,
  155. * Wait for replies or timeout
  156. */
  157. if (data->test_params.wait != 0 &&
  158. (i+1) % data->test_params.wait == 0) {
  159. ret = wait_event_interruptible_timeout(reply_wq,
  160. check_pings(data) == 0,
  161. msecs_to_jiffies(1000));
  162. if (ret < 1)
  163. pr_err("Timeout occurred\n");
  164. }
  165. }
  166. }
  167. pr_debug("Completed iteration. Marking thread as completed\n");
  168. spin_lock(&data_lock);
  169. threads_completed++;
  170. wake_up_interruptible(&thread_wq);
  171. spin_unlock(&data_lock);
  172. }
  173. return fail ? -IPCLITE_TEST_FAIL : 0;
  174. }
  175. static int negative_tests(void *data_ptr)
  176. {
  177. struct ipclite_thread_data *t_data = data_ptr;
  178. int ret = 0, fail = 0;
  179. uint64_t param;
  180. while (!kthread_should_stop()) {
  181. wait_event_interruptible(t_data->wq, t_data->run);
  182. if (kthread_should_stop())
  183. break;
  184. t_data->run = false;
  185. pr_info("Test 1: Sending messages to disabled cores\n");
  186. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  187. if (!is_selected_receiver(i))
  188. continue;
  189. param = get_param_macro(TEST_CASE, NEGATIVE,
  190. PING_SEND, 0, 0);
  191. ret = ipclite_test_msg_send(i, param);
  192. if (ret == 0) {
  193. pr_err("TEST FAILED\n");
  194. fail++;
  195. }
  196. }
  197. if (!fail)
  198. pr_info("TEST PASSED\n");
  199. pr_info("Test 2: Passing NULL to get_global_parition_info\n");
  200. ret = get_global_partition_info(NULL);
  201. if (ret == 0) {
  202. pr_err("TEST FAILED\n");
  203. fail++;
  204. } else
  205. pr_info("TEST PASSED\n");
  206. if (fail != 0)
  207. pr_err("Negative TEST FAILED\n");
  208. else
  209. pr_info("Negative TEST PASSED\n");
  210. param = get_param_macro(TEST_CASE, NEGATIVE, 0,
  211. IPCLITE_TEST_STOP, 0);
  212. ipclite_test_msg_send(IPCMEM_APPS, param);
  213. wait_event_interruptible_timeout(core_wq,
  214. cores_completed == data->test_params.num_senders,
  215. msecs_to_jiffies(1000));
  216. complete(&test_done);
  217. }
  218. return fail == 0 ? 0 : -IPCLITE_TEST_FAIL;
  219. }
  220. static int hw_unlock_test(void *hw_mutex_byte)
  221. {
  222. int ret = 0;
  223. uint64_t param;
  224. if (!hw_mutex_byte) {
  225. pr_err("Byte for hardware mutex testing is not initialized.\n");
  226. return -EFAULT;
  227. }
  228. pr_info("Testing HW Mutex Lock Acquire Functionality\n");
  229. *((int *)(hw_mutex_byte)) = -1;
  230. pr_debug("The initial value of the byte is %d\n", *((int *)(hw_mutex_byte)));
  231. pr_debug("Locking the mutex from APPS Side\n");
  232. ret = ipclite_hw_mutex_acquire();
  233. if (ret != 0) {
  234. pr_err("Could not acquire hw mutex from APPS side\n");
  235. return ret;
  236. }
  237. pr_debug("Setting the value of the byte to %d\n", IPCMEM_APPS);
  238. *((int *)(hw_mutex_byte)) = IPCMEM_APPS;
  239. pr_debug("The new value of the byte is %d\n", *((int *)(hw_mutex_byte)));
  240. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  241. if (i == IPCMEM_APPS || !is_selected_receiver(i))
  242. continue;
  243. pr_debug("Pinging %s to try and release the locked mutex\n",
  244. core_name[i]);
  245. param = get_param_macro(TEST_CASE, HW_MUTEX,
  246. HW_MUTEX_RELEASE,
  247. IPCLITE_TEST_START, 0);
  248. ipclite_test_msg_send(i, param);
  249. // Wait for timeout here
  250. udelay(1000);
  251. }
  252. if (*((int *)(hw_mutex_byte)) != IPCMEM_APPS)
  253. return -IPCLITE_TEST_FAIL;
  254. ret = ipclite_hw_mutex_release();
  255. if (ret != 0)
  256. pr_err("Could not release mutex lock successfully\n");
  257. return ret;
  258. }
  259. static int hw_mutex_test(void *data_ptr)
  260. {
  261. struct ipclite_thread_data *t_data = data_ptr;
  262. struct ipclite_test_data *data = t_data->data;
  263. int ret = 0;
  264. void *addr = data->global_memory->virt_base;
  265. while (!kthread_should_stop()) {
  266. wait_event_interruptible(t_data->wq, t_data->run);
  267. if (kthread_should_stop())
  268. break;
  269. t_data->run = false;
  270. ret = hw_unlock_test(addr);
  271. if (ret == 0)
  272. pr_info("HW Unlock Test Passed.\n");
  273. else
  274. pr_info("HW Unlock Test Failed.\n");
  275. complete(&test_done);
  276. }
  277. return ret;
  278. }
  279. /* Ping cores which are not selected for ssr in the background */
  280. static int send_bg_pings(void *data_ptr)
  281. {
  282. struct ipclite_thread_data *t_data = data_ptr;
  283. struct ipclite_test_data *data = t_data->data;
  284. int ret;
  285. uint64_t param;
  286. while (!kthread_should_stop()) {
  287. wait_event_interruptible(t_data->wq, t_data->run);
  288. if (kthread_should_stop())
  289. break;
  290. t_data->run = false;
  291. while (!ssr_complete && !kthread_should_stop()) {
  292. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  293. if (i == data->ssr_client || !is_selected_receiver(i))
  294. continue;
  295. param = get_param_macro(TEST_CASE,
  296. SSR,
  297. PING_SEND, 0, 0);
  298. ret = ipclite_test_msg_send(i, param);
  299. if (ret != 0)
  300. pr_err("Unable to ping core %d\n", i);
  301. }
  302. wait_event_interruptible_timeout(ssr_wq,
  303. ssr_complete,
  304. msecs_to_jiffies(1000));
  305. }
  306. pr_debug("SSR recovery of core %d completed. Exiting thread\n",
  307. data->ssr_client);
  308. }
  309. return 0;
  310. }
  311. /* Wait for 30s and then send pings one to by one to see if core wakeup
  312. * is completed
  313. */
  314. static int ssr_wakeup_check(void *data_ptr)
  315. {
  316. struct ipclite_thread_data *t_data = data_ptr;
  317. struct ipclite_test_data *data = t_data->data;
  318. int count = 0, ret = 0;
  319. uint64_t param;
  320. while (!kthread_should_stop()) {
  321. wait_event_interruptible(t_data->wq, t_data->run);
  322. if (kthread_should_stop())
  323. break;
  324. t_data->run = false;
  325. ssr_complete = false;
  326. msleep_interruptible(30000);
  327. while (count < 10) {
  328. pr_debug("Sent ping number %d to check if wakeup is completed\n",
  329. count);
  330. param = get_param_macro(TEST_CASE, SSR,
  331. SSR_WAKEUP,
  332. IPCLITE_TEST_START, 0);
  333. ret = ipclite_test_msg_send(data->ssr_client, param);
  334. ++count;
  335. wait_event_interruptible_timeout(ssr_wq,
  336. ssr_complete,
  337. msecs_to_jiffies(1000));
  338. }
  339. if (count == 10 && !ssr_complete) {
  340. pr_info("FW Core wakeup failed.\n");
  341. return -IPCLITE_TEST_FAIL;
  342. }
  343. pr_info("FW Core wakeup completed successfully.\n");
  344. pr_info("Going for non crashing testing.\n");
  345. param = get_param_macro(TEST_CASE, PING, 0,
  346. IPCLITE_TEST_START, 0);
  347. ipclite_test_msg_send(data->ssr_client, param);
  348. complete(&crash_done);
  349. }
  350. return 0;
  351. }
  352. static int ssr_test(void *data_ptr)
  353. {
  354. struct ipclite_thread_data *t_data = data_ptr;
  355. struct ipclite_test_data *data = t_data->data;
  356. uint64_t param = 0;
  357. int ret = 0;
  358. while (!kthread_should_stop()) {
  359. wait_event_interruptible(t_data->wq, t_data->run);
  360. if (kthread_should_stop())
  361. break;
  362. t_data->run = false;
  363. ssr_complete = false;
  364. ret = thread_init(&wakeup_check, data, ssr_wakeup_check);
  365. if (ret != 0) {
  366. pr_err("Thread creation failed\n");
  367. return -EINVAL;
  368. }
  369. ret = thread_init(&bg_pings, data, send_bg_pings);
  370. if (ret != 0) {
  371. pr_err("Thread creation failed\n");
  372. kthread_stop(wakeup_check.thread);
  373. return -EINVAL;
  374. }
  375. pr_info("Starting on SSR test for core %d\n", data->ssr_client);
  376. memset(data->pings_sent, 0, sizeof(data->pings_sent));
  377. memset(data->pings_received, 0, sizeof(data->pings_received));
  378. param = get_param_macro(TEST_CASE, SSR,
  379. SSR_CRASHING, IPCLITE_TEST_START, 0);
  380. ipclite_test_msg_send(data->ssr_client, param);
  381. wait_for_completion(&crash_done);
  382. kthread_stop(wakeup_check.thread);
  383. kthread_stop(bg_pings.thread);
  384. complete(&test_done);
  385. }
  386. return 0;
  387. }
  388. static int inc_byte(void *data_ptr)
  389. {
  390. struct ipclite_thread_data *t_data = data_ptr;
  391. ipclite_atomic_uint32_t *addr = t_data->data;
  392. while (!kthread_should_stop()) {
  393. wait_event_interruptible(t_data->wq, t_data->run);
  394. if (kthread_should_stop())
  395. break;
  396. t_data->run = false;
  397. for (int i = 0; i < data->test_params.num_itr; ++i)
  398. ipclite_global_atomic_inc(addr);
  399. threads_completed++;
  400. wake_up_interruptible(&thread_wq);
  401. }
  402. return 0;
  403. }
  404. static int dec_byte(void *data_ptr)
  405. {
  406. struct ipclite_thread_data *t_data = data_ptr;
  407. ipclite_atomic_uint32_t *addr = t_data->data;
  408. while (!kthread_should_stop()) {
  409. wait_event_interruptible(t_data->wq, t_data->run);
  410. if (kthread_should_stop())
  411. break;
  412. t_data->run = false;
  413. for (int i = 0; i < data->test_params.num_itr; ++i)
  414. ipclite_global_atomic_dec(addr);
  415. threads_completed++;
  416. wake_up_interruptible(&thread_wq);
  417. }
  418. return 0;
  419. }
  420. static int global_atomics_test(void *byte, int test_number)
  421. {
  422. int ret = 0;
  423. int total_increment = 0;
  424. uint64_t param;
  425. bool fail = false;
  426. struct ipclite_thread_data ga_t1, ga_t2;
  427. if (!byte) {
  428. pr_err("Byte not initialized. Test Failed\n");
  429. return -EFAULT;
  430. }
  431. pr_debug("The initial value of the byte is %x\n", *((int *)byte));
  432. threads_completed = 0;
  433. threads_started = 0;
  434. switch (test_number) {
  435. case GLOBAL_ATOMICS_INC:
  436. ret = thread_init(&ga_t1, byte, inc_byte);
  437. if (ret != 0) {
  438. pr_err("Thread creation failed\n");
  439. return -EINVAL;
  440. }
  441. ret = thread_init(&ga_t2, byte, inc_byte);
  442. if (ret != 0) {
  443. pr_err("Thread creation failed\n");
  444. kthread_stop(ga_t1.thread);
  445. return -EINVAL;
  446. }
  447. break;
  448. case GLOBAL_ATOMICS_DEC:
  449. ret = thread_init(&ga_t1, byte, dec_byte);
  450. if (ret != 0) {
  451. pr_err("Thread creation failed\n");
  452. return -EINVAL;
  453. }
  454. ret = thread_init(&ga_t2, byte, dec_byte);
  455. if (ret != 0) {
  456. pr_err("Thread creation failed\n");
  457. kthread_stop(ga_t1.thread);
  458. return -EINVAL;
  459. }
  460. break;
  461. case GLOBAL_ATOMICS_INC_DEC:
  462. ret = thread_init(&ga_t1, byte, inc_byte);
  463. if (ret != 0) {
  464. pr_err("Thread creation failed\n");
  465. return -EINVAL;
  466. }
  467. ret = thread_init(&ga_t2, byte, dec_byte);
  468. if (ret != 0) {
  469. pr_err("Thread creation failed\n");
  470. kthread_stop(ga_t1.thread);
  471. return -EINVAL;
  472. }
  473. break;
  474. default:
  475. pr_err("Wrong input provided\n");
  476. return -EINVAL;
  477. }
  478. param = get_param_macro(TEST_CASE,
  479. GLOBAL_ATOMIC,
  480. test_number,
  481. IPCLITE_TEST_START, 0);
  482. for (int i = 0; i < IPCMEM_NUM_HOSTS; ++i) {
  483. if (i == IPCMEM_APPS || !is_selected_receiver(i))
  484. continue;
  485. ret = ipclite_test_msg_send(i, param);
  486. if (ret == 0)
  487. threads_started += 2;
  488. }
  489. if (is_selected_receiver(IPCMEM_APPS)) {
  490. ga_t1.run = true;
  491. wake_up_interruptible(&ga_t1.wq);
  492. ga_t2.run = true;
  493. wake_up_interruptible(&ga_t2.wq);
  494. threads_started += 2;
  495. }
  496. /* Wait for all threads to complete or timeout */
  497. ret = wait_event_interruptible_timeout(thread_wq,
  498. threads_started == 2 * data->test_params.num_receivers &&
  499. threads_completed == 2 * data->test_params.num_receivers,
  500. msecs_to_jiffies(1000));
  501. if (ret < 1)
  502. pr_err("Threads could not complete successfully\n");
  503. pr_debug("The value of the byte is %x\n", *((int *)byte));
  504. /* Stopping threads if they have not already completed before evaluation */
  505. kthread_stop(ga_t1.thread);
  506. kthread_stop(ga_t2.thread);
  507. total_increment = 2 * data->test_params.num_receivers * data->test_params.num_itr;
  508. switch (test_number) {
  509. case GLOBAL_ATOMICS_INC:
  510. if (*((int *)byte) == total_increment)
  511. pr_info("Increment Successful.\n");
  512. else {
  513. pr_err("Increment Failed.\n");
  514. fail = true;
  515. }
  516. break;
  517. case GLOBAL_ATOMICS_DEC:
  518. if (*((int *)byte) == 0)
  519. pr_info("Decrement Successful\n");
  520. else {
  521. pr_err("Decrement Failed\n");
  522. fail = true;
  523. }
  524. break;
  525. case GLOBAL_ATOMICS_INC_DEC:
  526. if (*((int *)byte) == 0)
  527. pr_info("Increment and Decrement Successful\n");
  528. else {
  529. pr_err("Increment and Decrement Failed\n");
  530. fail = true;
  531. }
  532. break;
  533. default:
  534. pr_err("Wrong input provided\n");
  535. return -EINVAL;
  536. }
  537. return fail ? -IPCLITE_TEST_FAIL : 0;
  538. }
  539. static inline uint32_t bitops_count_trailing_one(uint32_t x)
  540. {
  541. uint32_t mask = 0;
  542. for (int i = 0; i < BITS(ipclite_atomic_uint32_t); i++) {
  543. mask = 1 << i;
  544. if (!(x & mask))
  545. return i;
  546. }
  547. return BITS(ipclite_atomic_uint32_t);
  548. }
  549. /**
  550. * @brief Finds the first zero in the bitmap
  551. *
  552. * @param bmap_addr pointer to bitmap
  553. * @param size the size of the bitmap indicated in number of bits
  554. * @return uint32_t index of the first zero
  555. */
  556. static uint32_t bitops_util_find_first_zero(uint32_t *bmap_addr, uint32_t size)
  557. {
  558. uint32_t res = 0;
  559. for (int i = 0; i * BITS(ipclite_atomic_uint32_t) < size; i++) {
  560. if (bmap_addr[i] != ~(uint32_t)0) {
  561. res = i * BITS(ipclite_atomic_uint32_t) +
  562. bitops_count_trailing_one(bmap_addr[i]);
  563. return res < size ? res : size;
  564. }
  565. }
  566. return size;
  567. }
  568. static int alloc_index(int *bitmap_base)
  569. {
  570. uint32_t prev = 0, index = 0;
  571. do {
  572. index = bitops_util_find_first_zero((unsigned int *) bitmap_base,
  573. NUM_HANDLES);
  574. if (index > NUM_HANDLES) {
  575. pr_err("No Memory Error. Exiting\n");
  576. break;
  577. }
  578. prev = ipclite_global_test_and_set_bit(index % 32,
  579. (ipclite_atomic_uint32_t *)(bitmap_base + index/32));
  580. if ((prev & (1UL << (index % 32))) == 0)
  581. break;
  582. } while (true);
  583. return index;
  584. }
  585. void clear_index(int *bitmap_base, uint32_t index)
  586. {
  587. uint32_t addr_idx = index/32, ii = index % 32;
  588. if (bitmap_base == NULL) {
  589. pr_err("Invalid pointer passed\n");
  590. return;
  591. }
  592. ipclite_global_test_and_clear_bit(ii, (ipclite_atomic_uint32_t *)(bitmap_base + addr_idx));
  593. }
  594. static int global_atomics_test_set_clear(struct ipclite_test_data *data)
  595. {
  596. int index = 0, ret = 0;
  597. bool fail = false;
  598. uint64_t param;
  599. handle_ptr = data->global_memory->virt_base;
  600. pr_info("Starting global atomics Test 4. Starting allocation of index\n");
  601. pr_debug("The total number of handles is %d\n", NUM_HANDLES);
  602. pr_debug("Global Base : %p\n", handle_ptr);
  603. for (int itr = 0; itr < data->test_params.num_itr; itr++) {
  604. threads_started = 0;
  605. threads_completed = 0;
  606. for (int j = 0; j < IPCMEM_NUM_HOSTS; ++j) {
  607. if (j == IPCMEM_APPS || !is_selected_receiver(j))
  608. continue;
  609. param = get_param_macro(TEST_CASE,
  610. GLOBAL_ATOMIC,
  611. GLOBAL_ATOMICS_SET_CLR,
  612. IPCLITE_TEST_START, 0);
  613. ret = ipclite_test_msg_send(j, param);
  614. if (ret == 0)
  615. threads_started++;
  616. }
  617. if (is_selected_receiver(IPCMEM_APPS)) {
  618. threads_started++;
  619. for (int i = 0; i < 512; ++i) {
  620. index = alloc_index((int *)handle_ptr);
  621. handle_data[i] = index;
  622. handle_ptr->handle_data[index] = IPCMEM_APPS;
  623. }
  624. for (int i = 0; i < 512; ++i) {
  625. index = handle_data[i];
  626. if (handle_ptr->handle_data[index] != IPCMEM_APPS) {
  627. pr_err("Handle data has been overwritten.\n");
  628. pr_err("This is a bug : Core : %d Index : %d\n",
  629. handle_ptr->handle_data[index], index);
  630. fail = true;
  631. }
  632. }
  633. for (int i = 0; i < 512; ++i) {
  634. index = handle_data[i];
  635. clear_index((int *)handle_ptr, index);
  636. }
  637. threads_completed++;
  638. if (fail)
  639. break;
  640. }
  641. wait_event_interruptible_timeout(thread_wq,
  642. threads_started == data->test_params.num_receivers &&
  643. threads_completed == data->test_params.num_receivers,
  644. msecs_to_jiffies(1000));
  645. }
  646. if (!fail)
  647. pr_info("Global Atomics Set and Clear test passed successfully\n");
  648. return fail ? -IPCLITE_TEST_FAIL : 0;
  649. }
  650. static int global_atomics_test_wrapper(void *data_ptr)
  651. {
  652. int result = 0, ret = 0;
  653. struct ipclite_thread_data *t_data = data_ptr;
  654. struct ipclite_test_data *data = t_data->data;
  655. void *addr = data->global_memory->virt_base;
  656. while (!kthread_should_stop()) {
  657. wait_event_interruptible(t_data->wq, t_data->run);
  658. if (kthread_should_stop())
  659. break;
  660. t_data->run = false;
  661. *((int *)addr) = 0;
  662. result = global_atomics_test(addr, GLOBAL_ATOMICS_INC);
  663. result &= global_atomics_test(addr, GLOBAL_ATOMICS_DEC);
  664. result &= global_atomics_test(addr, GLOBAL_ATOMICS_INC_DEC);
  665. result &= global_atomics_test_set_clear(data);
  666. if (result != 0) {
  667. pr_err("Global Atomics TEST FAILED\n");
  668. ret = -IPCLITE_TEST_FAIL;
  669. } else {
  670. pr_info("Global Atomics TEST PASSED\n");
  671. ret = 0;
  672. }
  673. complete(&test_done);
  674. }
  675. return ret;
  676. }
  677. static int ping_test(void *data_ptr)
  678. {
  679. int ret = 0;
  680. uint64_t param_macro;
  681. struct ipclite_test_data *data = data_ptr;
  682. struct ipclite_thread_data th_arr[IPCLITE_TEST_MAX_THREADS];
  683. int count;
  684. memset(data->pings_sent, 0, sizeof(data->pings_sent));
  685. memset(data->pings_received, 0, sizeof(data->pings_received));
  686. threads_completed = 0;
  687. param_macro = 0;
  688. for (count = 0; count < data->test_params.num_thread; ++count) {
  689. ret = thread_init(&th_arr[count], data, ping_selected_receivers);
  690. if (ret != 0)
  691. break;
  692. }
  693. if (count != data->test_params.num_thread)
  694. while (count > 0) {
  695. kthread_stop(th_arr[count-1].thread);
  696. --count;
  697. }
  698. if (ret != 0) {
  699. pr_err("Threads could not be initialized. Ping Test Failed\n");
  700. return ret;
  701. }
  702. for (threads_started = 0; threads_started < data->test_params.num_thread;
  703. ++threads_started) {
  704. th_arr[threads_started].run = true;
  705. wake_up_interruptible(&th_arr[threads_started].wq);
  706. }
  707. ret = wait_event_interruptible_timeout(thread_wq,
  708. threads_started == data->test_params.num_thread &&
  709. threads_completed == data->test_params.num_thread,
  710. msecs_to_jiffies(1000) * data->test_params.num_thread);
  711. if (ret < 1) {
  712. pr_err("Threads not completed successfully. Only completed %d threads\n",
  713. threads_completed);
  714. return ret;
  715. }
  716. pr_info("All threads completed successfully.\n");
  717. pr_debug("Going for checking\n");
  718. /*Wait for the queue to get processed before checking if all replies are received*/
  719. if (!data->test_params.wait)
  720. msleep_interruptible(1000);
  721. ret = check_pings(data);
  722. if (ret == 0)
  723. pr_debug("All replies received successfully.\n");
  724. else
  725. pr_debug("All replies not received successfully.\n");
  726. while (count > 0) {
  727. kthread_stop(th_arr[count-1].thread);
  728. --count;
  729. }
  730. param_macro = get_param_macro(TEST_CASE, PING, 0,
  731. IPCLITE_TEST_STOP, 0);
  732. ipclite_test_msg_send(IPCMEM_APPS, param_macro);
  733. return ret;
  734. }
  735. static int wrapper_ping_test(void *data_ptr)
  736. {
  737. int ret = 0;
  738. uint64_t param_macro;
  739. struct ipclite_thread_data *t_data = data_ptr;
  740. struct ipclite_test_data *data = t_data->data;
  741. while (!kthread_should_stop()) {
  742. wait_event_interruptible(t_data->wq, t_data->run);
  743. if (kthread_should_stop())
  744. break;
  745. t_data->run = false;
  746. for (int i = 0; i < data->test_params.num_itr; ++i) {
  747. cores_completed = 0;
  748. param_macro = get_param_macro(TEST_CASE,
  749. PING,
  750. 0, IPCLITE_TEST_START, 0);
  751. /* Ping all senders to start sending messages.
  752. * If APPS is one of the senders start sending
  753. */
  754. ping_sel_senders(param_macro);
  755. if (is_selected_sender(IPCMEM_APPS))
  756. ping_test(data);
  757. wait_event_interruptible_timeout(core_wq,
  758. cores_completed == data->test_params.num_senders,
  759. msecs_to_jiffies(1000));
  760. ret = check_pings(data);
  761. if (ret != 0)
  762. pr_info("Iteration %d of ping test failed\n", i+1);
  763. else
  764. pr_info("Iteration %d of ping test passed\n", i+1);
  765. }
  766. if (is_selected_sender(IPCMEM_APPS))
  767. complete(&test_done);
  768. }
  769. return 0;
  770. }
  771. static int debug_tests(void *data_ptr)
  772. {
  773. struct ipclite_thread_data *t_data = data_ptr;
  774. uint64_t param;
  775. int disabled_core = ffz(data->test_params.enabled_cores);
  776. while (!kthread_should_stop()) {
  777. wait_event_interruptible(t_data->wq, t_data->run);
  778. if (kthread_should_stop())
  779. break;
  780. t_data->run = false;
  781. param = get_param_macro(TEST_CASE, DEBUG,
  782. PING_SEND, 0, 0);
  783. if (disabled_core == IPCMEM_NUM_HOSTS)
  784. pr_err("All cores are enabled. No Disabled cores\n");
  785. /* Pinging one enabled and disabled cores to get the error and dbg prints */
  786. if (disabled_core < IPCMEM_NUM_HOSTS)
  787. ipclite_test_msg_send(disabled_core, param);
  788. param = get_param_macro(TEST_CASE, PING, 0,
  789. IPCLITE_TEST_STOP, 0);
  790. ipclite_test_msg_send(IPCMEM_APPS, param);
  791. wait_event_interruptible_timeout(core_wq,
  792. cores_completed == data->test_params.num_senders,
  793. msecs_to_jiffies(1000));
  794. complete(&test_done);
  795. }
  796. return 0;
  797. }
  798. static void ipclite_test_set_enabled_cores(void)
  799. {
  800. if (data->test_params.enabled_cores < 0 ||
  801. data->test_params.enabled_cores > IPCLITE_TEST_ALL_CORES) {
  802. pr_err("Invalid parameter value given to enabled cores\n");
  803. data->test_params.enabled_cores = IPCLITE_TEST_ALL_CORES;
  804. return;
  805. }
  806. pr_info("Enabled cores set to %d\n", data->test_params.enabled_cores);
  807. }
  808. static void ipclite_test_set_wait(void)
  809. {
  810. uint64_t param;
  811. if (data->test_params.wait < 0) {
  812. pr_err("Invalid parameter value given to wait\n");
  813. data->test_params.wait = 1;
  814. return;
  815. }
  816. pr_info("wait set to %d\n", data->test_params.wait);
  817. param = get_param_macro(WAIT, 0, data->test_params.wait, 0, 0);
  818. ping_all_enabled_cores(param);
  819. }
  820. static void ipclite_test_set_num_pings(void)
  821. {
  822. uint64_t param;
  823. pr_info("num_pings set to %d\n", data->test_params.num_pings);
  824. param = get_param_macro(NUM_PINGS, 0,
  825. data->test_params.num_pings, 0, 0);
  826. ping_all_enabled_cores(param);
  827. }
  828. static void ipclite_test_set_num_itr(void)
  829. {
  830. uint64_t param;
  831. pr_info("num_itr set to %d\n", data->test_params.num_itr);
  832. param = get_param_macro(NUM_ITR, 1,
  833. data->test_params.num_itr, 0, 0);
  834. ping_all_enabled_cores(param);
  835. }
  836. static void ipclite_test_set_receivers(void)
  837. {
  838. uint64_t param;
  839. if (data->test_params.selected_receivers < 0 ||
  840. data->test_params.selected_receivers > IPCLITE_TEST_ALL_CORES) {
  841. pr_err("Invalid parameter value given to selected_receivers\n");
  842. data->test_params.selected_receivers = 1;
  843. data->test_params.num_receivers = 1;
  844. return;
  845. }
  846. /* Check number of 1s using hamming weight function.
  847. * Number of 1s is number of receivers
  848. */
  849. data->test_params.num_receivers = hweight_long(data->test_params.selected_receivers);
  850. pr_info("selected_receivers set to %d\n", data->test_params.selected_receivers);
  851. param = get_param_macro(RECEIVER_LIST, 0,
  852. data->test_params.selected_receivers, 0, 0);
  853. ping_all_enabled_cores(param);
  854. }
  855. static void ipclite_test_set_senders(void)
  856. {
  857. if (data->test_params.selected_senders < 0 ||
  858. data->test_params.selected_senders > IPCLITE_TEST_ALL_CORES) {
  859. pr_err("Invalid parameter value given to selected_senders\n");
  860. data->test_params.selected_senders = 1;
  861. data->test_params.num_senders = 1;
  862. return;
  863. }
  864. /* Check number of 1s using hamming weight function. */
  865. data->test_params.num_senders = hweight_long(data->test_params.selected_senders);
  866. pr_info("selected_senders set to %d\n", data->test_params.selected_senders);
  867. }
  868. static void ipclite_test_set_num_threads(void)
  869. {
  870. uint64_t param;
  871. if (data->test_params.num_thread < 0 ||
  872. data->test_params.num_thread > IPCLITE_TEST_MAX_THREADS) {
  873. pr_err("Invalid parameter value given to num_thread\n");
  874. data->test_params.num_thread = 1;
  875. return;
  876. }
  877. pr_info("num_thread set to %d\n", data->test_params.num_thread);
  878. param = get_param_macro(NUM_THREADS, 0,
  879. data->test_params.num_thread, 0, 0);
  880. ping_all_enabled_cores(param);
  881. }
  882. static void ipclite_test_set_test(void)
  883. {
  884. uint64_t param;
  885. int ret = 0;
  886. if (data->test_params.selected_test_case < 0 || data->test_params.selected_test_case > 8) {
  887. pr_err("Invalid parameter value given to test_case\n");
  888. data->test_params.selected_test_case = 0;
  889. return;
  890. }
  891. pr_info("selected_test_case set to %d\n", data->test_params.selected_test_case);
  892. param = get_param_macro(TEST_CASE,
  893. data->test_params.selected_test_case, 0,
  894. IPCLITE_TEST_START, 0);
  895. switch (data->test_params.selected_test_case) {
  896. case PING:
  897. ret = thread_init(&thread_data, data, wrapper_ping_test);
  898. if (ret != 0) {
  899. pr_err("Could not create thread for testing\n");
  900. return;
  901. }
  902. thread_data.run = true;
  903. wake_up_interruptible(&thread_data.wq);
  904. break;
  905. case NEGATIVE:
  906. ping_sel_senders(param);
  907. if (is_selected_sender(IPCMEM_APPS)) {
  908. pr_info("Starting test %d for core %s\n",
  909. NEGATIVE, core_name[IPCMEM_APPS]);
  910. ret = thread_init(&thread_data, data, negative_tests);
  911. if (ret != 0) {
  912. pr_err("Could not create thread for testing\n");
  913. return;
  914. }
  915. thread_data.run = true;
  916. wake_up_interruptible(&thread_data.wq);
  917. }
  918. break;
  919. case GLOBAL_ATOMIC:
  920. ret = thread_init(&thread_data, data, global_atomics_test_wrapper);
  921. if (ret != 0) {
  922. pr_err("Could not create thread for testing\n");
  923. return;
  924. }
  925. thread_data.run = true;
  926. wake_up_interruptible(&thread_data.wq);
  927. break;
  928. case DEBUG:
  929. ping_sel_senders(param);
  930. if (is_selected_sender(IPCMEM_APPS)) {
  931. ret = thread_init(&thread_data, data, debug_tests);
  932. if (ret != 0) {
  933. pr_err("Could not create thread for testing\n");
  934. return;
  935. }
  936. thread_data.run = true;
  937. wake_up_interruptible(&thread_data.wq);
  938. }
  939. break;
  940. case SSR:
  941. if (data->test_params.num_senders != 1) {
  942. pr_err("SSR Testing requires only 1 core to be selected\n");
  943. return;
  944. }
  945. /* Find first set (ffs) to get the bit position/index of sender */
  946. data->ssr_client = ffs(data->test_params.selected_senders) - 1;
  947. if (data->ssr_client == 0 || !is_enabled_core(data->ssr_client)) {
  948. pr_err("Invalid core selected for SSR Testing\n");
  949. return;
  950. }
  951. pr_info("Starting test %d for core %s\n",
  952. SSR, core_name[data->ssr_client]);
  953. ret = thread_init(&thread_data, data, ssr_test);
  954. if (ret != 0) {
  955. pr_err("Could not create thread for testing\n");
  956. return;
  957. }
  958. thread_data.run = true;
  959. wake_up_interruptible(&thread_data.wq);
  960. break;
  961. case HW_MUTEX:
  962. if (data->test_params.num_senders != 1) {
  963. pr_err("HW Mutex Testing requires only 1 core to be selected\n");
  964. return;
  965. }
  966. if (is_selected_sender(IPCMEM_APPS)) {
  967. pr_info("Starting test %d for core %s\n",
  968. HW_MUTEX, core_name[IPCMEM_APPS]);
  969. ret = thread_init(&thread_data, data, hw_mutex_test);
  970. if (ret != 0) {
  971. pr_err("Could not create thread for testing\n");
  972. return;
  973. }
  974. thread_data.run = true;
  975. wake_up_interruptible(&thread_data.wq);
  976. } else
  977. ping_sel_senders(param);
  978. break;
  979. default:
  980. pr_err("Wrong input provided\n");
  981. return;
  982. }
  983. wait_for_completion(&test_done);
  984. if (thread_data.thread != NULL)
  985. ret = kthread_stop(thread_data.thread);
  986. if (ret != 0)
  987. pr_err("Test did not complete successfully\n");
  988. else
  989. pr_info("Test completed successfully\n");
  990. }
  991. static int parse_param(char **temp_buf, int *addr)
  992. {
  993. char *token;
  994. int ret;
  995. token = strsep(temp_buf, " ");
  996. if (!token) {
  997. pr_err("Token value is NULL in parse param\n");
  998. return -EINVAL;
  999. }
  1000. ret = kstrtoint(token, 0, addr);
  1001. if (ret < 0) {
  1002. pr_err("Parameter value not read correctly\n");
  1003. return ret;
  1004. }
  1005. return 0;
  1006. }
  1007. static ssize_t ipclite_test_params_write(struct kobject *kobj,
  1008. struct kobj_attribute *attr,
  1009. const char *buf, size_t count)
  1010. {
  1011. char *temp_buf = kmalloc(strlen(buf)+1, GFP_KERNEL);
  1012. char *temp_ptr = temp_buf;
  1013. int ret, param = 0;
  1014. if (!temp_buf) {
  1015. pr_err("Memory not allocated\n");
  1016. return -EINVAL;
  1017. }
  1018. ret = strscpy(temp_buf, buf, strlen(buf)+1);
  1019. if (ret < 0) {
  1020. pr_err("User input is too large\n");
  1021. goto exit;
  1022. }
  1023. ret = parse_param(&temp_buf, &param);
  1024. if (ret != 0)
  1025. goto exit;
  1026. if (param == ENABLED_CORES) {
  1027. ret = parse_param(&temp_buf, &data->test_params.enabled_cores);
  1028. if (ret == 0)
  1029. ipclite_test_set_enabled_cores();
  1030. goto exit;
  1031. } else
  1032. data->test_params.selected_test_case = param;
  1033. switch (data->test_params.selected_test_case) {
  1034. case PING:
  1035. ret = parse_param(&temp_buf, &data->test_params.selected_senders);
  1036. if (ret != 0)
  1037. break;
  1038. ipclite_test_set_senders();
  1039. ret = parse_param(&temp_buf, &data->test_params.selected_receivers);
  1040. if (ret != 0)
  1041. break;
  1042. ipclite_test_set_receivers();
  1043. ret = parse_param(&temp_buf, &data->test_params.num_pings);
  1044. if (ret != 0)
  1045. break;
  1046. ipclite_test_set_num_pings();
  1047. ret = parse_param(&temp_buf, &data->test_params.wait);
  1048. if (ret != 0)
  1049. break;
  1050. ipclite_test_set_wait();
  1051. ret = parse_param(&temp_buf, &data->test_params.num_itr);
  1052. if (ret != 0)
  1053. break;
  1054. ipclite_test_set_num_itr();
  1055. ret = parse_param(&temp_buf, &data->test_params.num_thread);
  1056. if (ret != 0)
  1057. break;
  1058. ipclite_test_set_num_threads();
  1059. break;
  1060. case NEGATIVE:
  1061. ret = parse_param(&temp_buf, &data->test_params.selected_senders);
  1062. if (ret != 0)
  1063. break;
  1064. ipclite_test_set_senders();
  1065. ret = parse_param(&temp_buf, &data->test_params.selected_receivers);
  1066. if (ret != 0)
  1067. break;
  1068. ipclite_test_set_receivers();
  1069. break;
  1070. case GLOBAL_ATOMIC:
  1071. ret = parse_param(&temp_buf, &data->test_params.selected_receivers);
  1072. if (ret != 0)
  1073. break;
  1074. ipclite_test_set_receivers();
  1075. ret = parse_param(&temp_buf, &data->test_params.num_itr);
  1076. if (ret != 0)
  1077. break;
  1078. ipclite_test_set_num_itr();
  1079. break;
  1080. case DEBUG:
  1081. ret = parse_param(&temp_buf, &data->test_params.selected_senders);
  1082. if (ret != 0)
  1083. break;
  1084. ipclite_test_set_senders();
  1085. break;
  1086. case SSR:
  1087. ret = parse_param(&temp_buf, &data->test_params.selected_senders);
  1088. if (ret != 0)
  1089. break;
  1090. ipclite_test_set_senders();
  1091. ret = parse_param(&temp_buf, &data->test_params.selected_receivers);
  1092. if (ret != 0)
  1093. break;
  1094. ipclite_test_set_receivers();
  1095. ret = parse_param(&temp_buf, &data->test_params.num_pings);
  1096. if (ret != 0)
  1097. break;
  1098. ipclite_test_set_num_pings();
  1099. break;
  1100. case HW_MUTEX:
  1101. ret = parse_param(&temp_buf, &data->test_params.selected_senders);
  1102. if (ret != 0)
  1103. break;
  1104. ipclite_test_set_senders();
  1105. ret = parse_param(&temp_buf, &data->test_params.selected_receivers);
  1106. if (ret != 0)
  1107. break;
  1108. ipclite_test_set_receivers();
  1109. break;
  1110. default:
  1111. pr_err("Wrong input provided\n");
  1112. goto exit;
  1113. }
  1114. if (ret == 0)
  1115. ipclite_test_set_test();
  1116. exit:
  1117. kfree(temp_ptr);
  1118. return count;
  1119. }
  1120. static int ipclite_test_callback_fn(unsigned int client_id, long long msg,
  1121. void *data_ptr)
  1122. {
  1123. struct ipclite_test_data *data = data_ptr;
  1124. uint64_t header, parameter_info, test_info, payload_info,
  1125. start_stop_info, pass_fail_info;
  1126. uint64_t reply_macro;
  1127. int ret = 0;
  1128. /* Unpack the different bit fields from message value */
  1129. header = (msg & GENMASK(63, 56))>>56;
  1130. parameter_info = (msg & GENMASK(55, 48))>>48;
  1131. test_info = (msg & GENMASK(47, 40))>>40;
  1132. payload_info = (msg & GENMASK(39, 16))>>16;
  1133. start_stop_info = (msg & GENMASK(15, 8))>>8;
  1134. pass_fail_info = (msg & GENMASK(7, 0));
  1135. if (!data) {
  1136. pr_err("Callback data pointer not loaded successfully\n");
  1137. return -EFAULT;
  1138. }
  1139. data->client_id = client_id;
  1140. if (header != IPCLITE_TEST_HEADER) {
  1141. pr_err("Corrupted message packed received\n");
  1142. return -EINVAL;
  1143. }
  1144. pr_debug("The message received is %lx\n", msg);
  1145. switch (test_info) {
  1146. case PING:
  1147. case NEGATIVE:
  1148. case DEBUG:
  1149. if (payload_info == PING_SEND) {
  1150. reply_macro = get_param_macro(TEST_CASE,
  1151. test_info,
  1152. PING_REPLY,
  1153. 0, 0);
  1154. ipclite_test_msg_send(client_id, reply_macro);
  1155. break;
  1156. }
  1157. if (payload_info == PING_REPLY) {
  1158. ping_receive(data);
  1159. break;
  1160. }
  1161. if (pass_fail_info == IPCLITE_TEST_PASS)
  1162. pr_info("Test passed on core %s\n", core_name[client_id]);
  1163. else if (pass_fail_info == IPCLITE_TEST_FAIL)
  1164. pr_info("Test failed on core %s\n", core_name[client_id]);
  1165. if (start_stop_info == IPCLITE_TEST_STOP) {
  1166. ++cores_completed;
  1167. if (cores_completed == data->test_params.num_senders)
  1168. pr_info("Test completed on all cores\n");
  1169. if (is_selected_sender(IPCMEM_APPS))
  1170. wake_up_interruptible(&core_wq);
  1171. else
  1172. complete(&test_done);
  1173. }
  1174. break;
  1175. case HW_MUTEX:
  1176. if (start_stop_info == IPCLITE_TEST_START) {
  1177. ret = ipclite_hw_mutex_release();
  1178. if (ret == 0)
  1179. *((int *)data->global_memory->virt_base) = IPCMEM_APPS;
  1180. reply_macro = get_param_macro(TEST_CASE,
  1181. test_info,
  1182. HW_MUTEX_RELEASE,
  1183. IPCLITE_TEST_STOP, 0);
  1184. ipclite_test_msg_send(client_id, reply_macro);
  1185. }
  1186. if (pass_fail_info == IPCLITE_TEST_PASS)
  1187. pr_info("HW Unlock Test passed on core %s\n",
  1188. core_name[client_id]);
  1189. else if (pass_fail_info == IPCLITE_TEST_FAIL)
  1190. pr_info("HW Unlock Test failed on core %s\n",
  1191. core_name[client_id]);
  1192. if (start_stop_info == IPCLITE_TEST_STOP)
  1193. complete(&test_done);
  1194. break;
  1195. case SSR:
  1196. if (payload_info == PING_SEND) {
  1197. reply_macro = get_param_macro(TEST_CASE,
  1198. test_info,
  1199. PING_REPLY,
  1200. 0, 0);
  1201. data->pings_received[client_id]++;
  1202. ipclite_test_msg_send(client_id, reply_macro);
  1203. if (data->pings_received[client_id] == data->test_params.num_pings) {
  1204. pr_info("Waking up ssr_wakeup_check_thread.\n");
  1205. pr_info("Signaling other cores to make sure there is no other crash\n");
  1206. wakeup_check.run = true;
  1207. wake_up_interruptible(&wakeup_check.wq);
  1208. bg_pings.run = true;
  1209. wake_up_interruptible(&bg_pings.wq);
  1210. }
  1211. }
  1212. if (payload_info == SSR_WAKEUP) {
  1213. if (start_stop_info == IPCLITE_TEST_STOP) {
  1214. ssr_complete = true;
  1215. pr_info("%s wakeup completed\n",
  1216. core_name[client_id]);
  1217. wake_up_interruptible(&ssr_wq);
  1218. }
  1219. }
  1220. if (pass_fail_info == IPCLITE_TEST_PASS)
  1221. pr_info("Test %d passed on core %s\n",
  1222. test_info, core_name[client_id]);
  1223. else if (pass_fail_info == IPCLITE_TEST_FAIL)
  1224. pr_info("Test %d failed on core %s\n",
  1225. test_info, core_name[client_id]);
  1226. break;
  1227. case GLOBAL_ATOMIC:
  1228. if (start_stop_info == IPCLITE_TEST_STOP) {
  1229. pr_debug("%s completed Global Atomics Test.\n",
  1230. core_name[client_id]);
  1231. if (payload_info == GLOBAL_ATOMICS_SET_CLR)
  1232. threads_completed++;
  1233. else
  1234. threads_completed += 2;
  1235. wake_up_interruptible(&thread_wq);
  1236. }
  1237. break;
  1238. default:
  1239. pr_info("Wrong input given\n");
  1240. }
  1241. return 0;
  1242. }
  1243. struct kobj_attribute ipclite_test_params = __ATTR(ipclite_test_params,
  1244. 0660,
  1245. NULL,
  1246. ipclite_test_params_write);
  1247. static int ipclite_test_sysfs_node_setup(void)
  1248. {
  1249. int ret = 0;
  1250. sysfs_dir = kobject_create_and_add("ipclite_test", kernel_kobj);
  1251. if (sysfs_dir == NULL) {
  1252. pr_err("Cannot create sysfs directory\n");
  1253. return -ENOENT;
  1254. }
  1255. ret = sysfs_create_file(sysfs_dir, &ipclite_test_params.attr);
  1256. if (ret) {
  1257. pr_err("Cannot create sysfs file for ipclite test module. Error - %d\n",
  1258. ret);
  1259. return -ENOENT;
  1260. }
  1261. return 0;
  1262. }
  1263. static int __init ipclite_test_init(void)
  1264. {
  1265. int ret = 0;
  1266. data = kzalloc(sizeof(*data), GFP_KERNEL);
  1267. if (!data)
  1268. return -ENOMEM;
  1269. data->global_memory = kzalloc(sizeof(*(data->global_memory)),
  1270. GFP_KERNEL);
  1271. if (!data->global_memory) {
  1272. kfree(data);
  1273. data = NULL;
  1274. return -ENOMEM;
  1275. }
  1276. ret = get_global_partition_info(data->global_memory);
  1277. if (ret != 0) {
  1278. pr_err("Unable to load global partition information\n");
  1279. goto bail;
  1280. }
  1281. ret = ipclite_register_test_client(ipclite_test_callback_fn, data);
  1282. if (ret != 0) {
  1283. pr_err("Could not register client\n");
  1284. goto bail;
  1285. }
  1286. ret = ipclite_test_sysfs_node_setup();
  1287. if (ret != 0) {
  1288. pr_err("Failed to create sysfs interface\n");
  1289. goto bail;
  1290. }
  1291. init_test_params();
  1292. return 0;
  1293. bail:
  1294. kfree(data->global_memory);
  1295. kfree(data);
  1296. data = NULL;
  1297. return ret;
  1298. }
  1299. static void __exit ipclite_test_exit(void)
  1300. {
  1301. pr_info("Removing IPCLite Test Module\n");
  1302. sysfs_remove_file(sysfs_dir, &ipclite_test_params.attr);
  1303. kobject_put(sysfs_dir);
  1304. kfree(data->global_memory);
  1305. kfree(data);
  1306. data = NULL;
  1307. }
  1308. module_init(ipclite_test_init);
  1309. module_exit(ipclite_test_exit);
  1310. MODULE_LICENSE("GPL v2");