// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2024 Loongson Technology Corporation Limited
 */

#include <asm/kvm_eiointc.h>
#include <asm/kvm_pch_pic.h>
#include <asm/kvm_vcpu.h>
#include <linux/count_zeros.h>

/* update the isr according to irq level and route irq to eiointc */
static void pch_pic_update_irq(struct loongarch_pch_pic *s, int irq, int level)
{
	u64 mask = BIT(irq);

	/*
	 * set isr and route irq to eiointc and
	 * the route table is in htmsi_vector[]
	 */
	if (level) {
		if (mask & s->irr & ~s->mask) {
			s->isr |= mask;
			irq = s->htmsi_vector[irq];
			eiointc_set_irq(s->kvm->arch.eiointc, irq, level);
		}
	} else {
		if (mask & s->isr & ~s->irr) {
			s->isr &= ~mask;
			irq = s->htmsi_vector[irq];
			eiointc_set_irq(s->kvm->arch.eiointc, irq, level);
		}
	}
}

/* update batch irqs, the irq_mask is a bitmap of irqs */
static void pch_pic_update_batch_irqs(struct loongarch_pch_pic *s, u64 irq_mask, int level)
{
	int irq, bits;

	/* find each irq by irqs bitmap and update each irq */
	bits = sizeof(irq_mask) * 8;
	irq = find_first_bit((void *)&irq_mask, bits);
	while (irq < bits) {
		pch_pic_update_irq(s, irq, level);
		bitmap_clear((void *)&irq_mask, irq, 1);
		irq = find_first_bit((void *)&irq_mask, bits);
	}
}

/* called when a irq is triggered in pch pic */
void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level)
{
	u64 mask = BIT(irq);

	spin_lock(&s->lock);
	if (level)
		s->irr |= mask; /* set irr */
	else {
		/*
		 * In edge triggered mode, 0 does not mean to clear irq
		 * The irr register variable is cleared when cpu writes to the
		 * PCH_PIC_CLEAR_START address area
		 */
		if (s->edge & mask) {
			spin_unlock(&s->lock);
			return;
		}
		s->irr &= ~mask;
	}
	pch_pic_update_irq(s, irq, level);
	spin_unlock(&s->lock);
}

/* msi irq handler */
void pch_msi_set_irq(struct kvm *kvm, int irq, int level)
{
	eiointc_set_irq(kvm->arch.eiointc, irq, level);
}

/*
 * pch pic register is 64-bit, but it is accessed by 32-bit,
 * so we use high to get whether low or high 32 bits we want
 * to read.
 */
static u32 pch_pic_read_reg(u64 *s, int high)
{
	u64 val = *s;

	/* read the high 32 bits when high is 1 */
	return high ? (u32)(val >> 32) : (u32)val;
}

/*
 * pch pic register is 64-bit, but it is accessed by 32-bit,
 * so we use high to get whether low or high 32 bits we want
 * to write.
 */
static u32 pch_pic_write_reg(u64 *s, int high, u32 v)
{
	u64 val = *s, data = v;

	if (high) {
		/*
		 * Clear val high 32 bits
		 * Write the high 32 bits when the high is 1
		 */
		*s = (val << 32 >> 32) | (data << 32);
		val >>= 32;
	} else
		/*
		 * Clear val low 32 bits
		 * Write the low 32 bits when the high is 0
		 */
		*s = (val >> 32 << 32) | v;

	return (u32)val;
}

static int loongarch_pch_pic_read(struct loongarch_pch_pic *s, gpa_t addr, int len, void *val)
{
	int offset, index, ret = 0;
	u32 data = 0;
	u64 int_id = 0;

	offset = addr - s->pch_pic_base;

	spin_lock(&s->lock);
	switch (offset) {
	case PCH_PIC_INT_ID_START ... PCH_PIC_INT_ID_END:
		/* int id version */
		int_id |= (u64)PCH_PIC_INT_ID_VER << 32;
		/* irq number */
		int_id |= (u64)31 << (32 + 16);
		/* int id value */
		int_id |= PCH_PIC_INT_ID_VAL;
		*(u64 *)val = int_id;
		break;
	case PCH_PIC_MASK_START ... PCH_PIC_MASK_END:
		offset -= PCH_PIC_MASK_START;
		index = offset >> 2;
		/* read mask reg */
		data = pch_pic_read_reg(&s->mask, index);
		*(u32 *)val = data;
		break;
	case PCH_PIC_HTMSI_EN_START ... PCH_PIC_HTMSI_EN_END:
		offset -= PCH_PIC_HTMSI_EN_START;
		index = offset >> 2;
		/* read htmsi enable reg */
		data = pch_pic_read_reg(&s->htmsi_en, index);
		*(u32 *)val = data;
		break;
	case PCH_PIC_EDGE_START ... PCH_PIC_EDGE_END:
		offset -= PCH_PIC_EDGE_START;
		index = offset >> 2;
		/* read edge enable reg */
		data = pch_pic_read_reg(&s->edge, index);
		*(u32 *)val = data;
		break;
	case PCH_PIC_AUTO_CTRL0_START ... PCH_PIC_AUTO_CTRL0_END:
	case PCH_PIC_AUTO_CTRL1_START ... PCH_PIC_AUTO_CTRL1_END:
		/* we only use default mode: fixed interrupt distribution mode */
		*(u32 *)val = 0;
		break;
	case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END:
		/* only route to int0: eiointc */
		*(u8 *)val = 1;
		break;
	case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END:
		offset -= PCH_PIC_HTMSI_VEC_START;
		/* read htmsi vector */
		data = s->htmsi_vector[offset];
		*(u8 *)val = data;
		break;
	case PCH_PIC_POLARITY_START ... PCH_PIC_POLARITY_END:
		/* we only use defalut value 0: high level triggered */
		*(u32 *)val = 0;
		break;
	default:
		ret = -EINVAL;
	}
	spin_unlock(&s->lock);

	return ret;
}

static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,
			struct kvm_io_device *dev,
			gpa_t addr, int len, void *val)
{
	int ret;
	struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic;

	if (!s) {
		kvm_err("%s: pch pic irqchip not valid!\n", __func__);
		return -EINVAL;
	}

	/* statistics of pch pic reading */
	vcpu->stat.pch_pic_read_exits++;
	ret = loongarch_pch_pic_read(s, addr, len, val);

	return ret;
}

