sym_fw.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
  4. * of PCI-SCSI IO processors.
  5. *
  6. * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>
  7. *
  8. * This driver is derived from the Linux sym53c8xx driver.
  9. * Copyright (C) 1998-2000 Gerard Roudier
  10. *
  11. * The sym53c8xx driver is derived from the ncr53c8xx driver that had been
  12. * a port of the FreeBSD ncr driver to Linux-1.2.13.
  13. *
  14. * The original ncr driver has been written for 386bsd and FreeBSD by
  15. * Wolfgang Stanglmeier <wolf@cologne.de>
  16. * Stefan Esser <se@mi.Uni-Koeln.de>
  17. * Copyright (C) 1994 Wolfgang Stanglmeier
  18. *
  19. * Other major contributions:
  20. *
  21. * NVRAM detection and reading.
  22. * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
  23. *
  24. *-----------------------------------------------------------------------------
  25. */
  26. #include "sym_glue.h"
  27. /*
  28. * Macros used for all firmwares.
  29. */
  30. #define SYM_GEN_A(s, label) ((short) offsetof(s, label)),
  31. #define SYM_GEN_B(s, label) ((short) offsetof(s, label)),
  32. #define SYM_GEN_Z(s, label) ((short) offsetof(s, label)),
  33. #define PADDR_A(label) SYM_GEN_PADDR_A(struct SYM_FWA_SCR, label)
  34. #define PADDR_B(label) SYM_GEN_PADDR_B(struct SYM_FWB_SCR, label)
  35. #if SYM_CONF_GENERIC_SUPPORT
  36. /*
  37. * Allocate firmware #1 script area.
  38. */
  39. #define SYM_FWA_SCR sym_fw1a_scr
  40. #define SYM_FWB_SCR sym_fw1b_scr
  41. #define SYM_FWZ_SCR sym_fw1z_scr
  42. #include "sym_fw1.h"
  43. static struct sym_fwa_ofs sym_fw1a_ofs = {
  44. SYM_GEN_FW_A(struct SYM_FWA_SCR)
  45. };
  46. static struct sym_fwb_ofs sym_fw1b_ofs = {
  47. SYM_GEN_FW_B(struct SYM_FWB_SCR)
  48. };
  49. static struct sym_fwz_ofs sym_fw1z_ofs = {
  50. SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
  51. };
  52. #undef SYM_FWA_SCR
  53. #undef SYM_FWB_SCR
  54. #undef SYM_FWZ_SCR
  55. #endif /* SYM_CONF_GENERIC_SUPPORT */
  56. /*
  57. * Allocate firmware #2 script area.
  58. */
  59. #define SYM_FWA_SCR sym_fw2a_scr
  60. #define SYM_FWB_SCR sym_fw2b_scr
  61. #define SYM_FWZ_SCR sym_fw2z_scr
  62. #include "sym_fw2.h"
  63. static struct sym_fwa_ofs sym_fw2a_ofs = {
  64. SYM_GEN_FW_A(struct SYM_FWA_SCR)
  65. };
  66. static struct sym_fwb_ofs sym_fw2b_ofs = {
  67. SYM_GEN_FW_B(struct SYM_FWB_SCR)
  68. SYM_GEN_B(struct SYM_FWB_SCR, start64)
  69. SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
  70. };
  71. static struct sym_fwz_ofs sym_fw2z_ofs = {
  72. SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
  73. };
  74. #undef SYM_FWA_SCR
  75. #undef SYM_FWB_SCR
  76. #undef SYM_FWZ_SCR
  77. #undef SYM_GEN_A
  78. #undef SYM_GEN_B
  79. #undef SYM_GEN_Z
  80. #undef PADDR_A
  81. #undef PADDR_B
  82. #if SYM_CONF_GENERIC_SUPPORT
  83. /*
  84. * Patch routine for firmware #1.
  85. */
  86. static void
  87. sym_fw1_patch(struct Scsi_Host *shost)
  88. {
  89. struct sym_hcb *np = sym_get_hcb(shost);
  90. struct sym_fw1a_scr *scripta0;
  91. struct sym_fw1b_scr *scriptb0;
  92. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  93. scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
  94. /*
  95. * Remove LED support if not needed.
  96. */
  97. if (!(np->features & FE_LED0)) {
  98. scripta0->idle[0] = cpu_to_scr(SCR_NO_OP);
  99. scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP);
  100. scripta0->start[0] = cpu_to_scr(SCR_NO_OP);
  101. }
  102. #ifdef SYM_CONF_IARB_SUPPORT
  103. /*
  104. * If user does not want to use IMMEDIATE ARBITRATION
  105. * when we are reselected while attempting to arbitrate,
  106. * patch the SCRIPTS accordingly with a SCRIPT NO_OP.
  107. */
  108. if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
  109. scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
  110. #endif
  111. /*
  112. * Patch some data in SCRIPTS.
  113. * - start and done queue initial bus address.
  114. * - target bus address table bus address.
  115. */
  116. scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba);
  117. scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba);
  118. scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba);
  119. }
  120. #endif /* SYM_CONF_GENERIC_SUPPORT */
  121. /*
  122. * Patch routine for firmware #2.
  123. */
  124. static void
  125. sym_fw2_patch(struct Scsi_Host *shost)
  126. {
  127. struct sym_data *sym_data = shost_priv(shost);
  128. struct pci_dev *pdev = sym_data->pdev;
  129. struct sym_hcb *np = sym_data->ncb;
  130. struct sym_fw2a_scr *scripta0;
  131. struct sym_fw2b_scr *scriptb0;
  132. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  133. scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
  134. /*
  135. * Remove LED support if not needed.
  136. */
  137. if (!(np->features & FE_LED0)) {
  138. scripta0->idle[0] = cpu_to_scr(SCR_NO_OP);
  139. scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP);
  140. scripta0->start[0] = cpu_to_scr(SCR_NO_OP);
  141. }
  142. #if SYM_CONF_DMA_ADDRESSING_MODE == 2
  143. /*
  144. * Remove useless 64 bit DMA specific SCRIPTS,
  145. * when this feature is not available.
  146. */
  147. if (!use_dac(np)) {
  148. scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP);
  149. scripta0->is_dmap_dirty[1] = 0;
  150. scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP);
  151. scripta0->is_dmap_dirty[3] = 0;
  152. }
  153. #endif
  154. #ifdef SYM_CONF_IARB_SUPPORT
  155. /*
  156. * If user does not want to use IMMEDIATE ARBITRATION
  157. * when we are reselected while attempting to arbitrate,
  158. * patch the SCRIPTS accordingly with a SCRIPT NO_OP.
  159. */
  160. if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
  161. scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
  162. #endif
  163. /*
  164. * Patch some variable in SCRIPTS.
  165. * - start and done queue initial bus address.
  166. * - target bus address table bus address.
  167. */
  168. scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba);
  169. scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba);
  170. scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba);
  171. /*
  172. * Remove the load of SCNTL4 on reselection if not a C10.
  173. */
  174. if (!(np->features & FE_C10)) {
  175. scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP);
  176. scripta0->resel_scntl4[1] = cpu_to_scr(0);
  177. }
  178. /*
  179. * Remove a couple of work-arounds specific to C1010 if
  180. * they are not desirable. See `sym_fw2.h' for more details.
  181. */
  182. if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_66 &&
  183. pdev->revision < 0x1 &&
  184. np->pciclk_khz < 60000)) {
  185. scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
  186. scripta0->datao_phase[1] = cpu_to_scr(0);
  187. }
  188. if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 /* &&
  189. pdev->revision < 0xff */)) {
  190. scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
  191. scripta0->sel_done[1] = cpu_to_scr(0);
  192. }
  193. /*
  194. * Patch some other variables in SCRIPTS.
  195. * These ones are loaded by the SCRIPTS processor.
  196. */
  197. scriptb0->pm0_data_addr[0] =
  198. cpu_to_scr(np->scripta_ba +
  199. offsetof(struct sym_fw2a_scr, pm0_data));
  200. scriptb0->pm1_data_addr[0] =
  201. cpu_to_scr(np->scripta_ba +
  202. offsetof(struct sym_fw2a_scr, pm1_data));
  203. }
  204. /*
  205. * Fill the data area in scripts.
  206. * To be done for all firmwares.
  207. */
  208. static void
  209. sym_fw_fill_data (u32 *in, u32 *out)
  210. {
  211. int i;
  212. for (i = 0; i < SYM_CONF_MAX_SG; i++) {
  213. *in++ = SCR_CHMOV_TBL ^ SCR_DATA_IN;
  214. *in++ = offsetof (struct sym_dsb, data[i]);
  215. *out++ = SCR_CHMOV_TBL ^ SCR_DATA_OUT;
  216. *out++ = offsetof (struct sym_dsb, data[i]);
  217. }
  218. }
  219. /*
  220. * Setup useful script bus addresses.
  221. * To be done for all firmwares.
  222. */
  223. static void
  224. sym_fw_setup_bus_addresses(struct sym_hcb *np, struct sym_fw *fw)
  225. {
  226. u32 *pa;
  227. u_short *po;
  228. int i;
  229. /*
  230. * Build the bus address table for script A
  231. * from the script A offset table.
  232. */
  233. po = (u_short *) fw->a_ofs;
  234. pa = (u32 *) &np->fwa_bas;
  235. for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++)
  236. pa[i] = np->scripta_ba + po[i];
  237. /*
  238. * Same for script B.
  239. */
  240. po = (u_short *) fw->b_ofs;
  241. pa = (u32 *) &np->fwb_bas;
  242. for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++)
  243. pa[i] = np->scriptb_ba + po[i];
  244. /*
  245. * Same for script Z.
  246. */
  247. po = (u_short *) fw->z_ofs;
  248. pa = (u32 *) &np->fwz_bas;
  249. for (i = 0 ; i < sizeof(np->fwz_bas)/sizeof(u32) ; i++)
  250. pa[i] = np->scriptz_ba + po[i];
  251. }
  252. #if SYM_CONF_GENERIC_SUPPORT
  253. /*
  254. * Setup routine for firmware #1.
  255. */
  256. static void
  257. sym_fw1_setup(struct sym_hcb *np, struct sym_fw *fw)
  258. {
  259. struct sym_fw1a_scr *scripta0;
  260. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  261. /*
  262. * Fill variable parts in scripts.
  263. */
  264. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  265. /*
  266. * Setup bus addresses used from the C code..
  267. */
  268. sym_fw_setup_bus_addresses(np, fw);
  269. }
  270. #endif /* SYM_CONF_GENERIC_SUPPORT */
  271. /*
  272. * Setup routine for firmware #2.
  273. */
  274. static void
  275. sym_fw2_setup(struct sym_hcb *np, struct sym_fw *fw)
  276. {
  277. struct sym_fw2a_scr *scripta0;
  278. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  279. /*
  280. * Fill variable parts in scripts.
  281. */
  282. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  283. /*
  284. * Setup bus addresses used from the C code..
  285. */
  286. sym_fw_setup_bus_addresses(np, fw);
  287. }
  288. /*
  289. * Allocate firmware descriptors.
  290. */
  291. #if SYM_CONF_GENERIC_SUPPORT
  292. static struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
  293. #endif /* SYM_CONF_GENERIC_SUPPORT */
  294. static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
  295. /*
  296. * Find the most appropriate firmware for a chip.
  297. */
  298. struct sym_fw *
  299. sym_find_firmware(struct sym_chip *chip)
  300. {
  301. if (chip->features & FE_LDSTR)
  302. return &sym_fw2;
  303. #if SYM_CONF_GENERIC_SUPPORT
  304. else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC)))
  305. return &sym_fw1;
  306. #endif
  307. else
  308. return NULL;
  309. }
  310. /*
  311. * Bind a script to physical addresses.
  312. */
  313. void sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len)
  314. {
  315. u32 opcode, new, old, tmp1, tmp2;
  316. u32 *end, *cur;
  317. int relocs;
  318. cur = start;
  319. end = start + len/4;
  320. while (cur < end) {
  321. opcode = *cur;
  322. /*
  323. * If we forget to change the length
  324. * in scripts, a field will be
  325. * padded with 0. This is an illegal
  326. * command.
  327. */
  328. if (opcode == 0) {
  329. printf ("%s: ERROR0 IN SCRIPT at %d.\n",
  330. sym_name(np), (int) (cur-start));
  331. ++cur;
  332. continue;
  333. }
  334. /*
  335. * We use the bogus value 0xf00ff00f ;-)
  336. * to reserve data area in SCRIPTS.
  337. */
  338. if (opcode == SCR_DATA_ZERO) {
  339. *cur++ = 0;
  340. continue;
  341. }
  342. if (DEBUG_FLAGS & DEBUG_SCRIPT)
  343. printf ("%d: <%x>\n", (int) (cur-start),
  344. (unsigned)opcode);
  345. /*
  346. * We don't have to decode ALL commands
  347. */
  348. switch (opcode >> 28) {
  349. case 0xf:
  350. /*
  351. * LOAD / STORE DSA relative, don't relocate.
  352. */
  353. relocs = 0;
  354. break;
  355. case 0xe:
  356. /*
  357. * LOAD / STORE absolute.
  358. */
  359. relocs = 1;
  360. break;
  361. case 0xc:
  362. /*
  363. * COPY has TWO arguments.
  364. */
  365. relocs = 2;
  366. tmp1 = cur[1];
  367. tmp2 = cur[2];
  368. if ((tmp1 ^ tmp2) & 3) {
  369. printf ("%s: ERROR1 IN SCRIPT at %d.\n",
  370. sym_name(np), (int) (cur-start));
  371. }
  372. /*
  373. * If PREFETCH feature not enabled, remove
  374. * the NO FLUSH bit if present.
  375. */
  376. if ((opcode & SCR_NO_FLUSH) &&
  377. !(np->features & FE_PFEN)) {
  378. opcode = (opcode & ~SCR_NO_FLUSH);
  379. }
  380. break;
  381. case 0x0:
  382. /*
  383. * MOVE/CHMOV (absolute address)
  384. */
  385. if (!(np->features & FE_WIDE))
  386. opcode = (opcode | OPC_MOVE);
  387. relocs = 1;
  388. break;
  389. case 0x1:
  390. /*
  391. * MOVE/CHMOV (table indirect)
  392. */
  393. if (!(np->features & FE_WIDE))
  394. opcode = (opcode | OPC_MOVE);
  395. relocs = 0;
  396. break;
  397. #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
  398. case 0x2:
  399. /*
  400. * MOVE/CHMOV in target role (absolute address)
  401. */
  402. opcode &= ~0x20000000;
  403. if (!(np->features & FE_WIDE))
  404. opcode = (opcode & ~OPC_TCHMOVE);
  405. relocs = 1;
  406. break;
  407. case 0x3:
  408. /*
  409. * MOVE/CHMOV in target role (table indirect)
  410. */
  411. opcode &= ~0x20000000;
  412. if (!(np->features & FE_WIDE))
  413. opcode = (opcode & ~OPC_TCHMOVE);
  414. relocs = 0;
  415. break;
  416. #endif
  417. case 0x8:
  418. /*
  419. * JUMP / CALL
  420. * don't relocate if relative :-)
  421. */
  422. if (opcode & 0x00800000)
  423. relocs = 0;
  424. else if ((opcode & 0xf8400000) == 0x80400000)/*JUMP64*/
  425. relocs = 2;
  426. else
  427. relocs = 1;
  428. break;
  429. case 0x4:
  430. case 0x5:
  431. case 0x6:
  432. case 0x7:
  433. relocs = 1;
  434. break;
  435. default:
  436. relocs = 0;
  437. break;
  438. }
  439. /*
  440. * Scriptify:) the opcode.
  441. */
  442. *cur++ = cpu_to_scr(opcode);
  443. /*
  444. * If no relocation, assume 1 argument
  445. * and just scriptize:) it.
  446. */
  447. if (!relocs) {
  448. *cur = cpu_to_scr(*cur);
  449. ++cur;
  450. continue;
  451. }
  452. /*
  453. * Otherwise performs all needed relocations.
  454. */
  455. while (relocs--) {
  456. old = *cur;
  457. switch (old & RELOC_MASK) {
  458. case RELOC_REGISTER:
  459. new = (old & ~RELOC_MASK) + np->mmio_ba;
  460. break;
  461. case RELOC_LABEL_A:
  462. new = (old & ~RELOC_MASK) + np->scripta_ba;
  463. break;
  464. case RELOC_LABEL_B:
  465. new = (old & ~RELOC_MASK) + np->scriptb_ba;
  466. break;
  467. case RELOC_SOFTC:
  468. new = (old & ~RELOC_MASK) + np->hcb_ba;
  469. break;
  470. case 0:
  471. /*
  472. * Don't relocate a 0 address.
  473. * They are mostly used for patched or
  474. * script self-modified areas.
  475. */
  476. if (old == 0) {
  477. new = old;
  478. break;
  479. }
  480. fallthrough;
  481. default:
  482. new = 0;
  483. panic("sym_fw_bind_script: "
  484. "weird relocation %x\n", old);
  485. break;
  486. }
  487. *cur++ = cpu_to_scr(new);
  488. }
  489. }
  490. }