11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of PCI-SCSI IO processors. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver is derived from the Linux sym53c8xx driver. 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1998-2000 Gerard Roudier 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a port of the FreeBSD ncr driver to Linux-1.2.13. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The original ncr driver has been written for 386bsd and FreeBSD by 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Wolfgang Stanglmeier <wolf@cologne.de> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Stefan Esser <se@mi.Uni-Koeln.de> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1994 Wolfgang Stanglmeier 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Other major contributions: 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NVRAM detection and reading. 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *----------------------------------------------------------------------------- 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "sym_glue.h" 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Macros used for all firmwares. 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_GEN_A(s, label) ((short) offsetof(s, label)), 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_GEN_B(s, label) ((short) offsetof(s, label)), 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_GEN_Z(s, label) ((short) offsetof(s, label)), 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PADDR_A(label) SYM_GEN_PADDR_A(struct SYM_FWA_SCR, label) 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PADDR_B(label) SYM_GEN_PADDR_B(struct SYM_FWB_SCR, label) 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if SYM_CONF_GENERIC_SUPPORT 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Allocate firmware #1 script area. 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_FWA_SCR sym_fw1a_scr 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_FWB_SCR sym_fw1b_scr 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_FWZ_SCR sym_fw1z_scr 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "sym_fw1.h" 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fwa_ofs sym_fw1a_ofs = { 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_FW_A(struct SYM_FWA_SCR) 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fwb_ofs sym_fw1b_ofs = { 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_FW_B(struct SYM_FWB_SCR) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fwz_ofs sym_fw1z_ofs = { 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_FW_Z(struct SYM_FWZ_SCR) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_FWA_SCR 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_FWB_SCR 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_FWZ_SCR 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* SYM_CONF_GENERIC_SUPPORT */ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Allocate firmware #2 script area. 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_FWA_SCR sym_fw2a_scr 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_FWB_SCR sym_fw2b_scr 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SYM_FWZ_SCR sym_fw2z_scr 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "sym_fw2.h" 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fwa_ofs sym_fw2a_ofs = { 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_FW_A(struct SYM_FWA_SCR) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fwb_ofs sym_fw2b_ofs = { 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_FW_B(struct SYM_FWB_SCR) 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_B(struct SYM_FWB_SCR, start64) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_B(struct SYM_FWB_SCR, pm_handle) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fwz_ofs sym_fw2z_ofs = { 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SYM_GEN_FW_Z(struct SYM_FWZ_SCR) 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_FWA_SCR 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_FWB_SCR 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_FWZ_SCR 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_GEN_A 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_GEN_B 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef SYM_GEN_Z 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef PADDR_A 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef PADDR_B 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if SYM_CONF_GENERIC_SUPPORT 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Patch routine for firmware #1. 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1075111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcoxsym_fw1_patch(struct Scsi_Host *shost) 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1095111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox struct sym_hcb *np = sym_get_hcb(shost); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw1a_scr *scripta0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw1b_scr *scriptb0; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0 = (struct sym_fw1a_scr *) np->scripta0; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0 = (struct sym_fw1b_scr *) np->scriptb0; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remove LED support if not needed. 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_LED0)) { 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->idle[0] = cpu_to_scr(SCR_NO_OP); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->start[0] = cpu_to_scr(SCR_NO_OP); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SYM_CONF_IARB_SUPPORT 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If user does not want to use IMMEDIATE ARBITRATION 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * when we are reselected while attempting to arbitrate, 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * patch the SCRIPTS accordingly with a SCRIPT NO_OP. 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!SYM_CONF_SET_IARB_ON_ARB_LOST) 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Patch some data in SCRIPTS. 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - start and done queue initial bus address. 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - target bus address table bus address. 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* SYM_CONF_GENERIC_SUPPORT */ 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Patch routine for firmware #2. 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1495111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcoxsym_fw2_patch(struct Scsi_Host *shost) 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1515111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox struct sym_data *sym_data = shost_priv(shost); 1525111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox struct pci_dev *pdev = sym_data->pdev; 1535111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox struct sym_hcb *np = sym_data->ncb; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw2a_scr *scripta0; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw2b_scr *scriptb0; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0 = (struct sym_fw2a_scr *) np->scripta0; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0 = (struct sym_fw2b_scr *) np->scriptb0; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remove LED support if not needed. 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_LED0)) { 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->idle[0] = cpu_to_scr(SCR_NO_OP); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->reselected[0] = cpu_to_scr(SCR_NO_OP); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->start[0] = cpu_to_scr(SCR_NO_OP); 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if SYM_CONF_DMA_ADDRESSING_MODE == 2 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remove useless 64 bit DMA specific SCRIPTS, 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * when this feature is not available. 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1744d85b471593d03e141f9160a58574b9204363267Matthew Wilcox if (!use_dac(np)) { 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->is_dmap_dirty[1] = 0; 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->is_dmap_dirty[3] = 0; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SYM_CONF_IARB_SUPPORT 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If user does not want to use IMMEDIATE ARBITRATION 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * when we are reselected while attempting to arbitrate, 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * patch the SCRIPTS accordingly with a SCRIPT NO_OP. 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!SYM_CONF_SET_IARB_ON_ARB_LOST) 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Patch some variable in SCRIPTS. 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - start and done queue initial bus address. 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - target bus address table bus address. 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->startpos[0] = cpu_to_scr(np->squeue_ba); 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->done_pos[0] = cpu_to_scr(np->dqueue_ba); 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->targtbl[0] = cpu_to_scr(np->targtbl_ba); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remove the load of SCNTL4 on reselection if not a C10. 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_C10)) { 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->resel_scntl4[1] = cpu_to_scr(0); 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remove a couple of work-arounds specific to C1010 if 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * they are not desirable. See `sym_fw2.h' for more details. 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2125111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_66 && 2135111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox pdev->revision < 0x1 && 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds np->pciclk_khz < 60000)) { 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->datao_phase[1] = cpu_to_scr(0); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2185111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 /* && 2195111eefa17615bdf17ca00ec2cdca16302c7697eMatthew Wilcox pdev->revision < 0xff */)) { 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0->sel_done[1] = cpu_to_scr(0); 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Patch some other variables in SCRIPTS. 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * These ones are loaded by the SCRIPTS processor. 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->pm0_data_addr[0] = 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_to_scr(np->scripta_ba + 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offsetof(struct sym_fw2a_scr, pm0_data)); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0->pm1_data_addr[0] = 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_to_scr(np->scripta_ba + 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds offsetof(struct sym_fw2a_scr, pm1_data)); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fill the data area in scripts. 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * To be done for all firmwares. 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssym_fw_fill_data (u32 *in, u32 *out) 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < SYM_CONF_MAX_SG; i++) { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *in++ = SCR_CHMOV_TBL ^ SCR_DATA_IN; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *in++ = offsetof (struct sym_dsb, data[i]); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *out++ = SCR_CHMOV_TBL ^ SCR_DATA_OUT; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *out++ = offsetof (struct sym_dsb, data[i]); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup useful script bus addresses. 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * To be done for all firmwares. 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssym_fw_setup_bus_addresses(struct sym_hcb *np, struct sym_fw *fw) 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 *pa; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_short *po; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Build the bus address table for script A 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * from the script A offset table. 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds po = (u_short *) fw->a_ofs; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pa = (u32 *) &np->fwa_bas; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pa[i] = np->scripta_ba + po[i]; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Same for script B. 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds po = (u_short *) fw->b_ofs; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pa = (u32 *) &np->fwb_bas; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++) 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pa[i] = np->scriptb_ba + po[i]; 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Same for script Z. 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds po = (u_short *) fw->z_ofs; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pa = (u32 *) &np->fwz_bas; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0 ; i < sizeof(np->fwz_bas)/sizeof(u32) ; i++) 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pa[i] = np->scriptz_ba + po[i]; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if SYM_CONF_GENERIC_SUPPORT 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup routine for firmware #1. 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssym_fw1_setup(struct sym_hcb *np, struct sym_fw *fw) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw1a_scr *scripta0; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw1b_scr *scriptb0; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0 = (struct sym_fw1a_scr *) np->scripta0; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0 = (struct sym_fw1b_scr *) np->scriptb0; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fill variable parts in scripts. 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_fw_fill_data(scripta0->data_in, scripta0->data_out); 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup bus addresses used from the C code.. 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_fw_setup_bus_addresses(np, fw); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* SYM_CONF_GENERIC_SUPPORT */ 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup routine for firmware #2. 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssym_fw2_setup(struct sym_hcb *np, struct sym_fw *fw) 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw2a_scr *scripta0; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sym_fw2b_scr *scriptb0; 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scripta0 = (struct sym_fw2a_scr *) np->scripta0; 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scriptb0 = (struct sym_fw2b_scr *) np->scriptb0; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fill variable parts in scripts. 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_fw_fill_data(scripta0->data_in, scripta0->data_out); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup bus addresses used from the C code.. 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_fw_setup_bus_addresses(np, fw); 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Allocate firmware descriptors. 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if SYM_CONF_GENERIC_SUPPORT 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic"); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* SYM_CONF_GENERIC_SUPPORT */ 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based"); 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Find the most appropriate firmware for a chip. 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct sym_fw * 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssym_find_firmware(struct sym_chip *chip) 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chip->features & FE_LDSTR) 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &sym_fw2; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if SYM_CONF_GENERIC_SUPPORT 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC))) 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &sym_fw1; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bind a script to physical addresses. 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len) 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 opcode, new, old, tmp1, tmp2; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 *end, *cur; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int relocs; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cur = start; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds end = start + len/4; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (cur < end) { 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = *cur; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we forget to change the length 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in scripts, a field will be 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * padded with 0. This is an illegal 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * command. 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (opcode == 0) { 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf ("%s: ERROR0 IN SCRIPT at %d.\n", 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_name(np), (int) (cur-start)); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++cur; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We use the bogus value 0xf00ff00f ;-) 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to reserve data area in SCRIPTS. 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (opcode == SCR_DATA_ZERO) { 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cur++ = 0; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DEBUG_FLAGS & DEBUG_SCRIPT) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf ("%d: <%x>\n", (int) (cur-start), 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned)opcode); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We don't have to decode ALL commands 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (opcode >> 28) { 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xf: 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LOAD / STORE DSA relative, don't relocate. 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 0; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xe: 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LOAD / STORE absolute. 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 1; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0xc: 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * COPY has TWO arguments. 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 2; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp1 = cur[1]; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp2 = cur[2]; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tmp1 ^ tmp2) & 3) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf ("%s: ERROR1 IN SCRIPT at %d.\n", 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_name(np), (int) (cur-start)); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If PREFETCH feature not enabled, remove 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the NO FLUSH bit if present. 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((opcode & SCR_NO_FLUSH) && 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds !(np->features & FE_PFEN)) { 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = (opcode & ~SCR_NO_FLUSH); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x0: 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOVE/CHMOV (absolute address) 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_WIDE)) 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = (opcode | OPC_MOVE); 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 1; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1: 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOVE/CHMOV (table indirect) 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_WIDE)) 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = (opcode | OPC_MOVE); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 0; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SYM_CONF_TARGET_ROLE_SUPPORT 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x2: 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOVE/CHMOV in target role (absolute address) 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode &= ~0x20000000; 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_WIDE)) 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = (opcode & ~OPC_TCHMOVE); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 1; 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x3: 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOVE/CHMOV in target role (table indirect) 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode &= ~0x20000000; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(np->features & FE_WIDE)) 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = (opcode & ~OPC_TCHMOVE); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 0; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x8: 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * JUMP / CALL 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * don't relocate if relative :-) 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (opcode & 0x00800000) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 0; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if ((opcode & 0xf8400000) == 0x80400000)/*JUMP64*/ 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 2; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 1; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4: 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x5: 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x6: 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x7: 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 1; 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds relocs = 0; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Scriptify:) the opcode. 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cur++ = cpu_to_scr(opcode); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If no relocation, assume 1 argument 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and just scriptize:) it. 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!relocs) { 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cur = cpu_to_scr(*cur); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++cur; 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Otherwise performs all needed relocations. 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (relocs--) { 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds old = *cur; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (old & RELOC_MASK) { 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RELOC_REGISTER: 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = (old & ~RELOC_MASK) + np->mmio_ba; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RELOC_LABEL_A: 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = (old & ~RELOC_MASK) + np->scripta_ba; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RELOC_LABEL_B: 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = (old & ~RELOC_MASK) + np->scriptb_ba; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case RELOC_SOFTC: 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = (old & ~RELOC_MASK) + np->hcb_ba; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Don't relocate a 0 address. 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * They are mostly used for patched or 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * script self-modified areas. 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (old == 0) { 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = old; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fall through */ 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = 0; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds panic("sym_fw_bind_script: " 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "weird relocation %x\n", old); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cur++ = cpu_to_scr(new); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 555