sym_fw.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  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. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  274. /*
  275. * Fill variable parts in scripts.
  276. */
  277. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  278. /*
  279. * Setup bus addresses used from the C code..
  280. */
  281. sym_fw_setup_bus_addresses(np, fw);
  282. }
  283. #endif /* SYM_CONF_GENERIC_SUPPORT */
  284. /*
  285. * Setup routine for firmware #2.
  286. */
  287. static void
  288. sym_fw2_setup(struct sym_hcb *np, struct sym_fw *fw)
  289. {
  290. struct sym_fw2a_scr *scripta0;
  291. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  292. /*
  293. * Fill variable parts in scripts.
  294. */
  295. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  296. /*
  297. * Setup bus addresses used from the C code..
  298. */
  299. sym_fw_setup_bus_addresses(np, fw);
  300. }
  301. /*
  302. * Allocate firmware descriptors.
  303. */
  304. #if SYM_CONF_GENERIC_SUPPORT
  305. static struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
  306. #endif /* SYM_CONF_GENERIC_SUPPORT */
  307. static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
  308. /*
  309. * Find the most appropriate firmware for a chip.
  310. */
  311. struct sym_fw *
  312. sym_find_firmware(struct sym_chip *chip)
  313. {
  314. if (chip->features & FE_LDSTR)
  315. return &sym_fw2;
  316. #if SYM_CONF_GENERIC_SUPPORT
  317. else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC)))
  318. return &sym_fw1;
  319. #endif
  320. else
  321. return NULL;
  322. }
  323. /*
  324. * Bind a script to physical addresses.
  325. */
  326. void sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len)
  327. {
  328. u32 opcode, new, old, tmp1, tmp2;
  329. u32 *end, *cur;
  330. int relocs;
  331. cur = start;
  332. end = start + len/4;
  333. while (cur < end) {
  334. opcode = *cur;
  335. /*
  336. * If we forget to change the length
  337. * in scripts, a field will be
  338. * padded with 0. This is an illegal
  339. * command.
  340. */
  341. if (opcode == 0) {
  342. printf ("%s: ERROR0 IN SCRIPT at %d.\n",
  343. sym_name(np), (int) (cur-start));
  344. ++cur;
  345. continue;
  346. };
  347. /*
  348. * We use the bogus value 0xf00ff00f ;-)
  349. * to reserve data area in SCRIPTS.
  350. */
  351. if (opcode == SCR_DATA_ZERO) {
  352. *cur++ = 0;
  353. continue;
  354. }
  355. if (DEBUG_FLAGS & DEBUG_SCRIPT)
  356. printf ("%d: <%x>\n", (int) (cur-start),
  357. (unsigned)opcode);
  358. /*
  359. * We don't have to decode ALL commands
  360. */
  361. switch (opcode >> 28) {
  362. case 0xf:
  363. /*
  364. * LOAD / STORE DSA relative, don't relocate.
  365. */
  366. relocs = 0;
  367. break;
  368. case 0xe:
  369. /*
  370. * LOAD / STORE absolute.
  371. */
  372. relocs = 1;
  373. break;
  374. case 0xc:
  375. /*
  376. * COPY has TWO arguments.
  377. */
  378. relocs = 2;
  379. tmp1 = cur[1];
  380. tmp2 = cur[2];
  381. if ((tmp1 ^ tmp2) & 3) {
  382. printf ("%s: ERROR1 IN SCRIPT at %d.\n",
  383. sym_name(np), (int) (cur-start));
  384. }
  385. /*
  386. * If PREFETCH feature not enabled, remove
  387. * the NO FLUSH bit if present.
  388. */
  389. if ((opcode & SCR_NO_FLUSH) &&
  390. !(np->features & FE_PFEN)) {
  391. opcode = (opcode & ~SCR_NO_FLUSH);
  392. }
  393. break;
  394. case 0x0:
  395. /*
  396. * MOVE/CHMOV (absolute address)
  397. */
  398. if (!(np->features & FE_WIDE))
  399. opcode = (opcode | OPC_MOVE);
  400. relocs = 1;
  401. break;
  402. case 0x1:
  403. /*
  404. * MOVE/CHMOV (table indirect)
  405. */
  406. if (!(np->features & FE_WIDE))
  407. opcode = (opcode | OPC_MOVE);
  408. relocs = 0;
  409. break;
  410. #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
  411. case 0x2:
  412. /*
  413. * MOVE/CHMOV in target role (absolute address)
  414. */
  415. opcode &= ~0x20000000;
  416. if (!(np->features & FE_WIDE))
  417. opcode = (opcode & ~OPC_TCHMOVE);
  418. relocs = 1;
  419. break;
  420. case 0x3:
  421. /*
  422. * MOVE/CHMOV in target role (table indirect)
  423. */
  424. opcode &= ~0x20000000;
  425. if (!(np->features & FE_WIDE))
  426. opcode = (opcode & ~OPC_TCHMOVE);
  427. relocs = 0;
  428. break;
  429. #endif
  430. case 0x8:
  431. /*
  432. * JUMP / CALL
  433. * don't relocate if relative :-)
  434. */
  435. if (opcode & 0x00800000)
  436. relocs = 0;
  437. else if ((opcode & 0xf8400000) == 0x80400000)/*JUMP64*/
  438. relocs = 2;
  439. else
  440. relocs = 1;
  441. break;
  442. case 0x4:
  443. case 0x5:
  444. case 0x6:
  445. case 0x7:
  446. relocs = 1;
  447. break;
  448. default:
  449. relocs = 0;
  450. break;
  451. };
  452. /*
  453. * Scriptify:) the opcode.
  454. */
  455. *cur++ = cpu_to_scr(opcode);
  456. /*
  457. * If no relocation, assume 1 argument
  458. * and just scriptize:) it.
  459. */
  460. if (!relocs) {
  461. *cur = cpu_to_scr(*cur);
  462. ++cur;
  463. continue;
  464. }
  465. /*
  466. * Otherwise performs all needed relocations.
  467. */
  468. while (relocs--) {
  469. old = *cur;
  470. switch (old & RELOC_MASK) {
  471. case RELOC_REGISTER:
  472. new = (old & ~RELOC_MASK) + np->mmio_ba;
  473. break;
  474. case RELOC_LABEL_A:
  475. new = (old & ~RELOC_MASK) + np->scripta_ba;
  476. break;
  477. case RELOC_LABEL_B:
  478. new = (old & ~RELOC_MASK) + np->scriptb_ba;
  479. break;
  480. case RELOC_SOFTC:
  481. new = (old & ~RELOC_MASK) + np->hcb_ba;
  482. break;
  483. case 0:
  484. /*
  485. * Don't relocate a 0 address.
  486. * They are mostly used for patched or
  487. * script self-modified areas.
  488. */
  489. if (old == 0) {
  490. new = old;
  491. break;
  492. }
  493. /* fall through */
  494. default:
  495. new = 0;
  496. panic("sym_fw_bind_script: "
  497. "weird relocation %x\n", old);
  498. break;
  499. }
  500. *cur++ = cpu_to_scr(new);
  501. }
  502. };
  503. }