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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [sparc/] [kernel/] [traps.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/* $Id: traps.c,v 1.1 2005-12-20 09:50:43 jcastillo Exp $
2
 * arch/sparc/kernel/traps.c
3
 *
4
 * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
5
 */
6
 
7
/*
8
 * I hate traps on the sparc, grrr...
9
 */
10
 
11
#include <linux/sched.h>  /* for jiffies */
12
#include <linux/kernel.h>
13
#include <linux/config.h>
14
#include <linux/signal.h>
15
 
16
#include <asm/delay.h>
17
#include <asm/system.h>
18
#include <asm/ptrace.h>
19
#include <asm/oplib.h>
20
#include <asm/page.h>
21
#include <asm/pgtable.h>
22
#include <asm/kdebug.h>
23
#include <asm/unistd.h>
24
#include <asm/traps.h>
25
#include <asm/smp.h>
26
 
27
/* #define TRAP_DEBUG */
28
 
29
struct trap_trace_entry {
30
        unsigned long pc;
31
        unsigned long type;
32
};
33
 
34
int trap_curbuf = 0;
35
struct trap_trace_entry trapbuf[1024];
36
 
37
void syscall_trace_entry(struct pt_regs *regs)
38
{
39
        printk("%s[%d]: ", current->comm, current->pid);
40
        printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1],
41
               (int) regs->u_regs[UREG_I0]);
42
}
43
 
44
void syscall_trace_exit(struct pt_regs *regs)
45
{
46
}
47
 
48
void sun4m_nmi(struct pt_regs *regs)
49
{
50
        unsigned long afsr, afar;
51
 
52
        printk("Aieee: sun4m NMI received!\n");
53
        /* XXX HyperSparc hack XXX */
54
        __asm__ __volatile__("mov 0x500, %%g1\n\t"
55
                             "lda [%%g1] 0x4, %0\n\t"
56
                             "mov 0x600, %%g1\n\t"
57
                             "lda [%%g1] 0x4, %1\n\t" :
58
                             "=r" (afsr), "=r" (afar));
59
        printk("afsr=%08lx afar=%08lx\n", afsr, afar);
60
        printk("you lose buddy boy...\n");
61
        show_regs(regs);
62
        prom_halt();
63
}
64
 
65
void die_if_kernel(char *str, struct pt_regs *regs)
66
{
67
        unsigned long i;
68
        unsigned long *pc;
69
 
70
        /* Amuse the user. */
71
        printk(
72
"              \\|/ ____ \\|/\n"
73
"              \"@'/ ,. \\`@\"\n"
74
"              /_| \\__/ |_\\\n"
75
"                 \\__U_/\n");
76
 
77
        printk("%s(%d): %s\n", current->comm, current->pid, str);
78
        show_regs(regs);
79
#if CONFIG_AP1000
80
        ap_panic();
81
#endif
82
        printk("Instruction DUMP:");
83
        pc = (unsigned long *) regs->pc;
84
        for(i = -3; i < 6; i++)
85
                printk("%c%08lx%c",i?' ':'<',pc[i],i?' ':'>');
86
        printk("\n");
87
        if(regs->psr & PSR_PS)
88
                do_exit(SIGKILL);
89
        do_exit(SIGSEGV);
90
}
91
 
92
void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
93
{
94
        if(type < 0x80) {
95
                /* Sun OS's puke from bad traps, Linux survives! */
96
                printk("Unimplemented Sparc TRAP, type = %02lx\n", type);
97
                die_if_kernel("Whee... Hello Mr. Penguin", current->tss.kregs);
98
        }
99
        if(type == SP_TRAP_SBPT) {
100
                send_sig(SIGTRAP, current, 1);
101
                return;
102
        }
103
        current->tss.sig_desc = SUBSIG_BADTRAP(type - 0x80);
104
        current->tss.sig_address = pc;
105
        send_sig(SIGILL, current, 1);
106
}
107
 
108
void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
109
                            unsigned long psr)
110
{
111
        if(psr & PSR_PS)
112
                die_if_kernel("Kernel illegal instruction", regs);
113
#ifdef TRAP_DEBUG
114
        printk("Ill instr. at pc=%08lx instruction is %08lx\n",
115
               regs->pc, *(unsigned long *)regs->pc);
116
#endif
117
        current->tss.sig_address = pc;
118
        current->tss.sig_desc = SUBSIG_ILLINST;
119
        send_sig(SIGILL, current, 1);
120
}
121
 
122
void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
123
                         unsigned long psr)
124
{
125
        if(psr & PSR_PS)
126
                die_if_kernel("Penguin instruction from Penguin mode??!?!", regs);
127
        current->tss.sig_address = pc;
128
        current->tss.sig_desc = SUBSIG_PRIVINST;
129
        send_sig(SIGILL, current, 1);
130
}
131
 
132
/* XXX User may want to be allowed to do this. XXX */
133
 
134
void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned long npc,
135
                            unsigned long psr)
136
{
137
        if(regs->psr & PSR_PS) {
138
                printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc,
139
                       regs->u_regs[UREG_RETPC]);
140
                die_if_kernel("BOGUS", regs);
141
                /* die_if_kernel("Kernel MNA access", regs); */
142
        }
143
        current->tss.sig_address = pc;
144
        current->tss.sig_desc = SUBSIG_PRIVINST;
145
        send_sig(SIGBUS, current, 1);
146
}
147
 
148
extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
149
                   void *fpqueue, unsigned long *fpqdepth);
150
extern void fpload(unsigned long *fpregs, unsigned long *fsr);
151
 
152
static unsigned long init_fsr = 0x0UL;
153
static unsigned long init_fregs[32] __attribute__ ((aligned (8))) =
154
                { ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL,
155
                  ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL,
156
                  ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL,
157
                  ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL, ~0UL };
158
 
159
void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
160
                 unsigned long psr)
161
{
162
        /* Sanity check... */
163
        if(psr & PSR_PS)
164
                die_if_kernel("Kernel gets FloatingPenguinUnit disabled trap", regs);
165
 
166
        put_psr(get_psr() | PSR_EF);    /* Allow FPU ops. */
167
        regs->psr |= PSR_EF;
168
#ifndef __SMP__
169
        if(last_task_used_math == current)
170
                return;
171
        if(last_task_used_math) {
172
                /* Other processes fpu state, save away */
173
                struct task_struct *fptask = last_task_used_math;
174
                fpsave(&fptask->tss.float_regs[0], &fptask->tss.fsr,
175
                       &fptask->tss.fpqueue[0], &fptask->tss.fpqdepth);
176
        }
177
        last_task_used_math = current;
178
        if(current->used_math) {
179
                fpload(&current->tss.float_regs[0], &current->tss.fsr);
180
        } else {
181
                /* Set initial sane state. */
182
                fpload(&init_fregs[0], &init_fsr);
183
                current->used_math = 1;
184
        }
185
#else
186
        if(!current->used_math) {
187
                fpload(&init_fregs[0], &init_fsr);
188
                current->used_math = 1;
189
        } else {
190
                fpload(&current->tss.float_regs[0], &current->tss.fsr);
191
        }
192
        current->flags |= PF_USEDFPU;
193
#endif
194
}
195
 
196
static unsigned long fake_regs[32] __attribute__ ((aligned (8)));
197
static unsigned long fake_fsr;
198
static unsigned long fake_queue[32] __attribute__ ((aligned (8)));
199
static unsigned long fake_depth;
200
 
201
void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
202
                 unsigned long psr)
203
{
204
        static calls = 0;
205
#ifndef __SMP__
206
        struct task_struct *fpt = last_task_used_math;
207
#else
208
        struct task_struct *fpt = current;
209
#endif
210
 
211
        put_psr(get_psr() | PSR_EF);
212
        /* If nobody owns the fpu right now, just clear the
213
         * error into our fake static buffer and hope it don't
214
         * happen again.  Thank you crashme...
215
         */
216
#ifndef __SMP__
217
        if(!fpt) {
218
#else
219
        if(!(fpt->flags & PF_USEDFPU)) {
220
#endif
221
                fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth);
222
                regs->psr &= ~PSR_EF;
223
                return;
224
        }
225
        fpsave(&fpt->tss.float_regs[0], &fpt->tss.fsr,
226
               &fpt->tss.fpqueue[0], &fpt->tss.fpqdepth);
227
        fpt->tss.sig_address = pc;
228
        fpt->tss.sig_desc = SUBSIG_FPERROR; /* as good as any */
229
#ifdef __SMP__
230
        fpt->flags &= ~PF_USEDFPU;
231
#endif
232
        if(psr & PSR_PS) {
233
                /* The first fsr store/load we tried trapped,
234
                 * the second one will not (we hope).
235
                 */
236
                printk("WARNING: FPU exception from kernel mode. at pc=%08lx\n",
237
                       regs->pc);
238
                regs->pc = regs->npc;
239
                regs->npc += 4;
240
                calls++;
241
                if(calls > 2)
242
                        die_if_kernel("Too many Penguin-FPU traps from kernel mode",
243
                                      regs);
244
                return;
245
        }
246
        send_sig(SIGFPE, fpt, 1);
247
#ifndef __SMP__
248
        last_task_used_math = NULL;
249
#endif
250
        regs->psr &= ~PSR_EF;
251
        if(calls > 0)
252
                calls=0;
253
}
254
 
255
void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc,
256
                         unsigned long psr)
257
{
258
        if(psr & PSR_PS)
259
                die_if_kernel("Penguin overflow trap from kernel mode", regs);
260
        current->tss.sig_address = pc;
261
        current->tss.sig_desc = SUBSIG_TAG; /* as good as any */
262
        send_sig(SIGEMT, current, 1);
263
}
264
 
265
void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc,
266
                       unsigned long psr)
267
{
268
#ifdef TRAP_DEBUG
269
        printk("Watchpoint detected at PC %08lx NPC %08lx PSR %08lx\n",
270
               pc, npc, psr);
271
#endif
272
        if(psr & PSR_PS)
273
                panic("Tell me what a watchpoint trap is, and I'll then deal "
274
                      "with such a beast...");
275
}
276
 
277
void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc,
278
                       unsigned long psr)
279
{
280
#ifdef TRAP_DEBUG
281
        printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n",
282
               pc, npc, psr);
283
#endif
284
        send_sig(SIGILL, current, 1);
285
}
286
 
287
void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc,
288
                        unsigned long psr)
289
{
290
        send_sig(SIGILL, current, 1);
291
}
292
 
293
void handle_bad_flush(struct pt_regs *regs, unsigned long pc, unsigned long npc,
294
                      unsigned long psr)
295
{
296
#ifdef TRAP_DEBUG
297
        printk("Unimplemented FLUSH Exception at PC %08lx NPC %08lx PSR %08lx\n",
298
               pc, npc, psr);
299
#endif
300
        printk("INSTRUCTION=%08lx\n", *((unsigned long *) regs->pc));
301
        send_sig(SIGILL, current, 1);
302
}
303
 
304
void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc,
305
                         unsigned long psr)
306
{
307
#ifdef TRAP_DEBUG
308
        printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n",
309
               pc, npc, psr);
310
#endif
311
        send_sig(SIGILL, current, 1);
312
}
313
 
314
void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc,
315
                       unsigned long psr)
316
{
317
        send_sig(SIGILL, current, 1);
318
}
319
 
320
/* Since we have our mappings set up, on multiprocessors we can spin them
321
 * up here so that timer interrupts work during initialization.
322
 */
323
 
324
extern void sparc_cpu_startup(void);
325
 
326
extern int linux_num_cpus;
327
extern ctxd_t *srmmu_ctx_table_phys;
328
 
329
int linux_smp_still_initting;
330
unsigned int thiscpus_tbr;
331
int thiscpus_mid;
332
 
333
void trap_init(void)
334
{
335
}

powered by: WebSVN 2.1.0

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