System-specific handling of bus errors for DECstation variations
authorMaciej W. Rozycki <macro@linux-mips.org>
Wed, 22 Jun 2005 20:56:26 +0000 (20:56 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Sat, 29 Oct 2005 18:31:30 +0000 (19:31 +0100)
supporting parity errors only for memory (Pmax/3min/Maxine).
Fixes for resources decoded by the KN04/KN05 MB ASIC.  Additional
clean-ups for the ECC handler.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/dec/Makefile
arch/mips/dec/ecc-berr.c
arch/mips/dec/kn02-irq.c
arch/mips/dec/setup.c
include/asm-mips/dec/ecc.h
include/asm-mips/dec/kn01.h
include/asm-mips/dec/kn02.h
include/asm-mips/dec/kn02xa.h
include/asm-mips/dec/kn05.h

index 688757a..ed181fd 100644 (file)
@@ -2,8 +2,8 @@
 # Makefile for the DECstation family specific parts of the kernel
 #
 
-obj-y          := ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \
-                  setup.o time.o
+obj-y          := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
+                  kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
 
 obj-$(CONFIG_PROM_CONSOLE)     += promcon.o
 obj-$(CONFIG_CPU_HAS_WB)       += wbflush.o
index a36503c..8f3498a 100644 (file)
@@ -6,7 +6,7 @@
  *     5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
  *     5900/260 (KN05) systems.
  *
- *     Copyright (c) 2003  Maciej W. Rozycki
+ *     Copyright (c) 2003, 2005  Maciej W. Rozycki
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -15,6 +15,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
@@ -57,7 +58,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
 
        const char *kind, *agent, *cycle, *event;
        const char *status = "", *xbit = "", *fmt = "";
-       dma_addr_t address;
+       unsigned long address;
        u16 syn = 0, sngl;
 
        int i = 0;
@@ -66,7 +67,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
        u32 chksyn = *kn0x_chksyn;
        int action = MIPS_BE_FATAL;
 
-       /* For non-ECC ack ASAP, so any subsequent errors get caught. */
+       /* For non-ECC ack ASAP, so that any subsequent errors get caught. */
        if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
                dec_ecc_be_ack();
 
@@ -74,7 +75,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
 
        if (!(erraddr & KN0X_EAR_VALID)) {
                /* No idea what happened. */
-               printk(KERN_ALERT "Unidentified bus error %s.\n", kind);
+               printk(KERN_ALERT "Unidentified bus error %s\n", kind);
                return action;
        }
 
@@ -126,7 +127,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
                        /* Ack now, no rewrite will happen. */
                        dec_ecc_be_ack();
 
-                       fmt = KERN_ALERT "%s" "invalid.\n";
+                       fmt = KERN_ALERT "%s" "invalid\n";
                } else {
                        sngl = syn & KN0X_ESR_SNGLO;
                        syn &= KN0X_ESR_SYNLO;
@@ -161,12 +162,12 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
                                if (syn == 0x01) {
                                        fmt = KERN_ALERT "%s"
                                              "%#04x -- %s bit error "
-                                             "at check bit C%s.\n";
+                                             "at check bit C%s\n";
                                        xbit = "X";
                                } else {
                                        fmt = KERN_ALERT "%s"
                                              "%#04x -- %s bit error "
-                                             "at check bit C%s%u.\n";
+                                             "at check bit C%s%u\n";
                                }
                                i = syn >> 2;
                        } else {
@@ -176,16 +177,16 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
                                if (i < 32)
                                        fmt = KERN_ALERT "%s"
                                              "%#04x -- %s bit error "
-                                             "at data bit D%s%u.\n";
+                                             "at data bit D%s%u\n";
                                else
                                        fmt = KERN_ALERT "%s"
-                                             "%#04x -- %s bit error.\n";
+                                             "%#04x -- %s bit error\n";
                        }
                }
        }
 
        if (action != MIPS_BE_FIXUP)
-               printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n",
+               printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
                        kind, agent, cycle, event, address);
 
        if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
@@ -207,8 +208,8 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                return IRQ_HANDLED;
 
        /*
-        * FIXME: Find affected processes and kill them, otherwise we
-        * must die.
+        * FIXME: Find the affected processes and kill them, otherwise
+        * we must die.
         *
         * The interrupt is asynchronously delivered thus EPC and RA
         * may be irrelevant, but are printed for a reference.
@@ -235,7 +236,7 @@ static inline void dec_kn02_be_init(void)
        spin_lock_irqsave(&kn02_lock, flags);
 
        /* Preset write-only bits of the Control Register cache. */
-       cached_kn02_csr = *csr | KN03_CSR_LEDS;
+       cached_kn02_csr = *csr | KN02_CSR_LEDS;
 
        /* Set normal ECC detection and generation. */
        cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
@@ -250,7 +251,7 @@ static inline void dec_kn02_be_init(void)
 static inline void dec_kn03_be_init(void)
 {
        volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR);
-       volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR);
+       volatile u32 *mbcs = (void *)(KN4K_SLOT_BASE + KN4K_MB_CSR);
 
        kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR);
        kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN);
@@ -265,7 +266,7 @@ static inline void dec_kn03_be_init(void)
        *mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
               KN03_MCR_CORRECT;
        if (current_cpu_data.cputype == CPU_R4400SC)
-               *mbcs |= KN05_MB_CSR_EE;
+               *mbcs |= KN4K_MB_CSR_EE;
        fast_iob();
 }
 
index e0bfcd1..644085e 100644 (file)
@@ -4,7 +4,7 @@
  *     DECstation 5000/200 (KN02) Control and Status Register
  *     interrupts.
  *
- *     Copyright (c) 2002, 2003  Maciej W. Rozycki
+ *     Copyright (c) 2002, 2003, 2005  Maciej W. Rozycki
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -111,7 +111,7 @@ void __init init_kn02_irqs(int base)
 
        /* Mask interrupts. */
        spin_lock_irqsave(&kn02_lock, flags);
-       cached_kn02_csr &= ~KN03_CSR_IOINTEN;
+       cached_kn02_csr &= ~KN02_CSR_IOINTEN;
        *csr = cached_kn02_csr;
        iob();
        spin_unlock_irqrestore(&kn02_lock, flags);
index 82408ce..f63fb9c 100644 (file)
@@ -113,7 +113,16 @@ void __init dec_be_init(void)
 {
        switch (mips_machtype) {
        case MACH_DS23100:      /* DS2100/DS3100 Pmin/Pmax */
+               board_be_handler = dec_kn01_be_handler;
+               busirq.handler = dec_kn01_be_interrupt;
                busirq.flags |= SA_SHIRQ;
+               dec_kn01_be_init();
+               break;
+       case MACH_DS5000_1XX:   /* DS5000/1xx 3min */
+       case MACH_DS5000_XX:    /* DS5000/xx Maxine */
+               board_be_handler = dec_kn02xa_be_handler;
+               busirq.handler = dec_kn02xa_be_interrupt;
+               dec_kn02xa_be_init();
                break;
        case MACH_DS5000_200:   /* DS5000/200 3max */
        case MACH_DS5000_2X0:   /* DS5000/240 3max+ */
index 724908b..19495a4 100644 (file)
@@ -49,7 +49,8 @@ struct pt_regs;
 
 extern void dec_ecc_be_init(void);
 extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup);
-extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id,
+                                       struct pt_regs *regs);
 #endif
 
 #endif /* __ASM_MIPS_DEC_ECC_H */
index 325fcbb..607a385 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
  * are by courtesy of Chris Fraser.
- * Copyright (C) 2002, 2003  Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
  */
 #ifndef __ASM_MIPS_DEC_KN01_H
 #define __ASM_MIPS_DEC_KN01_H
 #define KN01_CSR_VRGTRB                (1<<0)  /* red DAC voltage over blue (r/o) */
 #define KN01_CSR_LEDS          (0xff<<0) /* ~diagnostic LEDs (w/o) */
 
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct pt_regs;
+
+extern u16 cached_kn01_csr;
+extern spinlock_t kn01_lock;
+
+extern void dec_kn01_be_init(void);
+extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
+                                        struct pt_regs *regs);
+#endif
+
 #endif /* __ASM_MIPS_DEC_KN01_H */