static int loongarch_pch_pic_write(struct loongarch_pch_pic *s, gpa_t addr,
					int len, const void *val)
{
	int ret;
	u32 old, data, offset, index;
	u64 irq;

	ret = 0;
	data = *(u32 *)val;
	offset = addr - s->pch_pic_base;

	spin_lock(&s->lock);
	switch (offset) {
	case PCH_PIC_MASK_START ... PCH_PIC_MASK_END:
		offset -= PCH_PIC_MASK_START;
		/* get whether high or low 32 bits we want to write */
		index = offset >> 2;
		old = pch_pic_write_reg(&s->mask, index, data);
		/* enable irq when mask value change to 0 */
		irq = (old & ~data) << (32 * index);
		pch_pic_update_batch_irqs(s, irq, 1);
		/* disable irq when mask value change to 1 */
		irq = (~old & data) << (32 * index);
		pch_pic_update_batch_irqs(s, irq, 0);
		break;
	case PCH_PIC_HTMSI_EN_START ... PCH_PIC_HTMSI_EN_END:
		offset -= PCH_PIC_HTMSI_EN_START;
		index = offset >> 2;
		pch_pic_write_reg(&s->htmsi_en, index, data);
		break;
	case PCH_PIC_EDGE_START ... PCH_PIC_EDGE_END:
		offset -= PCH_PIC_EDGE_START;
		index = offset >> 2;
		/* 1: edge triggered, 0: level triggered */
		pch_pic_write_reg(&s->edge, index, data);
		break;
	case PCH_PIC_CLEAR_START ... PCH_PIC_CLEAR_END:
		offset -= PCH_PIC_CLEAR_START;
		index = offset >> 2;
		/* write 1 to clear edge irq */
		old = pch_pic_read_reg(&s->irr, index);
		/*
		 * get the irq bitmap which is edge triggered and
		 * already set and to be cleared
		 */
		irq = old & pch_pic_read_reg(&s->edge, index) & data;
		/* write irr to the new state where irqs have been cleared */
		pch_pic_write_reg(&s->irr, index, old & ~irq);
		/* update cleared irqs */
		pch_pic_update_batch_irqs(s, irq, 0);
		break;
	case PCH_PIC_AUTO_CTRL0_START ... PCH_PIC_AUTO_CTRL0_END:
		offset -= PCH_PIC_AUTO_CTRL0_START;
		index = offset >> 2;
		/* we only use default mode: fixed interrupt distribution mode */
		pch_pic_write_reg(&s->auto_ctrl0, index, 0);
		break;
	case PCH_PIC_AUTO_CTRL1_START ... PCH_PIC_AUTO_CTRL1_END:
		offset -= PCH_PIC_AUTO_CTRL1_START;
		index = offset >> 2;
		/* we only use default mode: fixed interrupt distribution mode */
		pch_pic_write_reg(&s->auto_ctrl1, index, 0);
		break;
	case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END:
		offset -= PCH_PIC_ROUTE_ENTRY_START;
		/* only route to int0: eiointc */
		s->route_entry[offset] = 1;
		break;
	case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END:
		/* route table to eiointc */
		offset -= PCH_PIC_HTMSI_VEC_START;
		s->htmsi_vector[offset] = (u8)data;
		break;
	case PCH_PIC_POLARITY_START ... PCH_PIC_POLARITY_END:
		offset -= PCH_PIC_POLARITY_START;
		index = offset >> 2;
		/* we only use defalut value 0: high level triggered */
		pch_pic_write_reg(&s->polarity, index, 0);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	spin_unlock(&s->lock);

	return ret;
}

static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,
			struct kvm_io_device *dev,
			gpa_t addr, int len, const void *val)
{
	int ret;
	struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic;

	if (!s) {
		kvm_err("%s: pch pic irqchip not valid!\n", __func__);
		return -EINVAL;
	}

	/* statistics of pch pic writing */
	vcpu->stat.pch_pic_write_exits++;
	ret = loongarch_pch_pic_write(s, addr, len, val);

	return ret;
}

static const struct kvm_io_device_ops kvm_pch_pic_ops = {
	.read	= kvm_pch_pic_read,
	.write	= kvm_pch_pic_write,
};

static int kvm_pch_pic_init(struct kvm_device *dev, u64 addr)
{
	int ret;
	struct kvm *kvm = dev->kvm;
	struct kvm_io_device *device;
	struct loongarch_pch_pic *s = dev->kvm->arch.pch_pic;

	s->pch_pic_base = addr;
	device = &s->device;
	/* init device by pch pic writing and reading ops */
	kvm_iodevice_init(device, &kvm_pch_pic_ops);
	mutex_lock(&kvm->slots_lock);
	/* register pch pic device */
	ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, addr, PCH_PIC_SIZE, device);
	mutex_unlock(&kvm->slots_lock);

	return (ret < 0) ? -EFAULT : 0;
}

/* used by user space to get or set pch pic registers */
static int kvm_pch_pic_regs_access(struct kvm_device *dev,
				struct kvm_device_attr *attr,
				bool is_write)
{
	int addr, offset, len = 8, ret = 0;
	void __user *data;
	void *p = NULL;
	struct loongarch_pch_pic *s;

	s = dev->kvm->arch.pch_pic;
	addr = attr->attr;
	data = (void __user *)attr->addr;

	/* get pointer to pch pic register by addr */
	switch (addr) {
	case PCH_PIC_MASK_START:
		p = &s->mask;
		break;
	case PCH_PIC_HTMSI_EN_START:
		p = &s->htmsi_en;
		break;
	case PCH_PIC_EDGE_START:
		p = &s->edge;
		break;
	case PCH_PIC_AUTO_CTRL0_START:
		p = &s->auto_ctrl0;
		break;
	case PCH_PIC_AUTO_CTRL1_START:
		p = &s->auto_ctrl1;
		break;
	case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END:
		offset = addr - PCH_PIC_ROUTE_ENTRY_START;
		p = &s->route_entry[offset];
		len = 1;
		break;
	case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END:
		offset = addr - PCH_PIC_HTMSI_VEC_START;
		p = &s->htmsi_vector[offset];
		len = 1;
		break;
	case PCH_PIC_INT_IRR_START:
		p = &s->irr;
		break;
	case PCH_PIC_INT_ISR_START:
		p = &s->isr;
		break;
	case PCH_PIC_POLARITY_START:
		p = &s->polarity;
		break;
	default:
		return -EINVAL;
	}

	spin_lock(&s->lock);
	/* write or read value according to is_write */
	if (is_write) {
		if (copy_from_user(p, data, len))
			ret = -EFAULT;
	} else {
		if (copy_to_user(data, p, len))
			ret = -EFAULT;
	}
	spin_unlock(&s->lock);

	return ret;
}

static int kvm_pch_pic_get_attr(struct kvm_device *dev,
				struct kvm_device_attr *attr)
{
	switch (attr->group) {
	case KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS:
		return kvm_pch_pic_regs_access(dev, attr, false);
	default:
		return -EINVAL;
	}
}

static int kvm_pch_pic_set_attr(struct kvm_device *dev,
				struct kvm_device_attr *attr)
{
	u64 addr;
	void __user *uaddr = (void __user *)(long)attr->addr;

	switch (attr->group) {
	case KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL:
		switch (attr->attr) {
		case KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT:
			if (copy_from_user(&addr, uaddr, sizeof(addr)))
				return -EFAULT;

			if (!dev->kvm->arch.pch_pic) {
				kvm_err("%s: please create pch_pic irqchip first!\n", __func__);
				return -ENODEV;
			}

			return kvm_pch_pic_init(dev, addr);
		default:
			kvm_err("%s: unknown group (%d) attr (%lld)\n", __func__, attr->group,
					attr->attr);
			return -EINVAL;
		}
	case KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS:
		return kvm_pch_pic_regs_access(dev, attr, true);
	default:
		return -EINVAL;
	}
}

static int kvm_setup_default_irq_routing(struct kvm *kvm)
{
	int i, ret;
	u32 nr = KVM_IRQCHIP_NUM_PINS;
	struct kvm_irq_routing_entry *entries;

	entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL);
	if (!entries)
		return -ENOMEM;

	for (i = 0; i < nr; i++) {
		entries[i].gsi = i;
		entries[i].type = KVM_IRQ_ROUTING_IRQCHIP;
		entries[i].u.irqchip.irqchip = 0;
		entries[i].u.irqchip.pin = i;
	}
	ret = kvm_set_irq_routing(kvm, entries, nr, 0);
	kfree(entries);

	return ret;
}

static int kvm_pch_pic_create(struct kvm_device *dev, u32 type)
{
	int ret;
	struct kvm *kvm = dev->kvm;
	struct loongarch_pch_pic *s;

	/* pch pic should not has been created */
	if (kvm->arch.pch_pic)
		return -EINVAL;

	ret = kvm_setup_default_irq_routing(kvm);
	if (ret)
		return -ENOMEM;

	s = kzalloc(sizeof(struct loongarch_pch_pic), GFP_KERNEL);
	if (!s)
		return -ENOMEM;

	spin_lock_init(&s->lock);
	s->kvm = kvm;
	kvm->arch.pch_pic = s;

	return 0;
}

static void kvm_pch_pic_destroy(struct kvm_device *dev)
{
	struct kvm *kvm;
	struct loongarch_pch_pic *s;

	if (!dev || !dev->kvm || !dev->kvm->arch.pch_pic)
		return;

	kvm = dev->kvm;
	s = kvm->arch.pch_pic;
	/* unregister pch pic device and free it's memory */
	kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &s->device);
	kfree(s);
}

static struct kvm_device_ops kvm_pch_pic_dev_ops = {
	.name = "kvm-loongarch-pch-pic",
	.create = kvm_pch_pic_create,
	.destroy = kvm_pch_pic_destroy,
	.set_attr = kvm_pch_pic_set_attr,
	.get_attr = kvm_pch_pic_get_attr,
};

int kvm_loongarch_register_pch_pic_device(void)
{
	return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
}
