patch-2.4.19 linux-2.4.19/arch/mips/sgi-ip22/ip22-berr.c

Next file: linux-2.4.19/arch/mips/sgi-ip22/ip22-gio.c
Previous file: linux-2.4.19/arch/mips/sgi-ip22/Makefile
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/mips/sgi-ip22/ip22-berr.c linux-2.4.19/arch/mips/sgi-ip22/ip22-berr.c
@@ -0,0 +1,78 @@
+/*
+ * ip22-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002 Ladislav Michl
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+
+unsigned int cpu_err_stat;	/* Status reg for CPU */
+unsigned int gio_err_stat;	/* Status reg for GIO */
+unsigned int cpu_err_addr;	/* Error address reg for CPU */
+unsigned int gio_err_addr;	/* Error address reg for GIO */
+
+volatile int nofault;
+
+static void save_and_clear_buserr(void)
+{
+	/* save memory controler's error status registers */ 
+	cpu_err_addr = mcmisc_regs->cerr;
+	cpu_err_stat = mcmisc_regs->cstat;
+	gio_err_addr = mcmisc_regs->gerr;
+	gio_err_stat = mcmisc_regs->gstat;
+
+	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition, 
+ * if the error happened during a CPU read, it also asserts the bus error 
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+void be_ip22_interrupt(int irq, struct pt_regs *regs)
+{
+	save_and_clear_buserr();
+	printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
+}
+
+int be_ip22_handler(struct pt_regs *regs, int is_fixup)
+{
+	save_and_clear_buserr();
+	if (nofault) {
+		nofault = 0;
+		compute_return_epc(regs);
+		return MIPS_BE_DISCARD;
+	}
+	return MIPS_BE_FIXUP;
+}
+
+int ip22_baddr(unsigned int *val, unsigned long addr)
+{
+	nofault = 1;
+	*val = *(volatile unsigned int *) addr;
+	__asm__ __volatile__("nop;nop;nop;nop");
+	if (nofault) {
+		nofault = 0;
+		return 0;
+	}
+	return -EFAULT;
+}
+
+void __init bus_error_init(void)
+{
+	be_board_handler = be_ip22_handler;
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)