native.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  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-base.h>
  18. #include "cxl.h"
  19. #include "trace.h"
  20. static int afu_control(struct cxl_afu *afu, u64 command,
  21. u64 result, u64 mask, bool enabled)
  22. {
  23. u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  24. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  25. int rc = 0;
  26. spin_lock(&afu->afu_cntl_lock);
  27. pr_devel("AFU command starting: %llx\n", command);
  28. trace_cxl_afu_ctrl(afu, command);
  29. cxl_p2n_write(afu, CXL_AFU_Cntl_An, AFU_Cntl | command);
  30. AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  31. while ((AFU_Cntl & mask) != result) {
  32. if (time_after_eq(jiffies, timeout)) {
  33. dev_warn(&afu->dev, "WARNING: AFU control timed out!\n");
  34. rc = -EBUSY;
  35. goto out;
  36. }
  37. if (!cxl_ops->link_ok(afu->adapter)) {
  38. afu->enabled = enabled;
  39. rc = -EIO;
  40. goto out;
  41. }
  42. pr_devel_ratelimited("AFU control... (0x%016llx)\n",
  43. AFU_Cntl | command);
  44. cpu_relax();
  45. AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  46. };
  47. pr_devel("AFU command complete: %llx\n", command);
  48. afu->enabled = enabled;
  49. out:
  50. trace_cxl_afu_ctrl_done(afu, command, rc);
  51. spin_unlock(&afu->afu_cntl_lock);
  52. return rc;
  53. }
  54. static int afu_enable(struct cxl_afu *afu)
  55. {
  56. pr_devel("AFU enable request\n");
  57. return afu_control(afu, CXL_AFU_Cntl_An_E,
  58. CXL_AFU_Cntl_An_ES_Enabled,
  59. CXL_AFU_Cntl_An_ES_MASK, true);
  60. }
  61. int cxl_afu_disable(struct cxl_afu *afu)
  62. {
  63. pr_devel("AFU disable request\n");
  64. return afu_control(afu, 0, CXL_AFU_Cntl_An_ES_Disabled,
  65. CXL_AFU_Cntl_An_ES_MASK, false);
  66. }
  67. /* This will disable as well as reset */
  68. static int native_afu_reset(struct cxl_afu *afu)
  69. {
  70. pr_devel("AFU reset request\n");
  71. return afu_control(afu, CXL_AFU_Cntl_An_RA,
  72. CXL_AFU_Cntl_An_RS_Complete | CXL_AFU_Cntl_An_ES_Disabled,
  73. CXL_AFU_Cntl_An_RS_MASK | CXL_AFU_Cntl_An_ES_MASK,
  74. false);
  75. }
  76. static int native_afu_check_and_enable(struct cxl_afu *afu)
  77. {
  78. if (!cxl_ops->link_ok(afu->adapter)) {
  79. WARN(1, "Refusing to enable afu while link down!\n");
  80. return -EIO;
  81. }
  82. if (afu->enabled)
  83. return 0;
  84. return afu_enable(afu);
  85. }
  86. int cxl_psl_purge(struct cxl_afu *afu)
  87. {
  88. u64 PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
  89. u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
  90. u64 dsisr, dar;
  91. u64 start, end;
  92. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  93. int rc = 0;
  94. trace_cxl_psl_ctrl(afu, CXL_PSL_SCNTL_An_Pc);
  95. pr_devel("PSL purge request\n");
  96. if (!cxl_ops->link_ok(afu->adapter)) {
  97. dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
  98. rc = -EIO;
  99. goto out;
  100. }
  101. if ((AFU_Cntl & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
  102. WARN(1, "psl_purge request while AFU not disabled!\n");
  103. cxl_afu_disable(afu);
  104. }
  105. cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
  106. PSL_CNTL | CXL_PSL_SCNTL_An_Pc);
  107. start = local_clock();
  108. PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
  109. while ((PSL_CNTL & CXL_PSL_SCNTL_An_Ps_MASK)
  110. == CXL_PSL_SCNTL_An_Ps_Pending) {
  111. if (time_after_eq(jiffies, timeout)) {
  112. dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n");
  113. rc = -EBUSY;
  114. goto out;
  115. }
  116. if (!cxl_ops->link_ok(afu->adapter)) {
  117. rc = -EIO;
  118. goto out;
  119. }
  120. dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
  121. pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%016llx PSL_DSISR: 0x%016llx\n", PSL_CNTL, dsisr);
  122. if (dsisr & CXL_PSL_DSISR_TRANS) {
  123. dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
  124. dev_notice(&afu->dev, "PSL purge terminating pending translation, DSISR: 0x%016llx, DAR: 0x%016llx\n", dsisr, dar);
  125. cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
  126. } else if (dsisr) {
  127. dev_notice(&afu->dev, "PSL purge acknowledging pending non-translation fault, DSISR: 0x%016llx\n", dsisr);
  128. cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
  129. } else {
  130. cpu_relax();
  131. }
  132. PSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);
  133. };
  134. end = local_clock();
  135. pr_devel("PSL purged in %lld ns\n", end - start);
  136. cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
  137. PSL_CNTL & ~CXL_PSL_SCNTL_An_Pc);
  138. out:
  139. trace_cxl_psl_ctrl_done(afu, CXL_PSL_SCNTL_An_Pc, rc);
  140. return rc;
  141. }
  142. static int spa_max_procs(int spa_size)
  143. {
  144. /*
  145. * From the CAIA:
  146. * end_of_SPA_area = SPA_Base + ((n+4) * 128) + (( ((n*8) + 127) >> 7) * 128) + 255
  147. * Most of that junk is really just an overly-complicated way of saying
  148. * the last 256 bytes are __aligned(128), so it's really:
  149. * end_of_SPA_area = end_of_PSL_queue_area + __aligned(128) 255
  150. * and
  151. * end_of_PSL_queue_area = SPA_Base + ((n+4) * 128) + (n*8) - 1
  152. * so
  153. * sizeof(SPA) = ((n+4) * 128) + (n*8) + __aligned(128) 256
  154. * Ignore the alignment (which is safe in this case as long as we are
  155. * careful with our rounding) and solve for n:
  156. */
  157. return ((spa_size / 8) - 96) / 17;
  158. }
  159. int cxl_alloc_spa(struct cxl_afu *afu)
  160. {
  161. /* Work out how many pages to allocate */
  162. afu->spa_order = 0;
  163. do {
  164. afu->spa_order++;
  165. afu->spa_size = (1 << afu->spa_order) * PAGE_SIZE;
  166. afu->spa_max_procs = spa_max_procs(afu->spa_size);
  167. } while (afu->spa_max_procs < afu->num_procs);
  168. WARN_ON(afu->spa_size > 0x100000); /* Max size supported by the hardware */
  169. if (!(afu->spa = (struct cxl_process_element *)
  170. __get_free_pages(GFP_KERNEL | __GFP_ZERO, afu->spa_order))) {
  171. pr_err("cxl_alloc_spa: Unable to allocate scheduled process area\n");
  172. return -ENOMEM;
  173. }
  174. pr_devel("spa pages: %i afu->spa_max_procs: %i afu->num_procs: %i\n",
  175. 1<<afu->spa_order, afu->spa_max_procs, afu->num_procs);
  176. return 0;
  177. }
  178. static void attach_spa(struct cxl_afu *afu)
  179. {
  180. u64 spap;
  181. afu->sw_command_status = (__be64 *)((char *)afu->spa +
  182. ((afu->spa_max_procs + 3) * 128));
  183. spap = virt_to_phys(afu->spa) & CXL_PSL_SPAP_Addr;
  184. spap |= ((afu->spa_size >> (12 - CXL_PSL_SPAP_Size_Shift)) - 1) & CXL_PSL_SPAP_Size;
  185. spap |= CXL_PSL_SPAP_V;
  186. 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);
  187. cxl_p1n_write(afu, CXL_PSL_SPAP_An, spap);
  188. }
  189. static inline void detach_spa(struct cxl_afu *afu)
  190. {
  191. cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0);
  192. }
  193. void cxl_release_spa(struct cxl_afu *afu)
  194. {
  195. if (afu->spa) {
  196. free_pages((unsigned long) afu->spa, afu->spa_order);
  197. afu->spa = NULL;
  198. }
  199. }
  200. int cxl_tlb_slb_invalidate(struct cxl *adapter)
  201. {
  202. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  203. pr_devel("CXL adapter wide TLBIA & SLBIA\n");
  204. cxl_p1_write(adapter, CXL_PSL_AFUSEL, CXL_PSL_AFUSEL_A);
  205. cxl_p1_write(adapter, CXL_PSL_TLBIA, CXL_TLB_SLB_IQ_ALL);
  206. while (cxl_p1_read(adapter, CXL_PSL_TLBIA) & CXL_TLB_SLB_P) {
  207. if (time_after_eq(jiffies, timeout)) {
  208. dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
  209. return -EBUSY;
  210. }
  211. if (!cxl_ops->link_ok(adapter))
  212. return -EIO;
  213. cpu_relax();
  214. }
  215. cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_ALL);
  216. while (cxl_p1_read(adapter, CXL_PSL_SLBIA) & CXL_TLB_SLB_P) {
  217. if (time_after_eq(jiffies, timeout)) {
  218. dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
  219. return -EBUSY;
  220. }
  221. if (!cxl_ops->link_ok(adapter))
  222. return -EIO;
  223. cpu_relax();
  224. }
  225. return 0;
  226. }
  227. static int cxl_write_sstp(struct cxl_afu *afu, u64 sstp0, u64 sstp1)
  228. {
  229. int rc;
  230. /* 1. Disable SSTP by writing 0 to SSTP1[V] */
  231. cxl_p2n_write(afu, CXL_SSTP1_An, 0);
  232. /* 2. Invalidate all SLB entries */
  233. if ((rc = cxl_afu_slbia(afu)))
  234. return rc;
  235. /* 3. Set SSTP0_An */
  236. cxl_p2n_write(afu, CXL_SSTP0_An, sstp0);
  237. /* 4. Set SSTP1_An */
  238. cxl_p2n_write(afu, CXL_SSTP1_An, sstp1);
  239. return 0;
  240. }
  241. /* Using per slice version may improve performance here. (ie. SLBIA_An) */
  242. static void slb_invalid(struct cxl_context *ctx)
  243. {
  244. struct cxl *adapter = ctx->afu->adapter;
  245. u64 slbia;
  246. WARN_ON(!mutex_is_locked(&ctx->afu->spa_mutex));
  247. cxl_p1_write(adapter, CXL_PSL_LBISEL,
  248. ((u64)be32_to_cpu(ctx->elem->common.pid) << 32) |
  249. be32_to_cpu(ctx->elem->lpid));
  250. cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
  251. while (1) {
  252. if (!cxl_ops->link_ok(adapter))
  253. break;
  254. slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
  255. if (!(slbia & CXL_TLB_SLB_P))
  256. break;
  257. cpu_relax();
  258. }
  259. }
  260. static int do_process_element_cmd(struct cxl_context *ctx,
  261. u64 cmd, u64 pe_state)
  262. {
  263. u64 state;
  264. unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
  265. int rc = 0;
  266. trace_cxl_llcmd(ctx, cmd);
  267. WARN_ON(!ctx->afu->enabled);
  268. ctx->elem->software_state = cpu_to_be32(pe_state);
  269. smp_wmb();
  270. *(ctx->afu->sw_command_status) = cpu_to_be64(cmd | 0 | ctx->pe);
  271. smp_mb();
  272. cxl_p1n_write(ctx->afu, CXL_PSL_LLCMD_An, cmd | ctx->pe);
  273. while (1) {
  274. if (time_after_eq(jiffies, timeout)) {
  275. dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n");
  276. rc = -EBUSY;
  277. goto out;
  278. }
  279. if (!cxl_ops->link_ok(ctx->afu->adapter)) {
  280. dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
  281. rc = -EIO;
  282. goto out;
  283. }
  284. state = be64_to_cpup(ctx->afu->sw_command_status);
  285. if (state == ~0ULL) {
  286. pr_err("cxl: Error adding process element to AFU\n");
  287. rc = -1;
  288. goto out;
  289. }
  290. if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) ==
  291. (cmd | (cmd >> 16) | ctx->pe))
  292. break;
  293. /*
  294. * The command won't finish in the PSL if there are
  295. * outstanding DSIs. Hence we need to yield here in
  296. * case there are outstanding DSIs that we need to
  297. * service. Tuning possiblity: we could wait for a
  298. * while before sched
  299. */
  300. schedule();
  301. }
  302. out:
  303. trace_cxl_llcmd_done(ctx, cmd, rc);
  304. return rc;
  305. }
  306. static int add_process_element(struct cxl_context *ctx)
  307. {
  308. int rc = 0;
  309. mutex_lock(&ctx->afu->spa_mutex);
  310. pr_devel("%s Adding pe: %i started\n", __func__, ctx->pe);
  311. if (!(rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_ADD, CXL_PE_SOFTWARE_STATE_V)))
  312. ctx->pe_inserted = true;
  313. pr_devel("%s Adding pe: %i finished\n", __func__, ctx->pe);
  314. mutex_unlock(&ctx->afu->spa_mutex);
  315. return rc;
  316. }
  317. static int terminate_process_element(struct cxl_context *ctx)
  318. {
  319. int rc = 0;
  320. /* fast path terminate if it's already invalid */
  321. if (!(ctx->elem->software_state & cpu_to_be32(CXL_PE_SOFTWARE_STATE_V)))
  322. return rc;
  323. mutex_lock(&ctx->afu->spa_mutex);
  324. pr_devel("%s Terminate pe: %i started\n", __func__, ctx->pe);
  325. /* We could be asked to terminate when the hw is down. That
  326. * should always succeed: it's not running if the hw has gone
  327. * away and is being reset.
  328. */
  329. if (cxl_ops->link_ok(ctx->afu->adapter))
  330. rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
  331. CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
  332. ctx->elem->software_state = 0; /* Remove Valid bit */
  333. pr_devel("%s Terminate pe: %i finished\n", __func__, ctx->pe);
  334. mutex_unlock(&ctx->afu->spa_mutex);
  335. return rc;
  336. }
  337. static int remove_process_element(struct cxl_context *ctx)
  338. {
  339. int rc = 0;
  340. mutex_lock(&ctx->afu->spa_mutex);
  341. pr_devel("%s Remove pe: %i started\n", __func__, ctx->pe);
  342. /* We could be asked to remove when the hw is down. Again, if
  343. * the hw is down, the PE is gone, so we succeed.
  344. */
  345. if (cxl_ops->link_ok(ctx->afu->adapter))
  346. rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
  347. if (!rc)
  348. ctx->pe_inserted = false;
  349. slb_invalid(ctx);
  350. pr_devel("%s Remove pe: %i finished\n", __func__, ctx->pe);
  351. mutex_unlock(&ctx->afu->spa_mutex);
  352. return rc;
  353. }
  354. void cxl_assign_psn_space(struct cxl_context *ctx)
  355. {
  356. if (!ctx->afu->pp_size || ctx->master) {
  357. ctx->psn_phys = ctx->afu->psn_phys;
  358. ctx->psn_size = ctx->afu->adapter->ps_size;
  359. } else {
  360. ctx->psn_phys = ctx->afu->psn_phys +
  361. (ctx->afu->pp_offset + ctx->afu->pp_size * ctx->pe);
  362. ctx->psn_size = ctx->afu->pp_size;
  363. }
  364. }
  365. static int activate_afu_directed(struct cxl_afu *afu)
  366. {
  367. int rc;
  368. dev_info(&afu->dev, "Activating AFU directed mode\n");
  369. afu->num_procs = afu->max_procs_virtualised;
  370. if (afu->spa == NULL) {
  371. if (cxl_alloc_spa(afu))
  372. return -ENOMEM;
  373. }
  374. attach_spa(afu);
  375. cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_AFU);
  376. cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
  377. cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
  378. afu->current_mode = CXL_MODE_DIRECTED;
  379. if ((rc = cxl_chardev_m_afu_add(afu)))
  380. return rc;
  381. if ((rc = cxl_sysfs_afu_m_add(afu)))
  382. goto err;
  383. if ((rc = cxl_chardev_s_afu_add(afu)))
  384. goto err1;
  385. return 0;
  386. err1:
  387. cxl_sysfs_afu_m_remove(afu);
  388. err:
  389. cxl_chardev_afu_remove(afu);
  390. return rc;
  391. }
  392. #ifdef CONFIG_CPU_LITTLE_ENDIAN
  393. #define set_endian(sr) ((sr) |= CXL_PSL_SR_An_LE)
  394. #else
  395. #define set_endian(sr) ((sr) &= ~(CXL_PSL_SR_An_LE))
  396. #endif
  397. static u64 calculate_sr(struct cxl_context *ctx)
  398. {
  399. u64 sr = 0;
  400. set_endian(sr);
  401. if (ctx->master)
  402. sr |= CXL_PSL_SR_An_MP;
  403. if (mfspr(SPRN_LPCR) & LPCR_TC)
  404. sr |= CXL_PSL_SR_An_TC;
  405. if (ctx->kernel) {
  406. sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF);
  407. sr |= CXL_PSL_SR_An_HV;
  408. } else {
  409. sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
  410. sr &= ~(CXL_PSL_SR_An_HV);
  411. if (!test_tsk_thread_flag(current, TIF_32BIT))
  412. sr |= CXL_PSL_SR_An_SF;
  413. }
  414. return sr;
  415. }
  416. static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
  417. {
  418. u32 pid;
  419. int r, result;
  420. cxl_assign_psn_space(ctx);
  421. ctx->elem->ctxtime = 0; /* disable */
  422. ctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));
  423. ctx->elem->haurp = 0; /* disable */
  424. ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1));
  425. pid = current->pid;
  426. if (ctx->kernel)
  427. pid = 0;
  428. ctx->elem->common.tid = 0;
  429. ctx->elem->common.pid = cpu_to_be32(pid);
  430. ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
  431. ctx->elem->common.csrp = 0; /* disable */
  432. ctx->elem->common.aurp0 = 0; /* disable */
  433. ctx->elem->common.aurp1 = 0; /* disable */
  434. cxl_prefault(ctx, wed);
  435. ctx->elem->common.sstp0 = cpu_to_be64(ctx->sstp0);
  436. ctx->elem->common.sstp1 = cpu_to_be64(ctx->sstp1);
  437. for (r = 0; r < CXL_IRQ_RANGES; r++) {
  438. ctx->elem->ivte_offsets[r] = cpu_to_be16(ctx->irqs.offset[r]);
  439. ctx->elem->ivte_ranges[r] = cpu_to_be16(ctx->irqs.range[r]);
  440. }
  441. ctx->elem->common.amr = cpu_to_be64(amr);
  442. ctx->elem->common.wed = cpu_to_be64(wed);
  443. /* first guy needs to enable */
  444. if ((result = cxl_ops->afu_check_and_enable(ctx->afu)))
  445. return result;
  446. return add_process_element(ctx);
  447. }
  448. static int deactivate_afu_directed(struct cxl_afu *afu)
  449. {
  450. dev_info(&afu->dev, "Deactivating AFU directed mode\n");
  451. afu->current_mode = 0;
  452. afu->num_procs = 0;
  453. cxl_sysfs_afu_m_remove(afu);
  454. cxl_chardev_afu_remove(afu);
  455. cxl_ops->afu_reset(afu);
  456. cxl_afu_disable(afu);
  457. cxl_psl_purge(afu);
  458. return 0;
  459. }
  460. static int activate_dedicated_process(struct cxl_afu *afu)
  461. {
  462. dev_info(&afu->dev, "Activating dedicated process mode\n");
  463. cxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_Process);
  464. cxl_p1n_write(afu, CXL_PSL_CtxTime_An, 0); /* disable */
  465. cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0); /* disable */
  466. cxl_p1n_write(afu, CXL_PSL_AMOR_An, 0xFFFFFFFFFFFFFFFFULL);
  467. cxl_p1n_write(afu, CXL_PSL_LPID_An, mfspr(SPRN_LPID));
  468. cxl_p1n_write(afu, CXL_HAURP_An, 0); /* disable */
  469. cxl_p1n_write(afu, CXL_PSL_SDR_An, mfspr(SPRN_SDR1));
  470. cxl_p2n_write(afu, CXL_CSRP_An, 0); /* disable */
  471. cxl_p2n_write(afu, CXL_AURP0_An, 0); /* disable */
  472. cxl_p2n_write(afu, CXL_AURP1_An, 0); /* disable */
  473. afu->current_mode = CXL_MODE_DEDICATED;
  474. afu->num_procs = 1;
  475. return cxl_chardev_d_afu_add(afu);
  476. }
  477. static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
  478. {
  479. struct cxl_afu *afu = ctx->afu;
  480. u64 pid;
  481. int rc;
  482. pid = (u64)current->pid << 32;
  483. if (ctx->kernel)
  484. pid = 0;
  485. cxl_p2n_write(afu, CXL_PSL_PID_TID_An, pid);
  486. cxl_p1n_write(afu, CXL_PSL_SR_An, calculate_sr(ctx));
  487. if ((rc = cxl_write_sstp(afu, ctx->sstp0, ctx->sstp1)))
  488. return rc;
  489. cxl_prefault(ctx, wed);
  490. cxl_p1n_write(afu, CXL_PSL_IVTE_Offset_An,
  491. (((u64)ctx->irqs.offset[0] & 0xffff) << 48) |
  492. (((u64)ctx->irqs.offset[1] & 0xffff) << 32) |
  493. (((u64)ctx->irqs.offset[2] & 0xffff) << 16) |
  494. ((u64)ctx->irqs.offset[3] & 0xffff));
  495. cxl_p1n_write(afu, CXL_PSL_IVTE_Limit_An, (u64)
  496. (((u64)ctx->irqs.range[0] & 0xffff) << 48) |
  497. (((u64)ctx->irqs.range[1] & 0xffff) << 32) |
  498. (((u64)ctx->irqs.range[2] & 0xffff) << 16) |
  499. ((u64)ctx->irqs.range[3] & 0xffff));
  500. cxl_p2n_write(afu, CXL_PSL_AMR_An, amr);
  501. /* master only context for dedicated */
  502. cxl_assign_psn_space(ctx);
  503. if ((rc = cxl_ops->afu_reset(afu)))
  504. return rc;
  505. cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
  506. return afu_enable(afu);
  507. }
  508. static int deactivate_dedicated_process(struct cxl_afu *afu)
  509. {
  510. dev_info(&afu->dev, "Deactivating dedicated process mode\n");
  511. afu->current_mode = 0;
  512. afu->num_procs = 0;
  513. cxl_chardev_afu_remove(afu);
  514. return 0;
  515. }
  516. static int native_afu_deactivate_mode(struct cxl_afu *afu, int mode)
  517. {
  518. if (mode == CXL_MODE_DIRECTED)
  519. return deactivate_afu_directed(afu);
  520. if (mode == CXL_MODE_DEDICATED)
  521. return deactivate_dedicated_process(afu);
  522. return 0;
  523. }
  524. static int native_afu_activate_mode(struct cxl_afu *afu, int mode)
  525. {
  526. if (!mode)
  527. return 0;
  528. if (!(mode & afu->modes_supported))
  529. return -EINVAL;
  530. if (!cxl_ops->link_ok(afu->adapter)) {
  531. WARN(1, "Device link is down, refusing to activate!\n");
  532. return -EIO;
  533. }
  534. if (mode == CXL_MODE_DIRECTED)
  535. return activate_afu_directed(afu);
  536. if (mode == CXL_MODE_DEDICATED)
  537. return activate_dedicated_process(afu);
  538. return -EINVAL;
  539. }
  540. static int native_attach_process(struct cxl_context *ctx, bool kernel,
  541. u64 wed, u64 amr)
  542. {
  543. if (!cxl_ops->link_ok(ctx->afu->adapter)) {
  544. WARN(1, "Device link is down, refusing to attach process!\n");
  545. return -EIO;
  546. }
  547. ctx->kernel = kernel;
  548. if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
  549. return attach_afu_directed(ctx, wed, amr);
  550. if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
  551. return attach_dedicated(ctx, wed, amr);
  552. return -EINVAL;
  553. }
  554. static inline int detach_process_native_dedicated(struct cxl_context *ctx)
  555. {
  556. cxl_ops->afu_reset(ctx->afu);
  557. cxl_afu_disable(ctx->afu);
  558. cxl_psl_purge(ctx->afu);
  559. return 0;
  560. }
  561. static inline int detach_process_native_afu_directed(struct cxl_context *ctx)
  562. {
  563. if (!ctx->pe_inserted)
  564. return 0;
  565. if (terminate_process_element(ctx))
  566. return -1;
  567. if (remove_process_element(ctx))
  568. return -1;
  569. return 0;
  570. }
  571. static int native_detach_process(struct cxl_context *ctx)
  572. {
  573. trace_cxl_detach(ctx);
  574. if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
  575. return detach_process_native_dedicated(ctx);
  576. return detach_process_native_afu_directed(ctx);
  577. }
  578. static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)
  579. {
  580. u64 pidtid;
  581. /* If the adapter has gone away, we can't get any meaningful
  582. * information.
  583. */
  584. if (!cxl_ops->link_ok(afu->adapter))
  585. return -EIO;
  586. info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
  587. info->dar = cxl_p2n_read(afu, CXL_PSL_DAR_An);
  588. info->dsr = cxl_p2n_read(afu, CXL_PSL_DSR_An);
  589. pidtid = cxl_p2n_read(afu, CXL_PSL_PID_TID_An);
  590. info->pid = pidtid >> 32;
  591. info->tid = pidtid & 0xffffffff;
  592. info->afu_err = cxl_p2n_read(afu, CXL_AFU_ERR_An);
  593. info->errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
  594. return 0;
  595. }
  596. static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,
  597. u64 dsisr, u64 errstat)
  598. {
  599. u64 fir1, fir2, fir_slice, serr, afu_debug;
  600. fir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR1);
  601. fir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL_FIR2);
  602. fir_slice = cxl_p1n_read(ctx->afu, CXL_PSL_FIR_SLICE_An);
  603. serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);
  604. afu_debug = cxl_p1n_read(ctx->afu, CXL_AFU_DEBUG_An);
  605. dev_crit(&ctx->afu->dev, "PSL ERROR STATUS: 0x%016llx\n", errstat);
  606. dev_crit(&ctx->afu->dev, "PSL_FIR1: 0x%016llx\n", fir1);
  607. dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2);
  608. dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
  609. dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
  610. dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
  611. dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
  612. cxl_stop_trace(ctx->afu->adapter);
  613. return cxl_ops->ack_irq(ctx, 0, errstat);
  614. }
  615. static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
  616. {
  617. if (irq_info->dsisr & CXL_PSL_DSISR_TRANS)
  618. cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);
  619. else
  620. cxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);
  621. return IRQ_HANDLED;
  622. }
  623. static irqreturn_t native_irq_multiplexed(int irq, void *data)
  624. {
  625. struct cxl_afu *afu = data;
  626. struct cxl_context *ctx;
  627. struct cxl_irq_info irq_info;
  628. int ph = cxl_p2n_read(afu, CXL_PSL_PEHandle_An) & 0xffff;
  629. int ret;
  630. if ((ret = native_get_irq_info(afu, &irq_info))) {
  631. WARN(1, "Unable to get CXL IRQ Info: %i\n", ret);
  632. return fail_psl_irq(afu, &irq_info);
  633. }
  634. rcu_read_lock();
  635. ctx = idr_find(&afu->contexts_idr, ph);
  636. if (ctx) {
  637. ret = cxl_irq(irq, ctx, &irq_info);
  638. rcu_read_unlock();
  639. return ret;
  640. }
  641. rcu_read_unlock();
  642. WARN(1, "Unable to demultiplex CXL PSL IRQ for PE %i DSISR %016llx DAR"
  643. " %016llx\n(Possible AFU HW issue - was a term/remove acked"
  644. " with outstanding transactions?)\n", ph, irq_info.dsisr,
  645. irq_info.dar);
  646. return fail_psl_irq(afu, &irq_info);
  647. }
  648. static irqreturn_t native_slice_irq_err(int irq, void *data)
  649. {
  650. struct cxl_afu *afu = data;
  651. u64 fir_slice, errstat, serr, afu_debug;
  652. WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq);
  653. serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
  654. fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An);
  655. errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);
  656. afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An);
  657. dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr);
  658. dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice);
  659. dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat);
  660. dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug);
  661. cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
  662. return IRQ_HANDLED;
  663. }
  664. static irqreturn_t native_irq_err(int irq, void *data)
  665. {
  666. struct cxl *adapter = data;
  667. u64 fir1, fir2, err_ivte;
  668. WARN(1, "CXL ERROR interrupt %i\n", irq);
  669. err_ivte = cxl_p1_read(adapter, CXL_PSL_ErrIVTE);
  670. dev_crit(&adapter->dev, "PSL_ErrIVTE: 0x%016llx\n", err_ivte);
  671. dev_crit(&adapter->dev, "STOPPING CXL TRACE\n");
  672. cxl_stop_trace(adapter);
  673. fir1 = cxl_p1_read(adapter, CXL_PSL_FIR1);
  674. fir2 = cxl_p1_read(adapter, CXL_PSL_FIR2);
  675. dev_crit(&adapter->dev, "PSL_FIR1: 0x%016llx\nPSL_FIR2: 0x%016llx\n", fir1, fir2);
  676. return IRQ_HANDLED;
  677. }
  678. int cxl_native_register_psl_err_irq(struct cxl *adapter)
  679. {
  680. int rc;
  681. adapter->irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
  682. dev_name(&adapter->dev));
  683. if (!adapter->irq_name)
  684. return -ENOMEM;
  685. if ((rc = cxl_register_one_irq(adapter, native_irq_err, adapter,
  686. &adapter->err_hwirq,
  687. &adapter->err_virq,
  688. adapter->irq_name))) {
  689. kfree(adapter->irq_name);
  690. adapter->irq_name = NULL;
  691. return rc;
  692. }
  693. cxl_p1_write(adapter, CXL_PSL_ErrIVTE, adapter->err_hwirq & 0xffff);
  694. return 0;
  695. }
  696. void cxl_native_release_psl_err_irq(struct cxl *adapter)
  697. {
  698. if (adapter->err_virq != irq_find_mapping(NULL, adapter->err_hwirq))
  699. return;
  700. cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
  701. cxl_unmap_irq(adapter->err_virq, adapter);
  702. cxl_ops->release_one_irq(adapter, adapter->err_hwirq);
  703. kfree(adapter->irq_name);
  704. }
  705. int cxl_native_register_serr_irq(struct cxl_afu *afu)
  706. {
  707. u64 serr;
  708. int rc;
  709. afu->err_irq_name = kasprintf(GFP_KERNEL, "cxl-%s-err",
  710. dev_name(&afu->dev));
  711. if (!afu->err_irq_name)
  712. return -ENOMEM;
  713. if ((rc = cxl_register_one_irq(afu->adapter, native_slice_irq_err, afu,
  714. &afu->serr_hwirq,
  715. &afu->serr_virq, afu->err_irq_name))) {
  716. kfree(afu->err_irq_name);
  717. afu->err_irq_name = NULL;
  718. return rc;
  719. }
  720. serr = cxl_p1n_read(afu, CXL_PSL_SERR_An);
  721. serr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);
  722. cxl_p1n_write(afu, CXL_PSL_SERR_An, serr);
  723. return 0;
  724. }
  725. void cxl_native_release_serr_irq(struct cxl_afu *afu)
  726. {
  727. if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq))
  728. return;
  729. cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
  730. cxl_unmap_irq(afu->serr_virq, afu);
  731. cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
  732. kfree(afu->err_irq_name);
  733. }
  734. int cxl_native_register_psl_irq(struct cxl_afu *afu)
  735. {
  736. int rc;
  737. afu->psl_irq_name = kasprintf(GFP_KERNEL, "cxl-%s",
  738. dev_name(&afu->dev));
  739. if (!afu->psl_irq_name)
  740. return -ENOMEM;
  741. if ((rc = cxl_register_one_irq(afu->adapter, native_irq_multiplexed, afu,
  742. &afu->psl_hwirq, &afu->psl_virq,
  743. afu->psl_irq_name))) {
  744. kfree(afu->psl_irq_name);
  745. afu->psl_irq_name = NULL;
  746. }
  747. return rc;
  748. }
  749. void cxl_native_release_psl_irq(struct cxl_afu *afu)
  750. {
  751. if (afu->psl_virq != irq_find_mapping(NULL, afu->psl_hwirq))
  752. return;
  753. cxl_unmap_irq(afu->psl_virq, afu);
  754. cxl_ops->release_one_irq(afu->adapter, afu->psl_hwirq);
  755. kfree(afu->psl_irq_name);
  756. }
  757. static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
  758. {
  759. u64 dsisr;
  760. pr_devel("RECOVERING FROM PSL ERROR... (0x%016llx)\n", errstat);
  761. /* Clear PSL_DSISR[PE] */
  762. dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
  763. cxl_p2n_write(afu, CXL_PSL_DSISR_An, dsisr & ~CXL_PSL_DSISR_An_PE);
  764. /* Write 1s to clear error status bits */
  765. cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
  766. }
  767. static int native_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
  768. {
  769. trace_cxl_psl_irq_ack(ctx, tfc);
  770. if (tfc)
  771. cxl_p2n_write(ctx->afu, CXL_PSL_TFC_An, tfc);
  772. if (psl_reset_mask)
  773. recover_psl_err(ctx->afu, psl_reset_mask);
  774. return 0;
  775. }
  776. int cxl_check_error(struct cxl_afu *afu)
  777. {
  778. return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
  779. }
  780. static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
  781. {
  782. if (unlikely(!cxl_ops->link_ok(afu->adapter)))
  783. return -EIO;
  784. if (unlikely(off >= afu->crs_len))
  785. return -ERANGE;
  786. *out = in_le64(afu->afu_desc_mmio + afu->crs_offset +
  787. (cr * afu->crs_len) + off);
  788. return 0;
  789. }
  790. static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
  791. {
  792. if (unlikely(!cxl_ops->link_ok(afu->adapter)))
  793. return -EIO;
  794. if (unlikely(off >= afu->crs_len))
  795. return -ERANGE;
  796. *out = in_le32(afu->afu_desc_mmio + afu->crs_offset +
  797. (cr * afu->crs_len) + off);
  798. return 0;
  799. }
  800. static int native_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out)
  801. {
  802. u64 aligned_off = off & ~0x3L;
  803. u32 val;
  804. int rc;
  805. rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
  806. if (!rc)
  807. *out = (val >> ((off & 0x3) * 8)) & 0xffff;
  808. return rc;
  809. }
  810. static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
  811. {
  812. u64 aligned_off = off & ~0x3L;
  813. u32 val;
  814. int rc;
  815. rc = native_afu_cr_read32(afu, cr, aligned_off, &val);
  816. if (!rc)
  817. *out = (val >> ((off & 0x3) * 8)) & 0xff;
  818. return rc;
  819. }
  820. const struct cxl_backend_ops cxl_native_ops = {
  821. .module = THIS_MODULE,
  822. .adapter_reset = cxl_pci_reset,
  823. .alloc_one_irq = cxl_pci_alloc_one_irq,
  824. .release_one_irq = cxl_pci_release_one_irq,
  825. .alloc_irq_ranges = cxl_pci_alloc_irq_ranges,
  826. .release_irq_ranges = cxl_pci_release_irq_ranges,
  827. .setup_irq = cxl_pci_setup_irq,
  828. .handle_psl_slice_error = native_handle_psl_slice_error,
  829. .psl_interrupt = NULL,
  830. .ack_irq = native_ack_irq,
  831. .attach_process = native_attach_process,
  832. .detach_process = native_detach_process,
  833. .link_ok = cxl_adapter_link_ok,
  834. .release_afu = cxl_pci_release_afu,
  835. .afu_read_err_buffer = cxl_pci_afu_read_err_buffer,
  836. .afu_check_and_enable = native_afu_check_and_enable,
  837. .afu_activate_mode = native_afu_activate_mode,
  838. .afu_deactivate_mode = native_afu_deactivate_mode,
  839. .afu_reset = native_afu_reset,
  840. .afu_cr_read8 = native_afu_cr_read8,
  841. .afu_cr_read16 = native_afu_cr_read16,
  842. .afu_cr_read32 = native_afu_cr_read32,
  843. .afu_cr_read64 = native_afu_cr_read64,
  844. };