Annotation of prex-old/sys/arch/i386/i386/trap.c, Revision 1.1.1.1.2.1
1.1 nbrk 1: /*-
2: * Copyright (c) 2005-2007, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * trap.c - called from the trap handler when a processor trap occurs.
32: */
33:
34: #include <kernel.h>
35: #include <exception.h>
36: #include <thread.h>
37: #include <task.h>
38: #include <cpu.h>
39: #include <locore.h>
40:
41: #ifdef DEBUG
42: static void trap_dump(struct cpu_regs *);
43:
44: static char *const trap_name[] = {
45: "Divide error", /* 0 */
46: "Debug trap", /* 1 */
47: "NMI", /* 2 */
48: "Breakpoint", /* 3 */
49: "Overflow", /* 4 */
50: "Bounds check", /* 5 */
51: "Invalid opecode", /* 6 */
52: "Device not available", /* 7 */
53: "Double fault", /* 8 */
54: "Coprocessor overrun", /* 9 */
55: "Invalid TSS", /* 10 */
56: "Segment not present", /* 11 */
57: "Stack bounds", /* 12 */
58: "General Protection", /* 13 */
59: "Page fault", /* 14 */
60: "Reserved", /* 15 */
61: "Coprocessor error", /* 16 */
62: "Alignment check", /* 17 */
63: "Cache flush denied" /* 18 */
64: };
65: #define MAXTRAP (sizeof(trap_name) / sizeof(void *) - 1)
66: #endif /* DEBUG */
67:
68: /*
69: * Trap/exception mapping table.
70: * i386 trap code is translated to the architecture
71: * independent exception code.
72: */
73: static const int exception_map[] = {
74: SIGFPE, /* 0: Divide error */
75: SIGTRAP, /* 1: Debug trap */
76: SIGILL, /* 2: NMI */
77: SIGTRAP, /* 3: Breakpoint */
78: SIGFPE, /* 4: Overflow */
79: SIGILL, /* 5: Bounds check */
80: SIGILL, /* 6: Invalid opecode */
81: SIGFPE, /* 7: Device not available */
82: SIGILL, /* 8: Double fault */
83: SIGFPE, /* 9: Coprocessor overrun */
84: SIGSEGV, /* 10: Invalid TSS */
85: SIGSEGV, /* 11: Segment not present */
86: SIGSEGV, /* 12: Stack bounds */
87: SIGILL, /* 13: General Protection fault */
88: SIGSEGV, /* 14: Page fault */
89: SIGILL, /* 15: Reserved */
90: SIGFPE, /* 16: Coprocessor error */
91: SIGILL, /* 17: Alignment check */
92: SIGILL, /* 18: Cache flush denied */
93: };
94:
95: /*
96: * Trap handler
97: * Invoke the exception handler if it is needed.
98: */
99: void
100: trap_handler(struct cpu_regs *regs)
101: {
102: u_long trap_no = regs->trap_no;
1.1.1.1.2.1! nbrk 103: #ifdef DEBUG
! 104: task_t self = cur_task();
! 105: #endif
1.1 nbrk 106:
107: if (trap_no > 18)
108: panic("Unknown trap");
109: else if (trap_no == 2)
110: panic("NMI");
111:
112: /*
113: * Check whether this trap is kernel page fault caused
114: * by known routine to access user space.
115: */
116: if (trap_no == 14 && regs->cs == KERNEL_CS &&
1.1.1.1.2.1! nbrk 117: (regs->eip == (uint32_t)known_fault1 ||
! 118: regs->eip == (uint32_t)known_fault2 ||
! 119: regs->eip == (uint32_t)known_fault3)) {
! 120: DPRINTF(("\n*** Detect Fault! address=%x task=%s ***\n",
! 121: get_cr2(),
! 122: self->name != NULL ? self->name : "no name", self));
! 123: regs->eip = (uint32_t)umem_fault;
1.1 nbrk 124: return;
125: }
126: #ifdef DEBUG
1.1.1.1.2.1! nbrk 127: printf("============================\n");
! 128: printf("Trap %x: %s\n", (u_int)trap_no, trap_name[trap_no]);
1.1 nbrk 129: if (trap_no == 14)
1.1.1.1.2.1! nbrk 130: printf(" Fault address=%x\n", get_cr2());
! 131: printf("============================\n");
1.1 nbrk 132: trap_dump(regs);
133: if (regs->cs == KERNEL_CS) {
134: interrupt_mask(0);
1.1.1.1.2.1! nbrk 135: interrupt_enable();
1.1 nbrk 136: for (;;) ;
137: }
138: #endif
139: if (regs->cs == KERNEL_CS)
140: panic("Kernel exception");
141:
142: exception_mark(exception_map[trap_no]);
143: exception_deliver();
144: }
145:
146: #ifdef DEBUG
147: static void
148: trap_dump(struct cpu_regs *r)
149: {
1.1.1.1.2.1! nbrk 150: task_t self = cur_task();
! 151: uint32_t ss, esp, *fp;
1.1 nbrk 152: u_int i;
153:
154: if (r->cs & 3) {
155: ss = r->ss;
156: esp = r->esp;
157: } else {
158: ss = r->ds;
1.1.1.1.2.1! nbrk 159: esp = (uint32_t)r;
1.1 nbrk 160: }
1.1.1.1.2.1! nbrk 161: printf("Trap frame %x error %x\n", r, r->err_code);
! 162: printf(" eax %08x ebx %08x ecx %08x edx %08x esi %08x edi %08x\n",
1.1 nbrk 163: r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi);
1.1.1.1.2.1! nbrk 164: printf(" eip %08x esp %08x ebp %08x eflags %08x\n",
1.1 nbrk 165: r->eip, esp, r->ebp, r->eflags);
1.1.1.1.2.1! nbrk 166: printf(" cs %08x ss %08x ds %08x es %08x esp0 %08x\n",
1.1 nbrk 167: r->cs, ss, r->ds, r->es, tss_get());
168:
169: if (irq_level > 0)
1.1.1.1.2.1! nbrk 170: printf(" >> trap in isr (irq_level=%d)\n", irq_level);
! 171: printf(" >> interrupt is %s\n",
1.1 nbrk 172: (get_eflags() & EFL_IF) ? "enabled" : "disabled");
173:
174: if (r->cs == KERNEL_CS)
1.1.1.1.2.1! nbrk 175: printf(" >> Oops! it's kernel mode now!!!\n");
! 176: printf(" >> task=%s (id:%x)\n",
! 177: self->name != NULL ? self->name : "no name", self);
1.1 nbrk 178:
179: if (r->cs == KERNEL_CS) {
1.1.1.1.2.1! nbrk 180: printf("Stack trace:\n");
! 181: fp = (uint32_t *)r->ebp;
1.1 nbrk 182: for (i = 0; i < 8; i++) {
183: if (fp == 0)
184: break;
1.1.1.1.2.1! nbrk 185: fp = (uint32_t *)(*fp); /* XXX: may cause fault */
1.1 nbrk 186: if (!(*(fp + 1) && *fp))
187: break;
1.1.1.1.2.1! nbrk 188: printf(" %08x\n", *(fp + 1));
1.1 nbrk 189: }
190: }
191: }
192: #endif /* DEBUG */
CVSweb