patch-2.1.79 linux/arch/alpha/kernel/cia.c

Next file: linux/arch/alpha/kernel/entry.S
Previous file: linux/arch/alpha/kernel/bios32.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.78/linux/arch/alpha/kernel/cia.c linux/arch/alpha/kernel/cia.c
@@ -6,7 +6,6 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/bios32.h>
 #include <linux/pci.h>
@@ -38,12 +37,19 @@
  * BIOS32-style PCI interface:
  */
 
-#ifdef CONFIG_ALPHA_CIA
+/* #define DEBUG_MCHECK */
+/* #define DEBUG_CONFIG */
+/* #define DEBUG_DUMP_REGS */
 
-#ifdef DEBUG 
-# define DBG(args)	printk args
+#ifdef DEBUG_MCHECK
+# define DBGM(args)	printk args
 #else
-# define DBG(args)
+# define DBGM(args)
+#endif
+#ifdef DEBUG_CONFIG
+# define DBGC(args)	printk args
+#else
+# define DBGC(args)
 #endif
 
 #define vulp	volatile unsigned long *
@@ -51,7 +57,7 @@
 
 static volatile unsigned int CIA_mcheck_expected = 0;
 static volatile unsigned int CIA_mcheck_taken = 0;
-static unsigned long CIA_jd;
+static unsigned int CIA_jd;
 
 
 /*
@@ -101,8 +107,9 @@
 {
 	unsigned long addr;
 
-	DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n",
-	     bus, device_fn, where, pci_addr, type1));
+	DBGC(("mk_conf_addr(bus=%d, device_fn=0x%x, where=0x%x, "
+	      "pci_addr=0x%p, type1=0x%p)\n",
+	      bus, device_fn, where, pci_addr, type1));
 
 	if (bus == 0) {
 		int device = device_fn >> 3;
@@ -110,7 +117,8 @@
 		/* type 0 configuration cycle: */
 
 		if (device > 20) {
-			DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", device));
+			DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
+			      device));
 			return -1;
 		}
 
@@ -122,7 +130,7 @@
 		addr = (bus << 16) | (device_fn << 8) | (where);
 	}
 	*pci_addr = addr;
-	DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+	DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
 	return 0;
 }
 
@@ -133,22 +141,25 @@
 	unsigned int stat0, value;
 	unsigned int cia_cfg = 0; /* to keep gcc quiet */
 
+	value = 0xffffffffU;
+	mb();
+
 	save_flags(flags);	/* avoid getting hit by machine check */
 	cli();
 
-	DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+	DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
 
 	/* reset status register to avoid losing errors: */
-	stat0 = *((volatile unsigned int *)CIA_IOC_CIA_ERR);
-	*((volatile unsigned int *)CIA_IOC_CIA_ERR) = stat0;
+	stat0 = *(vuip)CIA_IOC_CIA_ERR;
+	*(vuip)CIA_IOC_CIA_ERR = stat0;
 	mb();
-	DBG(("conf_read: CIA ERR was 0x%x\n", stat0));
+	DBGC(("conf_read: CIA ERR was 0x%x\n", stat0));
 	/* if Type1 access, must set CIA CFG */
 	if (type1) {
-		cia_cfg = *((unsigned int *)CIA_IOC_CFG);
+		cia_cfg = *(vuip)CIA_IOC_CFG;
+		*(vuip)CIA_IOC_CFG = cia_cfg | 1;
 		mb();
-		*((unsigned int *)CIA_IOC_CFG) = cia_cfg | 1;
-		DBG(("conf_read: TYPE1 access\n"));
+		DBGC(("conf_read: TYPE1 access\n"));
 	}
 
 	mb();
@@ -157,8 +168,7 @@
 	CIA_mcheck_taken = 0;
 	mb();
 	/* access configuration space: */
-	value = *((volatile unsigned int *)addr);
-	mb();
+	value = *(vuip)addr;
 	mb();
 	if (CIA_mcheck_taken) {
 		CIA_mcheck_taken = 0;
@@ -167,26 +177,25 @@
 	}
 	CIA_mcheck_expected = 0;
 	mb();
-	/*
-	 * david.rusling@reo.mts.dec.com.  This code is needed for the
-	 * EB64+ as it does not generate a machine check (why I don't
-	 * know).  When we build kernels for one particular platform
-	 * then we can make this conditional on the type.
-	 */
+
 #if 0
