// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Loongson-3 Virtual IPI interrupt support.
 *
 * Copyright (C) 2019  Loongson Technologies, Inc.  All rights reserved.
 *
 * Authors: Chen Zhu <zhuchen@loongson.cn>
 * Authors: Huacai Chen <chenhc@lemote.com>
 */

#include <linux/kvm_host.h>

#define IPI_BASE            0x3ff01000ULL

#define CORE0_STATUS_OFF       0x000
#define CORE0_EN_OFF           0x004
#define CORE0_SET_OFF          0x008
#define CORE0_CLEAR_OFF        0x00c
#define CORE0_BUF_20           0x020
#define CORE0_BUF_28           0x028
#define CORE0_BUF_30           0x030
#define CORE0_BUF_38           0x038

#define CORE1_STATUS_OFF       0x100
#define CORE1_EN_OFF           0x104
#define CORE1_SET_OFF          0x108
#define CORE1_CLEAR_OFF        0x10c
#define CORE1_BUF_20           0x120
#define CORE1_BUF_28           0x128
#define CORE1_BUF_30           0x130
#define CORE1_BUF_38           0x138

#define CORE2_STATUS_OFF       0x200
#define CORE2_EN_OFF           0x204
#define CORE2_SET_OFF          0x208
#define CORE2_CLEAR_OFF        0x20c
#define CORE2_BUF_20           0x220
#define CORE2_BUF_28           0x228
#define CORE2_BUF_30           0x230
#define CORE2_BUF_38           0x238

#define CORE3_STATUS_OFF       0x300
#define CORE3_EN_OFF           0x304
#define CORE3_SET_OFF          0x308
#define CORE3_CLEAR_OFF        0x30c
#define CORE3_BUF_20           0x320
#define CORE3_BUF_28           0x328
#define CORE3_BUF_30           0x330
#define CORE3_BUF_38           0x338

static int loongson_vipi_read(struct loongson_kvm_ipi *ipi,
				gpa_t addr, int len, void *val)
{
	uint32_t core = (addr >> 8) & 3;
	uint32_t node = (addr >> 44) & 3;
	uint32_t id = core + node * 4;
	uint64_t offset = addr & 0xff;
	void *pbuf;
	struct ipi_state *s = &(ipi->ipistate[id]);

	BUG_ON(offset & (len - 1));

	switch (offset) {
	case CORE0_STATUS_OFF:
		*(uint64_t *)val = s->status;
		break;

	case CORE0_EN_OFF:
		*(uint64_t *)val = s->en;
		break;

	case CORE0_SET_OFF:
		*(uint64_t *)val = 0;
		break;

	case CORE0_CLEAR_OFF:
		*(uint64_t *)val = 0;
		break;

	case CORE0_BUF_20 ... CORE0_BUF_38:
		pbuf = (void *)s->buf + (offset - 0x20);
		if (len == 8)
			*(uint64_t *)val = *(uint64_t *)pbuf;
		else /* Assume len == 4 */
			*(uint32_t *)val = *(uint32_t *)pbuf;
		break;

	default:
		pr_notice("%s with unknown addr %llx\n", __func__, addr);
		break;
	}

	return 0;
}

static int loongson_vipi_write(struct loongson_kvm_ipi *ipi,
				gpa_t addr, int len, const void *val)
{
	uint32_t core = (addr >> 8) & 3;
	uint32_t node = (addr >> 44) & 3;
	uint32_t id = core + node * 4;
	uint64_t data, offset = addr & 0xff;
	void *pbuf;
	struct kvm *kvm = ipi->kvm;
	struct kvm_mips_interrupt irq;
	struct ipi_state *s = &(ipi->ipistate[id]);

	data = *(uint64_t *)val;
	BUG_ON(offset & (len - 1));

	switch (offset) {
	case CORE0_STATUS_OFF:
		break;

	case CORE0_EN_OFF:
		s->en = data;
		break;

	case CORE0_SET_OFF:
		s->status |= data;
		irq.cpu = id;
		irq.irq = 6;
		kvm_vcpu_ioctl_interrupt(kvm_get_vcpu(kvm, id), &irq);
		break;

	case CORE0_CLEAR_OFF:
		s->status &= ~data;
		if (!s->status) {
			irq.cpu = id;
			irq.irq = -6;
			kvm_vcpu_ioctl_interrupt(kvm_get_vcpu(kvm, id), &irq);
		}
		break;

	case CORE0_BUF_20 ... CORE0_BUF_38:
		pbuf = (void *)s->buf + (offset - 0x20);
		if (len == 8)
			*(uint64_t *)pbuf = (uint64_t)data;
		else /* Assume len == 4 */
			*(uint32_t *)pbuf = (uint32_t)data;
		break;

	default:
		pr_notice("%s with unknown addr %llx\n", __func__, addr);
		break;
	}

	return 0;
}

static int kvm_ipi_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			gpa_t addr, int len, void *val)
{
	unsigned long flags;
	struct loongson_kvm_ipi *ipi;
	struct ipi_io_device *ipi_device;

	ipi_device = container_of(dev, struct ipi_io_device, device);
	ipi = ipi_device->ipi;

	spin_lock_irqsave(&ipi->lock, flags);
	loongson_vipi_read(ipi, addr, len, val);
	spin_unlock_irqrestore(&ipi->lock, flags);

	return 0;
}

static int kvm_ipi_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			gpa_t addr, int len, const void *val)
{
	unsigned long flags;
	struct loongson_kvm_ipi *ipi;
	struct ipi_io_device *ipi_device;

	ipi_device = container_of(dev, struct ipi_io_device, device);
	ipi = ipi_device->ipi;

	spin_lock_irqsave(&ipi->lock, flags);
	loongson_vipi_write(ipi, addr, len, val);
	spin_unlock_irqrestore(&ipi->lock, flags);

	return 0;
}

static const struct kvm_io_device_ops kvm_ipi_ops = {
	.read     = kvm_ipi_read,
	.write    = kvm_ipi_write,
};

void kvm_init_loongson_ipi(struct kvm *kvm)
{
	int i;
	unsigned long addr;
	struct loongson_kvm_ipi *s;
	struct kvm_io_device *device;

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

	/*
	 * Initialize IPI device
	 */
	for (i = 0; i < 4; i++) {
		device = &s->dev_ipi[i].device;
		kvm_iodevice_init(device, &kvm_ipi_ops);
		addr = (((unsigned long)i) << 44) + IPI_BASE;
		mutex_lock(&kvm->slots_lock);
		kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, addr, 0x400, device);
		mutex_unlock(&kvm->slots_lock);
		s->dev_ipi[i].ipi = s;
		s->dev_ipi[i].node_id = i;
	}
}
