ia64/xen-unstable

view extras/mini-os/traps.c @ 4146:f2d61710e4d9

bitkeeper revision 1.1236.25.24 (42366e9aQ71LQ8uCB-Y1IwVNqx5eqA)

Merge djm@kirby.fc.hp.com://home/djm/src/xen/xeno-unstable-ia64.bk
into sportsman.spdomain:/home/djm/xeno-unstable-ia64.bk
author djm@sportsman.spdomain
date Tue Mar 15 05:11:54 2005 +0000 (2005-03-15)
parents 7561a06348cf
children 189c87adf876 1883ec07708b
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 coprocessor_segment_overrun(void);
19 void invalid_TSS(void);
20 void segment_not_present(void);
21 void stack_segment(void);
22 void general_protection(void);
23 void page_fault(void);
24 void coprocessor_error(void);
25 void simd_coprocessor_error(void);
26 void alignment_check(void);
27 void spurious_interrupt_bug(void);
28 void machine_check(void);
31 extern void do_exit(void);
33 void dump_regs(struct pt_regs *regs)
34 {
35 unsigned long esp;
36 unsigned short ss;
38 #ifdef __x86_64__
39 esp = regs->rsp;
40 ss = regs->ss;
41 #else
42 esp = (unsigned long) (&regs->esp);
43 ss = __KERNEL_DS;
44 if (regs->cs & 2) {
45 esp = regs->esp;
46 ss = regs->ss & 0xffff;
47 }
48 #endif
49 printf("EIP: %04x:[<%p>] %08x\n",
50 0xffff & regs->cs , regs->eip, regs->error_code);
51 printf("EFLAGS: %p\n",regs->eflags);
52 printf("eax: %p ebx: %p ecx: %p edx: %p\n",
53 regs->eax, regs->ebx, regs->ecx, regs->edx);
54 printf("esi: %p edi: %p ebp: %p esp: %p\n",
55 regs->esi, regs->edi, regs->ebp, esp);
56 #ifdef __x86_64__
57 printf("r8 : %p r9 : %p r10: %p r11: %p\n",
58 regs->r8, regs->r9, regs->r10, regs->r11);
59 printf("r12: %p r13: %p r14: %p r15: %p\n",
60 regs->r12, regs->r13, regs->r14, regs->r15);
61 #endif
62 printf("ds: %04x es: %04x ss: %04x\n",
63 regs->ds & 0xffff, regs->es & 0xffff, ss);
64 }
67 static __inline__ void dump_code(unsigned long eip)
68 {
69 unsigned char *ptr = (unsigned char *)eip;
70 int x;
72 printk("Bytes at eip: ");
73 for ( x = -4; x < 5; x++ )
74 printf("%02x ", ptr[x]);
75 printk("\n");
76 }
78 static void __inline__ do_trap(int trapnr, char *str,
79 struct pt_regs * regs)
80 {
81 printk("FATAL: Unhandled Trap %d (%s)\n", trapnr, str);
82 dump_regs(regs);
83 dump_code(regs->eip);
84 do_exit();
85 }
87 #define DO_ERROR(trapnr, str, name) \
88 void do_##name(struct pt_regs * regs) \
89 { \
90 do_trap(trapnr, str, regs); \
91 }
93 #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
94 void do_##name(struct pt_regs * regs) \
95 { \
96 do_trap(trapnr, str, regs); \
97 }
99 DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
100 DO_ERROR( 3, "int3", int3)
101 DO_ERROR( 4, "overflow", overflow)
102 DO_ERROR( 5, "bounds", bounds)
103 DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
104 DO_ERROR( 7, "device not available", device_not_available)
105 DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
106 DO_ERROR(10, "invalid TSS", invalid_TSS)
107 DO_ERROR(11, "segment not present", segment_not_present)
108 DO_ERROR(12, "stack segment", stack_segment)
109 DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
110 DO_ERROR(18, "machine check", machine_check)
112 extern unsigned long virt_cr2;
113 void do_page_fault(struct pt_regs *regs)
114 {
115 unsigned long addr = virt_cr2;
116 printk("Page fault at linear address %p\n", addr);
117 dump_regs(regs);
118 dump_code(regs->eip);
119 #ifdef __x86_64__
120 {
121 unsigned long *tab = (unsigned long *)start_info.pt_base;
122 unsigned long page;
124 printk("Pagetable walk from %p:\n", tab);
126 page = tab[l4_table_offset(addr)];
127 tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
128 printk(" L4 = %p (%p)\n", page, tab);
129 if ( !(page & _PAGE_PRESENT) )
130 goto out;
132 page = tab[l3_table_offset(addr)];
133 tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
134 printk(" L3 = %p (%p)\n", page, tab);
135 if ( !(page & _PAGE_PRESENT) )
136 goto out;
138 page = tab[l2_table_offset(addr)];
139 tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
140 printk(" L2 = %p (%p) %s\n", page, tab,
141 (page & _PAGE_PSE) ? "(2MB)" : "");
142 if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
143 goto out;
145 page = tab[l1_table_offset(addr)];
146 printk(" L1 = %p\n", page);
147 }
148 #endif
149 out:
150 do_exit();
151 }
153 void do_general_protection(struct pt_regs *regs)
154 {
155 printk("GPF\n");
156 dump_regs(regs);
157 dump_code(regs->eip);
158 do_exit();
159 }
162 void do_debug(struct pt_regs * regs)
163 {
164 printk("Debug exception\n");
165 #define TF_MASK 0x100
166 regs->eflags &= ~TF_MASK;
167 dump_regs(regs);
168 do_exit();
169 }
171 void do_coprocessor_error(struct pt_regs * regs)
172 {
173 printk("Copro error\n");
174 dump_regs(regs);
175 dump_code(regs->eip);
176 do_exit();
177 }
179 void simd_math_error(void *eip)
180 {
181 printk("SIMD error\n");
182 }
184 void do_simd_coprocessor_error(struct pt_regs * regs)
185 {
186 printk("SIMD copro error\n");
187 }
189 void do_spurious_interrupt_bug(struct pt_regs * regs)
190 {
191 }
193 /*
194 * Submit a virtual IDT to teh hypervisor. This consists of tuples
195 * (interrupt vector, privilege ring, CS:EIP of handler).
196 * The 'privilege ring' field specifies the least-privileged ring that
197 * can trap to that vector using a software-interrupt instruction (INT).
198 */
199 #ifdef __x86_64__
200 #define _P 0,
201 #endif
202 static trap_info_t trap_table[] = {
203 { 0, 0, __KERNEL_CS, _P (unsigned long)divide_error },
204 { 1, 0, __KERNEL_CS, _P (unsigned long)debug },
205 { 3, 3, __KERNEL_CS, _P (unsigned long)int3 },
206 { 4, 3, __KERNEL_CS, _P (unsigned long)overflow },
207 { 5, 3, __KERNEL_CS, _P (unsigned long)bounds },
208 { 6, 0, __KERNEL_CS, _P (unsigned long)invalid_op },
209 { 7, 0, __KERNEL_CS, _P (unsigned long)device_not_available },
210 { 9, 0, __KERNEL_CS, _P (unsigned long)coprocessor_segment_overrun },
211 { 10, 0, __KERNEL_CS, _P (unsigned long)invalid_TSS },
212 { 11, 0, __KERNEL_CS, _P (unsigned long)segment_not_present },
213 { 12, 0, __KERNEL_CS, _P (unsigned long)stack_segment },
214 { 13, 0, __KERNEL_CS, _P (unsigned long)general_protection },
215 { 14, 0, __KERNEL_CS, _P (unsigned long)page_fault },
216 { 15, 0, __KERNEL_CS, _P (unsigned long)spurious_interrupt_bug },
217 { 16, 0, __KERNEL_CS, _P (unsigned long)coprocessor_error },
218 { 17, 0, __KERNEL_CS, _P (unsigned long)alignment_check },
219 { 18, 0, __KERNEL_CS, _P (unsigned long)machine_check },
220 { 19, 0, __KERNEL_CS, _P (unsigned long)simd_coprocessor_error },
221 { 0, 0, 0, 0 }
222 };
226 void trap_init(void)
227 {
228 HYPERVISOR_set_trap_table(trap_table);
229 }