📄 usercopy.s
字号:
bne a0,a3,1b # at least one more word b bytecmp/* * deal with simultaneously unalignable cmp by aligning one src */unalgncmp: subu a3,zero,a1 # calc byte cnt to get src2 aligned and a3,NBPW-1 subu a2,a3 beq a3,zero,partaligncmp # already aligned addu a3,a0 # src1 endpoint1: lbu v0,0(a0) lbu v1,0(a1) addu a0,1 addu a1,1 bne v0,v1,cmpne bne a0,a3,1b/* * src unaligned, dst aligned loop */partaligncmp: and a3,a2,~(NBPW-1) subu a2,a3 beq a3,zero,bytecmp addu a3,a01:#ifdef MIPSEB lwl v0,0(a0) lwr v0,3(a0)#endif#ifdef MIPSEL lwr v0,0(a0) lwl v0,3(a0)#endif lw v1,0(a1) addu a0,NBPW addu a1,NBPW bne v0,v1,cmpne bne a0,a3,1b/* * brute force byte cmp loop */bytecmp: addu a3,a2,a0 # src1 endpoint; BDSLOT ble a2,zero,cmpdone1: lbu v0,0(a0) lbu v1,0(a1) addu a0,1 addu a1,1 bne v0,v1,cmpne bne a0,a3,1bcmpdone: move v0,zero j racmpne: li v0,1 j ra END(bcmp)/* * struct u_prof offsets */#define PR_BASE 0#define PR_SIZE 4#define PR_OFF 8#define PR_SCALE 12/* * addupc(pc, &u.u_prof, ticks) */LEAF(addupc) lw v1,PR_OFF(a1) # base of profile region subu a0,v1 # corrected pc bltz a0,1f # below of profile region lw v0,PR_SCALE(a1) # fixed point scale factor multu v0,a0 mflo v0 # shift 64 bit result right 16 srl v0,16 mfhi v1 sll v1,16 or v0,v1 addu v0,1 # round-up to even and v0,~1 lw v1,PR_SIZE(a1) bgeu v0,v1,1f # above profile region lw v1,PR_BASE(a1) # base of profile buckets addu v0,v1 bltz v0,adderr # outside kuseg#ifdef ASSERTIONS lw v1,u+PCB_CPUPTR lw v1,CPU_NOFAULT(v1) beq v1,zero,8f PANIC("recursive nofault")8:#endif ASSERTIONS .set noreorder lw a3,u+PCB_CPUPTR li v1,NF_ADDUPC # LDSLOT sw v1,CPU_NOFAULT(a3) lh v1,0(v0) # add ticks to bucket nop # ??? Not in mad version ??? addu v1,a2 sh v1,0(v0) sw zero,CPU_NOFAULT(a3) .set reorder1: j ra END(addupc)LEAF(adderr) sw zero,PR_SCALE(a1) j ra END(adderr)LEAF(fubyte)XLEAF(fuibyte)#ifdef ASSERTIONS lw v0,u+PCB_CPUPTR lw v0,CPU_NOFAULT(v0) beq v0,zero,8f PANIC("recursive nofault")8:#endif ASSERTIONS .set noreorder bltz a0,uerror li v0,NF_FSUMEM # BDSLOT lw v1,u+PCB_CPUPTR nop sw v0,CPU_NOFAULT(v1) lbu v0,0(a0) sw zero,CPU_NOFAULT(v1) # LDSLOT .set reorder j ra END(fubyte)LEAF(subyte)XLEAF(suibyte)#ifdef ASSERTIONS lw v0,u+PCB_CPUPTR lw v0,CPU_NOFAULT(v0) beq v0,zero,8f PANIC("recursive nofault")8:#endif ASSERTIONS .set noreorder bltz a0,uerror li v0,NF_FSUMEM # BDSLOT lw v1,u+PCB_CPUPTR nop sw v0,CPU_NOFAULT(v1) sb a1,0(a0) sw zero,CPU_NOFAULT(v1) .set reorder j ra END(subyte)LEAF(fuword)XLEAF(fuiword)#ifdef ASSERTIONS lw v0,u+PCB_CPUPTR lw v0,CPU_NOFAULT(v0) beq v0,zero,8f PANIC("recursive nofault")8:#endif ASSERTIONS .set noreorder bltz a0,uerror li v0,NF_FSUMEM # BDSLOT lw v1,u+PCB_CPUPTR nop sw v0,CPU_NOFAULT(v1) lw v0,0(a0) sw zero,CPU_NOFAULT(v1) # LDSLOT .set reorder j ra END(fuword) LEAF(suword)XLEAF(suiword)#ifdef ASSERTIONS lw v0,u+PCB_CPUPTR lw v0,CPU_NOFAULT(v0) beq v0,zero,8f PANIC("recursive nofault")8:#endif ASSERTIONS .set noreorder bltz a0,uerror li v0,NF_FSUMEM # BDSLOT lw v1,u+PCB_CPUPTR nop sw v0,CPU_NOFAULT(v1) sw a1,0(a0) sw zero,CPU_NOFAULT(v1) .set reorder j ra END(suword)LEAF(uerror) li v0,-1 # error return j ra END(uerror)#ifdef notdef/* useracc now in machdep.c *//* * useracc(addr, bcnt, rw) * verify user access to virtual addresses addr .. addr+bcnt-1 * if rw is 0, write access is verified, if rw is 1, read access */LEAF(useracc) beq a1,zero,3f # nothing to check#ifdef ASSERTIONS lw v0,u+PCB_CPUPTR lw v0,CPU_NOFAULT(v0) beq v0,zero,8f PANIC("recursive nofault")8:#endif ASSERTIONS .set noreorder bltz a0,uaerror li v0,NF_USERACC lw v1,u+PCB_CPUPTR nop sw v0,CPU_NOFAULT(v1) .set reorder addu t0,a0,a1 # end + 1 and a0,~PGOFSET # back-up to start of page bne a2,zero,2f # verify read access /* * verify write access */1: lw v0,0(a0) addu a0,NBPG sw v0,-NBPG(a0) bltu a0,t0,1b .set noreorder sw zero,CPU_NOFAULT(v1) j ra li v0,1 # BDSLOT .set reorder /* * verify read access */2: lw v0,0(a0) addu a0,NBPG bltu a0,t0,2b .set noreorder3: sw zero,CPU_NOFAULT(v1) j ra li v0,1 # BDSLOT .set reorder END(useracc)#endif notdefLEAF(uaerror) move v0,zero j ra END(uaerror)/* * strlen - return bytes in null terminated string */LEAF(strlen) move v0,a0 # save beginning pointer1: lb v1,0(a0) # look at byte addu a0,1 # advance current pointer bne v1,zero,1b # check for null byte subu v0,a0,v0 # byte count including null byte subu v0,1 # exclude null byte j ra END(strlen)/* * kn01_clean_icache(addr, len) * flush i cache for range of addr to addr+len-1 * MUST NOT DESTROY a0 AND a1, SEE clean_cache ABOVE */LEAF(kn01_clean_icache) lw t1,icache_size .set noreorder nop mfc0 t3,C0_SR # save sr nop mtc0 zero,C0_SR # interrupts off nop .set reorder .set noreorder la v0,1f or v0,K1BASE j v0 # run uncached nop1: li v0,SR_ISC|SR_SWC # disable intr, isolate and swap mtc0 v0,C0_SR bltu t1,a1,1f # cache is smaller than region nop move t1,a11: addu t1,a0 # ending address + 1 move t0,a0 la v0,1f # run cached j v0 nop .set reorder1: sb zero,0(t0) sb zero,4(t0) sb zero,8(t0) sb zero,12(t0) sb zero,16(t0) sb zero,20(t0) sb zero,24(t0) addu t0,32 sb zero,-4(t0) bltu t0,t1,1b .set noreorder la v0,1f or v0,K1BASE j v0 # run uncached nop1: nop # insure isolated stores out of pipe mtc0 zero,C0_SR # unisolate, unswap nop # keep pipeline clean nop # keep pipeline clean nop # keep pipeline clean mtc0 t3,C0_SR # enable interrupts j ra # return and run cached nop .set reorder END(kn01_clean_icache)LEAF(kn01_clean_dcache) lw t2,dcache_size .set noreorder nop mfc0 t3,C0_SR # save sr nop .set reorder .set noreorder li v0,SR_ISC # disable interrupts, isolate caches mtc0 v0,C0_SR bltu t2,a1,1f # cache is smaller than region nop move t2,a11: addu t2,a0 # ending address + 1 move t0,a0 nop nop # cache must be isolated by now .set reorder1: sb zero,0(t0) sb zero,4(t0) sb zero,8(t0) sb zero,12(t0) sb zero,16(t0) sb zero,20(t0) sb zero,24(t0) addu t0,32 sb zero,-4(t0) bltu t0,t2,1b .set noreorder nop # insure isolated stores out of pipe nop nop mtc0 t3,C0_SR # un-isolate, enable interrupts nop # insure cache unisolated nop # insure cache unisolated nop # insure cache unisolated j ra nop .set reorder END(kn01_clean_dcache)/* * kn01flush_cache() * flush entire cache */LEAF(kn01flush_cache) lw t1,icache_size # must load before isolating lw t2,dcache_size # must load before isolating .set noreorder nop mfc0 t3,C0_SR # save SR nop mtc0 zero,C0_SR # interrupts off nop .set reorder .set noreorder la v0,1f or v0,K1BASE j v0 # run uncached nop /* * flush text cache */1: li v0,SR_ISC|SR_SWC # disable intr, isolate and swap mtc0 v0,C0_SR li t0,K1BASE subu t0,t1 li t1,K1BASE la v0,1f # run cached j v0 nop .set reorder1: sb zero,0(t0) sb zero,4(t0) sb zero,8(t0) sb zero,12(t0) sb zero,16(t0) sb zero,20(t0) sb zero,24(t0) addu t0,32 sb zero,-4(t0) bne t0,t1,1b .set noreorder la v0,1f or v0,K1BASE j v0 # run uncached nop /* * flush data cache */1: li v0,SR_ISC # isolate and swap back caches mtc0 v0,C0_SR li t0,K1BASE subu t0,t2 la v0,1f j v0 # back to cached mode nop .set reorder1: sb zero,0(t0) sb zero,4(t0) sb zero,8(t0) sb zero,12(t0) sb zero,16(t0) sb zero,20(t0) sb zero,24(t0) addu t0,32 sb zero,-4(t0) bne t0,t1,1b .set noreorder nop # insure isolated stores out of pipe nop nop mtc0 t3,C0_SR # un-isolate, enable interrupts nop # insure cache unisolate nop nop nop .set reorder#ifdef CACHETRICKS lw v0,icachemask # index of last entry in icachecnt li v1,0 sll v0,1 # offset to last entry1: lhu t0,icachecnt(v1) addu t0,1 sh t0,icachecnt(v1) addu v1,2 ble v1,v0,1b # more cachecnt's to bump lw v0,dcachemask # index of last entry in dcachecnt li v1,0 sll v0,1 # offset to last entry1: lhu t0,dcachecnt(v1) addu t0,1 sh t0,dcachecnt(v1) addu v1,2 ble v1,v0,1b # more cachecnt's to bump#endif CACHETRICKS j ra END(kn01flush_cache)/* * kn01_page_iflush(addr) * flush one page of i cache, addr is assumed to be in K0SEG */LEAF(kn01_page_iflush) lw t1,icache_size .set noreorder nop mfc0 t3,C0_SR # save sr nop mtc0 zero,C0_SR # interrupts off nop .set reorder .set noreorder la v0,1f or v0,K1BASE j v0 # run uncached nop # BDSLOT /* * flush text cache */1: li v0,SR_ISC|SR_SWC # disable intr, isolate and swap mtc0 v0,C0_SR bltu t1,NBPG,1f # cache is smaller than region nop # BDSLOT li t1,NBPG1: addu t1,a0 # ending address + 1 move t0,a0 la v0,1f # run cached j v0 nop # cache must be isolated by now .set reorder1: sb zero,0(t0) sb zero,4(t0) sb zero,8(t0) sb zero,12(t0) sb zero,16(t0) sb zero,20(t0) sb zero,24(t0) addu t0,32 sb zero,-4(t0) bltu t0,t1,1b .set noreorder la v0,1f or v0,K1BASE j v0 # run uncached nop1: nop # insure isolated stores out of pipe mtc0 zero,C0_SR # unisolate, unswap nop nop nop nop mtc0 t3,C0_SR # enable interrupts la v0,1f # run cached j v0 nop .set reorder1:#ifdef CACHETRICKS lw v0,icachemask srl t1,a0,PGSHIFT and t1,v0 sll t1,1 # cachecnt index lhu t0,icachecnt(t1) addu t0,1 sh t0,icachecnt(t1)#endif CACHETRICKS j ra END(kn01_page_iflush)/* * kn01_page_dflush(addr) * flush one page of i cache, addr is assumed to be in K0SEG */LEAF(kn01_page_dflush)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -