/*
 * ip28-berr.c: Bus error handling.
 *
 * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
 * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/seq_file.h>

#include <asm/addrspace.h>
#include <asm/traps.h>
#include <asm/branch.h>
#include <asm/irq_regs.h>
#include <asm/sgi/mc.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ioc.h>
#include <asm/sgi/ip22.h>
#include <asm/r4kcache.h>
#include <linux/uaccess.h>
#include <asm/bootinfo.h>

static unsigned int count_be_is_fixup;
static unsigned int count_be_handler;
static unsigned int count_be_interrupt;
static int debug_be_interrupt;

static unsigned int cpu_err_stat;	/* Status reg for CPU */
static unsigned int gio_err_stat;	/* Status reg for GIO */
static unsigned int cpu_err_addr;	/* Error address reg for CPU */
static unsigned int gio_err_addr;	/* Error address reg for GIO */
static unsigned int extio_stat;
static unsigned int hpc3_berr_stat;	/* Bus error interrupt status */

struct hpc3_stat {
	unsigned long addr;
	unsigned int ctrl;
	unsigned int cbp;
	unsigned int ndptr;
};

static struct {
	struct hpc3_stat pbdma[8];
	struct hpc3_stat scsi[2];
	struct hpc3_stat ethrx, ethtx;
} hpc3;

static struct {
	unsigned long err_addr;
	struct {
		u32 lo;
		u32 hi;
	} tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
} cache_tags;

static inline void save_cache_tags(unsigned busaddr)
{
	unsigned long addr = CAC_BASE | busaddr;
	int i;
	cache_tags.err_addr = addr;

	/*
	 * Starting with a bus-address, save secondary cache (indexed by
	 * PA[23..18:7..6]) tags first.
	 */
	addr &= ~1L;
#define tag cache_tags.tags[0]
	cache_op(Index_Load_Tag_S, addr);
	tag[0].lo = read_c0_taglo();	/* PA[35:18], VA[13:12] */
	tag[0].hi = read_c0_taghi();	/* PA[39:36] */
	cache_op(Index_Load_Tag_S, addr | 1L);
	tag[1].lo = read_c0_taglo();	/* PA[35:18], VA[13:12] */
	tag[1].hi = read_c0_taghi();	/* PA[39:36] */
#undef tag

	/*
	 * Save all primary data cache (indexed by VA[13:5]) tags which
	 * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
	 * Saving all tags and evaluating them later is easier and safer
	 * than relying on VA[13:12] from the secondary cache tags to pick
	 * matching primary tags here already.
	 */
	addr &= (0xffL << 56) | ((1 << 12) - 1);
#define tag cache_tags.tagd[i]
	for (i = 0; i < 4; ++i, addr += (1 << 12)) {
		cache_op(Index_Load_Tag_D, addr);
		tag[0].lo = read_c0_taglo();	/* PA[35:12] */
		tag[0].hi = read_c0_taghi();	/* PA[39:36] */
		cache_op(Index_Load_Tag_D, addr | 1L);
		tag[1].lo = read_c0_taglo();	/* PA[35:12] */
		tag[1].hi = read_c0_taghi();	/* PA[39:36] */
	}
#undef tag

	/*
	 * Save primary instruction cache (indexed by VA[13:6]) tags
	 * the same way.
	 */
	addr &= (0xffL << 56) | ((1 << 12) - 1);
#define tag cache_tags.tagi[i]
	for (i = 0; i < 4; ++i, addr += (1 << 12)) {
		cache_op(Index_Load_Tag_I, addr);
		tag[0].lo = read_c0_taglo();	/* PA[35:12] */
		tag[0].hi = read_c0_taghi();	/* PA[39:36] */
		cache_op(Index_Load_Tag_I, addr | 1L);
		tag[1].lo = read_c0_taglo();	/* PA[35:12] */
		tag[1].hi = read_c0_taghi();	/* PA[39:36] */
	}
#undef tag
}

#define GIO_ERRMASK	0xff00
#define CPU_ERRMASK	0x3f00

static void save_and_clear_buserr(void)
{
	int i;

	/* save status registers */
	cpu_err_addr = sgimc->cerr;
	cpu_err_stat = sgimc->cstat;
	gio_err_addr = sgimc->gerr;
	gio_err_stat = sgimc->gstat;
	extio_stat = sgioc->extio;
	hpc3_berr_stat = hpc3c0->bestat;

	hpc3.scsi[0].addr  = (unsigned long)&hpc3c0->scsi_chan0;
	hpc3.scsi[0].ctrl  = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
	hpc3.scsi[0].cbp   = hpc3c0->scsi_chan0.cbptr;
	hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;

	hpc3.scsi[1].addr  = (unsigned long)&hpc3c0->scsi_chan1;
	hpc3.scsi[1].ctrl  = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
	hpc3.scsi[1].cbp   = hpc3c0->scsi_chan1.cbptr;
	hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;

	hpc3.ethrx.addr	 = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
	hpc3.ethrx.ctrl	 = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
	hpc3.ethrx.cbp	 = hpc3c0->ethregs.rx_cbptr;
	hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;

	hpc3.ethtx.addr	 = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
	hpc3.ethtx.ctrl	 = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
	hpc3.ethtx.cbp	 = hpc3c0->ethregs.tx_cbptr;
	hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;

	for (i = 0; i < 8; ++i) {
		/* HPC3_PDMACTRL_ISACT ? */
		hpc3.pbdma[i].addr  = (unsigned long)&hpc3c0->pbdma[i];
		hpc3.pbdma[i].ctrl  = hpc3c0->pbdma[i].pbdma_ctrl;
		hpc3.pbdma[i].cbp   = hpc3c0->pbdma[i].pbdma_bptr;
		hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
	}
	i = 0;
	if (gio_err_stat & CPU_ERRMASK)
		i = gio_err_addr;
	if (cpu_err_stat & CPU_ERRMASK)
		i = cpu_err_addr;
	save_cache_tags(i);

	sgimc->cstat = sgimc->gstat = 0;
}

static void print_cache_tags(void)
{
	u32 scb, scw;
	int i;

	printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);

	/* PA[31:12] shifted to PTag0 (PA[35:12]) format */
	scw = (cache_tags.err_addr >> 4) & 0x0fffff00;

	scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
	for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
		if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
		    (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
		    continue;
		printk(KERN_ERR
		       "D: 0: %08x %08x, 1: %08x %08x  (VA[13:5]  %04x)\n",
			cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
			cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
			scb | (1 << 12)*i);
	}
	scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
	for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
		if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
		    (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
		    continue;
		printk(KERN_ERR
		       "I: 0: %08x %08x, 1: %08x %08x  (VA[13:6]  %04x)\n",
			cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
			cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
			scb | (1 << 12)*i);
	}
	i = read_c0_config();
	scb = i & (1 << 13) ? 7:6;	/* scblksize = 2^[7..6] */
	scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */

	i = ((1 << scw) - 1) & ~((1 << scb) - 1);
	printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x	(PA[%u:%u] %05x)\n",
		cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
		cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
		scw-1, scb, i & (unsigned)cache_tags.err_addr);
}

static inline const char *cause_excode_text(int cause)
{
	static const char *txt[32] =
	{	"Interrupt",
		"TLB modification",
		"TLB (load or instruction fetch)",
		"TLB (store)",
		"Address error (load or instruction fetch)",
		"Address error (store)",
		"Bus error (instruction fetch)",
		"Bus error (data: load or store)",
		"Syscall",
		"Breakpoint",
		"Reserved instruction",
		"Coprocessor unusable",
		"Arithmetic Overflow",
		"Trap",
		"14",
		"Floating-Point",
		"16", "17", "18", "19", "20", "21", "22",
		"Watch Hi/Lo",
		"24", "25", "26", "27", "28", "29", "30", "31",
	};
	return txt[(cause & 0x7c) >> 2];
}

static void print_buserr(const struct pt_regs *regs)
{
	const int field = 2 * sizeof(unsigned long);
	int error = 0;

	if (extio_stat & EXTIO_MC_BUSERR) {
		printk(KERN_ERR "MC Bus Error\n");
		error |= 1;
	}
	if (extio_stat & EXTIO_HPC3_BUSERR) {
		printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
			hpc3_berr_stat,
			(hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
					  HPC3_BESTAT_PIDSHIFT,
			(hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
			hpc3_berr_stat & HPC3_BESTAT_BLMASK);
		error |= 2;
	}
	if (extio_stat & EXTIO_EISA_BUSERR) {
		printk(KERN_ERR "EISA Bus Error\n");
		error |= 4;
	}
	if (cpu_err_stat & CPU_ERRMASK) {
		printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
			cpu_err_stat,
			cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
			cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
			cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
			cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
			cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
			cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
			cpu_err_addr);
		error |= 8;
	}
	if (gio_err_stat & GIO_ERRMASK) {
		printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
			gio_err_stat,
			gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
			gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
			gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
			gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
			gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
			gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
			gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
			gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
			gio_err_addr);
		error |= 16;
	}
	if (!error)
		printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
	else {
		printk(KERN_ERR "CP0: config %08x,  "
			"MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
			"MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
			read_c0_config(),
			sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
			sgimc->cmacc, sgimc->gmacc,
			sgimc->mconfig0, sgimc->mconfig1);
		print_cache_tags();
	}
	printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
	       cause_excode_text(regs->cp0_cause),
	       field, regs->cp0_epc, field, regs->regs[31]);
}

/*
 * Check, whether MC's (virtual) DMA address caused the bus error.
 * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
 */

