// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Western Digital Corporation or its affiliates.
 * Copyright (C) 2022 Ventana Micro Systems Inc.
 *
 * Authors:
 *	Anup Patel <apatel@ventanamicro.com>
 */

#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/kvm_host.h>
#include <linux/math.h>
#include <linux/spinlock.h>
#include <linux/swab.h>
#include <kvm/iodev.h>
#include <asm/csr.h>
#include <asm/kvm_aia_imsic.h>

#define IMSIC_MAX_EIX	(IMSIC_MAX_ID / BITS_PER_TYPE(u64))

struct imsic_mrif_eix {
	unsigned long eip[BITS_PER_TYPE(u64) / BITS_PER_LONG];
	unsigned long eie[BITS_PER_TYPE(u64) / BITS_PER_LONG];
};

struct imsic_mrif {
	struct imsic_mrif_eix eix[IMSIC_MAX_EIX];
	unsigned long eithreshold;
	unsigned long eidelivery;
};

struct imsic {
	struct kvm_io_device iodev;

	u32 nr_msis;
	u32 nr_eix;
	u32 nr_hw_eix;

	/*
	 * At any point in time, the register state is in
	 * one of the following places:
	 *
	 * 1) Hardware: IMSIC VS-file (vsfile_cpu >= 0)
	 * 2) Software: IMSIC SW-file (vsfile_cpu < 0)
	 */

	/* IMSIC VS-file */
	rwlock_t vsfile_lock;
	int vsfile_cpu;
	int vsfile_hgei;
	void __iomem *vsfile_va;
	phys_addr_t vsfile_pa;

	/* IMSIC SW-file */
	struct imsic_mrif *swfile;
	phys_addr_t swfile_pa;
};

#define imsic_vs_csr_read(__c)			\
({						\
	unsigned long __r;			\
	csr_write(CSR_VSISELECT, __c);		\
	__r = csr_read(CSR_VSIREG);		\
	__r;					\
})

#define imsic_read_switchcase(__ireg)			\
	case __ireg:					\
		return imsic_vs_csr_read(__ireg);
#define imsic_read_switchcase_2(__ireg)			\
	imsic_read_switchcase(__ireg + 0)		\
	imsic_read_switchcase(__ireg + 1)
#define imsic_read_switchcase_4(__ireg)			\
	imsic_read_switchcase_2(__ireg + 0)		\
	imsic_read_switchcase_2(__ireg + 2)
#define imsic_read_switchcase_8(__ireg)			\
	imsic_read_switchcase_4(__ireg + 0)		\
	imsic_read_switchcase_4(__ireg + 4)
#define imsic_read_switchcase_16(__ireg)		\
	imsic_read_switchcase_8(__ireg + 0)		\
	imsic_read_switchcase_8(__ireg + 8)
#define imsic_read_switchcase_32(__ireg)		\
	imsic_read_switchcase_16(__ireg + 0)		\
	imsic_read_switchcase_16(__ireg + 16)
#define imsic_read_switchcase_64(__ireg)		\
	imsic_read_switchcase_32(__ireg + 0)		\
	imsic_read_switchcase_32(__ireg + 32)

static unsigned long imsic_eix_read(int ireg)
{
	switch (ireg) {
	imsic_read_switchcase_64(IMSIC_EIP0)
	imsic_read_switchcase_64(IMSIC_EIE0)
	}

	return 0;
}

#define imsic_vs_csr_swap(__c, __v)		\
({						\
	unsigned long __r;			\
	csr_write(CSR_VSISELECT, __c);		\
	__r = csr_swap(CSR_VSIREG, __v);	\
	__r;					\
})

#define imsic_swap_switchcase(__ireg, __v)		\
	case __ireg:					\
		return imsic_vs_csr_swap(__ireg, __v);
#define imsic_swap_switchcase_2(__ireg, __v)		\
	imsic_swap_switchcase(__ireg + 0, __v)		\
	imsic_swap_switchcase(__ireg + 1, __v)
#define imsic_swap_switchcase_4(__ireg, __v)		\
	imsic_swap_switchcase_2(__ireg + 0, __v)	\
	imsic_swap_switchcase_2(__ireg + 2, __v)
#define imsic_swap_switchcase_8(__ireg, __v)		\
	imsic_swap_switchcase_4(__ireg + 0, __v)	\
	imsic_swap_switchcase_4(__ireg + 4, __v)
#define imsic_swap_switchcase_16(__ireg, __v)		\
	imsic_swap_switchcase_8(__ireg + 0, __v)	\
	imsic_swap_switchcase_8(__ireg + 8, __v)
#define imsic_swap_switchcase_32(__ireg, __v)		\
	imsic_swap_switchcase_16(__ireg + 0, __v)	\
	imsic_swap_switchcase_16(__ireg + 16, __v)
