1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 6#ifndef __LS7A_KVM_IRQ_H 7#define __LS7A_KVM_IRQ_H 8 9#include <linux/mm_types.h> 10#include <linux/hrtimer.h> 11#include <linux/kvm_host.h> 12#include <linux/spinlock.h> 13#include <loongson.h> 14#include <linux/seq_file.h> 15#include "kvmcpu.h" 16 17#include <kvm/iodev.h> 18 19#define LS7A_APIC_NUM_PINS 64 20 21#define LS7A_ROUTE_ENTRY_OFFSET 0x100 22#define LS7A_INT_ID_OFFSET 0x0 23#define LS7A_INT_ID_VAL 0x7000000UL 24#define LS7A_INT_ID_VER 0x1f0001UL 25#define LS7A_INT_MASK_OFFSET 0x20 26#define LS7A_INT_EDGE_OFFSET 0x60 27#define LS7A_INT_CLEAR_OFFSET 0x80 28#define LS7A_INT_STATUS_OFFSET 0x3a0 29#define LS7A_INT_POL_OFFSET 0x3e0 30#define LS7A_HTMSI_EN_OFFSET 0x40 31#define LS7A_HTMSI_VEC_OFFSET 0x200 32#define LS7A_AUTO_CTRL0_OFFSET 0xc0 33#define LS7A_AUTO_CTRL1_OFFSET 0xe0 34 35#define LS7A_IOAPIC_GUEST_REG_BASE 0x10000000UL 36#define LS7A_IOAPIC_GUEST_REG_BASE_ALIAS 0xe0010000000UL 37 38#define LS7A_IOAPIC_NUM_PINS 32 39 40typedef struct kvm_ls7a_ioapic_state { 41 u64 int_id; 42 /* 0x020 interrupt mask register */ 43 u64 int_mask; 44 /* 0x040 1=msi */ 45 u64 htmsi_en; 46 /* 0x060 edge=1 level =0 */ 47 u64 intedge; 48 /* 0x080 for clean edge int,set 1 clean,set 0 is noused */ 49 u64 intclr; 50 /* 0x0c0 */ 51 u64 auto_crtl0; 52 /* 0x0e0 */ 53 u64 auto_crtl1; 54 /* 0x100 - 0x140 */ 55 u8 route_entry[64]; 56 /* 0x200 - 0x240 */ 57 u8 htmsi_vector[64]; 58 /* 0x300 */ 59 u64 intisr_chip0; 60 /* 0x320 */ 61 u64 intisr_chip1; 62 /* edge detection */ 63 u64 last_intirr; 64 /* 0x380 interrupt request register */ 65 u64 intirr; 66 /* 0x3a0 interrupt service register */ 67 u64 intisr; 68 /* 0x3e0 interrupt level polarity selection register, 69 * 0 for high level tirgger 70 */ 71 u64 int_polarity; 72} LS7AApicState; 73 74struct ls7a_kvm_ioapic { 75 spinlock_t lock; 76 bool wakeup_needed; 77 unsigned pending_acks; 78 struct kvm *kvm; 79 struct kvm_ls7a_ioapic_state ls7a_ioapic; 80 struct kvm_io_device dev_ls7a_ioapic; 81 struct kvm_io_device ls7a_ioapic_alias; 82 void (*ack_notifier)(void *opaque, int irq); 83 unsigned long irq_states[LS7A_APIC_NUM_PINS]; 84}; 85 86static inline struct ls7a_kvm_ioapic *ls7a_ioapic_irqchip(struct kvm *kvm) 87{ 88 return kvm->arch.v_ioapic; 89} 90 91static inline int ls7a_ioapic_in_kernel(struct kvm *kvm) 92{ 93 int ret; 94 95 ret = (ls7a_ioapic_irqchip(kvm) != NULL); 96 return ret; 97} 98 99int kvm_set_ls7a_ioapic(struct kvm *kvm, struct ls7a_ioapic_state *state); 100int kvm_get_ls7a_ioapic(struct kvm *kvm, struct ls7a_ioapic_state *state); 101int kvm_create_ls7a_ioapic(struct kvm *kvm); 102void kvm_destroy_ls7a_ioapic(struct kvm *kvm); 103int kvm_ls7a_ioapic_set_irq(struct kvm *kvm, int irq, int level); 104 105void ls7a_ioapic_lock(struct ls7a_kvm_ioapic *s, unsigned long *flags); 106void ls7a_ioapic_unlock(struct ls7a_kvm_ioapic *s, unsigned long *flags); 107int kvm_ls7a_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); 108int kvm_ls7a_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, 109 int irq_source_id, int level, bool line_status); 110 111void kvm_dump_ls7a_ioapic_state(struct seq_file *m, struct ls7a_kvm_ioapic *ioapic); 112#endif 113