index 2c935f9..83a042e 100644 (file)
@@ -8,16 +8,11 @@
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
  * are by courtesy of Chris Fraser.
- * Copyright (C) 2002, 2003  Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
  */
 #ifndef __ASM_MIPS_DEC_KN02_H
 #define __ASM_MIPS_DEC_KN02_H
 
-#ifndef __ASSEMBLY__
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#endif
-
 #include <asm/addrspace.h>
 #include <asm/dec/ecc.h>
 
@@ -53,8 +48,8 @@
 #define KN02_CSR_PSU           (1<<27)         /* power supply unit warning */
 #define KN02_CSR_NVRAM         (1<<26)         /* ~NVRAM clear jumper */
 #define KN02_CSR_REFEVEN       (1<<25)         /* mem refresh bank toggle */
-#define KN03_CSR_NRMOD         (1<<24)         /* ~NRMOD manufact. jumper */
-#define KN03_CSR_IOINTEN       (0xff<<16)      /* IRQ mask bits */
+#define KN02_CSR_NRMOD         (1<<24)         /* ~NRMOD manufact. jumper */
+#define KN02_CSR_IOINTEN       (0xff<<16)      /* IRQ mask bits */
 #define KN02_CSR_DIAGCHK       (1<<15)         /* diagn/norml ECC reads */
 #define KN02_CSR_DIAGGEN       (1<<14)         /* diagn/norml ECC writes */
 #define KN02_CSR_CORRECT       (1<<13)         /* ECC correct/check */
@@ -63,8 +58,8 @@
 #define KN02_CSR_BNK32M                (1<<10)         /* 32M/8M stride */
 #define KN02_CSR_DIAGDN                (1<<9)          /* DIAGDN manufact. jumper */
 #define KN02_CSR_BAUD38                (1<<8)          /* DZ11 38/19kbps ext. rate */
-#define KN03_CSR_IOINT         (0xff<<0)       /* IRQ status bits (r/o) */
-#define KN03_CSR_LEDS          (0xff<<0)       /* ~diagnostic LEDs (w/o) */
+#define KN02_CSR_IOINT         (0xff<<0)       /* IRQ status bits (r/o) */
+#define KN02_CSR_LEDS          (0xff<<0)       /* ~diagnostic LEDs (w/o) */
 
 
 /*
 
 
 #ifndef __ASSEMBLY__
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
 extern u32 cached_kn02_csr;
 extern spinlock_t kn02_lock;
 extern void init_kn02_irqs(int base);
index f6bdf73..3c25a33 100644 (file)
@@ -9,7 +9,7 @@
  *
  * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
  * are by courtesy of Chris Fraser.
- * Copyright (C) 2000, 2002, 2003  Maciej W. Rozycki
+ * Copyright (C) 2000, 2002, 2003, 2005  Maciej W. Rozycki
  *
  * These are addresses which have to be known early in the boot process.
  * For other addresses refer to tc.h, ioasic_addrs.h and friends.
 #define KN02XA_MER_PAGERR      (1<<16)         /* 2k page boundary error */
 #define KN02XA_MER_TRANSERR    (1<<15)         /* transfer length error */
 #define KN02XA_MER_PARDIS      (1<<14)         /* parity error disable */
-#define KN02XA_MER_RES_12      (0x3<<12)       /* unused */
-#define KN02XA_MER_BYTERR      (0xf<<8)        /* byte lane error bitmask */
+#define KN02XA_MER_SIZE                (1<<13)         /* r/o mirror of MSR_SIZE */
+#define KN02XA_MER_RES_12      (1<<12)         /* unused */
+#define KN02XA_MER_BYTERR      (0xf<<8)        /* byte lane error bitmask: */
+#define KN02XA_MER_BYTERR_3    (0x8<<8)        /* byte lane #3 */
+#define KN02XA_MER_BYTERR_2    (0x4<<8)        /* byte lane #2 */
+#define KN02XA_MER_BYTERR_1    (0x2<<8)        /* byte lane #1 */
+#define KN02XA_MER_BYTERR_0    (0x1<<8)        /* byte lane #0 */
 #define KN02XA_MER_RES_0       (0xff<<0)       /* unused */
 
 /*
 #define KN02XA_EAR_ADDRESS     (0x7ffffff<<2)  /* address involved */
 #define KN02XA_EAR_RES_0       (0x3<<0)        /* unused */
 
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+
+struct pt_regs;
+
+extern void dec_kn02xa_be_init(void);
+extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
+                                          struct pt_regs *regs);
+#endif
+
 #endif /* __ASM_MIPS_DEC_KN02XA_H */
