linux/arch/mips/sgi-ip32/crime.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2001, 2003 Keith M Wesolowski
   7 * Copyright (C) 2005 Ilya A. Volynets <ilya@total-knowledge.com>
   8 */
   9#include <linux/types.h>
  10#include <linux/init.h>
  11#include <linux/kernel.h>
  12#include <linux/interrupt.h>
  13#include <linux/export.h>
  14#include <asm/bootinfo.h>
  15#include <asm/io.h>
  16#include <asm/mipsregs.h>
  17#include <asm/page.h>
  18#include <asm/ip32/crime.h>
  19#include <asm/ip32/mace.h>
  20
  21struct sgi_crime __iomem *crime;
  22struct sgi_mace __iomem *mace;
  23
  24EXPORT_SYMBOL_GPL(mace);
  25
  26void __init crime_init(void)
  27{
  28        unsigned int id, rev;
  29        const int field = 2 * sizeof(unsigned long);
  30
  31        set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
  32        crime = ioremap(CRIME_BASE, sizeof(struct sgi_crime));
  33        mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
  34
  35        id = crime->id;
  36        rev = id & CRIME_ID_REV;
  37        id = (id & CRIME_ID_IDBITS) >> 4;
  38        printk(KERN_INFO "CRIME id %1x rev %d at 0x%0*lx\n",
  39               id, rev, field, (unsigned long) CRIME_BASE);
  40}
  41
  42irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id)
  43{
  44        unsigned long stat, addr;
  45        int fatal = 0;
  46
  47        stat = crime->mem_error_stat & CRIME_MEM_ERROR_STAT_MASK;
  48        addr = crime->mem_error_addr & CRIME_MEM_ERROR_ADDR_MASK;
  49
  50        printk("CRIME memory error at 0x%08lx ST 0x%08lx<", addr, stat);
  51
  52        if (stat & CRIME_MEM_ERROR_INV)
  53                printk("INV,");
  54        if (stat & CRIME_MEM_ERROR_ECC) {
  55                unsigned long ecc_syn =
  56                        crime->mem_ecc_syn & CRIME_MEM_ERROR_ECC_SYN_MASK;
  57                unsigned long ecc_gen =
  58                        crime->mem_ecc_chk & CRIME_MEM_ERROR_ECC_CHK_MASK;
  59                printk("ECC,SYN=0x%08lx,GEN=0x%08lx,", ecc_syn, ecc_gen);
  60        }
  61        if (stat & CRIME_MEM_ERROR_MULTIPLE) {
  62                fatal = 1;
  63                printk("MULTIPLE,");
  64        }
  65        if (stat & CRIME_MEM_ERROR_HARD_ERR) {
  66                fatal = 1;
  67                printk("HARD,");
  68        }
  69        if (stat & CRIME_MEM_ERROR_SOFT_ERR)
  70                printk("SOFT,");
  71        if (stat & CRIME_MEM_ERROR_CPU_ACCESS)
  72                printk("CPU,");
  73        if (stat & CRIME_MEM_ERROR_VICE_ACCESS)
  74                printk("VICE,");
  75        if (stat & CRIME_MEM_ERROR_GBE_ACCESS)
  76                printk("GBE,");
  77        if (stat & CRIME_MEM_ERROR_RE_ACCESS)
  78                printk("RE,REID=0x%02lx,", (stat & CRIME_MEM_ERROR_RE_ID)>>8);
  79        if (stat & CRIME_MEM_ERROR_MACE_ACCESS)
  80                printk("MACE,MACEID=0x%02lx,", stat & CRIME_MEM_ERROR_MACE_ID);
  81
  82        crime->mem_error_stat = 0;
  83
  84        if (fatal) {
  85                printk("FATAL>\n");
  86                panic("Fatal memory error.");
  87        } else
  88                printk("NONFATAL>\n");
  89
  90        return IRQ_HANDLED;
  91}
  92
  93irqreturn_t crime_cpuerr_intr(unsigned int irq, void *dev_id)
  94{
  95        unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK;
  96        unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK;
  97
  98        addr <<= 2;
  99        printk("CRIME CPU error at 0x%09lx status 0x%08lx\n", addr, stat);
 100        crime->cpu_error_stat = 0;
 101
 102        return IRQ_HANDLED;
 103}
 104