native.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. /*
  2. * Copyright 2014 IBM Corp.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/spinlock.h>
  10. #include <linux/sched.h>
  11. #include <linux/slab.h>
  12. #include <linux/sched.h>
  13. #include <linux/mutex.h>
  14. #include <linux/mm.h>
  15. #include <linux/uaccess.h>
  16. #include <asm/synch.h>
  17. #include <misc/cxl.h>
  18. #include "cxl.h"
  19. static int afu_control(struct cxl_afu *afu, u64 command,
  20. u64 result, u64 mask, bool enabled)
  21. {
  22. u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  23. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  24. spin_lock(&afu->afu_cntl_lock);
  25. pr_devel("AFU command starting: %llx\n", command);
  26. cxl_p2n_write(afu, CXL_AFU_Cntl_An, AFU_Cntl | command);
  27. AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  28. while ((AFU_Cntl & mask) != result) {
  29. if (time_after_eq(jiffies, timeout)) {
  30. dev_warn(&afu->dev, "WARNING: AFU control timed out!\n");
  31. spin_unlock(&afu->afu_cntl_lock);
  32. return -EBUSY;
  33. }
  34. pr_devel_ratelimited("AFU control... (0x%.16llx)\n",
  35. AFU_Cntl | command);
  36. cpu_relax();
  37. AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  38. };
  39. pr_devel("AFU command complete: %llx\n", command);
  40. afu->enabled = enabled;
  41. spin_unlock(&afu->afu_cntl_lock);
  42. return 0;
  43. }
  44. static int afu_enable(struct cxl_afu *afu)
  45. {
  46. pr_devel("AFU enable request\n");
  47. return afu_control(afu, CXL_AFU_Cntl_An_E,
  48. CXL_AFU_Cntl_An_ES_Enabled,
  49. CXL_AFU_Cntl_An_ES_MASK, true);
  50. }
  51. int cxl_afu_disable(struct cxl_afu *afu)
  52. {
  53. pr_devel("AFU disable request\n");
  54. return afu_control(afu, 0, CXL_AFU_Cntl_An_ES_Disabled,
  55. CXL_AFU_Cntl_An_ES_MASK, false);
  56. }
  57. /* This will disable as well as reset */
  58. int cxl_afu_reset(struct cxl_afu *afu)
  59. {
  60. pr_devel("AFU reset request\n");
  61. return afu_control(afu, CXL_AFU_Cntl_An_RA,
  62. CXL_AFU_Cntl_An_RS_Complete | CXL_AFU_Cntl_An_ES_Disabled,
  63. CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
  64. false);
  65. }
  66. static int afu_check_and_enable(struct cxl_afu *afu)
  67. {
  68. if (afu->enabled)
  69. return 0;
  70. return afu_enable(afu);
  71. }
  72. int cxl_psl_purge(struct cxl_afu *afu)
  73. {
  74. u64 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
  75. u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  76. u64 dsisr, dar;
  77. u64 start, end;
  78. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  79. pr_devel("PSL purge request\n");
  80. if ((AFU_Cntl & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
  81. WARN(1, "psl_purge request while AFU not disabled!\n");
  82. cxl_afu_disable(afu);
  83. }
  84. cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
  85. PSL_CNTL | CXL_PSL_SCNTL_An_Pc);
  86. start = local_clock();
  87. PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
  88. while ((PSL_CNTL & CXL_PSL_SCNTL_An_Ps_MASK)
  89. == CXL_PSL_SCNTL_An_Ps_Pending) {
  90. if (time_after_eq(jiffies, timeout)) {
  91. dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n");
  92. return -EBUSY;
  93. }
  94. dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
  95. pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%.16llx PSL_DSISR: 0x%.16llx\n", PSL_CNTL, dsisr);
  96. if (dsisr & CXL_PSL_DSISR_TRANS) {
  97. dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
  98. dev_notice(&afu->dev, "PSL purge terminating pending translation, DSISR: 0x%.16llx, DAR: 0x%.16llx\n", dsisr, dar);
  99. cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
  100. } else if (dsisr) {
  101. dev_notice(&afu->dev, "PSL purge acknowledging pending non-translation fault, DSISR: 0x%.16llx\n", dsisr);
  102. cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
  103. } else {
  104. cpu_relax();
  105. }
  106. PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
  107. };
  108. end = local_clock();
  109. pr_devel("PSL purged in %lld ns\n", end - start);
  110. cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
  111. PSL_CNTL & ~CXL_PSL_SCNTL_An_Pc);
  112. return 0;
  113. }
  114. static int spa_max_procs(int spa_size)
  115. {
  116. /*
  117. * From the CAIA:
  118. * end_of_SPA_area = SPA_Base + ((n+4) * 128) + (( ((n*8) + 127) >> 7) * 128) + 255
  119. * Most of that junk is really just an overly-complicated way of saying
  120. * the last 256 bytes are __aligned(128), so it's really:
  121. * end_of_SPA_area = end_of_PSL_queue_area + __aligned(128) 255
  122. * and
  123. * end_of_PSL_queue_area = SPA_Base + ((n+4) * 128) + (n*8) - 1
  124. * so
  125. * sizeof(SPA) = ((n+4) * 128) + (n*8) + __aligned(128) 256
  126. * Ignore the alignment (which is safe in this case as long as we are
  127. * careful with our rounding) and solve for n:
  128. */
  129. return ((spa_size / 8) - 96) / 17;
  130. }
  131. static int alloc_spa(struct cxl_afu *afu)
  132. {
  133. u64 spap;
  134. /* Work out how many pages to allocate */
  135. afu->spa_order = 0;
  136. do {
  137. afu->spa_order++;
  138. afu->spa_size = (1 << afu->spa_order) * PAGE_SIZE;
  139. afu->spa_max_procs = spa_max_procs(afu->spa_size);
  140. } while (afu->spa_max_procs < afu->num_procs);
  141. WARN_ON(afu->spa_size > 0x100000); /* Max size supported by the hardware */
  142. if (!(afu->spa = (struct cxl_process_element *)
  143. __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->spa_order))) {
  144. pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n");
  145. return -ENOMEM;
  146. }
  147. pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n",
  148. 1<<afu->spa_order, afu->spa_max_procs, afu->num_procs);
  149. afu->sw_command_status = (__be64 *)((char *)afu->spa +
  150. ((afu->spa_max_procs + 3) * 128));
  151. spap = virt_to_phys(afu->spa) & CXL_PSL_SPAP_Addr;
  152. spap |= ((afu->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size;
  153. spap |= CXL_PSL_SPAP_V;
  154. pr_devel("cxl: SPA allocated at 0x%p. Max processes: %i, sw_command_status: 0x%p CXL_PSL_SPAP_An=0x%016llx\n", afu->spa, afu->spa_max_procs, afu->sw_command_status, spap);
  155. cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap);
  156. return 0;
  157. }
  158. static void release_spa(struct cxl_afu *afu)
  159. {
  160. free_pages((unsigned long) afu->spa, afu->spa_order);
  161. }
  162. int cxl_tlb_slb_invalidate(struct cxl *adapter)
  163. {
  164. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  165. pr_devel("CXL adapter wide TLBIA & SLBIA\n");
  166. cxl_p1_write(adapter, CXL_PSL_AFUSEL, CXL_PSL_AFUSEL_A);
  167. cxl_p1_write(adapter, CXL_PSL_TLBIA, CXL_TLB_SLB_IQ_ALL);
  168. while (cxl_p1_read(adapter, CXL_PSL_TLBIA) & CXL_TLB_SLB_P) {
  169. if (time_after_eq(jiffies, timeout)) {
  170. dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
  171. return -EBUSY;
  172. }
  173. cpu_relax();
  174. }
  175. cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_ALL);
  176. while (cxl_p1_read(adapter, CXL_PSL_SLBIA) & CXL_TLB_SLB_P) {
  177. if (time_after_eq(jiffies, timeout)) {
  178. dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
  179. return -EBUSY;
  180. }
  181. cpu_relax();
  182. }
  183. return 0;
  184. }
  185. int cxl_afu_slbia(struct cxl_afu *afu)
  186. {
  187. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  188. pr_devel("cxl_afu_slbia issuing SLBIA command\n");
  189. cxl_p2n_write(afu, CXL_SLBIA_An, CXL_TLB_SLB_IQ_ALL);
  190. while (cxl_p2n_read(afu, CXL_SLBIA_An) & CXL_TLB_SLB_P) {
  191. if (time_after_eq(jiffies, timeout)) {
  192. dev_warn(&afu->dev, "WARNING: CXL AFU SLBIA timed out!\n");
  193. return -EBUSY;
  194. }
  195. cpu_relax();
  196. }
  197. return 0;
  198. }
  199. static int cxl_write_sstp(struct cxl_afu *afu, u64 sstp0, u64 sstp1)
  200. {
  201. int rc;
  202. /* 1. Disable SSTP by writing 0 to SSTP1[V] */
  203. cxl_p2n_write(afu, CXL_SSTP1_An, 0);
  204. /* 2. Invalidate all SLB entries */
  205. if ((rc = cxl_afu_slbia(afu)))
  206. return rc;
  207. /* 3. Set SSTP0_An */
  208. cxl_p2n_write(afu, CXL_SSTP0_An, sstp0);
  209. /* 4. Set SSTP1_An */
  210. cxl_p2n_write(afu, CXL_SSTP1_An, sstp1);
  211. return 0;
  212. }
  213. /* Using per slice version may improve performance here. (ie. SLBIA_An) */
  214. static void slb_invalid(struct cxl_context *ctx)
  215. {
  216. struct cxl *adapter = ctx->afu->adapter;
  217. u64 slbia;
  218. WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex));
  219. cxl_p1_write(adapter, CXL_PSL_LBISEL,
  220. ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
  221. be32_to_cpu(ctx->elem->lpid));
  222. cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
  223. while (1) {
  224. slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
  225. if (!(slbia & CXL_TLB_SLB_P))
  226. break;
  227. cpu_relax();
  228. }
  229. }
  230. static int do_process_element_cmd(struct cxl_context *ctx,
  231. u64 cmd, u64 pe_state)
  232. {
  233. u64 state;
  234. WARN_ON(!ctx->afu->enabled);
  235. ctx->elem->software_state = cpu_to_be32(pe_state);
  236. smp_wmb();
  237. *(ctx->afu->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe);
  238. smp_mb();
  239. cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
  240. while (1) {
  241. state = be64_to_cpup(ctx->afu->sw_command_status);
  242. if (state == ~0ULL) {
  243. pr_err("cxl: Error adding process element to AFU\n");
  244. return -1;
  245. }
  246. if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) ==
  247. (cmd | (cmd >> 16) | ctx->pe))
  248. break;
  249. /*
  250. * The command won't finish in the PSL if there are
  251. * outstanding DSIs. Hence we need to yield here in
  252. * case there are outstanding DSIs that we need to
  253. * service. Tuning possiblity: we could wait for a
  254. * while before sched
  255. */
  256. schedule();
  257. }
  258. return 0;
  259. }
  260. static int add_process_element(struct cxl_context *ctx)
  261. {
  262. int rc = 0;
  263. mutex_lock(&ctx->afu->spa_mutex);
  264. pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe);
  265. if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V)))
  266. ctx->pe_inserted = true;
  267. pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe);
  268. mutex_unlock(&ctx->afu->spa_mutex);
  269. return rc;
  270. }
  271. static int terminate_process_element(struct cxl_context *ctx)
  272. {
  273. int rc = 0;
  274. /* fast path terminate if it's already invalid */
  275. if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
  276. return rc;
  277. mutex_lock(&ctx->afu->spa_mutex);
  278. pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
  279. rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
  280. CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
  281. ctx->elem->software_state = 0; /* Remove Valid bit */
  282. pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
  283. mutex_unlock(&ctx->afu->spa_mutex);
  284. return rc;
  285. }
  286. static int remove_process_element(struct cxl_context *ctx)
  287. {
  288. int rc = 0;
  289. mutex_lock(&ctx->afu->spa_mutex);
  290. pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
  291. if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0)))
  292. ctx->pe_inserted = false;
  293. slb_invalid(ctx);
  294. pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
  295. mutex_unlock(&ctx->afu->spa_mutex);
  296. return rc;
  297. }
  298. static void assign_psn_space(struct cxl_context *ctx)
  299. {
  300. if (!ctx->afu->pp_size || ctx->master) {
  301. ctx->psn_phys = ctx->afu->psn_phys;
  302. ctx->psn_size = ctx->afu->adapter->ps_size;
  303. } else {
  304. ctx->psn_phys = ctx->afu->psn_phys +
  305. (ctx->afu->pp_offset + ctx->afu->pp_size * ctx->pe);
  306. ctx->psn_size = ctx->afu->pp_size;
  307. }
  308. }
  309. static int activate_afu_directed(struct cxl_afu *afu)
  310. {
  311. int rc;
  312. dev_info(&afu->dev, "Activating AFU directed mode\n");
  313. if (alloc_spa(afu))
  314. return -ENOMEM;
  315. cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_AFU);
  316. cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
  317. cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
  318. afu->current_mode = CXL_MODE_DIRECTED;
  319. afu->num_procs = afu->max_procs_virtualised;
  320. if ((rc = cxl_chardev_m_afu_add(afu)))
  321. return rc;
  322. if ((rc = cxl_sysfs_afu_m_add(afu)))
  323. goto err;
  324. if ((rc = cxl_chardev_s_afu_add(afu)))
  325. goto err1;
  326. return 0;
  327. err1:
  328. cxl_sysfs_afu_m_remove(afu);
  329. err:
  330. cxl_chardev_afu_remove(afu);
  331. return rc;
  332. }
  333. #ifdef CONFIG_CPU_LITTLE_ENDIAN
  334. #define set_endian(sr) ((sr) |= CXL_PSL_SR_An_LE)
  335. #else
  336. #define set_endian(sr) ((sr) &= ~(CXL_PSL_SR_An_LE))
  337. #endif
  338. static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
  339. {
  340. u64 sr;
  341. int r, result;
  342. assign_psn_space(ctx);
  343. ctx->elem->ctxtime = 0; /* disable */
  344. ctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));
  345. ctx->elem->haurp = 0; /* disable */
  346. ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1));
  347. sr = CXL_PSL_SR_An_SC;
  348. if (ctx->master)
  349. sr |= CXL_PSL_SR_An_MP;
  350. if (mfspr(SPRN_LPCR) & LPCR_TC)
  351. sr |= CXL_PSL_SR_An_TC;
  352. /* HV=0, PR=1, R=1 for userspace
  353. * For kernel contexts: this would need to change
  354. */
  355. sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
  356. set_endian(sr);
  357. sr &= ~(CXL_PSL_SR_An_HV);
  358. if (!test_tsk_thread_flag(current, TIF_32BIT))
  359. sr |= CXL_PSL_SR_An_SF;
  360. ctx->elem->common.pid = cpu_to_be32(current->pid);
  361. ctx->elem->common.tid = 0;
  362. ctx->elem->sr = cpu_to_be64(sr);
  363. ctx->elem->common.csrp = 0; /* disable */
  364. ctx->elem->common.aurp0 = 0; /* disable */
  365. ctx->elem->common.aurp1 = 0; /* disable */
  366. cxl_prefault(ctx, wed);
  367. ctx->elem->common.sstp0 = cpu_to_be64(ctx->sstp0);
  368. ctx->elem->common.sstp1 = cpu_to_be64(ctx->sstp1);
  369. for (r = 0; r < CXL_IRQ_RANGES; r++) {
  370. ctx->elem->ivte_offsets[r] = cpu_to_be16(ctx->irqs.offset[r]);
  371. ctx->elem->ivte_ranges[r] = cpu_to_be16(ctx->irqs.range[r]);
  372. }
  373. ctx->elem->common.amr = cpu_to_be64(amr);
  374. ctx->elem->common.wed = cpu_to_be64(wed);
  375. /* first guy needs to enable */
  376. if ((result = afu_check_and_enable(ctx->afu)))
  377. return result;
  378. add_process_element(ctx);
  379. return 0;
  380. }
  381. static int deactivate_afu_directed(struct cxl_afu *afu)
  382. {
  383. dev_info(&afu->dev, "Deactivating AFU directed mode\n");
  384. afu->current_mode = 0;
  385. afu->num_procs = 0;
  386. cxl_sysfs_afu_m_remove(afu);
  387. cxl_chardev_afu_remove(afu);
  388. cxl_afu_reset(afu);
  389. cxl_afu_disable(afu);
  390. cxl_psl_purge(afu);
  391. release_spa(afu);
  392. return 0;
  393. }
  394. static int activate_dedicated_process(struct cxl_afu *afu)
  395. {
  396. dev_info(&afu->dev, "Activating dedicated process mode\n");
  397. cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_Process);
  398. cxl_p1n_write(afu, CXL_PSL_CtxTime_An, 0); /* disable */
  399. cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0); /* disable */
  400. cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
  401. cxl_p1n_write(afu, CXL_PSL_LPID_An, mfspr(SPRN_LPID));
  402. cxl_p1n_write(afu, CXL_HAURP_An, 0); /* disable */
  403. cxl_p1n_write(afu, CXL_PSL_SDR_An, mfspr(SPRN_SDR1));
  404. cxl_p2n_write(afu, CXL_CSRP_An, 0); /* disable */
  405. cxl_p2n_write(afu, CXL_AURP0_An, 0); /* disable */
  406. cxl_p2n_write(afu, CXL_AURP1_An, 0); /* disable */
  407. afu->current_mode = CXL_MODE_DEDICATED;
  408. afu->num_procs = 1;
  409. return cxl_chardev_d_afu_add(afu);
  410. }
  411. static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
  412. {
  413. struct cxl_afu *afu = ctx->afu;
  414. u64 sr;
  415. int rc;
  416. sr = CXL_PSL_SR_An_SC;
  417. set_endian(sr);
  418. if (ctx->master)
  419. sr |= CXL_PSL_SR_An_MP;
  420. if (mfspr(SPRN_LPCR) & LPCR_TC)
  421. sr |= CXL_PSL_SR_An_TC;
  422. sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
  423. if (!test_tsk_thread_flag(current, TIF_32BIT))
  424. sr |= CXL_PSL_SR_An_SF;
  425. cxl_p2n_write(afu, CXL_PSL_PID_TID_An, (u64)current->pid << 32);
  426. cxl_p1n_write(afu, CXL_PSL_SR_An, sr);
  427. if ((rc = cxl_write_sstp(afu, ctx->sstp0, ctx->sstp1)))
  428. return rc;
  429. cxl_prefault(ctx, wed);
  430. cxl_p1n_write(afu, CXL_PSL_IVTE_Offset_An,
  431. (((u64)ctx->irqs.offset[0] & 0xffff) << 48) |
  432. (((u64)ctx->irqs.offset[1] & 0xffff) << 32) |
  433. (((u64)ctx->irqs.offset[2] & 0xffff) << 16) |
  434. ((u64)ctx->irqs.offset[3] & 0xffff));
  435. cxl_p1n_write(afu, CXL_PSL_IVTE_Limit_An, (u64)
  436. (((u64)ctx->irqs.range[0] & 0xffff) << 48) |
  437. (((u64)ctx->irqs.range[1] & 0xffff) << 32) |
  438. (((u64)ctx->irqs.range[2] & 0xffff) << 16) |
  439. ((u64)ctx->irqs.range[3] & 0xffff));
  440. cxl_p2n_write(afu, CXL_PSL_AMR_An, amr);
  441. /* master only context for dedicated */
  442. assign_psn_space(ctx);
  443. if ((rc = cxl_afu_reset(afu)))
  444. return rc;
  445. cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
  446. return afu_enable(afu);
  447. }
  448. static int deactivate_dedicated_process(struct cxl_afu *afu)
  449. {
  450. dev_info(&afu->dev, "Deactivating dedicated process mode\n");
  451. afu->current_mode = 0;
  452. afu->num_procs = 0;
  453. cxl_chardev_afu_remove(afu);
  454. return 0;
  455. }
  456. int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
  457. {
  458. if (mode == CXL_MODE_DIRECTED)
  459. return deactivate_afu_directed(afu);
  460. if (mode == CXL_MODE_DEDICATED)
  461. return deactivate_dedicated_process(afu);
  462. return 0;
  463. }
  464. int cxl_afu_deactivate_mode(struct cxl_afu *afu)
  465. {
  466. return _cxl_afu_deactivate_mode(afu, afu->current_mode);
  467. }
  468. int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
  469. {
  470. if (!mode)
  471. return 0;
  472. if (!(mode & afu->modes_supported))
  473. return -EINVAL;
  474. if (mode == CXL_MODE_DIRECTED)
  475. return activate_afu_directed(afu);
  476. if (mode == CXL_MODE_DEDICATED)
  477. return activate_dedicated_process(afu);
  478. return -EINVAL;
  479. }
  480. int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
  481. {
  482. ctx->kernel = kernel;
  483. if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
  484. return attach_afu_directed(ctx, wed, amr);
  485. if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
  486. return attach_dedicated(ctx, wed, amr);
  487. return -EINVAL;
  488. }
  489. static inline int detach_process_native_dedicated(struct cxl_context *ctx)
  490. {
  491. cxl_afu_reset(ctx->afu);
  492. cxl_afu_disable(ctx->afu);
  493. cxl_psl_purge(ctx->afu);
  494. return 0;
  495. }
  496. /*
  497. * TODO: handle case when this is called inside a rcu_read_lock() which may
  498. * happen when we unbind the driver (ie. cxl_context_detach_all()) . Terminate
  499. * & remove use a mutex lock and schedule which will not good with lock held.
  500. * May need to write do_process_element_cmd() that handles outstanding page
  501. * faults synchronously.
  502. */
  503. static inline int detach_process_native_afu_directed(struct cxl_context *ctx)
  504. {
  505. if (!ctx->pe_inserted)
  506. return 0;
  507. if (terminate_process_element(ctx))
  508. return -1;
  509. if (remove_process_element(ctx))
  510. return -1;
  511. return 0;
  512. }
  513. int cxl_detach_process(struct cxl_context *ctx)
  514. {
  515. if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
  516. return detach_process_native_dedicated(ctx);
  517. return detach_process_native_afu_directed(ctx);
  518. }
  519. int cxl_get_irq(struct cxl_context *ctx, struct cxl_irq_info *info)
  520. {
  521. u64 pidtid;
  522. info->dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An);
  523. info->dar = cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An);
  524. info->dsr = cxl_p2n_read(ctx->afu, CXL_PSL_DSR_An);
  525. pidtid = cxl_p2n_read(ctx->afu, CXL_PSL_PID_TID_An);
  526. info->pid = pidtid >> 32;
  527. info->tid = pidtid & 0xffffffff;
  528. info->afu_err = cxl_p2n_read(ctx->afu, CXL_AFU_ERR_An);
  529. info->errstat = cxl_p2n_read(ctx->afu, CXL_PSL_ErrStat_An);
  530. return 0;
  531. }
  532. static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
  533. {
  534. u64 dsisr;
  535. pr_devel("RECOVERING FROM PSL ERROR... (0x%.16llx)\n", errstat);
  536. /* Clear PSL_DSISR[PE] */
  537. dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
  538. cxl_p2n_write(afu, CXL_PSL_DSISR_An, dsisr & ~CXL_PSL_DSISR_An_PE);
  539. /* Write 1s to clear error status bits */
  540. cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
  541. }
  542. int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
  543. {
  544. if (tfc)
  545. cxl_p2n_write(ctx->afu, CXL_PSL_TFC_An, tfc);
  546. if (psl_reset_mask)
  547. recover_psl_err(ctx->afu, psl_reset_mask);
  548. return 0;
  549. }
  550. int cxl_check_error(struct cxl_afu *afu)
  551. {
  552. return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
  553. }