OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i960/] [kernel/] [traps.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 *  linux/arch/i960/kernel/traps.c
 *  linux/arch/i960/kernel/traps.c
 *
 *
 *  Copyright (C) 1999          Keith Adams <kma@cse.ogi.edu>
 *  Copyright (C) 1999          Keith Adams <kma@cse.ogi.edu>
 *                              Oregon Graduate Institute
 *                              Oregon Graduate Institute
 *
 *
 *  Based on:
 *  Based on:
 *
 *
 *  linux/arch/m68k/kernel/traps.c
 *  linux/arch/m68k/kernel/traps.c
 *
 *
 *  Copyright (C) 1993, 1994 by Hamish Macdonald
 *  Copyright (C) 1993, 1994 by Hamish Macdonald
 *
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 * for more details.
 */
 */
 
 
/*
/*
 * Sets up all exception vectors
 * Sets up all exception vectors
 */
 */
 
 
#include <linux/config.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/a.out.h>
#include <linux/a.out.h>
#include <linux/user.h>
#include <linux/user.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/linkage.h>
#include <linux/linkage.h>
 
 
#include <asm/setup.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/segment.h>
#include <asm/traps.h>
#include <asm/traps.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>
#include <asm/machdep.h>
#include <asm/machdep.h>
#include <asm/i960jx.h>
#include <asm/i960jx.h>
#include <asm/mon960.h>
#include <asm/mon960.h>
 
 
/* set fault handlers in fault table, syscall table */
/* set fault handlers in fault table, syscall table */
void trap_init (void)
void trap_init (void)
{
{
        int     ii;
        int     ii;
        unsigned long** prcb = (unsigned long**) get_prcbptr();
        unsigned long** prcb = (unsigned long**) get_prcbptr();
        unsigned long* syscall_tab = prcb[5];
        unsigned long* syscall_tab = prcb[5];
        unsigned long* fault_tab = prcb[0];
        unsigned long* fault_tab = prcb[0];
        extern void fault(void);
        extern void fault(void);
 
 
        /* faults use syscall table entry 1 (0 is for syscalls) */
        /* faults use syscall table entry 1 (0 is for syscalls) */
        syscall_tab[13] = ((unsigned long) fault) | 0x2;
        syscall_tab[13] = ((unsigned long) fault) | 0x2;
        for (ii=0; ii < 20; ii += 2) {
        for (ii=0; ii < 20; ii += 2) {
               /* leave trace trap to mon960; don't mess with reserved
               /* leave trace trap to mon960; don't mess with reserved
                * fields. */
                * fields. */
                if (ii == 2 || ii == 8 || ii == 12 || ii == 16 || ii == 18)
                if (ii == 2 || ii == 8 || ii == 12 || ii == 16 || ii == 18)
                        continue;
                        continue;
 
 
                fault_tab[ii] = (1 << 2) | 2;   /* use syscall #1 */
                fault_tab[ii] = (1 << 2) | 2;   /* use syscall #1 */
                fault_tab[ii+1] = 0x27f;        /* magic number */
                fault_tab[ii+1] = 0x27f;        /* magic number */
        }
        }
}
}
 
 
void cfault(unsigned long* fault_rec, struct pt_regs* regs)
void cfault(unsigned long* fault_rec, struct pt_regs* regs)
{
{
        int     ii;
        int     ii;
        unsigned long wd = fault_rec[2];
        unsigned long wd = fault_rec[2];
        unsigned char type = (wd >> 16);
        unsigned char type = (wd >> 16);
        unsigned char subtype = (unsigned char)(wd);
        unsigned char subtype = (unsigned char)(wd);
        char* nm = "<no fault>";
        char* nm = "<no fault>";
        int sig = 0;
        int sig = 0;
 
 
        switch(type) {
        switch(type) {
                case 3:
                case 3:
                        /* arithmetic fault */
                        /* arithmetic fault */
                        nm = "arithmetic error";
                        nm = "arithmetic error";
                        sig = SIGFPE;
                        sig = SIGFPE;
                        break;
                        break;
                case 5:
                case 5:
                        /* constraint error? */
                        /* constraint error? */
                        nm = "constraint error";
                        nm = "constraint error";
                        break;
                        break;
                case 2:
                case 2:
                        switch(subtype) {
                        switch(subtype) {
                                case 1:
                                case 1:
                                        nm = "illegal instruction";
                                        nm = "illegal instruction";
                                        sig = SIGILL;
                                        sig = SIGILL;
                                        break;
                                        break;
                                case 2:
                                case 2:
                                        nm = "accessed bad address";
                                        nm = "accessed bad address";
                                        sig = SIGSEGV;
                                        sig = SIGSEGV;
                                        break;
                                        break;
                                case 3:
                                case 3:
                                        nm = "unaligned";
                                        nm = "unaligned";
                                        sig = SIGBUS;
                                        sig = SIGBUS;
                                        break;
                                        break;
                                case 4:
                                case 4:
                                        nm = "invalid operand";
                                        nm = "invalid operand";
                                        sig = SIGILL;
                                        sig = SIGILL;
                                        break;
                                        break;
                        }
                        }
                        break;
                        break;
                case 7:
                case 7:
                        nm = "protection fault";
                        nm = "protection fault";
                        sig = SIGILL;
                        sig = SIGILL;
                        break;
                        break;
                case 1:
                case 1:
                        nm = "trace fault";
                        nm = "trace fault";
                        /* bugger: we need to do better tracing */
                        /* bugger: we need to do better tracing */
                        break;
                        break;
 
 
                case 0xa:
                case 0xa:
                        nm = "type.mismatch";
                        nm = "type.mismatch";
                        sig = SIGILL;
                        sig = SIGILL;
                        break;
                        break;
        }
        }
 
 
        if (user_mode(regs)) {
        if (user_mode(regs)) {
                extern void leave_kernel(struct pt_regs* regs);
                extern void leave_kernel(struct pt_regs* regs);
                if (sig) {
                if (sig) {
                        current-> signal |= (1 << (sig -1));
                        current-> signal |= (1 << (sig -1));
                }
                }
                leave_kernel(regs);
                leave_kernel(regs);
                return;
                return;
        }
        }
 
 
        cli();
        cli();
        /* Amuse the user. */
        /* Amuse the user. */
        printk("\n"
        printk("\n"
"              \\|/ ____ \\|/\n"
"              \\|/ ____ \\|/\n"
"              \"@'/ ,. \\`@\"\n"
"              \"@'/ ,. \\`@\"\n"
"              /_| \\__/ |_\\\n"
"              /_| \\__/ |_\\\n"
"                 \\__U_/\n");
"                 \\__U_/\n");
 
 
        printk("kernel fault: %s\n", nm);
        printk("kernel fault: %s\n", nm);
        for (ii=0; ii < 4; ii++)
        for (ii=0; ii < 4; ii++)
                printk("fault_rec: 0x%8x\n", fault_rec[ii]);
                printk("fault_rec: 0x%8x\n", fault_rec[ii]);
 
 
        show_regs(regs);
        show_regs(regs);
        stack_trace();
        stack_trace();
 
 
#ifdef CONFIG_MON960
#ifdef CONFIG_MON960
        system_break();
        system_break();
#else
#else
        for (;;) ;
        for (;;) ;
#endif
#endif
}
}
 
 
void die_if_kernel(char* msg, struct pt_regs* regs, long err)
void die_if_kernel(char* msg, struct pt_regs* regs, long err)
{
{
        if (user_mode(regs))
        if (user_mode(regs))
                return;
                return;
 
 
        /* Amuse the user. */
        /* Amuse the user. */
        printk(
        printk(
"              \\|/ ____ \\|/\n"
"              \\|/ ____ \\|/\n"
"              \"@'/ ,. \\`@\"\n"
"              \"@'/ ,. \\`@\"\n"
"              /_| \\__/ |_\\\n"
"              /_| \\__/ |_\\\n"
"                 \\__U_/\n");
"                 \\__U_/\n");
 
 
        printk("%s: %04lx\n", msg, err & 0xffff);
        printk("%s: %04lx\n", msg, err & 0xffff);
        show_regs(regs);
        show_regs(regs);
        stack_trace();
        stack_trace();
 
 
        cli();
        cli();
        for (;;) ;
        for (;;) ;
}
}
 
 
/*
/*
 * Print a quick n' dirty stack trace
 * Print a quick n' dirty stack trace
 */
 */
struct frameo {
struct frameo {
        struct frameo*  pfp;
        struct frameo*  pfp;
        unsigned long   sp;
        unsigned long   sp;
        void*           rip;
        void*           rip;
};
};
 
 
void stack_trace(void)
void stack_trace(void)
{
{
        unsigned long fp;
        unsigned long fp;
 
 
        __asm__ __volatile__ ("flushreg; mov    pfp, %0" : "=r"(fp));
        __asm__ __volatile__ ("flushreg; mov    pfp, %0" : "=r"(fp));
        stack_trace_from(fp);
        stack_trace_from(fp);
}
}
 
 
void stack_trace_from(unsigned long ulfp)
void stack_trace_from(unsigned long ulfp)
{
{
        int     ii;
        int     ii;
        long    flags;
        long    flags;
        struct frameo* fp = (struct frameo*) ulfp;
        struct frameo* fp = (struct frameo*) ulfp;
 
 
        save_flags(flags);
        save_flags(flags);
        cli();
        cli();
        printk("trace: fp == %p\n", fp);
        printk("trace: fp == %p\n", fp);
        for (ii=1; fp && (ii <  50); ii++, fp=fp->pfp) {
        for (ii=1; fp && (ii <  50); ii++, fp=fp->pfp) {
                unsigned long type = ((unsigned long)fp) & 0xf;
                unsigned long type = ((unsigned long)fp) & 0xf;
                fp = ((unsigned long)fp) & ~0xf;
                fp = ((unsigned long)fp) & ~0xf;
 
 
                switch(type) {
                switch(type) {
                        case    1:
                        case    1:
                                printk("<f>");
                                printk("<f>");
                                break;
                                break;
 
 
                        case 2:
                        case 2:
                        case 3:
                        case 3:
                                printk("<s>");
                                printk("<s>");
                                break;
                                break;
                        case 7:
                        case 7:
                                printk("<i>");
                                printk("<i>");
                }
                }
                printk("\t%8x", fp->rip);
                printk("\t%8x", fp->rip);
                if (! (ii & 0x3))
                if (! (ii & 0x3))
                        printk("\n");
                        printk("\n");
        }
        }
 
 
        if (!fp) {
        if (!fp) {
                printk("<bottom of stack>\n");
                printk("<bottom of stack>\n");
        }
        }
 
 
        printk("\n");
        printk("\n");
        restore_flags(flags);
        restore_flags(flags);
}
}
 
 
void ckpt(int num, unsigned long val)
void ckpt(int num, unsigned long val)
{
{
 
 
        printk("--------reached ckpt: %d\tval:0x%8x\n", num, val);
        printk("--------reached ckpt: %d\tval:0x%8x\n", num, val);
#if 0
#if 0
        struct pt_regs* regs;
        struct pt_regs* regs;
        asm("flushreg; subo 16, fp, %0" : "=r"(regs));
        asm("flushreg; subo 16, fp, %0" : "=r"(regs));
 
 
        show_regs(regs);
        show_regs(regs);
#endif
#endif
        printk("current stack trace:\n");
        printk("current stack trace:\n");
        stack_trace();
        stack_trace();
        printk("new stack strace:\n");
        printk("new stack strace:\n");
        stack_trace_from(val);
        stack_trace_from(val);
        printk("offset of ksp: 0x%8x\n",
        printk("offset of ksp: 0x%8x\n",
               &(((struct task_struct*)0)->kernel_stack_page));
               &(((struct task_struct*)0)->kernel_stack_page));
        printk("current ksp: 0x%8x\n", current->kernel_stack_page);
        printk("current ksp: 0x%8x\n", current->kernel_stack_page);
}
}
 
 
void system_break(void)
void system_break(void)
{
{
        long    flags;
        long    flags;
 
 
        save_flags(flags);
        save_flags(flags);
        cli();
        cli();
        mon_entry();
        mon_entry();
        restore_flags(flags);
        restore_flags(flags);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.