1/* 2 * Copyright (C) 2012-2014 ARM Ltd. 3 * Author: Marc Zyngier <marc.zyngier@arm.com> 4 * 5 * Derived from virt/kvm/arm/vgic.c 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20#ifndef __KVM_VGIC_H__ 21#define __KVM_VGIC_H__ 22 23#include <kvm/iodev.h> 24 25#define VGIC_ADDR_UNDEF (-1) 26#define IS_VGIC_ADDR_UNDEF(_x) ((_x) == VGIC_ADDR_UNDEF) 27 28#define PRODUCT_ID_KVM 0x4b /* ASCII code K */ 29#define IMPLEMENTER_ARM 0x43b 30 31#define ACCESS_READ_VALUE (1 << 0) 32#define ACCESS_READ_RAZ (0 << 0) 33#define ACCESS_READ_MASK(x) ((x) & (1 << 0)) 34#define ACCESS_WRITE_IGNORED (0 << 1) 35#define ACCESS_WRITE_SETBIT (1 << 1) 36#define ACCESS_WRITE_CLEARBIT (2 << 1) 37#define ACCESS_WRITE_VALUE (3 << 1) 38#define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) 39 40#define VCPU_NOT_ALLOCATED ((u8)-1) 41 42unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x); 43 44void vgic_update_state(struct kvm *kvm); 45int vgic_init_common_maps(struct kvm *kvm); 46 47u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, int cpuid, u32 offset); 48u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, int cpuid, u32 offset); 49 50void vgic_dist_irq_set_pending(struct kvm_vcpu *vcpu, int irq); 51void vgic_dist_irq_clear_pending(struct kvm_vcpu *vcpu, int irq); 52void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq); 53void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid, 54 int irq, int val); 55 56void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 57void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 58 59bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq); 60void vgic_unqueue_irqs(struct kvm_vcpu *vcpu); 61 62struct kvm_exit_mmio { 63 phys_addr_t phys_addr; 64 void *data; 65 u32 len; 66 bool is_write; 67 void *private; 68}; 69 70void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg, 71 phys_addr_t offset, int mode); 72bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio, 73 phys_addr_t offset); 74 75static inline 76u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask) 77{ 78 return le32_to_cpu(*((u32 *)mmio->data)) & mask; 79} 80 81static inline 82void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value) 83{ 84 *((u32 *)mmio->data) = cpu_to_le32(value) & mask; 85} 86 87struct vgic_io_range { 88 phys_addr_t base; 89 unsigned long len; 90 int bits_per_irq; 91 bool (*handle_mmio)(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio, 92 phys_addr_t offset); 93}; 94 95int vgic_register_kvm_io_dev(struct kvm *kvm, gpa_t base, int len, 96 const struct vgic_io_range *ranges, 97 int redist_id, 98 struct vgic_io_device *iodev); 99 100static inline bool is_in_range(phys_addr_t addr, unsigned long len, 101 phys_addr_t baseaddr, unsigned long size) 102{ 103 return (addr >= baseaddr) && (addr + len <= baseaddr + size); 104} 105 106const 107struct vgic_io_range *vgic_find_range(const struct vgic_io_range *ranges, 108 int len, gpa_t offset); 109 110bool vgic_handle_enable_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio, 111 phys_addr_t offset, int vcpu_id, int access); 112 113bool vgic_handle_set_pending_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio, 114 phys_addr_t offset, int vcpu_id); 115 116bool vgic_handle_clear_pending_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio, 117 phys_addr_t offset, int vcpu_id); 118 119bool vgic_handle_set_active_reg(struct kvm *kvm, 120 struct kvm_exit_mmio *mmio, 121 phys_addr_t offset, int vcpu_id); 122 123bool vgic_handle_clear_active_reg(struct kvm *kvm, 124 struct kvm_exit_mmio *mmio, 125 phys_addr_t offset, int vcpu_id); 126 127bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio, 128 phys_addr_t offset); 129 130void vgic_kick_vcpus(struct kvm *kvm); 131 132int vgic_has_attr_regs(const struct vgic_io_range *ranges, phys_addr_t offset); 133int vgic_set_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr); 134int vgic_get_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr); 135 136int vgic_init(struct kvm *kvm); 137void vgic_v2_init_emulation(struct kvm *kvm); 138void vgic_v3_init_emulation(struct kvm *kvm); 139 140#endif 141