? sys/arch/mips/ChangeLog
Index: sys/arch/mips/cavium/octeon_cpunode.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/cavium/octeon_cpunode.c,v
retrieving revision 1.12
diff -p -u -r1.12 octeon_cpunode.c
--- sys/arch/mips/cavium/octeon_cpunode.c	23 Jan 2018 06:57:49 -0000	1.12
+++ sys/arch/mips/cavium/octeon_cpunode.c	12 Jul 2019 20:55:33 -0000
@@ -179,7 +179,7 @@ octeon_fixup_cpu_info_references(int32_t
 	KASSERT(load_addr < (intptr_t)(ci + 1));
 
 	KASSERT(INSN_LUI_P(new_insns[0]));
-	KASSERT(INSN_LOAD_P(new_insns[1]) || INSN_STORE_P(new_insns[1]));
+	KASSERT(INSN_LOAD_P(new_insns[1]) || INSN_STORE_P(new_insns[1]) || INSN_ADDIU_P(new_insns[1]));
 
 	/*
 	 * Use the lui and load/store instruction as a prototype and
Index: sys/arch/mips/cavium/dev/if_cnmac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/cavium/dev/if_cnmac.c,v
retrieving revision 1.14
diff -p -u -r1.14 if_cnmac.c
--- sys/arch/mips/cavium/dev/if_cnmac.c	7 Jun 2019 07:41:22 -0000	1.14
+++ sys/arch/mips/cavium/dev/if_cnmac.c	12 Jul 2019 20:55:33 -0000
@@ -371,6 +371,7 @@ octeon_eth_attach(device_t parent, devic
 	/* 802.1Q VLAN-sized frames are supported */
 	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
 
+	octeon_gmx_link_enable(sc->sc_gmx_port, 0);
 	octeon_gmx_set_mac_addr(sc->sc_gmx_port, enaddr);
 
 	if_attach(ifp);
Index: sys/arch/mips/cavium/dev/octeon_pow.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/cavium/dev/octeon_pow.c,v
retrieving revision 1.4
diff -p -u -r1.4 octeon_pow.c
--- sys/arch/mips/cavium/dev/octeon_pow.c	28 May 2019 08:59:34 -0000	1.4
+++ sys/arch/mips/cavium/dev/octeon_pow.c	12 Jul 2019 20:55:33 -0000
@@ -94,7 +94,7 @@ static inline int	octeon_pow_tag_sw_poll
 static inline void	octeon_pow_tag_sw_wait(void);
 static inline void	octeon_pow_config_int_pc(struct octeon_pow_softc *, int);
 static inline void      octeon_pow_config_int(struct octeon_pow_softc *, int,
-			    uint64_t, uint64_t, uint64_t);
+			    uint64_t, uint64_t, uint64_t, uint64_t);
 static inline void	octeon_pow_intr_work(struct octeon_pow_softc *,
 			    struct octeon_pow_intr_handle *, int);
 static int		octeon_pow_intr(void *);
@@ -279,9 +279,9 @@ octeon_pow_bootstrap(struct octeon_confi
 
 static inline void
 octeon_pow_config_int(struct octeon_pow_softc *sc, int group,
-   uint64_t tc_thr, uint64_t ds_thr, uint64_t iq_thr)
+   uint64_t tc_thr, uint64_t ds_thr, uint64_t iq_thr, uint64_t pc_thr)
 {
-	uint64_t wq_int_thr;
+	uint64_t wq_int_thr, wq_int_pc;
 
 	wq_int_thr =
 	    POW_WQ_INT_THRX_TC_EN |
@@ -289,6 +289,10 @@ octeon_pow_config_int(struct octeon_pow_
 	    (ds_thr << POW_WQ_INT_THRX_DS_THR_SHIFT) |
 	    (iq_thr << POW_WQ_INT_THRX_IQ_THR_SHIFT);
 	_POW_WR8(sc, POW_WQ_INT_THR0_OFFSET + (group * 8), wq_int_thr);
+
+	wq_int_pc =
+	    (pc_thr << POW_WQ_INT_PC_PC_THR_SHIFT);
+	_POW_WR8(sc, POW_WQ_INT_PC_OFFSET, wq_int_pc);
 }
 
 /*
@@ -301,6 +305,7 @@ octeon_pow_config_int(struct octeon_pow_
  *    => each group can set timeout
  * => temporary disable bit
  *    => use CIU generic timer
+ * => periodic counter
  */
 
 void
@@ -308,9 +313,10 @@ octeon_pow_config(struct octeon_pow_soft
 {
 
 	octeon_pow_config_int(sc, group,
-	    0x0f,		/* TC */
+	    0x01,		/* TC */
 	    0x00,		/* DS */
-	    0x00);		/* IQ */
+	    0x00,		/* IQ */
+	    0x05);		/* PC */
 }
 
 void *
Index: sys/arch/mips/cavium/dev/octeon_rnm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/cavium/dev/octeon_rnm.c,v
retrieving revision 1.2
diff -p -u -r1.2 octeon_rnm.c
--- sys/arch/mips/cavium/dev/octeon_rnm.c	8 Jan 2019 19:41:09 -0000	1.2
+++ sys/arch/mips/cavium/dev/octeon_rnm.c	12 Jul 2019 20:55:33 -0000
@@ -110,7 +110,7 @@ octeon_rnm_attach(device_t parent, devic
 		sc->sc_rnghz = 1;
 
 	rnd_attach_source(&sc->sc_rndsrc, device_xname(sc->sc_dev),
-	    RND_TYPE_RNG, RND_FLAG_NO_ESTIMATE);
+	    RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE);
 
 	callout_init(&sc->sc_rngto, 0);
 
Index: sys/arch/mips/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/cpu.h,v
retrieving revision 1.126
diff -p -u -r1.126 cpu.h
--- sys/arch/mips/include/cpu.h	16 Sep 2018 09:25:46 -0000	1.126
+++ sys/arch/mips/include/cpu.h	12 Jul 2019 20:55:33 -0000
@@ -85,6 +85,7 @@ void		  cpuwatch_clr(cpu_watchpoint_t *)
 
 struct cpu_info {
 	struct cpu_data ci_data;	/* MI per-cpu data */
+	struct cpu_info *ci_self;	/* self-pointer */
 	void *ci_nmi_stack;		/* NMI exception stack */
 	struct cpu_softc *ci_softc;	/* chip-dependent hook */
 	device_t ci_dev;		/* owning device */
@@ -184,13 +185,24 @@ extern struct cpu_info *cpuid_infos[];
 register struct lwp *mips_curlwp asm(MIPS_CURLWP_QUOTED);
 
 #define	curlwp			mips_curlwp
-#define	curcpu()		lwp_getcpu(curlwp)
 #define	curpcb			((struct pcb *)lwp_getpcb(curlwp))
 #ifdef MULTIPROCESSOR
 #define	cpu_number()		(curcpu()->ci_index)
+extern struct callout_cpu callout_cpu0;
+static inline struct cpu_info *
+mips_curcpu(void) {
+	extern int32_t mipsNN_cp0_ebase_read(void);
+	u_int num = mipsNN_cp0_ebase_read() & 0x3ff;
+
+        KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+
+	return num == 0 ? &cpu_info_store : cpuid_infos[num];
+}
+#define	curcpu()		mips_curcpu()
 #define	CPU_IS_PRIMARY(ci)	((ci)->ci_flags & CPUF_PRIMARY)
 #else
 #define	cpu_number()		(0)
+#define	curcpu()		(&cpu_info_store)
 #define	CPU_IS_PRIMARY(ci)	(true)
 #endif
 
Index: sys/arch/mips/include/db_machdep.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/db_machdep.h,v
retrieving revision 1.30
diff -p -u -r1.30 db_machdep.h
--- sys/arch/mips/include/db_machdep.h	6 Nov 2017 03:47:47 -0000	1.30
+++ sys/arch/mips/include/db_machdep.h	12 Jul 2019 20:55:33 -0000
@@ -81,6 +81,7 @@ extern db_regs_t	ddb_regs;	/* register s
 /*
  * Interface to  disassembly (shared with mdb)
  */
+db_addr_t	db_disasm(db_addr_t loc, bool altfmt);
 db_addr_t	db_disasm_insn(int insn, db_addr_t loc, bool altfmt);
 
 
Index: sys/arch/mips/include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/intr.h,v
retrieving revision 1.10
diff -p -u -r1.10 intr.h
--- sys/arch/mips/include/intr.h	6 Jun 2015 04:31:52 -0000	1.10
+++ sys/arch/mips/include/intr.h	12 Jul 2019 20:55:33 -0000
@@ -80,22 +80,22 @@
 
 #ifdef __INTR_PRIVATE
 struct splsw {
-	int	(*splsw_splhigh)(void);
-	int	(*splsw_splsched)(void);
-	int	(*splsw_splvm)(void);
-	int	(*splsw_splsoftserial)(void);
-	int	(*splsw_splsoftnet)(void);
-	int	(*splsw_splsoftbio)(void);
-	int	(*splsw_splsoftclock)(void);
-	int	(*splsw_splraise)(int);
-	void	(*splsw_spl0)(void);
-	void	(*splsw_splx)(int);
-	int	(*splsw_splhigh_noprof)(void);
-	void	(*splsw_splx_noprof)(int);
+	int	(*splsw_splhigh)(struct cpu_info *);
+	int	(*splsw_splsched)(struct cpu_info *);
+	int	(*splsw_splvm)(struct cpu_info *);
+	int	(*splsw_splsoftserial)(struct cpu_info *);
+	int	(*splsw_splsoftnet)(struct cpu_info *);
+	int	(*splsw_splsoftbio)(struct cpu_info *);
+	int	(*splsw_splsoftclock)(struct cpu_info *);
+	int	(*splsw_splraise)(int, struct cpu_info *);
+	void	(*splsw_spl0)(struct cpu_info *);
+	void	(*splsw_splx)(int, struct cpu_info *);
+	int	(*splsw_splhigh_noprof)(struct cpu_info *);
+	void	(*splsw_splx_noprof)(int, struct cpu_info *);
 	void	(*splsw__setsoftintr)(uint32_t);
 	void	(*splsw__clrsoftintr)(uint32_t);
 	int	(*splsw_splintr)(uint32_t *);
-	void	(*splsw_splcheck)(void);
+	void	(*splsw_splcheck)(struct cpu_info *);
 };
 
 struct ipl_sr_map {
Index: sys/arch/mips/include/locore.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/locore.h,v
retrieving revision 1.104
diff -p -u -r1.104 locore.h
--- sys/arch/mips/include/locore.h	6 Apr 2019 03:06:26 -0000	1.104
+++ sys/arch/mips/include/locore.h	12 Jul 2019 20:55:33 -0000
@@ -373,7 +373,7 @@ void	mips_cp0_cause_write(uint32_t);
 uint32_t mips_cp0_status_read(void);
 void	mips_cp0_status_write(uint32_t);
 
-void	softint_process(uint32_t);
+void	softint_process(uint32_t, int);
 void	softint_fast_dispatch(struct lwp *, int);
 
 /*
@@ -591,8 +591,8 @@ typedef struct {
 			       uint64_t *);
 	void	(*lav_mutex_enter)(kmutex_t *);
 	void	(*lav_mutex_exit)(kmutex_t *);
-	void	(*lav_mutex_spin_enter)(kmutex_t *);
-	void	(*lav_mutex_spin_exit)(kmutex_t *);
+	void	(*lav_mutex_spin_enter)(kmutex_t *, struct cpu_info *);
+	void	(*lav_mutex_spin_exit)(kmutex_t *, struct cpu_info *);
 } mips_locore_atomicvec_t;
 
 void	mips_set_wbflush(void (*)(void));
Index: sys/arch/mips/include/mips_opcode.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/mips_opcode.h,v
retrieving revision 1.21
diff -p -u -r1.21 mips_opcode.h
--- sys/arch/mips/include/mips_opcode.h	27 Jun 2015 03:30:01 -0000	1.21
+++ sys/arch/mips/include/mips_opcode.h	12 Jul 2019 20:55:33 -0000
@@ -391,6 +391,7 @@ typedef union {
 #define	INSN_SW_P(insn)		(((insn) >> 26) == OP_SW)
 #define	INSN_LD_P(insn)		(((insn) >> 26) == OP_LD)
 #define	INSN_SD_P(insn)		(((insn) >> 26) == OP_SD)
+#define	INSN_ADDIU_P(insn)	(((insn) >> 26) == OP_ADDIU)
 
 #define INSN_LOAD_P(insn)	(INSN_LD_P(insn) || INSN_LW_P(insn))
 #define INSN_STORE_P(insn)	(INSN_SD_P(insn) || INSN_SW_P(insn))
Index: sys/arch/mips/include/mips_param.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/mips_param.h,v
retrieving revision 1.40
diff -p -u -r1.40 mips_param.h
--- sys/arch/mips/include/mips_param.h	19 Jun 2019 09:55:27 -0000	1.40
+++ sys/arch/mips/include/mips_param.h	12 Jul 2019 20:55:33 -0000
@@ -81,7 +81,11 @@
 #endif
 
 #ifndef COHERENCY_UNIT
-#define COHERENCY_UNIT	32	/* MIPS cachelines are usually 32 bytes */
+#define COHERENCY_UNIT	128	/* MIPS cachelines are usually 32 bytes */
+#endif
+
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE	128	/* MIPS cachelines are usually 32 bytes */
 #endif
 
 #ifdef ENABLE_MIPS_16KB_PAGE
Index: sys/arch/mips/include/netbsd32_machdep.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/netbsd32_machdep.h,v
retrieving revision 1.5
diff -p -u -r1.5 netbsd32_machdep.h
--- sys/arch/mips/include/netbsd32_machdep.h	31 Oct 2017 12:37:23 -0000	1.5
+++ sys/arch/mips/include/netbsd32_machdep.h	12 Jul 2019 20:55:33 -0000
@@ -34,6 +34,17 @@
 
 #include <sys/types.h>
 
+#define PT32_GETREGS            (PT_FIRSTMACH + 1)
+#define PT32_SETREGS            (PT_FIRSTMACH + 2)
+#define PT32_GETFPREGS          (PT_FIRSTMACH + 3)
+#define PT32_SETFPREGS          (PT_FIRSTMACH + 4)
+#ifdef PT_STEP
+/* XXX */
+#define PT32_STEP               (PT_FIRSTMACH + 0)
+#define PT32_SETSTEP            (PT_FIRSTMACH + 5)
+#define PT32_CLEARSTEP          (PT_FIRSTMACH + 6)
+#endif
+
 /*
  * On MIPS, pointers are signed.
  */
@@ -63,15 +74,24 @@ extern const char machine_arch32[];
 
 /* <mips/sysarch.h> */
 struct mips_cacheflush_args32 {
-	netbsd32_intptr_t va;
-	netbsd32_size_t nbytes;
+	int32_t va;
+	uint32_t nbytes;
 	int whichcache;
 };
 
 struct mips_cachectl_args32 {
-	netbsd32_intptr_t va;
-	netbsd32_size_t nbytes;
+	int32_t va;
+	uint32_t nbytes;
 	int ctl;
 };
 
+/* Translate ptrace() PT_* request from 32-bit userland to kernel. */
+int netbsd32_ptrace_translate_request(int);
+
+int netbsd32_process_read_regs(struct lwp *, struct reg32 *);
+int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *);
+
+int netbsd32_process_write_regs(struct lwp *, const struct reg32 *);
+int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t);
+
 #endif /* _MACHINE_NETBSD32_H_ */
Index: sys/arch/mips/include/ptrace.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/ptrace.h,v
retrieving revision 1.17
diff -p -u -r1.17 ptrace.h
--- sys/arch/mips/include/ptrace.h	18 Jun 2019 21:18:12 -0000	1.17
+++ sys/arch/mips/include/ptrace.h	12 Jul 2019 20:55:33 -0000
@@ -83,4 +83,19 @@
 #include <machine/reg.h>	/* Historically in sys/ptrace.h */
 #include <machine/regnum.h>	/* real register names */
 
+#ifdef COMPAT_NETBSD32
+#include <machine/netbsd32_machdep.h>
+
+#define process_read_regs32     netbsd32_process_read_regs
+#define process_read_fpregs32   netbsd32_process_read_fpregs
+
+#define process_write_regs32    netbsd32_process_write_regs
+#define process_write_fpregs32  netbsd32_process_write_fpregs
+
+#define process_reg32           struct reg32
+#define process_fpreg32         struct fpreg32
+
+#define PTRACE_TRANSLATE_REQUEST32(x) netbsd32_ptrace_translate_request(x)
+#endif  /* COMPAT_NETBSD32 */
+
 #endif	 /* _MIPS_PTRACE_H_ */
Index: sys/arch/mips/mips/cpu_subr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/cpu_subr.c,v
retrieving revision 1.34
diff -p -u -r1.34 cpu_subr.c
--- sys/arch/mips/mips/cpu_subr.c	21 Jan 2019 08:04:26 -0000	1.34
+++ sys/arch/mips/mips/cpu_subr.c	12 Jul 2019 20:55:33 -0000
@@ -61,6 +61,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v
 #include <mips/frame.h>
 #include <mips/userret.h>
 #include <mips/pte.h>
+#include <mips/cpuregs.h>
 
 #if defined(DDB) || defined(KGDB)
 #ifdef DDB
@@ -80,6 +81,7 @@ struct cpu_info cpu_info_store
 	__aligned(1LU << ilog2((2*sizeof(struct cpu_info)-1)))
 #endif
     = {
+	.ci_self = &cpu_info_store,
 	.ci_curlwp = &lwp0,
 	.ci_tlb_info = &pmap_tlb0_info,
 	.ci_pmap_kern_segtab = &pmap_kern_segtab,
@@ -180,6 +182,7 @@ cpu_info_alloc(struct pmap_tlb_info *ti,
 #endif /* MIPS64_OCTEON */
 
 	KASSERT(cpu_id != 0);
+	ci->ci_self = ci;
 	ci->ci_cpuid = cpu_id;
 	ci->ci_pmap_kern_segtab = &pmap_kern_segtab,
 	ci->ci_package_id = cpu_package_id;
Index: sys/arch/mips/mips/db_disasm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/db_disasm.c,v
retrieving revision 1.32
diff -p -u -r1.32 db_disasm.c
--- sys/arch/mips/mips/db_disasm.c	6 Apr 2019 03:06:26 -0000	1.32
+++ sys/arch/mips/mips/db_disasm.c	12 Jul 2019 20:55:33 -0000
@@ -828,7 +828,7 @@ db_disasm_insn(int insn, db_addr_t loc, 
 	db_printf("\n");
 	if (bdslot) {
 		db_printf("\t\tbdslot:\t");
-		db_disasm(loc+4, false);
+		db_disasm(loc+4, altfmt);
 		return (loc + 8);
 	}
 	return (loc + 4);
Index: sys/arch/mips/mips/lock_stubs_llsc.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/lock_stubs_llsc.S,v
retrieving revision 1.9
diff -p -u -r1.9 lock_stubs_llsc.S
--- sys/arch/mips/mips/lock_stubs_llsc.S	6 Apr 2019 03:06:26 -0000	1.9
+++ sys/arch/mips/mips/lock_stubs_llsc.S	12 Jul 2019 20:55:33 -0000
@@ -221,14 +221,12 @@ STATIC_LEAF(llsc_mutex_exit)
 END(llsc_mutex_exit)
 
 /*
- * void	mutex_spin_enter(kmutex_t *mtx);
+ * void	mutex_spin_enter(kmutex_t *mtx, struct cpu_info *ci);
  */
 STATIC_NESTED(llsc_mutex_spin_enter, CALLFRAME_SIZ, ra)
-	move	t0, a0
-	PTR_L	t2, L_CPU(MIPS_CURLWP)
-	INT_L	a0, MTX_IPL(t0)
+	INT_L	t2, MTX_IPL(a0)
 #ifdef PARANOIA
-	INT_L	ta1, CPU_INFO_CPL(t2)
+	INT_L	ta1, CPU_INFO_CPL(a1)
 #endif
 
 	/*
@@ -236,10 +234,17 @@ STATIC_NESTED(llsc_mutex_spin_enter, CAL
 	 * but it's written to have little overhead.  call splraise
 	 * (only uses a0-a3 and v0-v1)
 	 */
+	move	t0, a0
+	move	t1, a1
 	move	t3, ra			# need to save ra
+
+	move	a0, t2
 	jal	_C_LABEL(splraise)
 	 nop
+
 	move	ra, t3			# move ra back
+	move	a1, t1
+	move	a0, t0
 #ifdef PARANOIA
 10:	bne	ta1, v0, 10b		# loop forever if v0 != ta1
 	 nop
@@ -250,16 +255,16 @@ STATIC_NESTED(llsc_mutex_spin_enter, CAL
 	 * exit.  Even if an interrupt happens, the mutex count will not change.
 	 */
 1:
-	INT_L	ta2, CPU_INFO_MTX_COUNT(t2)
+	INT_L	ta2, CPU_INFO_MTX_COUNT(a1)
 	INT_ADDU ta3, ta2, -1
-	INT_S	ta3, CPU_INFO_MTX_COUNT(t2)
+	INT_S	ta3, CPU_INFO_MTX_COUNT(a1)
 	bltz	ta2, 2f
 	 nop
-	INT_S	v0, CPU_INFO_MTX_OLDSPL(t2)	/* returned by splraise */
+	INT_S	v0, CPU_INFO_MTX_OLDSPL(a1)	/* returned by splraise */
 2:
 #ifdef PARANOIA
-	INT_L	ta1, CPU_INFO_MTX_OLDSPL(t2)
-	INT_L	ta2, CPU_INFO_CPL(t2)	# get updated CPL
+	INT_L	ta1, CPU_INFO_MTX_OLDSPL(a1)
+	INT_L	ta2, CPU_INFO_CPL(a1)	# get updated CPL
 	sltu	v0, ta2, ta0		# v0 = cpl < mtx_ipl
 	sltu	v1, ta2, ta1		# v1 = cpl < oldspl
 	sll	v0, 1
@@ -268,18 +273,18 @@ STATIC_NESTED(llsc_mutex_spin_enter, CAL
 	 nop
 #endif /* PARANOIA */
 #if defined(FULL)
-	INT_LL	t3, MTX_LOCK(t0)
+	INT_LL	t3, MTX_LOCK(a0)
 3:
 	bnez	t3, 4f
 	 li	t1, 1
-	INT_SC	t1, MTX_LOCK(t0)
+	INT_SC	t1, MTX_LOCK(a0)
 	beqz	t1, 3b
-	 INT_LL	t3, MTX_LOCK(t0)
+	 INT_LL	t3, MTX_LOCK(a0)
 	j	ra
 	 BDSYNC
 4:
 	j	_C_LABEL(mutex_spin_retry)
-	 move	a0, t0
+	 nop
 #else
 	j	ra
 	 nop
@@ -287,10 +292,9 @@ STATIC_NESTED(llsc_mutex_spin_enter, CAL
 END(llsc_mutex_spin_enter)
 
 /*
- * void	mutex_spin_exit(kmutex_t *mtx);
+ * void	mutex_spin_exit(kmutex_t *mtx, struct cpu_info *ci);
  */
 LEAF(llsc_mutex_spin_exit)
-	PTR_L	t2, L_CPU(MIPS_CURLWP)
 #if defined(DIAGNOSTIC)
 	INT_L	t0, MTX_LOCK(a0)
 	beqz	t0, 2f
@@ -304,32 +308,32 @@ LEAF(llsc_mutex_spin_exit)
 	 * and overwrite the oldspl value with a bogus value.
 	 */
 #ifdef PARANOIA
-	INT_L	a2, MTX_IPL(a0)
+	INT_L	t2, MTX_IPL(a0)
 #endif
-	INT_L	a0, CPU_INFO_MTX_OLDSPL(t2)
+	INT_L	t1, CPU_INFO_MTX_OLDSPL(a1)
 
 	/*
 	 * Increment the mutex count
 	 */
-	INT_L	t0, CPU_INFO_MTX_COUNT(t2)
+	INT_L	t0, CPU_INFO_MTX_COUNT(a1)
 	INT_ADDU t0, t0, 1
-	INT_S	t0, CPU_INFO_MTX_COUNT(t2)
+	INT_S	t0, CPU_INFO_MTX_COUNT(a1)
 
 	/*
 	 * If the IPL doesn't change, nothing to do
 	 */
-	INT_L	a1, CPU_INFO_CPL(t2)
+	INT_L	t3, CPU_INFO_CPL(a1)
 
 #ifdef PARANOIA
-	sltu	v0, a1, a2		# v0 = cpl < mtx_ipl
-	sltu	v1, a1, a0		# v1 = cpl < oldspl
+	sltu	v0, t3, t2		# v0 = cpl < mtx_ipl
+	sltu	v1, t3, t1		# v1 = cpl < oldspl
 	sll	v0, 1
 	or	v0, v1
 12:	bnez	v0, 12b			# loop forever if either is true
 	 nop
 #endif /* PARANOIA */
 
-	beq	a0, a1, 1f		# if oldspl == cpl
+	beq	t1, t3, 1f		# if oldspl == cpl
 	 nop				#   no reason to drop ipl
 
 	bltz	t0, 1f			# there are still holders
@@ -339,10 +343,11 @@ LEAF(llsc_mutex_spin_exit)
 	 * Mutex count is zero so we need to restore the old IPL
 	 */
 #ifdef PARANOIA
-	sltiu	v0, a0, IPL_HIGH+1
+	sltiu	v0, t1, IPL_HIGH+1
 13:	beqz	v0, 13b			# loop forever if ipl > IPL_HIGH
 	 nop
 #endif
+	move	a0, t1
 	j	 _C_LABEL(splx)
 	 nop
 1:
Index: sys/arch/mips/mips/lock_stubs_ras.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/lock_stubs_ras.S,v
retrieving revision 1.10
diff -p -u -r1.10 lock_stubs_ras.S
--- sys/arch/mips/mips/lock_stubs_ras.S	6 Apr 2019 03:06:26 -0000	1.10
+++ sys/arch/mips/mips/lock_stubs_ras.S	12 Jul 2019 20:55:33 -0000
@@ -358,46 +358,51 @@ END(ras_ucaserr)
 
 #ifndef LOCKDEBUG
 /*
- * void	mutex_spin_enter(kmutex_t *mtx);
+ * void	mutex_spin_enter(kmutex_t *mtx, struct cpu_info *ci);
  */
 STATIC_NESTED(ras_mutex_spin_enter, CALLFRAME_SIZ, ra)
-	move	t0, a0
-	PTR_L	t2, L_CPU(MIPS_CURLWP)
-	INT_L	a0, MTX_IPL(t0)
+	INT_L	t2, MTX_IPL(a0)
 #ifdef PARANOIA
-	INT_L	ta1, CPU_INFO_CPL(t2)		# get current cpl
+	INT_L	ta1, CPU_INFO_CPL(a1)		# get current cpl
 #endif
 
 	/*
 	 * We need to raise our IPL.
 	 * call splraise (only uses a0-a3, v0-v1, and ra)
 	 */
+	move	t0, a0
+	move	t1, a1
 	move	t3, ra
+
+	move	a0, t2
 	jal	_C_LABEL(splraise)
 	 nop
+
 	move	ra, t3
+	move	a1, t1
+	move	a0, t0
 
 	/*
 	 * If this is the first lock of the mutex, store the previous IPL
 	 * for exit.
 	 */
 1:
-	INT_L	ta2, CPU_INFO_MTX_COUNT(t2)
+	INT_L	ta2, CPU_INFO_MTX_COUNT(a1)
 	nop
 	INT_ADDU ta3, ta2, -1
-	INT_S	ta3, CPU_INFO_MTX_COUNT(t2)
+	INT_S	ta3, CPU_INFO_MTX_COUNT(a1)
 
 	bnez	ta2, 2f
 	 nop
-	INT_S	v0, CPU_INFO_MTX_OLDSPL(t2)	/* returned by splraise */
+	INT_S	v0, CPU_INFO_MTX_OLDSPL(a1)	/* returned by splraise */
 2:
 #if defined(DIAGNOSTIC)
-	INT_L	t3, MTX_LOCK(t0)
+	INT_L	t3, MTX_LOCK(a0)
 	li	t1, 1
 	bnez	t3, 3f
-	 nop
+	 move	a0, t2
 	j	ra
-	 INT_S	t1, MTX_LOCK(t0)
+	 INT_S	t1, MTX_LOCK(a0)
 3:
 	j	_C_LABEL(mutex_spin_retry)
 	 nop
@@ -408,11 +413,9 @@ STATIC_NESTED(ras_mutex_spin_enter, CALL
 END(ras_mutex_spin_enter)
 
 /*
- * void	mutex_spin_exit(kmutex_t *mtx);
+ * void	mutex_spin_exit(kmutex_t *mtx, struct cpu_info *ci);
  */
 LEAF(ras_mutex_spin_exit)
-	PTR_L	t2, L_CPU(MIPS_CURLWP)
-	nop
 #if defined(DIAGNOSTIC)
 	INT_L	t0, MTX_LOCK(a0)
 	nop
@@ -427,34 +430,34 @@ LEAF(ras_mutex_spin_exit)
 	 * and overwrite the oldspl value with a bogus value.
 	 */
 #ifdef PARANOIA
-	INT_L	a2, MTX_IPL(a0)
+	INT_L	t2, MTX_IPL(a0)
 #endif
-	INT_L	a0, CPU_INFO_MTX_OLDSPL(t2)
+	INT_L	t3, CPU_INFO_MTX_OLDSPL(a1)
 
 	/*
 	 * Increment the mutex count
 	 */
-	INT_L	t0, CPU_INFO_MTX_COUNT(t2)
-	nop
+	INT_L	t0, CPU_INFO_MTX_COUNT(a1)
+	NOP_L
 	INT_ADDU t0, t0, 1
-	INT_S	t0, CPU_INFO_MTX_COUNT(t2)
+	INT_S	t0, CPU_INFO_MTX_COUNT(a1)
 
 	/*
 	 * If the IPL doesn't change, nothing to do
 	 */
-	INT_L	a1, CPU_INFO_CPL(t2)
-	nop
+	INT_L	t1, CPU_INFO_CPL(a1)
+	NOP_L
 
 #ifdef PARANOIA
-	sltu	v0, a1, a2		# v0 = cpl < mtx_ipl
-	sltu	v1, a1, a0		# v1 = cpl < oldspl
+	sltu	v0, t1, t2		# v0 = cpl < mtx_ipl
+	sltu	v1, t1, t3		# v1 = cpl < oldspl
 	sll	v0, 1
 	or	v0, v1
 12:	bnez	v0, 12b			# loop forever if either is true
 	 nop
 #endif /* PARANOIA */
 
-	beq	a0, a1, 1f		# if oldspl == cpl
+	beq	t3, t1, 1f		# if oldspl == cpl
 	 nop				#   no reason to drop ipl
 
 	bltz	t0, 1f			# there are still holders
@@ -464,10 +467,11 @@ LEAF(ras_mutex_spin_exit)
 	 * Mutex count is zero so we need to restore the old IPL
 	 */
 #ifdef PARANOIA
-	sltiu	v0, a0, IPL_HIGH+1
+	sltiu	v0, t2, IPL_HIGH+1
 13:	beqz	v0, 13b			# loop forever if ipl > IPL_HIGH
 	 nop
 #endif
+	move	a0, t2
 	j	 _C_LABEL(splx)
 	 nop
 1:
Index: sys/arch/mips/mips/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/locore.S,v
retrieving revision 1.219
diff -p -u -r1.219 locore.S
--- sys/arch/mips/mips/locore.S	7 Sep 2018 21:14:45 -0000	1.219
+++ sys/arch/mips/mips/locore.S	12 Jul 2019 20:55:33 -0000
@@ -219,6 +219,7 @@ _C_LABEL(verylocore):
  */
 NESTED(cpu_switchto, CALLFRAME_SIZ, ra)
 #if defined(PARANOIA)
+#error maybe invalid CPU_INFO
 	/*
 	 * Make sure we are at IPL_SCHED
 	 */
Index: sys/arch/mips/mips/mipsX_subr.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mipsX_subr.S,v
retrieving revision 1.105
diff -p -u -r1.105 mipsX_subr.S
--- sys/arch/mips/mips/mipsX_subr.S	25 Jun 2019 21:26:04 -0000	1.105
+++ sys/arch/mips/mips/mipsX_subr.S	12 Jul 2019 20:55:34 -0000
@@ -126,6 +126,7 @@
 #include <sys/endian.h>
 
 #include <mips/asm.h>
+#define CPU_INFO_BASE (0)
 #include <mips/cpuregs.h>
 #if defined(MIPS3)
 #include <mips/cache_r4k.h>
@@ -501,6 +502,8 @@ MIPSX(tlb_miss_common):
 	REG_ADDU k0, 1				#1d
 	REG_S	k0, %lo(CPUVAR(EV_TLBMISSES))(k1) #1e
 #endif
+	li	k0, 0x1130
+	li	k1, 0x1131
 	eret					#1f: return from exception
 	.set	at
 #ifdef MIPS3_LOONGSON2
@@ -582,9 +585,9 @@ VECTOR(MIPSX(cache), unknown)
 	and	k0, k1					#02
 	li	k1, MIPS_KSEG1_START			#03
 	or	k0, k1					#04
-	lui	k1, %hi(CPUVAR(CURLWP))			#05: k1=hi of curlwp
+	lui	k1, %hi(CPUVAR(BASE))			#05: k1=hi of curcpu
 	jr	k0					#06
-	 PTR_L	k1, %lo(CPUVAR(CURLWP))(k1)		#07: k1=lo of curlwp
+	 addiu	k1, %lo(CPUVAR(BASE))			#07: k1=lo of curcpu
 _VECTOR_END(MIPSX(cache))
 
 /*
@@ -623,9 +626,9 @@ VECTOR(MIPSX(exception), unknown)
 						#  shifted left by 2 bits so
 						#  we dont have to shift.
 	PTR_L	k0, 0(k0)			#09: get the function address
-	lui	k1, %hi(CPUVAR(CURLWP))		#0a: k1=hi of curlwp
+	lui	k1, %hi(CPUVAR(BASE))		#0a: k1=hi of curcpu
 	jr	k0				#0b: jump to the function
-	 PTR_L	k1, %lo(CPUVAR(CURLWP))(k1)	#0c: k1=lo of curlwp
+	 addiu	k1, %lo(CPUVAR(BASE))		#0c: k1=lo of curcpu
 	nop					#0d
 	nop					#0e
 #ifndef _LP64
@@ -633,9 +636,9 @@ VECTOR(MIPSX(exception), unknown)
 #endif
 	.p2align 4
 MIPSX(nopagetable):
-	lui	k1, %hi(CPUVAR(CURLWP))		#10: k1=hi of curlwp
+	lui	k1, %hi(CPUVAR(BASE))		#06: k1=hi of curcpu
 	j	MIPSX(slowfault)		#11: no page table present
-	 PTR_L	k1, %lo(CPUVAR(CURLWP))(k1)	#12: k1=lo of curlwp
+	 addiu	k1, %lo(CPUVAR(BASE))		#06: k1=hi of curcpu
 	nop					#13: branch delay slot
 	.set	at
 _VECTOR_END(MIPSX(exception))
@@ -648,13 +651,12 @@ VECTOR(MIPSX(intr), unknown)
 	mfc0	k0, MIPS_COP_0_STATUS		#00: get the status register
 	MFC0_HAZARD				#01: stall
 	and	k0, k0, MIPS3_SR_KSU_USER	#02: test for user mode
+	lui	k1, %hi(CPUVAR(BASE))		#06: k1=hi of curcpu
 	bnez	k0, 1f				#03: yep, do it
-	 nop					#04:  branch deay
+	 addiu	k1, %lo(CPUVAR(BASE))		#07: k1=hi of curcpu
 	j	MIPSX(kern_intr)		#05: nope, kernel intr
 1:
-	lui	k1, %hi(CPUVAR(CURLWP))		#06: k1=hi of curlwp
-	j	MIPSX(user_intr)		#07: user intr
-	 PTR_L	k1, %lo(CPUVAR(CURLWP))(k1)	#08: k1=lo of curlwp
+	j	MIPSX(user_intr)		#08: user intr
 	.set	at
 _VECTOR_END(MIPSX(intr))
 
@@ -704,11 +706,14 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exceptio
 	.set	noat
 	.mask	0x80000000, -4
 #if defined(PARANOIA)
-	PTR_L	k0, L_PCB(MIPS_CURLWP)
+#error k1 is not initialized
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)
 	slt	k0, k0, sp		# k0 = L_PCB(MIPS_CURLWP) < sp
 1:	beqz	k0, 1b			# loop forever if false
 	 nop
-	PTR_L	k0, L_PCB(MIPS_CURLWP)
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)
 	PTR_ADDU k0, USPACE
 	slt	k0, sp, k0		# k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
 2:	beqz	k0, 2b			# loop forever if false
@@ -751,6 +756,7 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exceptio
 	REG_S	v1, TF_BASE+TF_REG_MULHI(sp)
 	REG_S	a3, TF_BASE+TF_REG_EPC(sp)
 	REG_S	a1, TF_BASE+TF_REG_CAUSE(sp)
+	REG_S	s7, TF_BASE+TF_REG_S7(sp)
 #if defined(DDB) || defined(KGDB)
 	REG_S	s0, TF_BASE+TF_REG_S0(sp)
 	REG_S	s1, TF_BASE+TF_REG_S1(sp)
@@ -759,7 +765,6 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exceptio
 	REG_S	s4, TF_BASE+TF_REG_S4(sp)
 	REG_S	s5, TF_BASE+TF_REG_S5(sp)
 	REG_S	s6, TF_BASE+TF_REG_S6(sp)
-	REG_S	s7, TF_BASE+TF_REG_S7(sp)
 	PTR_ADDU v0, sp, KERNFRAME_SIZ
 	REG_S	v0, TF_BASE+TF_REG_SP(sp)
 	REG_S	s8, TF_BASE+TF_REG_S8(sp)
@@ -772,12 +777,13 @@ NESTED_NOPROFILE(MIPSX(kern_gen_exceptio
 #if defined(__mips_n32) || defined(__mips_n64)
 	PTR_ADDU a4, sp, TF_BASE		# 5th arg is p. to trapframe
 #endif
+	PTR_L	MIPS_CURLWP, CPU_INFO_CURLWP(k1)
+	move	s7, k1
 #ifdef PARANOIA
 	/*
 	 * save PPL in trapframe
 	 */
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
-	INT_L	t1, CPU_INFO_CPL(t0)		# get current priority level
+	INT_L	t1, CPU_INFO_CPL(s7)		# get current priority level
 	INT_S	t1, TF_BASE+TF_PPL(sp)		# save priority level
 #endif /* PARANOIA */
 
@@ -845,8 +851,7 @@ MIPSX(kern_return):
 
 #ifdef PARANOIA
 	INT_L	t2, TF_BASE+TF_PPL(sp)		# get saved priority level
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
-	INT_L	t1, CPU_INFO_CPL(t0)		# get current priority level
+	INT_L	t1, CPU_INFO_CPL(s7)		# get current priority level
 11:	bne	t2, t1, 11b			# loop forever if unequal
 	 nop
 
@@ -890,6 +895,7 @@ MIPSX(kern_return):
 	#REG_L	t8, TF_BASE+TF_REG_T8(sp)	# is MIPS_CURLWP
 	REG_L	t9, TF_BASE+TF_REG_T9(sp)
 	REG_L	ra, TF_BASE+TF_REG_RA(sp)
+	REG_L	s7, TF_BASE+TF_REG_S7(sp)
 #ifdef DDBnotyet
 	REG_L	s0, TF_BASE+TF_REG_S0(sp)
 	REG_L	s1, TF_BASE+TF_REG_S1(sp)
@@ -898,10 +904,11 @@ MIPSX(kern_return):
 	REG_L	s4, TF_BASE+TF_REG_S4(sp)
 	REG_L	s5, TF_BASE+TF_REG_S5(sp)
 	REG_L	s6, TF_BASE+TF_REG_S6(sp)
-	REG_L	s7, TF_BASE+TF_REG_S7(sp)
 	REG_L	s8, TF_BASE+TF_REG_S8(sp)
 #endif
 	PTR_ADDU sp, KERNFRAME_SIZ
+	li	k0, 0x1140
+	li	k1, 0x1141
 	eret					# return to interrupted point
 	.set	at
 END(MIPSX(kern_gen_exception))
@@ -928,12 +935,14 @@ NESTED_NOPROFILE(MIPSX(kern_nonmaskable_
 	.set	noat
 	.mask	0x80000000, -4
 #if defined(PARANOIA)
-	PTR_L	k0, L_PCB(MIPS_CURLWP)
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)
 	slt	k0, k0, sp		# k0 = L_PCB(MIPS_CURLWP) < sp
 1:	beqz	k0, 1b			# loop forever if false
 	 nop
 
-	PTR_L	k0, L_PCB(MIPS_CURLWP)
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)
 	PTR_ADDU k0, USPACE
 	slt	k0, sp, k0		# k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
 2:	beqz	k0, 2b			# loop forever if false
@@ -944,9 +953,9 @@ NESTED_NOPROFILE(MIPSX(kern_nonmaskable_
  * Save the relevant kernel registers onto the NMI stack.
  * We save s0 - s8, sp and gp so DDB can see them.
  */
-	move	k1, sp				# save for later
-	PTR_L	sp, CPU_INFO_NMI_STACK(k0)	# get NMI stack
-	REG_S	k1, TF_BASE+TF_REG_SP(sp)
+	move	k0, sp				# save for later
+	PTR_L	sp, CPU_INFO_NMI_STACK(k1)	# get NMI stack
+	REG_S	k0, TF_BASE+TF_REG_SP(sp)
 	REG_S	AT, TF_BASE+TF_REG_AST(sp)
 	REG_S	v0, TF_BASE+TF_REG_V0(sp)
 	REG_S	v1, TF_BASE+TF_REG_V1(sp)
@@ -988,7 +997,6 @@ NESTED_NOPROFILE(MIPSX(kern_nonmaskable_
 	//PTR_ADDU v0, sp, KERNFRAME_SIZ
 	REG_S	s8, TF_BASE+TF_REG_S8(sp)
 	REG_S	gp, TF_BASE+TF_REG_GP(sp)
-	PTR_L	t8, CPU_INFO_CURLWP(k0)
 #if defined(__mips_o32) || defined(__mips_o64)
 	PTR_ADDU v0, sp, TF_BASE
 	REG_S	v0, KERNFRAME_ARG5(sp)		# 5th arg is p. to trapframe
@@ -996,12 +1004,13 @@ NESTED_NOPROFILE(MIPSX(kern_nonmaskable_
 #if defined(__mips_n32) || defined(__mips_n64)
 	PTR_ADDU a4, sp, TF_BASE		# 5th arg is p. to trapframe
 #endif
+	PTR_L	MIPS_CURLWP, CPU_INFO_CURLWP(k1)
+	move	s7, k1
 
 	/*
 	 * save PPL in trapframe
 	 */
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
-	INT_L	t1, CPU_INFO_CPL(t0)		# get current priority level
+	INT_L	t1, CPU_INFO_CPL(s7)		# get current priority level
 	INT_S	t1, TF_BASE+TF_PPL(sp)		# save priority level
 
 #if defined(__mips_o32) && (defined(DDB) || defined(DEBUG) || defined(KGDB))
@@ -1059,17 +1068,18 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	.set	noat
 	.mask	0x80000000, -4
 #ifdef PARANOIA
-	PTR_L	k0, L_PCB(MIPS_CURLWP)
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)
 	slt	k0, k0, sp			# k0 = L_PCB(MIPS_CURLWP) < sp
 1:	beqz	k0, 1b				# loop forever if false
 	 nop
-	PTR_L	k0, L_PCB(MIPS_CURLWP)
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)
 	PTR_ADDU k0, USPACE
 	slt	k0, sp, k0			# k0 = sp < L_PCB(MIPS_CURLWP) + USPACE
 2:	beqz	k0, 2b				# loop forever if false
 	 nop
-	PTR_L	k0, L_CPU(MIPS_CURLWP)
-	INT_L	k0, CPU_INFO_IDEPTH(k0)		# grab interrupt depth
+	INT_L	k0, CPU_INFO_IDEPTH(k1)		# grab interrupt depth
 	sltu	k0, k0, 3			# must be < 3
 3:	beqz	k0, 3b				# loop forever if false
 	 nop
@@ -1077,7 +1087,7 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	/*
 	 * Save the relevant kernel registers onto the stack.  We don't need
 	 * to save s0 - s8, sp, and gp because the compiler does it for us.
-	 * But we use s0-s2 so need to save them.
+	 * But we use s0,s1,s7 so need to save them.
 	 */
 	PTR_SUBU sp, KERNFRAME_SIZ
 	REG_S	AT, TF_BASE+TF_REG_AST(sp)
@@ -1100,7 +1110,7 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	REG_S	s0, TF_BASE+TF_REG_S0(sp)	# used for saved ipl/idepth
 	REG_S	s1, TF_BASE+TF_REG_S1(sp)	# used for initial status
 	mfc0	s1, MIPS_COP_0_STATUS
-	REG_S	s2, TF_BASE+TF_REG_S2(sp)	# used for cpu_info
+	REG_S	s7, TF_BASE+TF_REG_S7(sp)	# used for cpu_info
 #ifdef DDB
 	REG_S	t8, TF_BASE+TF_REG_T8(sp)	# already contains MIPS_CURLWP
 #endif
@@ -1113,7 +1123,8 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
  * Call the interrupt handler.
  */
 	_MFC0	ta0, MIPS_COP_0_EXC_PC		# grab exception PC
-	PTR_L	s2, L_CPU(MIPS_CURLWP)		# delay slot
+	PTR_L	MIPS_CURLWP, CPU_INFO_CURLWP(k1)
+	move	s7, k1
 	REG_S	ta0, TF_BASE+TF_REG_EPC(sp)	# and save it
 
 #if defined(DDB) || defined(DEBUG) || defined(KGDB)
@@ -1121,7 +1132,7 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 #endif
 
 #ifdef PARANOIA
-	INT_L	s0, CPU_INFO_CPL(s2)
+	INT_L	s0, CPU_INFO_CPL(s7)
 	INT_S	s0, TF_BASE+TF_PPL(sp)		# save priority level
 
 	/*
@@ -1155,10 +1166,10 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	 nop
 #endif /* PARANOIA */
 
-	INT_L	t1, CPU_INFO_IDEPTH(s2)		# we need to inc. intr depth
+	INT_L	t1, CPU_INFO_IDEPTH(s7)		# we need to inc. intr depth
 	or	s0, t1				#   save old interrupt depth
 	INT_ADDU t1, 1
-	INT_S	t1, CPU_INFO_IDEPTH(s2)		#   store new interrupt depth
+	INT_S	t1, CPU_INFO_IDEPTH(s7)		#   store new interrupt depth
 
 	/*
 	 * Now we can clear exception level since no interrupts can be delivered
@@ -1179,7 +1190,7 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	 srl	a0, s0, 8			# 1st arg is previous pri level
 
 	and	t1, s0, 0xff			# get previous interrupt depth
-	INT_S	t1, CPU_INFO_IDEPTH(s2)		# to it previous value
+	INT_S	t1, CPU_INFO_IDEPTH(s7)		# to it previous value
 
 #if defined(PARANOIA)
 	mfc0	t0, MIPS_COP_0_STATUS		# verify INT_IE is still set
@@ -1203,6 +1214,7 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	beqz	a0, 4f				#   nope
 	 nop
 
+	srl	a1, s0, 8			# get saved priority level
 	jal	_C_LABEL(softint_process)	# softint_process(pending)
 	 nop
 
@@ -1210,12 +1222,12 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	srl	v1, s0, 8			# get saved priority level
 	bnez	v1, 4f				# branch if not at IPL_NONE
 	 nop
-	INT_L	t0, CPU_INFO_SOFTINTS(s2)	# get pending softints
+	INT_L	t0, CPU_INFO_SOFTINTS(s7)	# get pending softints
 	and	v0, t0, 1 << SOFTINT_KPREEMPT	# do we need a kernel preempt?
 	beqz	v0, 4f				#   nope
 	 nop
 	xor	t0, v0				# clear preempt bit
-	INT_S	t0, CPU_INFO_SOFTINTS(s2)	# and save it.
+	INT_S	t0, CPU_INFO_SOFTINTS(s7)	# and save it.
 
 	jal	_C_LABEL(splx_noprof)		# drop to IPL_SCHED
 	 li	a0, IPL_SCHED
@@ -1276,12 +1288,12 @@ NESTED_NOPROFILE(MIPSX(kern_intr), KERNF
 	COP0_SYNC
 
 	/*
-	 * Restore s0-s2 and goto common kernel return code.
+	 * Restore s0,s1,s7 and goto common kernel return code.
 	 */
 	REG_L	s0, TF_BASE+TF_REG_S0(sp)
 	REG_L	s1, TF_BASE+TF_REG_S1(sp)
 	b	MIPSX(kern_return)
-	 REG_L	s2, TF_BASE+TF_REG_S2(sp)
+	 REG_L	s7, TF_BASE+TF_REG_S7(sp)
 	.set	at
 END(MIPSX(kern_intr))
 
@@ -1296,8 +1308,9 @@ NESTED_NOPROFILE(MIPSX(user_reserved_ins
 	 * Save a minimum of registers to see if this is rdhwr $3,$29
 	 */
 	KERN_ENTRY_ERRATA
-	/* K1 already has CURLWP */
-	PTR_L	k0, L_PCB(k1)			# XXXuvm_lwp_getuarea
+	/* K1 has CURCPU */
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)			# XXXuvm_lwp_getuarea
 	PTR_ADDU k0, USPACE - TF_SIZ - CALLFRAME_SIZ
 
 	/* Need two working registers */
@@ -1335,10 +1348,13 @@ NESTED_NOPROFILE(MIPSX(user_reserved_ins
 	_MTC0	v0, MIPS_COP_0_EXC_PC
 	COP0_SYNC
 
-	PTR_L	v1, L_PRIVATE(k1)		# rdhwr $3,$29 updates v1
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	v1, L_PRIVATE(k0)		# rdhwr $3,$29 updates v1
 
 	REG_L	AT, CALLFRAME_SIZ+TF_REG_AST(k0)# restore reg
 	REG_L	v0, CALLFRAME_SIZ+TF_REG_V0(k0) # restore reg
+	li	k0, 0x1150
+	li	k1, 0x1151
 	eret
 END(MIPSX(user_reserved_insn))
 
@@ -1358,8 +1374,9 @@ NESTED_NOPROFILE(MIPSX(user_gen_exceptio
 	 * Save all the registers except the kernel temporaries onto the stack.
 	 */
 	KERN_ENTRY_ERRATA
-	/* K1 already has CURLWP */
-	PTR_L	k0, L_PCB(k1)			# XXXuvm_lwp_getuarea
+	/* K1 has CURCPU */
+	PTR_L	k0, CPU_INFO_CURLWP(k1)
+	PTR_L	k0, L_PCB(k0)			# XXXuvm_lwp_getuarea
 	PTR_ADDU k0, USPACE - TF_SIZ - CALLFRAME_SIZ
 	REG_S	AT, CALLFRAME_SIZ+TF_REG_AST(k0)
 	REG_S	v0, CALLFRAME_SIZ+TF_REG_V0(k0)
@@ -1405,7 +1422,8 @@ MIPSX(user_gen_exception_common):
 	PTR_LA	gp, _C_LABEL(_gp)		# switch to kernel GP
 #endif
 	move	sp, k0				# switch to kernel SP
-	move	MIPS_CURLWP, k1
+	PTR_L	MIPS_CURLWP, CPU_INFO_CURLWP(k1)
+	move	s7, k1
 #ifdef NOFPU
 	/*
 	 * enter kernel mode
@@ -1470,8 +1488,9 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
  * We don't need to save s0 - s8 because the compiler does it for us.
  */
 	KERN_ENTRY_ERRATA
-	/* k1 contains curlwp */
-	PTR_L	k0, L_PCB(k1)			# XXXuvm_lwp_getuarea
+	/* k1 contains curcpu */
+	PTR_L	k0, CPU_INFO_CURLWP(k1)		# curlwp
+	PTR_L	k0, L_PCB(k0)			# XXXuvm_lwp_getuarea
 	PTR_ADDU k0, USPACE - TF_SIZ - CALLFRAME_SIZ
 	REG_S	AT, CALLFRAME_SIZ+TF_REG_AST(k0)	# $1
 	REG_S	v0, CALLFRAME_SIZ+TF_REG_V0(k0)		# $2
@@ -1494,6 +1513,7 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	REG_S	s0, CALLFRAME_SIZ+TF_REG_S0(k0)		# $16
 	REG_S	s1, CALLFRAME_SIZ+TF_REG_S1(k0)		# $17
 	mfc0	s1, MIPS_COP_0_STATUS
+	REG_S	s7, CALLFRAME_SIZ+TF_REG_S7(k0)
 	REG_S	t8, CALLFRAME_SIZ+TF_REG_T8(k0)		# $24 MIPS_CURLWP
 	REG_S	t9, CALLFRAME_SIZ+TF_REG_T9(k0)		# $25
 	REG_S	gp, CALLFRAME_SIZ+TF_REG_GP(k0)		# $28
@@ -1506,7 +1526,8 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	REG_S	ta0, CALLFRAME_SIZ+TF_REG_EPC(k0)
 	REG_S	t0, CALLFRAME_SIZ+TF_REG_CAUSE(k0)
 	move	sp, k0				# switch to kernel SP
-	move	MIPS_CURLWP, k1			# set curlwp reg (t8)
+	PTR_L	MIPS_CURLWP, CPU_INFO_CURLWP(k1)	# set curlwp reg (t8)
+	move	s7, k1
 #if defined(DDB) || defined(DEBUG) || defined(KGDB)
 	REG_S	ta0, CALLFRAME_RA(sp)		# for debugging
 #endif
@@ -1547,9 +1568,8 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	/*
 	 * Since we interrupted user mode, the new interrupt depth must be 1.
 	 */
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
 	li	t1, 1
-	INT_S	t1, CPU_INFO_IDEPTH(t0)		# store new interrupt depth (1)
+	INT_S	t1, CPU_INFO_IDEPTH(s7)		# store new interrupt depth (1)
 
 	/*
 	 * Now hard interrupts can be processed.
@@ -1562,8 +1582,7 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	/*
 	 * Interrupt depth is now back to 0.
 	 */
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
-	INT_S	zero, CPU_INFO_IDEPTH(t0)
+	INT_S	zero, CPU_INFO_IDEPTH(s7)
 
 #ifdef __HAVE_FAST_SOFTINTS
 	/*
@@ -1581,6 +1600,7 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	and	a0, MIPS_SOFT_INT_MASK		# are there softints pending
 	beqz	a0, 4f				#   nope
 	 nop
+	xor	a1, a1
 	jal	_C_LABEL(softint_process)	# softint_process(pending)
 	 nop
 4:
@@ -1608,8 +1628,10 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	/*
 	 * Check pending asynchronous traps.
 	 */
+	move	t0, s7				# curcpu
 	REG_L	s0, CALLFRAME_SIZ+TF_REG_S0(sp)	# restore
 	REG_L	s1, CALLFRAME_SIZ+TF_REG_S1(sp)	# restore
+	REG_L	s7, CALLFRAME_SIZ+TF_REG_S7(sp)	# restore
 	INT_L	v0, L_MD_ASTPENDING(MIPS_CURLWP)# any pending ast?
 	beqz	v0, MIPSX(user_intr_return)	# if no, skip ast processing
 	 nop
@@ -1625,8 +1647,9 @@ NESTED_NOPROFILE(MIPSX(user_intr), CALLF
 	REG_S	s4, CALLFRAME_SIZ+TF_REG_S4(sp)	# $20
 	REG_S	s5, CALLFRAME_SIZ+TF_REG_S5(sp)	# $21
 	REG_S	s6, CALLFRAME_SIZ+TF_REG_S6(sp)	# $22
-	REG_S	s7, CALLFRAME_SIZ+TF_REG_S7(sp)	# $23
+	#REG_S	s7, CALLFRAME_SIZ+TF_REG_S7(sp)	# $23 (saved above)
 	REG_S	s8, CALLFRAME_SIZ+TF_REG_S8(sp)	# $30
+	move	s7, t0				# curcpu
 #if !defined(MIPS_DYNAMIC_STATUS_MASK) && defined(MIPSNNR2)
 	ei					# enable interrupts
 #else
@@ -1659,8 +1682,9 @@ NESTED_NOPROFILE(MIPSX(systemcall), CALL
 	 * Save all the registers but kernel temporaries onto the stack.
 	 */
 	KERN_ENTRY_ERRATA
-	/* k1 already contains curlwp */
-	PTR_L	k0, L_PCB(k1)			# XXXuvm_lwp_getuarea
+	/* k1 contains curcpu */
+	PTR_L	k0, CPU_INFO_CURLWP(k1)		# curlwp
+	PTR_L	k0, L_PCB(k0)			# XXXuvm_lwp_getuarea
 	PTR_ADDU k0, USPACE - TF_SIZ - CALLFRAME_SIZ
 	#REG_S	AT, CALLFRAME_SIZ+TF_REG_AST(k0)
 	#.set	at
@@ -1708,8 +1732,9 @@ NESTED_NOPROFILE(MIPSX(systemcall), CALL
 	REG_S	v0, CALLFRAME_SIZ+TF_REG_MULLO(k0)
 	REG_S	v1, CALLFRAME_SIZ+TF_REG_MULHI(k0)
 	REG_S	a3, CALLFRAME_SIZ+TF_REG_EPC(k0)
-	move	MIPS_CURLWP, k1			# set curlwp reg
 	move	sp, k0				# switch to kernel SP
+	PTR_L	MIPS_CURLWP, CPU_INFO_CURLWP(k1)	# set curlwp reg
+	move	s7, k1
 #ifdef __GP_SUPPORT__
 	PTR_LA	gp, _C_LABEL(_gp)		# switch to kernel GP
 #endif
@@ -1798,6 +1823,8 @@ NESTED_NOPROFILE(MIPSX(cache_exception),
 	mtc0	k0, MIPS_COP_0_STATUS		# restore status
 	COP0_SYNC
 
+	li	k0, 0x1160
+	li	k1, 0x1161
 	eret
 
 #if defined(MIPS64_XLS)
@@ -1838,25 +1865,27 @@ END(MIPSX(cache_exception))
  */
 LEAF_NOPROFILE(MIPSX(kern_tlb_invalid_exception))
 	.set	noat
+	PTR_ADDU sp, -SZREG
+	PTR_S	k1, (sp)
 	_MFC0	k0, MIPS_COP_0_BAD_VADDR	# get the fault address
 #if !defined(_LP64) && (MIPS64 + MIPS64R2) > 0
 #if VM_MIN_KERNEL_ADDRESS == MIPS_KSEG2_START
 	li	k1, VM_MIN_KERNEL_ADDRESS	# compute index
 	slt	k1, k0, k1
-	bnez	k1, _C_LABEL(MIPSX(kern_gen_exception)) # full trap processing
+	bnez	k1, _C_LABEL(MIPSX(kern_gen_exception1)) # full trap processing
 	 nop
 #elif VM_MIN_KERNEL_ADDRESS > MIPS_XKSEG_START
 	li	k1, VM_MIN_KERNEL_ADDRESS>>32	# compute index
 	dsll32	k1, k1, 0
 	slt	k1, k0, k1
-	bnez	k1, _C_LABEL(MIPSX(kern_gen_exception)) # full trap processing
+	bnez	k1, _C_LABEL(MIPSX(kern_gen_exception1)) # full trap processing
 	 nop
 #endif
 #endif /* !_LP64 && (MIPS64 + MIPS64R2) > 0 */
 	PTR_LA	k1, _C_LABEL(pmap_limits)
 	PTR_L	k1, PMAP_LIMITS_VIRTUAL_END(k1)
 	PTR_SUBU k1, k0
-	blez	k1, _C_LABEL(MIPSX(kern_gen_exception)) # full trap processing
+	blez	k1, _C_LABEL(MIPSX(kern_gen_exception1)) # full trap processing
 	 nop
 	PTR_LA	k1, _C_LABEL(pmap_kern_segtab)
 #ifdef _LP64
@@ -1870,7 +1899,7 @@ LEAF_NOPROFILE(MIPSX(kern_tlb_invalid_ex
 #endif
 	_MFC0	k0, MIPS_COP_0_BAD_VADDR	# get the fault address (again)
 	PTR_L	k1, (k1)			# load segtab address
-	beqz	k1, _C_LABEL(MIPSX(kern_gen_exception))
+	beqz	k1, _C_LABEL(MIPSX(kern_gen_exception1))
 	 nop
 #endif /* _LP64 */
 #ifdef MIPSNNR2
@@ -1883,7 +1912,7 @@ LEAF_NOPROFILE(MIPSX(kern_tlb_invalid_ex
 #endif
 	_MFC0	k0, MIPS_COP_0_BAD_VADDR	# get the fault address (again)
 	PTR_L	k1, (k1)			# load page table address
-	beqz	k1, _C_LABEL(MIPSX(kern_gen_exception))
+	beqz	k1, _C_LABEL(MIPSX(kern_gen_exception1))
 	 nop
 #ifdef MIPSNNR2
 	_EXT	k0, k0, PGSHIFT, PTPLENGTH
@@ -1898,7 +1927,7 @@ LEAF_NOPROFILE(MIPSX(kern_tlb_invalid_ex
 
 	mfc0	k0, MIPS_COP_0_TLB_INDEX
 	MFC0_HAZARD
-	bltz	k0, _C_LABEL(MIPSX(kern_gen_exception)) # ASSERT(TLB entry exists)
+	bltz	k0, _C_LABEL(MIPSX(kern_gen_exception1)) # ASSERT(TLB entry exists)
 	 nop					# - delay slot -
 
 	and	k0, k1, 4			# check even/odd page
@@ -1920,7 +1949,7 @@ LEAF_NOPROFILE(MIPSX(kern_tlb_invalid_ex
 #ifdef MIPS3
 	nop					# required for QED5230
 #endif
-	beqz	k0, _C_LABEL(MIPSX(kern_gen_exception))	# PTE invalid
+	beqz	k0, _C_LABEL(MIPSX(kern_gen_exception1))	# PTE invalid
 	 nop					# - delay slot -
 
 	INT_L	k0, 4(k1)			# get odd PTE entry
@@ -1950,6 +1979,9 @@ LEAF_NOPROFILE(MIPSX(kern_tlb_invalid_ex
 	nop
 	nop
 #endif
+	PTR_ADDU sp, SZREG
+	li	k0, 0x1170
+	li	k1, 0x1171
 	eret
 
 MIPSX(kern_tlbi_odd):
@@ -1966,7 +1998,7 @@ MIPSX(kern_tlbi_odd):
 #ifdef MIPS3
 	nop					# required for QED5230
 #endif
-	beqz	k0, _C_LABEL(MIPSX(kern_gen_exception))	# PTE invalid
+	beqz	k0, _C_LABEL(MIPSX(kern_gen_exception1))	# PTE invalid
 	 nop					# - delay slot -
 
 	INT_L	k0, -4(k1)			# get even PTE entry
@@ -1995,7 +2027,16 @@ MIPSX(kern_tlbi_odd):
 	nop
 	nop
 #endif
+	PTR_ADDU sp, SZREG
+	li	k0, 0x1180
+	li	k1, 0x1181
 	eret
+
+MIPSX(kern_gen_exception1):
+	PTR_L	k1, (sp)
+	PTR_ADDU sp, SZREG
+	j	_C_LABEL(kern_gen_exception)
+
 END(MIPSX(kern_tlb_invalid_exception))
 #endif /* (PGSHIFT & 1) == 0 */
 
@@ -2620,6 +2661,7 @@ END(MIPSX(tlb_record_asids))
  * and s1 respectively.  There is no need register save operation.
  */
 LEAF(MIPSX(lwp_trampoline))
+	REG_L	s7, L_CPU(MIPS_CURLWP)
 	PTR_ADDU sp, -CALLFRAME_SIZ
 
 	# Call lwp_startup(), with args from cpu_switchto()/cpu_lwp_fork()
@@ -2641,6 +2683,7 @@ LEAF(MIPSX(lwp_trampoline))
 	#
 	.set	noat
 MIPSX(user_return):
+	move	t0, s7
 	REG_L	s0, CALLFRAME_SIZ+TF_REG_S0(sp)		# $16
 	REG_L	s1, CALLFRAME_SIZ+TF_REG_S1(sp)		# $17
 	REG_L	s2, CALLFRAME_SIZ+TF_REG_S2(sp)		# $18
@@ -2652,7 +2695,6 @@ MIPSX(user_return):
 	REG_L	s8, CALLFRAME_SIZ+TF_REG_S8(sp)		# $30
 MIPSX(user_intr_return):
 #ifdef PARANOIA
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
 	INT_L	t1, CPU_INFO_CPL(t0)			# get curcpu()->ci_cpl
 2:	bnez	t1, 2b
 	 nop
@@ -2693,6 +2735,8 @@ MIPSX(user_intr_return):
 	REG_L	ra, CALLFRAME_SIZ+TF_REG_RA(k1)		# $31
 	mtc0	k0, MIPS_COP_0_STATUS
 	COP0_SYNC
+	li	k0, 0x3330
+	li	k1, 0x3331
 	eret
 	.set	at
 END(MIPSX(lwp_trampoline))
@@ -2903,6 +2947,8 @@ LEAF_NOPROFILE(MIPSX(VCED))
 	LONG_ADDU k0, 1
 	LONG_S	k0, 0(k1)
 #endif
+	li	k0, 0x1110
+	li	k1, 0x1111
 	eret
 	.set	at
 
@@ -2938,6 +2984,8 @@ LEAF_NOPROFILE(MIPSX(VCEI))
 	PTR_ADDU k0, 1
 	LONG_S	k0, 0(k1)
 #endif
+	li	k0, 0x1120
+	li	k1, 0x1121
 	eret
 	.set	at
 
Index: sys/arch/mips/mips/mips_fixup.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_fixup.c,v
retrieving revision 1.20
diff -p -u -r1.20 mips_fixup.c
--- sys/arch/mips/mips/mips_fixup.c	6 Apr 2019 03:06:26 -0000	1.20
+++ sys/arch/mips/mips/mips_fixup.c	12 Jul 2019 20:55:34 -0000
@@ -44,6 +44,10 @@ __KERNEL_RCSID(0, "$NetBSD: mips_fixup.c
 #include <mips/regnum.h>
 #include <mips/mips_opcode.h>
 
+#ifndef DEBUG_VERBOSE
+#define DEBUG_VERBOSE 1
+#endif
+
 bool
 mips_fixup_exceptions(mips_fixup_callback_t callback, void *arg)
 {
@@ -145,6 +149,25 @@ mips_fixup_exceptions(mips_fixup_callbac
 				}
 				lui_insnp = NULL;
 			}
+		} else if (lui_insn != 0 && INSN_ADDIU_P(insn)) {
+			size_t reg = (insn >> 16) & 31;
+			int32_t load_addr = lui_offset + (int16_t)insn;
+			if (addr <= load_addr && load_addr < addr + size &&
+				reg == lui_reg) {
+#ifdef DEBUG_VERBOSE
+				printf("%s: %#x: insn %08x: ori r%zu, %%lo(%#x)\n",
+				    __func__, (int32_t)(intptr_t)insnp,
+				    insn, reg, load_addr);
+#endif
+				new_insns[0] = lui_insn;
+				new_insns[1] = *insnp;
+				if ((callback)(load_addr, new_insns, arg)) {
+					*lui_insnp = new_insns[0];
+					*insnp = new_insns[1];
+					fixed = true;
+				}
+				lui_insnp = NULL;
+			}
 		} else if (INSN_LOAD_P(insn)) {
 			/*
 			 * If we are loading the register used in the LUI,
@@ -625,14 +648,14 @@ void
 mutex_spin_enter(kmutex_t *mtx)
 {
 
-	(*mips_locore_atomicvec.lav_mutex_spin_enter)(mtx);
+	(*mips_locore_atomicvec.lav_mutex_spin_enter)(mtx, curcpu());
 }
 
 void
 mutex_spin_exit(kmutex_t *mtx)
 {
 
-	(*mips_locore_atomicvec.lav_mutex_spin_exit)(mtx);
+	(*mips_locore_atomicvec.lav_mutex_spin_exit)(mtx, curcpu());
 }
 #endif	/* !LOCKDEBUG */
 
Index: sys/arch/mips/mips/mips_softint.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_softint.c,v
retrieving revision 1.7
diff -p -u -r1.7 mips_softint.c
--- sys/arch/mips/mips/mips_softint.c	6 Jun 2015 04:43:41 -0000	1.7
+++ sys/arch/mips/mips/mips_softint.c	12 Jul 2019 20:55:34 -0000
@@ -106,11 +106,13 @@ softint_trigger(uintptr_t si)
 	}
 
 void
-softint_process(uint32_t ipending)
+softint_process(uint32_t ipending, int ipl)
 {
 	struct cpu_info * const ci = curcpu();
 	u_int mask;
 
+	KASSERTMSG(ipl < IPL_VM, "%s: cpu%u (%p): ipl %d too high",
+		__func__, cpu_index(ci), ci, ipl);
 	KASSERT((ipending & MIPS_SOFT_INT_MASK) != 0);
 	KASSERT((ipending & ~MIPS_SOFT_INT_MASK) == 0);
 	KASSERT(ci->ci_cpl == IPL_HIGH);
@@ -119,16 +121,11 @@ softint_process(uint32_t ipending)
 	    "%s: cpu%u (%p): ci_mtx_count (%d) != 0",
 	     __func__, cpu_index(ci), ci, ci->ci_mtx_count);
 
-	if (ipending & MIPS_SOFT_INT_MASK_0) {
-		/*
-		 * Since we run at splhigh, 
-		 */
-		mask = SOFTINT_MASK_1 | SOFTINT_MASK_0;
-		ipending |= MIPS_SOFT_INT_MASK_1;
-	} else {
-		KASSERT(ipending & MIPS_SOFT_INT_MASK_1);
-		mask = SOFTINT_MASK_1;
-	}
+	mask = 0;
+	if (ipending & MIPS_SOFT_INT_MASK_1)
+		mask |= SOFTINT_MASK_1;
+	if (ipending & MIPS_SOFT_INT_MASK_0)
+		mask |= SOFTINT_MASK_0;
 
 	for (;;) {
 		u_int softints = ci->ci_softints & mask;
Index: sys/arch/mips/mips/netbsd32_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/netbsd32_machdep.c,v
retrieving revision 1.18
diff -p -u -r1.18 netbsd32_machdep.c
--- sys/arch/mips/mips/netbsd32_machdep.c	1 Mar 2019 11:06:55 -0000	1.18
+++ sys/arch/mips/mips/netbsd32_machdep.c	12 Jul 2019 20:55:34 -0000
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_mac
 #include <sys/buf.h>
 #include <sys/signal.h>
 #include <sys/signalvar.h>
+#include <sys/ptrace.h>
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
 #include <sys/compat_stub.h>
@@ -272,11 +273,16 @@ int
 cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
     struct core32 *chdr)
 {
-	int error;
+	int error, i;
 	struct coreseg cseg;
 	struct cpustate {
-		struct trapframe frame;
-		struct fpreg fpregs;
+		struct {
+			/* 32bit trap frame */
+			struct reg32 tf_registers;
+			uint32_t tf_ppl;
+			__register32_t tf_pad;
+		} frame; 
+		struct fpreg32 fpregs;
 	} cpustate;
 
 	if (iocookie == NULL) {
@@ -291,8 +297,22 @@ cpu_coredump32(struct lwp *l, struct cor
 	fpu_save(l);
 
 	struct pcb * const pcb = lwp_getpcb(l);
-	cpustate.frame = *l->l_md.md_utf;
-	cpustate.fpregs = pcb->pcb_fpregs;
+	struct trapframe *tf = l->l_md.md_utf;
+	struct reg *rp = &tf->tf_registers;
+	struct fpreg *fp = &pcb->pcb_fpregs;
+
+	for (i=0; i<__arraycount(cpustate.frame.tf_registers.r_regs); ++i) {
+		cpustate.frame.tf_registers.r_regs[i] = rp->r_regs[i];
+		if (cpustate.frame.tf_registers.r_regs[i] != rp->r_regs[i])
+			printf("%s: reg[%d] truncated\n", __func__, i);
+	}
+	cpustate.frame.tf_ppl = tf->tf_ppl;
+	cpustate.frame.tf_pad = tf->tf_pad;
+	for (i=0; i<__arraycount(cpustate.fpregs.r_regs); ++i) {
+		cpustate.fpregs.r_regs[i] = fp->r_regs[i];
+		if (cpustate.fpregs.r_regs[i] != fp->r_regs[i])
+			printf("%s: fpreg[%d] truncated\n", __func__, i);
+	}
 
 	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
 	cseg.c_addr = 0;
@@ -339,4 +359,75 @@ netbsd32_machdep_md_fini(void)
 	MODULE_HOOK_UNSET(netbsd32_machine32_hook);
 }
 
+int
+netbsd32_ptrace_translate_request(int req)
+{
 
+        switch (req)
+        {
+        case 0 ... PT_FIRSTMACH - 1:    return req;
+        case PT32_GETREGS:              return PT_GETREGS;
+        case PT32_SETREGS:              return PT_SETREGS;
+        case PT32_GETFPREGS:            return PT_GETFPREGS;
+        case PT32_SETFPREGS:            return PT_SETFPREGS;
+#ifdef PT_STEP
+        case PT32_STEP:                 return PT_STEP;
+        case PT32_SETSTEP:              return PT_SETSTEP;
+        case PT32_CLEARSTEP:            return PT_CLEARSTEP;
+#endif
+        default:                        return -1; 
+        }
+}
+
+int
+netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
+{
+	struct trapframe *tf = l->l_md.md_utf;
+	int i;
+
+	for (i=0; i<__arraycount(regs->r_regs); ++i)
+		regs->r_regs[i] = tf->tf_registers.r_regs[i];
+	return 0;
+}
+
+int
+netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *regs, size_t *sz)
+{
+	struct pcb * const pcb = lwp_getpcb(l);
+	int i;
+        KASSERT(*sz == sizeof(struct fpreg32));
+
+        fpu_save(l);
+	for (i=0; i<__arraycount(regs->r_regs); ++i)
+		regs->r_regs[i] = pcb->pcb_fpregs.r_regs[i];
+	return 0;
+}
+
+int
+netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs)
+{
+	struct trapframe *tf = l->l_md.md_utf;
+	int i;
+
+	for (i=0; i<__arraycount(tf->tf_registers.r_regs); ++i)
+		tf->tf_registers.r_regs[i] = regs->r_regs[i];
+	return 0;
+}
+
+int
+netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs,
+    size_t sz)
+{
+	struct pcb * const pcb = lwp_getpcb(l);
+	int i;
+	KASSERT(sz == sizeof(struct fpreg32));
+ 
+#ifndef NOFPU 
+	/* to load FPA contents next time when FP insn is executed */
+	fpu_discard(l);
+#endif /* !NOFPU */
+ 
+	for (i=0; i<__arraycount(pcb->pcb_fpregs.r_regs); ++i)
+		pcb->pcb_fpregs.r_regs[i] = regs->r_regs[i];
+        return 0; 
+}
Index: sys/arch/mips/mips/spl.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/spl.S,v
retrieving revision 1.17
diff -p -u -r1.17 spl.S
--- sys/arch/mips/mips/spl.S	12 Apr 2019 21:12:21 -0000	1.17
+++ sys/arch/mips/mips/spl.S	12 Jul 2019 20:55:34 -0000
@@ -66,10 +66,9 @@ _splraise:
 	/*
 	 * a0 = SR bits to be cleared for this IPL
 	 * a1 = this IPL (IPL_*)
+	 * a3 = struct cpu_info *
 	 * Can only use a0-a3 and v0-v1
 	 */
-	PTR_L	a3, L_CPU(MIPS_CURLWP)
-	NOP_L					# load delay
 	INT_L	v0, CPU_INFO_CPL(a3)		# get current IPL from cpu_info
 	NOP_L					# load delay
 	sltu	v1, a1, v0			# newipl < curipl
@@ -88,10 +87,6 @@ _splraise:
 	mtc0	zero, MIPS_COP_0_STATUS		## disable interrupts
 #endif
 	COP0_SYNC
-#ifdef MULTIPROCESSOR
-	PTR_L	a3, L_CPU(MIPS_CURLWP)		## make sure curcpu is correct
-	NOP_L					## load delay
-#endif
 	INT_S	a1, CPU_INFO_CPL(a3)		## save IPL in cpu_info
 	mtc0	a0, MIPS_COP_0_STATUS		## store back
 	COP0_SYNC
@@ -112,13 +107,12 @@ _splraise:
 
 STATIC_LEAF(_splsw_splx)
 STATIC_XLEAF(_splsw_splx_noprof)		# does not get mcount hooks
+	move	a3, a1				# curcpu
 #ifdef PARANOIA
 	sltiu	v0, a0, IPL_HIGH+1		# v0 = a0 <= IPL_HIGH
 98:	beqz	v0, 98b
 	 nop
 #endif
-	PTR_L	a3, L_CPU(MIPS_CURLWP)		# get cpu_info
-	NOP_L					# load delay
 	INT_L	a2, CPU_INFO_CPL(a3)		# get IPL from cpu_info
 	NOP_L					# load delay
 	beq	a0, a2, 2f			# if same, nothing to do
@@ -171,7 +165,7 @@ END(_splsw_splx)
 
 STATIC_LEAF(_splsw_spl0)
 	INT_L	v1, _C_LABEL(ipl_sr_map) + 4*IPL_NONE
-	PTR_L	a3, L_CPU(MIPS_CURLWP)
+	move	a3, a0				# curcpu
 	or	v1, MIPS_SR_INT_IE		# make sure interrupts are on
 	xor	v1, MIPS_INT_MASK		# invert
 	mfc0	a0, MIPS_COP_0_STATUS
@@ -236,6 +230,7 @@ STATIC_LEAF(_splsw_clrsoftintr)
 END(_splsw_clrsoftintr)
 
 STATIC_LEAF(_splsw_splraise)
+	move	a3, a1
 #if defined(DDB) && __mips >= 32
 	tgeiu	a0, IPL_HIGH+1
 #endif
@@ -249,8 +244,7 @@ END(_splsw_splraise)
 
 STATIC_LEAF(_splsw_splhigh)
 STATIC_XLEAF(_splsw_splhigh_noprof)
-	PTR_L	a3, L_CPU(MIPS_CURLWP)
-	NOP_L					# load delay
+	move	a3, a0				# curcpu
 	INT_L	v0, CPU_INFO_CPL(a3)		# get current IPL from cpu_info
 	li	a1, IPL_HIGH			# 
 	beq	v0, a1, 1f			# don't do anything if IPL_HIGH
@@ -262,10 +256,6 @@ STATIC_XLEAF(_splsw_splhigh_noprof)
 	DYNAMIC_STATUS_MASK(a0,a2)		# machine dependent masking
 	mtc0	a0, MIPS_COP_0_STATUS		## store back
 	COP0_SYNC
-#ifdef MULTIPROCESSOR
-	PTR_L	a3, L_CPU(MIPS_CURLWP)		## make sure curcpu is correct
-	NOP_L					## load delay
-#endif
 	INT_S	a1, CPU_INFO_CPL(a3)		## save IPL in cpu_info
 #ifdef PARANOIA
 	jr	ra				## return
@@ -285,6 +275,7 @@ END(_splsw_splhigh)
 
 	.p2align 4
 STATIC_LEAF(_splsw_splddb)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_DDB
 	b	_splraise
 	 li	a1, IPL_DDB
@@ -292,6 +283,7 @@ STATIC_LEAF(_splsw_splddb)
 END(_splsw_splddb)
 
 STATIC_LEAF(_splsw_splsched)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_SCHED
 	b	_splraise
 	 li	a1, IPL_SCHED
@@ -299,6 +291,7 @@ STATIC_LEAF(_splsw_splsched)
 END(_splsw_splsched)
 
 STATIC_LEAF(_splsw_splvm)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_VM
 	b	_splraise
 	 li	a1, IPL_VM
@@ -306,6 +299,7 @@ STATIC_LEAF(_splsw_splvm)
 END(_splsw_splvm)
 
 STATIC_LEAF(_splsw_splsoftserial)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTSERIAL
 	b	_splraise
 	 li	a1, IPL_SOFTSERIAL
@@ -313,6 +307,7 @@ STATIC_LEAF(_splsw_splsoftserial)
 END(_splsw_splsoftserial)
 
 STATIC_LEAF(_splsw_splsoftnet)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTNET
 	b	_splraise
 	 li	a1, IPL_SOFTNET
@@ -320,6 +315,7 @@ STATIC_LEAF(_splsw_splsoftnet)
 END(_splsw_splsoftnet)
 
 STATIC_LEAF(_splsw_splsoftbio)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTBIO
 	b	_splraise
 	 li	a1, IPL_SOFTBIO
@@ -327,6 +323,7 @@ STATIC_LEAF(_splsw_splsoftbio)
 END(_splsw_splsoftbio)
 
 STATIC_LEAF(_splsw_splsoftclock)
+	move	a3, a0				# curcpu
 	INT_L	a0, _C_LABEL(ipl_sr_map) + 4*IPL_SOFTCLOCK
 	b	_splraise
 	 li	a1, IPL_SOFTCLOCK
@@ -369,8 +366,7 @@ END(_splsw_splintr)
 
 STATIC_LEAF(_splsw_splcheck)
 #ifdef PARANOIA
-	PTR_L	t0, L_CPU(MIPS_CURLWP)
-	NOP_L					# load delay
+	move	t0, a0				# curcpu
 	INT_L	t1, CPU_INFO_CPL(t0)		# get current priority level
 
 	mfc0	t0, MIPS_COP_0_STATUS		# get current status
Index: sys/arch/mips/mips/spl_stubs.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/spl_stubs.c,v
retrieving revision 1.3
diff -p -u -r1.3 spl_stubs.c
--- sys/arch/mips/mips/spl_stubs.c	20 Feb 2011 16:38:13 -0000	1.3
+++ sys/arch/mips/mips/spl_stubs.c	12 Jul 2019 20:55:34 -0000
@@ -57,76 +57,83 @@ void	_setsoftintr(uint32_t)	__section(".
 void	_clrsoftintr(uint32_t)	__section(".stub");
 void	splcheck(void)		__section(".stub");
 
+extern struct callout_cpu callout_cpu0;
+
 int
 splhigh(void)
 {
-	return (*mips_splsw.splsw_splhigh)();
+	KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+	return (*mips_splsw.splsw_splhigh)(curcpu());
 }
 
 int
 splhigh_noprof(void)
 {
-	return (*mips_splsw.splsw_splhigh_noprof)();
+	KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+	return (*mips_splsw.splsw_splhigh_noprof)(curcpu());
 }
 
 int
 splsched(void)
 {
-	return (*mips_splsw.splsw_splsched)();
+	return (*mips_splsw.splsw_splsched)(curcpu());
 }
 
 int
 splvm(void)
 {
-	return (*mips_splsw.splsw_splvm)();
+	return (*mips_splsw.splsw_splvm)(curcpu());
 }
 
 int
 splsoftserial(void)
 {
-	return (*mips_splsw.splsw_splsoftserial)();
+	return (*mips_splsw.splsw_splsoftserial)(curcpu());
 }
 
 int
 splsoftnet(void)
 {
-	return (*mips_splsw.splsw_splsoftnet)();
+	return (*mips_splsw.splsw_splsoftnet)(curcpu());
 }
 
 int
 splsoftbio(void)
 {
-	return (*mips_splsw.splsw_splsoftbio)();
+	return (*mips_splsw.splsw_splsoftbio)(curcpu());
 }
 
 int
 splsoftclock(void)
 {
-	return (*mips_splsw.splsw_splsoftclock)();
+	return (*mips_splsw.splsw_splsoftclock)(curcpu());
 }
 
 void
 spl0(void)
 {
-	(*mips_splsw.splsw_spl0)();
+	(*mips_splsw.splsw_spl0)(curcpu());
 }
 
 void
 splx(int s)
 {
-	(*mips_splsw.splsw_splx)(s);
+	KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+	(*mips_splsw.splsw_splx)(s, curcpu());
 }
 
 void
 splx_noprof(int s)
 {
-	(*mips_splsw.splsw_splx_noprof)(s);
+	KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+	(*mips_splsw.splsw_splx_noprof)(s, curcpu());
 }
 
 int
 splraise(int s)
 {
-        return (*mips_splsw.splsw_splraise)(s);
+	KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+        return (*mips_splsw.splsw_splraise)(s, curcpu());
 }
 
 int
@@ -150,5 +157,6 @@ _clrsoftintr(uint32_t m)
 void
 splcheck(void)
 {
-	(*mips_splsw.splsw_splcheck)();
+	KASSERT(cpu_info_store.ci_data.cpu_callout == NULL || cpu_info_store.ci_data.cpu_callout == (void*)&callout_cpu0);
+	(*mips_splsw.splsw_splcheck)(curcpu());
 }
Index: sys/arch/mips/mips/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/trap.c,v
retrieving revision 1.249
diff -p -u -r1.249 trap.c
--- sys/arch/mips/mips/trap.c	6 Apr 2019 11:54:20 -0000	1.249
+++ sys/arch/mips/mips/trap.c	12 Jul 2019 20:55:34 -0000
@@ -617,13 +617,18 @@ trap(uint32_t status, uint32_t cause, va
 	    p->p_pid, p->p_comm, ksi.ksi_signo, cause,
 	    utf->tf_regs[_R_PC], vaddr);
 	printf("registers:\n");
+	int w = sizeof(utf->tf_regs[0]) * 2;
 	for (size_t i = 0; i < 32; i += 4) {
 		printf(
-		    "[%2zu]=%08"PRIxREGISTER" [%2zu]=%08"PRIxREGISTER
-		    " [%2zu]=%08"PRIxREGISTER" [%2zu]=%08"PRIxREGISTER "\n",
-		    i+0, utf->tf_regs[i+0], i+1, utf->tf_regs[i+1],
-		    i+2, utf->tf_regs[i+2], i+3, utf->tf_regs[i+3]);
+		    "[%2zu]=%0*"PRIxREGISTER" [%2zu]=%0*"PRIxREGISTER
+		    " [%2zu]=%0*"PRIxREGISTER" [%2zu]=%0*"PRIxREGISTER "\n",
+		    i+0, w, utf->tf_regs[i+0], i+1, w, utf->tf_regs[i+1],
+		    i+2, w, utf->tf_regs[i+2], i+3, w, utf->tf_regs[i+3]);
 	}
+#ifdef DDB
+	printf("%0*"PRIxREGISTER" ",w,utf->tf_regs[_R_PC]);
+	db_disasm(utf->tf_regs[_R_PC], false);
+#endif
 #endif
 	(*p->p_emul->e_trapsignal)(l, &ksi);
 	if ((type & T_USER) == 0) {
@@ -853,7 +858,7 @@ stacktrace_subr(mips_reg_t a0, mips_reg_
 	vaddr_t va, subr;
 	unsigned instr, mask;
 	InstFmt i;
-	int more, stksize;
+	int more, stksize, w4 = 0, w8;
 	unsigned int frames =  0;
 	int foundframesize = 0;
 	mips_reg_t regs[32] = {
@@ -972,8 +977,14 @@ mips3_eret:
 
 			case OP_ADD:
 			case OP_ADDU:
+			case OP_OR:
+			case OP_XOR:
+				w4 = 1;
+				/* FALLTHROUGH */
 			case OP_DADD:
 			case OP_DADDU:
+				w8 = !w4;
+				w4 = 0;
 				if (!(mask & (1 << i.RType.rd))
 				    || !(mask & (1 << i.RType.rt)))
 					break;
@@ -981,7 +992,7 @@ mips3_eret:
 					break;
 				mask |= (1 << i.RType.rs);
 				regs[i.RType.rs] = regs[i.RType.rt];
-				if (i.RType.func >= OP_DADD)
+				if (w8)
 					break;
 				regs[i.RType.rs] = (int32_t)regs[i.RType.rs];
 				break;
