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