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