sym_fw.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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.  * Redistribution and use in source and binary forms, with or without
  26.  * modification, are permitted provided that the following conditions
  27.  * are met:
  28.  * 1. Redistributions of source code must retain the above copyright
  29.  *    notice, this list of conditions and the following disclaimer.
  30.  * 2. The name of the author may not be used to endorse or promote products
  31.  *    derived from this software without specific prior written permission.
  32.  *
  33.  * Where this Software is combined with software released under the terms of 
  34.  * the GNU Public License ("GPL") and the terms of the GPL would require the 
  35.  * combined work to also be released under the terms of the GPL, the terms
  36.  * and conditions of this License will apply in addition to those of the
  37.  * GPL with the exception of any terms or conditions of this License that
  38.  * conflict with, or are expressly prohibited by, the GPL.
  39.  *
  40.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
  41.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43.  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  44.  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50.  * SUCH DAMAGE.
  51.  */
  52. #ifdef __FreeBSD__
  53. #include <dev/sym/sym_glue.h>
  54. #else
  55. #include "sym_glue.h"
  56. #endif
  57. /*
  58.  *  Macros used for all firmwares.
  59.  */
  60. #define SYM_GEN_A(s, label) ((short) offsetof(s, label)),
  61. #define SYM_GEN_B(s, label) ((short) offsetof(s, label)),
  62. #define SYM_GEN_Z(s, label) ((short) offsetof(s, label)),
  63. #define PADDR_A(label) SYM_GEN_PADDR_A(struct SYM_FWA_SCR, label)
  64. #define PADDR_B(label) SYM_GEN_PADDR_B(struct SYM_FWB_SCR, label)
  65. #if SYM_CONF_GENERIC_SUPPORT
  66. /*
  67.  *  Allocate firmware #1 script area.
  68.  */
  69. #define SYM_FWA_SCR sym_fw1a_scr
  70. #define SYM_FWB_SCR sym_fw1b_scr
  71. #define SYM_FWZ_SCR sym_fw1z_scr
  72. #ifdef __FreeBSD__
  73. #include <dev/sym/sym_fw1.h>
  74. #else
  75. #include "sym_fw1.h"
  76. #endif
  77. static struct sym_fwa_ofs sym_fw1a_ofs = {
  78. SYM_GEN_FW_A(struct SYM_FWA_SCR)
  79. };
  80. static struct sym_fwb_ofs sym_fw1b_ofs = {
  81. SYM_GEN_FW_B(struct SYM_FWB_SCR)
  82. #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
  83. SYM_GEN_B(struct SYM_FWB_SCR, data_io)
  84. #endif
  85. };
  86. static struct sym_fwz_ofs sym_fw1z_ofs = {
  87. SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
  88. #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
  89. SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram)
  90. #endif
  91. };
  92. #undef SYM_FWA_SCR
  93. #undef SYM_FWB_SCR
  94. #undef SYM_FWZ_SCR
  95. #endif /* SYM_CONF_GENERIC_SUPPORT */
  96. /*
  97.  *  Allocate firmware #2 script area.
  98.  */
  99. #define SYM_FWA_SCR sym_fw2a_scr
  100. #define SYM_FWB_SCR sym_fw2b_scr
  101. #define SYM_FWZ_SCR sym_fw2z_scr
  102. #ifdef __FreeBSD__
  103. #include <dev/sym/sym_fw2.h>
  104. #else
  105. #include "sym_fw2.h"
  106. #endif
  107. static struct sym_fwa_ofs sym_fw2a_ofs = {
  108. SYM_GEN_FW_A(struct SYM_FWA_SCR)
  109. };
  110. static struct sym_fwb_ofs sym_fw2b_ofs = {
  111. SYM_GEN_FW_B(struct SYM_FWB_SCR)
  112. #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
  113. SYM_GEN_B(struct SYM_FWB_SCR, data_io)
  114. #endif
  115. SYM_GEN_B(struct SYM_FWB_SCR, start64)
  116. SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
  117. };
  118. static struct sym_fwz_ofs sym_fw2z_ofs = {
  119. SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
  120. #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
  121. SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram)
  122. SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram64)
  123. #endif
  124. };
  125. #undef SYM_FWA_SCR
  126. #undef SYM_FWB_SCR
  127. #undef SYM_FWZ_SCR
  128. #undef SYM_GEN_A
  129. #undef SYM_GEN_B
  130. #undef SYM_GEN_Z
  131. #undef PADDR_A
  132. #undef PADDR_B
  133. #if SYM_CONF_GENERIC_SUPPORT
  134. /*
  135.  *  Patch routine for firmware #1.
  136.  */
  137. static void
  138. sym_fw1_patch(hcb_p np)
  139. {
  140. struct sym_fw1a_scr *scripta0;
  141. struct sym_fw1b_scr *scriptb0;
  142. #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
  143. struct sym_fw1z_scr *scriptz0 = 
  144. (struct sym_fw1z_scr *) np->scriptz0;
  145. #endif
  146. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  147. scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
  148. #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
  149. /*
  150.  *  Set up BUS physical address of SCRIPTS that is to 
  151.  *  be copied to on-chip RAM by the SCRIPTS processor.
  152.  */
  153. scriptz0->scripta0_ba[0] = cpu_to_scr(vtobus(scripta0));
  154. #endif
  155. /*
  156.  *  Remove LED support if not needed.
  157.  */
  158. if (!(np->features & FE_LED0)) {
  159. scripta0->idle[0] = cpu_to_scr(SCR_NO_OP);
  160. scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP);
  161. scripta0->start[0] = cpu_to_scr(SCR_NO_OP);
  162. }
  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 data 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. #endif /* SYM_CONF_GENERIC_SUPPORT */
  182. /*
  183.  *  Patch routine for firmware #2.
  184.  */
  185. static void
  186. sym_fw2_patch(hcb_p np)
  187. {
  188. struct sym_fw2a_scr *scripta0;
  189. struct sym_fw2b_scr *scriptb0;
  190. #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
  191. struct sym_fw2z_scr *scriptz0 = 
  192. (struct sym_fw2z_scr *) np->scriptz0;
  193. #endif
  194. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  195. scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
  196. #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
  197. /*
  198.  *  Set up BUS physical address of SCRIPTS that is to 
  199.  *  be copied to on-chip RAM by the SCRIPTS processor.
  200.  */
  201. scriptz0->scripta0_ba64[0] = /* Nothing is missing here */
  202. scriptz0->scripta0_ba[0] = cpu_to_scr(vtobus(scripta0));
  203. scriptz0->scriptb0_ba64[0] = cpu_to_scr(vtobus(scriptb0));
  204. scriptz0->ram_seg64[0] = np->scr_ram_seg;
  205. #endif
  206. /*
  207.  *  Remove LED support if not needed.
  208.  */
  209. if (!(np->features & FE_LED0)) {
  210. scripta0->idle[0] = cpu_to_scr(SCR_NO_OP);
  211. scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP);
  212. scripta0->start[0] = cpu_to_scr(SCR_NO_OP);
  213. }
  214. #if   SYM_CONF_DMA_ADDRESSING_MODE == 2
  215. /*
  216.  *  Remove useless 64 bit DMA specific SCRIPTS, 
  217.  *  when this feature is not available.
  218.  */
  219. if (!np->use_dac) {
  220. scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP);
  221. scripta0->is_dmap_dirty[1] = 0;
  222. scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP);
  223. scripta0->is_dmap_dirty[3] = 0;
  224. }
  225. #endif
  226. #ifdef SYM_CONF_IARB_SUPPORT
  227. /*
  228.  *    If user does not want to use IMMEDIATE ARBITRATION
  229.  *    when we are reselected while attempting to arbitrate,
  230.  *    patch the SCRIPTS accordingly with a SCRIPT NO_OP.
  231.  */
  232. if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
  233. scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
  234. #endif
  235. /*
  236.  *  Patch some variable in SCRIPTS.
  237.  *  - start and done queue initial bus address.
  238.  *  - target bus address table bus address.
  239.  */
  240. scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba);
  241. scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba);
  242. scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba);
  243. /*
  244.  *  Remove the load of SCNTL4 on reselection if not a C10.
  245.  */
  246. if (!(np->features & FE_C10)) {
  247. scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP);
  248. scripta0->resel_scntl4[1] = cpu_to_scr(0);
  249. }
  250. /*
  251.  *  Remove a couple of work-arounds specific to C1010 if 
  252.  *  they are not desirable. See `sym_fw2.h' for more details.
  253.  */
  254. if (!(np->device_id == PCI_ID_LSI53C1010_2 &&
  255.       np->revision_id < 0x1 &&
  256.       np->pciclk_khz < 60000)) {
  257. scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
  258. scripta0->datao_phase[1] = cpu_to_scr(0);
  259. }
  260. if (!(np->device_id == PCI_ID_LSI53C1010 &&
  261.       /* np->revision_id < 0xff */ 1)) {
  262. scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
  263. scripta0->sel_done[1] = cpu_to_scr(0);
  264. }
  265. /*
  266.  *  Patch some other variables in SCRIPTS.
  267.  *  These ones are loaded by the SCRIPTS processor.
  268.  */
  269. scriptb0->pm0_data_addr[0] =
  270. cpu_to_scr(np->scripta_ba + 
  271.    offsetof(struct sym_fw2a_scr, pm0_data));
  272. scriptb0->pm1_data_addr[0] =
  273. cpu_to_scr(np->scripta_ba + 
  274.    offsetof(struct sym_fw2a_scr, pm1_data));
  275. }
  276. /*
  277.  *  Fill the data area in scripts.
  278.  *  To be done for all firmwares.
  279.  */
  280. static void
  281. sym_fw_fill_data (u32 *in, u32 *out)
  282. {
  283. int i;
  284. for (i = 0; i < SYM_CONF_MAX_SG; i++) {
  285. *in++  = SCR_CHMOV_TBL ^ SCR_DATA_IN;
  286. *in++  = offsetof (struct sym_dsb, data[i]);
  287. *out++ = SCR_CHMOV_TBL ^ SCR_DATA_OUT;
  288. *out++ = offsetof (struct sym_dsb, data[i]);
  289. }
  290. }
  291. /*
  292.  *  Setup useful script bus addresses.
  293.  *  To be done for all firmwares.
  294.  */
  295. static void 
  296. sym_fw_setup_bus_addresses(hcb_p np, struct sym_fw *fw)
  297. {
  298. u32 *pa;
  299. u_short *po;
  300. int i;
  301. /*
  302.  *  Build the bus address table for script A 
  303.  *  from the script A offset table.
  304.  */
  305. po = (u_short *) fw->a_ofs;
  306. pa = (u32 *) &np->fwa_bas;
  307. for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++)
  308. pa[i] = np->scripta_ba + po[i];
  309. /*
  310.  *  Same for script B.
  311.  */
  312. po = (u_short *) fw->b_ofs;
  313. pa = (u32 *) &np->fwb_bas;
  314. for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++)
  315. pa[i] = np->scriptb_ba + po[i];
  316. /*
  317.  *  Same for script Z.
  318.  */
  319. po = (u_short *) fw->z_ofs;
  320. pa = (u32 *) &np->fwz_bas;
  321. for (i = 0 ; i < sizeof(np->fwz_bas)/sizeof(u32) ; i++)
  322. pa[i] = np->scriptz_ba + po[i];
  323. }
  324. #if SYM_CONF_GENERIC_SUPPORT
  325. /*
  326.  *  Setup routine for firmware #1.
  327.  */
  328. static void 
  329. sym_fw1_setup(hcb_p np, struct sym_fw *fw)
  330. {
  331. struct sym_fw1a_scr *scripta0;
  332. struct sym_fw1b_scr *scriptb0;
  333. scripta0 = (struct sym_fw1a_scr *) np->scripta0;
  334. scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
  335. /*
  336.  *  Fill variable parts in scripts.
  337.  */
  338. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  339. /*
  340.  *  Setup bus addresses used from the C code..
  341.  */
  342. sym_fw_setup_bus_addresses(np, fw);
  343. }
  344. #endif /* SYM_CONF_GENERIC_SUPPORT */
  345. /*
  346.  *  Setup routine for firmware #2.
  347.  */
  348. static void 
  349. sym_fw2_setup(hcb_p np, struct sym_fw *fw)
  350. {
  351. struct sym_fw2a_scr *scripta0;
  352. struct sym_fw2b_scr *scriptb0;
  353. scripta0 = (struct sym_fw2a_scr *) np->scripta0;
  354. scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
  355. /*
  356.  *  Fill variable parts in scripts.
  357.  */
  358. sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
  359. /*
  360.  *  Setup bus addresses used from the C code..
  361.  */
  362. sym_fw_setup_bus_addresses(np, fw);
  363. }
  364. /*
  365.  *  Allocate firmware descriptors.
  366.  */
  367. #if SYM_CONF_GENERIC_SUPPORT
  368. static struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
  369. #endif /* SYM_CONF_GENERIC_SUPPORT */
  370. static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
  371. /*
  372.  *  Find the most appropriate firmware for a chip.
  373.  */
  374. struct sym_fw * 
  375. sym_find_firmware(struct sym_pci_chip *chip)
  376. {
  377. if (chip->features & FE_LDSTR)
  378. return &sym_fw2;
  379. #if SYM_CONF_GENERIC_SUPPORT
  380. else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC)))
  381. return &sym_fw1;
  382. #endif
  383. else
  384. return 0;
  385. }
  386. /*
  387.  *  Bind a script to physical addresses.
  388.  */
  389. void sym_fw_bind_script (hcb_p np, u32 *start, int len)
  390. {
  391. u32 opcode, new, old, tmp1, tmp2;
  392. u32 *end, *cur;
  393. int relocs;
  394. cur = start;
  395. end = start + len/4;
  396. while (cur < end) {
  397. opcode = *cur;
  398. /*
  399.  *  If we forget to change the length
  400.  *  in scripts, a field will be
  401.  *  padded with 0. This is an illegal
  402.  *  command.
  403.  */
  404. if (opcode == 0) {
  405. printf ("%s: ERROR0 IN SCRIPT at %d.n",
  406. sym_name(np), (int) (cur-start));
  407. MDELAY (10000);
  408. ++cur;
  409. continue;
  410. };
  411. /*
  412.  *  We use the bogus value 0xf00ff00f ;-)
  413.  *  to reserve data area in SCRIPTS.
  414.  */
  415. if (opcode == SCR_DATA_ZERO) {
  416. *cur++ = 0;
  417. continue;
  418. }
  419. if (DEBUG_FLAGS & DEBUG_SCRIPT)
  420. printf ("%d:  <%x>n", (int) (cur-start),
  421. (unsigned)opcode);
  422. /*
  423.  *  We don't have to decode ALL commands
  424.  */
  425. switch (opcode >> 28) {
  426. case 0xf:
  427. /*
  428.  *  LOAD / STORE DSA relative, don't relocate.
  429.  */
  430. relocs = 0;
  431. break;
  432. case 0xe:
  433. /*
  434.  *  LOAD / STORE absolute.
  435.  */
  436. relocs = 1;
  437. break;
  438. case 0xc:
  439. /*
  440.  *  COPY has TWO arguments.
  441.  */
  442. relocs = 2;
  443. tmp1 = cur[1];
  444. tmp2 = cur[2];
  445. if ((tmp1 ^ tmp2) & 3) {
  446. printf ("%s: ERROR1 IN SCRIPT at %d.n",
  447. sym_name(np), (int) (cur-start));
  448. MDELAY (10000);
  449. }
  450. /*
  451.  *  If PREFETCH feature not enabled, remove 
  452.  *  the NO FLUSH bit if present.
  453.  */
  454. if ((opcode & SCR_NO_FLUSH) &&
  455.     !(np->features & FE_PFEN)) {
  456. opcode = (opcode & ~SCR_NO_FLUSH);
  457. }
  458. break;
  459. case 0x0:
  460. /*
  461.  *  MOVE/CHMOV (absolute address)
  462.  */
  463. if (!(np->features & FE_WIDE))
  464. opcode = (opcode | OPC_MOVE);
  465. relocs = 1;
  466. break;
  467. case 0x1:
  468. /*
  469.  *  MOVE/CHMOV (table indirect)
  470.  */
  471. if (!(np->features & FE_WIDE))
  472. opcode = (opcode | OPC_MOVE);
  473. relocs = 0;
  474. break;
  475. #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
  476. case 0x2:
  477. /*
  478.  *  MOVE/CHMOV in target role (absolute address)
  479.  */
  480. opcode &= ~0x20000000;
  481. if (!(np->features & FE_WIDE))
  482. opcode = (opcode & ~OPC_TCHMOVE);
  483. relocs = 1;
  484. break;
  485. case 0x3:
  486. /*
  487.  *  MOVE/CHMOV in target role (table indirect)
  488.  */
  489. opcode &= ~0x20000000;
  490. if (!(np->features & FE_WIDE))
  491. opcode = (opcode & ~OPC_TCHMOVE);
  492. relocs = 0;
  493. break;
  494. #endif
  495. case 0x8:
  496. /*
  497.  *  JUMP / CALL
  498.  *  dont't relocate if relative :-)
  499.  */
  500. if (opcode & 0x00800000)
  501. relocs = 0;
  502. else if ((opcode & 0xf8400000) == 0x80400000)/*JUMP64*/
  503. relocs = 2;
  504. else
  505. relocs = 1;
  506. break;
  507. case 0x4:
  508. case 0x5:
  509. case 0x6:
  510. case 0x7:
  511. relocs = 1;
  512. break;
  513. default:
  514. relocs = 0;
  515. break;
  516. };
  517. /*
  518.  *  Scriptify:) the opcode.
  519.  */
  520. *cur++ = cpu_to_scr(opcode);
  521. /*
  522.  *  If no relocation, assume 1 argument 
  523.  *  and just scriptize:) it.
  524.  */
  525. if (!relocs) {
  526. *cur = cpu_to_scr(*cur);
  527. ++cur;
  528. continue;
  529. }
  530. /*
  531.  *  Otherwise performs all needed relocations.
  532.  */
  533. while (relocs--) {
  534. old = *cur;
  535. switch (old & RELOC_MASK) {
  536. case RELOC_REGISTER:
  537. new = (old & ~RELOC_MASK) + np->mmio_ba;
  538. break;
  539. case RELOC_LABEL_A:
  540. new = (old & ~RELOC_MASK) + np->scripta_ba;
  541. break;
  542. case RELOC_LABEL_B:
  543. new = (old & ~RELOC_MASK) + np->scriptb_ba;
  544. break;
  545. case RELOC_SOFTC:
  546. new = (old & ~RELOC_MASK) + np->hcb_ba;
  547. break;
  548. case 0:
  549. /*
  550.  *  Don't relocate a 0 address.
  551.  *  They are mostly used for patched or 
  552.  *  script self-modified areas.
  553.  */
  554. if (old == 0) {
  555. new = old;
  556. break;
  557. }
  558. /* fall through */
  559. default:
  560. new = 0;
  561. panic("sym_fw_bind_script: "
  562.       "weird relocation %xn", old);
  563. break;
  564. }
  565. *cur++ = cpu_to_scr(new);
  566. }
  567. };
  568. }