📄 cpu_support.s
字号:
sdc1 $f20, 20*8($t1) sdc1 $f21, 21*8($t1) sdc1 $f22, 22*8($t1) sdc1 $f23, 23*8($t1) sdc1 $f24, 24*8($t1) sdc1 $f25, 25*8($t1) sdc1 $f26, 26*8($t1) sdc1 $f27, 27*8($t1) sdc1 $f28, 28*8($t1) sdc1 $f29, 29*8($t1) sdc1 $f30, 30*8($t1) sdc1 $f31, 31*8($t1) cfc1 $t8, $31 // fcr31 sd $t8, 32*8($t1) l_nosave_fpu: lw $t1, TCB_isstack($t0) // Restore FPU context ldc1 $f0, 0*8($t1) ldc1 $f1, 1*8($t1) ldc1 $f2, 2*8($t1) ldc1 $f3, 3*8($t1) ldc1 $f4, 4*8($t1) ldc1 $f5, 5*8($t1) ldc1 $f6, 6*8($t1) ldc1 $f7, 7*8($t1) ldc1 $f8, 8*8($t1) ldc1 $f9, 9*8($t1) ldc1 $f10, 10*8($t1) ldc1 $f11, 11*8($t1) ldc1 $f12, 12*8($t1) ldc1 $f13, 13*8($t1) ldc1 $f14, 14*8($t1) ldc1 $f15, 15*8($t1) ldc1 $f16, 16*8($t1) ldc1 $f17, 17*8($t1) ldc1 $f18, 18*8($t1) ldc1 $f19, 19*8($t1) ldc1 $f20, 20*8($t1) ldc1 $f21, 21*8($t1) ldc1 $f22, 22*8($t1) ldc1 $f23, 23*8($t1) ldc1 $f24, 24*8($t1) ldc1 $f25, 25*8($t1) ldc1 $f26, 26*8($t1) ldc1 $f27, 27*8($t1) ldc1 $f28, 28*8($t1) ldc1 $f29, 29*8($t1) ldc1 $f30, 30*8($t1) ldc1 $f31, 31*8($t1) ld $t8, 32*8($t1) ctc1 $t8, $31 // fcr31 sw $t0, Csym(fpu_ctxtsk) // fpu_ctxtsk = ctxtsk l_nosw_fpu: lw $t0, ISTKPOS lh $t1, 3*8+6($t0) // Higher half word of PSR or $t1, $t1, (SR_CU1|SR_FR) >> 16 sh $t1, 3*8+6($t0) // CP1(FPU) enable ld $t0, 0*8($sp) // Restore register for work ld $t1, 1*8($sp) ld $gp, 2*8($sp) addu $sp, $sp, 3*8 EIT_RETURN unavailable_cop l_goto_defaulthdr2: ld $t0, 0*8($sp) // Restore register for work ld $t1, 1*8($sp) ld $gp, 2*8($sp) addu $sp, $sp, 3*8 mtc0 $t9, $CP0_PSR // PSR restore l_goto_defaulthdr1: // t8 = Vector table address lw $kt0, EITVEC(EIT_DEFAULT) jr $kt0 .set at/* * Save FSP context * void save_fpuctx( T_COP0REGS *save_area ) */ .text .balign 4 .globl Csym(save_fpuctx) .type Csym(save_fpuctx), %functionCsym(save_fpuctx): mfc0 $t1, $CP0_PSR or $t0, $t0, SR_CU1|SR_FR mtc0 $t0, $CP0_PSR // FPU enable NOP(HzD_MTC0 - HzS_CU) sdc1 $f0, 0*8($a0) // Save FPU context sdc1 $f1, 1*8($a0) sdc1 $f2, 2*8($a0) sdc1 $f3, 3*8($a0) sdc1 $f4, 4*8($a0) sdc1 $f5, 5*8($a0) sdc1 $f6, 6*8($a0) sdc1 $f7, 7*8($a0) sdc1 $f8, 8*8($a0) sdc1 $f9, 9*8($a0) sdc1 $f10, 10*8($a0) sdc1 $f11, 11*8($a0) sdc1 $f12, 12*8($a0) sdc1 $f13, 13*8($a0) sdc1 $f14, 14*8($a0) sdc1 $f15, 15*8($a0) sdc1 $f16, 16*8($a0) sdc1 $f17, 17*8($a0) sdc1 $f18, 18*8($a0) sdc1 $f19, 19*8($a0) sdc1 $f20, 20*8($a0) sdc1 $f21, 21*8($a0) sdc1 $f22, 22*8($a0) sdc1 $f23, 23*8($a0) sdc1 $f24, 24*8($a0) sdc1 $f25, 25*8($a0) sdc1 $f26, 26*8($a0) sdc1 $f27, 27*8($a0) sdc1 $f28, 28*8($a0) sdc1 $f29, 29*8($a0) sdc1 $f30, 30*8($a0) sdc1 $f31, 31*8($a0) cfc1 $t0, $31 // fcr31 sd $t0, 32*8($a0) mtc0 $t1, $CP0_PSR // PSR restore jr $ra#endif /* TA_FPU *//* ------------------------------------------------------------------------ *//* * High level programming language routine for interrupt handler * Called by interrupt entry routine on the state saved in the interrupt * stack as shown below. * +---------------+ * isp -> | t8 | * +8 | t9 | * +16 | EPC | * +24 | PSR||taskmode | High:PSR Low:taskmode * +---------------+ * +32 | usp | Only RNG 1-3 * +---------------+ * * The vector table address is set in 't8.' * (t8 - EIT_VECTBL) / 4 = Vector number */ .text .balign 4 .globl Csym(defaulthdr_startup) .type Csym(defaulthdr_startup), %function .globl Csym(inthdr_startup) .type Csym(inthdr_startup), %functionCsym(defaulthdr_startup): .set noat /* During interrupt disable PSR.EXL=1 IE=? */ li $t9, EIT_DEFAULT << 2 // t9 = Vector table offset j l_inthdr1Csym(inthdr_startup): /* During interrupt disable PSR.EXL=1, IE=? */ li $t9, EIT_VECTBL subu $t9, $t8, $t9 // t9 = Vector table offset l_inthdr1: mfc0 $kt0, $CP0_PSR li $kt1, SR_DS|SR_IMMSK and $kt0, $kt0, $kt1 li $kt1, SR_XX|SR_KX|SR_SX|SR_UX or $kt0, $kt0, $kt1 mtc0 $kt0, $CP0_PSR // PSR setting EXL=0, IE=0 interrupt disable subu $sp, $sp, 24*8 // Register save sd $at, 4*8($sp) sd $v0, 5*8($sp) sd $v1, 6*8($sp) sd $a0, 7*8($sp) sd $a1, 8*8($sp) sd $a2, 9*8($sp) sd $a3, 10*8($sp) sd $t0, 11*8($sp) sd $t1, 12*8($sp) sd $t2, 13*8($sp) sd $t3, 14*8($sp) sd $t4, 15*8($sp) sd $t5, 16*8($sp) sd $t6, 17*8($sp) sd $t7, 18*8($sp) sd $gp, 19*8($sp) sd $fp, 20*8($sp) sd $ra, 21*8($sp) mfhi $t0 mflo $t1 sd $t0, 22*8($sp) sd $t1, 23*8($sp) .set at subu $a0, $t8, EIT_VECTBL srl $a0, $a0, 2 // a0 = dintno vector number#if USE_DBGSPT lui $t0, %hi(hook_ienter_jmp) lw $t0, %lo(hook_ienter_jmp)($t0) jr $t0 ret_hook_ienter:#endif lw $t0, Csym(hll_inthdr)($t9) lw $gp, Csym(hll_inthdr_gp)($t9) jalr $t0 // call hll_inthdr[n](dintno)#if USE_DBGSPT lui $t0, %hi(hook_ileave_jmp) lw $t0, %lo(hook_ileave_jmp)($t0) jr $t0 ret_hook_ileave:#endif .set noat ld $at, 4*8($sp) // Register restore ld $v0, 5*8($sp) ld $v1, 6*8($sp) ld $a0, 7*8($sp) ld $a1, 8*8($sp) ld $a2, 9*8($sp) ld $a3, 10*8($sp) ld $t0, 11*8($sp) ld $t1, 12*8($sp) ld $t2, 13*8($sp) ld $t3, 14*8($sp) ld $t4, 15*8($sp) ld $t5, 16*8($sp) ld $t6, 17*8($sp) ld $t7, 18*8($sp) ld $gp, 19*8($sp) ld $fp, 20*8($sp) ld $ra, 21*8($sp) ld $t8, 22*8($sp) ld $t9, 23*8($sp) mthi $t8 mtlo $t9 addu $sp, $sp, 24*8 EIT_RETURN inthdr_startup .set at#if USE_DBGSPT/* * Interrupt handler hook routine call * void enter( UINT dintno ) * void leave( UINT dintno ) */ .text .balign 4hook_ienter: subu $sp, $sp, 2*8 // Register save sd $t9, 4*8($sp) sd $a0, 5*8($sp) lw $t0, Csym(hook_ienterfn) lw $gp, Csym(hook_int_gp) jalr $t0 // call enter(dintno) ld $t9, 4*8($sp) // Register restore ld $a0, 5*8($sp) addu $sp, $sp, 1*8 // Leave a0 = dintno in stack j ret_hook_ienterhook_ileave: ld $a0, 4*8($sp) // Restore 'dintno' addu $sp, $sp, 1*8 lw $t0, Csym(hook_ileavefn) lw $gp, Csym(hook_int_gp) jalr $t0 // call leave(dintno) j ret_hook_ileave/* * Set/Free interrupt handler hook routine */ .text .balign 4 .globl Csym(hook_int) .type Csym(hook_int), %functionCsym(hook_int): la $t0, hook_ienter la $t1, hook_ileave sw $t0, hook_ienter_jmp sw $t1, hook_ileave_jmp jr $ra .globl Csym(unhook_int) .type Csym(unhook_int), %functionCsym(unhook_int): la $t0, ret_hook_ienter la $t1, ret_hook_ileave sw $t0, hook_ienter_jmp sw $t1, hook_ileave_jmp jr $ra .sdata .balign 4 hook_ienter_jmp: .int ret_hook_ienter hook_ileave_jmp: .int ret_hook_ileave#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ *//* * Entry processing of 'tk_ret_int()' */ .text .balign 4Csym(_tk_dis_dsp): addu $a0, $fp, 3*8+4 // PSR position on stack j Csym(c_tk_dis_dsp)Csym(_tk_ena_dsp): addu $a0, $fp, 3*8+4 // PSR position on stack j Csym(c_tk_ena_dsp)/* * Unsupported system call */ .text .balign 4 .globl Csym(no_support) .type Csym(no_support), %functionCsym(no_support): li $v0, E_RSFN jr $ra/* * System call entry table */ .text .balign 4 .type _svctbl, %object_svctbl: .int Csym(no_support)#define _tk_ret_int no_support#include <sys/svc/tksvctbl.h>#undef _tk_ret_int/* * System call entry * Do not need to save the temporary register. * The compiler saves the permanent register. * +---------------+ * isp/ssp -> | t8 | (Overwrite and save 'fp') * +8 | t9 | (Overwrite and save 'ra') * +16 | EPC | * +24 | PSR||taskmode | High:PSR Low:taskmode * +---------------+ * +32 | usp | Only RNG 1-3 * +---------------+ */ .text .balign 4 .globl Csym(call_entry) .type Csym(call_entry), %functionCsym(call_entry): /* During interrupt disable PSR.EXL=1, IE=? */ mfc0 $t0, $CP0_PSR and $t1, $t0, ~(SR_EXL|SR_IE) mtc0 $t1, $CP0_PSR // EXL=0, IE=0 Interrupt disable MOVE_ISP_SSP call_entry and $t1, $t0, ~SR_EXL mtc0 $t1, $CP0_PSR // EXL=0, IE=? caller's state subu $sp, $sp, 2*8 // Save register for work sd $s0, 0*8($sp) // s0 save sd $gp, 1*8($sp) // gp save sd $fp, 2*8($sp) // fp save (overwrite 't8') sd $ra, 3*8($sp) // ra save (overwrite 't9') addu $fp, $sp, 2*8 // fp = sp initial position move $t8, $gp // t8 = Caller gp move $s0, $v0 // s0 = Function code la $gp, _gp#if USE_DBGSPT lw $t0, hook_enter_jmp // Hook processing jr $t0 ret_hook_enter:#endif bgez $s0, l_esvc_function // s0 = Function code // <0: System call // >=0: Extended SVC /* T-Kernel system call */ lw $t1, 3*8($fp) // 'taskmode' when calling lw $t0, Csym(svc_call_limit) // Call protected level limit and $t1, $t1, TMF_CPL(3) // t1 = Protected level when calling bgt $t1, $t0, l_oacv_err sra $t2, $s0, 16 // t2 = Function number bgt $t2, N_TFN - 0x8000, l_illegal_svc srl $t3, $s0, 8 and $t3, $t3, 0xff // t3 = Number of arguments addu $t4, $fp, 4*8 // t4 = ssp Argument stack position (RNG0) beqz $t1, l_svc1 ld $t4, 4*8($fp) // t4 = usp Argument stack position (RNG1-3) l_svc1: subu $sp, $sp, 6*8 // Always set number of arguments to 6 sd $t8, 5*8($sp) // Sixth argument = Caller gp bltu $t3, 5, l_svc_p4 ld $t0, 4*8($t4) // Copy fifth argument sd $t0, 4*8($sp) l_svc_p4: sll $t2, $t2, 2 lw $t0, _svctbl - (-0x8000 << 2)($t2) jalr $t0 // T-Kernel system call addu $sp, $sp, 6*8 l_retsvc:#if USE_DBGSPT lw $t0, hook_leave_jmp // Hook processing jr $t0 ret_hook_leave:#endif ld $s0, -2*8($fp) // Restore register for work ld $t8, -1*8($fp) // Temporarily restore 'gp' to 't8' move $sp, $fp ld $fp, 0*8($sp) ld $ra, 1*8($sp) lw $t0, 3*8($sp) // If it is a call from protected level 0, and $t0, $t0, TMF_CPL(3) // do not process DCT beqz $t0, l_nodct_svc mfc0 $t1, $CP0_PSR // t1 = PSR#if TA_FPU and $t0, $t1, ~(SR_IE|SR_CU1)#else and $t0, $t1, ~SR_IE#endif mtc0 $t0, $CP0_PSR // Interrupt disable IE=0 NOP(HzD_MTC0 - HzS_INT) lw $t2, Csym(ctxtsk) // Is there a DCT request? lw $t0, TCB_reqdct($t2) bne $t0, 1, l_nodct_svc and $t0, $t1, SR_IM(1) // If it is dispatch disable, beqz $t0, l_nodct_svc // do not process DCT. lw $t3, ISTKPOS // If it is a call from the task independent part, lw $t4, Csym(int_stack_top)// do not process DCT. bne $t3, $t4, l_nodct_svc // (Suppose this does not happen, but just in case) move $gp, $t8 // gp restore j dct_startup // To DCT processing l_nodct_svc: move $gp, $t8 // gp restore MOVE_SSP_ISP call_entry CALL_RETURN call_entry l_esvc_function: /* Extended SVC */ move $a1, $s0 // a1 = Function code move $a2, $t8 // a2 = Caller gp subu $sp, $sp, 4*8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -