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 sym_hcb *np)
  101. {
  102. struct sym_fw1a_scr *scripta0;
  103. struct sym_fw1b_scr *scriptb0;
  104. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  105. scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
  106. /*
  107. * Remove LED support if not needed.
  108. */
  109. if (!(np->features & FE_LED0)) {
  110. scripta0->idle[0] = cpu_to_scr(SCR_NO_OP);
  111. scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP);
  112. scripta0->start[0] = cpu_to_scr(SCR_NO_OP);
  113. }
  114. #ifdef SYM_CONF_IARB_SUPPORT
  115. /*
  116. * If user does not want to use IMMEDIATE ARBITRATION
  117. * when we are reselected while attempting to arbitrate,
  118. * patch the SCRIPTS accordingly with a SCRIPT NO_OP.
  119. */
  120. if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
  121. scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
  122. #endif
  123. /*
  124. * Patch some data in SCRIPTS.
  125. * - start and done queue initial bus address.
  126. * - target bus address table bus address.
  127. */
  128. scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba);
  129. scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba);
  130. scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba);
  131. }
  132. #endif /* SYM_CONF_GENERIC_SUPPORT */
  133. /*
  134. * Patch routine for firmware #2.
  135. */
  136. static void
  137. sym_fw2_patch(struct sym_hcb *np)
  138. {
  139. struct sym_fw2a_scr *scripta0;
  140. struct sym_fw2b_scr *scriptb0;
  141. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  142. scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
  143. /*
  144. * Remove LED support if not needed.
  145. */
  146. if (!(np->features & FE_LED0)) {
  147. scripta0->idle[0] = cpu_to_scr(SCR_NO_OP);
  148. scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP);
  149. scripta0->start[0] = cpu_to_scr(SCR_NO_OP);
  150. }
  151. #if SYM_CONF_DMA_ADDRESSING_MODE == 2
  152. /*
  153. * Remove useless 64 bit DMA specific SCRIPTS,
  154. * when this feature is not available.
  155. */
  156. if (!np->use_dac) {
  157. scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP);
  158. scripta0->is_dmap_dirty[1] = 0;
  159. scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP);
  160. scripta0->is_dmap_dirty[3] = 0;
  161. }
  162. #endif
  163. #ifdef SYM_CONF_IARB_SUPPORT
  164. /*
  165. * If user does not want to use IMMEDIATE ARBITRATION
  166. * when we are reselected while attempting to arbitrate,
  167. * patch the SCRIPTS accordingly with a SCRIPT NO_OP.
  168. */
  169. if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
  170. scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
  171. #endif
  172. /*
  173. * Patch some variable in SCRIPTS.
  174. * - start and done queue initial bus address.
  175. * - target bus address table bus address.
  176. */
  177. scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba);
  178. scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba);
  179. scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba);
  180. /*
  181. * Remove the load of SCNTL4 on reselection if not a C10.
  182. */
  183. if (!(np->features & FE_C10)) {
  184. scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP);
  185. scripta0->resel_scntl4[1] = cpu_to_scr(0);
  186. }
  187. /*
  188. * Remove a couple of work-arounds specific to C1010 if
  189. * they are not desirable. See `sym_fw2.h' for more details.
  190. */
  191. if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 &&
  192. np->revision_id < 0x1 &&
  193. np->pciclk_khz < 60000)) {
  194. scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
  195. scripta0->datao_phase[1] = cpu_to_scr(0);
  196. }
  197. if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
  198. /* np->revision_id < 0xff */ 1)) {
  199. scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
  200. scripta0->sel_done[1] = cpu_to_scr(0);
  201. }
  202. /*
  203. * Patch some other variables in SCRIPTS.
  204. * These ones are loaded by the SCRIPTS processor.
  205. */
  206. scriptb0->pm0_data_addr[0] =
  207. cpu_to_scr(np->scripta_ba +
  208. offsetof(struct sym_fw2a_scr, pm0_data));
  209. scriptb0->pm1_data_addr[0] =
  210. cpu_to_scr(np->scripta_ba +
  211. offsetof(struct sym_fw2a_scr, pm1_data));
  212. }
  213. /*
  214. * Fill the data area in scripts.
  215. * To be done for all firmwares.
  216. */
  217. static void
  218. sym_fw_fill_data (u32 *in, u32 *out)
  219. {
  220. int i;
  221. for (i = 0; i < SYM_CONF_MAX_SG; i++) {
  222. *in++ = SCR_CHMOV_TBL ^ SCR_DATA_IN;
  223. *in++ = offsetof (struct sym_dsb, data[i]);
  224. *out++ = SCR_CHMOV_TBL ^ SCR_DATA_OUT;
  225. *out++ = offsetof (struct sym_dsb, data[i]);
  226. }
  227. }
  228. /*
  229. * Setup useful script bus addresses.
  230. * To be done for all firmwares.
  231. */
  232. static void
  233. sym_fw_setup_bus_addresses(struct sym_hcb *np, struct sym_fw *fw)
  234. {
  235. u32 *pa;
  236. u_short *po;
  237. int i;
  238. /*
  239. * Build the bus address table for script A
  240. * from the script A offset table.
  241. */
  242. po = (u_short *) fw->a_ofs;
  243. pa = (u32 *) &np->fwa_bas;
  244. for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++)
  245. pa[i] = np->scripta_ba + po[i];
  246. /*
  247. * Same for script B.
  248. */
  249. po = (u_short *) fw->b_ofs;
  250. pa = (u32 *) &np->fwb_bas;
  251. for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++)
  252. pa[i] = np->scriptb_ba + po[i];
  253. /*
  254. * Same for script Z.
  255. */
  256. po = (u_short *) fw->z_ofs;
  257. pa = (u32 *) &np->fwz_bas;
  258. for (i = 0 ; i < sizeof(np->fwz_bas)/sizeof(u32) ; i++)
  259. pa[i] = np->scriptz_ba + po[i];
  260. }
  261. #if SYM_CONF_GENERIC_SUPPORT
  262. /*
  263. * Setup routine for firmware #1.
  264. */
  265. static void
  266. sym_fw1_setup(struct sym_hcb *np, struct sym_fw *fw)
  267. {
  268. struct sym_fw1a_scr *scripta0;
  269. struct sym_fw1b_scr *scriptb0;
  270. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  271. scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
  272. /*
  273. * Fill variable parts in scripts.
  274. */
  275. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  276. /*
  277. * Setup bus addresses used from the C code..
  278. */
  279. sym_fw_setup_bus_addresses(np, fw);
  280. }
  281. #endif /* SYM_CONF_GENERIC_SUPPORT */
  282. /*
  283. * Setup routine for firmware #2.
  284. */
  285. static void
  286. sym_fw2_setup(struct sym_hcb *np, struct sym_fw *fw)
  287. {
  288. struct sym_fw2a_scr *scripta0;
  289. struct sym_fw2b_scr *scriptb0;
  290. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  291. scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
  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. }