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 __ASM_LOONGARCH_KVMCPU_H__
78c2ecf20Sopenharmony_ci#define __ASM_LOONGARCH_KVMCPU_H__
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/kvm_host.h>
108c2ecf20Sopenharmony_ci#include <asm/kvm_host.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define LARCH_INT_SIP0			0
138c2ecf20Sopenharmony_ci#define LARCH_INT_SIP1			1
148c2ecf20Sopenharmony_ci#define LARCH_INT_IP0			2
158c2ecf20Sopenharmony_ci#define LARCH_INT_IP1			3
168c2ecf20Sopenharmony_ci#define LARCH_INT_IP2			4
178c2ecf20Sopenharmony_ci#define LARCH_INT_IP3			5
188c2ecf20Sopenharmony_ci#define LARCH_INT_IP4			6
198c2ecf20Sopenharmony_ci#define LARCH_INT_IP5			7
208c2ecf20Sopenharmony_ci#define LARCH_INT_IP6			8
218c2ecf20Sopenharmony_ci#define LARCH_INT_IP7			9
228c2ecf20Sopenharmony_ci#define LARCH_INT_PMU			10
238c2ecf20Sopenharmony_ci#define LARCH_INT_TIMER			11
248c2ecf20Sopenharmony_ci#define LARCH_INT_IPI			12
258c2ecf20Sopenharmony_ci#define LOONGARCH_EXC_MAX		(LARCH_INT_IPI + 1)
268c2ecf20Sopenharmony_ci#define LOONGARCH_EXC_IPNUM		(LOONGARCH_EXC_MAX)
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/* Controlled by 0x5 guest exst */
298c2ecf20Sopenharmony_ci#define CPU_SIP0			(_ULCAST_(1))
308c2ecf20Sopenharmony_ci#define CPU_SIP1			(_ULCAST_(1) << 1)
318c2ecf20Sopenharmony_ci#define CPU_PMU				(_ULCAST_(1) << 10)
328c2ecf20Sopenharmony_ci#define CPU_TIMER			(_ULCAST_(1) << 11)
338c2ecf20Sopenharmony_ci#define CPU_IPI				(_ULCAST_(1) << 12)
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/* Controlled by 0x52 guest exception VIP
368c2ecf20Sopenharmony_ci * aligned to exst bit 5~12
378c2ecf20Sopenharmony_ci */
388c2ecf20Sopenharmony_ci#define CPU_IP0				(_ULCAST_(1))
398c2ecf20Sopenharmony_ci#define CPU_IP1				(_ULCAST_(1) << 1)
408c2ecf20Sopenharmony_ci#define CPU_IP2				(_ULCAST_(1) << 2)
418c2ecf20Sopenharmony_ci#define CPU_IP3				(_ULCAST_(1) << 3)
428c2ecf20Sopenharmony_ci#define CPU_IP4				(_ULCAST_(1) << 4)
438c2ecf20Sopenharmony_ci#define CPU_IP5				(_ULCAST_(1) << 5)
448c2ecf20Sopenharmony_ci#define CPU_IP6				(_ULCAST_(1) << 6)
458c2ecf20Sopenharmony_ci#define CPU_IP7				(_ULCAST_(1) << 7)
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define MNSEC_PER_SEC			(NSEC_PER_SEC >> 20)
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* KVM_IRQ_LINE irq field index values */
508c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_SHIFT		24
518c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_MASK		0xff
528c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_VCPU_SHIFT		16
538c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_VCPU_MASK		0xff
548c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_NUM_SHIFT		0
558c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_NUM_MASK		0xffff
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/* irq_type field */
588c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_CPU_IP		0
598c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_CPU_IO		1
608c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_HT		2
618c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_MSI		3
628c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_IOAPIC		4
638c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_TYPE_ROUTE		5
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/* out-of-kernel GIC cpu interrupt injection irq_number field */
668c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_CPU_IRQ		0
678c2ecf20Sopenharmony_ci#define KVM_LOONGSON_IRQ_CPU_FIQ		1
688c2ecf20Sopenharmony_ci#define KVM_LOONGSON_CPU_IP_NUM			8
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_citypedef union loongarch_instruction  larch_inst;
718c2ecf20Sopenharmony_citypedef int (*exit_handle_fn)(struct kvm_vcpu *);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciint  _kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst);
748c2ecf20Sopenharmony_ciint  _kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst);
758c2ecf20Sopenharmony_ciint  _kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run);
768c2ecf20Sopenharmony_ciint  _kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run);
778c2ecf20Sopenharmony_ciint  _kvm_emu_idle(struct kvm_vcpu *vcpu);
788c2ecf20Sopenharmony_ciint  _kvm_handle_pv_hcall(struct kvm_vcpu *vcpu);
798c2ecf20Sopenharmony_ciint  _kvm_pending_timer(struct kvm_vcpu *vcpu);
808c2ecf20Sopenharmony_ciint  _kvm_handle_fault(struct kvm_vcpu *vcpu, int fault);
818c2ecf20Sopenharmony_civoid _kvm_deliver_intr(struct kvm_vcpu *vcpu);
828c2ecf20Sopenharmony_civoid irqchip_debug_init(struct kvm *kvm);
838c2ecf20Sopenharmony_civoid irqchip_debug_destroy(struct kvm *kvm);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_civoid kvm_own_fpu(struct kvm_vcpu *vcpu);
868c2ecf20Sopenharmony_civoid kvm_own_lsx(struct kvm_vcpu *vcpu);
878c2ecf20Sopenharmony_civoid kvm_lose_fpu(struct kvm_vcpu *vcpu);
888c2ecf20Sopenharmony_civoid kvm_own_lasx(struct kvm_vcpu *vcpu);
898c2ecf20Sopenharmony_civoid kvm_own_lbt(struct kvm_vcpu *vcpu);
908c2ecf20Sopenharmony_civoid kvm_restore_lbt(struct kvm_vcpu *cpu);
918c2ecf20Sopenharmony_civoid kvm_save_lbt(struct kvm_vcpu *cpu);
928c2ecf20Sopenharmony_civoid kvm_save_fpu(struct kvm_vcpu *cpu);
938c2ecf20Sopenharmony_civoid kvm_restore_fpu(struct kvm_vcpu *cpu);
948c2ecf20Sopenharmony_civoid kvm_save_lsx(struct kvm_vcpu *cpu);
958c2ecf20Sopenharmony_civoid kvm_restore_lsx(struct kvm_vcpu *cpu);
968c2ecf20Sopenharmony_civoid kvm_restore_lsx_upper(struct kvm_vcpu *cpu);
978c2ecf20Sopenharmony_civoid kvm_save_lasx(struct kvm_vcpu *cpu);
988c2ecf20Sopenharmony_civoid kvm_restore_lasx(struct kvm_vcpu *cpu);
998c2ecf20Sopenharmony_civoid kvm_restore_lasx_upper(struct kvm_vcpu *cpu);
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_civoid kvm_lose_hw_perf(struct kvm_vcpu *vcpu);
1028c2ecf20Sopenharmony_civoid kvm_restore_hw_perf(struct kvm_vcpu *vcpu);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_civoid kvm_acquire_timer(struct kvm_vcpu *vcpu);
1058c2ecf20Sopenharmony_civoid kvm_reset_timer(struct kvm_vcpu *vcpu);
1068c2ecf20Sopenharmony_cienum hrtimer_restart kvm_count_timeout(struct kvm_vcpu *vcpu);
1078c2ecf20Sopenharmony_civoid kvm_init_timer(struct kvm_vcpu *vcpu, unsigned long hz);
1088c2ecf20Sopenharmony_civoid kvm_restore_timer(struct kvm_vcpu *vcpu);
1098c2ecf20Sopenharmony_civoid kvm_save_timer(struct kvm_vcpu *vcpu);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/*
1128c2ecf20Sopenharmony_ci * Loongarch KVM guest interrupt handling.
1138c2ecf20Sopenharmony_ci */
1148c2ecf20Sopenharmony_cistatic inline void _kvm_queue_irq(struct kvm_vcpu *vcpu, unsigned int irq)
1158c2ecf20Sopenharmony_ci{
1168c2ecf20Sopenharmony_ci	set_bit(irq, &vcpu->arch.irq_pending);
1178c2ecf20Sopenharmony_ci	clear_bit(irq, &vcpu->arch.irq_clear);
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistatic inline void _kvm_dequeue_irq(struct kvm_vcpu *vcpu, unsigned int irq)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci	clear_bit(irq, &vcpu->arch.irq_pending);
1238c2ecf20Sopenharmony_ci	set_bit(irq, &vcpu->arch.irq_clear);
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci#endif /* __ASM_LOONGARCH_KVMCPU_H__ */
127