#include <sys/errno.h>
#include <mips/asm.h>
#include "assym.h"
.set noreorder
LEAF(copyinstr)
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(copystrerr)
blt a0, zero, _C_LABEL(copystrefault)
PTR_S v0, PCB_ONFAULT(v1)
move t0, a2
beq a2, zero, 4f
nop
1:
lbu v0, 0(a0)
PTR_SUBU a2, a2, 1
beq v0, zero, 2f
sb v0, 0(a1) # write trailing NUL
PTR_ADDU a0, a0, 1
bne a2, zero, 1b
PTR_ADDU a1, a1, 1
4:
li v0, ENAMETOOLONG
2:
beq a3, zero, 3f
PTR_SUBU a2, t0, a2
PTR_S a2, 0(a3)
3:
j ra # v0 is 0 or ENAMETOOLONG
PTR_S zero, PCB_ONFAULT(v1)
END(copyinstr)
LEAF(copyoutstr)
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(copystrerr)
blt a1, zero, _C_LABEL(copystrefault)
PTR_S v0, PCB_ONFAULT(v1)
move t0, a2
beq a2, zero, 4f
nop
1:
lbu v0, 0(a0)
PTR_SUBU a2, a2, 1
beq v0, zero, 2f
sb v0, 0(a1)
PTR_ADDU a0, a0, 1
bne a2, zero, 1b
PTR_ADDU a1, a1, 1
4:
li v0, ENAMETOOLONG
2:
beq a3, zero, 3f
PTR_SUBU a2, t0, a2
PTR_S a2, 0(a3)
3:
j ra # v0 is 0 or ENAMETOOLONG
PTR_S zero, PCB_ONFAULT(v1)
END(copyoutstr)
LEAF(copystrerr)
j ra
PTR_S zero, PCB_ONFAULT(v1)
END(copystrerr)
LEAF(copystrefault)
b copystrerr
li v0, EFAULT
END(copystrefault)
NESTED(kcopy, 2*CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, 2*CALLFRAME_SIZ # set up stack frame
.mask 0x80010000, -SZREG
REG_S ra, CALLFRAME_SIZ+CALLFRAME_RA(sp) # save ra
REG_S s0, CALLFRAME_SIZ+CALLFRAME_S0(sp) # save s0
move v0, a0 # swap a0, a1 for call to memcpy
move a0, a1
move a1, v0
PTR_L v1, L_PCB(MIPS_CURLWP) # set up fault handler
PTR_LA v0, _C_LABEL(kcopyerr)
PTR_L s0, PCB_ONFAULT(v1) # save old handler
jal memcpy
PTR_S v0, PCB_ONFAULT(v1)
PTR_L v1, L_PCB(MIPS_CURLWP) # restore the old handler
REG_L ra, CALLFRAME_SIZ+CALLFRAME_RA(sp) # restore ra
PTR_S s0, PCB_ONFAULT(v1)
REG_L s0, CALLFRAME_SIZ+CALLFRAME_S0(sp) # restore s0
PTR_ADDU sp, sp, 2*CALLFRAME_SIZ # kill stack frame
j ra
move v0, zero # success!
END(kcopy)
LEAF(kcopyerr)
PTR_L v1, L_PCB(MIPS_CURLWP) # restore the old handler
REG_L ra, CALLFRAME_SIZ+CALLFRAME_RA(sp) # restore ra
PTR_S s0, PCB_ONFAULT(v1)
REG_L s0, CALLFRAME_SIZ+CALLFRAME_S0(sp) # restore s0
j ra
PTR_ADDU sp, sp, 2*CALLFRAME_SIZ # kill stack frame
END(kcopyerr)
NESTED(copyin, CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, CALLFRAME_SIZ
.mask 0x80000000, -4
REG_S ra, CALLFRAME_RA(sp)
blt a0, zero, _C_LABEL(copyefault)
move v0, a0 # swap a0, a1 for call to memcpy
move a0, a1
move a1, v0
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(copyerr)
jal memcpy
PTR_S v0, PCB_ONFAULT(v1)
PTR_L v1, L_PCB(MIPS_CURLWP)
REG_L ra, CALLFRAME_RA(sp)
PTR_ADDU sp, sp, CALLFRAME_SIZ
PTR_S zero, PCB_ONFAULT(v1)
j ra
move v0, zero
END(copyin)
NESTED(copyout, CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, CALLFRAME_SIZ
.mask 0x80000000, -4
REG_S ra, CALLFRAME_RA(sp)
blt a1, zero, _C_LABEL(copyefault)
move v0, a0 # swap a0, a1 for call to memcpy
move a0, a1
move a1, v0
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(copyerr)
jal memcpy
PTR_S v0, PCB_ONFAULT(v1)
PTR_L v1, L_PCB(MIPS_CURLWP)
REG_L ra, CALLFRAME_RA(sp)
PTR_ADDU sp, sp, CALLFRAME_SIZ
PTR_S zero, PCB_ONFAULT(v1)
j ra
move v0, zero
END(copyout)
LEAF(copyerr)
PTR_L v1, L_PCB(MIPS_CURLWP)
REG_L ra, CALLFRAME_RA(sp)
PTR_ADDU sp, sp, CALLFRAME_SIZ
j ra
PTR_S zero, PCB_ONFAULT(v1)
END(copyerr)
LEAF(copyefault)
b copyerr
li v0, EFAULT
END(copyefault)
LEAF(kfetch_32)
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(kfetcherr)
bgez a0, _C_LABEL(kfetcherr)
PTR_S v0, PCB_ONFAULT(v1)
INT_L v0, 0(a0) # fetch int
nop # load delay for mips1
move t0, v0 # dependent instruction
xor t0, v0 # make t0 zero
j ra
PTR_S t0, PCB_ONFAULT(v1)
END(kfetch_32)
#define UFETCHSTORE_PROLOGUE \
PTR_L v1, L_PCB(MIPS_CURLWP) ;\
PTR_LA v0, _C_LABEL(ufetchstore_fault) ;\
blt a0, zero, _C_LABEL(ufetchstore_efault) ;\
PTR_S v0, PCB_ONFAULT(v1)
#define UFETCHSTORE_EPILOGUE ;\
PTR_S zero, PCB_ONFAULT(v1)
#define UFETCHTORE_RETURN_SUCCESS ;\
j ra ;\
move v0, zero
LEAF(_ufetch_8)
UFETCHSTORE_PROLOGUE
lbu v0, 0(a0)
UFETCHSTORE_EPILOGUE
sb v0, 0(a1)
UFETCHTORE_RETURN_SUCCESS
END(_ufetch_8)
LEAF(_ufetch_16)
UFETCHSTORE_PROLOGUE
lhu v0, 0(a0)
UFETCHSTORE_EPILOGUE
sh v0, 0(a1)
UFETCHTORE_RETURN_SUCCESS
END(_ufetch_16)
LEAF(_ufetch_32)
UFETCHSTORE_PROLOGUE
lw v0, 0(a0)
UFETCHSTORE_EPILOGUE
sw v0, 0(a1)
UFETCHTORE_RETURN_SUCCESS
END(_ufetch_32)
#ifdef _LP64
LEAF(_ufetch_64)
UFETCHSTORE_PROLOGUE
ld v0, 0(a0)
UFETCHSTORE_EPILOGUE
sd v0, 0(a1)
UFETCHTORE_RETURN_SUCCESS
END(_ufetch_64)
#endif
LEAF(_ustore_8)
UFETCHSTORE_PROLOGUE
sb a1, 0(a0)
UFETCHSTORE_EPILOGUE
UFETCHTORE_RETURN_SUCCESS
END(_ustore_8)
LEAF(_ustore_16)
UFETCHSTORE_PROLOGUE
sh a1, 0(a0)
UFETCHSTORE_EPILOGUE
UFETCHTORE_RETURN_SUCCESS
END(_ustore_16)
LEAF(_ustore_32)
UFETCHSTORE_PROLOGUE
sw a1, 0(a0)
UFETCHSTORE_EPILOGUE
UFETCHTORE_RETURN_SUCCESS
END(_ustore_32)
#ifdef _LP64
LEAF(_ustore_64)
UFETCHSTORE_PROLOGUE
sd a1, 0(a0)
UFETCHSTORE_EPILOGUE
UFETCHTORE_RETURN_SUCCESS
END(_ustore_64)
#endif
LEAF(ufetchstore_efault)
li v0, EFAULT
XLEAF(ufetchstore_fault)
j ra
UFETCHSTORE_EPILOGUE
END(ufetchstore_efault)
LEAF(mips_ufetch32)
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(mips_ufetch32_fault)
blt a0, zero, _C_LABEL(mips_ufetch32_fault)
PTR_S v0, PCB_ONFAULT(v1)
INT_L v0, 0(a0) # fetch int
j ra
PTR_S zero, PCB_ONFAULT(v1)
END(mips_ufetch32)
LEAF(mips_ustore32_isync)
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(mips_ufetch32_fault)
blt a0, zero, _C_LABEL(mips_ufetch32_fault)
PTR_S v0, PCB_ONFAULT(v1)
INT_S a1, 0(a0) # store word
PTR_S zero, PCB_ONFAULT(v1)
PTR_L t9, _C_LABEL(mips_cache_ops) + MIPSX_FLUSHICACHE
move v0, zero
j t9 # NOTE: must not clobber v0!
li a1, 4 # size of word
END(mips_ustore32_isync)
LEAF(mips_ufetch32_fault)
li v0, -1
j ra
PTR_S zero, PCB_ONFAULT(v1)
END(mips_ufetch32_fault)
LEAF(badaddr)
PTR_L v1, L_PCB(MIPS_CURLWP)
PTR_LA v0, _C_LABEL(baderr)
bne a1, 1, 2f
PTR_S v0, PCB_ONFAULT(v1)
b 5f
lbu v0, (a0)
2:
bne a1, 2, 4f
nop
b 5f
lhu v0, (a0)
4:
INT_L v0, (a0)
5:
nop
move t0, v0 # dependent instruction
xor t0, t0 # zero t0
PTR_S t0, PCB_ONFAULT(v1) # clear onfault
j ra
move v0, zero # made it w/o errors
END(badaddr)
LEAF(kfetcherr)
PTR_S zero, PCB_ONFAULT(v1)
j ra
move v0, a1
END(kfetcherr)
LEAF(fswberr)
XLEAF(baderr)
PTR_S zero, PCB_ONFAULT(v1)
j ra
li v0, -1
END(fswberr)