Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / kernel / interrupts.c
1 #include <lwk/kernel.h>
2 #include <lwk/init.h>
3 #include <lwk/kallsyms.h>
4 #include <lwk/task.h>
5 #include <lwk/sched.h>
6 #include <lwk/timer.h>
7 #include <lwk/palacios.h>
8 #include <arch/desc.h>
9 #include <arch/idt_vectors.h>
10 #include <arch/show.h>
11 #include <arch/xcall.h>
12 #include <arch/i387.h>
13 #include <arch/io.h>
14
15 idtvec_handler_t idtvec_table[NUM_IDT_ENTRIES];
16 static DEFINE_SPINLOCK(idtvec_table_lock);
17
18 extern void asm_idtvec_table(void);
19
20 void
21 do_unhandled_idt_vector(struct pt_regs *regs, unsigned int vector)
22 {
23         if ((vector >= IRQ0_VECTOR) && (vector <= IRQ15_VECTOR)) {
24                 printk(KERN_EMERG
25                        "Unhandled Interrupt! (vector=%u, isa_irq=%u)\n",
26                        vector, vector - IRQ0_VECTOR);
27         } else {
28                 printk(KERN_EMERG
29                        "Unhandled Interrupt! (vector=%u)\n", vector);
30         }
31 }
32
33 void
34 do_divide_error(struct pt_regs *regs, unsigned int vector)
35 {
36         printk("Divide Error Exception\n");
37         show_registers(regs);
38         while (1) {}
39 }
40
41 void
42 do_nmi(struct pt_regs *regs, unsigned int vector)
43 {
44         printk("NMI Exception\n");
45         show_registers(regs);
46         while (1) {}
47 }
48
49 void
50 do_int3(struct pt_regs *regs, unsigned int vector)
51 {
52         printk("INT3 Exception\n");
53         show_registers(regs);
54         while (1) {}
55 }
56
57 void
58 do_overflow(struct pt_regs *regs, unsigned int vector)
59 {
60         printk("Overflow Exception\n");
61         show_registers(regs);
62         while (1) {}
63 }
64
65 void
66 do_bounds(struct pt_regs *regs, unsigned int vector)
67 {
68         printk("Bounds Exception\n");
69         show_registers(regs);
70         while (1) {}
71 }
72
73 void
74 do_invalid_op(struct pt_regs *regs, unsigned int vector)
75 {
76         printk("Invalid Op Exception\n");
77         show_registers(regs);
78         while (1) {}
79 }
80
81 void
82 do_device_not_available(struct pt_regs *regs, unsigned int vector)
83 {
84         BUG_ON(current->arch.flags & TF_USED_FPU);
85         current->arch.flags |= TF_USED_FPU;
86         clts();
87         fpu_restore_state(current);
88 }
89
90 void
91 do_double_fault(struct pt_regs *regs, unsigned int vector)
92 {
93         printk("Double Fault Exception\n");
94         show_registers(regs);
95         while (1) {}
96 }
97
98 void
99 do_coproc_segment_overrun(struct pt_regs *regs, unsigned int vector)
100 {
101         printk("Coprocessor Segment Exception\n");
102         show_registers(regs);
103         while (1) {}
104 }
105
106 void
107 do_invalid_tss(struct pt_regs *regs, unsigned int vector)
108 {
109         printk("Invalid TSS Exception)\n");
110         show_registers(regs);
111         while (1) {}
112 }
113
114 void
115 do_segment_not_present(struct pt_regs *regs, unsigned int vector)
116 {
117         printk("Segment Not Present Exception\n");
118         show_registers(regs);
119         while (1) {}
120 }
121
122 void
123 do_stack_segment(struct pt_regs *regs, unsigned int vector)
124 {
125         printk("Stack Segment Exception\n");
126         show_registers(regs);
127         while (1) {}
128 }
129
130 void
131 do_general_protection(struct pt_regs *regs, unsigned int vector)
132 {
133         printk("General Protection Exception\n");
134         show_registers(regs);
135         while (1) {}
136 }
137
138 void
139 do_page_fault(struct pt_regs *regs, unsigned int vector)
140 {
141         printk("Page Fault Exception (regs %p)\n", regs );
142
143         static uint8_t recursive_fault;
144         if( recursive_fault++ )
145                 panic( "Recursive page fault!  Halt and catch fire!" );
146
147         show_registers(regs);
148         while (1) {}
149 }
150
151 void
152 do_spurious_interrupt_bug(struct pt_regs *regs, unsigned int vector)
153 {
154         printk("Spurious Interrupt Exception\n");
155         show_registers(regs);
156         while (1) {}
157 }
158
159 void
160 do_coprocessor_error(struct pt_regs *regs, unsigned int vector)
161 {
162         printk("Coprocessor Error Exception\n");
163         show_registers(regs);
164         while (1) {}
165 }
166
167 void
168 do_alignment_check(struct pt_regs *regs, unsigned int vector)
169 {
170         printk("Alignment Check Exception\n");
171         show_registers(regs);
172         while (1) {}
173 }
174
175 void
176 do_machine_check(struct pt_regs *regs, unsigned int vector)
177 {
178         printk("Machine Check Exception\n");
179         show_registers(regs);
180         while (1) {}
181 }
182
183 void
184 do_simd_coprocessor_error(struct pt_regs *regs, unsigned int vector)
185 {
186         printk("SIMD Coprocessor Error Exception\n");
187         show_registers(regs);
188         while (1) {}
189 }
190
191 void
192 do_apic_timer(struct pt_regs *regs, unsigned int vector)
193 {
194         expire_timers();
195 }
196
197 void
198 do_apic_perf_counter(struct pt_regs *regs, unsigned int vector)
199 {
200         printk("APIC Perf. Counter Interrupt, vector=%u\n", vector);
201         show_registers(regs);
202         while (1) {}
203 }
204
205 void
206 do_apic_thermal(struct pt_regs *regs, unsigned int vector)
207 {
208         printk("APIC Thermal Interrupt, vector=%u\n", vector);
209         show_registers(regs);
210         while (1) {}
211 }
212
213 void
214 do_apic_error(struct pt_regs *regs, unsigned int vector)
215 {
216         printk("APIC Error Interrupt, vector=%u\n", vector);
217         show_registers(regs);
218         while (1) {}
219 }
220
221 void
222 do_apic_spurious(struct pt_regs *regs, unsigned int vector)
223 {
224         printk("APIC Spurious Interrupt, vector=%u\n", vector);
225         show_registers(regs);
226         while (1) {}
227 }
228
229 void
230 do_keyboard_interrupt(struct pt_regs *regs, unsigned int vector)
231 {
232         const uint8_t KB_OUTPUT_FULL = 0x01;
233         const uint8_t KB_STATUS_PORT = 0x64;
234         const uint8_t KB_DATA_PORT = 0x60;
235
236         uint8_t status = inb( KB_STATUS_PORT );
237
238         if( (status & KB_OUTPUT_FULL) == 0 )
239                 return;
240
241         uint8_t key = inb( KB_DATA_PORT );
242 #ifdef CONFIG_V3VEE
243         send_key_to_vmm( status, key );
244 #endif
245 }
246
247
248 void
249 set_idtvec_handler(unsigned int vector, idtvec_handler_t handler)
250 {
251         char namebuf[KSYM_NAME_LEN+1];
252         unsigned long symsize, offset;
253         unsigned long irqstate;
254
255         ASSERT(vector < NUM_IDT_ENTRIES);
256
257         if (handler != &do_unhandled_idt_vector) {
258                 printk(KERN_DEBUG "IDT Vector %3u -> %s()\n",
259                         vector, kallsyms_lookup( (unsigned long)handler,
260                                                   &symsize, &offset, namebuf )
261                 );
262         }
263
264         spin_lock_irqsave(&idtvec_table_lock, irqstate);
265         idtvec_table[vector] = handler;
266         spin_unlock_irqrestore(&idtvec_table_lock, irqstate);
267 }
268
269 void
270 do_interrupt(struct pt_regs *regs, unsigned int vector)
271 {
272         idtvec_table[vector](regs, vector);
273         if (vector >= FIRST_EXTERNAL_VECTOR)
274                 lapic_ack_interrupt();
275 }
276
277 void __init
278 interrupts_init(void)
279 {
280         int vector;
281
282         /*
283          * Initialize the Interrupt Descriptor Table (IDT).
284          */
285         for (vector = 0; vector < NUM_IDT_ENTRIES; vector++) {
286                 void *asm_handler = (void *) (
287                   (uintptr_t)(&asm_idtvec_table) + (vector * 16)
288                 );
289                 set_intr_gate(vector, asm_handler);
290                 set_idtvec_handler(vector, &do_unhandled_idt_vector);
291         }
292
293         /*
294          * Register handlers for the standard x86_64 interrupts & exceptions.
295          */
296         set_idtvec_handler( DIVIDE_ERROR_VECTOR,           &do_divide_error           );
297         set_idtvec_handler( NMI_VECTOR,                    &do_nmi                    );
298         set_idtvec_handler( INT3_VECTOR,                   &do_int3                   );
299         set_idtvec_handler( OVERFLOW_VECTOR,               &do_overflow               );
300         set_idtvec_handler( BOUNDS_VECTOR,                 &do_bounds                 );
301         set_idtvec_handler( INVALID_OP_VECTOR,             &do_invalid_op             );
302         set_idtvec_handler( DEVICE_NOT_AVAILABLE_VECTOR,   &do_device_not_available   );
303         set_idtvec_handler( DOUBLE_FAULT_VECTOR,           &do_double_fault           );
304         set_idtvec_handler( COPROC_SEGMENT_OVERRUN_VECTOR, &do_coproc_segment_overrun );
305         set_idtvec_handler( INVALID_TSS_VECTOR,            &do_invalid_tss            );
306         set_idtvec_handler( SEGMENT_NOT_PRESENT_VECTOR,    &do_segment_not_present    );
307         set_idtvec_handler( STACK_SEGMENT_VECTOR,          &do_stack_segment          );
308         set_idtvec_handler( GENERAL_PROTECTION_VECTOR,     &do_general_protection     );
309         set_idtvec_handler( PAGE_FAULT_VECTOR,             &do_page_fault             );
310         set_idtvec_handler( SPURIOUS_INTERRUPT_BUG_VECTOR, &do_spurious_interrupt_bug );
311         set_idtvec_handler( COPROCESSOR_ERROR_VECTOR,      &do_coprocessor_error      );
312         set_idtvec_handler( ALIGNMENT_CHECK_VECTOR,        &do_alignment_check        );
313         set_idtvec_handler( MACHINE_CHECK_VECTOR,          &do_machine_check          );
314         set_idtvec_handler( SIMD_COPROCESSOR_ERROR_VECTOR, &do_simd_coprocessor_error );
315         set_idtvec_handler( IRQ1_VECTOR, &do_keyboard_interrupt );
316
317         /*
318          * Register handlers for all of the local APIC vectors.
319          */
320         set_idtvec_handler( APIC_TIMER_VECTOR,        &do_apic_timer        );
321         set_idtvec_handler( APIC_PERF_COUNTER_VECTOR, &do_apic_perf_counter );
322         set_idtvec_handler( APIC_THERMAL_VECTOR,      &do_apic_thermal      );
323         set_idtvec_handler( APIC_ERROR_VECTOR,        &do_apic_error        );
324         set_idtvec_handler( APIC_SPURIOUS_VECTOR,     &do_apic_spurious     );
325
326         /*
327          * Register handlers for inter-CPU interrupts (cross calls).
328          */
329         set_idtvec_handler( XCALL_FUNCTION_VECTOR,   &arch_xcall_function_interrupt   );
330         set_idtvec_handler( XCALL_RESCHEDULE_VECTOR, &arch_xcall_reschedule_interrupt );
331 }
332
333