#define imsic_swap_switchcase_64(__ireg, __v)		\
	imsic_swap_switchcase_32(__ireg + 0, __v)	\
	imsic_swap_switchcase_32(__ireg + 32, __v)

static unsigned long imsic_eix_swap(int ireg, unsigned long val)
{
	switch (ireg) {
	imsic_swap_switchcase_64(IMSIC_EIP0, val)
	imsic_swap_switchcase_64(IMSIC_EIE0, val)
	}

	return 0;
}

#define imsic_vs_csr_write(__c, __v)		\
do {						\
	csr_write(CSR_VSISELECT, __c);		\
	csr_write(CSR_VSIREG, __v);		\
} while (0)

#define imsic_write_switchcase(__ireg, __v)		\
	case __ireg:					\
		imsic_vs_csr_write(__ireg, __v);	\
		break;
#define imsic_write_switchcase_2(__ireg, __v)		\
	imsic_write_switchcase(__ireg + 0, __v)		\
	imsic_write_switchcase(__ireg + 1, __v)
#define imsic_write_switchcase_4(__ireg, __v)		\
	imsic_write_switchcase_2(__ireg + 0, __v)	\
	imsic_write_switchcase_2(__ireg + 2, __v)
#define imsic_write_switchcase_8(__ireg, __v)		\
	imsic_write_switchcase_4(__ireg + 0, __v)	\
	imsic_write_switchcase_4(__ireg + 4, __v)
#define imsic_write_switchcase_16(__ireg, __v)		\
	imsic_write_switchcase_8(__ireg + 0, __v)	\
	imsic_write_switchcase_8(__ireg + 8, __v)
#define imsic_write_switchcase_32(__ireg, __v)		\
	imsic_write_switchcase_16(__ireg + 0, __v)	\
	imsic_write_switchcase_16(__ireg + 16, __v)
#define imsic_write_switchcase_64(__ireg, __v)		\
	imsic_write_switchcase_32(__ireg + 0, __v)	\
	imsic_write_switchcase_32(__ireg + 32, __v)

static void imsic_eix_write(int ireg, unsigned long val)
{
	switch (ireg) {
	imsic_write_switchcase_64(IMSIC_EIP0, val)
	imsic_write_switchcase_64(IMSIC_EIE0, val)
	}
}

#define imsic_vs_csr_set(__c, __v)		\
do {						\
	csr_write(CSR_VSISELECT, __c);		\
	csr_set(CSR_VSIREG, __v);		\
} while (0)

#define imsic_set_switchcase(__ireg, __v)		\
	case __ireg:					\
		imsic_vs_csr_set(__ireg, __v);		\
		break;
#define imsic_set_switchcase_2(__ireg, __v)		\
	imsic_set_switchcase(__ireg + 0, __v)		\
	imsic_set_switchcase(__ireg + 1, __v)
#define imsic_set_switchcase_4(__ireg, __v)		\
	imsic_set_switchcase_2(__ireg + 0, __v)		\
	imsic_set_switchcase_2(__ireg + 2, __v)
#define imsic_set_switchcase_8(__ireg, __v)		\
	imsic_set_switchcase_4(__ireg + 0, __v)		\
	imsic_set_switchcase_4(__ireg + 4, __v)
#define imsic_set_switchcase_16(__ireg, __v)		\
	imsic_set_switchcase_8(__ireg + 0, __v)		\
	imsic_set_switchcase_8(__ireg + 8, __v)
#define imsic_set_switchcase_32(__ireg, __v)		\
	imsic_set_switchcase_16(__ireg + 0, __v)	\
	imsic_set_switchcase_16(__ireg + 16, __v)
#define imsic_set_switchcase_64(__ireg, __v)		\
	imsic_set_switchcase_32(__ireg + 0, __v)	\
	imsic_set_switchcase_32(__ireg + 32, __v)

static void imsic_eix_set(int ireg, unsigned long val)
{
	switch (ireg) {
	imsic_set_switchcase_64(IMSIC_EIP0, val)
	imsic_set_switchcase_64(IMSIC_EIE0, val)
	}
}

static unsigned long imsic_mrif_atomic_rmw(struct imsic_mrif *mrif,
					   unsigned long *ptr,
					   unsigned long new_val,
					   unsigned long wr_mask)
{
	unsigned long old_val = 0, tmp = 0;

	__asm__ __volatile__ (
		"0:	lr.w.aq   %1, %0\n"
		"	and       %2, %1, %3\n"
		"	or        %2, %2, %4\n"
		"	sc.w.rl   %2, %2, %0\n"
		"	bnez      %2, 0b"
		: "+A" (*ptr), "+r" (old_val), "+r" (tmp)
		: "r" (~wr_mask), "r" (new_val & wr_mask)
		: "memory");

	return old_val;
}

