/*
 *	linux/arch/mips/dec/ecc-berr.c
 *
 *	Bus error event handling code for systems equipped with ECC
 *	handling logic, i.e. DECstation/DECsystem 5000/200 (KN02),
 *	5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
 *	5900/260 (KN05) systems.
 *
 *	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
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>

#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/irq_regs.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/traps.h>

#include <asm/dec/ecc.h>
#include <asm/dec/kn02.h>
#include <asm/dec/kn03.h>
#include <asm/dec/kn05.h>

static volatile u32 *kn0x_erraddr;
static volatile u32 *kn0x_chksyn;

static inline void dec_ecc_be_ack(void)
{
	*kn0x_erraddr = 0;			/* any write clears the IRQ */
	iob();
}

static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
{
	static const char excstr[] = "exception";
	static const char intstr[] = "interrupt";
	static const char cpustr[] = "CPU";
	static const char dmastr[] = "DMA";
	static const char readstr[] = "read";
	static const char mreadstr[] = "memory read";
	static const char writestr[] = "write";
	static const char mwritstr[] = "partial memory write";
	static const char timestr[] = "timeout";
	static const char overstr[] = "overrun";
	static const char eccstr[] = "ECC error";

	const char *kind, *agent, *cycle, *event;
	const char *status = "", *xbit = "", *fmt = "";
	unsigned long address;
	u16 syn = 0, sngl;

	int i = 0;

	u32 erraddr = *kn0x_erraddr;
	u32 chksyn = *kn0x_chksyn;
	int action = MIPS_BE_FATAL;

	/* 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();

	kind = invoker ? intstr : excstr;

	if (!(erraddr & KN0X_EAR_VALID)) {
		/* No idea what happened. */
		printk(KERN_ALERT "Unidentified bus error %s\n", kind);
		return action;
	}

	agent = (erraddr & KN0X_EAR_CPU) ? cpustr : dmastr;

	if (erraddr & KN0X_EAR_ECCERR) {
		/* An ECC error on a CPU or DMA transaction. */
		cycle = (erraddr & KN0X_EAR_WRITE) ? mwritstr : mreadstr;
		event = eccstr;
	} else {
		/* A CPU timeout or a DMA overrun. */
		cycle = (erraddr & KN0X_EAR_WRITE) ? writestr : readstr;
		event = (erraddr & KN0X_EAR_CPU) ? timestr : overstr;
	}

	address = erraddr & KN0X_EAR_ADDRESS;
	/* For ECC errors on reads adjust for MT pipelining. */
	if ((erraddr & (KN0X_EAR_WRITE | KN0X_EAR_ECCERR)) == KN0X_EAR_ECCERR)
		address = (address & ~0xfffLL) | ((address - 5) & 0xfffLL);
	address <<= 2;

	/* Only CPU errors are fixable. */
	if (erraddr & KN0X_EAR_CPU && is_fixup)
		action = MIPS_BE_FIXUP;

	if (erraddr & KN0X_EAR_ECCERR) {
		static const u8 data_sbit[32] = {
			0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,
			0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,
			0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
			0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,
		};
		static const u8 data_mbit[25] = {
			0x07, 0x0d, 0x1f,
			0x2f, 0x32, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
			0x43, 0x45, 0x46, 0x49, 0x4c, 0x51, 0x5e,
			0x61, 0x6e, 0x73, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
		};
		static const char sbestr[] = "corrected single";
		static const char dbestr[] = "uncorrectable double";
		static const char mbestr[] = "uncorrectable multiple";

		if (!(address & 0x4))
			syn = chksyn;			/* Low bank. */
		else
			syn = chksyn >> 16;		/* High bank. */

		if (!(syn & KN0X_ESR_VLDLO)) {
			/* Ack now, no rewrite will happen. */
			dec_ecc_be_ack();

			fmt = KERN_ALERT "%s" "invalid\n";
		} else {
			sngl = syn & KN0X_ESR_SNGLO;
			syn &= KN0X_ESR_SYNLO;

			/*
			 * Multibit errors may be tagged incorrectly;
			 * check the syndrome explicitly.
			 */
			for (i = 0; i < 25; i++)
				if (syn == data_mbit[i])
					break;

			if (i < 25) {
				status = mbestr;
			} else if (!sngl) {
				status = dbestr;
			} else {
				volatile u32 *ptr =
					(void *)CKSEG1ADDR(address);

				*ptr = *ptr;		/* Rewrite. */
				iob();

				status = sbestr;
				action = MIPS_BE_DISCARD;
			}

			/* Ack now, now we've rewritten (or not). */
			dec_ecc_be_ack();

			if (syn && syn == (syn & -syn)) {
				if (syn == 0x01) {
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error "
					      "at check bit C%s\n";
					xbit = "X";
				} else {
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error "
					      "at check bit C%s%u\n";
				}
				i = syn >> 2;
			} else {
				for (i = 0; i < 32; i++)
					if (syn == data_sbit[i])
						break;
				if (i < 32)
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error "
					      "at data bit D%s%u\n";
				else
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error\n";
			}
		}
	}

	if (action != MIPS_BE_FIXUP)
		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)
		printk(fmt, "  ECC syndrome ", syn, status, xbit, i);

	return action;
}

int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup)
{
	return dec_ecc_be_backend(regs, is_fixup, 0);
}

irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id)
{
	struct pt_regs *regs = get_irq_regs();

	int action = dec_ecc_be_backend(regs, 0, 1);

	if (action == MIPS_BE_DISCARD)
		return IRQ_HANDLED;

	/*
	 * 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.
	 */
	printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
	       regs->cp0_epc, regs->regs[31]);
	die("Unrecoverable bus error", regs);
}


/*
 * Initialization differs a bit between KN02 and KN03/KN05, so we
 * need two variants.  Once set up, all systems can be handled the
 * same way.
 */
static inline void dec_kn02_be_init(void)
{
	volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
	unsigned long flags;

	kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR);
	kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN);

	spin_lock_irqsave(&kn02_lock, flags);

	/* Preset write-only bits of the Control Register cache. */
	cached_kn02_csr = *csr | KN02_CSR_LEDS;

	/* Set normal ECC detection and generation. */
	cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
	/* Enable ECC correction. */
	cached_kn02_csr |= KN02_CSR_CORRECT;
	*csr = cached_kn02_csr;
	iob();

	spin_unlock_irqrestore(&kn02_lock, flags);
}

static inline void dec_kn03_be_init(void)
{
	volatile u32 *mcr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
	volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);

	kn0x_erraddr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_ERRADDR);
	kn0x_chksyn = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_CHKSYN);

	/*
	 * Set normal ECC detection and generation, enable ECC correction.
	 * For KN05 we also need to make sure EE (?) is enabled in the MB.
	 * Otherwise DBE/IBE exceptions would be masked but bus error
	 * interrupts would still arrive, resulting in an inevitable crash
	 * if get_dbe() triggers one.
	 */
	*mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
	       KN03_MCR_CORRECT;
	if (current_cpu_data.cputype == CPU_R4400SC)
		*mbcs |= KN4K_MB_CSR_EE;
	fast_iob();
}

void __init dec_ecc_be_init(void)
{
	if (mips_machtype == MACH_DS5000_200)
		dec_kn02_be_init();
	else
		dec_kn03_be_init();

	/* Clear any leftover errors from the firmware. */
	dec_ecc_be_ack();
}
