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