^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Bus error event handling code for 5000-series systems equipped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * with parity error detection logic, i.e. DECstation/DECsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 5000/120, /125, /133 (KN02-BA), 5000/150 (KN04-BA) and Personal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * DECstation/DECsystem 5000/20, /25, /33 (KN02-CA), 5000/50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (KN04-CA) systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2005 Maciej W. Rozycki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/addrspace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/cpu-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/irq_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/dec/kn02ca.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/dec/kn02xa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/dec/kn05.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static inline void dec_kn02xa_be_ack(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) volatile u32 *mer = (void *)CKSEG1ADDR(KN02XA_MER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) volatile u32 *mem_intr = (void *)CKSEG1ADDR(KN02XA_MEM_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *mer = KN02CA_MER_INTR; /* Clear errors; keep the ARC IRQ. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *mem_intr = 0; /* Any write clears the bus IRQ. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) iob();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int invoker)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) volatile u32 *kn02xa_mer = (void *)CKSEG1ADDR(KN02XA_MER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) volatile u32 *kn02xa_ear = (void *)CKSEG1ADDR(KN02XA_EAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static const char excstr[] = "exception";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static const char intstr[] = "interrupt";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static const char cpustr[] = "CPU";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static const char mreadstr[] = "memory read";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static const char readstr[] = "read";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static const char writestr[] = "write";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const char timestr[] = "timeout";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static const char paritystr[] = "parity error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static const char lanestat[][4] = { " OK", "BAD" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const char *kind, *agent, *cycle, *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned long address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 mer = *kn02xa_mer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 ear = *kn02xa_ear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int action = MIPS_BE_FATAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Ack ASAP, so that any subsequent errors get caught. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) dec_kn02xa_be_ack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) kind = invoker ? intstr : excstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* No DMA errors? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) agent = cpustr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) address = ear & KN02XA_EAR_ADDRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Low 256MB is decoded as memory, high -- as TC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (address < 0x10000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) cycle = mreadstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) event = paritystr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) cycle = invoker ? writestr : readstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) event = timestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (is_fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) action = MIPS_BE_FIXUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (action != MIPS_BE_FIXUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) kind, agent, cycle, event, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (action != MIPS_BE_FIXUP && address < 0x10000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) printk(KERN_ALERT " Byte lane status %#3x -- "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) "#3: %s, #2: %s, #1: %s, #0: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) (mer & KN02XA_MER_BYTERR) >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return dec_kn02xa_be_backend(regs, is_fixup, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct pt_regs *regs = get_irq_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int action = dec_kn02xa_be_backend(regs, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (action == MIPS_BE_DISCARD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * FIXME: Find the affected processes and kill them, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * we must die.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * The interrupt is asynchronously delivered thus EPC and RA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * may be irrelevant, but are printed for a reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) regs->cp0_epc, regs->regs[31]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) die("Unrecoverable bus error", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void __init dec_kn02xa_be_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* For KN04 we need to make sure EE (?) is enabled in the MB. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (current_cpu_type() == CPU_R4000SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *mbcs |= KN4K_MB_CSR_EE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) fast_iob();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Clear any leftover errors from the firmware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) dec_kn02xa_be_ack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }