sym_fw.c 13 KB

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