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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [or32/] [kernel/] [traps.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/arch/or32/kernel/traps.c
3
 *
4
 *  or32 version
5
 *    author(s): Matjaz Breskvar (phoenix@opencores.org)
6
 *
7
 *  derived from cris, i386, m68k, ppc, sh ports.
8
 *
9
 *  changes:
10
 *  18. 11. 2003: Matjaz Breskvar (phoenix@opencores.org)
11
 *    initial port to or32 architecture
12
 *
13
 *  based on: linux/arch/cris/kernel/traps.c
14
 *  Copyright (C) 2000,2001 Axis Communications AB
15
 *
16
 *  Authors:   Bjorn Wesen
17
 *             Hans-Peter Nilsson
18
 *
19
 *  Here we handle the break vectors not used by the system call
20
 *  mechanism, as well as some general stack/register dumping
21
 *  things.
22
 *
23
 */
24
 
25
#include <linux/config.h>
26
#include <linux/init.h>
27
#include <linux/sched.h>
28
#include <linux/kernel.h>
29
#include <linux/string.h>
30
#include <linux/errno.h>
31
#include <linux/ptrace.h>
32
#include <linux/timer.h>
33
#include <linux/mm.h>
34
#include <asm/uaccess.h>
35
 
36
#include <asm/system.h>
37
#include <asm/segment.h>
38
#include <asm/io.h>
39
#include <asm/pgtable.h>
40
 
41
/* __PHX__ asm/hw_irq.h missing */
42
// #include <linux/irq.h>
43
#include <linux/module.h>
44
 
45
extern char _etext, _stext;
46
 
47
int kstack_depth_to_print = 0x180;
48
 
49
/*
50
 * If the address is either in the .text section of the
51
 * kernel, or in the vmalloc'ed module regions, it *may*
52
 * be the address of a calling routine
53
 */
54
 
55
#ifdef CONFIG_MODULES
56
 
57
extern struct module *module_list;
58
extern struct module kernel_module;
59
 
60
static inline int kernel_text_address(unsigned long addr)
61
{
62
        int retval = 0;
63
        struct module *mod;
64
 
65
        if (addr >= (unsigned long) &_stext &&
66
            addr <= (unsigned long) &_etext)
67
                return 1;
68
 
69
        for (mod = module_list; mod != &kernel_module; mod = mod->next) {
70
                /* mod_bound tests for addr being inside the vmalloc'ed
71
                 * module area. Of course it'd be better to test only
72
                 * for the .text subset... */
73
                if (mod_bound(addr, 0, mod)) {
74
                        retval = 1;
75
                        break;
76
                }
77
        }
78
 
79
        return retval;
80
}
81
 
82
#else
83
 
84
static inline int kernel_text_address(unsigned long addr)
85
{
86
        return (addr >= (unsigned long) &_stext &&
87
                addr <= (unsigned long) &_etext);
88
}
89
 
90
#endif
91
 
92
void show_trace(unsigned long * stack)
93
{
94
        int i;
95
        unsigned long addr;
96
 
97
        if (!stack)
98
                stack = (unsigned long*)&stack;
99
 
100
        printk("Call Trace:   ");
101
        i = 1;
102
        while (((long) stack & (THREAD_SIZE-1)) != 0) {
103
                if (__get_user (addr, stack)) {
104
                        /* This message matches "failing address" marked
105
                           s390 in ksymoops, so lines containing it will
106
                           not be filtered out by ksymoops.  */
107
                        printk ("Failing address 0x%lx\n", (unsigned long)stack);
108
 
109
                        break;
110
                }
111
                stack++;
112
 
113
                if (kernel_text_address(addr)) {
114
                        if (i && ((i % 6) == 0))
115
                                printk("\n ");
116
                        printk(" [<%08lx>]", addr);
117
                        i++;
118
                }
119
        }
120
        printk("\n");
121
}
122
 
123
/* displays a short stack trace */
124
 
125
int show_stack(unsigned long *esp)
126
{
127
        unsigned long addr, *stack;
128
        int i;
129
 
130
        // debugging aid: "show_stack(NULL);" prints the
131
        // back trace for this cpu.
132
 
133
        if(esp==NULL)
134
                esp=(unsigned long*)&esp;
135
 
136
        stack = esp;
137
 
138
        printk("Stack dump [0x%08lx]:\n", (unsigned long)esp);
139
        for(i = 0; i < kstack_depth_to_print; i++) {
140
                if (((long) stack & (THREAD_SIZE-1)) == 0)
141
                        break;
142
                if (__get_user (addr, stack)) {
143
                        /* This message matches "failing address" marked
144
                           s390 in ksymoops, so lines containing it will
145
                           not be filtered out by ksymoops.  */
146
                        printk ("Failing address 0x%lx\n", (unsigned long)stack);
147
                        break;
148
                }
149
                stack++;
150
 
151
                printk("sp + %02d: 0x%08lx\n", i*4, addr);
152
        }
153
        printk("\n");
154
 
155
        show_trace(esp);
156
 
157
        return 0;
158
}
159
 
160
void show_trace_task(struct task_struct *tsk)
161
{
162
        /*
163
         * __PHX__: TODO: SysRq-T trace dump...
164
         */
165
}
166
 
167
/*
168
 * The architecture-independent backtrace generator
169
 */
170
void dump_stack(void)
171
{
172
        show_stack(0);
173
}
174
 
175
void show_registers(struct pt_regs *regs)
176
{
177
        int i;
178
        int in_kernel = 1;
179
        unsigned long esp;
180
 
181
        esp = (unsigned long) (&regs->sp);
182
        if (user_mode(regs))
183
                in_kernel = 0;
184
 
185
        printk("CPU #: %d\n"
186
               "   PC: %08lx    SR: %08lx    SP: %08lx\n",
187
               smp_processor_id(), regs->pc, regs->sr, regs->sp);
188
        printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
189
               0L, regs->sp, regs->gprs[0], regs->gprs[1]);
190
        printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
191
               regs->gprs[2], regs->gprs[3], regs->gprs[4], regs->gprs[5]);
192
        printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n",
193
               regs->gprs[6], regs->gprs[7], regs->gprs[8], regs->gprs[9]);
194
        printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n",
195
               regs->gprs[10], regs->gprs[11], regs->gprs[12], regs->gprs[13]);
196
        printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n",
197
               regs->gprs[14], regs->gprs[15], regs->gprs[16], regs->gprs[17]);
198
        printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n",
199
               regs->gprs[18], regs->gprs[19], regs->gprs[20], regs->gprs[21]);
200
        printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n",
201
               regs->gprs[22], regs->gprs[23], regs->gprs[24], regs->gprs[25]);
202
        printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n",
203
               regs->gprs[26], regs->gprs[27], regs->gprs[28], regs->gprs[29]);
204 1574 nogj
        printk("  RES: %08lx oGPR3: %08lx syscallno: %08lx\n",
205
               regs->result, regs->orig_gpr3, regs->syscallno);
206 1275 phoenix
 
207
        printk("Process %s (pid: %d, stackpage=%08lx)\n",
208
               current->comm, current->pid, (unsigned long)current);
209
        /*
210
         * When in-kernel, we also print out the stack and code at the
211
         * time of the fault..
212
         */
213
        if (in_kernel) {
214
 
215
                printk("\nStack: ");
216
                show_stack((unsigned long*)esp);
217
 
218
                printk("\nCode: ");
219
                if(regs->pc < PAGE_OFFSET)
220
                        goto bad;
221
 
222
                for(i=-24;i<24;i++)
223
                {
224
                        unsigned char c;
225
                        if(__get_user(c, &((unsigned char*)regs->pc)[i])) {
226
bad:
227
                                printk(" Bad PC value.");
228
                                break;
229
                        }
230
 
231
                        if (i == 0)
232
                          printk("(%02x) ", c);
233
                        else
234
                          printk("%02x ", c);
235
                }
236
        }
237
        printk("\n");
238
}
239
 
240
void nommu_dump_state(struct pt_regs *regs,
241
                      unsigned long ea, unsigned long vector)
242
{
243
        int i;
244
        unsigned long addr, stack = regs->sp;
245
 
246
        printk("\n\r[nommu_dump_state] :: ea %x, vector %x\n\r",
247
               ea, vector);
248
 
249
        printk("CPU #: %d\n"
250
               "   PC: %08lx    SR: %08lx    SP: %08lx\n",
251
               0, regs->pc, regs->sr, regs->sp);
252
        printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
253
               0L, regs->sp, regs->gprs[0], regs->gprs[1]);
254
        printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
255
               regs->gprs[2], regs->gprs[3], regs->gprs[4], regs->gprs[5]);
256
        printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n",
257
               regs->gprs[6], regs->gprs[7], regs->gprs[8], regs->gprs[9]);
258
        printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n",
259
               regs->gprs[10], regs->gprs[11], regs->gprs[12], regs->gprs[13]);
260
        printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n",
261
               regs->gprs[14], regs->gprs[15], regs->gprs[16], regs->gprs[17]);
262
        printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n",
263
               regs->gprs[18], regs->gprs[19], regs->gprs[20], regs->gprs[21]);
264
        printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n",
265
               regs->gprs[22], regs->gprs[23], regs->gprs[24], regs->gprs[25]);
266
        printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n",
267
               regs->gprs[26], regs->gprs[27], regs->gprs[28], regs->gprs[29]);
268 1574 nogj
        printk("  RES: %08lx oGPR3: %08lx syscallno: %08lx\n",
269
               regs->result, regs->orig_gpr3, regs->syscallno);
270 1275 phoenix
 
271
        printk("Process %s (pid: %d, stackpage=%08lx)\n",
272
               ((struct task_struct*)(__pa(current)))->comm,
273
               ((struct task_struct*)(__pa(current)))->pid,
274
               (unsigned long)current);
275
 
276
        printk("\nStack: ");
277
        printk("Stack dump [0x%08lx]:\n", (unsigned long)stack);
278
        for(i = 0; i < kstack_depth_to_print; i++) {
279
                if (((long) stack & (THREAD_SIZE-1)) == 0)
280
                        break;
281
                stack++;
282
 
283
                printk("%x :: sp + %02d: 0x%08lx\n", stack, i*4,
284
                       *((unsigned long*)(__pa(stack))));
285
        }
286
        printk("\n");
287
 
288
        printk("Call Trace:   ");
289
        i = 1;
290
        while (((long) stack & (THREAD_SIZE-1)) != 0) {
291
                addr = *((unsigned long*)__pa(stack));
292
                stack++;
293
 
294
                if (kernel_text_address(addr)) {
295
                        if (i && ((i % 6) == 0))
296
                                printk("\n ");
297
                        printk(" [<%08lx>]", addr);
298
                        i++;
299
                }
300
        }
301
        printk("\n");
302
 
303
        printk("\nCode: ");
304
 
305
        for(i=-24;i<24;i++)
306
        {
307
                unsigned char c;
308
                c = &((unsigned char*)(__pa(regs->pc)))[i];
309
 
310
                if (i == 0)
311
                        printk("(%02x) ", c);
312
                else
313
                        printk("%02x ", c);
314
        }
315
        printk("\n");
316
}
317
 
318
 
319
/* This is normally the 'Oops' routine */
320
void die(const char * str, struct pt_regs * regs, long err)
321
{
322
 
323
        console_verbose();
324
        printk("\n%s#: %04lx\n", str, err & 0xffff);
325
        show_registers(regs);
326
#ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION
327
        printk("\n\nUNHANDLED_EXCEPTION: entering infinite loop\n");
328
 
329
        /* shut down interrupts */
330
        cli();
331
 
332
/*
333
 * this doesn't work
334
 *
335
 */
336
#if 0
337
        /* stop the simulator */
338
        __asm__ __volatile__(
339
                "l.nop   1                     ;"
340
                "l.ori   r3,r0,0x8001          ;"
341
                "l.mtspr r0,r3,64              ;" /* SPR_ESR_BASE */
342
                "l.movhi r3,hi(0xf0000100)     ;"
343
                "l.ori   r3,r3,lo(0xf0000100)  ;"
344
                "l.mtspr r0,r3,32              ;" /* SPR_EPCR_BASE */
345
                "l.nop   1                     ;"
346
                "l.nop   1                     ;"
347
                "l.nop   1                     ;"
348
                "l.nop   1                     ;"
349
                "l.rfe");
350
#endif
351
 
352
        __asm__ __volatile__(
353
                "l.nop   1");
354
        for (;;)
355
                ;
356
#endif
357
        do_exit(SIGSEGV);
358
}
359
 
360
/* This is normally the 'Oops' routine */
361
void die_if_kernel(const char * str, struct pt_regs * regs, long err)
362
{
363
        if(user_mode(regs))
364
                return;
365
 
366
        die(str, regs, err);
367
}
368
 
369
void unhandled_exception(struct pt_regs *regs, int ea, int vector)
370
{
371
        printk("Unable to handle exception at EA =0x%x, vector 0x%x",
372
                ea, vector);
373
        die("Oops", regs, 9);
374
}
375
 
376
void __init trap_init(void)
377
{
378
        /* Nothing needs to be done */
379
}

powered by: WebSVN 2.1.0

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