1*edf88417SAvi Kivity /* 2*edf88417SAvi Kivity * irq.h: in kernel interrupt controller related definitions 3*edf88417SAvi Kivity * Copyright (c) 2007, Intel Corporation. 4*edf88417SAvi Kivity * 5*edf88417SAvi Kivity * This program is free software; you can redistribute it and/or modify it 6*edf88417SAvi Kivity * under the terms and conditions of the GNU General Public License, 7*edf88417SAvi Kivity * version 2, as published by the Free Software Foundation. 8*edf88417SAvi Kivity * 9*edf88417SAvi Kivity * This program is distributed in the hope it will be useful, but WITHOUT 10*edf88417SAvi Kivity * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11*edf88417SAvi Kivity * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12*edf88417SAvi Kivity * more details. 13*edf88417SAvi Kivity * 14*edf88417SAvi Kivity * You should have received a copy of the GNU General Public License along with 15*edf88417SAvi Kivity * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16*edf88417SAvi Kivity * Place - Suite 330, Boston, MA 02111-1307 USA. 17*edf88417SAvi Kivity * Authors: 18*edf88417SAvi Kivity * Yaozu (Eddie) Dong <Eddie.dong@intel.com> 19*edf88417SAvi Kivity * 20*edf88417SAvi Kivity */ 21*edf88417SAvi Kivity 22*edf88417SAvi Kivity #ifndef __IRQ_H 23*edf88417SAvi Kivity #define __IRQ_H 24*edf88417SAvi Kivity 25*edf88417SAvi Kivity #include <linux/mm_types.h> 26*edf88417SAvi Kivity #include <linux/hrtimer.h> 27*edf88417SAvi Kivity #include <linux/kvm_host.h> 28*edf88417SAvi Kivity #include "iodev.h" 29*edf88417SAvi Kivity 30*edf88417SAvi Kivity struct kvm; 31*edf88417SAvi Kivity struct kvm_vcpu; 32*edf88417SAvi Kivity 33*edf88417SAvi Kivity typedef void irq_request_func(void *opaque, int level); 34*edf88417SAvi Kivity 35*edf88417SAvi Kivity struct kvm_kpic_state { 36*edf88417SAvi Kivity u8 last_irr; /* edge detection */ 37*edf88417SAvi Kivity u8 irr; /* interrupt request register */ 38*edf88417SAvi Kivity u8 imr; /* interrupt mask register */ 39*edf88417SAvi Kivity u8 isr; /* interrupt service register */ 40*edf88417SAvi Kivity u8 priority_add; /* highest irq priority */ 41*edf88417SAvi Kivity u8 irq_base; 42*edf88417SAvi Kivity u8 read_reg_select; 43*edf88417SAvi Kivity u8 poll; 44*edf88417SAvi Kivity u8 special_mask; 45*edf88417SAvi Kivity u8 init_state; 46*edf88417SAvi Kivity u8 auto_eoi; 47*edf88417SAvi Kivity u8 rotate_on_auto_eoi; 48*edf88417SAvi Kivity u8 special_fully_nested_mode; 49*edf88417SAvi Kivity u8 init4; /* true if 4 byte init */ 50*edf88417SAvi Kivity u8 elcr; /* PIIX edge/trigger selection */ 51*edf88417SAvi Kivity u8 elcr_mask; 52*edf88417SAvi Kivity struct kvm_pic *pics_state; 53*edf88417SAvi Kivity }; 54*edf88417SAvi Kivity 55*edf88417SAvi Kivity struct kvm_pic { 56*edf88417SAvi Kivity struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ 57*edf88417SAvi Kivity irq_request_func *irq_request; 58*edf88417SAvi Kivity void *irq_request_opaque; 59*edf88417SAvi Kivity int output; /* intr from master PIC */ 60*edf88417SAvi Kivity struct kvm_io_device dev; 61*edf88417SAvi Kivity }; 62*edf88417SAvi Kivity 63*edf88417SAvi Kivity struct kvm_pic *kvm_create_pic(struct kvm *kvm); 64*edf88417SAvi Kivity void kvm_pic_set_irq(void *opaque, int irq, int level); 65*edf88417SAvi Kivity int kvm_pic_read_irq(struct kvm_pic *s); 66*edf88417SAvi Kivity void kvm_pic_update_irq(struct kvm_pic *s); 67*edf88417SAvi Kivity 68*edf88417SAvi Kivity #define IOAPIC_NUM_PINS KVM_IOAPIC_NUM_PINS 69*edf88417SAvi Kivity #define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */ 70*edf88417SAvi Kivity #define IOAPIC_EDGE_TRIG 0 71*edf88417SAvi Kivity #define IOAPIC_LEVEL_TRIG 1 72*edf88417SAvi Kivity 73*edf88417SAvi Kivity #define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 74*edf88417SAvi Kivity #define IOAPIC_MEM_LENGTH 0x100 75*edf88417SAvi Kivity 76*edf88417SAvi Kivity /* Direct registers. */ 77*edf88417SAvi Kivity #define IOAPIC_REG_SELECT 0x00 78*edf88417SAvi Kivity #define IOAPIC_REG_WINDOW 0x10 79*edf88417SAvi Kivity #define IOAPIC_REG_EOI 0x40 /* IA64 IOSAPIC only */ 80*edf88417SAvi Kivity 81*edf88417SAvi Kivity /* Indirect registers. */ 82*edf88417SAvi Kivity #define IOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */ 83*edf88417SAvi Kivity #define IOAPIC_REG_VERSION 0x01 84*edf88417SAvi Kivity #define IOAPIC_REG_ARB_ID 0x02 /* x86 IOAPIC only */ 85*edf88417SAvi Kivity 86*edf88417SAvi Kivity /*ioapic delivery mode*/ 87*edf88417SAvi Kivity #define IOAPIC_FIXED 0x0 88*edf88417SAvi Kivity #define IOAPIC_LOWEST_PRIORITY 0x1 89*edf88417SAvi Kivity #define IOAPIC_PMI 0x2 90*edf88417SAvi Kivity #define IOAPIC_NMI 0x4 91*edf88417SAvi Kivity #define IOAPIC_INIT 0x5 92*edf88417SAvi Kivity #define IOAPIC_EXTINT 0x7 93*edf88417SAvi Kivity 94*edf88417SAvi Kivity struct kvm_ioapic { 95*edf88417SAvi Kivity u64 base_address; 96*edf88417SAvi Kivity u32 ioregsel; 97*edf88417SAvi Kivity u32 id; 98*edf88417SAvi Kivity u32 irr; 99*edf88417SAvi Kivity u32 pad; 100*edf88417SAvi Kivity union ioapic_redir_entry { 101*edf88417SAvi Kivity u64 bits; 102*edf88417SAvi Kivity struct { 103*edf88417SAvi Kivity u8 vector; 104*edf88417SAvi Kivity u8 delivery_mode:3; 105*edf88417SAvi Kivity u8 dest_mode:1; 106*edf88417SAvi Kivity u8 delivery_status:1; 107*edf88417SAvi Kivity u8 polarity:1; 108*edf88417SAvi Kivity u8 remote_irr:1; 109*edf88417SAvi Kivity u8 trig_mode:1; 110*edf88417SAvi Kivity u8 mask:1; 111*edf88417SAvi Kivity u8 reserve:7; 112*edf88417SAvi Kivity u8 reserved[4]; 113*edf88417SAvi Kivity u8 dest_id; 114*edf88417SAvi Kivity } fields; 115*edf88417SAvi Kivity } redirtbl[IOAPIC_NUM_PINS]; 116*edf88417SAvi Kivity struct kvm_io_device dev; 117*edf88417SAvi Kivity struct kvm *kvm; 118*edf88417SAvi Kivity }; 119*edf88417SAvi Kivity 120*edf88417SAvi Kivity struct kvm_lapic { 121*edf88417SAvi Kivity unsigned long base_address; 122*edf88417SAvi Kivity struct kvm_io_device dev; 123*edf88417SAvi Kivity struct { 124*edf88417SAvi Kivity atomic_t pending; 125*edf88417SAvi Kivity s64 period; /* unit: ns */ 126*edf88417SAvi Kivity u32 divide_count; 127*edf88417SAvi Kivity ktime_t last_update; 128*edf88417SAvi Kivity struct hrtimer dev; 129*edf88417SAvi Kivity } timer; 130*edf88417SAvi Kivity struct kvm_vcpu *vcpu; 131*edf88417SAvi Kivity struct page *regs_page; 132*edf88417SAvi Kivity void *regs; 133*edf88417SAvi Kivity }; 134*edf88417SAvi Kivity 135*edf88417SAvi Kivity #ifdef DEBUG 136*edf88417SAvi Kivity #define ASSERT(x) \ 137*edf88417SAvi Kivity do { \ 138*edf88417SAvi Kivity if (!(x)) { \ 139*edf88417SAvi Kivity printk(KERN_EMERG "assertion failed %s: %d: %s\n", \ 140*edf88417SAvi Kivity __FILE__, __LINE__, #x); \ 141*edf88417SAvi Kivity BUG(); \ 142*edf88417SAvi Kivity } \ 143*edf88417SAvi Kivity } while (0) 144*edf88417SAvi Kivity #else 145*edf88417SAvi Kivity #define ASSERT(x) do { } while (0) 146*edf88417SAvi Kivity #endif 147*edf88417SAvi Kivity 148*edf88417SAvi Kivity static inline struct kvm_pic *pic_irqchip(struct kvm *kvm) 149*edf88417SAvi Kivity { 150*edf88417SAvi Kivity return kvm->arch.vpic; 151*edf88417SAvi Kivity } 152*edf88417SAvi Kivity 153*edf88417SAvi Kivity static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm) 154*edf88417SAvi Kivity { 155*edf88417SAvi Kivity return kvm->arch.vioapic; 156*edf88417SAvi Kivity } 157*edf88417SAvi Kivity 158*edf88417SAvi Kivity static inline int irqchip_in_kernel(struct kvm *kvm) 159*edf88417SAvi Kivity { 160*edf88417SAvi Kivity return pic_irqchip(kvm) != NULL; 161*edf88417SAvi Kivity } 162*edf88417SAvi Kivity 163*edf88417SAvi Kivity void kvm_vcpu_kick(struct kvm_vcpu *vcpu); 164*edf88417SAvi Kivity int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu); 165*edf88417SAvi Kivity int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu); 166*edf88417SAvi Kivity int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu); 167*edf88417SAvi Kivity int kvm_create_lapic(struct kvm_vcpu *vcpu); 168*edf88417SAvi Kivity void kvm_lapic_reset(struct kvm_vcpu *vcpu); 169*edf88417SAvi Kivity void kvm_pic_reset(struct kvm_kpic_state *s); 170*edf88417SAvi Kivity void kvm_ioapic_reset(struct kvm_ioapic *ioapic); 171*edf88417SAvi Kivity void kvm_free_lapic(struct kvm_vcpu *vcpu); 172*edf88417SAvi Kivity u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu); 173*edf88417SAvi Kivity void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); 174*edf88417SAvi Kivity void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); 175*edf88417SAvi Kivity 176*edf88417SAvi Kivity struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, 177*edf88417SAvi Kivity unsigned long bitmap); 178*edf88417SAvi Kivity u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); 179*edf88417SAvi Kivity void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); 180*edf88417SAvi Kivity int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); 181*edf88417SAvi Kivity void kvm_ioapic_update_eoi(struct kvm *kvm, int vector); 182*edf88417SAvi Kivity int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); 183*edf88417SAvi Kivity int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig); 184*edf88417SAvi Kivity void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); 185*edf88417SAvi Kivity int kvm_ioapic_init(struct kvm *kvm); 186*edf88417SAvi Kivity void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); 187*edf88417SAvi Kivity int kvm_lapic_enabled(struct kvm_vcpu *vcpu); 188*edf88417SAvi Kivity int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); 189*edf88417SAvi Kivity void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec); 190*edf88417SAvi Kivity void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); 191*edf88417SAvi Kivity void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); 192*edf88417SAvi Kivity void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); 193*edf88417SAvi Kivity void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu); 194*edf88417SAvi Kivity 195*edf88417SAvi Kivity #endif 196