📄 mips.s
字号:
nop nop nop nop nop eret nop#else j k0 # transfer control to client rfe#endif .set at .set reorder .end _go/************************************************************** _exception:* This routine is used to save the state of a client program after* an exception is encountered. But it first checks to see if there* is a user defined exception handler (via onintr), and then checks* to see if it's a floating-point instruction (if PMON has fp emulation* enabled.)*/ .globl _exception .ent _exception_exception: .set noat la k0,DBGREG sw k1,R_K1TMP*4(k0) la k0,asm_exception_ptr lw k0,(k0) beq k0,zero,1f jalr k1,k0 # 970313 1: # if (curlst == &pmlst) branch to exc2 la k0,curlst lw k0,(k0) la k1,pmlst beq k0,k1,exc2 # skip if in PMON # see if we have a user defined handler .set noreorder mfc0 k0,C0_CAUSE nop .set reorder and k0,CAUSE_EXCMASK la k1,hndlrtbl addu k0,k1 # calc table entry addr lw k0,(k0) # get contents of table entry beq k0,zero,exc2 lw k0,4(k0) # user routine addr la k1,DBGREG lw k1,R_K1TMP*4(k1) # restore k1 j k0 # jump to user handlerexc2:#ifdef FPEM /* see if it's a cp1 unusable */ .set noreorder mfc0 k0,C0_CAUSE nop .set reorder li k1,(CAUSE_CEMASK|CAUSE_EXCMASK) and k0,k1 li k1,((1<<CAUSE_CESHIFT)|(11<<CAUSE_EXCSHIFT)) subu k0,k1 bne k0,zero,1f la k0,cop1 # jump to emulation package la k1,DBGREG lw k1,R_K1TMP*4(k1) # restore k1 j k0 1:#endif#ifdef INCLUDE_MDEM /* see if it's a reserved instr trap */ .set noreorder mfc0 k0,C0_CAUSE nop .set reorder li k1,CAUSE_EXCMASK and k0,k1 li k1,(10<<CAUSE_EXCSHIFT) subu k0,k1 bne k0,zero,1f # save return address la k0,1f subu sp,8 sw k0,4(sp) la k0,trap10 # jump to emulation package la k1,DBGREG lw k1,R_K1TMP*4(k1) # restore k1 j k0 # save return address in k0 1:#endif # if (curlst == &clilst) branch to 1f la k0,curlst lw k0,(k0) la k1,clilst beq k0,k1,1f .set noreorder mfc0 a0,C0_EPC nop mfc0 a1,C0_CAUSE nop .set reorder la k1,DBGREG lw k1,R_K1TMP*4(k1) # restore k1 j pmexception1: la k0,DBGREG lw k1,R_K1TMP*4(k0) # restore k1 sw k1,R_K1*4(k0) /* $27 (k1) */ sw AT,R_AT*4(k0) /* $1 (AT) */ .set at sw v0,R_V0*4(k0) /* $2 (v0) */ sw v1,R_V1*4(k0) /* $3 (v1) */ sw a0,R_A0*4(k0) /* $4 (a0) */ sw a1,R_A1*4(k0) /* $5 (a1) */ sw a2,R_A2*4(k0) /* $6 (a2) */ sw a3,R_A3*4(k0) /* $7 (a3) */ sw t0,R_T0*4(k0) /* $8 (t0) */ sw t1,R_T1*4(k0) /* $9 (t1) */ sw t2,R_T2*4(k0) /* $10 (t2) */ sw t3,R_T3*4(k0) /* $11 (t3) */ sw t4,R_T4*4(k0) /* $12 (t4) */ sw t5,R_T5*4(k0) /* $13 (t5) */ sw t6,R_T6*4(k0) /* $14 (t6) */ sw t7,R_T7*4(k0) /* $15 (t7) */ sw s0,R_S0*4(k0) /* $16 (s0) */ sw s1,R_S1*4(k0) /* $17 (s1) */ sw s2,R_S2*4(k0) /* $18 (s2) */ sw s3,R_S3*4(k0) /* $19 (s3) */ sw s4,R_S4*4(k0) /* $20 (s4) */ sw s5,R_S5*4(k0) /* $21 (s5) */ sw s6,R_S6*4(k0) /* $22 (s6) */ sw s7,R_S7*4(k0) /* $23 (s7) */ sw t8,R_T8*4(k0) /* $24 (t8) */ sw t9,R_T9*4(k0) /* $25 (t9) */ /* $26 (k0) */ sw gp,R_GP*4(k0) /* $28 (gp) */ sw sp,R_SP*4(k0) /* $29 (sp) */ sw s8,R_FP*4(k0) /* $30 (s8) */ sw ra,R_RA*4(k0) /* $31 (ra) */ .set noreorder#ifdef R4KEXCEPTIONS mfc0 k1,C0_SR # get current SR value nop and k1,~(1<<1) # SR_EXL sw k1,R_STATUS*4(k0) # save Status#else # save the SR value but fixup the KU & IE bits to # reflect their state before the exception mfc0 k1,C0_SR # get current SR value nop li t0,0x3f # KU&IE mask and t1,k1,t0 # extract KU&IE bits not t0 # invert the mask and k1,t0 # clear KU&IE field srl t1,2 # fixup KU&IE field or k1,t1 # insert the KU&IE field sw k1,R_STATUS*4(k0) # save Status#endif mfc0 k1,C0_CAUSE nop sw k1,R_CAUSE*4(k0) /* Cause */ mfc0 k1,C0_EPC nop sw k1,R_PC*4(k0) /* EPC */ mfc0 k1,C0_BADVADDR nop sw k1,R_BADVA*4(k0) /* BadVA */ .set reorder # 970404 moved to be after C0_CAUSE because emulated mfhi/mflo # obscures the cause and epc reg mfhi k1 sw k1,R_HI*4(k0) /* Hi */ mflo k1 sw k1,R_LO*4(k0) /* Lo */ la sp,stack+STKSIZE-24 la t0,exception j t0 .end _exception/************************************************************** onintr()* Used to install user defined exception handlers.*/ .globl onintr .ent onintronintr: # a0=exec a1=struct sll a0,2 la t0,idummy sw t0,(a1) la t1,hndlrtbl addu t1,a0 lw t0,(t1) beq t0,zero,1f sw t0,(a1)1: sw a1,(t1) j ra .end onintr/************************************************************** clrhndlrs()* Used to remove user defined exception handlers.* also recopies exception vector handler.*/ .globl clrhndlrs .ent clrhndlrsclrhndlrs: subu sp,24 sw ra,20(sp) # remove user defined handlers la t1,hndlrtbl li t2,0 li t3,161: sll t0,t2,2 addu t0,t1 sw zero,(t0) addu t2,1 bne t2,t3,1b#if !defined(NON_CACHED) && !defined(LR64388) # recopy the handler la a0,handler la a1,ehandler li a2,0x80000000 # utlb miss jal copyHandler/* always copy this. But sometimes it's pointless */ li a2,0x80000040 # debug jal copyHandler li a2,0x80000080 # general vector jal copyHandler li a0,ICACHE jal flush_cache#endif lw ra,20(sp) addu sp,24 j ra .end clrhndlrs/************************************************************** clienttos()* This routine returns the correct top-of-stack value.* Used by C routines, when they need to set the client stack pointer.*/ .globl clienttos .ent clienttosclienttos:#ifdef NEWMEMSIZE la t0,topClientMem lw v0,(t0)#else la t0,memorysize lw v0,(t0) addu v0,CLIENTPC#endif and v0,~7 # double word align subu v0,24 # make room for a0-a3.. j ra .end clienttos/************************************************************** disableints()* This is used make sure that interrupts are disabled.*/ .globl disableints .ent disableintsdisableints: .set noreorder mfc0 t0,C0_SR nop and t0,~SR_IEC mtc0 t0,C0_SR .set reorder j ra .end disableints#if 0/************************************************************** cp1init()* Used to initialize coprocessor 1 (the FPU)*/ .globl cp1init .ent cp1initcp1init: .set noreorder mfc0 t0,C0_SR nop or t0,SR_CU1 mtc0 t0,C0_SR nop # give it time.. nop # .. la t6,DBGREG cfc1 t1,C1_CSR nop sw t1,R_FCR*4(t6) nop # required because of 33000 bug cfc1 t1,C1_FRID nop sw t1,R_FID*4(t6) .set reorder j ra .end cp1init#endif/************************************************************** copyHandler:* Used to copy the exception handler to the various* vector addresses.*/ .globl copyHandler .ent copyHandlercopyHandler: # a0=src a1=end a2=dst # must not change a0 or a1 # must force a0 & a1 to kseg1 or t0,a0,K1BASE or t1,a1,K1BASE1: lw v0,(t0) sw v0,(a2) addu t0,4 addu a2,4 blt t0,t1,1b j ra .end copyHandler/************************************************************** flush_cache(type,adr)* Flush the designated cache (ICACHEI, DCACHE, ICACHE, IADDR)* Note that this is not a real subroutine, it simply* transfers control to the routine pointed to by 'flush_ptr',* being very careful to not use Kseg0 just in case the caches* haven't been flushed yet.*/ .globl flush_target .globl flush_cache .ent flush_cacheflush_target: # a0=type a1=adrflush_cache: # a0=type a1=adr la t1,flush_ptr or t1,K1BASE lw t0,(t1) or t0,K1BASE bne t0,zero,1f j ra 1: j t0 .end flush_cache/************************************************************** Ulong sw2keg1()*/ .globl sw2kseg1 .ent sw2kseg1sw2kseg1: # switch to kseg1 move v0,ra or ra,K1BASE j ra .end sw2kseg1/************************************************************** restoreKseg(Ulong addr)*/ .globl restoreKseg .ent restoreKsegrestoreKseg: and ra,~0xe0000000 and a0,0xe0000000 or ra,a0 j ra .end restoreKseg#ifdef ATMIZER/************************************************************** atmizer_flush* dummy flush routine, the ATMizer has no flushable cache*/ .globl atmizer_flush .ent atmizer_flushatmizer_flush: j ra .end atmizer_flush#endif/* * This is used by onintr to terminate the list of user defined handlers * for a given EXC value. */ .dataidummy: .word 0 .word exc2/* provide a default value for a1 */initial_a1: .asciiz "g"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -