[BACK]Return to trap.c CVS log [TXT][DIR] Up to [local] / prex-old / sys / arch / i386 / i386

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