// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	Bus error event handling code for DECstation/DECsystem 3100
 *	and 2100 (KN01) systems equipped with parity error detection
 *	logic.
 *
 *	Copyright (c) 2005  Maciej W. Rozycki
 */

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

#include <asm/inst.h>
#include <asm/irq_regs.h>
#include <asm/mipsregs.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/traps.h>
#include <linux/uaccess.h>

#include <asm/dec/kn01.h>


/* CP0 hazard avoidance. */
#define BARRIER				\
	__asm__ __volatile__(		\
		".set	push\n\t"	\
		".set	noreorder\n\t"	\
		"nop\n\t"		\
		".set	pop\n\t")

/*
 * Bits 7:0 of the Control Register are write-only -- the
 * corresponding bits of the Status Register have a different
 * meaning.  Hence we use a cache.  It speeds up things a bit
 * as well.
 *
 * There is no default value -- it has to be initialized.
 */
u16 cached_kn01_csr;
static DEFINE_RAW_SPINLOCK(kn01_lock);


static inline void dec_kn01_be_ack(void)
{
	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
	unsigned long flags;

	raw_spin_lock_irqsave(&kn01_lock, flags);

	*csr = cached_kn01_csr | KN01_CSR_MEMERR;	/* Clear bus IRQ. */
	iob();

	raw_spin_unlock_irqrestore(&kn01_lock, flags);
}

static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
{
	volatile u32 *kn01_erraddr = (void *)CKSEG1ADDR(KN01_SLOT_BASE +
							KN01_ERRADDR);

	static const char excstr[] = "exception";
	static const char intstr[] = "interrupt";
	static const char cpustr[] = "CPU";
	static const char mreadstr[] = "memory read";
	static const char readstr[] = "read";
	static const char writestr[] = "write";
	static const char timestr[] = "timeout";
	static const char paritystr[] = "parity error";

	int data = regs->cp0_cause & 4;
	unsigned int __user *pc = (unsigned int __user *)regs->cp0_epc +
				  ((regs->cp0_cause & CAUSEF_BD) != 0);
	union mips_instruction insn;
	unsigned long entrylo, offset;
	long asid, entryhi, vaddr;

	const char *kind, *agent, *cycle, *event;
	unsigned long address;

	u32 erraddr = *kn01_erraddr;
	int action = MIPS_BE_FATAL;

	/* Ack ASAP, so that any subsequent errors get caught. */
	dec_kn01_be_ack();

	kind = invoker ? intstr : excstr;

	agent = cpustr;

	if (invoker)
		address = erraddr;
	else {
		/* Bloody hardware doesn't record the address for reads... */
		if (data) {
			/* This never faults. */
			__get_user(insn.word, pc);
			vaddr = regs->regs[insn.i_format.rs] +
				insn.i_format.simmediate;
		} else
			vaddr = (long)pc;
		if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1)
			address = CPHYSADDR(vaddr);
		else {
			/* Peek at what physical address the CPU used. */
			asid = read_c0_entryhi();
			entryhi = asid & (PAGE_SIZE - 1);
			entryhi |= vaddr & ~(PAGE_SIZE - 1);
			write_c0_entryhi(entryhi);
			BARRIER;
			tlb_probe();
			/* No need to check for presence. */
			tlb_read();
			entrylo = read_c0_entrylo0();
			write_c0_entryhi(asid);
			offset = vaddr & (PAGE_SIZE - 1);
			address = (entrylo & ~(PAGE_SIZE - 1)) | offset;
		}
	}

	/* Treat low 256MB as memory, high -- as I/O. */
	if (address < 0x10000000) {
		cycle = mreadstr;
		event = paritystr;
	} else {
		cycle = invoker ? writestr : readstr;
		event = timestr;
	}

	if (is_fixup)
		action = MIPS_BE_FIXUP;

	if (action != MIPS_BE_FIXUP)
		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
			kind, agent, cycle, event, address);

	return action;
}

int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
{
	return dec_kn01_be_backend(regs, is_fixup, 0);
}

irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id)
{
	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
	struct pt_regs *regs = get_irq_regs();
	int action;

	if (!(*csr & KN01_CSR_MEMERR))
		return IRQ_NONE;		/* Must have been video. */

	action = dec_kn01_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);
}


void __init dec_kn01_be_init(void)
{
	volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
	unsigned long flags;

	raw_spin_lock_irqsave(&kn01_lock, flags);

	/* Preset write-only bits of the Control Register cache. */
	cached_kn01_csr = *csr;
	cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS;
	cached_kn01_csr |= KN01_CSR_LEDS;

	/* Enable parity error detection. */
	cached_kn01_csr &= ~KN01_CSR_PARDIS;
	*csr = cached_kn01_csr;
	iob();

	raw_spin_unlock_irqrestore(&kn01_lock, flags);

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