static int addr_is_ram(unsigned long addr, unsigned sz)
{
	int i;

	for (i = 0; i < boot_mem_map.nr_map; i++) {
		unsigned long a = boot_mem_map.map[i].addr;
		if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
			return 1;
	}
	return 0;
}

static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
{
	/* This is likely rather similar to correct code ;-) */

	vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */

	/* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
	if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
		u32 ctl = sgimc->dma_ctrl;
		if (ctl & 1) {
			unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
			/* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
			unsigned long pte = (lo >> 6) << 12; /* PTEBase */
			pte += 8*((vaddr >> pgsz) & 0x1ff);
			if (addr_is_ram(pte, 8)) {
				/*
				 * Note: Since DMA hardware does look up
				 * translation on its own, this PTE *must*
				 * match the TLB/EntryLo-register format !
				 */
				unsigned long a = *(unsigned long *)
						PHYS_TO_XKSEG_UNCACHED(pte);
				a = (a & 0x3f) << 6; /* PFN */
				a += vaddr & ((1 << pgsz) - 1);
				return cpu_err_addr == a;
			}
		}
	}
	return 0;
}

static int check_vdma_memaddr(void)
{
	if (cpu_err_stat & CPU_ERRMASK) {
		u32 a = sgimc->maddronly;

		if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
			return cpu_err_addr == a;

		if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
		    check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
		    check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
		    check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
			return 1;
	}
	return 0;
}

static int check_vdma_gioaddr(void)
{
	if (gio_err_stat & GIO_ERRMASK) {
		u32 a = sgimc->gio_dma_trans;
		a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
		return gio_err_addr == a;
	}
	return 0;
}

/*
 * MC sends an interrupt whenever bus or parity errors occur. In addition,
 * if the error happened during a CPU read, it also asserts the bus error
 * pin on the R4K. Code in bus error handler save the MC bus error registers
 * and then clear the interrupt when this happens.
 */

static int ip28_be_interrupt(const struct pt_regs *regs)
{
	int i;

	save_and_clear_buserr();
	/*
	 * Try to find out, whether we got here by a mispredicted speculative
	 * load/store operation.  If so, it's not fatal, we can go on.
	 */
	/* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
	if (regs->cp0_cause & CAUSEF_EXCCODE)
		goto mips_be_fatal;

	/* Any cause other than "Bus error interrupt" (IP6) is weird. */
	if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
		goto mips_be_fatal;

	if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
		goto mips_be_fatal;

	/* Any state other than "Memory bus error" is fatal. */
	if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
		goto mips_be_fatal;

	/* GIO errors other than timeouts are fatal */
	if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
		goto mips_be_fatal;

	/*
	 * Now we have an asynchronous bus error, speculatively or DMA caused.
	 * Need to search all DMA descriptors for the error address.
	 */
	for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
		struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
		if ((cpu_err_stat & CPU_ERRMASK) &&
		    (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
			break;
		if ((gio_err_stat & GIO_ERRMASK) &&
		    (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
			break;
	}
	if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
		struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
		printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
		       " ctl %08x, ndp %08x, cbp %08x\n",
		       CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
		goto mips_be_fatal;
	}
	/* Check MC's virtual DMA stuff. */
	if (check_vdma_memaddr()) {
		printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
			sgimc->maddronly);
		goto mips_be_fatal;
	}
	if (check_vdma_gioaddr()) {
		printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
			sgimc->gmaddronly);
		goto mips_be_fatal;
	}
	/* A speculative bus error... */
	if (debug_be_interrupt) {
		print_buserr(regs);
		printk(KERN_ERR "discarded!\n");
	}
	return MIPS_BE_DISCARD;

mips_be_fatal:
	print_buserr(regs);
	return MIPS_BE_FATAL;
}

void ip22_be_interrupt(int irq)
{
	struct pt_regs *regs = get_irq_regs();

	count_be_interrupt++;

	if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
		/* Assume it would be too dangerous to continue ... */
		die_if_kernel("Oops", regs);
		force_sig(SIGBUS, current);
	} else if (debug_be_interrupt)
		show_regs((struct pt_regs *)regs);
}

static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
{
	/*
	 * We arrive here only in the unusual case of do_be() invocation,
	 * i.e. by a bus error exception without a bus error interrupt.
	 */
	if (is_fixup) {
		count_be_is_fixup++;
		save_and_clear_buserr();
		return MIPS_BE_FIXUP;
	}
	count_be_handler++;
	return ip28_be_interrupt(regs);
}

void __init ip22_be_init(void)
{
	board_be_handler = ip28_be_handler;
}

int ip28_show_be_info(struct seq_file *m)
{
	seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
	seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
	seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);

	return 0;
}

static int __init debug_be_setup(char *str)
{
	debug_be_interrupt++;
	return 1;
}
__setup("ip28_debug_be", debug_be_setup);
