18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef __LS3A_KVM_IPI_H
78c2ecf20Sopenharmony_ci#define __LS3A_KVM_IPI_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/mm_types.h>
108c2ecf20Sopenharmony_ci#include <linux/hrtimer.h>
118c2ecf20Sopenharmony_ci#include <linux/kvm_host.h>
128c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <kvm/iodev.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_citypedef struct gipi_single {
178c2ecf20Sopenharmony_ci	uint32_t status;
188c2ecf20Sopenharmony_ci	uint32_t en;
198c2ecf20Sopenharmony_ci	uint32_t set;
208c2ecf20Sopenharmony_ci	uint32_t clear;
218c2ecf20Sopenharmony_ci	uint64_t buf[4];
228c2ecf20Sopenharmony_ci} gipi_single;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_citypedef struct gipiState {
258c2ecf20Sopenharmony_ci	gipi_single core[KVM_MAX_VCPUS];
268c2ecf20Sopenharmony_ci} gipiState;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistruct ls3a_kvm_ipi;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_citypedef struct ipi_io_device {
318c2ecf20Sopenharmony_ci	struct ls3a_kvm_ipi *ipi;
328c2ecf20Sopenharmony_ci	struct kvm_io_device device;
338c2ecf20Sopenharmony_ci	int nodeNum;
348c2ecf20Sopenharmony_ci} ipi_io_device;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistruct ls3a_kvm_ipi {
378c2ecf20Sopenharmony_ci	spinlock_t lock;
388c2ecf20Sopenharmony_ci	struct kvm *kvm;
398c2ecf20Sopenharmony_ci	gipiState ls3a_gipistate;
408c2ecf20Sopenharmony_ci	int nodeNum;
418c2ecf20Sopenharmony_ci	ipi_io_device dev_ls3a_ipi;
428c2ecf20Sopenharmony_ci};
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#define SMP_MAILBOX			(LOONGSON_VIRT_REG_BASE + 0x0000)
458c2ecf20Sopenharmony_ci#define KVM_IPI_REG_ADDRESS(id, off)	(SMP_MAILBOX | (id << 8) | off)
468c2ecf20Sopenharmony_ci#define KVM_IOCSR_IPI_ADDR_SIZE		0x10000
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#define CORE0_STATUS_OFF	0x000
498c2ecf20Sopenharmony_ci#define CORE0_EN_OFF		0x004
508c2ecf20Sopenharmony_ci#define CORE0_SET_OFF		0x008
518c2ecf20Sopenharmony_ci#define CORE0_CLEAR_OFF		0x00c
528c2ecf20Sopenharmony_ci#define CORE0_BUF_20		0x020
538c2ecf20Sopenharmony_ci#define CORE0_BUF_28		0x028
548c2ecf20Sopenharmony_ci#define CORE0_BUF_30		0x030
558c2ecf20Sopenharmony_ci#define CORE0_BUF_38		0x038
568c2ecf20Sopenharmony_ci#define CORE0_IPI_SEND		0x040
578c2ecf20Sopenharmony_ci#define CORE0_MAIL_SEND		0x048
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic inline struct ls3a_kvm_ipi *ls3a_ipi_irqchip(struct kvm *kvm)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	return kvm->arch.v_gipi;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic inline int ls3a_ipi_in_kernel(struct kvm *kvm)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	int ret;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	ret = (ls3a_ipi_irqchip(kvm) != NULL);
698c2ecf20Sopenharmony_ci	return ret;
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciint kvm_create_ls3a_ipi(struct kvm *kvm);
738c2ecf20Sopenharmony_civoid kvm_destroy_ls3a_ipi(struct kvm *kvm);
748c2ecf20Sopenharmony_ciint kvm_set_ls3a_ipi(struct kvm *kvm, struct loongarch_gipiState *state);
758c2ecf20Sopenharmony_ciint kvm_get_ls3a_ipi(struct kvm *kvm, struct loongarch_gipiState *state);
768c2ecf20Sopenharmony_ciint kvm_helper_send_ipi(struct kvm_vcpu *vcpu, unsigned int cpu, unsigned int action);
778c2ecf20Sopenharmony_ci#endif
78