patch-2.1.87 linux/arch/m68k/kernel/traps.c
Next file: linux/arch/m68k/mac/Makefile
Previous file: linux/arch/m68k/kernel/time.c
Back to the patch index
Back to the overall index
- Lines: 253
- Date:
Thu Feb 12 16:30:13 1998
- Orig file:
v2.1.86/linux/arch/m68k/kernel/traps.c
- Orig date:
Mon Jun 16 16:35:54 1997
diff -u --recursive --new-file v2.1.86/linux/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c
@@ -36,6 +36,7 @@
#include <asm/traps.h>
#include <asm/pgtable.h>
#include <asm/machdep.h>
+#include <asm/siginfo.h>
#ifdef CONFIG_KGDB
#include <asm/kgdb.h>
#endif
@@ -64,23 +65,10 @@
__ALIGN_STR "\n"
SYMBOL_NAME_STR(nmihandler) ": rte");
-__initfunc(void trap_init (void))
+__initfunc(void base_trap_init(void))
{
- int i;
-
/* setup the exception vector table */
- __asm__ volatile ("movec %0,%/vbr" : : "r" ((void*)vectors));
-
- for (i = 48; i < 64; i++)
- vectors[i] = trap;
-
- for (i = 64; i < 256; i++)
- vectors[i] = inthandler;
-
- /* if running on an amiga, make the NMI interrupt do nothing */
- if (MACH_IS_AMIGA) {
- vectors[VEC_INT7] = nmihandler;
- }
+ __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
if (CPU_IS_040) {
/* set up FPSP entry points */
@@ -134,6 +122,23 @@
}
}
+__initfunc(void trap_init (void))
+{
+ int i;
+
+ for (i = 48; i < 64; i++)
+ if (!vectors[i])
+ vectors[i] = trap;
+
+ for (i = 64; i < 256; i++)
+ vectors[i] = inthandler;
+
+ /* if running on an amiga, make the NMI interrupt do nothing */
+ if (MACH_IS_AMIGA) {
+ vectors[VEC_INT7] = nmihandler;
+ }
+}
+
void set_evector(int vecnum, void (*handler)(void))
{
if (vecnum >= 0 && vecnum <= 256)
@@ -202,7 +207,7 @@
return;
}
- if (fslw & (MMU060_DESC_ERR | MMU060_WP)) {
+ if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
unsigned long errorcode;
unsigned long addr = fp->un.fmt4.effaddr;
errorcode = ((fslw & MMU060_WP) ? 1 : 0) |
@@ -230,9 +235,9 @@
static inline unsigned long probe040 (int iswrite, int fc, unsigned long addr)
{
unsigned long mmusr;
- unsigned long fs = get_fs();
+ mm_segment_t fs = get_fs();
- set_fs (fc);
+ set_fs (MAKE_MM_SEG(fc));
if (iswrite)
/* write */
@@ -261,7 +266,7 @@
unsigned long wbd,
struct frame *fp)
{
- unsigned long fs = get_fs ();
+ mm_segment_t fs = get_fs ();
unsigned long mmusr;
unsigned long errorcode;
@@ -277,7 +282,7 @@
/* just return if we can't perform the writeback */
return;
- set_fs (wbs & WBTM_040);
+ set_fs (MAKE_MM_SEG(wbs & WBTM_040));
switch (wbs & WBSIZ_040) {
case BA_SIZE_BYTE:
put_user (wbd & 0xff, (char *)wba);
@@ -833,34 +838,37 @@
asmlinkage void trap_c(struct frame *fp)
{
int sig;
+ siginfo_t info;
- if ((fp->ptregs.sr & PS_S)
- && ((fp->ptregs.vector) >> 2) == VEC_TRACE
- && !(fp->ptregs.sr & PS_T)) {
- /* traced a trapping instruction */
- unsigned char *lp = ((unsigned char *)&fp->un.fmt2) + 4;
- current->flags |= PF_DTRACE;
- /* clear the trace bit */
- (*(unsigned short *)lp) &= ~PS_T;
- return;
- } else if (fp->ptregs.sr & PS_S) {
- bad_super_trap(fp);
+ if (fp->ptregs.sr & PS_S) {
+ if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
+ /* traced a trapping instruction */
+ current->flags |= PF_DTRACE;
+ } else
+ bad_super_trap(fp);
return;
}
/* send the appropriate signal to the user program */
switch ((fp->ptregs.vector) >> 2) {
case VEC_ADDRERR:
+ info.si_code = BUS_ADRALN;
sig = SIGBUS;
break;
- case VEC_BUSERR:
- sig = SIGSEGV;
- break;
case VEC_ILLEGAL:
- case VEC_PRIV:
case VEC_LINE10:
case VEC_LINE11:
+ info.si_code = ILL_ILLOPC;
+ sig = SIGILL;
+ break;
+ case VEC_PRIV:
+ info.si_code = ILL_PRVOPC;
+ sig = SIGILL;
+ break;
case VEC_COPROC:
+ info.si_code = ILL_COPROC;
+ sig = SIGILL;
+ break;
case VEC_TRAP1:
case VEC_TRAP2:
case VEC_TRAP3:
@@ -875,51 +883,76 @@
case VEC_TRAP12:
case VEC_TRAP13:
case VEC_TRAP14:
+ info.si_code = ILL_ILLTRP;
sig = SIGILL;
break;
case VEC_FPBRUC:
+ case VEC_FPOE:
+ case VEC_FPNAN:
+ info.si_code = FPE_FLTINV;
+ sig = SIGFPE;
+ break;
case VEC_FPIR:
+ info.si_code = FPE_FLTRES;
+ sig = SIGFPE;
+ break;
case VEC_FPDIVZ:
+ info.si_code = FPE_FLTDIV;
+ sig = SIGFPE;
+ break;
case VEC_FPUNDER:
- case VEC_FPOE:
+ info.si_code = FPE_FLTUND;
+ sig = SIGFPE;
+ break;
case VEC_FPOVER:
- case VEC_FPNAN:
- {
- unsigned char fstate[FPSTATESIZE];
-
- __asm__ __volatile__ (".chip 68k/68881\n\t"
- "fsave %0@\n\t"
- ".chip 68k" : : "a" (fstate) : "memory");
- /* Set the exception pending bit in the 68882 idle frame */
- if (*(unsigned short *) fstate == 0x1f38)
- {
- fstate[fstate[1]] |= 1 << 3;
- __asm__ __volatile__ (".chip 68k/68881\n\t"
- "frestore %0@\n\t"
- ".chip 68k" : : "a" (fstate));
- }
- }
- /* fall through */
+ info.si_code = FPE_FLTOVF;
+ sig = SIGFPE;
+ break;
case VEC_ZERODIV:
+ info.si_code = FPE_INTDIV;
+ sig = SIGFPE;
+ break;
+ case VEC_CHK:
case VEC_TRAP:
+ info.si_code = FPE_INTOVF;
sig = SIGFPE;
break;
case VEC_TRACE: /* ptrace single step */
- fp->ptregs.sr &= ~PS_T;
+ info.si_code = TRAP_TRACE;
+ sig = SIGTRAP;
+ break;
case VEC_TRAP15: /* breakpoint */
+ info.si_code = TRAP_BRKPT;
sig = SIGTRAP;
break;
default:
+ info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
}
-
- send_sig (sig, current, 1);
-}
-
-asmlinkage void set_esp0 (unsigned long ssp)
-{
- current->tss.esp0 = ssp;
+ info.si_signo = sig;
+ info.si_errno = 0;
+ switch (fp->ptregs.format) {
+ default:
+ info.si_addr = (void *) fp->ptregs.pc;
+ break;
+ case 2:
+ info.si_addr = (void *) fp->un.fmt2.iaddr;
+ break;
+ case 7:
+ info.si_addr = (void *) fp->un.fmt7.effaddr;
+ break;
+ case 9:
+ info.si_addr = (void *) fp->un.fmt9.iaddr;
+ break;
+ case 10:
+ info.si_addr = (void *) fp->un.fmta.daddr;
+ break;
+ case 11:
+ info.si_addr = (void *) fp->un.fmtb.daddr;
+ break;
+ }
+ force_sig_info (sig, &info, current);
}
void die_if_kernel (char *str, struct pt_regs *fp, int nr)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov