BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / luna68k / luna68k / trap.c
index ce0ca25..bc30b5e 100644 (file)
@@ -1,45 +1,69 @@
 /*
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1992 OMRON Corporation.
 /*
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1992 OMRON Corporation.
- * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- * from: Utah $Hdr: trap.c 1.35 91/12/26$
- * OMRON: $Id: trap.c,v 1.2 92/06/14 06:23:41 moti Exp $
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  *
  *
- * from: hp300/hp300/trap.c     7.23 (Berkeley) 7/9/92
+ * from: Utah $Hdr: trap.c 1.35 91/12/26$
+ * from: hp300/hp300/trap.c    8.4 (Berkeley) 9/23/93
  *
  *
- *     @(#)trap.c      7.2 (Berkeley) %G%
+ *     @(#)trap.c      8.5 (Berkeley) 12/6/93
  */
 
  */
 
-#include "param.h"
-#include "systm.h"
-#include "proc.h"
-#include "acct.h"
-#include "kernel.h"
-#include "signalvar.h"
-#include "resourcevar.h"
-#include "syscall.h"
-#include "syslog.h"
-#include "user.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/acct.h>
+#include <sys/kernel.h>
+#include <sys/signalvar.h>
+#include <sys/resourcevar.h>
+#include <sys/syscall.h>
+#include <sys/syslog.h>
+#include <sys/user.h>
 #ifdef KTRACE
 #ifdef KTRACE
-#include "ktrace.h"
+#include <sys/ktrace.h>
 #endif
 
 #endif
 
-#include "../include/psl.h"
-#include "../include/trap.h"
-#include "../include/cpu.h"
-#include "../include/reg.h"
-#include "../include/mtpr.h"
+#include <machine/psl.h>
+#include <machine/trap.h>
+#include <machine/cpu.h>
+#include <machine/reg.h>
+#include <machine/mtpr.h>
 
 
-#include "vm/vm.h"
-#include "vm/pmap.h"
+#include <vm/vm.h>
+#include <vm/pmap.h>
 
 struct sysent  sysent[];
 int    nsysent;
 
 struct sysent  sysent[];
 int    nsysent;
@@ -79,8 +103,17 @@ short       exframesize[] = {
        -1, -1, -1, -1  /* type C-F - undefined */
 };
 
        -1, -1, -1, -1  /* type C-F - undefined */
 };
 
+#ifdef LUNA2
+#define KDFAULT(c)     (mmutype == MMU_68040 ? \
+                           ((c) & SSW4_TMMASK) == SSW4_TMKD : \
+                           ((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))
+#define WRFAULT(c)     (mmutype == MMU_68040 ? \
+                           ((c) & SSW4_RW) == 0 : \
+                           ((c) & (SSW_DF|SSW_RW)) == SSW_DF)
+#else
 #define KDFAULT(c)     (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
 #define WRFAULT(c)     (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
 #define KDFAULT(c)     (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
 #define WRFAULT(c)     (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
+#endif
 
 #ifdef DEBUG
 int mmudebug = 0;
 
 #ifdef DEBUG
 int mmudebug = 0;
@@ -104,35 +137,43 @@ userret(p, fp, oticks, faultaddr, fromtrap)
        int fromtrap;
 {
        int sig, s;
        int fromtrap;
 {
        int sig, s;
+#ifdef LUNA2
+       int beenhere = 0;
 
 
+again:
+#endif
        /* take pending signals */
        while ((sig = CURSIG(p)) != 0)
        /* take pending signals */
        while ((sig = CURSIG(p)) != 0)
-               psig(sig);
-       p->p_pri = p->p_usrpri;
+               postsig(sig);
+       p->p_priority = p->p_usrpri;
        if (want_resched) {
                /*
                 * Since we are curproc, clock will normally just change
                 * our priority without moving us from one queue to another
                 * (since the running process is not on a queue.)
        if (want_resched) {
                /*
                 * Since we are curproc, clock will normally just change
                 * our priority without moving us from one queue to another
                 * (since the running process is not on a queue.)
-                * If that happened after we setrq ourselves but before we
-                * swtch()'ed, we might not be on the queue indicated by
-                * our priority.
+                * If that happened after we put ourselves on the run queue
+                * but before we switched, we might not be on the queue
+                * indicated by our priority.
                 */
                s = splstatclock();
                 */
                s = splstatclock();
-               setrq(p);
+               setrunqueue(p);
                p->p_stats->p_ru.ru_nivcsw++;
                p->p_stats->p_ru.ru_nivcsw++;
-               swtch();
+               mi_switch();
                splx(s);
                while ((sig = CURSIG(p)) != 0)
                splx(s);
                while ((sig = CURSIG(p)) != 0)
-                       psig(sig);
+                       postsig(sig);
        }
 
        /*
         * If profiling, charge system time to the trapped pc.
         */
        }
 
        /*
         * If profiling, charge system time to the trapped pc.
         */
-       if (p->p_flag & SPROFIL)
-               addupc_intr(p, fp->f_pc, (int)(p->p_sticks - oticks));
-#ifdef HP380
+       if (p->p_flag & P_PROFIL) {
+               extern int psratio;
+
+               addupc_task(p, fp->f_pc,
+                           (int)(p->p_sticks - oticks) * psratio);
+       }
+#ifdef LUNA2
        /*
         * Deal with user mode writebacks (from trap, or from sigreturn).
         * If any writeback fails, go back and attempt signal delivery.
        /*
         * Deal with user mode writebacks (from trap, or from sigreturn).
         * If any writeback fails, go back and attempt signal delivery.
@@ -158,7 +199,7 @@ userret(p, fp, oticks, faultaddr, fromtrap)
                }
        }
 #endif
                }
        }
 #endif
-       curpri = p->p_pri;
+       curpriority = p->p_priority;
 }
 
 /*
 }
 
 /*
@@ -193,7 +234,7 @@ trap(type, code, v, frame)
        default:
 dopanic:
                printf("trap type %d, code = %x, v = %x\n", type, code, v);
        default:
 dopanic:
                printf("trap type %d, code = %x, v = %x\n", type, code, v);
-               regdump(frame.f_regs, 128);
+               regdump(&frame, 128);
                type &= ~T_USER;
                if ((unsigned)type < TRAP_TYPES)
                        panic(trap_type[type]);
                type &= ~T_USER;
                if ((unsigned)type < TRAP_TYPES)
                        panic(trap_type[type]);
@@ -263,6 +304,19 @@ copyfault:
                break;
 #endif
 
                break;
 #endif
 
+#ifdef LUNA2
+       case T_FPEMULI|T_USER:  /* unimplemented FP instuction */
+       case T_FPEMULD|T_USER:  /* unimplemented FP data type */
+               /* XXX need to FSAVE */
+               printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
+                      p->p_pid, p->p_comm,
+                      frame.f_format == 2 ? "instruction" : "data type",
+                      frame.f_pc, frame.f_fmt2.f_iaddr);
+               /* XXX need to FRESTORE */
+               i = SIGFPE;
+               break;
+#endif
+
        case T_ILLINST|T_USER:  /* illegal instruction fault */
        case T_PRIVINST|T_USER: /* privileged instruction fault */
                ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
        case T_ILLINST|T_USER:  /* illegal instruction fault */
        case T_PRIVINST|T_USER: /* privileged instruction fault */
                ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
@@ -344,8 +398,8 @@ copyfault:
                        return;
                }
                spl0();
                        return;
                }
                spl0();
-               if (p->p_flag & SOWEUPC) {
-                       p->p_flag &= ~SOWEUPC;
+               if (p->p_flag & P_OWEUPC) {
+                       p->p_flag &= ~P_OWEUPC;
                        ADDUPROF(p);
                }
                goto out;
                        ADDUPROF(p);
                }
                goto out;
@@ -422,6 +476,10 @@ copyfault:
                }
                if (rv == KERN_SUCCESS) {
                        if (type == T_MMUFLT) {
                }
                if (rv == KERN_SUCCESS) {
                        if (type == T_MMUFLT) {
+#ifdef LUNA2
+                               if (mmutype == MMU_68040)
+                                       (void) writeback(&frame, 1);
+#endif
                                return;
                        }
                        goto out;
                                return;
                        }
                        goto out;
@@ -447,6 +505,318 @@ out:
        userret(p, &frame, sticks, v, 1);
 }
 
        userret(p, &frame, sticks, v, 1);
 }
 
+#ifdef LUNA2
+#ifdef DEBUG
+struct writebackstats {
+       int calls;
+       int cpushes;
+       int move16s;
+       int wb1s, wb2s, wb3s;
+       int wbsize[4];
+} wbstats;
+
+char *f7sz[] = { "longword", "byte", "word", "line" };
+char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" };
+char *f7tm[] = { "d-push", "u-data", "u-code", "M-data",
+                "M-code", "k-data", "k-code", "RES" };
+char wberrstr[] =
+    "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n";
+#endif
+
+writeback(fp, docachepush)
+       struct frame *fp;
+       int docachepush;
+{
+       register struct fmt7 *f = &fp->f_fmt7;
+       register struct proc *p = curproc;
+       int err = 0;
+       u_int fa;
+       caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault;
+
+#ifdef DEBUG
+       if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
+               printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa);
+               dumpssw(f->f_ssw);
+       }
+       wbstats.calls++;
+#endif
+       /*
+        * Deal with special cases first.
+        */
+       if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) {
+               /*
+                * Dcache push fault.
+                * Line-align the address and write out the push data to
+                * the indicated physical address.
+                */
+#ifdef DEBUG
+               if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
+                       printf(" pushing %s to PA %x, data %x",
+                              f7sz[(f->f_ssw & SSW4_SZMASK) >> 5],
+                              f->f_fa, f->f_pd0);
+                       if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN)
+                               printf("/%x/%x/%x",
+                                      f->f_pd1, f->f_pd2, f->f_pd3);
+                       printf("\n");
+               }
+               if (f->f_wb1s & SSW4_WBSV)
+                       panic("writeback: cache push with WB1S valid");
+               wbstats.cpushes++;
+#endif
+               /*
+                * XXX there are security problems if we attempt to do a
+                * cache push after a signal handler has been called.
+                */
+               if (docachepush) {
+                       pmap_enter(kernel_pmap, (vm_offset_t)vmmap,
+                                  trunc_page(f->f_fa), VM_PROT_WRITE, TRUE);
+                       fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF];
+                       bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16);
+                       DCFL(pmap_extract(kernel_pmap, (vm_offset_t)fa));
+                       pmap_remove(kernel_pmap, (vm_offset_t)vmmap,
+                                   (vm_offset_t)&vmmap[NBPG]);
+               } else
+                       printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n",
+                              p->p_pid, p->p_comm, p->p_ucred->cr_uid);
+       } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) {
+               /*
+                * MOVE16 fault.
+                * Line-align the address and write out the push data to
+                * the indicated virtual address.
+                */
+#ifdef DEBUG
+               if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+                       printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n",
+                              f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1,
+                              f->f_pd2, f->f_pd3);
+               if (f->f_wb1s & SSW4_WBSV)
+                       panic("writeback: MOVE16 with WB1S valid");
+               wbstats.move16s++;
+#endif
+               if (KDFAULT(f->f_wb1s))
+                       bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16);
+               else
+                       err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0);
+               if (err) {
+                       fa = f->f_fa & ~0xF;
+#ifdef DEBUG
+                       if (mmudebug & MDB_WBFAILED)
+                               printf(wberrstr, p->p_pid, p->p_comm,
+                                      "MOVE16", fp->f_pc, f->f_fa,
+                                      f->f_fa & ~0xF, f->f_pd0);
+#endif
+               }
+       } else if (f->f_wb1s & SSW4_WBSV) {
+               /*
+                * Writeback #1.
+                * Position the "memory-aligned" data and write it out.
+                */
+               register u_int wb1d = f->f_wb1d;
+               register int off;
+
+#ifdef DEBUG
+               if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+                       dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d);
+               wbstats.wb1s++;
+               wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
+#endif
+               off = (f->f_wb1a & 3) * 8;
+               switch (f->f_wb1s & SSW4_SZMASK) {
+               case SSW4_SZLW:
+                       if (off)
+                               wb1d = (wb1d >> (32 - off)) | (wb1d << off);
+                       if (KDFAULT(f->f_wb1s))
+                               *(long *)f->f_wb1a = wb1d;
+                       else
+                               err = suword((caddr_t)f->f_wb1a, wb1d);
+                       break;
+               case SSW4_SZB:
+                       off = 24 - off;
+                       if (off)
+                               wb1d >>= off;
+                       if (KDFAULT(f->f_wb1s))
+                               *(char *)f->f_wb1a = wb1d;
+                       else
+                               err = subyte((caddr_t)f->f_wb1a, wb1d);
+                       break;
+               case SSW4_SZW:
+                       off = (off + 16) % 32;
+                       if (off)
+                               wb1d = (wb1d >> (32 - off)) | (wb1d << off);
+                       if (KDFAULT(f->f_wb1s))
+                               *(short *)f->f_wb1a = wb1d;
+                       else
+                               err = susword((caddr_t)f->f_wb1a, wb1d);
+                       break;
+               }
+               if (err) {
+                       fa = f->f_wb1a;
+#ifdef DEBUG
+                       if (mmudebug & MDB_WBFAILED)
+                               printf(wberrstr, p->p_pid, p->p_comm,
+                                      "#1", fp->f_pc, f->f_fa,
+                                      f->f_wb1a, f->f_wb1d);
+#endif
+               }
+       }
+       /*
+        * Deal with the "normal" writebacks.
+        *
+        * XXX writeback2 is known to reflect a LINE size writeback after
+        * a MOVE16 was already dealt with above.  Ignore it.
+        */
+       if (err == 0 && (f->f_wb2s & SSW4_WBSV) &&
+           (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) {
+#ifdef DEBUG
+               if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+                       dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
+               wbstats.wb2s++;
+               wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
+#endif
+               switch (f->f_wb2s & SSW4_SZMASK) {
+               case SSW4_SZLW:
+                       if (KDFAULT(f->f_wb2s))
+                               *(long *)f->f_wb2a = f->f_wb2d;
+                       else
+                               err = suword((caddr_t)f->f_wb2a, f->f_wb2d);
+                       break;
+               case SSW4_SZB:
+                       if (KDFAULT(f->f_wb2s))
+                               *(char *)f->f_wb2a = f->f_wb2d;
+                       else
+                               err = subyte((caddr_t)f->f_wb2a, f->f_wb2d);
+                       break;
+               case SSW4_SZW:
+                       if (KDFAULT(f->f_wb2s))
+                               *(short *)f->f_wb2a = f->f_wb2d;
+                       else
+                               err = susword((caddr_t)f->f_wb2a, f->f_wb2d);
+                       break;
+               }
+               if (err) {
+                       fa = f->f_wb2a;
+#ifdef DEBUG
+                       if (mmudebug & MDB_WBFAILED) {
+                               printf(wberrstr, p->p_pid, p->p_comm,
+                                      "#2", fp->f_pc, f->f_fa,
+                                      f->f_wb2a, f->f_wb2d);
+                               dumpssw(f->f_ssw);
+                               dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
+                       }
+#endif
+               }
+       }
+       if (err == 0 && (f->f_wb3s & SSW4_WBSV)) {
+#ifdef DEBUG
+               if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
+                       dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d);
+               wbstats.wb3s++;
+               wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++;
+#endif
+               switch (f->f_wb3s & SSW4_SZMASK) {
+               case SSW4_SZLW:
+                       if (KDFAULT(f->f_wb3s))
+                               *(long *)f->f_wb3a = f->f_wb3d;
+                       else
+                               err = suword((caddr_t)f->f_wb3a, f->f_wb3d);
+                       break;
+               case SSW4_SZB:
+                       if (KDFAULT(f->f_wb3s))
+                               *(char *)f->f_wb3a = f->f_wb3d;
+                       else
+                               err = subyte((caddr_t)f->f_wb3a, f->f_wb3d);
+                       break;
+               case SSW4_SZW:
+                       if (KDFAULT(f->f_wb3s))
+                               *(short *)f->f_wb3a = f->f_wb3d;
+                       else
+                               err = susword((caddr_t)f->f_wb3a, f->f_wb3d);
+                       break;
+#ifdef DEBUG
+               case SSW4_SZLN:
+                       panic("writeback: wb3s indicates LINE write");
+#endif
+               }
+               if (err) {
+                       fa = f->f_wb3a;
+#ifdef DEBUG
+                       if (mmudebug & MDB_WBFAILED)
+                               printf(wberrstr, p->p_pid, p->p_comm,
+                                      "#3", fp->f_pc, f->f_fa,
+                                      f->f_wb3a, f->f_wb3d);
+#endif
+               }
+       }
+       p->p_addr->u_pcb.pcb_onfault = oonfault;
+       /*
+        * Determine the cause of the failure if any translating to
+        * a signal.  If the corresponding VA is valid and RO it is
+        * a protection fault (SIGBUS) otherwise consider it an
+        * illegal reference (SIGSEGV).
+        */
+       if (err) {
+               if (vm_map_check_protection(&p->p_vmspace->vm_map,      
+                                           trunc_page(fa), round_page(fa),
+                                           VM_PROT_READ) &&
+                   !vm_map_check_protection(&p->p_vmspace->vm_map,
+                                            trunc_page(fa), round_page(fa),
+                                            VM_PROT_WRITE))
+                       err = SIGBUS;
+               else
+                       err = SIGSEGV;
+       }
+       return(err);
+}
+
+#ifdef DEBUG
+dumpssw(ssw)
+       register u_short ssw;
+{
+       printf(" SSW: %x: ", ssw);
+       if (ssw & SSW4_CP)
+               printf("CP,");
+       if (ssw & SSW4_CU)
+               printf("CU,");
+       if (ssw & SSW4_CT)
+               printf("CT,");
+       if (ssw & SSW4_CM)
+               printf("CM,");
+       if (ssw & SSW4_MA)
+               printf("MA,");
+       if (ssw & SSW4_ATC)
+               printf("ATC,");
+       if (ssw & SSW4_LK)
+               printf("LK,");
+       if (ssw & SSW4_RW)
+               printf("RW,");
+       printf(" SZ=%s, TT=%s, TM=%s\n",
+              f7sz[(ssw & SSW4_SZMASK) >> 5],
+              f7tt[(ssw & SSW4_TTMASK) >> 3],
+              f7tm[ssw & SSW4_TMMASK]);
+}
+
+dumpwb(num, s, a, d)
+       int num;
+       u_short s;
+       u_int a, d;
+{
+       register struct proc *p = curproc;
+       vm_offset_t pa;
+
+       printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n",
+              num, a, d, f7sz[(s & SSW4_SZMASK) >> 5],
+              f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]);
+       printf("               PA ");
+       pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)a);
+       if (pa == 0)
+               printf("<invalid address>");
+       else
+               printf("%x, current value %x", pa, fuword((caddr_t)a));
+       printf("\n");
+}
+#endif
+#endif
+
 /*
  * Proces a system call.
  */
 /*
  * Proces a system call.
  */
@@ -476,17 +846,24 @@ syscall(code, frame)
        params = (caddr_t)frame.f_regs[SP] + sizeof(int);
        switch (code) {
 
        params = (caddr_t)frame.f_regs[SP] + sizeof(int);
        switch (code) {
 
-       case SYS_indir:
+       case SYS_syscall:
                /*
                 * Code is first argument, followed by actual args.
                 */
                code = fuword(params);
                params += sizeof(int);
                /*
                 * Code is first argument, followed by actual args.
                 */
                code = fuword(params);
                params += sizeof(int);
+               /*
+                * XXX sigreturn requires special stack manipulation
+                * that is only done if entered via the sigreturn
+                * trap.  Cannot allow it here so make sure we fail.
+                */
+               if (code == SYS_sigreturn)
+                       code = numsys;
                break;
 
                break;
 
-       case SYS___indir:
+       case SYS___syscall:
                /*
                /*
-                * Like indir, but code is a quad, so as to maintain
+                * Like syscall, but code is a quad, so as to maintain
                 * quad alignment for the rest of the arguments.
                 */
                code = fuword(params + _QUAD_LOWWORD * sizeof(int));
                 * quad alignment for the rest of the arguments.
                 */
                code = fuword(params + _QUAD_LOWWORD * sizeof(int));
@@ -500,7 +877,7 @@ syscall(code, frame)
        if (code < numsys)
                callp += code;
        else
        if (code < numsys)
                callp += code;
        else
-               callp += SYS_indir;     /* => nosys */
+               callp += SYS_syscall;   /* => nosys */
        argsize = callp->sy_narg * sizeof(int);
        if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
 #ifdef KTRACE
        argsize = callp->sy_narg * sizeof(int);
        if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
 #ifdef KTRACE