static unsigned long imsic_mrif_atomic_or(struct imsic_mrif *mrif,
					  unsigned long *ptr,
					  unsigned long val)
{
	return atomic_long_fetch_or(val, (atomic_long_t *)ptr);
}

#define imsic_mrif_atomic_write(__mrif, __ptr, __new_val)	\
		imsic_mrif_atomic_rmw(__mrif, __ptr, __new_val, -1UL)
#define imsic_mrif_atomic_read(__mrif, __ptr)			\
		imsic_mrif_atomic_or(__mrif, __ptr, 0)

static u32 imsic_mrif_topei(struct imsic_mrif *mrif, u32 nr_eix, u32 nr_msis)
{
	struct imsic_mrif_eix *eix;
	u32 i, imin, imax, ei, max_msi;
	unsigned long eipend[BITS_PER_TYPE(u64) / BITS_PER_LONG];
	unsigned long eithreshold = imsic_mrif_atomic_read(mrif,
							&mrif->eithreshold);

	max_msi = (eithreshold && (eithreshold <= nr_msis)) ?
		   eithreshold : nr_msis;
	for (ei = 0; ei < nr_eix; ei++) {
		eix = &mrif->eix[ei];
		eipend[0] = imsic_mrif_atomic_read(mrif, &eix->eie[0]) &
			    imsic_mrif_atomic_read(mrif, &eix->eip[0]);
#ifdef CONFIG_32BIT
		eipend[1] = imsic_mrif_atomic_read(mrif, &eix->eie[1]) &
			    imsic_mrif_atomic_read(mrif, &eix->eip[1]);
		if (!eipend[0] && !eipend[1])
#else
		if (!eipend[0])
#endif
			continue;

		imin = ei * BITS_PER_TYPE(u64);
		imax = ((imin + BITS_PER_TYPE(u64)) < max_msi) ?
			imin + BITS_PER_TYPE(u64) : max_msi;
		for (i = (!imin) ? 1 : imin; i < imax; i++) {
			if (test_bit(i - imin, eipend))
				return (i << TOPEI_ID_SHIFT) | i;
		}
	}

	return 0;
}

static int imsic_mrif_isel_check(u32 nr_eix, unsigned long isel)
{
	u32 num = 0;

	switch (isel) {
	case IMSIC_EIDELIVERY:
	case IMSIC_EITHRESHOLD:
		break;
	case IMSIC_EIP0 ... IMSIC_EIP63:
		num = isel - IMSIC_EIP0;
		break;
	case IMSIC_EIE0 ... IMSIC_EIE63:
		num = isel - IMSIC_EIE0;
		break;
	default:
		return -ENOENT;
	}
#ifndef CONFIG_32BIT
	if (num & 0x1)
		return -EINVAL;
#endif
	if ((num / 2) >= nr_eix)
		return -EINVAL;

	return 0;
}

static int imsic_mrif_rmw(struct imsic_mrif *mrif, u32 nr_eix,
			  unsigned long isel, unsigned long *val,
			  unsigned long new_val, unsigned long wr_mask)
{
	bool pend;
	struct imsic_mrif_eix *eix;
	unsigned long *ei, num, old_val = 0;

	switch (isel) {
	case IMSIC_EIDELIVERY:
		old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eidelivery,
						new_val, wr_mask & 0x1);
		break;
	case IMSIC_EITHRESHOLD:
		old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eithreshold,
				new_val, wr_mask & (IMSIC_MAX_ID - 1));
		break;
	case IMSIC_EIP0 ... IMSIC_EIP63:
	case IMSIC_EIE0 ... IMSIC_EIE63:
		if (isel >= IMSIC_EIP0 && isel <= IMSIC_EIP63) {
			pend = true;
			num = isel - IMSIC_EIP0;
		} else {
			pend = false;
			num = isel - IMSIC_EIE0;
		}

		if ((num / 2) >= nr_eix)
			return -EINVAL;
		eix = &mrif->eix[num / 2];

#ifndef CONFIG_32BIT
		if (num & 0x1)
			return -EINVAL;
		ei = (pend) ? &eix->eip[0] : &eix->eie[0];
#else
		ei = (pend) ? &eix->eip[num & 0x1] : &eix->eie[num & 0x1];
#endif

		/* Bit0 of EIP0 or EIE0 is read-only */
		if (!num)
			wr_mask &= ~BIT(0);

		old_val = imsic_mrif_atomic_rmw(mrif, ei, new_val, wr_mask);
		break;
	default:
		return -ENOENT;
	}

	if (val)
		*val = old_val;

	return 0;
}

struct imsic_vsfile_read_data {
	int hgei;
	u32 nr_eix;
	bool clear;
	struct imsic_mrif *mrif;
};

static void imsic_vsfile_local_read(void *data)
{
	u32 i;
	struct imsic_mrif_eix *eix;
	struct imsic_vsfile_read_data *idata = data;
	struct imsic_mrif *mrif = idata->mrif;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to store
	 * values in MRIF because imsic_vsfile_read() is always called
	 * with pointer to temporary MRIF on stack.
	 */

	if (idata->clear) {
		mrif->eidelivery = imsic_vs_csr_swap(IMSIC_EIDELIVERY, 0);
		mrif->eithreshold = imsic_vs_csr_swap(IMSIC_EITHRESHOLD, 0);
		for (i = 0; i < idata->nr_eix; i++) {
			eix = &mrif->eix[i];
			eix->eip[0] = imsic_eix_swap(IMSIC_EIP0 + i * 2, 0);
			eix->eie[0] = imsic_eix_swap(IMSIC_EIE0 + i * 2, 0);
#ifdef CONFIG_32BIT
			eix->eip[1] = imsic_eix_swap(IMSIC_EIP0 + i * 2 + 1, 0);
			eix->eie[1] = imsic_eix_swap(IMSIC_EIE0 + i * 2 + 1, 0);
#endif
		}
	} else {
		mrif->eidelivery = imsic_vs_csr_read(IMSIC_EIDELIVERY);
		mrif->eithreshold = imsic_vs_csr_read(IMSIC_EITHRESHOLD);
		for (i = 0; i < idata->nr_eix; i++) {
			eix = &mrif->eix[i];
			eix->eip[0] = imsic_eix_read(IMSIC_EIP0 + i * 2);
			eix->eie[0] = imsic_eix_read(IMSIC_EIE0 + i * 2);
#ifdef CONFIG_32BIT
			eix->eip[1] = imsic_eix_read(IMSIC_EIP0 + i * 2 + 1);
			eix->eie[1] = imsic_eix_read(IMSIC_EIE0 + i * 2 + 1);
#endif
		}
	}

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static void imsic_vsfile_read(int vsfile_hgei, int vsfile_cpu, u32 nr_eix,
			      bool clear, struct imsic_mrif *mrif)
{
	struct imsic_vsfile_read_data idata;

	/* We can only read clear if we have a IMSIC VS-file */
	if (vsfile_cpu < 0 || vsfile_hgei <= 0)
		return;

	/* We can only read clear on local CPU */
	idata.hgei = vsfile_hgei;
	idata.nr_eix = nr_eix;
	idata.clear = clear;
	idata.mrif = mrif;
	on_each_cpu_mask(cpumask_of(vsfile_cpu),
			 imsic_vsfile_local_read, &idata, 1);
}

struct imsic_vsfile_rw_data {
	int hgei;
	int isel;
	bool write;
	unsigned long val;
};

static void imsic_vsfile_local_rw(void *data)
{
	struct imsic_vsfile_rw_data *idata = data;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	switch (idata->isel) {
	case IMSIC_EIDELIVERY:
		if (idata->write)
			imsic_vs_csr_write(IMSIC_EIDELIVERY, idata->val);
		else
			idata->val = imsic_vs_csr_read(IMSIC_EIDELIVERY);
		break;
	case IMSIC_EITHRESHOLD:
		if (idata->write)
			imsic_vs_csr_write(IMSIC_EITHRESHOLD, idata->val);
		else
			idata->val = imsic_vs_csr_read(IMSIC_EITHRESHOLD);
		break;
	case IMSIC_EIP0 ... IMSIC_EIP63:
	case IMSIC_EIE0 ... IMSIC_EIE63:
#ifndef CONFIG_32BIT
		if (idata->isel & 0x1)
			break;
#endif
		if (idata->write)
			imsic_eix_write(idata->isel, idata->val);
		else
			idata->val = imsic_eix_read(idata->isel);
		break;
	default:
		break;
	}

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static int imsic_vsfile_rw(int vsfile_hgei, int vsfile_cpu, u32 nr_eix,
			   unsigned long isel, bool write,
			   unsigned long *val)
{
	int rc;
	struct imsic_vsfile_rw_data rdata;

	/* We can only access register if we have a IMSIC VS-file */
	if (vsfile_cpu < 0 || vsfile_hgei <= 0)
		return -EINVAL;

	/* Check IMSIC register iselect */
	rc = imsic_mrif_isel_check(nr_eix, isel);
	if (rc)
		return rc;

	/* We can only access register on local CPU */
	rdata.hgei = vsfile_hgei;
	rdata.isel = isel;
	rdata.write = write;
	rdata.val = (write) ? *val : 0;
	on_each_cpu_mask(cpumask_of(vsfile_cpu),
			 imsic_vsfile_local_rw, &rdata, 1);

	if (!write)
		*val = rdata.val;

	return 0;
}

static void imsic_vsfile_local_clear(int vsfile_hgei, u32 nr_eix)
{
	u32 i;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	/* We can only zero-out if we have a IMSIC VS-file */
	if (vsfile_hgei <= 0)
		return;

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	imsic_vs_csr_write(IMSIC_EIDELIVERY, 0);
	imsic_vs_csr_write(IMSIC_EITHRESHOLD, 0);
	for (i = 0; i < nr_eix; i++) {
		imsic_eix_write(IMSIC_EIP0 + i * 2, 0);
		imsic_eix_write(IMSIC_EIE0 + i * 2, 0);
#ifdef CONFIG_32BIT
		imsic_eix_write(IMSIC_EIP0 + i * 2 + 1, 0);
		imsic_eix_write(IMSIC_EIE0 + i * 2 + 1, 0);
#endif
	}

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static void imsic_vsfile_local_update(int vsfile_hgei, u32 nr_eix,
				      struct imsic_mrif *mrif)
{
	u32 i;
	struct imsic_mrif_eix *eix;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	/* We can only update if we have a HW IMSIC context */
	if (vsfile_hgei <= 0)
		return;

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to read values
	 * from MRIF in this function because it is always called with
	 * pointer to temporary MRIF on stack.
	 */

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	for (i = 0; i < nr_eix; i++) {
		eix = &mrif->eix[i];
		imsic_eix_set(IMSIC_EIP0 + i * 2, eix->eip[0]);
		imsic_eix_set(IMSIC_EIE0 + i * 2, eix->eie[0]);
#ifdef CONFIG_32BIT
		imsic_eix_set(IMSIC_EIP0 + i * 2 + 1, eix->eip[1]);
		imsic_eix_set(IMSIC_EIE0 + i * 2 + 1, eix->eie[1]);
#endif
	}
	imsic_vs_csr_write(IMSIC_EITHRESHOLD, mrif->eithreshold);
	imsic_vs_csr_write(IMSIC_EIDELIVERY, mrif->eidelivery);

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static void imsic_vsfile_cleanup(struct imsic *imsic)
{
	int old_vsfile_hgei, old_vsfile_cpu;
	unsigned long flags;

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to clear the
	 * SW-file in this function because it is always called when the
	 * VCPU is being destroyed.
	 */

	write_lock_irqsave(&imsic->vsfile_lock, flags);
	old_vsfile_hgei = imsic->vsfile_hgei;
	old_vsfile_cpu = imsic->vsfile_cpu;
	imsic->vsfile_cpu = imsic->vsfile_hgei = -1;
	imsic->vsfile_va = NULL;
	imsic->vsfile_pa = 0;
	write_unlock_irqrestore(&imsic->vsfile_lock, flags);

	memset(imsic->swfile, 0, sizeof(*imsic->swfile));

	if (old_vsfile_cpu >= 0)
		kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
}

static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
	struct imsic_mrif *mrif = imsic->swfile;

	if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
	    imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
		kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT);
	else
		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
}

static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
			      struct imsic_mrif *mrif)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to read and
	 * write SW-file and MRIF in this function because it is always
	 * called when VCPU is not using SW-file and the MRIF points to
	 * a temporary MRIF on stack.
	 */

	memcpy(mrif, imsic->swfile, sizeof(*mrif));
	if (clear) {
		memset(imsic->swfile, 0, sizeof(*imsic->swfile));
		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
	}
}

static void imsic_swfile_update(struct kvm_vcpu *vcpu,
				struct imsic_mrif *mrif)
{
	u32 i;
	struct imsic_mrif_eix *seix, *eix;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
	struct imsic_mrif *smrif = imsic->swfile;

	imsic_mrif_atomic_write(smrif, &smrif->eidelivery, mrif->eidelivery);
	imsic_mrif_atomic_write(smrif, &smrif->eithreshold, mrif->eithreshold);
	for (i = 0; i < imsic->nr_eix; i++) {
		seix = &smrif->eix[i];
		eix = &mrif->eix[i];
		imsic_mrif_atomic_or(smrif, &seix->eip[0], eix->eip[0]);
		imsic_mrif_atomic_or(smrif, &seix->eie[0], eix->eie[0]);
#ifdef CONFIG_32BIT
		imsic_mrif_atomic_or(smrif, &seix->eip[1], eix->eip[1]);
		imsic_mrif_atomic_or(smrif, &seix->eie[1], eix->eie[1]);
#endif
	}

	imsic_swfile_extirq_update(vcpu);
}

void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
{
	unsigned long flags;
	struct imsic_mrif tmrif;
	int old_vsfile_hgei, old_vsfile_cpu;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	/* Read and clear IMSIC VS-file details */
	write_lock_irqsave(&imsic->vsfile_lock, flags);
	old_vsfile_hgei = imsic->vsfile_hgei;
	old_vsfile_cpu = imsic->vsfile_cpu;
	imsic->vsfile_cpu = imsic->vsfile_hgei = -1;
	imsic->vsfile_va = NULL;
	imsic->vsfile_pa = 0;
	write_unlock_irqrestore(&imsic->vsfile_lock, flags);

	/* Do nothing, if no IMSIC VS-file to release */
	if (old_vsfile_cpu < 0)
		return;

	/*
	 * At this point, all interrupt producers are still using
	 * the old IMSIC VS-file so we first re-direct all interrupt
	 * producers.
	 */

	/* Purge the G-stage mapping */
	kvm_riscv_gstage_iounmap(vcpu->kvm,
				 vcpu->arch.aia_context.imsic_addr,
				 IMSIC_MMIO_PAGE_SZ);

	/* TODO: Purge the IOMMU mapping ??? */

	/*
	 * At this point, all interrupt producers have been re-directed
	 * to somewhere else so we move register state from the old IMSIC
	 * VS-file to the IMSIC SW-file.
	 */

	/* Read and clear register state from old IMSIC VS-file */
	memset(&tmrif, 0, sizeof(tmrif));
	imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu, imsic->nr_hw_eix,
			  true, &tmrif);

	/* Update register state in IMSIC SW-file */
	imsic_swfile_update(vcpu, &tmrif);

	/* Free-up old IMSIC VS-file */
	kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
}

