home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / os / machsun3.tz / machsun3 / mk.kernel / sun3 / trap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  25.6 KB  |  1,099 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1992 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon 
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    trap.c,v $
  29.  * Revision 2.12  91/08/01  14:09:28  dbg
  30.  *     Restore thread_should_halt test to exit path of
  31.  *     user_page_fault_continue.  Fix user single-step handling.
  32.  *     [91/08/01            dbg]
  33.  * 
  34.  * Revision 2.11  91/07/31  18:14:48  dbg
  35.  *     Support stack switching.
  36.  *     [91/03/25            dbg]
  37.  * 
  38.  * Revision 2.8  91/03/16  14:59:20  rpd
  39.  *     Hacked for AST interface changes.
  40.  *     [91/03/15            rpd]
  41.  * 
  42.  *     Added resume, continuation arguments to vm_fault.
  43.  *     [91/03/13            rpd]
  44.  * 
  45.  *     Updated for new kmem_alloc interface.
  46.  *     [91/03/03            rpd]
  47.  * 
  48.  * Revision 2.7  91/01/08  15:52:58  rpd
  49.  *     Added KEEP_STACKS support.
  50.  *     [91/01/07            rpd]
  51.  *     Added continuation argument to thread_block.
  52.  *     [90/12/08            rpd]
  53.  * 
  54.  * Revision 2.6  90/10/25  14:48:07  rwd
  55.  *     Fixed the map argument to db_find_watchpoint.
  56.  *     Made the faultaddr argument to pagefault a vm_offset_t.
  57.  *     [90/10/18            rpd]
  58.  *     Added watchpoint support.
  59.  *     [90/10/16            rwd]
  60.  * 
  61.  * Revision 2.5  90/08/27  22:12:12  dbg
  62.  *     Remove kdbnofault test - it's done in kdb_trap instead.
  63.  *     [90/07/26            dbg]
  64.  * 
  65.  *     Use jmp_buf_t instead of label_t.
  66.  *     [90/07/17            dbg]
  67.  * 
  68.  * Revision 2.4  90/06/02  15:07:19  rpd
  69.  *     Updated to new csw_needed macro.
  70.  *     [90/03/26  23:01:08  rpd]
  71.  * 
  72.  * Revision 2.3  89/10/23  12:02:14  dbg
  73.  *     Turn off debug_all_traps_with_kdb, to let user processes
  74.  *     handle traps.  Always pass trap code, not MACH exception
  75.  *     code, to kdb_trap.
  76.  *     [89/10/20            dbg]
  77.  * 
  78.  * Revision 2.2  89/09/08  11:27:39  dbg
  79.  *     On page fault in kernel mode: if the current task's map is a
  80.  *     submap of the kernel and the address falls within it, try it
  81.  *     first.  Avoids deadlock (on the kernel map) with other kernel
  82.  *     tasks.
  83.  *     [89/09/06            dbg]
  84.  * 
  85.  * Revision 2.1  89/08/03  16:53:50  rwd
  86.  * Created.
  87.  * 
  88.  * 18-May-89  Randall Dean (rwd) at Carnegie-Mellon University
  89.  *    Torn from old trap.c by dbg.  Fixed non-thread case for
  90.  *    MACH_KERNEL
  91.  *
  92.  */
  93.  
  94. /*
  95.  * Trap handler for SUN3.
  96.  *
  97.  * From SUNOS 3.4
  98.  */
  99.  
  100. #include <platforms.h>
  101. #include <mach_kdb.h>
  102. #include <fpa.h>
  103.  
  104. #include <mach/exception.h>
  105. #include <mach/kern_return.h>
  106. #include <mach/vm_param.h>
  107.  
  108. #include <kern/thread.h>
  109. #include <kern/task.h>
  110.  
  111. #include <vm/vm_map.h>
  112. #include <vm/vm_fault.h>
  113. #include <vm/vm_kern.h>
  114.  
  115. #include <sun/fault.h>
  116.  
  117. #include <mach/sun3/exception.h>
  118. #include <sun3/frame.h>
  119. #include <sun3/machparam.h>
  120. #include <sun3/psl.h>
  121. #include <sun3/trap.h>
  122.  
  123. #if    NFPA > 0
  124. #include <sundev/fpareg.h>
  125. #include <sun3/enable.h>
  126.  
  127. extern short        fpa_exist;
  128. extern enum fpa_state    fpa_state;
  129. #endif
  130.  
  131. char    *trap_type[] = {
  132.     "Vector address 0x0",
  133.     "Vector address 0x4",
  134.     "Bus error",
  135.     "Address error",
  136.     "Illegal instruction",
  137.     "Divide by zero",
  138.     "CHK, CHK2 instruction",
  139.     "TRAPV, cpTRAPcc, cpTRAPcc instruction",
  140.     "Privilege violation",
  141.     "Trace",
  142.     "1010 emulator trap",
  143.     "1111 emulator trap",
  144.     "Vector address 0x30",
  145.     "Coprocessor protocol error",
  146.     "Stack format error",
  147.     "Uninitialized interrupt",
  148.     "Vector address 0x40",
  149.     "Vector address 0x44",
  150.     "Vector address 0x48",
  151.     "Vector address 0x4c",
  152.     "Vector address 0x50",
  153.     "Vector address 0x54",
  154.     "Vector address 0x58",
  155.     "Vector address 0x5c",
  156.     "Spurious interrupt",
  157. };
  158. int    TRAP_TYPES = sizeof(trap_type)/sizeof(trap_type[0]);
  159.  
  160. #define    DEBUG    1
  161.  
  162. #if defined(DEBUG) || defined (lint)
  163. int tdebug = 0;
  164. int tudebug = 0;
  165. int lodebug = 0;
  166. int bedebug = 0;
  167. #else
  168. #define    tdebug    0
  169. #define    tudebug    0
  170. #define    lodebug    0
  171. #define    bedebug    0
  172. #endif defined(DEBUG) || defined(lint)
  173.  
  174. #if    MACH_KDB
  175. boolean_t    debug_all_traps_with_kdb = FALSE;
  176. extern struct db_watchpoint *db_watchpoint_list;
  177. extern boolean_t db_watchpoints_inserted;
  178.  
  179. void
  180. thread_kdb_return()
  181. {
  182.     register thread_t self = current_thread();
  183.     register struct mc68020_saved_state *regs = self->pcb->user_regs;
  184.  
  185.     if (kdb_trap(regs->vector, regs)) {
  186.         thread_exception_return();
  187.         /*NOTREACHED*/
  188.     }
  189. }
  190. #endif    MACH_KDB
  191.  
  192. /*
  193.  * Called from the trap handler when a processor trap occurs.
  194.  * Returns amount to adjust the stack: > 0 removes bus error
  195.  * info, == 0 does nothing.
  196.  */
  197. int
  198. kernel_trap(type, regs)
  199.     int    type;
  200.     register
  201.     struct mc68020_saved_state *regs;
  202. {
  203.     int    besize = 0;
  204.     int    be;
  205.  
  206.     register thread_t    thread = current_thread();
  207.  
  208.     be = (type == T_BUSERR) ? getbuserr() : 0;
  209.  
  210.     if (tdebug) {
  211.         int i = type / sizeof(int);
  212.         if ((unsigned)i < TRAP_TYPES)
  213.         printf("trap: %s\n", trap_type[i]);
  214.         showregs("trap", type, regs, be);
  215.     }
  216.  
  217.     /*
  218.      * Reset sp value to adjusted system sp.
  219.      */
  220.     regs->sp = (int)(regs+1);
  221.     switch (regs->stkfmt) {
  222.         case SF_NORMAL:
  223.         case SF_THROWAWAY:
  224.         break;
  225.         case SF_NORMAL6:
  226.         regs->sp += sizeof (struct bei_normal6);
  227.         break;
  228.         case SF_COPROC:
  229.         regs->sp += sizeof (struct bei_coproc);
  230.         break;
  231.         case SF_MEDIUM:
  232.         regs->sp += sizeof (struct bei_medium);
  233.         besize = sizeof (struct bei_medium);
  234.         break;
  235.         case SF_LONGB:
  236.         regs->sp += sizeof (struct bei_longb);
  237.         besize = sizeof (struct bei_longb);
  238.         break;
  239.         default:
  240.         panic("bad system stack format");
  241.         /*NOTREACHED*/
  242.     }
  243.  
  244.     switch (type) {
  245.  
  246.         case T_BUSERR:
  247.  
  248.         if (be & BE_TIMEOUT)
  249.             DELAY(2000);    /* allow for refresh recovery time */
  250.  
  251.         /* may have been expected by C */
  252.         if (nofault) {
  253.             jmp_buf_t *ftmp;
  254.  
  255.             ftmp = nofault;
  256.             nofault = 0;
  257.             longjmp(ftmp);
  258.         }
  259.  
  260.         if (thread == THREAD_NULL)
  261.             break;    /* trap in boot phase */
  262.  
  263. #if    NFPA > 0
  264.         /*
  265.          * If enable register is not turned on, try to initialize
  266.          * the FPA.  Otherwise, panic if we cannot initialize it.
  267.          * In case of FPA bus error in kernel mode, shut down the
  268.          * FPA instead of the whole system.
  269.          */
  270.         if (fpa_exist
  271.             && (be & BE_FPAENA)
  272.             && fpa_state != FPA_DISABLED) {
  273.  
  274.             if (fpa_init(thread) == 0)
  275.             return (0);
  276.         }
  277.         if (be & BE_FPAENA)
  278.             panic("FPA not enabled");
  279.         if (be & BE_FPABERR) {
  280.             showregs("FPA KERNEL BUS ERROR",
  281.                  type,
  282.                  regs,
  283.                  be);
  284.             traceback((long)regs->sp, (long)regs->pc);
  285.             printf("FPA BUS ERROR: IERR == %x\n", fpa->fp_ierr);
  286.             fpa_shutdown();
  287.  
  288.             exc = EXC_BAD_ACCESS;
  289.             code = KERN_INVALID_ADDRESS;
  290.             subcode = (int)fpa;    /* fpa address as indicator */
  291.             break;
  292.         }
  293. #endif    NFPA > 0
  294.             
  295.         switch (regs->stkfmt) {
  296.             case SF_MEDIUM:
  297.             {
  298.             struct bei_medium *beip =
  299.                 (struct bei_medium *)(regs+1);
  300.  
  301. #if    NFPA > 0
  302.             if (fpa_exist &&
  303.                 fpa_state != FPA_DISABLED &&
  304.                 (char *)beip->bei_fault >= (char *)fpa &&
  305.                 (char *)beip->bei_fault <=
  306.                 (char *)fpa + sizeof(struct fpa_device))
  307.                 if (fpa_init(thread) == 0)
  308.                 return (0);
  309. #endif    NFPA > 0
  310.             if (beip->bei_dfault) {
  311.                 if (kernel_page_fault(
  312.                     (vm_offset_t)beip->bei_fault,
  313.                     beip->bei_rw,
  314.                     regs)
  315.                     == KERN_SUCCESS)
  316.                 return (0);
  317.             }
  318.             break;
  319.             }
  320.             case SF_LONGB:
  321.             {
  322.             struct bei_longb *beip =
  323.                 (struct bei_longb *)(regs+1);
  324.  
  325. #if    NFPA > 0
  326.             if (fpa_exist &&
  327.                 fpa_state != FPA_DISABLED &&
  328.                 (char *)beip->bei_fault >= (char *)fpa &&
  329.                 (char *)beip->bei_fault <=
  330.                 (char *)fpa + sizeof(struct fpa_device))
  331.                 if (fpa_init(thread) == 0)
  332.                 return (0);
  333. #endif    NFPA > 0
  334.             if (beip->bei_dfault) {
  335.                 if (kernel_page_fault(
  336.                     (vm_offset_t)beip->bei_fault,
  337.                     beip->bei_rw,
  338.                     regs)
  339.                     == KERN_SUCCESS)
  340.                 return (0);
  341.             }
  342.             break;
  343.             }
  344.             default:
  345.             panic("bad bus error stack format");
  346.         }
  347.  
  348.         if (lodebug) {
  349.             showregs("lofault", type, regs, be);
  350.             traceback((long)regs->sp, (long)regs->pc);
  351.         }
  352.  
  353.         if (thread->recover != 0) {
  354.             regs->pc = thread->recover;
  355.             thread->recover = 0;
  356.             return (besize);
  357.         }
  358.         break;
  359.  
  360.         case T_TRACE:
  361.         {
  362.         register pcb_t pcb;
  363.  
  364.         if (thread == THREAD_NULL)
  365.             break;    /* trap in boot phase */
  366.  
  367.         pcb = thread->pcb;
  368. #if    MACH_KDB
  369.         if (pcb->flag & TRACE_KDB) {
  370.             /*
  371.              * Trace trap to kernel debugger
  372.              */
  373.             pcb->flag &= ~TRACE_KDB;
  374.             break;
  375.         }
  376. #endif    MACH_KDB
  377.         /*
  378.          * Trace trap in kernel mode immediately after 'trap'
  379.          * instruction in user mode.  Defer the trace until the
  380.          * thread re-enters user mode.
  381.          */
  382.         pcb->flag |= TRACE_PENDING;
  383.         return (0);
  384.         }
  385.  
  386.         default:
  387.         break;
  388.     }
  389.  
  390. #if    MACH_KDB
  391.     switch (kdb_trap(type, regs)) {
  392.         case 2:
  393.         /* clear bus error frame */
  394.         return (besize);
  395.         case 1:
  396.         /* normal return */
  397.         return (0);
  398.         case 0:
  399.         /* no debugger (!) */
  400.         break;
  401.     }
  402. #endif    MACH_KDB
  403.     (void) splhigh();
  404.     showregs((char *)0, type, regs, be);
  405.     traceback((long)regs->a6, (long)regs->sp);
  406.     {
  407.         int i = regs->vector/sizeof(int);
  408.         if (i < TRAP_TYPES)
  409.         panic(trap_type[i]);
  410.         panic("trap");
  411.     }
  412.     /*NOTREACHED*/
  413. }
  414.  
  415.  
  416. void    user_page_fault();        /* forward */
  417. void    user_page_fault_continue();    /* forward */
  418.  
  419. /*
  420.  *    User mode trap.
  421.  */
  422. int
  423. user_trap(type, regs)
  424.     int    type;
  425.     register
  426.     struct mc68020_saved_state *regs;
  427. {
  428.     int    exc, code;
  429.     int    subcode = 0;
  430.     int    besize = 0;
  431.     int    be;
  432.  
  433.     register thread_t    thread = current_thread();
  434.     register pcb_t        pcb = thread->pcb;
  435.  
  436.     pcb->user_regs = regs;
  437.     pcb->discard_frame = FALSE;
  438.  
  439.     be = (type == T_BUSERR) ? getbuserr() : 0;
  440.  
  441.     if (tdebug) {
  442.         int i = type / sizeof(int);
  443.         if ((unsigned)i < TRAP_TYPES)
  444.         printf("trap: %s\n", trap_type[i]);
  445.         showregs("trap", type, regs, be);
  446.     }
  447.  
  448.     switch (type) {
  449.  
  450.         case T_ADDRERR:
  451.         exc = EXC_BAD_INSTRUCTION;
  452.         code = regs->vector;
  453.         break;
  454.  
  455.         case T_PRIVVIO:
  456.         exc = EXC_BAD_INSTRUCTION;
  457.         code = EXC_SUN3_PRIVILEGE_VIOLATION;
  458.         break;
  459.  
  460.         case T_COPROCERR:        /* coprocessor protocol error */
  461.         /*
  462.          * Dump out obnoxious info to warn user
  463.          * that something isn`t right w/ the 68881
  464.          */
  465.         showregs("USER COPROCESSOR PROTOCOL ERROR", type, regs, be);
  466.  
  467.         exc = EXC_BAD_INSTRUCTION;
  468.         code = EXC_SUN3_COPROCESSOR;
  469.         break;
  470.  
  471.         case T_M_BADTRAP:        /* (some) undefined trap */
  472.         case T_ILLINST:        /* illegal instruction fault */
  473.         exc = EXC_BAD_INSTRUCTION;
  474.         code = regs->vector;
  475.         break;
  476.  
  477.         case T_M_FLOATERR:        /* (some) floating error trap */
  478.         case T_ZERODIV:        /* divide by zero */
  479.         code = regs->vector;
  480.         if (code == EXC_SUN3_FLT_BSUN ||
  481.             code == EXC_SUN3_FLT_OPERAND_ERROR) {
  482.             exc = EXC_BAD_INSTRUCTION;
  483.         }
  484.         else {
  485.             exc = EXC_ARITHMETIC;
  486.         }
  487.         break;
  488.  
  489.         case T_CHKINST:        /* CHK [CHK2] instruction */
  490.         case T_TRAPV:        /* TRAPV [cpTRAPcc TRAPcc] instr */
  491.         exc = EXC_SOFTWARE;
  492.         code = regs->vector;
  493.         break;
  494.  
  495.         case T_BUSERR:
  496.         /*
  497.          * User bus error.  Try to handle FPA, then pagefault.
  498.          */
  499.  
  500.         if (be & BE_TIMEOUT)
  501.             DELAY(2000);    /* allow for refresh recovery time */
  502.  
  503.         /*
  504.          * Copy the "rerun" bits to the "fault" bits.
  505.          *
  506.          * This is what is going on here (don`t believe
  507.          * the 2nd edition 68020 description in section
  508.          * 6.4.1, it is full of errors).  A rerun bit
  509.          * being on means that the prefetch failed.  A
  510.          * fault bit being on means the processor tried
  511.          * to use bad prefetch data.  Upon return via
  512.          * the RTE instruction, the `20 will retry the
  513.          * instruction access only if BOTH the rerun and
  514.          * the corresponding fault bit is on.
  515.          *
  516.          * We need to do guarantee that any time we have a
  517.          * fault that we have actually just run the cycle,
  518.          * otherwise the current external state (i.e. the
  519.          * bus error register) might not anything to do with
  520.          * what really happened to cause the prefetch to fail.
  521.          * For example the prefetch might have occured previous
  522.          * to an earlier bus error exception whose handling
  523.          * might have resolved the prefetch problem.  Thus by
  524.          * copying the "rerun" bits, we force the `20 to rerun
  525.          * every previously faulted prefetch upon return from
  526.          * this bus error.  This way we are guaranteed that we
  527.          * never get a "bogus" `20 internal bus error when it
  528.          * attempts to use a previously faulted prefetch.  On
  529.          * the downside, this hack might make the kernel fix up
  530.          * a prefetch fault that the `20 was not going to use.
  531.          * What we really need is a ``do not know anything about
  532.          * a prefetch`` bit.  If we had something like that then 
  533.          * the `20 could know enough to rerun the prefetch, but
  534.          * only if it turns out that it really needs it.
  535.          *
  536.          * RISC does have its advantages.
  537.          *
  538.          * N.B.  This code depends on not having an executable
  539.          * where the last instruction in the text segment is
  540.          * too close the end of a page.  We do not want to get
  541.          * ourselves in trouble trying to fix up a fault beyond
  542.          * the end of the text segment.  But because the loader
  543.          * already pads out by an additional page when it sees
  544.          * this problem due to microcode bugs with the first
  545.          * year or so worth of 68020 chips, we should not get
  546.          * in trouble here.
  547.          */
  548.  
  549.         switch (regs->stkfmt) {
  550.             case SF_MEDIUM:
  551.             {
  552.             struct bei_medium *beip =
  553.                 (struct bei_medium *)(regs+1);
  554.  
  555.             besize = sizeof (struct bei_medium);
  556.             beip->bei_faultc = beip->bei_rerunc;
  557.             beip->bei_faultb = beip->bei_rerunb;
  558.             break;
  559.             }
  560.             case SF_LONGB:
  561.             {
  562.             struct bei_longb *beip =
  563.                 (struct bei_longb *)(regs+1);
  564.  
  565.             besize = sizeof (struct bei_longb);
  566.             beip->bei_faultc = beip->bei_rerunc;
  567.             beip->bei_faultb = beip->bei_rerunb;
  568.             break;
  569.             }
  570.             default:
  571.             panic("bad bus error stack format");
  572.         }
  573.  
  574. #if NFPA > 0
  575.         if (fpa_exist && (be & BE_FPAENA) && fpa_state != FPA_DISABLED)
  576.             if (fpa_init(thread) == 0)
  577.             return(0);
  578.         if (be & (BE_FPAENA | BE_FPABERR)) {
  579.             /*
  580.              * FPA exception from FPA board.
  581.              * We save bus error PC in pcb_fpa_pc and save the
  582.              * current bus error information at pcb_fpa_fmtptr.
  583.              * Other information saved are: (high core) the bus
  584.              * error exception frame, a short of frame type and
  585.              * vector offset, the struct regs, a long of AST bits
  586.              * of flag, short indicating the size of this area,
  587.              * and a short indicating the size to restore to
  588.              * the kernel stack.
  589.              * The exception frame is returned to 68020 (by rte)
  590.              * when pcb_fpa_pc equals PC in syscall: of
  591.              * locore.s.
  592.              */
  593.             struct fpa_stack *fp;
  594.  
  595.             code = (be & BE_FPAENA) ? EXC_SUN3_FLT_FPA_ENABLE
  596.                         : EXC_SUN3_FLT_FPA_ERROR;
  597.  
  598.             if (pcb->pcb_fpa_fmtptr == NULL) {
  599.             /* First FPA exception, alloc space */
  600.             (void) kmem_alloc_wired(kernel_map,
  601.                         (vm_offset_t *) &fp,
  602.                         sizeof (struct fpa_stack));
  603.             pcb->pcb_fpa_fmtptr = fp;
  604.             fp->fpst_alloc_size = sizeof (struct fpa_stack);
  605.             }
  606.             else
  607.             fp = pcb->pcb_fpa_fmtptr;
  608.  
  609.             pcb->pcb_fpa_pc = regs->pc;
  610.             fp->fpst_ast_bits = pcb->flag & AST_CLR;
  611.             /*
  612.              * Current kernel stack: (high core)exception stk,
  613.              * a short(stkfmt+vector offset), regs(low core).
  614.              * We save regs, a short(stkfmt+vector offset),
  615.              * and the exception stack.
  616.              */
  617.             fp->fpst_save_size = sizeof (struct regs)
  618.                 + sizeof (short) + besize;
  619.             bcopy((char *)regs, (char *)&fp->fpst_regs,
  620.               (unsigned)fp->fpst_save_size);
  621.  
  622.             exc = EXC_ARITHMETIC;
  623.             break;
  624.         }
  625. #endif NFPA > 0
  626.  
  627.         if (be & ~(BE_INVALID|BE_PROTERR)){
  628.             /*
  629.              * Some other error indicated in the bus error
  630.              * invalid so there is nothing we can do now.
  631.              */
  632.         }
  633.         else if (regs->stkfmt == SF_MEDIUM) {
  634.             struct bei_medium *beip =
  635.             (struct bei_medium *)(regs + 1);
  636.  
  637. #if    NFPA > 0
  638.             if (fpa_exist && fpa_state != FPA_DISABLED &&
  639.             (char *)beip->bei_fault >= (char *)fpa && 
  640.             (char *)beip->bei_fault <
  641.                 (char *)fpa + sizeof(struct fpa_device))
  642.  
  643.             if (fpa_init(thread) == 0)
  644.                 return(0);            
  645. #endif    NFPA > 0
  646.             if ((bedebug && (beip->bei_faultb || beip->bei_faultc))
  647.                 || (bedebug > 1 && beip->bei_fault))
  648.             printf("medium fault b %d %x, c %d %x, d %d %x\n",
  649.                     beip->bei_faultb, regs->pc + 4,
  650.                     beip->bei_faultc, regs->pc + 2,
  651.                     beip->bei_dfault, beip->bei_fault);
  652.  
  653.             if (beip->bei_dfault) {
  654.             user_page_fault((vm_offset_t)beip->bei_fault,
  655.                     beip->bei_rw,
  656.                     regs);
  657.             /*NOTREACHED*/
  658.             }
  659.             else if (beip->bei_faultc) {
  660.             user_page_fault((vm_offset_t)(regs->pc+2),
  661.                     TRUE,
  662.                     regs);
  663.             /*NOTREACHED*/
  664.             }
  665.             else if (beip->bei_faultb) {
  666.             user_page_fault((vm_offset_t)(regs->pc+4),
  667.                     TRUE,
  668.                     regs);
  669.             /*NOTREACHED*/
  670.             }
  671.         }
  672.         else {
  673.             struct bei_longb *beip =
  674.             (struct bei_longb *)(regs + 1);
  675.  
  676. #if    NFPA > 0
  677.             if (fpa_exist && fpa_state != FPA_DISABLED &&
  678.             (char *)beip->bei_fault >= (char *)fpa && 
  679.             (char *)beip->bei_fault <
  680.                 (char *)fpa + sizeof(struct fpa_device))
  681.  
  682.             if (fpa_init(thread) == 0)
  683.                 return(0);            
  684. #endif    NFPA > 0
  685.             if ((bedebug && (beip->bei_faultb || beip->bei_faultc))
  686.                 || (bedebug > 1 && beip->bei_fault))
  687.             printf("long fault b %d %x, c %d %x, d %d %x\n",
  688.                     beip->bei_faultb, beip->bei_stageb,
  689.                     beip->bei_faultc, beip->bei_stageb-2,
  690.                     beip->bei_dfault, beip->bei_fault);
  691.  
  692.             if (beip->bei_dfault) {
  693.             user_page_fault((vm_offset_t)beip->bei_fault,
  694.                     beip->bei_rw,
  695.                     regs);
  696.             /*NOTREACHED*/
  697.             }
  698.             else if (beip->bei_faultc) {
  699.             user_page_fault((vm_offset_t)(beip->bei_stageb-2),
  700.                     TRUE,
  701.                     regs);
  702.             /*NOTREACHED*/
  703.             }
  704.             else if (beip->bei_faultb) {
  705.             user_page_fault((vm_offset_t)beip->bei_stageb,
  706.                     TRUE,
  707.                     regs);
  708.             /*NOTREACHED*/
  709.             }
  710.         }
  711.         if (tudebug)
  712.             showregs("USER BUS ERROR", type, regs, be);
  713.  
  714.         exc = EXC_BAD_ACCESS;
  715.         break;
  716.  
  717.         case T_TRACE:
  718.         {
  719.         int    s, r;
  720.  
  721. #if    MACH_KDB
  722.         if (pcb->flag & TRACE_KDB) {
  723.             /*
  724.              * Trap to kernel debugger.
  725.              */
  726.             pcb->flag &= ~TRACE_KDB;
  727.             (void) kdb_trap(T_TRACE, regs);
  728.             return (0);
  729.         }
  730. #endif    MACH_KDB
  731.         s = splhigh();
  732.  
  733.         r = pcb->flag & AST_CLR;
  734.         pcb->flag &= ~AST_CLR;
  735.  
  736.         if (r & TRACE_AST) {
  737.             /*
  738.              * Tracing for AST - may also be tracing for
  739.              * user.
  740.              */
  741.             if ((r & TRACE_USER) == 0) {
  742.             regs->sr &= ~SR_TRACE;
  743.             ast_taken();
  744.             /* back at spl0 */
  745.             return (0);
  746.             }
  747.             /*
  748.              * User-mode trace takes priority over AST.
  749.              * We`ll catch the AST when exception blocks.
  750.              */
  751.         }
  752.         splx(s);
  753.  
  754.         exc = EXC_BREAKPOINT;
  755.         code = EXC_SUN3_TRACE;
  756.         break;
  757.         }
  758.  
  759.         case T_BRKPT:
  760.         exc = EXC_BREAKPOINT;
  761.         code = EXC_SUN3_BREAKPOINT;
  762.         break;
  763.  
  764.         case T_EMU1010:        /* 1010 emulator trap */
  765.         case T_EMU1111:        /* 1111 emulator trap */
  766.         exc = EXC_EMULATION;
  767.         code = regs->vector;
  768.         break;
  769.     }
  770.  
  771.     /*
  772.      * Exception occured - clear pending trace.
  773.      */
  774.     pcb->flag &= ~TRACE_PENDING;
  775.  
  776. #if    MACH_KDB
  777.     if (debug_all_traps_with_kdb) {
  778.         (void) kdb_trap(type, regs);
  779.         thread_exception_return();
  780.         /*NOTREACHED*/
  781.     }
  782. #endif    MACH_KDB
  783.     exception(exc, code, subcode);
  784.     /*NOTREACHED*/
  785. }
  786.  
  787. void
  788. thread_exception_return()
  789. {
  790.     register pcb_t        pcb = current_thread()->pcb;
  791.     int    besize = 0;
  792.  
  793.     if (pcb->discard_frame) {
  794.         switch (pcb->user_regs->stkfmt) {
  795.         case SF_MEDIUM:
  796.             besize = sizeof(struct bei_medium);
  797.             break;
  798.         case SF_LONGB:
  799.             besize = sizeof(struct bei_longb);
  800.             break;
  801.         default:
  802.             break;
  803.         }
  804.     }
  805.  
  806.     Thread_exception_return(besize);
  807.     /*NOTREACHED*/
  808. }
  809.  
  810.  
  811. void
  812. user_page_fault(faultaddr, read_fault, regs)
  813.     register vm_offset_t faultaddr;
  814.     int        read_fault;
  815.     register struct mc68020_saved_state *regs;
  816. {
  817.     register thread_t    thread = current_thread();
  818.     register pcb_t        pcb = thread->pcb;
  819.  
  820.     pcb->fault_addr = faultaddr;
  821.     pcb->fault_type = (read_fault) ? VM_PROT_READ
  822.                        : VM_PROT_READ | VM_PROT_WRITE,
  823.  
  824.     (void) vm_fault(thread->task->map,
  825.             trunc_page(faultaddr),
  826.             pcb->fault_type,
  827.             FALSE,
  828.             FALSE,
  829.             user_page_fault_continue);
  830.     /*NOTREACHED*/
  831. }
  832.  
  833. void
  834. user_page_fault_continue(result)
  835.     kern_return_t    result;
  836. {
  837.     register thread_t    thread = current_thread();
  838.     register pcb_t        pcb = thread->pcb;
  839.     register struct mc68020_saved_state *regs = pcb->user_regs;
  840.  
  841.     if (result == KERN_SUCCESS) {
  842. #if    MACH_KDB
  843.         if (db_watchpoint_list &&
  844.         db_watchpoints_inserted &&
  845.         (pcb->fault_type & VM_PROT_WRITE))
  846.         {
  847.         if (db_find_watchpoint(thread->task->map,
  848.                        pcb->fault_addr,
  849.                        regs))
  850.             kdb_trap(T_WATCHPOINT, regs);
  851.         }
  852. #endif    MACH_KDB
  853.         /*
  854.          *    If halt was requested, stop here instead of
  855.          *    waiting for instruction to complete.  The page
  856.          *    is still missing, and we`ll never finish.
  857.          */
  858.         while (thread_should_halt(thread))
  859.         thread_halt_self();
  860.  
  861.         thread_exception_return();
  862.         /*NOTREACHED*/
  863.     }
  864.     exception(EXC_BAD_ACCESS, result, pcb->fault_addr);
  865.     /*NOTREACHED*/
  866. }
  867.  
  868.  
  869. kern_return_t
  870. kernel_page_fault(faultaddr, read_fault, regs)
  871.     register vm_offset_t faultaddr;
  872.     int        read_fault;
  873.     register struct mc68020_saved_state *regs;
  874. {
  875.     register vm_map_t    map;
  876.     kern_return_t        result;
  877.     register thread_t    thread = current_thread();
  878.     vm_prot_t        fault_type;
  879.  
  880.     fault_type = (read_fault) ? VM_PROT_READ
  881.                   : VM_PROT_READ|VM_PROT_WRITE;
  882.  
  883.     /*
  884.      * If the current map is a submap of the kernel map,
  885.      * and the address is within that map, fault on that
  886.      * map.  If we wait until vm_fault (vm_map_lookup) to
  887.      * look for the submap, we may deadlock on the kernel
  888.      * map lock.
  889.      */
  890.     if (thread == THREAD_NULL)
  891.         map = kernel_map;
  892.     else {
  893.         map = thread->task->map;
  894.         if (faultaddr < vm_map_min(map) ||
  895.         faultaddr >= vm_map_max(map))
  896.         map = kernel_map;
  897.     }
  898.  
  899.     result = vm_fault(map,
  900.             trunc_page(faultaddr),
  901.             fault_type,
  902.             FALSE,
  903.             FALSE,
  904.             (void (*)()) 0);
  905.  
  906. #if    MACH_KDB
  907.     if ((result == KERN_SUCCESS) &&
  908.         db_watchpoint_list &&
  909.         db_watchpoints_inserted &&
  910.         !read_fault)
  911.     {
  912.         if (db_find_watchpoint(map, faultaddr, regs))
  913.         kdb_trap(T_WATCHPOINT, regs);
  914.         else {
  915.         if ((regs->sr & SR_T1) && (thread != THREAD_NULL)) {
  916.             (void) spl7();
  917.             thread->pcb->flag |= TRACE_KDB;
  918.         }
  919.         }
  920.     }
  921. #endif    MACH_KDB
  922.  
  923.     return(result);
  924. }
  925.  
  926. int syscall_error(regs, exc, code, subcode)
  927.     struct    mc68020_saved_state *regs;
  928.     int    exc, code, subcode;
  929. {
  930.     register thread_t    thread = current_thread();
  931.     register pcb_t        pcb;
  932.  
  933.     if (thread == 0)
  934.         halt("syscall error in boot phase");
  935.     pcb = thread->pcb;
  936.     pcb->user_regs = regs;
  937.  
  938.     assert(USERMODE(regs->sr));
  939.  
  940.     /*
  941.      * Exception occured - clear pending trace.    XXX
  942.      */
  943.     pcb->flag &= ~TRACE_PENDING;
  944.  
  945.     exception(exc, code, subcode);
  946.     /*NOTREACHED*/
  947. }
  948.  
  949. /*
  950.  * Print out a traceback for kernel traps
  951.  */
  952. traceback(afp, sp)
  953.     long afp, sp;
  954. {
  955.     unsigned int    tospage = btoc(sp);
  956.     struct frame *    fp = (struct frame *)afp;
  957.     static int    done = 0;
  958.  
  959.     extern char *    panicstr;
  960.  
  961.     if (panicstr && done++ > 0)
  962.         return;
  963.  
  964.     printf("Begin traceback...fp = %x, sp = %x\n", fp, sp);
  965.     while (btoc(fp) == tospage) {
  966.         if (fp == fp->fr_savfp) {
  967.         printf("FP loop at %x", fp);
  968.         break;
  969.         }
  970.         printf("Called from %x, fp=%x, args=%x %x %x %x\n",
  971.             fp->fr_savpc, fp->fr_savfp,
  972.             fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3]);
  973.         fp = fp->fr_savfp;
  974.     }
  975.     printf("End traceback...\n");
  976.     DELAY(2000000);
  977. }
  978.  
  979. showregs(str, type, regs, be)
  980.     char *    str;
  981.     int    type;
  982.     struct mc68020_saved_state *regs;
  983.     int    be;
  984. {
  985.     int    s, fcode, accaddr;
  986.     char *    why;
  987.  
  988.     s = spl7();
  989.  
  990.     printf("trap address 0x%x, pc = %x, sr = %x, stkfmt %x, context %x\n",
  991.            regs->vector,
  992.            regs->pc,
  993.            regs->sr,
  994.            regs->stkfmt,
  995.            getcontext());
  996.  
  997.     if (type == T_BUSERR)
  998.         printf("Bus Error Reg %b\n", be, BUSERR_BITS);
  999.     if (type == T_BUSERR || type == T_ADDRERR) {
  1000.         switch (regs->stkfmt) {
  1001.         case SF_MEDIUM:
  1002.         {
  1003.             struct bei_medium *beip =
  1004.             (struct bei_medium *)(regs + 1);
  1005.  
  1006.             fcode = beip->bei_fcode;
  1007.             if (beip->bei_dfault) {
  1008.             why = "data";
  1009.             accaddr = beip->bei_fault;
  1010.             }
  1011.             else if (beip->bei_faultc) {
  1012.             why = "stage c";
  1013.             accaddr = regs->pc + 2;
  1014.             }
  1015.             else if (beip->bei_faultc) {
  1016.             why = "stage b";
  1017.             accaddr = regs->pc + 4;
  1018.             }
  1019.             else {
  1020.             why = "unknown";
  1021.             accaddr = 0;
  1022.             }
  1023.             printf("%s fault address %x faultc %d faultb %d ",
  1024.                why,
  1025.                accaddr,
  1026.                beip->bei_faultc,
  1027.                beip->bei_faultb);
  1028.             printf("dfault %d rw %d size %d fcode %d\n",
  1029.                beip->bei_dfault,
  1030.                beip->bei_rw,
  1031.                beip->bei_size,
  1032.                fcode);
  1033.             break;
  1034.         }
  1035.         case SF_LONGB:
  1036.         {
  1037.             struct bei_longb *beip =
  1038.             (struct bei_longb *)(regs + 1);
  1039.  
  1040.             fcode = beip->bei_fcode;
  1041.             if (beip->bei_dfault) {
  1042.             why = "data";
  1043.             accaddr = beip->bei_fault;
  1044.             }
  1045.             else if (beip->bei_faultc) {
  1046.             why = "stage c";
  1047.             accaddr = beip->bei_stageb - 2;
  1048.             }
  1049.             else if (beip->bei_faultc) {
  1050.             why = "stage b";
  1051.             accaddr = beip->bei_stageb;
  1052.             }
  1053.             else {
  1054.             why = "unknown";
  1055.             accaddr = 0;
  1056.             }
  1057.             printf("%s fault address %x faultc %d faultb %d ",
  1058.                why,
  1059.                accaddr,
  1060.                beip->bei_faultc,
  1061.                beip->bei_faultb);
  1062.             printf("dfault %d rw %d size %d fcode %d\n",
  1063.                beip->bei_dfault,
  1064.                beip->bei_rw,
  1065.                beip->bei_size,
  1066.                fcode);
  1067.             break;
  1068.         }
  1069.         default:
  1070.             panic("bad bus error stack format");
  1071.         }
  1072.         if (fcode == FC_SD || fcode == FC_SP) {
  1073.         printf("KERNEL MODE\n");
  1074.         printf("page map %x\n", getpgmap((caddr_t)accaddr));
  1075.         }
  1076.     }
  1077.     printf("D0-D7  %x %x %x %x %x %x %x %x\n",
  1078.         regs->d0,
  1079.         regs->d1,
  1080.         regs->d2,
  1081.         regs->d3,
  1082.         regs->d4,
  1083.         regs->d5,
  1084.         regs->d6,
  1085.         regs->d7);
  1086.     printf("A0-A7  %x %x %x %x %x %x %x %x\n",
  1087.         regs->a0,
  1088.         regs->a1,
  1089.         regs->a2,
  1090.         regs->a3,
  1091.         regs->a4,
  1092.         regs->a5,
  1093.         regs->a6,
  1094.         regs->sp);
  1095.     DELAY(2000000);
  1096.     splx(s);
  1097. }
  1098.  
  1099.