Home | History | Annotate | Line # | Download | only in mips
      1 /*	$NetBSD: trap.c,v 1.265 2023/10/24 18:08:16 andvar Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988 University of Utah.
      5  * Copyright (c) 1992, 1993
      6  *	The Regents of the University of California.  All rights reserved.
      7  *
      8  * This code is derived from software contributed to Berkeley by
      9  * the Systems Programming Group of the University of Utah Computer
     10  * Science Department and Ralph Campbell.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. Neither the name of the University nor the names of its contributors
     21  *    may be used to endorse or promote products derived from this software
     22  *    without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  *
     36  * from: Utah Hdr: trap.c 1.32 91/04/06
     37  *
     38  *	@(#)trap.c	8.5 (Berkeley) 1/11/94
     39  */
     40 
     41 #include <sys/cdefs.h>
     42 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.265 2023/10/24 18:08:16 andvar Exp $");
     43 
     44 #include "opt_cputype.h"	/* which mips CPU levels do we support? */
     45 #include "opt_ddb.h"
     46 #include "opt_dtrace.h"
     47 #include "opt_kgdb.h"
     48 #include "opt_multiprocessor.h"
     49 
     50 #include <sys/param.h>
     51 #include <sys/systm.h>
     52 #include <sys/kernel.h>
     53 #include <sys/cpu.h>
     54 #include <sys/proc.h>
     55 #include <sys/ras.h>
     56 #include <sys/signalvar.h>
     57 #include <sys/syscall.h>
     58 #include <sys/buf.h>
     59 #include <sys/ktrace.h>
     60 #include <sys/kauth.h>
     61 #include <sys/atomic.h>
     62 
     63 #include <mips/cache.h>
     64 #include <mips/locore.h>
     65 #include <mips/mips_opcode.h>
     66 
     67 #include <uvm/uvm.h>
     68 
     69 #include <mips/trap.h>
     70 #include <mips/reg.h>
     71 #include <mips/regnum.h>			/* symbolic register indices */
     72 #include <mips/pcb.h>
     73 #include <mips/pte.h>
     74 #include <mips/psl.h>
     75 #include <mips/userret.h>
     76 
     77 #ifdef DDB
     78 #include <machine/db_machdep.h>
     79 #include <ddb/db_sym.h>
     80 #endif
     81 
     82 #ifdef KGDB
     83 #include <sys/kgdb.h>
     84 #endif
     85 
     86 #ifdef KDTRACE_HOOKS
     87 #include <sys/dtrace_bsd.h>
     88 
     89 /* Not used for now, but needed for dtrace/fbt modules */
     90 dtrace_doubletrap_func_t	dtrace_doubletrap_func = NULL;
     91 dtrace_trap_func_t		dtrace_trap_func = NULL;
     92 
     93 int				(* dtrace_invop_jump_addr)(struct trapframe *);
     94 #endif /* KDTRACE_HOOKS */
     95 
     96 const char * const trap_names[] = {
     97 	"external interrupt",
     98 	"TLB modification",
     99 	"TLB miss (load or instr. fetch)",
    100 	"TLB miss (store)",
    101 	"address error (load or I-fetch)",
    102 	"address error (store)",
    103 	"bus error (I-fetch)",
    104 	"bus error (load or store)",
    105 	"system call",
    106 	"breakpoint",
    107 	"reserved instruction",
    108 	"coprocessor unusable",
    109 	"arithmetic overflow",
    110 	"r4k trap/r3k reserved 13",
    111 	"r4k virtual coherency instruction/r3k reserved 14",
    112 	"r4k floating point/ r3k reserved 15",
    113 	"mips NMI",
    114 	"reserved 17",
    115 	"mipsNN cp2 exception",
    116 	"mipsNN TLBRI",
    117 	"mipsNN TLBXI",
    118 	"reserved 21",
    119 	"mips64 MDMX",
    120 	"r4k watch",
    121 	"mipsNN machine check",
    122 	"mipsNN thread",
    123 	"DSP exception",
    124 	"reserved 27",
    125 	"reserved 28",
    126 	"reserved 29",
    127 	"mipsNN cache error",
    128 	"r4000 virtual coherency data",
    129 };
    130 
    131 void trap(uint32_t, uint32_t, vaddr_t, vaddr_t, struct trapframe *);
    132 void ast(void);
    133 
    134 #ifdef TRAP_SIGDEBUG
    135 static void sigdebug(const struct trapframe *, const ksiginfo_t *, int,
    136     vaddr_t);
    137 #define SIGDEBUG(a, b, c, d) sigdebug(a, b, c, d)
    138 #else
    139 #define SIGDEBUG(a, b, c, d)
    140 #endif
    141 
    142 /*
    143  * fork syscall returns directly to user process via lwp_trampoline(),
    144  * which will be called the very first time when child gets running.
    145  */
    146 void
    147 md_child_return(struct lwp *l)
    148 {
    149 	struct trapframe *utf = l->l_md.md_utf;
    150 
    151 	utf->tf_regs[_R_V0] = 0;
    152 	utf->tf_regs[_R_V1] = 1;
    153 	utf->tf_regs[_R_A3] = 0;
    154 	userret(l);
    155 }
    156 
    157 #ifdef MIPS3_PLUS
    158 #define TRAPTYPE(x) (((x) & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT)
    159 #else
    160 #define TRAPTYPE(x) (((x) & MIPS1_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT)
    161 #endif
    162 #define KERNLAND_P(x) ((intptr_t)(x) < 0)
    163 
    164 /*
    165  * Trap is called from locore to handle most types of processor traps.
    166  * System calls are broken out for efficiency.  MIPS can handle software
    167  * interrupts as a part of real interrupt processing.
    168  */
    169 void
    170 trap(uint32_t status, uint32_t cause, vaddr_t vaddr, vaddr_t pc,
    171     struct trapframe *tf)
    172 {
    173 	struct lwp * const l = curlwp;
    174 	struct proc * const p = curproc;
    175 	struct trapframe * const utf = l->l_md.md_utf;
    176 	struct pcb * const pcb = lwp_getpcb(l);
    177 	vm_prot_t ftype;
    178 	ksiginfo_t ksi;
    179 	extern void fswintrberr(void);
    180 	void *onfault;
    181 	InstFmt insn;
    182 	uint32_t instr;
    183 	int type;
    184 	int rv = 0;
    185 
    186 	KSI_INIT_TRAP(&ksi);
    187 
    188 	curcpu()->ci_data.cpu_ntrap++;
    189 	if (CPUISMIPS3 && (status & MIPS3_SR_NMI)) {
    190 		type = T_NMI;
    191 	} else {
    192 		type = TRAPTYPE(cause);
    193 	}
    194 	if (USERMODE(status)) {
    195 		tf = utf;
    196 		type |= T_USER;
    197 	}
    198 
    199 #ifdef KDTRACE_HOOKS
    200 	/*
    201 	 * A trap can occur while DTrace executes a probe. Before
    202 	 * executing the probe, DTrace blocks re-scheduling and sets
    203 	 * a flag in its per-cpu flags to indicate that it doesn't
    204 	 * want to fault. On returning from the probe, the no-fault
    205 	 * flag is cleared and finally re-scheduling is enabled.
    206 	 *
    207 	 * If the DTrace kernel module has registered a trap handler,
    208 	 * call it and if it returns non-zero, assume that it has
    209 	 * handled the trap and modified the trap frame so that this
    210 	 * function can return normally.
    211 	 */
    212 	/*
    213 	 * XXXDTRACE: add pid probe handler here (if ever)
    214 	 */
    215 	if (!USERMODE(status)) {
    216 		if ((dtrace_trap_func != NULL) &&
    217 		    ((*dtrace_trap_func)(tf, type) != 0)) {
    218 			return;
    219 		}
    220 	}
    221 #endif /* KDTRACE_HOOKS */
    222 
    223 	switch (type) {
    224 	default:
    225 	dopanic:
    226 		(void)splhigh();
    227 
    228 		/*
    229 		 * use snprintf to allow a single, idempotent, readable printf
    230 		 */
    231 		char strbuf[256], *str = strbuf;
    232 		int n, sz = sizeof(strbuf);
    233 
    234 		n = snprintf(str, sz, "pid %d(%s): ", p->p_pid, p->p_comm);
    235 		sz -= n;
    236 		str += n;
    237 		n = snprintf(str, sz, "trap: cpu%d, %s in %s mode\n",
    238 			cpu_number(), trap_names[TRAPTYPE(cause)],
    239 			USERMODE(status) ? "user" : "kernel");
    240 		sz -= n;
    241 		str += n;
    242 		n = snprintf(str, sz, "status=%#x, cause=%#x, epc=%#"
    243 			PRIxVADDR ", vaddr=%#" PRIxVADDR "\n",
    244 			status, cause, pc, vaddr);
    245 		sz -= n;
    246 		str += n;
    247 		if (USERMODE(status)) {
    248 			KASSERT(tf == utf);
    249 			n = snprintf(str, sz, "frame=%p usp=%#" PRIxREGISTER
    250 			    " ra=%#" PRIxREGISTER "\n",
    251 			    tf, tf->tf_regs[_R_SP], tf->tf_regs[_R_RA]);
    252 			sz -= n;
    253 			str += n;
    254 		} else {
    255 			n = snprintf(str, sz, "tf=%p ksp=%p ra=%#"
    256 			    PRIxREGISTER " ppl=%#x\n", tf,
    257 			    type == T_NMI
    258 				? (void*)(uintptr_t)tf->tf_regs[_R_SP]
    259 				: tf+1,
    260 			    tf->tf_regs[_R_RA], tf->tf_ppl);
    261 			sz -= n;
    262 			str += n;
    263 		}
    264 		printf("%s", strbuf);
    265 
    266 		if (type == T_BUS_ERR_IFETCH || type == T_BUS_ERR_LD_ST)
    267 			(void)(*mips_locoresw.lsw_bus_error)(cause);
    268 
    269 #if defined(DDB)
    270 		kdb_trap(type, &tf->tf_registers);
    271 		/* XXX force halt XXX */
    272 #elif defined(KGDB)
    273 		{
    274 			extern mips_reg_t kgdb_cause, kgdb_vaddr;
    275 			struct reg *regs = &ddb_regs;
    276 			kgdb_cause = cause;
    277 			kgdb_vaddr = vaddr;
    278 
    279 			/*
    280 			 * init global ddb_regs, used in db_interface.c routines
    281 			 * shared between ddb and gdb. Send ddb_regs to gdb so
    282 			 * that db_machdep.h macros will work with it, and
    283 			 * allow gdb to alter the PC.
    284 			 */
    285 			db_set_ddb_regs(type, &tf->tf_registers);
    286 			PC_BREAK_ADVANCE(regs);
    287 			if (kgdb_trap(type, regs)) {
    288 				tf->tf_regs[_R_PC] = regs->r_regs[_R_PC];
    289 				return;
    290 			}
    291 		}
    292 #else
    293 		panic("trap");
    294 #endif
    295 		/*NOTREACHED*/
    296 	case T_TLB_MOD:
    297 	case T_TLB_MOD+T_USER: {
    298 		const bool user_p = (type & T_USER) || !KERNLAND_P(vaddr);
    299 		pmap_t pmap = user_p
    300 		    ? p->p_vmspace->vm_map.pmap
    301 		    : pmap_kernel();
    302 
    303 		kpreempt_disable();
    304 
    305 		pt_entry_t * const ptep = pmap_pte_lookup(pmap, vaddr);
    306 		if (!ptep)
    307 			panic("%ctlbmod: %#"PRIxVADDR": no pte",
    308 			    user_p ? 'u' : 'k', vaddr);
    309 		pt_entry_t pte = *ptep;
    310 		if (!pte_valid_p(pte)) {
    311 			panic("%ctlbmod: %#"PRIxVADDR": invalid pte %#"PRIx32
    312 			    " @ ptep %p", user_p ? 'u' : 'k', vaddr,
    313 			    pte_value(pte), ptep);
    314 		}
    315 		if (pte_readonly_p(pte)) {
    316 			/* write to read only page */
    317 			ftype = VM_PROT_WRITE;
    318 			kpreempt_enable();
    319 			if (user_p) {
    320 				goto pagefault;
    321 			} else {
    322 				goto kernelfault;
    323 			}
    324 		}
    325 		UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
    326 		UVMHIST_LOG(maphist, "%ctlbmod(va=%#lx, pc=%#lx, tf=%#jx)",
    327 		    user_p ? 'u' : 'k', vaddr, pc, (uintptr_t)tf);
    328 		if (!pte_modified_p(pte)) {
    329 			pte |= mips_pg_m_bit();
    330 #ifdef MULTIPROCESSOR
    331 			atomic_or_32(ptep, mips_pg_m_bit());
    332 #else
    333 			*ptep = pte;
    334 #endif
    335 		}
    336 		// We got a TLB MOD exception so we must have a valid ASID
    337 		// and there must be a matching entry in the TLB.  So when
    338 		// we try to update it, we better have done it.
    339 		KASSERTMSG(pte_valid_p(pte), "%#"PRIx32, pte_value(pte));
    340 		vaddr = trunc_page(vaddr);
    341 		int ok = pmap_tlb_update_addr(pmap, vaddr, pte, 0);
    342 		kpreempt_enable();
    343 		if (ok != 1) {
    344 #if 0 /* PMAP_FAULTINFO? */
    345 			/*
    346 			 * Since we don't block interrupts here,
    347 			 * this can legitimately happen if we get
    348 			 * a TLB miss that's serviced in an interrupt
    349 			 * handler that happens to randomly evict the
    350 			 * TLB entry we're concerned about.
    351 			 */
    352 			printf("pmap_tlb_update_addr(%p,%#"
    353 			    PRIxVADDR",%#"PRIxPTE", 0) returned %d\n",
    354 			    pmap, vaddr, pte_value(pte), ok);
    355 #endif
    356 		}
    357 		paddr_t pa = pte_to_paddr(pte);
    358 		KASSERTMSG(uvm_pageismanaged(pa),
    359 		    "%#"PRIxVADDR" pa %#"PRIxPADDR, vaddr, pa);
    360 		pmap_set_modified(pa);
    361 		if (type & T_USER)
    362 			userret(l);
    363 		UVMHIST_LOG(maphist, " <-- done", 0, 0, 0, 0);
    364 		return; /* GEN */
    365 	}
    366 	case T_TLB_LD_MISS:
    367 	case T_TLB_ST_MISS:
    368 		ftype = (type == T_TLB_LD_MISS) ? VM_PROT_READ : VM_PROT_WRITE;
    369 		if (KERNLAND_P(vaddr))
    370 			goto kernelfault;
    371 		/*
    372 		 * It is an error for the kernel to access user space except
    373 		 * through the copyin/copyout routines.
    374 		 */
    375 		if (pcb->pcb_onfault == NULL) {
    376 			goto dopanic;
    377 		}
    378 		goto pagefault;
    379 	case T_TLB_LD_MISS+T_USER:
    380 		ftype = VM_PROT_READ;
    381 		goto pagefault;
    382 	case T_TLB_ST_MISS+T_USER:
    383 		ftype = VM_PROT_WRITE;
    384 	pagefault: {
    385 		const vaddr_t va = trunc_page(vaddr);
    386 		struct vmspace * const vm = p->p_vmspace;
    387 		struct vm_map * const map = &vm->vm_map;
    388 #ifdef PMAP_FAULTINFO
    389 		struct pcb_faultinfo * const pfi = &pcb->pcb_faultinfo;
    390 #endif
    391 
    392 		kpreempt_disable();
    393 #ifdef _LP64
    394 		/*
    395 		 * If the pmap has been activated and we allocated the segtab
    396 		 * for the low 4GB, seg0tab may still be NULL.  We can't
    397 		 * really fix this in pmap_enter (we can only update the local
    398 		 * cpu's cpu_info but not other cpu's) so we need to detect
    399 		 * and fix this here.
    400 		 */
    401 		struct cpu_info * const ci = curcpu();
    402 		if ((va >> XSEGSHIFT) == 0 &&
    403 		    __predict_false(ci->ci_pmap_user_seg0tab == NULL
    404 				&& ci->ci_pmap_user_segtab->seg_seg[0] != NULL)) {
    405 			ci->ci_pmap_user_seg0tab =
    406 			    ci->ci_pmap_user_segtab->seg_seg[0];
    407 			kpreempt_enable();
    408 			if (type & T_USER) {
    409 				userret(l);
    410 			}
    411 			return; /* GEN */
    412 		}
    413 #endif
    414 		KASSERT(KERNLAND_P(va) || curcpu()->ci_pmap_asid_cur != 0);
    415 		pmap_tlb_asid_check();
    416 		kpreempt_enable();
    417 
    418 #ifdef PMAP_FAULTINFO
    419 		if (p->p_pid == pfi->pfi_lastpid && va == pfi->pfi_faultaddr) {
    420 			if (++pfi->pfi_repeats > 4) {
    421 				tlb_asid_t asid = tlb_get_asid();
    422 				pt_entry_t *ptep = pfi->pfi_faultptep;
    423 				printf("trap: fault #%u (%s/%s) for %#"
    424 				    PRIxVADDR" (%#"PRIxVADDR") at pc %#"
    425 				    PRIxVADDR" curpid=%u/%u ptep@%p=%#"
    426 				    PRIxPTE")\n", pfi->pfi_repeats,
    427 				    trap_names[TRAPTYPE(cause)],
    428 				    trap_names[pfi->pfi_faulttype], va,
    429 				    vaddr, pc, map->pmap->pm_pai[0].pai_asid,
    430 				    asid, ptep, ptep ? pte_value(*ptep) : 0);
    431 				if (pfi->pfi_repeats >= 4) {
    432 					cpu_Debugger();
    433 				} else {
    434 					pfi->pfi_faulttype = TRAPTYPE(cause);
    435 				}
    436 			}
    437 		} else {
    438 			pfi->pfi_lastpid = p->p_pid;
    439 			pfi->pfi_faultaddr = va;
    440 			pfi->pfi_repeats = 0;
    441 			pfi->pfi_faultptep = NULL;
    442 			pfi->pfi_faulttype = TRAPTYPE(cause);
    443 		}
    444 #endif /* PMAP_FAULTINFO */
    445 
    446 		onfault = pcb->pcb_onfault;
    447 		pcb->pcb_onfault = NULL;
    448 		rv = uvm_fault(map, va, ftype);
    449 		pcb->pcb_onfault = onfault;
    450 
    451 #if defined(VMFAULT_TRACE)
    452 		if (!KERNLAND_P(va))
    453 			printf(
    454 			    "uvm_fault(%p (pmap %p), %#"PRIxVADDR
    455 			    " (%"PRIxVADDR"), %d) -> %d at pc %#"PRIxVADDR"\n",
    456 			    map, vm->vm_map.pmap, va, vaddr, ftype, rv, pc);
    457 #endif
    458 		/*
    459 		 * If this was a stack access we keep track of the maximum
    460 		 * accessed stack size.  Also, if vm_fault gets a protection
    461 		 * failure it is due to accessing the stack region outside
    462 		 * the current limit and we need to reflect that as an access
    463 		 * error.
    464 		 */
    465 		if ((void *)va >= vm->vm_maxsaddr) {
    466 			if (rv == 0)
    467 				uvm_grow(p, va);
    468 			else if (rv == EACCES)
    469 				rv = EFAULT;
    470 		}
    471 		if (rv == 0) {
    472 #ifdef PMAP_FAULTINFO
    473 			if (pfi->pfi_repeats == 0) {
    474 				pfi->pfi_faultptep =
    475 				    pmap_pte_lookup(map->pmap, va);
    476 			}
    477 			KASSERT(*(pt_entry_t *)pfi->pfi_faultptep);
    478 #endif
    479 			if (type & T_USER) {
    480 				userret(l);
    481 			}
    482 			return; /* GEN */
    483 		}
    484 		if ((type & T_USER) == 0)
    485 			goto copyfault;
    486 
    487 		KSI_INIT_TRAP(&ksi);
    488 		switch (rv) {
    489 		case EINVAL:
    490 			ksi.ksi_signo = SIGBUS;
    491 			ksi.ksi_code = BUS_ADRERR;
    492 			break;
    493 		case EACCES:
    494 			ksi.ksi_signo = SIGSEGV;
    495 			ksi.ksi_code = SEGV_ACCERR;
    496 			break;
    497 		case ENOMEM:
    498 			ksi.ksi_signo = SIGKILL;
    499 			printf("UVM: pid %d.%d (%s), uid %d killed: "
    500 			    "out of swap\n", p->p_pid, l->l_lid, p->p_comm,
    501 			    l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1);
    502 			break;
    503 		default:
    504 			ksi.ksi_signo = SIGSEGV;
    505 			ksi.ksi_code = SEGV_MAPERR;
    506 			break;
    507 		}
    508 		ksi.ksi_trap = type & ~T_USER;
    509 		ksi.ksi_addr = (void *)vaddr;
    510 		break; /* SIGNAL */
    511 	}
    512 	kernelfault: {
    513 		onfault = pcb->pcb_onfault;
    514 
    515 		pcb->pcb_onfault = NULL;
    516 		rv = uvm_fault(kernel_map, trunc_page(vaddr), ftype);
    517 		pcb->pcb_onfault = onfault;
    518 		if (rv == 0)
    519 			return; /* KERN */
    520 		goto copyfault;
    521 	}
    522 	case T_ADDR_ERR_LD:	/* misaligned access */
    523 	case T_ADDR_ERR_ST:	/* misaligned access */
    524 	case T_BUS_ERR_LD_ST:	/* BERR asserted to CPU */
    525 		onfault = pcb->pcb_onfault;
    526 		rv = EFAULT;
    527 	copyfault:
    528 		if (onfault == NULL) {
    529 			goto dopanic;
    530 		}
    531 		tf->tf_regs[_R_PC] = (intptr_t)onfault;
    532 		tf->tf_regs[_R_V0] = rv;
    533 		return; /* KERN */
    534 
    535 	case T_ADDR_ERR_LD+T_USER:	/* misaligned or kseg access */
    536 	case T_ADDR_ERR_ST+T_USER:	/* misaligned or kseg access */
    537 	case T_BUS_ERR_IFETCH+T_USER:	/* BERR asserted to CPU */
    538 	case T_BUS_ERR_LD_ST+T_USER:	/* BERR asserted to CPU */
    539 		ksi.ksi_trap = type & ~T_USER;
    540 		ksi.ksi_addr = (void *)vaddr;
    541 		if (KERNLAND_P(vaddr)) {
    542 			ksi.ksi_signo = SIGSEGV;
    543 			ksi.ksi_code = SEGV_MAPERR;
    544 		} else {
    545 			ksi.ksi_signo = SIGBUS;
    546 			if (type == T_BUS_ERR_IFETCH+T_USER
    547 			    || type == T_BUS_ERR_LD_ST+T_USER)
    548 				ksi.ksi_code = BUS_OBJERR;
    549 			else
    550 				ksi.ksi_code = BUS_ADRALN;
    551 		}
    552 		break; /* SIGNAL */
    553 
    554 	case T_BREAK:
    555 #ifdef KDTRACE_HOOKS
    556 		if ((dtrace_invop_jump_addr != NULL) &&
    557 		    (dtrace_invop_jump_addr(tf) == 0)) {
    558 			return;
    559 		}
    560 #endif /* KDTRACE_HOOKS */
    561 		/* FALLTHROUGH */
    562 	case T_WATCH:
    563 #if defined(DDB)
    564 		kdb_trap(type, &tf->tf_registers);
    565 		return;	/* KERN */
    566 #elif defined(KGDB)
    567 		{
    568 			extern mips_reg_t kgdb_cause, kgdb_vaddr;
    569 			struct reg *regs = &ddb_regs;
    570 			kgdb_cause = cause;
    571 			kgdb_vaddr = vaddr;
    572 
    573 			/*
    574 			 * init global ddb_regs, used in db_interface.c routines
    575 			 * shared between ddb and gdb. Send ddb_regs to gdb so
    576 			 * that db_machdep.h macros will work with it, and
    577 			 * allow gdb to alter the PC.
    578 			 */
    579 			db_set_ddb_regs(type, &tf->tf_registers);
    580 			PC_BREAK_ADVANCE(regs);
    581 			if (!kgdb_trap(type, regs))
    582 				printf("kgdb: ignored %s\n",
    583 				       trap_names[TRAPTYPE(cause)]);
    584 			else
    585 				tf->tf_regs[_R_PC] = regs->r_regs[_R_PC];
    586 
    587 			return;
    588 		}
    589 #else
    590 		goto dopanic;
    591 #endif
    592 	case T_BREAK+T_USER: {
    593 		/* compute address of break instruction */
    594 		vaddr_t va = pc + (cause & MIPS_CR_BR_DELAY ? sizeof(int) : 0);
    595 
    596 		/* read break instruction */
    597 		instr = mips_ufetch32((void *)va);
    598 		insn.word = instr;
    599 
    600 		if (l->l_md.md_ss_addr != va || instr != MIPS_BREAK_SSTEP) {
    601 			bool advance_pc = false;
    602 
    603 			ksi.ksi_trap = type & ~T_USER;
    604 			ksi.ksi_signo = SIGTRAP;
    605 			ksi.ksi_addr = (void *)va;
    606 			ksi.ksi_code = TRAP_BRKPT;
    607 
    608 			if ((insn.JType.op == OP_SPECIAL) &&
    609 			    (insn.RType.func == OP_BREAK)) {
    610 				int code = (insn.RType.rs << 5) | insn.RType.rt;
    611 				switch (code) {
    612 				case 0:
    613 					/* we broke, skip it to avoid infinite loop */
    614 					advance_pc = true;
    615 					break;
    616 				case MIPS_BREAK_INTOVERFLOW:
    617 					ksi.ksi_signo = SIGFPE;
    618 					ksi.ksi_code = FPE_INTOVF;
    619 					advance_pc = true;
    620 					break;
    621 				case MIPS_BREAK_INTDIVZERO:
    622 					ksi.ksi_signo = SIGFPE;
    623 					ksi.ksi_code = FPE_INTDIV;
    624 					advance_pc = true;
    625 					break;
    626 				default:
    627 					/* do nothing */
    628 					break;
    629 				}
    630 			}
    631 
    632 			if (advance_pc)
    633 				tf->tf_regs[_R_PC] += 4;
    634 			break;
    635 		}
    636 		/*
    637 		 * Restore original instruction and clear BP
    638 		 */
    639 		rv = mips_ustore32_isync((void *)va, l->l_md.md_ss_instr);
    640 		if (rv != 0) {
    641 			vaddr_t sa, ea;
    642 			sa = trunc_page(va);
    643 			ea = round_page(va + sizeof(int) - 1);
    644 			rv = uvm_map_protect(&p->p_vmspace->vm_map,
    645 				sa, ea, VM_PROT_ALL, false);
    646 			if (rv == 0) {
    647 				rv = mips_ustore32_isync((void *)va,
    648 				    l->l_md.md_ss_instr);
    649 				(void)uvm_map_protect(&p->p_vmspace->vm_map,
    650 				sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, false);
    651 			}
    652 		}
    653 		mips_icache_sync_all();		/* XXXJRT -- necessary? */
    654 		mips_dcache_wbinv_all();	/* XXXJRT -- necessary? */
    655 
    656 		if (rv != 0)
    657 			printf("Warning: can't restore instruction"
    658 			    " at %#"PRIxVADDR": 0x%x\n",
    659 			    l->l_md.md_ss_addr, l->l_md.md_ss_instr);
    660 		l->l_md.md_ss_addr = 0;
    661 		ksi.ksi_trap = type & ~T_USER;
    662 		ksi.ksi_signo = SIGTRAP;
    663 		ksi.ksi_addr = (void *)va;
    664 		ksi.ksi_code = TRAP_TRACE;
    665 		break; /* SIGNAL */
    666 	}
    667 	case T_DSP+T_USER:
    668 #if (MIPS32R2 + MIPS64R2) > 0
    669 		if (MIPS_HAS_DSP) {
    670 			dsp_load();
    671 			userret(l);
    672 			return; /* GEN */
    673 		}
    674 #endif /* (MIPS32R3 + MIPS64R2) > 0 */
    675 		/* FALLTHROUGH */
    676 	case T_RES_INST+T_USER:
    677 	case T_COP_UNUSABLE+T_USER:
    678 #if !defined(FPEMUL) && !defined(NOFPU)
    679 		if (__SHIFTOUT(cause, MIPS_CR_COP_ERR) == MIPS_CR_COP_ERR_CU1) {
    680 			fpu_load();          	/* load FPA */
    681 		} else
    682 #endif
    683 		{
    684 			mips_emul_inst(status, cause, pc, utf);
    685 		}
    686 		userret(l);
    687 		return; /* GEN */
    688 	case T_FPE+T_USER:
    689 #if defined(FPEMUL)
    690 		mips_emul_inst(status, cause, pc, utf);
    691 #elif !defined(NOFPU)
    692 		utf->tf_regs[_R_CAUSE] = cause;
    693 		mips_fpu_trap(pc, utf);
    694 #endif
    695 		userret(l);
    696 		return; /* GEN */
    697 	case T_OVFLOW+T_USER:
    698 	case T_TRAP+T_USER: {
    699 		/* compute address of trap/faulting instruction */
    700 		vaddr_t va = pc + (cause & MIPS_CR_BR_DELAY ? sizeof(int) : 0);
    701 		bool advance_pc = false;
    702 
    703 		/* read break instruction */
    704 		instr = mips_ufetch32((void *)va);
    705 		insn.word = instr;
    706 
    707 		ksi.ksi_trap = type & ~T_USER;
    708 		ksi.ksi_signo = SIGFPE;
    709 		ksi.ksi_addr = (void *)(intptr_t)pc /*utf->tf_regs[_R_PC]*/;
    710 		ksi.ksi_code = FPE_FLTOVF; /* XXX */
    711 
    712 		if ((insn.JType.op == OP_SPECIAL) &&
    713 		    (insn.RType.func == OP_TEQ)) {
    714 			int code = (insn.RType.rd << 5) | insn.RType.shamt;
    715 			switch (code) {
    716 			case MIPS_BREAK_INTOVERFLOW:
    717 				ksi.ksi_code = FPE_INTOVF;
    718 				advance_pc = true;
    719 				break;
    720 			case MIPS_BREAK_INTDIVZERO:
    721 				ksi.ksi_code = FPE_INTDIV;
    722 				advance_pc = true;
    723 				break;
    724 			}
    725 		}
    726 
    727 		/* XXX when else do we advance the PC? */
    728 		if (advance_pc)
    729 			tf->tf_regs[_R_PC] += 4;
    730 		break; /* SIGNAL */
    731 	 }
    732 	}
    733 	utf->tf_regs[_R_CAUSE] = cause;
    734 	utf->tf_regs[_R_BADVADDR] = vaddr;
    735 	SIGDEBUG(utf, &ksi, rv, pc);
    736 	(*p->p_emul->e_trapsignal)(l, &ksi);
    737 	if ((type & T_USER) == 0) {
    738 #ifdef DDB
    739 		Debugger();
    740 #endif
    741 		panic("trapsignal");
    742 	}
    743 	userret(l);
    744 	return;
    745 }
    746 
    747 /*
    748  * Handle asynchronous software traps.
    749  * This is called from MachUserIntr() either to deliver signals or
    750  * to make involuntary context switch (preemption).
    751  */
    752 void
    753 ast(void)
    754 {
    755 	struct lwp * const l = curlwp;
    756 	u_int astpending;
    757 
    758 	while ((astpending = l->l_md.md_astpending) != 0) {
    759 		//curcpu()->ci_data.cpu_nast++;
    760 		l->l_md.md_astpending = 0;
    761 
    762 #ifdef MULTIPROCESSOR
    763 		{
    764 			kpreempt_disable();
    765 			struct cpu_info * const ci = l->l_cpu;
    766 			if (ci->ci_tlb_info->ti_synci_page_bitmap != 0)
    767 				pmap_tlb_syncicache_ast(ci);
    768 			kpreempt_enable();
    769 		}
    770 #endif
    771 
    772 		if (l->l_pflag & LP_OWEUPC) {
    773 			l->l_pflag &= ~LP_OWEUPC;
    774 			ADDUPROF(l);
    775 		}
    776 
    777 		userret(l);
    778 
    779 		if (l->l_cpu->ci_want_resched) {
    780 			/*
    781 			 * We are being preempted.
    782 			 */
    783 			preempt();
    784 		}
    785 	}
    786 }
    787 
    788 
    789 /* XXX need to rewrite ancient comment XXX
    790  * This routine is called by procxmt() to single step one instruction.
    791  * We do this by storing a break instruction after the current instruction,
    792  * resuming execution, and then restoring the old instruction.
    793  */
    794 int
    795 mips_singlestep(struct lwp *l)
    796 {
    797 	struct trapframe * const tf = l->l_md.md_utf;
    798 	struct proc * const p = l->l_proc;
    799 	vaddr_t pc, va;
    800 	int rv;
    801 
    802 	if (l->l_md.md_ss_addr) {
    803 		printf("SS %s (%d): breakpoint already set at %#"PRIxVADDR"\n",
    804 			p->p_comm, p->p_pid, l->l_md.md_ss_addr);
    805 		return EFAULT;
    806 	}
    807 	pc = (vaddr_t)tf->tf_regs[_R_PC];
    808 	if (mips_ufetch32((void *)pc) != 0) { /* not a NOP instruction */
    809 		struct pcb * const pcb = lwp_getpcb(l);
    810 		va = mips_emul_branch(tf, pc, PCB_FSR(pcb), true);
    811 	} else {
    812 		va = pc + sizeof(int);
    813 	}
    814 
    815 	/*
    816 	 * We can't single-step into a RAS.  Check if we're in
    817 	 * a RAS, and set the breakpoint just past it.
    818 	 */
    819 	if (p->p_raslist != NULL) {
    820 		while (ras_lookup(p, (void *)va) != (void *)-1)
    821 			va += sizeof(int);
    822 	}
    823 
    824 	l->l_md.md_ss_addr = va;
    825 	l->l_md.md_ss_instr = mips_ufetch32((void *)va);
    826 	rv = mips_ustore32_isync((void *)va, MIPS_BREAK_SSTEP);
    827 	if (rv != 0) {
    828 		vaddr_t sa, ea;
    829 		sa = trunc_page(va);
    830 		ea = round_page(va + sizeof(int) - 1);
    831 		rv = uvm_map_protect(&p->p_vmspace->vm_map,
    832 		    sa, ea, VM_PROT_ALL, false);
    833 		if (rv == 0) {
    834 			rv = mips_ustore32_isync((void *)va,
    835 			    MIPS_BREAK_SSTEP);
    836 			(void)uvm_map_protect(&p->p_vmspace->vm_map,
    837 			    sa, ea, VM_PROT_READ|VM_PROT_EXECUTE, false);
    838 		}
    839 	}
    840 #if 0
    841 	printf("SS %s (%d): breakpoint set at %x: %x (pc %x) br %x\n",
    842 		p->p_comm, p->p_pid, p->p_md.md_ss_addr,
    843 		p->p_md.md_ss_instr, pc, mips_ufetch32((void *)va)); /* XXX */
    844 #endif
    845 	return 0;
    846 }
    847 
    848 #ifdef TRAP_SIGDEBUG
    849 static void
    850 frame_dump(const struct trapframe *tf, struct pcb *pcb)
    851 {
    852 
    853 	printf("trapframe %p\n", tf);
    854 	printf("ast %#018lx   v0 %#018lx   v1 %#018lx\n",
    855 	    tf->tf_regs[_R_AST], tf->tf_regs[_R_V0], tf->tf_regs[_R_V1]);
    856 	printf(" a0 %#018lx   a1 %#018lx   a2 %#018lx\n",
    857 	    tf->tf_regs[_R_A0], tf->tf_regs[_R_A1], tf->tf_regs[_R_A2]);
    858 #if defined(__mips_n32) || defined(__mips_n64)
    859 	printf(" a3 %#018lx   a4  %#018lx  a5  %#018lx\n",
    860 	    tf->tf_regs[_R_A3], tf->tf_regs[_R_A4], tf->tf_regs[_R_A5]);
    861 	printf(" a6 %#018lx   a7  %#018lx  t0  %#018lx\n",
    862 	    tf->tf_regs[_R_A6], tf->tf_regs[_R_A7], tf->tf_regs[_R_T0]);
    863 	printf(" t1 %#018lx   t2  %#018lx  t3  %#018lx\n",
    864 	    tf->tf_regs[_R_T1], tf->tf_regs[_R_T2], tf->tf_regs[_R_T3]);
    865 #else
    866 	printf(" a3 %#018lx   t0  %#018lx  t1  %#018lx\n",
    867 	    tf->tf_regs[_R_A3], tf->tf_regs[_R_T0], tf->tf_regs[_R_T1]);
    868 	printf(" t2 %#018lx   t3  %#018lx  t4  %#018lx\n",
    869 	    tf->tf_regs[_R_T2], tf->tf_regs[_R_T3], tf->tf_regs[_R_T4]);
    870 	printf(" t5 %#018lx   t6  %#018lx  t7  %#018lx\n",
    871 	    tf->tf_regs[_R_T5], tf->tf_regs[_R_T6], tf->tf_regs[_R_T7]);
    872 #endif
    873 	printf(" s0 %#018lx   s1  %#018lx  s2  %#018lx\n",
    874 	    tf->tf_regs[_R_S0], tf->tf_regs[_R_S1], tf->tf_regs[_R_S2]);
    875 	printf(" s3 %#018lx   s4  %#018lx  s5  %#018lx\n",
    876 	    tf->tf_regs[_R_S3], tf->tf_regs[_R_S4], tf->tf_regs[_R_S5]);
    877 	printf(" s6 %#018lx   s7  %#018lx  t8  %#018lx\n",
    878 	    tf->tf_regs[_R_S6], tf->tf_regs[_R_S7], tf->tf_regs[_R_T8]);
    879 	printf(" t9 %#018lx   k0  %#018lx  k1  %#018lx\n",
    880 	    tf->tf_regs[_R_T9], tf->tf_regs[_R_K0], tf->tf_regs[_R_K1]);
    881 	printf(" gp %#018lx   sp  %#018lx  s8  %#018lx\n",
    882 	    tf->tf_regs[_R_GP], tf->tf_regs[_R_SP], tf->tf_regs[_R_S8]);
    883 	printf(" ra %#018lx   sr  %#018lx  pc  %#018lx\n",
    884 	    tf->tf_regs[_R_RA], tf->tf_regs[_R_SR], tf->tf_regs[_R_PC]);
    885 	printf(" mullo     %#018lx mulhi %#018lx\n",
    886 	    tf->tf_regs[_R_MULLO], tf->tf_regs[_R_MULHI]);
    887 	printf(" badvaddr  %#018lx cause %#018lx\n",
    888 	    tf->tf_regs[_R_BADVADDR], tf->tf_regs[_R_CAUSE]);
    889 	printf("\n");
    890 	hexdump(printf, "Stack dump", tf, 256);
    891 }
    892 
    893 static void
    894 sigdebug(const struct trapframe *tf, const ksiginfo_t *ksi, int e,
    895     vaddr_t pc)
    896 {
    897 	struct lwp *l = curlwp;
    898 	struct proc *p = l->l_proc;
    899 
    900 	printf("pid %d.%d (%s): signal %d code=%d (trap %#lx) "
    901 	    "@pc %#lx addr %#lx error=%d\n",
    902 	    p->p_pid, l->l_lid, p->p_comm, ksi->ksi_signo, ksi->ksi_code,
    903 	    tf->tf_regs[_R_CAUSE], (unsigned long)pc, tf->tf_regs[_R_BADVADDR],
    904 	    e);
    905 	frame_dump(tf, lwp_getpcb(l));
    906 }
    907 #endif /* TRAP_SIGDEBUG */
    908