1 /* 2 * linux/arch/mips/dec/kn01-berr.c 3 * 4 * Bus error event handling code for DECstation/DECsystem 3100 5 * and 2100 (KN01) systems equipped with parity error detection 6 * logic. 7 * 8 * Copyright (c) 2005 Maciej W. Rozycki 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 13 * 2 of the License, or (at your option) any later version. 14 */ 15 16 #include <linux/init.h> 17 #include <linux/interrupt.h> 18 #include <linux/kernel.h> 19 #include <linux/spinlock.h> 20 #include <linux/types.h> 21 22 #include <asm/inst.h> 23 #include <asm/irq_regs.h> 24 #include <asm/mipsregs.h> 25 #include <asm/page.h> 26 #include <asm/ptrace.h> 27 #include <asm/system.h> 28 #include <asm/traps.h> 29 #include <asm/uaccess.h> 30 31 #include <asm/dec/kn01.h> 32 33 34 /* CP0 hazard avoidance. */ 35 #define BARRIER \ 36 __asm__ __volatile__( \ 37 ".set push\n\t" \ 38 ".set noreorder\n\t" \ 39 "nop\n\t" \ 40 ".set pop\n\t") 41 42 /* 43 * Bits 7:0 of the Control Register are write-only -- the 44 * corresponding bits of the Status Register have a different 45 * meaning. Hence we use a cache. It speeds up things a bit 46 * as well. 47 * 48 * There is no default value -- it has to be initialized. 49 */ 50 u16 cached_kn01_csr; 51 DEFINE_SPINLOCK(kn01_lock); 52 53 54 static inline void dec_kn01_be_ack(void) 55 { 56 volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR); 57 unsigned long flags; 58 59 spin_lock_irqsave(&kn01_lock, flags); 60 61 *csr = cached_kn01_csr | KN01_CSR_MEMERR; /* Clear bus IRQ. */ 62 iob(); 63 64 spin_unlock_irqrestore(&kn01_lock, flags); 65 } 66 67 static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker) 68 { 69 volatile u32 *kn01_erraddr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + 70 KN01_ERRADDR); 71 72 static const char excstr[] = "exception"; 73 static const char intstr[] = "interrupt"; 74 static const char cpustr[] = "CPU"; 75 static const char mreadstr[] = "memory read"; 76 static const char readstr[] = "read"; 77 static const char writestr[] = "write"; 78 static const char timestr[] = "timeout"; 79 static const char paritystr[] = "parity error"; 80 81 int data = regs->cp0_cause & 4; 82 unsigned int __user *pc = (unsigned int __user *)regs->cp0_epc + 83 ((regs->cp0_cause & CAUSEF_BD) != 0); 84 union mips_instruction insn; 85 unsigned long entrylo, offset; 86 long asid, entryhi, vaddr; 87 88 const char *kind, *agent, *cycle, *event; 89 unsigned long address; 90 91 u32 erraddr = *kn01_erraddr; 92 int action = MIPS_BE_FATAL; 93 94 /* Ack ASAP, so that any subsequent errors get caught. */ 95 dec_kn01_be_ack(); 96 97 kind = invoker ? intstr : excstr; 98 99 agent = cpustr; 100 101 if (invoker) 102 address = erraddr; 103 else { 104 /* Bloody hardware doesn't record the address for reads... */ 105 if (data) { 106 /* This never faults. */ 107 __get_user(insn.word, pc); 108 vaddr = regs->regs[insn.i_format.rs] + 109 insn.i_format.simmediate; 110 } else 111 vaddr = (long)pc; 112 if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1) 113 address = CPHYSADDR(vaddr); 114 else { 115 /* Peek at what physical address the CPU used. */ 116 asid = read_c0_entryhi(); 117 entryhi = asid & (PAGE_SIZE - 1); 118 entryhi |= vaddr & ~(PAGE_SIZE - 1); 119 write_c0_entryhi(entryhi); 120 BARRIER; 121 tlb_probe(); 122 /* No need to check for presence. */ 123 tlb_read(); 124 entrylo = read_c0_entrylo0(); 125 write_c0_entryhi(asid); 126 offset = vaddr & (PAGE_SIZE - 1); 127 address = (entrylo & ~(PAGE_SIZE - 1)) | offset; 128 } 129 } 130 131 /* Treat low 256MB as memory, high -- as I/O. */ 132 if (address < 0x10000000) { 133 cycle = mreadstr; 134 event = paritystr; 135 } else { 136 cycle = invoker ? writestr : readstr; 137 event = timestr; 138 } 139 140 if (is_fixup) 141 action = MIPS_BE_FIXUP; 142 143 if (action != MIPS_BE_FIXUP) 144 printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n", 145 kind, agent, cycle, event, address); 146 147 return action; 148 } 149 150 int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup) 151 { 152 return dec_kn01_be_backend(regs, is_fixup, 0); 153 } 154 155 irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id) 156 { 157 volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR); 158 struct pt_regs *regs = get_irq_regs(); 159 int action; 160 161 if (!(*csr & KN01_CSR_MEMERR)) 162 return IRQ_NONE; /* Must have been video. */ 163 164 action = dec_kn01_be_backend(regs, 0, 1); 165 166 if (action == MIPS_BE_DISCARD) 167 return IRQ_HANDLED; 168 169 /* 170 * FIXME: Find the affected processes and kill them, otherwise 171 * we must die. 172 * 173 * The interrupt is asynchronously delivered thus EPC and RA 174 * may be irrelevant, but are printed for a reference. 175 */ 176 printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n", 177 regs->cp0_epc, regs->regs[31]); 178 die("Unrecoverable bus error", regs); 179 } 180 181 182 void __init dec_kn01_be_init(void) 183 { 184 volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR); 185 unsigned long flags; 186 187 spin_lock_irqsave(&kn01_lock, flags); 188 189 /* Preset write-only bits of the Control Register cache. */ 190 cached_kn01_csr = *csr; 191 cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS; 192 cached_kn01_csr |= KN01_CSR_LEDS; 193 194 /* Enable parity error detection. */ 195 cached_kn01_csr &= ~KN01_CSR_PARDIS; 196 *csr = cached_kn01_csr; 197 iob(); 198 199 spin_unlock_irqrestore(&kn01_lock, flags); 200 201 /* Clear any leftover errors from the firmware. */ 202 dec_kn01_be_ack(); 203 } 204