? 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;