1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * irq.h: in kernel interrupt controller related definitions 4*4882a593Smuzhiyun * Copyright (c) 2007, Intel Corporation. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Authors: 7*4882a593Smuzhiyun * Yaozu (Eddie) Dong <Eddie.dong@intel.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #ifndef __IRQ_H 11*4882a593Smuzhiyun #define __IRQ_H 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #include <linux/mm_types.h> 14*4882a593Smuzhiyun #include <linux/hrtimer.h> 15*4882a593Smuzhiyun #include <linux/kvm_host.h> 16*4882a593Smuzhiyun #include <linux/spinlock.h> 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #include <kvm/iodev.h> 19*4882a593Smuzhiyun #include "lapic.h" 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #define PIC_NUM_PINS 16 22*4882a593Smuzhiyun #define SELECT_PIC(irq) \ 23*4882a593Smuzhiyun ((irq) < 8 ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE) 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun struct kvm; 26*4882a593Smuzhiyun struct kvm_vcpu; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun struct kvm_kpic_state { 29*4882a593Smuzhiyun u8 last_irr; /* edge detection */ 30*4882a593Smuzhiyun u8 irr; /* interrupt request register */ 31*4882a593Smuzhiyun u8 imr; /* interrupt mask register */ 32*4882a593Smuzhiyun u8 isr; /* interrupt service register */ 33*4882a593Smuzhiyun u8 priority_add; /* highest irq priority */ 34*4882a593Smuzhiyun u8 irq_base; 35*4882a593Smuzhiyun u8 read_reg_select; 36*4882a593Smuzhiyun u8 poll; 37*4882a593Smuzhiyun u8 special_mask; 38*4882a593Smuzhiyun u8 init_state; 39*4882a593Smuzhiyun u8 auto_eoi; 40*4882a593Smuzhiyun u8 rotate_on_auto_eoi; 41*4882a593Smuzhiyun u8 special_fully_nested_mode; 42*4882a593Smuzhiyun u8 init4; /* true if 4 byte init */ 43*4882a593Smuzhiyun u8 elcr; /* PIIX edge/trigger selection */ 44*4882a593Smuzhiyun u8 elcr_mask; 45*4882a593Smuzhiyun u8 isr_ack; /* interrupt ack detection */ 46*4882a593Smuzhiyun struct kvm_pic *pics_state; 47*4882a593Smuzhiyun }; 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun struct kvm_pic { 50*4882a593Smuzhiyun spinlock_t lock; 51*4882a593Smuzhiyun bool wakeup_needed; 52*4882a593Smuzhiyun unsigned pending_acks; 53*4882a593Smuzhiyun struct kvm *kvm; 54*4882a593Smuzhiyun struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ 55*4882a593Smuzhiyun int output; /* intr from master PIC */ 56*4882a593Smuzhiyun struct kvm_io_device dev_master; 57*4882a593Smuzhiyun struct kvm_io_device dev_slave; 58*4882a593Smuzhiyun struct kvm_io_device dev_eclr; 59*4882a593Smuzhiyun void (*ack_notifier)(void *opaque, int irq); 60*4882a593Smuzhiyun unsigned long irq_states[PIC_NUM_PINS]; 61*4882a593Smuzhiyun }; 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun int kvm_pic_init(struct kvm *kvm); 64*4882a593Smuzhiyun void kvm_pic_destroy(struct kvm *kvm); 65*4882a593Smuzhiyun int kvm_pic_read_irq(struct kvm *kvm); 66*4882a593Smuzhiyun void kvm_pic_update_irq(struct kvm_pic *s); 67*4882a593Smuzhiyun irqchip_split(struct kvm * kvm)68*4882a593Smuzhiyunstatic inline int irqchip_split(struct kvm *kvm) 69*4882a593Smuzhiyun { 70*4882a593Smuzhiyun int mode = kvm->arch.irqchip_mode; 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun /* Matches smp_wmb() when setting irqchip_mode */ 73*4882a593Smuzhiyun smp_rmb(); 74*4882a593Smuzhiyun return mode == KVM_IRQCHIP_SPLIT; 75*4882a593Smuzhiyun } 76*4882a593Smuzhiyun irqchip_kernel(struct kvm * kvm)77*4882a593Smuzhiyunstatic inline int irqchip_kernel(struct kvm *kvm) 78*4882a593Smuzhiyun { 79*4882a593Smuzhiyun int mode = kvm->arch.irqchip_mode; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun /* Matches smp_wmb() when setting irqchip_mode */ 82*4882a593Smuzhiyun smp_rmb(); 83*4882a593Smuzhiyun return mode == KVM_IRQCHIP_KERNEL; 84*4882a593Smuzhiyun } 85*4882a593Smuzhiyun pic_in_kernel(struct kvm * kvm)86*4882a593Smuzhiyunstatic inline int pic_in_kernel(struct kvm *kvm) 87*4882a593Smuzhiyun { 88*4882a593Smuzhiyun return irqchip_kernel(kvm); 89*4882a593Smuzhiyun } 90*4882a593Smuzhiyun irqchip_in_kernel(struct kvm * kvm)91*4882a593Smuzhiyunstatic inline int irqchip_in_kernel(struct kvm *kvm) 92*4882a593Smuzhiyun { 93*4882a593Smuzhiyun int mode = kvm->arch.irqchip_mode; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun /* Matches smp_wmb() when setting irqchip_mode */ 96*4882a593Smuzhiyun smp_rmb(); 97*4882a593Smuzhiyun return mode != KVM_IRQCHIP_NONE; 98*4882a593Smuzhiyun } 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); 101*4882a593Smuzhiyun void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); 102*4882a593Smuzhiyun void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu); 103*4882a593Smuzhiyun void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu); 104*4882a593Smuzhiyun void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu); 105*4882a593Smuzhiyun void __kvm_migrate_timers(struct kvm_vcpu *vcpu); 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun int apic_has_pending_timer(struct kvm_vcpu *vcpu); 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun int kvm_setup_default_irq_routing(struct kvm *kvm); 110*4882a593Smuzhiyun int kvm_setup_empty_irq_routing(struct kvm *kvm); 111*4882a593Smuzhiyun int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, 112*4882a593Smuzhiyun struct kvm_lapic_irq *irq, 113*4882a593Smuzhiyun struct dest_map *dest_map); 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun #endif 116