1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) 2021 Western Digital Corporation or its affiliates. 4 * Copyright (C) 2022 Ventana Micro Systems Inc. 5 * 6 * Authors: 7 * Anup Patel <apatel@ventanamicro.com> 8 */ 9 10#ifndef __KVM_RISCV_AIA_H 11#define __KVM_RISCV_AIA_H 12 13#include <linux/jump_label.h> 14#include <linux/kvm_types.h> 15#include <asm/csr.h> 16 17struct kvm_aia { 18 /* In-kernel irqchip created */ 19 bool in_kernel; 20 21 /* In-kernel irqchip initialized */ 22 bool initialized; 23 24 /* Virtualization mode (Emulation, HW Accelerated, or Auto) */ 25 u32 mode; 26 27 /* Number of MSIs */ 28 u32 nr_ids; 29 30 /* Number of wired IRQs */ 31 u32 nr_sources; 32 33 /* Number of group bits in IMSIC address */ 34 u32 nr_group_bits; 35 36 /* Position of group bits in IMSIC address */ 37 u32 nr_group_shift; 38 39 /* Number of hart bits in IMSIC address */ 40 u32 nr_hart_bits; 41 42 /* Number of guest bits in IMSIC address */ 43 u32 nr_guest_bits; 44 45 /* Guest physical address of APLIC */ 46 gpa_t aplic_addr; 47 48 /* Internal state of APLIC */ 49 void *aplic_state; 50}; 51 52struct kvm_vcpu_aia_csr { 53 unsigned long vsiselect; 54 unsigned long hviprio1; 55 unsigned long hviprio2; 56 unsigned long vsieh; 57 unsigned long hviph; 58 unsigned long hviprio1h; 59 unsigned long hviprio2h; 60}; 61 62struct kvm_vcpu_aia { 63 /* CPU AIA CSR context of Guest VCPU */ 64 struct kvm_vcpu_aia_csr guest_csr; 65 66 /* CPU AIA CSR context upon Guest VCPU reset */ 67 struct kvm_vcpu_aia_csr guest_reset_csr; 68 69 /* Guest physical address of IMSIC for this VCPU */ 70 gpa_t imsic_addr; 71 72 /* HART index of IMSIC extacted from guest physical address */ 73 u32 hart_index; 74 75 /* Internal state of IMSIC for this VCPU */ 76 void *imsic_state; 77}; 78 79#define KVM_RISCV_AIA_UNDEF_ADDR (-1) 80 81#define kvm_riscv_aia_initialized(k) ((k)->arch.aia.initialized) 82 83#define irqchip_in_kernel(k) ((k)->arch.aia.in_kernel) 84 85extern unsigned int kvm_riscv_aia_nr_hgei; 86extern unsigned int kvm_riscv_aia_max_ids; 87DECLARE_STATIC_KEY_FALSE(kvm_riscv_aia_available); 88#define kvm_riscv_aia_available() \ 89 static_branch_unlikely(&kvm_riscv_aia_available) 90 91extern struct kvm_device_ops kvm_riscv_aia_device_ops; 92 93void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu); 94int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu); 95 96#define KVM_RISCV_AIA_IMSIC_TOPEI (ISELECT_MASK + 1) 97int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu, unsigned long isel, 98 unsigned long *val, unsigned long new_val, 99 unsigned long wr_mask); 100int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type, 101 bool write, unsigned long *val); 102int kvm_riscv_aia_imsic_has_attr(struct kvm *kvm, unsigned long type); 103void kvm_riscv_vcpu_aia_imsic_reset(struct kvm_vcpu *vcpu); 104int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu, 105 u32 guest_index, u32 offset, u32 iid); 106int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu); 107void kvm_riscv_vcpu_aia_imsic_cleanup(struct kvm_vcpu *vcpu); 108 109int kvm_riscv_aia_aplic_set_attr(struct kvm *kvm, unsigned long type, u32 v); 110int kvm_riscv_aia_aplic_get_attr(struct kvm *kvm, unsigned long type, u32 *v); 111int kvm_riscv_aia_aplic_has_attr(struct kvm *kvm, unsigned long type); 112int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level); 113int kvm_riscv_aia_aplic_init(struct kvm *kvm); 114void kvm_riscv_aia_aplic_cleanup(struct kvm *kvm); 115 116#ifdef CONFIG_32BIT 117void kvm_riscv_vcpu_aia_flush_interrupts(struct kvm_vcpu *vcpu); 118void kvm_riscv_vcpu_aia_sync_interrupts(struct kvm_vcpu *vcpu); 119#else 120static inline void kvm_riscv_vcpu_aia_flush_interrupts(struct kvm_vcpu *vcpu) 121{ 122} 123static inline void kvm_riscv_vcpu_aia_sync_interrupts(struct kvm_vcpu *vcpu) 124{ 125} 126#endif 127bool kvm_riscv_vcpu_aia_has_interrupts(struct kvm_vcpu *vcpu, u64 mask); 128 129void kvm_riscv_vcpu_aia_update_hvip(struct kvm_vcpu *vcpu); 130void kvm_riscv_vcpu_aia_load(struct kvm_vcpu *vcpu, int cpu); 131void kvm_riscv_vcpu_aia_put(struct kvm_vcpu *vcpu); 132int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu, 133 unsigned long reg_num, 134 unsigned long *out_val); 135int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu, 136 unsigned long reg_num, 137 unsigned long val); 138 139int kvm_riscv_vcpu_aia_rmw_topei(struct kvm_vcpu *vcpu, 140 unsigned int csr_num, 141 unsigned long *val, 142 unsigned long new_val, 143 unsigned long wr_mask); 144int kvm_riscv_vcpu_aia_rmw_ireg(struct kvm_vcpu *vcpu, unsigned int csr_num, 145 unsigned long *val, unsigned long new_val, 146 unsigned long wr_mask); 147#define KVM_RISCV_VCPU_AIA_CSR_FUNCS \ 148{ .base = CSR_SIREG, .count = 1, .func = kvm_riscv_vcpu_aia_rmw_ireg }, \ 149{ .base = CSR_STOPEI, .count = 1, .func = kvm_riscv_vcpu_aia_rmw_topei }, 150 151int kvm_riscv_vcpu_aia_update(struct kvm_vcpu *vcpu); 152void kvm_riscv_vcpu_aia_reset(struct kvm_vcpu *vcpu); 153int kvm_riscv_vcpu_aia_init(struct kvm_vcpu *vcpu); 154void kvm_riscv_vcpu_aia_deinit(struct kvm_vcpu *vcpu); 155 156int kvm_riscv_aia_inject_msi_by_id(struct kvm *kvm, u32 hart_index, 157 u32 guest_index, u32 iid); 158int kvm_riscv_aia_inject_msi(struct kvm *kvm, struct kvm_msi *msi); 159int kvm_riscv_aia_inject_irq(struct kvm *kvm, unsigned int irq, bool level); 160 161void kvm_riscv_aia_init_vm(struct kvm *kvm); 162void kvm_riscv_aia_destroy_vm(struct kvm *kvm); 163 164int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner, 165 void __iomem **hgei_va, phys_addr_t *hgei_pa); 166void kvm_riscv_aia_free_hgei(int cpu, int hgei); 167void kvm_riscv_aia_wakeon_hgei(struct kvm_vcpu *owner, bool enable); 168 169void kvm_riscv_aia_enable(void); 170void kvm_riscv_aia_disable(void); 171int kvm_riscv_aia_init(void); 172void kvm_riscv_aia_exit(void); 173 174#endif 175