source: trunk/packages/xen-common/xen-common/extras/mini-os/arch/x86/traps.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 7.4 KB
Line 
1
2#include <os.h>
3#include <traps.h>
4#include <hypervisor.h>
5#include <mm.h>
6#include <lib.h>
7#include <sched.h>
8
9/*
10 * These are assembler stubs in entry.S.
11 * They are the actual entry points for virtual exceptions.
12 */
13void divide_error(void);
14void debug(void);
15void int3(void);
16void overflow(void);
17void bounds(void);
18void invalid_op(void);
19void device_not_available(void);
20void coprocessor_segment_overrun(void);
21void invalid_TSS(void);
22void segment_not_present(void);
23void stack_segment(void);
24void general_protection(void);
25void page_fault(void);
26void coprocessor_error(void);
27void simd_coprocessor_error(void);
28void alignment_check(void);
29void spurious_interrupt_bug(void);
30void machine_check(void);
31
32
33void dump_regs(struct pt_regs *regs)
34{
35    printk("Thread: %s\n", current->name);
36#ifdef __i386__   
37    printk("EIP: %x, EFLAGS %x.\n", regs->eip, regs->eflags);
38    printk("EBX: %08x ECX: %08x EDX: %08x\n",
39           regs->ebx, regs->ecx, regs->edx);
40    printk("ESI: %08x EDI: %08x EBP: %08x EAX: %08x\n",
41           regs->esi, regs->edi, regs->ebp, regs->eax);
42    printk("DS: %04x ES: %04x orig_eax: %08x, eip: %08x\n",
43           regs->xds, regs->xes, regs->orig_eax, regs->eip);
44    printk("CS: %04x EFLAGS: %08x esp: %08x ss: %04x\n",
45           regs->xcs, regs->eflags, regs->esp, regs->xss);
46#else
47    printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
48    printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", 
49           regs->ss, regs->rsp, regs->eflags);
50    printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
51           regs->rax, regs->rbx, regs->rcx);
52    printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
53           regs->rdx, regs->rsi, regs->rdi); 
54    printk("RBP: %016lx R08: %016lx R09: %016lx\n",
55           regs->rbp, regs->r8, regs->r9); 
56    printk("R10: %016lx R11: %016lx R12: %016lx\n",
57           regs->r10, regs->r11, regs->r12); 
58    printk("R13: %016lx R14: %016lx R15: %016lx\n",
59           regs->r13, regs->r14, regs->r15); 
60#endif
61}
62
63static void do_trap(int trapnr, char *str, struct pt_regs * regs, unsigned long error_code)
64{
65    printk("FATAL:  Unhandled Trap %d (%s), error code=0x%lx\n", trapnr, str, error_code);
66    printk("Regs address %p\n", regs);
67    dump_regs(regs);
68    do_exit();
69}
70
71#define DO_ERROR(trapnr, str, name) \
72void do_##name(struct pt_regs * regs, unsigned long error_code) \
73{ \
74        do_trap(trapnr, str, regs, error_code); \
75}
76
77#define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
78void do_##name(struct pt_regs * regs, unsigned long error_code) \
79{ \
80        do_trap(trapnr, str, regs, error_code); \
81}
82
83DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
84DO_ERROR( 3, "int3", int3)
85DO_ERROR( 4, "overflow", overflow)
86DO_ERROR( 5, "bounds", bounds)
87DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
88DO_ERROR( 7, "device not available", device_not_available)
89DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
90DO_ERROR(10, "invalid TSS", invalid_TSS)
91DO_ERROR(11, "segment not present", segment_not_present)
92DO_ERROR(12, "stack segment", stack_segment)
93DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
94DO_ERROR(18, "machine check", machine_check)
95
96void page_walk(unsigned long virt_address)
97{
98        pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
99        unsigned long addr = virt_address;
100        printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base);
101   
102#if defined(__x86_64__)
103        page = tab[l4_table_offset(addr)];
104        tab = pte_to_virt(page);
105        printk(" L4 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l4_table_offset(addr));
106#endif
107#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
108        page = tab[l3_table_offset(addr)];
109        tab = pte_to_virt(page);
110        printk("  L3 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l3_table_offset(addr));
111#endif
112        page = tab[l2_table_offset(addr)];
113        tab = pte_to_virt(page);
114        printk("   L2 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l2_table_offset(addr));
115       
116        page = tab[l1_table_offset(addr)];
117        printk("    L1 = %"PRIpte" (%p)  [offset = %lx]\n", page, tab, l1_table_offset(addr));
118
119}
120
121#define read_cr2() \
122        (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
123
124static int handling_pg_fault = 0;
125
126void do_page_fault(struct pt_regs *regs, unsigned long error_code)
127{
128    unsigned long addr = read_cr2();
129    /* If we are already handling a page fault, and got another one
130       that means we faulted in pagetable walk. Continuing here would cause
131       a recursive fault */       
132    if(handling_pg_fault) 
133    {
134        printk("Page fault in pagetable walk (access to invalid memory?).\n"); 
135        do_exit();
136    }
137    handling_pg_fault = 1;
138
139#if defined(__x86_64__)
140    printk("Page fault at linear address %p, rip %p, code %lx\n",
141           addr, regs->rip, error_code);
142#else
143    printk("Page fault at linear address %p, eip %p, code %lx\n",
144           addr, regs->eip, error_code);
145#endif
146
147    dump_regs(regs);
148    page_walk(addr);
149    do_exit();
150    /* We should never get here ... but still */
151    handling_pg_fault = 0;
152}
153
154void do_general_protection(struct pt_regs *regs, long error_code)
155{
156#ifdef __i386__
157    printk("GPF eip: %p, error_code=%lx\n", regs->eip, error_code);
158#else   
159    printk("GPF rip: %p, error_code=%lx\n", regs->rip, error_code);
160#endif
161    dump_regs(regs);
162    do_exit();
163}
164
165
166void do_debug(struct pt_regs * regs)
167{
168    printk("Debug exception\n");
169#define TF_MASK 0x100
170    regs->eflags &= ~TF_MASK;
171    dump_regs(regs);
172    do_exit();
173}
174
175void do_coprocessor_error(struct pt_regs * regs)
176{
177    printk("Copro error\n");
178    dump_regs(regs);
179    do_exit();
180}
181
182void simd_math_error(void *eip)
183{
184    printk("SIMD error\n");
185}
186
187void do_simd_coprocessor_error(struct pt_regs * regs)
188{
189    printk("SIMD copro error\n");
190}
191
192void do_spurious_interrupt_bug(struct pt_regs * regs)
193{
194}
195
196/*
197 * Submit a virtual IDT to teh hypervisor. This consists of tuples
198 * (interrupt vector, privilege ring, CS:EIP of handler).
199 * The 'privilege ring' field specifies the least-privileged ring that
200 * can trap to that vector using a software-interrupt instruction (INT).
201 */
202static trap_info_t trap_table[] = {
203    {  0, 0, __KERNEL_CS, (unsigned long)divide_error                },
204    {  1, 0, __KERNEL_CS, (unsigned long)debug                       },
205    {  3, 3, __KERNEL_CS, (unsigned long)int3                        },
206    {  4, 3, __KERNEL_CS, (unsigned long)overflow                    },
207    {  5, 3, __KERNEL_CS, (unsigned long)bounds                      },
208    {  6, 0, __KERNEL_CS, (unsigned long)invalid_op                  },
209    {  7, 0, __KERNEL_CS, (unsigned long)device_not_available        },
210    {  9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
211    { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS                 },
212    { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present         },
213    { 12, 0, __KERNEL_CS, (unsigned long)stack_segment               },
214    { 13, 0, __KERNEL_CS, (unsigned long)general_protection          },
215    { 14, 0, __KERNEL_CS, (unsigned long)page_fault                  },
216    { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug      },
217    { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error           },
218    { 17, 0, __KERNEL_CS, (unsigned long)alignment_check             },
219    { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error      },
220    {  0, 0,           0, 0                           }
221};
222   
223
224
225void trap_init(void)
226{
227    HYPERVISOR_set_trap_table(trap_table);   
228}
229
Note: See TracBrowser for help on using the repository browser.