2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2014
7 * Jan Kiszka <jan.kiszka@siemens.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
15 #define NUM_IDT_DESC 64
17 #define X2APIC_EOI 0x80b
18 #define X2APIC_SPIV 0x80f
20 #define APIC_EOI_ACK 0
22 struct desc_table_reg {
25 } __attribute__((packed));
27 static u32 idt[NUM_IDT_DESC * 4];
28 static int_handler_t int_handler[NUM_IDT_DESC];
30 extern u8 irq_entry[];
32 static inline void write_idtr(struct desc_table_reg *val)
34 asm volatile("lidt %0" : : "m" (*val));
39 struct desc_table_reg dtr;
41 write_msr(X2APIC_SPIV, 0x1ff);
43 dtr.limit = NUM_IDT_DESC * 16 - 1;
48 static void __attribute__((used)) handle_interrupt(unsigned int vector)
50 int_handler[vector]();
51 write_msr(X2APIC_EOI, APIC_EOI_ACK);
54 void int_set_handler(unsigned int vector, int_handler_t handler)
56 unsigned long entry = (unsigned long)irq_entry + vector * 16;
58 int_handler[vector] = handler;
60 idt[vector * 4] = (entry & 0xffff) | (INMATE_CS64 << 16);
61 idt[vector * 4 + 1] = 0x8e00 | (entry & 0xffff0000);
62 idt[vector * 4 + 2] = entry >> 32;
67 ".macro irq_prologue vector\n\t"
69 "mov $vector,%rdi\n\t"
73 ".global irq_entry\n\t"
78 "irq_prologue vector\n\t"
93 "call handle_interrupt\n\t"