index b120362..61feac3 100644 (file)
@@ -1,10 +1,12 @@
 /*
  *     include/asm-mips/dec/kn05.h
  *
- *     DECstation 5000/260 (4max+ or KN05) and DECsystem 5900/260
+ *     DECstation/DECsystem 5000/260 (4max+ or KN05), 5000/150 (4min
+ *     or KN04-BA), Personal DECstation/DECsystem 5000/50 (4maxine or
+ *     KN04-CA) and DECsystem 5900/260 (KN05) R4k CPU card MB ASIC
  *     definitions.
  *
- *     Copyright (C) 2002, 2003  Maciej W. Rozycki
+ *     Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
  *
  *     WARNING!  All this information is pure guesswork based on the
  *     ROM.  It is provided here in hope it will give someone some
- *     food for thought.  No documentation for the KN05 module has
- *     been located so far.
+ *     food for thought.  No documentation for the KN05 nor the KN04
+ *     module has been located so far.
  */
 #ifndef __ASM_MIPS_DEC_KN05_H
 #define __ASM_MIPS_DEC_KN05_H
 
+#include <asm/addrspace.h>
 #include <asm/dec/ioasic_addrs.h>
 
 /*
  * The oncard MB (Memory Buffer) ASIC provides an additional address
  * decoder.  Certain address ranges within the "high" 16 slots are
- * passed to the I/O ASIC's decoder like with the KN03.  Others are
- * handled locally.  "Low" slots are always passed.
+ * passed to the I/O ASIC's decoder like with the KN03 or KN02-BA/CA.
+ * Others are handled locally.  "Low" slots are always passed.
  */
-#define KN05_MB_ROM    (16*IOASIC_SLOT_SIZE)   /* KN05 card ROM */
-#define KN05_IOCTL     (17*IOASIC_SLOT_SIZE)   /* I/O ASIC */
-#define KN05_ESAR      (18*IOASIC_SLOT_SIZE)   /* LANCE MAC address chip */
-#define KN05_LANCE     (19*IOASIC_SLOT_SIZE)   /* LANCE Ethernet */
-#define KN05_MB_INT    (20*IOASIC_SLOT_SIZE)   /* MB interrupt register */
-#define KN05_MB_EA     (21*IOASIC_SLOT_SIZE)   /* MB error address? */
-#define KN05_MB_EC     (22*IOASIC_SLOT_SIZE)   /* MB error ??? */
-#define KN05_MB_CSR    (23*IOASIC_SLOT_SIZE)   /* MB control & status */
-#define KN05_RES_24    (24*IOASIC_SLOT_SIZE)   /* unused? */
-#define KN05_RES_25    (25*IOASIC_SLOT_SIZE)   /* unused? */
-#define KN05_RES_26    (26*IOASIC_SLOT_SIZE)   /* unused? */
-#define KN05_RES_27    (27*IOASIC_SLOT_SIZE)   /* unused? */
-#define KN05_SCSI      (28*IOASIC_SLOT_SIZE)   /* ASC SCSI */
-#define KN05_RES_29    (29*IOASIC_SLOT_SIZE)   /* unused? */
-#define KN05_RES_30    (30*IOASIC_SLOT_SIZE)   /* unused? */
-#define KN05_RES_31    (31*IOASIC_SLOT_SIZE)   /* unused? */
+#define KN4K_SLOT_BASE KSEG1ADDR(0x1fc00000)
+
+#define KN4K_MB_ROM    (0*IOASIC_SLOT_SIZE)    /* KN05/KN04 card ROM */
+#define KN4K_IOCTL     (1*IOASIC_SLOT_SIZE)    /* I/O ASIC */
+#define KN4K_ESAR      (2*IOASIC_SLOT_SIZE)    /* LANCE MAC address chip */
+#define KN4K_LANCE     (3*IOASIC_SLOT_SIZE)    /* LANCE Ethernet */
+#define KN4K_MB_INT    (4*IOASIC_SLOT_SIZE)    /* MB interrupt register */
+#define KN4K_MB_EA     (5*IOASIC_SLOT_SIZE)    /* MB error address? */
+#define KN4K_MB_EC     (6*IOASIC_SLOT_SIZE)    /* MB error ??? */
+#define KN4K_MB_CSR    (7*IOASIC_SLOT_SIZE)    /* MB control & status */
+#define KN4K_RES_08    (8*IOASIC_SLOT_SIZE)    /* unused? */
+#define KN4K_RES_09    (9*IOASIC_SLOT_SIZE)    /* unused? */
+#define KN4K_RES_10    (10*IOASIC_SLOT_SIZE)   /* unused? */
+#define KN4K_RES_11    (11*IOASIC_SLOT_SIZE)   /* unused? */
+#define KN4K_SCSI      (12*IOASIC_SLOT_SIZE)   /* ASC SCSI */
+#define KN4K_RES_13    (13*IOASIC_SLOT_SIZE)   /* unused? */
+#define KN4K_RES_14    (14*IOASIC_SLOT_SIZE)   /* unused? */
+#define KN4K_RES_15    (15*IOASIC_SLOT_SIZE)   /* unused? */
 
 /*
  * Bits for the MB interrupt register.
  * The register appears read-only.
  */
-#define KN05_MB_INT_TC         (1<<0)          /* TURBOchannel? */
-#define KN05_MB_INT_RTC                (1<<1)          /* RTC? */
-#define KN05_MB_INT_MT         (1<<3)          /* ??? */
+#define KN4K_MB_INT_TC         (1<<0)          /* TURBOchannel? */
+#define KN4K_MB_INT_RTC                (1<<1)          /* RTC? */
+#define KN4K_MB_INT_MT         (1<<3)          /* ??? */
 
 /*
  * Bits for the MB control & status register.
  * Set to 0x00bf8001 on my system by the ROM.
  */
-#define KN05_MB_CSR_PF         (1<<0)          /* PreFetching enable? */
-#define KN05_MB_CSR_F          (1<<1)          /* ??? */
-#define KN05_MB_CSR_ECC                (0xff<<2)       /* ??? */
-#define KN05_MB_CSR_OD         (1<<10)         /* ??? */
-#define KN05_MB_CSR_CP         (1<<11)         /* ??? */
-#define KN05_MB_CSR_UNC                (1<<12)         /* ??? */
-#define KN05_MB_CSR_IM         (1<<13)         /* ??? */
-#define KN05_MB_CSR_NC         (1<<14)         /* ??? */
-#define KN05_MB_CSR_EE         (1<<15)         /* (bus) Exception Enable? */
-#define KN05_MB_CSR_MSK                (0x1f<<16)      /* ??? */
-#define KN05_MB_CSR_FW         (1<<21)         /* ??? */
+#define KN4K_MB_CSR_PF         (1<<0)          /* PreFetching enable? */
+#define KN4K_MB_CSR_F          (1<<1)          /* ??? */
+#define KN4K_MB_CSR_ECC                (0xff<<2)       /* ??? */
+#define KN4K_MB_CSR_OD         (1<<10)         /* ??? */
+#define KN4K_MB_CSR_CP         (1<<11)         /* ??? */
+#define KN4K_MB_CSR_UNC                (1<<12)         /* ??? */
+#define KN4K_MB_CSR_IM         (1<<13)         /* ??? */
+#define KN4K_MB_CSR_NC         (1<<14)         /* ??? */
+#define KN4K_MB_CSR_EE         (1<<15)         /* (bus) Exception Enable? */
+#define KN4K_MB_CSR_MSK                (0x1f<<16)      /* ??? */
+#define KN4K_MB_CSR_FW         (1<<21)         /* ??? */
 
 #endif /* __ASM_MIPS_DEC_KN05_H */