+	/*
+	  this code might be necessary if machine checks aren't taken,
+	  but I can't get it to work on CIA-2, so its disabled.
+	  */
 	draina();
 
 	/* now look for any errors */
-	stat0 = *((unsigned int *)CIA_IOC_CIA_ERR);
-	DBG(("conf_read: CIA ERR after read 0x%x\n", stat0));
-	if (stat0 & 0x8280U) { /* is any error bit set? */
-		/* if not NDEV, print status */
+	stat0 = *(vuip)CIA_IOC_CIA_ERR;
+	DBGC(("conf_read: CIA ERR after read 0x%x\n", stat0));
+	if (stat0 & 0x8FEF0FFFU) { /* is any error bit set? */
+		/* if not MAS_ABT, print status */
 		if (!(stat0 & 0x0080)) {
 			printk("CIA.c:conf_read: got stat0=%x\n", stat0);
 		}
 
 		/* reset error status: */
-		*((volatile unsigned long *)CIA_IOC_CIA_ERR) = stat0;
+		*(vuip)CIA_IOC_CIA_ERR = stat0;
 		mb();
 		wrmces(0x7);			/* reset machine check */
 		value = 0xffffffff;
@@ -195,18 +204,19 @@
 
 	/* if Type1 access, must reset IOC CFG so normal IO space ops work */
 	if (type1) {
-		*((unsigned int *)CIA_IOC_CFG) = cia_cfg & ~1;
+		*(vuip)CIA_IOC_CFG = cia_cfg & ~1;
 		mb();
 	}
 
-	DBG(("conf_read(): finished\n"));
+	DBGC(("conf_read(): finished\n"));
 
 	restore_flags(flags);
 	return value;
 }
 
 
-static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
+static void conf_write(unsigned long addr, unsigned int value,
+		       unsigned char type1)
 {
 	unsigned long flags;
 	unsigned int stat0;
@@ -216,47 +226,46 @@
 	cli();
 
 	/* reset status register to avoid losing errors: */
-	stat0 = *((volatile unsigned int *)CIA_IOC_CIA_ERR);
-	*((volatile unsigned int *)CIA_IOC_CIA_ERR) = stat0;
+	stat0 = *(vuip)CIA_IOC_CIA_ERR;
+	*(vuip)CIA_IOC_CIA_ERR = stat0;
 	mb();
-	DBG(("conf_write: CIA ERR was 0x%x\n", stat0));
+	DBGC(("conf_write: CIA ERR was 0x%x\n", stat0));
 	/* if Type1 access, must set CIA CFG */
 	if (type1) {
-		cia_cfg = *((unsigned int *)CIA_IOC_CFG);
+		cia_cfg = *(vuip)CIA_IOC_CFG;
+		*(vuip)CIA_IOC_CFG = cia_cfg | 1;
 		mb();
-		*((unsigned int *)CIA_IOC_CFG) = cia_cfg | 1;
-		DBG(("conf_read: TYPE1 access\n"));
+		DBGC(("conf_write: TYPE1 access\n"));
 	}
 
 	draina();
 	CIA_mcheck_expected = 1;
 	mb();
 	/* access configuration space: */
-	*((volatile unsigned int *)addr) = value;
-	mb();
+	*(vuip)addr = value;
 	mb();
+
 	CIA_mcheck_expected = 0;
 	mb();
+
+#if 0
 	/*
-	 * david.rusling@reo.mts.dec.com.  This code is needed for the
-	 * EB64+ as it does not generate a machine check (why I don't
-	 * know).  When we build kernels for one particular platform
-	 * then we can make this conditional on the type.
+	 * This code might be necessary if machine checks aren't taken,
+	 * but I can't get it to work on CIA-2, so its disabled.
 	 */
-#if 0
 	draina();
 
-	/* now look for any errors */
-	stat0 = *((unsigned int *)CIA_IOC_CIA_ERR);
-	DBG(("conf_write: CIA ERR after write 0x%x\n", stat0));
-	if (stat0 & 0x8280U) { /* is any error bit set? */
-		/* if not NDEV, print status */
+	/* Now look for any errors */
+	stat0 = *(vuip)CIA_IOC_CIA_ERR;
+	DBGC(("conf_write: CIA ERR after write 0x%x\n", stat0));
+	if (stat0 & 0x8FEF0FFFU) { /* is any error bit set? */
+		/* If not MAS_ABT, print status */
 		if (!(stat0 & 0x0080)) {
 			printk("CIA.c:conf_read: got stat0=%x\n", stat0);
 		}
 
 		/* reset error status: */
-		*((volatile unsigned long *)CIA_IOC_CIA_ERR) = stat0;
+		*(vulp)CIA_IOC_CIA_ERR = stat0;
 		mb();
 		wrmces(0x7);			/* reset machine check */
 		value = 0xffffffff;
@@ -265,11 +274,11 @@
 
 	/* if Type1 access, must reset IOC CFG so normal IO space ops work */
 	if (type1) {
-		*((unsigned int *)CIA_IOC_CFG) = cia_cfg & ~1;
+		*(vuip)CIA_IOC_CFG = cia_cfg & ~1;
 		mb();
 	}
 
-	DBG(("conf_write(): finished\n"));
+	DBGC(("conf_write(): finished\n"));
 	restore_flags(flags);
 }
 
@@ -390,15 +399,58 @@
 
 unsigned long cia_init(unsigned long mem_start, unsigned long mem_end)
 {
-        unsigned int cia_err ;
+        unsigned int cia_tmp;
+
+#ifdef DEBUG_DUMP_REGS
+	{
+		unsigned int temp;
+		temp = *(vuip)CIA_IOC_CIA_REV; mb();
+		printk("CIA_init: CIA_REV was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_PCI_LAT; mb();
+		printk("CIA_init: CIA_PCI_LAT was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
+		printk("CIA_init: CIA_CTRL was 0x%x\n", temp);
+		temp = *(vuip)0xfffffc8740000140UL; mb();
+		printk("CIA_init: CIA_CTRL1 was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_HAE_MEM; mb();
+		printk("CIA_init: CIA_HAE_MEM was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_HAE_IO; mb();
+		printk("CIA_init: CIA_HAE_IO was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CFG; mb();
+		printk("CIA_init: CIA_CFG was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CACK_EN; mb();
+		printk("CIA_init: CIA_CACK_EN was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CFG; mb();
+		printk("CIA_init: CIA_CFG was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CIA_DIAG; mb();
+		printk("CIA_init: CIA_DIAG was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_DIAG_CHECK; mb();
+		printk("CIA_init: CIA_DIAG_CHECK was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_PERF_MONITOR; mb();
+		printk("CIA_init: CIA_PERF_MONITOR was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_PERF_CONTROL; mb();
+		printk("CIA_init: CIA_PERF_CONTROL was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CIA_ERR; mb();
+		printk("CIA_init: CIA_ERR was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_CIA_STAT; mb();
+		printk("CIA_init: CIA_STAT was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_MCR; mb();
+		printk("CIA_init: CIA_MCR was 0x%x\n", temp);
+	}
+#endif /* DEBUG_DUMP_REGS */
 
         /* 
 	 * Set up error reporting.
 	 */
-	cia_err = *(vuip)CIA_IOC_CIA_ERR ;
-	cia_err |= (0x1 << 7) ;   /* master abort */
-	*(vuip)CIA_IOC_CIA_ERR = cia_err ;
-	mb() ;
+	cia_tmp = *(vuip)CIA_IOC_CIA_ERR;
+	cia_tmp |= 0x180;   /* master, target abort */
+	*(vuip)CIA_IOC_CIA_ERR = cia_tmp;
+	mb();
+
+	cia_tmp = *(vuip)CIA_IOC_CIA_CTRL;
+	cia_tmp |= 0x400;   /* turn on FILL_ERR to get mchecks */
+	*(vuip)CIA_IOC_CIA_CTRL = cia_tmp;
+	mb();
 
 	/*
 	 * Set up the PCI->physical memory translation windows.
@@ -411,16 +463,16 @@
  	*(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN_SIZE - 1) & 0xfff00000U;
 	*(vuip)CIA_IOC_PCI_T0_BASE = 0;
 
-	*(vuip)CIA_IOC_PCI_W1_BASE = 0x0 ;
-	*(vuip)CIA_IOC_PCI_W2_BASE = 0x0 ;
-	*(vuip)CIA_IOC_PCI_W3_BASE = 0x0 ;
+	*(vuip)CIA_IOC_PCI_W1_BASE = 0x0;
+	*(vuip)CIA_IOC_PCI_W2_BASE = 0x0;
+	*(vuip)CIA_IOC_PCI_W3_BASE = 0x0;
 
 	/*
 	 * check ASN in HWRPB for validity, report if bad
 	 */
 	if (hwrpb->max_asn != MAX_ASN) {
 		printk("CIA_init: max ASN from HWRPB is bad (0x%lx)\n",
-			hwrpb->max_asn);
+		       hwrpb->max_asn);
 		hwrpb->max_asn = MAX_ASN;
 	}
 
@@ -432,20 +484,29 @@
          */
         {
 #if 0
-          unsigned int cia_cfg = *((unsigned int *)CIA_IOC_CFG); mb();
-          if (cia_cfg) printk("CIA_init: CFG was 0x%x\n", cia_cfg);
+		unsigned int cia_cfg = *(vuip)CIA_IOC_CFG; mb();
+		if (cia_cfg) printk("CIA_init: CFG was 0x%x\n", cia_cfg);
 #endif
-          *((unsigned int *)CIA_IOC_CFG) = 0; mb();
+		*(vuip)CIA_IOC_CFG = 0; mb();
         }
  
+#if 0
+	{
+		unsigned int temp;
+		temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
+		printk("CIA_init: CIA_CTRL was 0x%x\n", temp);
+		temp = *(vuip)CIA_IOC_ERR_MASK; mb();
+		printk("CIA_init: CIA_ERR_MASK was 0x%x\n", temp);
+	}
+#endif
 	return mem_start;
 }
 
 int cia_pci_clr_err(void)
 {
-	CIA_jd = *((unsigned int *)CIA_IOC_CIA_ERR);
-	DBG(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
-	*((unsigned long *)CIA_IOC_CIA_ERR) = 0x0080;
+	CIA_jd = *(vuip)CIA_IOC_CIA_ERR;
+	DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
+	*(vulp)CIA_IOC_CIA_ERR = 0x0180;
 	mb();
 	return 0;
 }
@@ -462,17 +523,21 @@
 	long i;
 
 	mchk_header = (struct el_common *)la_ptr;
-	mchk_procdata =
-		(struct el_procdata *)(la_ptr + mchk_header->proc_offset);
-	mchk_sysdata = 
-	  (struct el_CIA_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
-
-	DBG(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr));
-	DBG(("                     pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-	     regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset));
-	DBG(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
-	     CIA_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
-#ifdef DEBUG
+	mchk_procdata = (struct el_procdata *)
+		(la_ptr + mchk_header->proc_offset);
+	mchk_sysdata = (struct el_CIA_sysdata_mcheck *)
+		(la_ptr + mchk_header->sys_offset);
+
+	DBGM(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+	      vector, la_ptr));
+	DBGM(("                     pc=0x%lx size=0x%x procoffset=0x%x "
+	      "sysoffset 0x%x\n", regs->pc, mchk_header->size,
+	      mchk_header->proc_offset, mchk_header->sys_offset));
+	DBGM(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+	      CIA_mcheck_expected, mchk_sysdata->epic_dcsr,
+	      mchk_sysdata->epic_pear));
+
+#ifdef DEBUG_MCHECK
 	{
 		unsigned long *ptr;
 		int i;
@@ -483,15 +548,15 @@
 			       ptr[i], ptr[i+1]);
 		}
 	}
-#endif /* DEBUG */
+#endif
+
 	/*
 	 * Check if machine check is due to a badaddr() and if so,
 	 * ignore the machine check.
 	 */
 	mb();
-	mb();
-	if (CIA_mcheck_expected/* && (mchk_sysdata->epic_dcsr && 0x0c00UL)*/) {
-		DBG(("CIA machine check expected\n"));
+	if (CIA_mcheck_expected) {
+		DBGM(("CIA machine check expected\n"));
 		CIA_mcheck_expected = 0;
 		CIA_mcheck_taken = 1;
 		mb();
@@ -504,34 +569,34 @@
 	}
 
 	switch ((unsigned int) mchk_header->code) {
-	      case MCHK_K_TPERR:	reason = "tag parity error"; break;
-	      case MCHK_K_TCPERR:	reason = "tag control parity error"; break;
-	      case MCHK_K_HERR:		reason = "generic hard error"; break;
-	      case MCHK_K_ECC_C:	reason = "correctable ECC error"; break;
-	      case MCHK_K_ECC_NC:	reason = "uncorrectable ECC error"; break;
-	      case MCHK_K_OS_BUGCHECK:	reason = "OS-specific PAL bugcheck"; break;
-	      case MCHK_K_PAL_BUGCHECK:	reason = "callsys in kernel mode"; break;
-	      case 0x96: reason = "i-cache read retryable error"; break;
-	      case 0x98: reason = "processor detected hard error"; break;
+	case MCHK_K_TPERR:	reason = "tag parity error"; break;
+	case MCHK_K_TCPERR:	reason = "tag control parity error"; break;
+	case MCHK_K_HERR:		reason = "generic hard error"; break;
+	case MCHK_K_ECC_C:	reason = "correctable ECC error"; break;
+	case MCHK_K_ECC_NC:	reason = "uncorrectable ECC error"; break;
+	case MCHK_K_OS_BUGCHECK:	reason = "OS-specific PAL bugcheck"; break;
+	case MCHK_K_PAL_BUGCHECK:	reason = "callsys in kernel mode"; break;
+	case 0x96: reason = "i-cache read retryable error"; break;
+	case 0x98: reason = "processor detected hard error"; break;
 
 		/* system specific (these are for Alcor, at least): */
-	      case 0x203: reason = "system detected uncorrectable ECC error"; break;
-	      case 0x205: reason = "parity error detected by CIA"; break;
-	      case 0x207: reason = "non-existent memory error"; break;
-	      case 0x209: reason = "PCI SERR detected"; break;
-	      case 0x20b: reason = "PCI data parity error detected"; break;
-	      case 0x20d: reason = "PCI address parity error detected"; break;
-	      case 0x20f: reason = "PCI master abort error"; break;
-	      case 0x211: reason = "PCI target abort error"; break;
-	      case 0x213: reason = "scatter/gather PTE invalid error"; break;
-	      case 0x215: reason = "flash ROM write error"; break;
-	      case 0x217: reason = "IOA timeout detected"; break;
-	      case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
-	      case 0x21b: reason = "EISA fail-safe timer timeout"; break;
-	      case 0x21d: reason = "EISA bus time-out"; break;
-	      case 0x21f: reason = "EISA software generated NMI"; break;
-	      case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
-	      default:
+	case 0x203: reason = "system detected uncorrectable ECC error"; break;
+	case 0x205: reason = "parity error detected by CIA"; break;
+	case 0x207: reason = "non-existent memory error"; break;
+	case 0x209: reason = "PCI SERR detected"; break;
+	case 0x20b: reason = "PCI data parity error detected"; break;
+	case 0x20d: reason = "PCI address parity error detected"; break;
+	case 0x20f: reason = "PCI master abort error"; break;
+	case 0x211: reason = "PCI target abort error"; break;
+	case 0x213: reason = "scatter/gather PTE invalid error"; break;
+	case 0x215: reason = "flash ROM write error"; break;
+	case 0x217: reason = "IOA timeout detected"; break;
+	case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
+	case 0x21b: reason = "EISA fail-safe timer timeout"; break;
+	case 0x21d: reason = "EISA bus time-out"; break;
+	case 0x21f: reason = "EISA software generated NMI"; break;
+	case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
+	default:
 		sprintf(buf, "reason for machine-check unknown (0x%x)",
 			(unsigned int) mchk_header->code);
 		reason = buf;
@@ -542,14 +607,14 @@
 
 	printk(KERN_CRIT "  CIA machine check: %s%s\n",
 	       reason, mchk_header->retry ? " (retryable)" : "");
+	printk(KERN_CRIT "   vector=0x%lx la_ptr=0x%lx pc=0x%lx\n",
+	       vector, la_ptr, regs->pc);
 
 	/* dump the the logout area to give all info: */
 
 	ptr = (unsigned long *)la_ptr;
 	for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-	    printk(KERN_CRIT " +%8lx %016lx %016lx\n",
-		   i*sizeof(long), ptr[i], ptr[i+1]);
+		printk(KERN_CRIT " +%8lx %016lx %016lx\n",
+		       i*sizeof(long), ptr[i], ptr[i+1]);
 	}
 }
-
-#endif /* CONFIG_ALPHA_CIA */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov