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