ia64/xen-unstable

view extras/mini-os/traps.c @ 3017:d0006e7baa9a

bitkeeper revision 1.1159.170.41 (419b5697bEIXHXiSbTxwpjfvjHraWw)

Reassert 2.1-devel after push to 2.0 tree.
author kaf24@freefall.cl.cam.ac.uk
date Wed Nov 17 13:48:07 2004 +0000 (2004-11-17)
parents aadd0dc51c45
children 9877b62b4f26 2d4c4c4574f2
line source
2 #include <os.h>
3 #include <hypervisor.h>
4 #include <mm.h>
5 #include <lib.h>
7 /*
8 * These are assembler stubs in entry.S.
9 * They are the actual entry points for virtual exceptions.
10 */
11 void divide_error(void);
12 void debug(void);
13 void int3(void);
14 void overflow(void);
15 void bounds(void);
16 void invalid_op(void);
17 void device_not_available(void);
18 void double_fault(void);
19 void coprocessor_segment_overrun(void);
20 void invalid_TSS(void);
21 void segment_not_present(void);
22 void stack_segment(void);
23 void general_protection(void);
24 void page_fault(void);
25 void coprocessor_error(void);
26 void simd_coprocessor_error(void);
27 void alignment_check(void);
28 void spurious_interrupt_bug(void);
29 void machine_check(void);
32 extern void do_exit(void);
34 void dump_regs(struct pt_regs *regs)
35 {
36 int in_kernel = 1;
37 unsigned long esp;
38 unsigned short ss;
40 esp = (unsigned long) (&regs->esp);
41 ss = __KERNEL_DS;
42 if (regs->xcs & 2) {
43 in_kernel = 0;
44 esp = regs->esp;
45 ss = regs->xss & 0xffff;
46 }
47 printf("EIP: %04x:[<%08lx>]\n",
48 0xffff & regs->xcs, regs->eip);
49 printf("EFLAGS: %08lx\n",regs->eflags);
50 printf("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
51 regs->eax, regs->ebx, regs->ecx, regs->edx);
52 printf("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
53 regs->esi, regs->edi, regs->ebp, esp);
54 printf("ds: %04x es: %04x ss: %04x\n",
55 regs->xds & 0xffff, regs->xes & 0xffff, ss);
56 printf("\n");
57 }
60 static __inline__ void dump_code(unsigned eip)
61 {
62 unsigned *ptr = (unsigned *)eip;
63 int x;
65 printk("Bytes at eip:\n");
66 for (x = -4; x < 5; x++)
67 printf("%x", ptr[x]);
68 }
71 /*
72 * C handlers here have their parameter-list constructed by the
73 * assembler stubs above. Each one gets a pointer to a list
74 * of register values (to be restored at end of exception).
75 * Some will also receive an error code -- this is the code that
76 * was generated by the processor for the underlying real exception.
77 *
78 * Note that the page-fault exception is special. It also receives
79 * the faulting linear address. Normally this would be found in
80 * register CR2, but that is not accessible in a virtualised OS.
81 */
83 static void __inline__ do_trap(int trapnr, char *str,
84 struct pt_regs * regs, long error_code)
85 {
86 printk("FATAL: Unhandled Trap (see mini-os:traps.c)");
87 printf("%d %s", trapnr, str);
88 dump_regs(regs);
89 dump_code(regs->eip);
91 do_exit();
92 }
94 #define DO_ERROR(trapnr, str, name) \
95 void do_##name(struct pt_regs * regs, long error_code) \
96 { \
97 do_trap(trapnr, str, regs, error_code); \
98 }
100 #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
101 void do_##name(struct pt_regs * regs, long error_code) \
102 { \
103 do_trap(trapnr, str, regs, error_code); \
104 }
106 DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
107 DO_ERROR( 3, "int3", int3)
108 DO_ERROR( 4, "overflow", overflow)
109 DO_ERROR( 5, "bounds", bounds)
110 DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
111 DO_ERROR( 7, "device not available", device_not_available)
112 DO_ERROR( 8, "double fault", double_fault)
113 DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
114 DO_ERROR(10, "invalid TSS", invalid_TSS)
115 DO_ERROR(11, "segment not present", segment_not_present)
116 DO_ERROR(12, "stack segment", stack_segment)
117 DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
118 DO_ERROR(18, "machine check", machine_check)
120 void do_page_fault(struct pt_regs *regs, long error_code,
121 unsigned long address)
122 {
123 printk("Page fault\n");
124 printk("Address: 0x%lx", address);
125 printk("Error Code: 0x%lx", error_code);
126 printk("eip: \t 0x%lx", regs->eip);
127 do_exit();
128 }
130 void do_general_protection(struct pt_regs * regs, long error_code)
131 {
133 HYPERVISOR_shared_info->events_mask = 0;
134 printk("GPF\n");
135 printk("Error Code: 0x%lx", error_code);
136 dump_regs(regs);
137 dump_code(regs->eip);
138 do_exit();
139 }
142 void do_debug(struct pt_regs * regs, long error_code)
143 {
144 printk("Debug exception\n");
145 #define TF_MASK 0x100
146 regs->eflags &= ~TF_MASK;
147 dump_regs(regs);
148 do_exit();
149 }
153 void do_coprocessor_error(struct pt_regs * regs, long error_code)
154 {
155 printk("Copro error\n");
156 dump_regs(regs);
157 dump_code(regs->eip);
158 do_exit();
159 }
161 void simd_math_error(void *eip)
162 {
163 printk("SIMD error\n");
164 }
166 void do_simd_coprocessor_error(struct pt_regs * regs,
167 long error_code)
168 {
169 printk("SIMD copro error\n");
170 }
172 void do_spurious_interrupt_bug(struct pt_regs * regs,
173 long error_code)
174 {
175 }
177 /*
178 * Submit a virtual IDT to teh hypervisor. This consists of tuples
179 * (interrupt vector, privilege ring, CS:EIP of handler).
180 * The 'privilege ring' field specifies the least-privileged ring that
181 * can trap to that vector using a software-interrupt instruction (INT).
182 */
183 static trap_info_t trap_table[] = {
184 { 0, 0, __KERNEL_CS, (unsigned long)divide_error },
185 { 1, 0, __KERNEL_CS, (unsigned long)debug },
186 { 3, 3, __KERNEL_CS, (unsigned long)int3 },
187 { 4, 3, __KERNEL_CS, (unsigned long)overflow },
188 { 5, 3, __KERNEL_CS, (unsigned long)bounds },
189 { 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
190 { 7, 0, __KERNEL_CS, (unsigned long)device_not_available },
191 { 8, 0, __KERNEL_CS, (unsigned long)double_fault },
192 { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
193 { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
194 { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
195 { 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
196 { 13, 0, __KERNEL_CS, (unsigned long)general_protection },
197 { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
198 { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug },
199 { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
200 { 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
201 { 18, 0, __KERNEL_CS, (unsigned long)machine_check },
202 { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
203 { 0, 0, 0, 0 }
204 };
208 void trap_init(void)
209 {
210 HYPERVISOR_set_trap_table(trap_table);
211 }