int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
{
	unsigned long flags;
	phys_addr_t new_vsfile_pa;
	struct imsic_mrif tmrif;
	void __iomem *new_vsfile_va;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_run *run = vcpu->run;
	struct kvm_vcpu_aia *vaia = &vcpu->arch.aia_context;
	struct imsic *imsic = vaia->imsic_state;
	int ret = 0, new_vsfile_hgei = -1, old_vsfile_hgei, old_vsfile_cpu;

	/* Do nothing for emulation mode */
	if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_EMUL)
		return 1;

	/* Read old IMSIC VS-file details */
	read_lock_irqsave(&imsic->vsfile_lock, flags);
	old_vsfile_hgei = imsic->vsfile_hgei;
	old_vsfile_cpu = imsic->vsfile_cpu;
	read_unlock_irqrestore(&imsic->vsfile_lock, flags);

	/* Do nothing if we are continuing on same CPU */
	if (old_vsfile_cpu == vcpu->cpu)
		return 1;

	/* Allocate new IMSIC VS-file */
	ret = kvm_riscv_aia_alloc_hgei(vcpu->cpu, vcpu,
				       &new_vsfile_va, &new_vsfile_pa);
	if (ret <= 0) {
		/* For HW acceleration mode, we can't continue */
		if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_HWACCEL) {
			run->fail_entry.hardware_entry_failure_reason =
								CSR_HSTATUS;
			run->fail_entry.cpu = vcpu->cpu;
			run->exit_reason = KVM_EXIT_FAIL_ENTRY;
			return 0;
		}

		/* Release old IMSIC VS-file */
		if (old_vsfile_cpu >= 0)
			kvm_riscv_vcpu_aia_imsic_release(vcpu);

		/* For automatic mode, we continue */
		goto done;
	}
	new_vsfile_hgei = ret;

	/*
	 * At this point, all interrupt producers are still using
	 * to the old IMSIC VS-file so we first move all interrupt
	 * producers to the new IMSIC VS-file.
	 */

	/* Zero-out new IMSIC VS-file */
	imsic_vsfile_local_clear(new_vsfile_hgei, imsic->nr_hw_eix);

	/* Update G-stage mapping for the new IMSIC VS-file */
	ret = kvm_riscv_gstage_ioremap(kvm, vcpu->arch.aia_context.imsic_addr,
				       new_vsfile_pa, IMSIC_MMIO_PAGE_SZ,
				       true, true);
	if (ret)
		goto fail_free_vsfile_hgei;

	/* TODO: Update the IOMMU mapping ??? */

	/* Update new IMSIC VS-file details in IMSIC context */
	write_lock_irqsave(&imsic->vsfile_lock, flags);
	imsic->vsfile_hgei = new_vsfile_hgei;
	imsic->vsfile_cpu = vcpu->cpu;
	imsic->vsfile_va = new_vsfile_va;
	imsic->vsfile_pa = new_vsfile_pa;
	write_unlock_irqrestore(&imsic->vsfile_lock, flags);

	/*
	 * At this point, all interrupt producers have been moved
	 * to the new IMSIC VS-file so we move register state from
	 * the old IMSIC VS/SW-file to the new IMSIC VS-file.
	 */

	memset(&tmrif, 0, sizeof(tmrif));
	if (old_vsfile_cpu >= 0) {
		/* Read and clear register state from old IMSIC VS-file */
		imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu,
				  imsic->nr_hw_eix, true, &tmrif);

		/* Free-up old IMSIC VS-file */
		kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
	} else {
		/* Read and clear register state from IMSIC SW-file */
		imsic_swfile_read(vcpu, true, &tmrif);
	}

	/* Restore register state in the new IMSIC VS-file */
	imsic_vsfile_local_update(new_vsfile_hgei, imsic->nr_hw_eix, &tmrif);

done:
	/* Set VCPU HSTATUS.VGEIN to new IMSIC VS-file */
	vcpu->arch.guest_context.hstatus &= ~HSTATUS_VGEIN;
	if (new_vsfile_hgei > 0)
		vcpu->arch.guest_context.hstatus |=
			((unsigned long)new_vsfile_hgei) << HSTATUS_VGEIN_SHIFT;

	/* Continue run-loop */
	return 1;

fail_free_vsfile_hgei:
	kvm_riscv_aia_free_hgei(vcpu->cpu, new_vsfile_hgei);
	return ret;
}

int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu, unsigned long isel,
				 unsigned long *val, unsigned long new_val,
				 unsigned long wr_mask)
{
	u32 topei;
	struct imsic_mrif_eix *eix;
	int r, rc = KVM_INSN_CONTINUE_NEXT_SEPC;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	if (isel == KVM_RISCV_AIA_IMSIC_TOPEI) {
		/* Read pending and enabled interrupt with highest priority */
		topei = imsic_mrif_topei(imsic->swfile, imsic->nr_eix,
					 imsic->nr_msis);
		if (val)
			*val = topei;

		/* Writes ignore value and clear top pending interrupt */
		if (topei && wr_mask) {
			topei >>= TOPEI_ID_SHIFT;
			if (topei) {
				eix = &imsic->swfile->eix[topei /
							  BITS_PER_TYPE(u64)];
				clear_bit(topei & (BITS_PER_TYPE(u64) - 1),
					  eix->eip);
			}
		}
	} else {
		r = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix, isel,
				   val, new_val, wr_mask);
		/* Forward unknown IMSIC register to user-space */
		if (r)
			rc = (r == -ENOENT) ? 0 : KVM_INSN_ILLEGAL_TRAP;
	}

	if (wr_mask)
		imsic_swfile_extirq_update(vcpu);

	return rc;
}

int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type,
				bool write, unsigned long *val)
{
	u32 isel, vcpu_id;
	unsigned long flags;
	struct imsic *imsic;
	struct kvm_vcpu *vcpu;
	int rc, vsfile_hgei, vsfile_cpu;

	if (!kvm_riscv_aia_initialized(kvm))
		return -ENODEV;

	vcpu_id = KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(type);
	vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id);
	if (!vcpu)
		return -ENODEV;

	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
	imsic = vcpu->arch.aia_context.imsic_state;

	read_lock_irqsave(&imsic->vsfile_lock, flags);

	rc = 0;
	vsfile_hgei = imsic->vsfile_hgei;
	vsfile_cpu = imsic->vsfile_cpu;
	if (vsfile_cpu < 0) {
		if (write) {
			rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix,
					    isel, NULL, *val, -1UL);
			imsic_swfile_extirq_update(vcpu);
		} else
			rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix,
					    isel, val, 0, 0);
	}

	read_unlock_irqrestore(&imsic->vsfile_lock, flags);

	if (!rc && vsfile_cpu >= 0)
		rc = imsic_vsfile_rw(vsfile_hgei, vsfile_cpu, imsic->nr_eix,
				     isel, write, val);

	return rc;
}

int kvm_riscv_aia_imsic_has_attr(struct kvm *kvm, unsigned long type)
{
	u32 isel, vcpu_id;
	struct imsic *imsic;
	struct kvm_vcpu *vcpu;

	if (!kvm_riscv_aia_initialized(kvm))
		return -ENODEV;

	vcpu_id = KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(type);
	vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id);
	if (!vcpu)
		return -ENODEV;

	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
	imsic = vcpu->arch.aia_context.imsic_state;
	return imsic_mrif_isel_check(imsic->nr_eix, isel);
}

void kvm_riscv_vcpu_aia_imsic_reset(struct kvm_vcpu *vcpu)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	if (!imsic)
		return;

	kvm_riscv_vcpu_aia_imsic_release(vcpu);

	memset(imsic->swfile, 0, sizeof(*imsic->swfile));
}

int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
				    u32 guest_index, u32 offset, u32 iid)
{
	unsigned long flags;
	struct imsic_mrif_eix *eix;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	/* We only emulate one IMSIC MMIO page for each Guest VCPU */
	if (!imsic || !iid || guest_index ||
	    (offset != IMSIC_MMIO_SETIPNUM_LE &&
	     offset != IMSIC_MMIO_SETIPNUM_BE))
		return -ENODEV;

	iid = (offset == IMSIC_MMIO_SETIPNUM_BE) ? __swab32(iid) : iid;
	if (imsic->nr_msis <= iid)
		return -EINVAL;

	read_lock_irqsave(&imsic->vsfile_lock, flags);

	if (imsic->vsfile_cpu >= 0) {
		writel(iid, imsic->vsfile_va + IMSIC_MMIO_SETIPNUM_LE);
		kvm_vcpu_kick(vcpu);
	} else {
		eix = &imsic->swfile->eix[iid / BITS_PER_TYPE(u64)];
		set_bit(iid & (BITS_PER_TYPE(u64) - 1), eix->eip);
		imsic_swfile_extirq_update(vcpu);
	}

	read_unlock_irqrestore(&imsic->vsfile_lock, flags);

	return 0;
}

static int imsic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			   gpa_t addr, int len, void *val)
{
	if (len != 4 || (addr & 0x3) != 0)
		return -EOPNOTSUPP;

	*((u32 *)val) = 0;

	return 0;
}

static int imsic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			    gpa_t addr, int len, const void *val)
{
	struct kvm_msi msi = { 0 };

	if (len != 4 || (addr & 0x3) != 0)
		return -EOPNOTSUPP;

	msi.address_hi = addr >> 32;
	msi.address_lo = (u32)addr;
	msi.data = *((const u32 *)val);
	kvm_riscv_aia_inject_msi(vcpu->kvm, &msi);

	return 0;
};

static struct kvm_io_device_ops imsic_iodoev_ops = {
	.read = imsic_mmio_read,
	.write = imsic_mmio_write,
};

int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu)
{
	int ret = 0;
	struct imsic *imsic;
	struct page *swfile_page;
	struct kvm *kvm = vcpu->kvm;

	/* Fail if we have zero IDs */
	if (!kvm->arch.aia.nr_ids)
		return -EINVAL;

	/* Allocate IMSIC context */
	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
	if (!imsic)
		return -ENOMEM;
	vcpu->arch.aia_context.imsic_state = imsic;

	/* Setup IMSIC context  */
	imsic->nr_msis = kvm->arch.aia.nr_ids + 1;
	rwlock_init(&imsic->vsfile_lock);
	imsic->nr_eix = BITS_TO_U64(imsic->nr_msis);
	imsic->nr_hw_eix = BITS_TO_U64(kvm_riscv_aia_max_ids);
	imsic->vsfile_hgei = imsic->vsfile_cpu = -1;

	/* Setup IMSIC SW-file */
	swfile_page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
				  get_order(sizeof(*imsic->swfile)));
	if (!swfile_page) {
		ret = -ENOMEM;
		goto fail_free_imsic;
	}
	imsic->swfile = page_to_virt(swfile_page);
	imsic->swfile_pa = page_to_phys(swfile_page);

	/* Setup IO device */
	kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);
	mutex_lock(&kvm->slots_lock);
	ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS,
				      vcpu->arch.aia_context.imsic_addr,
				      KVM_DEV_RISCV_IMSIC_SIZE,
				      &imsic->iodev);
	mutex_unlock(&kvm->slots_lock);
	if (ret)
		goto fail_free_swfile;

	return 0;

fail_free_swfile:
	free_pages((unsigned long)imsic->swfile,
		   get_order(sizeof(*imsic->swfile)));
fail_free_imsic:
	vcpu->arch.aia_context.imsic_state = NULL;
	kfree(imsic);
	return ret;
}

void kvm_riscv_vcpu_aia_imsic_cleanup(struct kvm_vcpu *vcpu)
{
	struct kvm *kvm = vcpu->kvm;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	if (!imsic)
		return;

	imsic_vsfile_cleanup(imsic);

	mutex_lock(&kvm->slots_lock);
	kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &imsic->iodev);
	mutex_unlock(&kvm->slots_lock);

	free_pages((unsigned long)imsic->swfile,
		   get_order(sizeof(*imsic->swfile)));

	vcpu->arch.aia_context.imsic_state = NULL;
	kfree(imsic);
}
