From e4130630e189f44c1371dc8c78b66b8bcf6df732 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Mon, 6 Oct 2003 17:18:26 +0000 Subject: bitkeeper revision 1.483 (3f81a3e2iM-0WXaGxUS3ywM3_KZqLw) move mini-os to extras directory --- extras/mini-os/traps.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 extras/mini-os/traps.c (limited to 'extras/mini-os/traps.c') diff --git a/extras/mini-os/traps.c b/extras/mini-os/traps.c new file mode 100644 index 0000000000..6352559c0f --- /dev/null +++ b/extras/mini-os/traps.c @@ -0,0 +1,231 @@ + +#include +#include +#include + +/* + * These are assembler stubs in entry.S. + * They are the actual entry points for virtual exceptions. + */ +void divide_error(void); +void debug(void); +void int3(void); +void overflow(void); +void bounds(void); +void invalid_op(void); +void device_not_available(void); +void double_fault(void); +void coprocessor_segment_overrun(void); +void invalid_TSS(void); +void segment_not_present(void); +void stack_segment(void); +void general_protection(void); +void page_fault(void); +void coprocessor_error(void); +void simd_coprocessor_error(void); +void alignment_check(void); +void spurious_interrupt_bug(void); +void machine_check(void); + + +extern void do_exit(void); + +int kstack_depth_to_print = 24; + +static inline int kernel_text_address(unsigned long addr) +{ + return ( (addr >> 20) > 0x800 && (addr >> 20) < 0x804 ); +} + +void show_trace(unsigned long * stack) +{ + int i; + unsigned long addr; + + if (!stack) + stack = (unsigned long*)&stack; + + printk("Call Trace: "); + i = 1; + while (((long) stack & (4095)) != 0) { + addr = *stack++; + if (kernel_text_address(addr)) { + printf("0x%lx", addr); + i++; + } + } + printk("\n"); +} + +void dump_regs(struct pt_regs *regs) { + printk("Register dump:"); + printk("ebx: \t 0x%lx", regs->ebx); + printk("ecx: \t 0x%lx", regs->ecx); + printk("edx: \t 0x%lx", regs->edx); + printk("esi: \t 0x%lx", regs->esi); + printk("edi: \t 0x%lx", regs->edi); + printk("ebp: \t 0x%lx", regs->ebp); + printk("eax: \t 0x%lx", regs->eax); + printk("xds: \t 0x%x", regs->xds); + printk("xes: \t 0x%x", regs->xes); + printk("orig_eax: \t 0x%lx", regs->orig_eax); + printk("eip: \t 0x%lx", regs->eip); + printk("xcs: \t 0x%x", regs->xcs); + printk("eflags: \t 0x%lx", regs->eflags); + printk("esp: \t 0x%lx", regs->esp); + printk("xss: \t 0x%x", regs->xss); +}; + +static inline void dump_code(unsigned eip) +{ + unsigned *ptr = (unsigned *)eip; + int x; + + printk("Bytes at eip:\n"); + for (x = -4; x < 5; x++) + printf("%x", ptr[x]); +} + + +/* + * C handlers here have their parameter-list constructed by the + * assembler stubs above. Each one gets a pointer to a list + * of register values (to be restored at end of exception). + * Some will also receive an error code -- this is the code that + * was generated by the processor for the underlying real exception. + * + * Note that the page-fault exception is special. It also receives + * the faulting linear address. Normally this would be found in + * register CR2, but that is not accessible in a virtualised OS. + */ + +static void inline do_trap(int trapnr, char *str, + struct pt_regs * regs, long error_code) +{ + printk("FATAL: Unhandled Trap (see mini-os:traps.c)"); + printf("%d %s", trapnr, str); + dump_regs(regs); + show_trace((void *)regs->esp); + dump_code(regs->eip); + + do_exit(); +} + +#define DO_ERROR(trapnr, str, name) \ +void do_##name(struct pt_regs * regs, long error_code) \ +{ \ + do_trap(trapnr, str, regs, error_code); \ +} + +#define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \ +void do_##name(struct pt_regs * regs, long error_code) \ +{ \ + do_trap(trapnr, str, regs, error_code); \ +} + +DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip) +DO_ERROR( 3, "int3", int3) +DO_ERROR( 4, "overflow", overflow) +DO_ERROR( 5, "bounds", bounds) +DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip) +DO_ERROR( 7, "device not available", device_not_available) +DO_ERROR( 8, "double fault", double_fault) +DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR(10, "invalid TSS", invalid_TSS) +DO_ERROR(11, "segment not present", segment_not_present) +DO_ERROR(12, "stack segment", stack_segment) +DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0) +DO_ERROR(18, "machine check", machine_check) + +void do_page_fault(struct pt_regs * regs, long error_code, + unsigned long address) +{ + printk("Page fault\n"); + printk("Address: 0x%lx", address); + printk("Error Code: 0x%lx", error_code); + printk("eip: \t 0x%lx", regs->eip); + do_exit(); +} + +void do_general_protection(struct pt_regs * regs, long error_code) +{ + + HYPERVISOR_shared_info->events_mask = 0; + printk("GPF\n"); + printk("Error Code: 0x%lx", error_code); + dump_regs(regs); + dump_code(regs->eip); + do_exit(); +} + + +void do_debug(struct pt_regs * regs, long error_code) +{ + printk("Debug exception\n"); +#define TF_MASK 0x100 + regs->eflags &= ~TF_MASK; + dump_regs(regs); + do_exit(); +} + + + +void do_coprocessor_error(struct pt_regs * regs, long error_code) +{ + printk("Copro error\n"); + dump_regs(regs); + dump_code(regs->eip); + do_exit(); +} + +void simd_math_error(void *eip) +{ + printk("SIMD error\n"); +} + +void do_simd_coprocessor_error(struct pt_regs * regs, + long error_code) +{ + printk("SIMD copro error\n"); +} + +void do_spurious_interrupt_bug(struct pt_regs * regs, + long error_code) +{ +} + +/* + * Submit a virtual IDT to teh hypervisor. This consists of tuples + * (interrupt vector, privilege ring, CS:EIP of handler). + * The 'privilege ring' field specifies the least-privileged ring that + * can trap to that vector using a software-interrupt instruction (INT). + */ +static trap_info_t trap_table[] = { + { 0, 0, __KERNEL_CS, (unsigned long)divide_error }, + { 1, 0, __KERNEL_CS, (unsigned long)debug }, + { 3, 3, __KERNEL_CS, (unsigned long)int3 }, + { 4, 3, __KERNEL_CS, (unsigned long)overflow }, + { 5, 3, __KERNEL_CS, (unsigned long)bounds }, + { 6, 0, __KERNEL_CS, (unsigned long)invalid_op }, + { 7, 0, __KERNEL_CS, (unsigned long)device_not_available }, + { 8, 0, __KERNEL_CS, (unsigned long)double_fault }, + { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun }, + { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS }, + { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present }, + { 12, 0, __KERNEL_CS, (unsigned long)stack_segment }, + { 13, 0, __KERNEL_CS, (unsigned long)general_protection }, + { 14, 0, __KERNEL_CS, (unsigned long)page_fault }, + { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug }, + { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error }, + { 17, 0, __KERNEL_CS, (unsigned long)alignment_check }, + { 18, 0, __KERNEL_CS, (unsigned long)machine_check }, + { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error }, + { 0, 0, 0, 0 } +}; + + + +void trap_init(void) +{ + HYPERVISOR_set_trap_table(trap_table); +} -- cgit v1.2.3