sym_fw.c 13 KB

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