#include "opt_cputype.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_lockdebug.h"
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
#include <sys/errno.h>
#include <mips/asm.h>
#include <mips/cpuregs.h>
#include <mips/trap.h>
#include <mips/locore.h>
RCSID("$NetBSD: locore.S,v 1.232 2026/06/30 12:24:48 skrll Exp $")
#include "assym.h"
.set noreorder
EXPORT(start)
EXPORT_OBJECT(kernel_text) # libkvm refers this
mfc0 k0, MIPS_COP_0_STATUS
MFC0_HAZARD
and k0, ~MIPS_SR_INT_IE
mtc0 k0, MIPS_COP_0_STATUS
COP0_SYNC
and k0, MIPS_SR_TS | MIPS3_SR_RE
mtc0 k0, MIPS_COP_0_STATUS
mtc0 zero, MIPS_COP_0_CAUSE
COP0_SYNC
#if defined(_LP64)
mfc0 k0, MIPS_COP_0_STATUS
MFC0_HAZARD
or k0, MIPS_SR_KX | MIPS_SR_UX
mtc0 k0, MIPS_COP_0_STATUS
#elif defined(__mips_n32)
mfc0 k0, MIPS_COP_0_STATUS
MFC0_HAZARD
or k0, MIPS_SR_KX
mtc0 k0, MIPS_COP_0_STATUS
#endif
#ifdef HPCMIPS_L1CACHE_DISABLE
mfc0 t0, MIPS_COP_0_CONFIG
li t1, 0xfffffff8
and t0, t0, t1
or t0, 0x00000002 # XXX, KSEG0 is uncached
mtc0 t0, MIPS_COP_0_CONFIG
COP0_SYNC
#endif
#ifdef MIPS64_OCTEON
mfc0 a0, MIPS_COP_0_EBASE # EBASE
COP0_SYNC
andi a1, a0, MIPS_EBASE_CPUNUM # fetch cpunum
beqz a1, 2f # normal startup if 0
nop
#ifdef MULTIPROCESSOR
j _C_LABEL(octeon_cpu_spinup)
nop
#else
1: wait
b 1b
nop
#endif
2:
#endif
PTR_LA v1, start
slt v0, v1, sp
bne v0, zero, 1f
PTR_ADDU v0, v1, -CALLFRAME_SIZ
PTR_SUBU v0, v1, sp
slt v0, v0, 4096 # within 4KB of _start
beq v0, zero, 2f
PTR_ADDU v0, v1, -CALLFRAME_SIZ
1:
move sp, v0
2:
#ifdef __GP_SUPPORT__
PTR_LA gp, _C_LABEL(_gp)
#endif
mfc0 t0, MIPS_COP_0_PRID # read product revision ID
COP0_SYNC
nop
#ifdef NOFPU
li t1, 0 # Dummy FPU_ID
#else
mfc0 k0, MIPS_COP_0_STATUS
MFC0_HAZARD
or k0, MIPS_SR_COP_1_BIT
mtc0 k0, MIPS_COP_0_STATUS
COP0_HAZARD_FPUENABLE
cfc1 t1, MIPS_FIR
and k0, ~MIPS_SR_COP_1_BIT
mtc0 k0, MIPS_COP_0_STATUS
#endif
INT_S t0, _C_LABEL(mips_options)+MO_CPU_ID # save PRID register
INT_S t1, _C_LABEL(mips_options)+MO_FPU_ID # save FPU ID register
PTR_LA MIPS_CURLWP, _C_LABEL(lwp0) # set curlwp
jal _C_LABEL(mach_init) # mach_init(a0, a1, a2, a3)
nop
PTR_L sp, L_PCB(MIPS_CURLWP) # switch to lwp0 stack
NOP_L
PTR_ADDU sp, USPACE - TF_SIZ - CALLFRAME_SIZ
jal _C_LABEL(splhigh_noprof) # go to splhigh
nop
#if __mips_isa_rev >= 2
ei
#else
mfc0 v0, MIPS_COP_0_STATUS
MFC0_HAZARD
or v0, MIPS_SR_INT_IE
mtc0 v0, MIPS_COP_0_STATUS
#endif
COP0_SYNC
jal _C_LABEL(main) # main(void)
nop
PANIC("main() returned") # main never returns
.set at
.globl _C_LABEL(verylocore)
_C_LABEL(verylocore):
NESTED(cpu_switchto, CALLFRAME_SIZ, ra)
#if defined(PARANOIA)
PTR_L v0, L_CPU(MIPS_CURLWP)
INT_L v1, CPU_INFO_CPL(v0)
#if __mips >= 32
tnei v1, IPL_SCHED
#else
li v0, IPL_SCHED
10: bne v0, v1, 10b
nop
#endif
mfc0 t0, MIPS_COP_0_STATUS
MFC0_HAZARD
and t0, MIPS_SR_INT_IE
#if __mips >= 32
teqi t0, 0
#else
11: beqz t0, 11b
nop
#endif
#endif
PTR_L a2, L_PCB(a0) # a2 = pcb of old lwp
mfc0 t0, MIPS_COP_0_STATUS
REG_PROLOGUE
REG_S s0, PCB_CONTEXT+SF_REG_S0(a2)
REG_S s1, PCB_CONTEXT+SF_REG_S1(a2)
REG_S s2, PCB_CONTEXT+SF_REG_S2(a2)
REG_S s3, PCB_CONTEXT+SF_REG_S3(a2)
REG_S s4, PCB_CONTEXT+SF_REG_S4(a2)
REG_S s5, PCB_CONTEXT+SF_REG_S5(a2)
REG_S s6, PCB_CONTEXT+SF_REG_S6(a2)
REG_S s7, PCB_CONTEXT+SF_REG_S7(a2)
REG_S sp, PCB_CONTEXT+SF_REG_SP(a2)
REG_S s8, PCB_CONTEXT+SF_REG_S8(a2)
REG_S ra, PCB_CONTEXT+SF_REG_RA(a2)
REG_S t0, PCB_CONTEXT+SF_REG_SR(a2)
#if defined(__mips_n32) || defined(__mips_n64)
REG_S gp, PCB_CONTEXT+SF_REG_GP(a2)
#endif
REG_EPILOGUE
#if defined(PARANOID_SPL)
jal _C_LABEL(splcheck)
nop
#endif
move s6, a0 # s6 = old lwp
move MIPS_CURLWP, a1 # t8 = new lwp
PTR_SUBU sp, CALLFRAME_SIZ
REG_S ra, CALLFRAME_RA(sp)
.mask 0x80000000, -4
jal _C_LABEL(mips_cpu_switch_resume)
move a0, MIPS_CURLWP
PTR_L t2, L_CPU(MIPS_CURLWP)
nop # patchable load delay slot
SYNC_PRODUCER
PTR_S MIPS_CURLWP, CPU_INFO_CURLWP(t2)
SYNC_DEKKER
PTR_L a0, L_PROC(MIPS_CURLWP) # argument to ras_lookup
PTR_L s5, L_PCB(MIPS_CURLWP) # XXXuvm_lwp_getuarea
PTR_L v1, P_RASLIST(a0) # get raslist
NOP_L # load delay
beqz v1, 1f # skip call if empty
nop
jal _C_LABEL(ras_lookup) # ras_lookup(p, pc)
PTR_L a1, (USPACE - TF_SIZ - CALLFRAME_SIZ + TF_REG_EPC)(s5)
PTR_ADDU v1, v0, 1
beqz v1, 1f # branch if v0 + 1 == 0
nop
PTR_S v0, (USPACE - TF_SIZ - CALLFRAME_SIZ + TF_REG_EPC)(s5)
1:
move v0, s6 # Save return value (old lwp)
REG_PROLOGUE
REG_L t0, PCB_CONTEXT+SF_REG_SR(s5)
#if defined(PARANOIA) && __mips >= 32
and t1, t0, MIPS_SR_INT_IE
teqi t1, 0
#elif defined(PARANOID_LOOP)
and t1, t0, MIPS_SR_INT_IE
2: beqz t1, 2b # status reg should not differ
nop
#endif
DYNAMIC_STATUS_MASK(t0,ra)
move a0, s5
REG_L ra, PCB_CONTEXT+SF_REG_RA(a0)
REG_L s0, PCB_CONTEXT+SF_REG_S0(a0)
REG_L s1, PCB_CONTEXT+SF_REG_S1(a0)
REG_L s2, PCB_CONTEXT+SF_REG_S2(a0)
REG_L s3, PCB_CONTEXT+SF_REG_S3(a0)
REG_L s4, PCB_CONTEXT+SF_REG_S4(a0)
REG_L s5, PCB_CONTEXT+SF_REG_S5(a0)
REG_L s6, PCB_CONTEXT+SF_REG_S6(a0)
REG_L s7, PCB_CONTEXT+SF_REG_S7(a0)
#if defined(__mips_n32) || defined(__mips_n64)
REG_L gp, PCB_CONTEXT+SF_REG_GP(a0)
#endif
REG_L sp, PCB_CONTEXT+SF_REG_SP(a0)
REG_L s8, PCB_CONTEXT+SF_REG_S8(a0)
REG_EPILOGUE
mtc0 t0, MIPS_COP_0_STATUS
#if defined(PARANOID_SPL)
COP0_SYNC
j _C_LABEL(splcheck)
nop
#else
JR_HB_RA
#endif
END(cpu_switchto)
#ifdef __HAVE_FAST_SOFTINTS
NESTED(softint_fast_dispatch, CALLFRAME_SIZ, ra)
PTR_SUBU sp, CALLFRAME_SIZ
REG_S a0, CALLFRAME_S0(sp) # save softint lwp
REG_S ra, CALLFRAME_RA(sp) # save return address
.mask 0x80000000, -4
PTR_L t0, L_PCB(MIPS_CURLWP) # t0 = curlwp->l_addr
mfc0 t1, MIPS_COP_0_STATUS
#if defined(PARANOIA) && __mips >= 32
MFC0_HAZARD
and v0, t1, MIPS_SR_INT_IE # assert interrupts are on
teqi v0, 0
#elif defined(PARANOID_LOOP)
MFC0_HAZARD
and v0, t1, MIPS_SR_INT_IE # assert interrupts are on
1: beqz v0, 1b
nop
#endif
PTR_LA t2, softint_cleanup # if softint blocks, return here
REG_PROLOGUE
REG_S s0, PCB_CONTEXT+SF_REG_S0(t0)
REG_S s1, PCB_CONTEXT+SF_REG_S1(t0)
REG_S s2, PCB_CONTEXT+SF_REG_S2(t0)
REG_S s3, PCB_CONTEXT+SF_REG_S3(t0)
REG_S s4, PCB_CONTEXT+SF_REG_S4(t0)
REG_S s5, PCB_CONTEXT+SF_REG_S5(t0)
REG_S s6, PCB_CONTEXT+SF_REG_S6(t0)
REG_S s7, PCB_CONTEXT+SF_REG_S7(t0)
REG_S sp, PCB_CONTEXT+SF_REG_SP(t0)
REG_S s8, PCB_CONTEXT+SF_REG_S8(t0)
REG_S t2, PCB_CONTEXT+SF_REG_RA(t0)
REG_S t1, PCB_CONTEXT+SF_REG_SR(t0)
#if defined(__mips_n32) || defined(__mips_n64)
REG_S gp, PCB_CONTEXT+SF_REG_GP(t0)
#endif
REG_EPILOGUE
move s0, MIPS_CURLWP # remember current lwp
move MIPS_CURLWP, a0 # switch to softint lwp
PTR_L s1, L_CPU(MIPS_CURLWP) # get curcpu()
nop # patchable load delay slot
SYNC_PRODUCER
PTR_S MIPS_CURLWP, CPU_INFO_CURLWP(s1) # ...
move s2, sp # remember sp
move s3, t0 # remember curpcb
PTR_L t2, L_PCB(MIPS_CURLWP)
move a0, s0 # wants the pinned lwp
jal _C_LABEL(softint_dispatch)
PTR_ADDU sp, t2, USPACE - TF_SIZ - CALLFRAME_SIZ
move sp, s2 # restore stack
move MIPS_CURLWP, s0 # restore curlwp
SYNC_PRODUCER
PTR_S MIPS_CURLWP, CPU_INFO_CURLWP(s1) # ....
SYNC_DEKKER
REG_L ra, CALLFRAME_RA(sp) # load early since we use it
REG_PROLOGUE
REG_L s0, PCB_CONTEXT+SF_REG_S0(s3) # restore the saved
REG_L s1, PCB_CONTEXT+SF_REG_S1(s3) # registers that we
REG_L s2, PCB_CONTEXT+SF_REG_S2(s3) # used
REG_L s3, PCB_CONTEXT+SF_REG_S3(s3)
REG_EPILOGUE
jr ra
PTR_ADDU sp, CALLFRAME_SIZ
softint_cleanup:
#ifdef PARANOIA
mfc0 t1, MIPS_COP_0_STATUS
MFC0_HAZARD
and v0, t1, MIPS_SR_INT_IE
#if __mips >= 32
teqi v0, 0
#else
1: beqz v0, 1b
nop
#endif
#endif
PTR_L t0, L_CPU(MIPS_CURLWP)
NOP_L # load delay
INT_L t1, CPU_INFO_MTX_COUNT(t0)
NOP_L # load delay
INT_ADDU t1, 1
INT_S t1, CPU_INFO_MTX_COUNT(t0)
REG_L ra, CALLFRAME_RA(sp)
REG_L v0, CALLFRAME_S0(sp) # get softint lwp
NOP_L # load delay
#if IPL_SCHED != IPL_HIGH
j _C_LABEL(splhigh_noprof)
#else
jr ra
#endif
PTR_ADDU sp, CALLFRAME_SIZ
END(softint_fast_dispatch)
#endif
LEAF(lwp_oncpu)
PTR_L t0, L_PCB(MIPS_CURLWP) # get curpcb
li v0, EFAULT # assume failure
PTR_LA t1, 1f # load addr of cleanup
PTR_S t1, PCB_ONFAULT(t0) # save onfault handler
PTR_L t2, L_CPU(a0) # grab cpu of supplied lwp
NOP_L # load delay
PTR_L t3, CPU_INFO_CURLWP(t2) # grab curlwp of that cpu
li v0, ESRCH # assume the lwp isn't curlwp
bne a0, t3, 1f # branch if true (not equal)
nop
PTR_S t2, 0(a1) # return the cpu_info
li v0, 0 # load success
1:
PTR_S zero, PCB_ONFAULT(t0) # reset fault handler
jr ra # and return.
nop
END(lwp_oncpu)
LEAF(savectx)
mfc0 v0, MIPS_COP_0_STATUS
#ifdef PARANOIA
MFC0_HAZARD
and t0, v0, MIPS_SR_INT_IE
#if __mips >= 32
teqi t0, 0
#else
1: beqz t0, 1b
nop
#endif
#endif
REG_PROLOGUE
REG_S s0, PCB_CONTEXT+SF_REG_S0(a0)
REG_S s1, PCB_CONTEXT+SF_REG_S1(a0)
REG_S s2, PCB_CONTEXT+SF_REG_S2(a0)
REG_S s3, PCB_CONTEXT+SF_REG_S3(a0)
REG_S s4, PCB_CONTEXT+SF_REG_S4(a0)
REG_S s5, PCB_CONTEXT+SF_REG_S5(a0)
REG_S s6, PCB_CONTEXT+SF_REG_S6(a0)
REG_S s7, PCB_CONTEXT+SF_REG_S7(a0)
REG_S t8, PCB_CONTEXT+SF_REG_T8(a0) # MIPS_CURLWP
#if defined(__mips_n32) || defined(__mips_n64)
REG_S gp, PCB_CONTEXT+SF_REG_GP(a0)
#endif
REG_S sp, PCB_CONTEXT+SF_REG_SP(a0)
REG_S s8, PCB_CONTEXT+SF_REG_S8(a0)
REG_S ra, PCB_CONTEXT+SF_REG_RA(a0)
REG_S v0, PCB_CONTEXT+SF_REG_SR(a0)
REG_EPILOGUE
jr ra
move v0, zero
END(savectx)
#if defined(DDB) || defined(KGDB)
LEAF(setjmp)
mfc0 v0, MIPS_COP_0_STATUS
REG_PROLOGUE
REG_S s0, SF_REG_S0(a0)
REG_S s1, SF_REG_S1(a0)
REG_S s2, SF_REG_S2(a0)
REG_S s3, SF_REG_S3(a0)
REG_S s4, SF_REG_S4(a0)
REG_S s5, SF_REG_S5(a0)
REG_S s6, SF_REG_S6(a0)
REG_S s7, SF_REG_S7(a0)
#if defined(__mips_n32) || defined(__mips_n64)
REG_S gp, SF_REG_GP(a0)
#endif
REG_S sp, SF_REG_SP(a0)
REG_S s8, SF_REG_S8(a0)
REG_S ra, SF_REG_RA(a0)
REG_S v0, SF_REG_SR(a0)
REG_EPILOGUE
jr ra
move v0, zero
END(setjmp)
LEAF(longjmp)
REG_PROLOGUE
REG_L v0, SF_REG_SR(a0)
DYNAMIC_STATUS_MASK(v0,ra) # machine dependent masking
REG_L ra, SF_REG_RA(a0)
REG_L s0, SF_REG_S0(a0)
REG_L s1, SF_REG_S1(a0)
REG_L s2, SF_REG_S2(a0)
REG_L s3, SF_REG_S3(a0)
REG_L s4, SF_REG_S4(a0)
REG_L s5, SF_REG_S5(a0)
REG_L s6, SF_REG_S6(a0)
REG_L s7, SF_REG_S7(a0)
#if defined(__mips_n32) || defined(__mips_n64)
REG_L gp, SF_REG_GP(a0)
#endif
REG_L sp, SF_REG_SP(a0)
REG_L s8, SF_REG_S8(a0)
REG_EPILOGUE
mtc0 v0, MIPS_COP_0_STATUS
COP0_SYNC
jr ra
li v0, 1
END(longjmp)
#endif
LEAF_NOPROFILE(mips_cp0_cause_read)
mfc0 v0, MIPS_COP_0_CAUSE
jr ra
nop
END(mips_cp0_cause_read)
LEAF(mips_cp0_cause_write)
mtc0 a0, MIPS_COP_0_CAUSE
JR_HB_RA
END(mips_cp0_cause_write)
LEAF(mips_cp0_status_read)
mfc0 v0, MIPS_COP_0_STATUS
jr ra
nop
END(mips_cp0_status_read)
LEAF(mips_cp0_status_write)
mtc0 a0, MIPS_COP_0_STATUS
JR_HB_RA
END(mips_cp0_status_write)
#if !defined(NOFPU) || defined(FPEMUL)
NESTED(mips_fpu_intr, CALLFRAME_SIZ, ra)
XNESTED(mips_fpu_trap)
.mask 0x80000000, -4
PTR_SUBU sp, CALLFRAME_SIZ
mfc0 t0, MIPS_COP_0_STATUS
REG_S ra, CALLFRAME_RA(sp)
or t0, t0, MIPS_SR_COP_1_BIT
mtc0 t0, MIPS_COP_0_STATUS
COP0_HAZARD_FPUENABLE
REG_PROLOGUE
REG_L a2, TF_REG_CAUSE(a1)
REG_EPILOGUE
cfc1 t0, MIPS_FCSR # stall til FP done
cfc1 t0, MIPS_FCSR # now get status
nop
sll t2, t0, (31 - 17) # unimplemented operation?
bgez t2, 3f # no, normal trap
nop
srl v1, a2, 31 # move branch delay bit to LSB
sll v1, 2 # shift it left by 2 (mult by 4)
PTR_ADDU a0, v1 # add to a0
INT_L a0, 0(a0) # a0 = coproc instruction
NOP_L # load delay
srl t2, a0, MIPS_OPCODE_SHIFT
beq t2, MIPS_OPCODE_C1, 4f
nop
srl a2, 8
sll a2, 8
ori a2, T_RES_INST << MIPS_CR_EXC_CODE_SHIFT
REG_PROLOGUE
REG_S a2, TF_REG_CAUSE(a1)
REG_EPILOGUE
and t2, t0, ~MIPS_FCSR_CAUSE
ctc1 t2, MIPS_FCSR
move a1, a0 # code = instruction
jal _C_LABEL(mips_fpuillinst)
move a0, MIPS_CURLWP # get current LWP
b FPReturn
nop
3:
REG_PROLOGUE
REG_S a2, TF_REG_CAUSE(a1)
REG_EPILOGUE
and a0, t0, ~MIPS_FCSR_CAUSE
ctc1 a0, MIPS_FCSR
move a1, t0 # FPU status
jal _C_LABEL(mips_fpuexcept)
move a0, MIPS_CURLWP # get current LWP
b FPReturn
nop
4:
jal _C_LABEL(mips_emul_fp)
nop
FPReturn:
mfc0 t0, MIPS_COP_0_STATUS
REG_L ra, CALLFRAME_RA(sp)
and t0, ~MIPS_SR_COP_1_BIT
mtc0 t0, MIPS_COP_0_STATUS
COP0_SYNC
j ra
PTR_ADDU sp, CALLFRAME_SIZ
END(mips_fpu_intr)
#endif
LEAF(mips_pagecopy)
.set push
#if defined(__mips_n32) || defined(_LP64)
.set mips3
#endif
li a2, PAGE_SIZE / (8 * SZREG)
1: REG_L t0, (0*SZREG)(a1)
REG_L ta0, (4*SZREG)(a1)
PTR_SUBU a2, 1
REG_L t1, (1*SZREG)(a1)
REG_L t2, (2*SZREG)(a1)
REG_L t3, (3*SZREG)(a1)
REG_L ta1, (5*SZREG)(a1)
REG_L ta2, (6*SZREG)(a1)
REG_L ta3, (7*SZREG)(a1)
REG_S t0, (0*SZREG)(a0)
REG_S ta0, (4*SZREG)(a0)
PTR_ADDU a1, 8*SZREG
REG_S t1, (1*SZREG)(a0)
REG_S t2, (2*SZREG)(a0)
REG_S t3, (3*SZREG)(a0)
REG_S ta1, (5*SZREG)(a0)
REG_S ta2, (6*SZREG)(a0)
REG_S ta3, (7*SZREG)(a0)
bgtz a2, 1b
PTR_ADDU a0, 8*SZREG
.set pop
jr ra
nop
END(mips_pagecopy)
LEAF(mips_pagezero)
.set push
#if (MIPS1 + MIPS32 + MIPS32R2) == 0
.set mips3
#endif
li a1, PAGE_SIZE / (8*SZREG)
1: REG_S zero, (0*SZREG)(a0) # try to miss cache first
REG_S zero, (4*SZREG)(a0)
subu a1, 1
REG_S zero, (1*SZREG)(a0) # fill in cache lines
REG_S zero, (2*SZREG)(a0)
REG_S zero, (3*SZREG)(a0)
REG_S zero, (5*SZREG)(a0)
REG_S zero, (6*SZREG)(a0)
REG_S zero, (7*SZREG)(a0)
bgtz a1,1b
PTR_ADDU a0, 8*SZREG
.set pop
jr ra
nop
END(mips_pagezero)
#ifndef DDB_TRACE
#if defined(DEBUG) || defined(DDB) || defined(KGDB) || defined(geo)
#if defined(__mips_o32) || defined(__mips_o64)
#define XCALLFRAME_SIZ (CALLFRAME_SIZ + 6*SZREG)
#define XCALLFRAME_RA (CALLFRAME_RA + 4*SZREG)
#endif
#if defined(__mips_n32) || defined(__mips_n64)
#define XCALLFRAME_SIZ (CALLFRAME_SIZ + 2*SZREG)
#define XCALLFRAME_RA (CALLFRAME_RA + 2*SZREG)
#endif
NESTED(stacktrace, XCALLFRAME_SIZ, ra)
XNESTED(logstacktrace)
PTR_SUBU sp, XCALLFRAME_SIZ # four arg-passing slots
move t0, ra # save caller's PC
PTR_ADDU t1, sp, XCALLFRAME_SIZ # save caller's SP
move t2, s8 # non-virtual frame pointer
PTR_LA v0, _C_LABEL(printf)
REG_S ra, XCALLFRAME_RA(sp) # save return address
#if defined(__mips_o32) || defined(__mips_o64)
REG_S t0, 4*SZREG(sp) # push caller's PC
REG_S t1, 5*SZREG(sp) # push caller's SP
REG_S t2, 6*SZREG(sp) # push caller's FP, in case
REG_S zero, 7*SZREG(sp) # caller's RA on stack
jal _C_LABEL(stacktrace_subr)
REG_S v0, 8*SZREG(sp) # push printf
#endif
#if defined(__mips_n32) || defined(__mips_n64)
move a4, t0 # pass caller's PC
move a5, t1 # pass caller's SP
move a6, t2 # pass caller's FP, in case
move a7, zero # caller's RA on stack
jal _C_LABEL(stacktrace_subr)
REG_S v0, 0(sp) # push printf
#endif
REG_L ra, XCALLFRAME_RA(sp)
PTR_ADDU sp, XCALLFRAME_SIZ
jr ra
nop
#undef XCALLFRAME_RA
#undef XCALLFRAME_SIZ
END(stacktrace)
#endif
#endif
.section .stub, "ax"
NESTED_NOPROFILE(tlb_update_addr, 0, ra)
lui v0,%hi(_C_LABEL(mips_locore_jumpvec)+LJV_TLB_UPDATE_ADDR)
PTR_L t9,%lo(_C_LABEL(mips_locore_jumpvec)+LJV_TLB_UPDATE_ADDR)(v0)
jr t9
nop
END(tlb_update_addr)
.sdata
.globl _C_LABEL(esym)
_C_LABEL(esym):
.word 0
#ifdef MIPS_DYNAMIC_STATUS_MASK
.globl _C_LABEL(mips_dynamic_status_mask)
_C_LABEL(mips_dynamic_status_mask):
.word 0xffffffff
#endif