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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [m68knommu/] [kernel/] [traps.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  linux/arch/m68knommu/kernel/traps.c
3
 *
4
 *  Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
5
 *                      Kenneth Albanowski <kjahds@kjahds.com>
6
 *                      The Silver Hammer Group, Ltd.
7
 *
8
 *  (Blame me for the icky bits -- kja)
9
 *
10
 *  Based on:
11
 *
12
 *  linux/arch/m68k/kernel/traps.c
13
 *
14
 *  Copyright (C) 1993, 1994 by Hamish Macdonald
15
 *
16
 *  68040 fixes by Michael Rausch
17
 *  68040 fixes by Martin Apel
18
 *  68060 fixes by Roman Hodek
19
 *  68060 fixes by Jesper Skov
20
 *
21
 * This file is subject to the terms and conditions of the GNU General Public
22
 * License.  See the file COPYING in the main directory of this archive
23
 * for more details.
24
 *
25
 *  Feb/1999 - Greg Ungerer (gerg@moreton.com.au) changes to support ColdFire.
26
 */
27
 
28
/*
29
 * Sets up all exception vectors
30
 */
31
 
32
#include <linux/config.h>
33
#include <linux/sched.h>
34
#include <linux/signal.h>
35
#include <linux/kernel.h>
36
#include <linux/mm.h>
37
#include <linux/types.h>
38
#include <linux/a.out.h>
39
#include <linux/user.h>
40
#include <linux/string.h>
41
#include <linux/linkage.h>
42
 
43
#include <asm/setup.h>
44
#include <asm/system.h>
45
#include <asm/segment.h>
46
#include <asm/traps.h>
47
#include <asm/pgtable.h>
48
#include <asm/machdep.h>
49
 
50
 
51
void trap_init (void)
52
{
53
        if (mach_trap_init)
54
                mach_trap_init();
55
}
56
 
57
static inline void console_verbose(void)
58
{
59
        extern int console_loglevel;
60
        console_loglevel = 15;
61
        if (mach_debug_init)
62
                mach_debug_init();
63
}
64
 
65
 
66
extern void die_if_kernel(char *,struct pt_regs *,int);
67
asmlinkage void trap_c(int vector, struct frame *fp);
68
 
69
asmlinkage void buserr_c(struct frame *fp)
70
{
71
#if 1
72
        extern void dump(struct pt_regs *fp);
73
        printk("%s(%d): BUSS ERROR TRAP\n", __FILE__, __LINE__);
74
        dump((struct pt_regs *) fp);
75
#endif
76
 
77
        /* Only set esp0 if coming from user mode */
78
        if (user_mode(&fp->ptregs)) {
79
                current->tss.esp0 = (unsigned long) fp;
80
        } else {
81
                die_if_kernel("Kernel mode BUS error",(struct pt_regs *)fp,0);
82
        }
83
 
84
        /* insert handler here */
85
        force_sig(SIGSEGV, current);
86
}
87
 
88
 
89
static int bad_super_trap_count = 0;
90
 
91
void bad_super_trap (int vector, struct frame *fp)
92
{
93
  if (bad_super_trap_count++) {
94
    while(1);
95
  }
96
 
97
  printk ("KERNEL: Bad trap from supervisor state, vector=%d\n", vector);
98
  dump((struct pt_regs *) fp);
99
  panic ("Trap from supervisor state");
100
}
101
 
102
asmlinkage void trap_c(int vector, struct frame *fp)
103
{
104
        int sig;
105
 
106
        if ((fp->ptregs.sr & PS_S)
107
            && ((fp->ptregs.vector) >> 2) == VEC_TRACE
108
            && !(fp->ptregs.sr & PS_T)) {
109
                /* traced a trapping instruction */
110
                unsigned char *lp = ((unsigned char *)&fp->un.fmt2) + 4;
111
                current->flags |= PF_DTRACE;
112
                /* clear the trace bit */
113
                (*(unsigned short *)lp) &= ~PS_T;
114
                return;
115
        } else if (fp->ptregs.sr & PS_S) {
116
                bad_super_trap(vector, fp);
117
                return;
118
        }
119
 
120
        /* send the appropriate signal to the user program */
121
        switch (vector) {
122
            case VEC_ADDRERR:
123
                sig = SIGBUS;
124
                break;
125
            case VEC_BUSERR:
126
                sig = SIGSEGV;
127
                break;
128
            case VEC_ILLEGAL:
129
            case VEC_PRIV:
130
            case VEC_LINE10:
131
            case VEC_LINE11:
132
            case VEC_COPROC:
133
            case VEC_TRAP2:
134
            case VEC_TRAP3:
135
            case VEC_TRAP4:
136
            case VEC_TRAP5:
137
            case VEC_TRAP6:
138
            case VEC_TRAP7:
139
            case VEC_TRAP8:
140
            case VEC_TRAP9:
141
            case VEC_TRAP10:
142
            case VEC_TRAP11:
143
            case VEC_TRAP12:
144
            case VEC_TRAP13:
145
            case VEC_TRAP14:
146
                sig = SIGILL;
147
                break;
148
#ifndef NO_FPU
149
            case VEC_FPBRUC:
150
            case VEC_FPIR:
151
            case VEC_FPDIVZ:
152
            case VEC_FPUNDER:
153
            case VEC_FPOE:
154
            case VEC_FPOVER:
155
            case VEC_FPNAN:
156
                {
157
                  unsigned char fstate[216];
158
 
159
                  __asm__ __volatile__ ("fsave %0@" : : "a" (fstate) : "memory");
160
                  /* Set the exception pending bit in the 68882 idle frame */
161
                  if (*(unsigned short *) fstate == 0x1f38)
162
                    {
163
                      fstate[fstate[1]] |= 1 << 3;
164
                      __asm__ __volatile__ ("frestore %0@" : : "a" (fstate));
165
                    }
166
                }
167
                /* fall through */
168
#endif
169
            case VEC_ZERODIV:
170
            case VEC_TRAP:
171
                sig = SIGFPE;
172
                break;
173
            case VEC_TRACE:             /* ptrace single step */
174
                fp->ptregs.sr &= ~PS_T;
175
            case VEC_TRAP15:            /* breakpoint */
176
                sig = SIGTRAP;
177
                break;
178
            case VEC_TRAP1:             /* gdbserver breakpoint */
179
                /* kwonsk: is this right? */
180
                fp->ptregs.pc -= 2;
181
                sig = SIGTRAP;
182
                break;
183
            default:
184
                sig = SIGILL;
185
                break;
186
        }
187
 
188
        send_sig (sig, current, 1);
189
}
190
 
191
asmlinkage void set_esp0 (unsigned long ssp)
192
{
193
  current->tss.esp0 = ssp;
194
}
195
 
196
void die_if_kernel (char *str, struct pt_regs *fp, int nr)
197
{
198
        if (!(fp->sr & PS_S))
199
                return;
200
 
201
        console_verbose();
202
        dump(fp);
203
 
204
        do_exit(SIGSEGV);
205
}

powered by: WebSVN 2.1.0

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