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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i960/] [kernel/] [traps.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*
2
 *  linux/arch/i960/kernel/traps.c
3
 *
4
 *  Copyright (C) 1999          Keith Adams <kma@cse.ogi.edu>
5
 *                              Oregon Graduate Institute
6
 *
7
 *  Based on:
8
 *
9
 *  linux/arch/m68k/kernel/traps.c
10
 *
11
 *  Copyright (C) 1993, 1994 by Hamish Macdonald
12
 *
13
 * This file is subject to the terms and conditions of the GNU General Public
14
 * License.  See the file COPYING in the main directory of this archive
15
 * for more details.
16
 */
17
 
18
/*
19
 * Sets up all exception vectors
20
 */
21
 
22
#include <linux/config.h>
23
#include <linux/sched.h>
24
#include <linux/signal.h>
25
#include <linux/kernel.h>
26
#include <linux/mm.h>
27
#include <linux/types.h>
28
#include <linux/a.out.h>
29
#include <linux/user.h>
30
#include <linux/string.h>
31
#include <linux/linkage.h>
32
 
33
#include <asm/setup.h>
34
#include <asm/system.h>
35
#include <asm/segment.h>
36
#include <asm/traps.h>
37
#include <asm/pgtable.h>
38
#include <asm/machdep.h>
39
#include <asm/i960jx.h>
40
#include <asm/mon960.h>
41
 
42
/* set fault handlers in fault table, syscall table */
43
void trap_init (void)
44
{
45
        int     ii;
46
        unsigned long** prcb = (unsigned long**) get_prcbptr();
47
        unsigned long* syscall_tab = prcb[5];
48
        unsigned long* fault_tab = prcb[0];
49
        extern void fault(void);
50
 
51
        /* faults use syscall table entry 1 (0 is for syscalls) */
52
        syscall_tab[13] = ((unsigned long) fault) | 0x2;
53
        for (ii=0; ii < 20; ii += 2) {
54
               /* leave trace trap to mon960; don't mess with reserved
55
                * fields. */
56
                if (ii == 2 || ii == 8 || ii == 12 || ii == 16 || ii == 18)
57
                        continue;
58
 
59
                fault_tab[ii] = (1 << 2) | 2;   /* use syscall #1 */
60
                fault_tab[ii+1] = 0x27f;        /* magic number */
61
        }
62
}
63
 
64
void cfault(unsigned long* fault_rec, struct pt_regs* regs)
65
{
66
        int     ii;
67
        unsigned long wd = fault_rec[2];
68
        unsigned char type = (wd >> 16);
69
        unsigned char subtype = (unsigned char)(wd);
70
        char* nm = "<no fault>";
71
        int sig = 0;
72
 
73
        switch(type) {
74
                case 3:
75
                        /* arithmetic fault */
76
                        nm = "arithmetic error";
77
                        sig = SIGFPE;
78
                        break;
79
                case 5:
80
                        /* constraint error? */
81
                        nm = "constraint error";
82
                        break;
83
                case 2:
84
                        switch(subtype) {
85
                                case 1:
86
                                        nm = "illegal instruction";
87
                                        sig = SIGILL;
88
                                        break;
89
                                case 2:
90
                                        nm = "accessed bad address";
91
                                        sig = SIGSEGV;
92
                                        break;
93
                                case 3:
94
                                        nm = "unaligned";
95
                                        sig = SIGBUS;
96
                                        break;
97
                                case 4:
98
                                        nm = "invalid operand";
99
                                        sig = SIGILL;
100
                                        break;
101
                        }
102
                        break;
103
                case 7:
104
                        nm = "protection fault";
105
                        sig = SIGILL;
106
                        break;
107
                case 1:
108
                        nm = "trace fault";
109
                        /* bugger: we need to do better tracing */
110
                        break;
111
 
112
                case 0xa:
113
                        nm = "type.mismatch";
114
                        sig = SIGILL;
115
                        break;
116
        }
117
 
118
        if (user_mode(regs)) {
119
                extern void leave_kernel(struct pt_regs* regs);
120
                if (sig) {
121
                        current-> signal |= (1 << (sig -1));
122
                }
123
                leave_kernel(regs);
124
                return;
125
        }
126
 
127
        cli();
128
        /* Amuse the user. */
129
        printk("\n"
130
"              \\|/ ____ \\|/\n"
131
"              \"@'/ ,. \\`@\"\n"
132
"              /_| \\__/ |_\\\n"
133
"                 \\__U_/\n");
134
 
135
        printk("kernel fault: %s\n", nm);
136
        for (ii=0; ii < 4; ii++)
137
                printk("fault_rec: 0x%8x\n", fault_rec[ii]);
138
 
139
        show_regs(regs);
140
        stack_trace();
141
 
142
#ifdef CONFIG_MON960
143
        system_break();
144
#else
145
        for (;;) ;
146
#endif
147
}
148
 
149
void die_if_kernel(char* msg, struct pt_regs* regs, long err)
150
{
151
        if (user_mode(regs))
152
                return;
153
 
154
        /* Amuse the user. */
155
        printk(
156
"              \\|/ ____ \\|/\n"
157
"              \"@'/ ,. \\`@\"\n"
158
"              /_| \\__/ |_\\\n"
159
"                 \\__U_/\n");
160
 
161
        printk("%s: %04lx\n", msg, err & 0xffff);
162
        show_regs(regs);
163
        stack_trace();
164
 
165
        cli();
166
        for (;;) ;
167
}
168
 
169
/*
170
 * Print a quick n' dirty stack trace
171
 */
172
struct frameo {
173
        struct frameo*  pfp;
174
        unsigned long   sp;
175
        void*           rip;
176
};
177
 
178
void stack_trace(void)
179
{
180
        unsigned long fp;
181
 
182
        __asm__ __volatile__ ("flushreg; mov    pfp, %0" : "=r"(fp));
183
        stack_trace_from(fp);
184
}
185
 
186
void stack_trace_from(unsigned long ulfp)
187
{
188
        int     ii;
189
        long    flags;
190
        struct frameo* fp = (struct frameo*) ulfp;
191
 
192
        save_flags(flags);
193
        cli();
194
        printk("trace: fp == %p\n", fp);
195
        for (ii=1; fp && (ii <  50); ii++, fp=fp->pfp) {
196
                unsigned long type = ((unsigned long)fp) & 0xf;
197
                fp = ((unsigned long)fp) & ~0xf;
198
 
199
                switch(type) {
200
                        case    1:
201
                                printk("<f>");
202
                                break;
203
 
204
                        case 2:
205
                        case 3:
206
                                printk("<s>");
207
                                break;
208
                        case 7:
209
                                printk("<i>");
210
                }
211
                printk("\t%8x", fp->rip);
212
                if (! (ii & 0x3))
213
                        printk("\n");
214
        }
215
 
216
        if (!fp) {
217
                printk("<bottom of stack>\n");
218
        }
219
 
220
        printk("\n");
221
        restore_flags(flags);
222
}
223
 
224
void ckpt(int num, unsigned long val)
225
{
226
 
227
        printk("--------reached ckpt: %d\tval:0x%8x\n", num, val);
228
#if 0
229
        struct pt_regs* regs;
230
        asm("flushreg; subo 16, fp, %0" : "=r"(regs));
231
 
232
        show_regs(regs);
233
#endif
234
        printk("current stack trace:\n");
235
        stack_trace();
236
        printk("new stack strace:\n");
237
        stack_trace_from(val);
238
        printk("offset of ksp: 0x%8x\n",
239
               &(((struct task_struct*)0)->kernel_stack_page));
240
        printk("current ksp: 0x%8x\n", current->kernel_stack_page);
241
}
242
 
243
void system_break(void)
244
{
245
        long    flags;
246
 
247
        save_flags(flags);
248
        cli();
249
        mon_entry();
250
        restore_flags(flags);
251
}

powered by: WebSVN 2.1.0

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