📄 cpu_asm.s
字号:
NOP(HzD_MTC0 - HzS_INT) dmfc0 $t8, $CP0_EHI // Save entry Hi and $t6, $a2, PTE_LOMSK // Convert from pte to Lo formants. and $t0, $a2, PTE_LOPFN or $t6, $t6, 0x10 // Cache mode correction (C bit) // 010 Cache off // 011 Write back/cache on srl $t0, $t0, ELO_PFNSFT or $t6, $t6, $t0 // t6 = Lo setting value and $t0, $a0, EHI_VPNMSK or $t0, $t0, $a1 dmtc0 $t0, $CP0_EHI NOP(HzD_MTC0 - HzS_TLBP) tlbp // Search for intended entry NOP(HzD_TLBP - HzS_MFC0) mfc0 $t0, $CP0_IDX bltz $t0, lu_newent // When not registered in TLB, register newly. /* Update */ tlbr // Read current entry NOP(HzD_TLBR - HzS_MFC0 - 2) and $t0, $a0, EHI_LOSEL // Select Lo register bnez $t0, lu_10 dmtc0 $t6, $CP0_ELO0 // Lo0 Setting j lu_11 lu_10: dmtc0 $t6, $CP0_ELO1 // Lo1 Setting lu_11: NOP(HzD_MTC0 - HzS_TLBW) tlbwi // Update TLB NOP(HzD_TLBW - HzS_FETCH - 1) j lu_ret lu_newent: /* Register newly */ and $t0, $a0, EHI_LOSEL // Select Lo register li $t1, ELO_INIT bnez $t0, lu_20 dmtc0 $t6, $CP0_ELO0 // Lo0 Setting dmtc0 $t1, $CP0_ELO1 // Lo1 Initialization j lu_21 lu_20: dmtc0 $t1, $CP0_ELO0 // Lo0 Initialization dmtc0 $t6, $CP0_ELO1 // Lo1 Setting lu_21: NOP(HzD_MTC0 - HzS_TLBW) tlbwr // Register new TLB NOP(HzD_TLBW - HzS_FETCH) lu_ret: dmtc0 $t8, $CP0_EHI // Restore entry Hi NOP(HzD_MTC0 - HzS_FETCH) mtc0_PSR $t7 // Turn back interrupt-disabled state jr $ra/* ------------------------------------------------------------------------ *//* * Exception handler *//* * Dedicated stack for page fault handler * Used as virtual memory within page fault handler * System stack cannot be used. */#define PAGEFAULTHDR_STACKSZ (4 * 1024)#define PAGEFAULTHDR_STACKTOP (pagefaulthdr_stack + PAGEFAULTHDR_STACKSZ) .lcomm pagefaulthdr_stack, PAGEFAULTHDR_STACKSZ/* * System exception handler entry * TA_ASM-format handler-format handler */ .text .balign 4 .globl Csym(asmSysExcHdr) .type Csym(asmSysExcHdr), %functionCsym(asmSysExcHdr): /* Interrupt is disabled PSR.EXL=1 IE=? */ .set noat lui $kt0, shigh(ISTKPOS) // Page fault at stack position lw $kt1, slow(ISTKPOS)($kt0) // Measures for adjusting to handler subu $kt1, $kt1, 1*8 sw $kt1, slow(ISTKPOS)($kt0) sd $sp, 0*8($kt1) // Save sp in exceptional stack dmfc0 $t9, $CP0_BVA // Obtain BadVAddr 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-disabled subu $sp, $sp, 23*8 // Save register 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 $ra, 20*8($sp) mfhi $t0 mflo $t1 sd $t0, 21*8($sp) sd $t1, 22*8($sp) .set at la $gp, _gp subu $a0, $t8, EIT_VECTBL srl $a0, $a0, 2 // vecno move $a1, $t9 // badvaddr jal Csym(SysExcHdr) // call SysExcHdr(vecno, badvaddr) lui $t0, shigh(ISTKPOS) // Turn back exception stack lw $t8, slow(ISTKPOS)($t0) addu $t8, $t8, 1*8 sw $t8, slow(ISTKPOS)($t0) .set noat ld $at, 4*8($sp) // Restore register 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 $ra, 20*8($sp) ld $t8, 21*8($sp) ld $t9, 22*8($sp) mthi $t8 mtlo $t9 addu $sp, $sp, 23*8 EIT_RETURN asmSysExcHdr .set at/* * Page fault handler entry * TA_ASM-format handler * * Provisional page fault handler entry * Used provisionally until T-Kernel starts. * Switched to a regular page fault handler after T-Kernel startup. */ .extern Csym(pPageFaultHdr), 4 // Address of page fault handler .text .balign 4 .globl Csym(asmPageFaultHdr) .type Csym(asmPageFaultHdr), %functionCsym(asmPageFaultHdr): /* Interrupt is disabled PSR.EXL=1 IE=? */ .set noat lui $kt0, shigh(ISTKPOS) lw $kt1, slow(ISTKPOS)($kt0) subu $kt1, $kt1, 1*8 sw $kt1, slow(ISTKPOS)($kt0) sd $sp, 0*8($kt1) // Save sp in exceptional stack la $kt0, pagefaulthdr_stack addu $t9, $kt0, PAGEFAULTHDR_STACKSZ sltu $kt0, $sp, $kt0 sltu $kt1, $sp, $t9 bnez $kt0, lf_stkchg bnez $kt1, lf_nostkchg // Do not switch if a dedicated stack is already used. lf_stkchg: move $sp, $t9 // Switch to dedicated stack lf_nostkchg: dmfc0 $t9, $CP0_BVA // Obtain BadVAddr 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-disabled subu $sp, $sp, 24*8 // Save register 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 $ra, 20*8($sp) mfhi $t0 mflo $t1 sd $t0, 21*8($sp) sd $t1, 22*8($sp) sd $t8, 23*8($sp) // Save vector table address .set at la $gp, _gp lw $t0, Csym(pPageFaultHdr) subu $a0, $t8, EIT_VECTBL srl $a0, $a0, 2 // vecno move $a1, $t9 // badvaddr jalr $t0 // call PageFaultHdr(vecno, badvaddr) lui $t0, shigh(ISTKPOS) // Turn back exception stack lw $t8, slow(ISTKPOS)($t0) ld $t9, 0*8($t8) // t9 = Stack pointer before switching addu $t8, $t8, 1*8 // t8 = isp sw $t8, slow(ISTKPOS)($t0) .set noat ld $t2, 21*8($sp) // Restore register ld $t3, 22*8($sp) mthi $t2 mtlo $t3 ld $at, 4*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 $ra, 20*8($sp) bnez $v0, lf_goto_monitor // When set at "!= 0", move to monitor ld $v0, 5*8($sp) // v0 Restore move $sp, $t9 // Turn back stack EIT_RETURN asmPageFaultHdr lf_goto_monitor: lw $v0, 3*8+4($t8) // PSR saved in exception stack or $v0, $v0, SR_KSU xor $v0, $v0, SR_KSU // PSR.KSU = 0 mtc0 $v0, $CP0_PSR ld $v0, 5*8($sp) // v0 Restore ld $t8, 23*8($sp) // Restore vector table address move $sp, $t9 // Turn back stack lui $kt0, %hi(Csym(DefaultHandlerEntry)) lw $kt0, %lo(Csym(DefaultHandlerEntry))($kt0) jr $kt0 // To monitor's default handler .set at/* * TLB miss exception handler * Registers are not saved to an exception stack through * an ordinary monitor. * Perform processing in the interrupt-disabled state without using stacks. */ .lcomm register_save_area, 3*8 // Area for saving work register .text .balign 4 .globl Csym(asmTLBMissHdr) .type Csym(asmTLBMissHdr), %functionCsym(asmTLBMissHdr): /* Interrupt is disabled PSR.EXL=1 IE=? */ .set noat la $kt0, register_save_area sd $at, 0*8($kt0) // Save work register sd $t0, 1*8($kt0) sd $t1, 2*8($kt0) .set at dmfc0 $kt1, $CP0_BVA // kt1 = BadVAddr dsra $t0, $kt1, 31 // Check if addresses are within valid range. not $t1, $t0 beqz $t0, lm_validaddr beqz $t1, lm_validaddr lm_invalidaddr: // Invalid address li $t0, ELO_INIT dmtc0 $t0, $CP0_ELO0 dmtc0 $t0, $CP0_ELO1 j lm_settlb lm_validaddr: // Valid address srl $t0, $kt1, 22 // t0 = Page directory index lw $t1, Csym(SATB) // t1 = Shared space page directory bgeu $t0, NUM_PDIR_ENTRIES, lm_sharedspace lw $t1, Csym(UATB) dmfc0 $kt0, $CP0_EHI and $kt0, $kt0, EHI_ASID // lsid sll $kt0, $kt0, SFT_PDIR_ENTRIES + 2 addu $t1, $t1, $kt0 // t1 = Unique space page directory lm_sharedspace: sll $kt0, $t0, 2 addu $t1, $t1, $kt0 lw $t1, ($t1) // PDE and $kt0, $t1, PTE_P // Check if page is valid. beqz $kt0, lm_notpresent_pde and $t1, $t1, PTE_PFA // t1 = Page table address or $t1, $t1, 0xffffffff80000000 // Convert into kseg0 area address sll $t0, $kt1, 10 srl $t0, $t0, 22 // t0 = Page table index sll $kt0, $t0, 2 addu $kt0, $t1, $kt0 lw $t1, 0($kt0) // PTE beqz $t1, lm_notpresent_pte or $t1, $t1, PTE_A // Set access bit sw $t1, 0($kt0) lm_notpresent_pte: and $t0, $t1, PTE_LOMSK // Convert from pte to Lo formants. and $t1, $t1, PTE_LOPFN or $t0, $t0, 0x10 // Cache mode correction srl $t1, $t1, ELO_PFNSFT or $t0, $t0, $t1 // t0 = Lo setting value and $kt0, $kt1, EHI_LOSEL li $t1, ELO_INIT bnez $kt0, lm_10 dmtc0 $t0, $CP0_ELO0 dmtc0 $t1, $CP0_ELO1 j lm_settlb lm_10: dmtc0 $t1, $CP0_ELO0 dmtc0 $t0, $CP0_ELO1 j lm_settlb lm_notpresent_pde: // Page table is absent. li $t1, ELO_INIT bgeu $t0, NUM_PDIR_ENTRIES, lm_20 xor $t1, $t1, ELO_G // Clear G bit in a unique space. lm_20: dmtc0 $t1, $CP0_ELO0 dmtc0 $t1, $CP0_ELO1 j lm_settlb lm_settlb: NOP(HzD_MTC0 - HzS_TLBW) tlbwr .set noat la $kt0, register_save_area ld $at, 0*8($kt0) // Restore work register ld $t0, 1*8($kt0) ld $t1, 2*8($kt0) eret .set at/* * TLB exception handler for re-startup processing * EXC_TLBINV_L TLB invalid exception (load) */ .text .balign 4 .globl Csym(warmBootTLBInvLHdr) .type Csym(warmBootTLBInvLHdr), %functionCsym(warmBootTLBInvLHdr): .set noat lui $kt0, shigh(SCINFO) // Restore from exception stack lw $kt1, slow(ISTKPOS)($kt0) lw $t8, 3*8($kt1) // taskmode lw $t9, 3*8+4($kt1) // PSR sw $t8, slow(TASKMODE)($kt0) mtc0 $t9, $CP0_PSR ld $t8, 0*8($kt1) ld $t9, 1*8($kt1) addu $kt1, $kt1, 4*8 sw $kt1, slow(ISTKPOS)($kt0) j Csym(asmTLBMissHdr) .set at/* ------------------------------------------------------------------------ *//* * Memory check function entry for monitor * W asmMonitorCheckMemory( VP laddr ) * * Always called in kernel mode and in interrupt-disabled state. */ .text .balign 4 .globl Csym(asmMonitorCheckMemory) .type Csym(asmMonitorCheckMemory), %functionCsym(asmMonitorCheckMemory): subu $sp, $sp, 7*8 sd $gp, 4*8($sp) sd $ra, 5*8($sp) la $gp, _gp mfc0 $t9, $CP0_PSR // PSR Save sd $t9, 6*8($sp) jal Csym(MonitorCheckMemory) ld $t9, 6*8($sp) mtc0 $t9, $CP0_PSR // PSR Restore ld $gp, 4*8($sp) ld $ra, 5*8($sp) addu $sp, $sp, 7*8 jr $ra/* ------------------------------------------------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -