Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/perseant-stdc-iso10646]: src/sys/arch/mips/mips 2564730
details: https://anonhg.NetBSD.org/src/rev/cf7a19e15c97
branches: perseant-stdc-iso10646
changeset: 850627:cf7a19e15c97
user: christos <christos%NetBSD.org@localhost>
date: Fri Jul 14 20:32:33 2017 +0000
description:
2564730
diffstat:
sys/arch/mips/mips/trap.c | 1189 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1189 insertions(+), 0 deletions(-)
diffs (truncated from 1193 to 300 lines):
diff -r 290c79283c70 -r cf7a19e15c97 sys/arch/mips/mips/trap.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/mips/mips/trap.c Fri Jul 14 20:32:33 2017 +0000
@@ -0,0 +1,1189 @@
+/* $NetBSD: trap.c,v 1.244.2.2 2017/07/14 20:32:33 christos Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1992, 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 and Ralph Campbell.
+ *
+ * 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. 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.
+ *
+ * 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: Utah Hdr: trap.c 1.32 91/04/06
+ *
+ * @(#)trap.c 8.5 (Berkeley) 1/11/94
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.244.2.2 2017/07/14 20:32:33 christos Exp $");
+
+#include "opt_cputype.h" /* which mips CPU levels do we support? */
+#include "opt_ddb.h"
+#include "opt_kgdb.h"
+#include "opt_multiprocessor.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/cpu.h>
+#include <sys/proc.h>
+#include <sys/ras.h>
+#include <sys/signalvar.h>
+#include <sys/syscall.h>
+#include <sys/buf.h>
+#include <sys/ktrace.h>
+#include <sys/kauth.h>
+#include <sys/atomic.h>
+
+#include <mips/cache.h>
+#include <mips/locore.h>
+#include <mips/mips_opcode.h>
+
+#include <uvm/uvm.h>
+
+#include <mips/trap.h>
+#include <mips/reg.h>
+#include <mips/regnum.h> /* symbolic register indices */
+#include <mips/pcb.h>
+#include <mips/pte.h>
+#include <mips/psl.h>
+#include <mips/userret.h>
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#include <ddb/db_sym.h>
+#endif
+
+#ifdef KGDB
+#include <sys/kgdb.h>
+#endif
+
+const char * const trap_names[] = {
+ "external interrupt",
+ "TLB modification",
+ "TLB miss (load or instr. fetch)",
+ "TLB miss (store)",
+ "address error (load or I-fetch)",
+ "address error (store)",
+ "bus error (I-fetch)",
+ "bus error (load or store)",
+ "system call",
+ "breakpoint",
+ "reserved instruction",
+ "coprocessor unusable",
+ "arithmetic overflow",
+ "r4k trap/r3k reserved 13",
+ "r4k virtual coherency instruction/r3k reserved 14",
+ "r4k floating point/ r3k reserved 15",
+ "mips NMI",
+ "reserved 17",
+ "mipsNN cp2 exception",
+ "mipsNN TLBRI",
+ "mipsNN TLBXI",
+ "reserved 21",
+ "mips64 MDMX",
+ "r4k watch",
+ "mipsNN machine check",
+ "mipsNN thread",
+ "DSP exception",
+ "reserved 27",
+ "reserved 28",
+ "reserved 29",
+ "mipsNN cache error",
+ "r4000 virtual coherency data",
+};
+
+void trap(uint32_t, uint32_t, vaddr_t, vaddr_t, struct trapframe *);
+void ast(void);
+
+/*
+ * fork syscall returns directly to user process via lwp_trampoline(),
+ * which will be called the very first time when child gets running.
+ */
+void
+child_return(void *arg)
+{
+ struct lwp *l = arg;
+ struct trapframe *utf = l->l_md.md_utf;
+
+ utf->tf_regs[_R_V0] = 0;
+ utf->tf_regs[_R_V1] = 1;
+ utf->tf_regs[_R_A3] = 0;
+ userret(l);
+ ktrsysret(SYS_fork, 0, 0);
+}
+
+#ifdef MIPS3_PLUS
+#define TRAPTYPE(x) (((x) & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT)
+#else
+#define TRAPTYPE(x) (((x) & MIPS1_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT)
+#endif
+#define KERNLAND_P(x) ((intptr_t)(x) < 0)
+
+/*
+ * Trap is called from locore to handle most types of processor traps.
+ * System calls are broken out for efficiency. MIPS can handle software
+ * interrupts as a part of real interrupt processing.
+ */
+void
+trap(uint32_t status, uint32_t cause, vaddr_t vaddr, vaddr_t pc,
+ struct trapframe *tf)
+{
+ int type;
+ struct lwp * const l = curlwp;
+ struct proc * const p = curproc;
+ struct trapframe * const utf = l->l_md.md_utf;
+ struct pcb * const pcb = lwp_getpcb(l);
+ vm_prot_t ftype;
+ ksiginfo_t ksi;
+ extern void fswintrberr(void);
+ void *onfault;
+ int rv;
+
+ KSI_INIT_TRAP(&ksi);
+
+ curcpu()->ci_data.cpu_ntrap++;
+ if (CPUISMIPS3 && (status & MIPS3_SR_NMI)) {
+ type = T_NMI;
+ } else {
+ type = TRAPTYPE(cause);
+ }
+ if (USERMODE(status)) {
+ tf = utf;
+ type |= T_USER;
+ LWP_CACHE_CREDS(l, p);
+ }
+
+ switch (type) {
+ default:
+ dopanic:
+ (void)splhigh();
+
+ /*
+ * use snprintf to allow a single, idempotent, readable printf
+ */
+ char strbuf[256], *str = strbuf;
+ int n, sz = sizeof(strbuf);
+
+ n = snprintf(str, sz, "pid %d(%s): ", p->p_pid, p->p_comm);
+ sz -= n;
+ str += n;
+ n = snprintf(str, sz, "trap: cpu%d, %s in %s mode\n",
+ cpu_number(), trap_names[TRAPTYPE(cause)],
+ USERMODE(status) ? "user" : "kernel");
+ sz -= n;
+ str += n;
+ n = snprintf(str, sz, "status=%#x, cause=%#x, epc=%#"
+ PRIxVADDR ", vaddr=%#" PRIxVADDR "\n",
+ status, cause, pc, vaddr);
+ sz -= n;
+ str += n;
+ if (USERMODE(status)) {
+ KASSERT(tf == utf);
+ n = snprintf(str, sz, "frame=%p usp=%#" PRIxREGISTER
+ " ra=%#" PRIxREGISTER "\n",
+ tf, tf->tf_regs[_R_SP], tf->tf_regs[_R_RA]);
+ sz -= n;
+ str += n;
+ } else {
+ n = snprintf(str, sz, "tf=%p ksp=%p ra=%#"
+ PRIxREGISTER " ppl=%#x\n", tf,
+ type == T_NMI
+ ? (void*)(uintptr_t)tf->tf_regs[_R_SP]
+ : tf+1,
+ tf->tf_regs[_R_RA], tf->tf_ppl);
+ sz -= n;
+ str += n;
+ }
+ printf("%s", strbuf);
+
+ if (type == T_BUS_ERR_IFETCH || type == T_BUS_ERR_LD_ST)
+ (void)(*mips_locoresw.lsw_bus_error)(cause);
+
+#if defined(DDB)
+ kdb_trap(type, &tf->tf_registers);
+ /* XXX force halt XXX */
+#elif defined(KGDB)
+ {
+ extern mips_reg_t kgdb_cause, kgdb_vaddr;
+ struct reg *regs = &ddb_regs;
+ kgdb_cause = cause;
+ kgdb_vaddr = vaddr;
+
+ /*
+ * init global ddb_regs, used in db_interface.c routines
+ * shared between ddb and gdb. Send ddb_regs to gdb so
+ * that db_machdep.h macros will work with it, and
+ * allow gdb to alter the PC.
+ */
+ db_set_ddb_regs(type, tf);
+ PC_BREAK_ADVANCE(regs);
+ if (kgdb_trap(type, regs)) {
+ tf->tf_regs[TF_EPC] = regs->r_regs[_R_PC];
+ return;
+ }
+ }
+#else
+ panic("trap");
+#endif
+ /*NOTREACHED*/
+ case T_TLB_MOD:
+ case T_TLB_MOD+T_USER: {
+ const bool user_p = (type & T_USER) || !KERNLAND_P(vaddr);
+ pmap_t pmap = user_p
+ ? p->p_vmspace->vm_map.pmap
+ : pmap_kernel();
+
+ kpreempt_disable();
+
+ pt_entry_t * const ptep = pmap_pte_lookup(pmap, vaddr);
+ if (!ptep)
+ panic("%ctlbmod: %#"PRIxVADDR": no pte",
+ user_p ? 'u' : 'k', vaddr);
+ pt_entry_t pte = *ptep;
+ if (!pte_valid_p(pte)) {
+ panic("%ctlbmod: %#"PRIxVADDR": invalid pte %#"PRIx32
+ " @ ptep %p", user_p ? 'u' : 'k', vaddr,
+ pte_value(pte), ptep);
+ }
+ if (pte_readonly_p(pte)) {
+ /* write to read only page */
+ ftype = VM_PROT_WRITE;
+ kpreempt_enable();
+ if (user_p) {
+ goto pagefault;
+ } else {
+ goto kernelfault;
+ }
+ }
+ UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
+ UVMHIST_LOG(maphist, "%ctlbmod(va=%#lx, pc=%#lx, tf=%p)",
+ user_p ? 'u' : 'k', vaddr, pc, tf);
+ if (!pte_modified_p(pte)) {
+ pte |= mips_pg_m_bit();
+#ifdef MULTIPROCESSOR
+ atomic_or_32(ptep, mips_pg_m_bit());
+#else
+ *ptep = pte;
+#endif
+ }
+ // We got a TLB MOD exception so we must have a valid ASID
+ // and there must be a matching entry in the TLB. So when
+ // we try to update it, we better have done it.
Home |
Main Index |
Thread Index |
Old Index