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.


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