📄 locore.s
字号:
* * MachEmptyWriteBuffer -- * * Return when the write buffer is empty. * * MachEmptyWriteBuffer() * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */LEAF(MachEmptyWriteBuffer) .set noreorder nop nop nop nop1: bc0t 1b nop j ra nop .set reorderEND(MachEmptyWriteBuffer)/*-------------------------------------------------------------------------- * * MachTLBWriteIndexed -- * * Write the given entry into the TLB at the given index. * * MachTLBWriteIndexed(index, highEntry, lowEntry) * int index; * int highEntry; * int lowEntry; * * Results: * None. * * Side effects: * TLB entry set. * *-------------------------------------------------------------------------- */LEAF(MachTLBWriteIndexed) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Save the current PID. sll a0, a0, VMMACH_TLB_INDEX_SHIFT mtc0 a0, MACH_COP_0_TLB_INDEX # Set the index. mtc0 a1, MACH_COP_0_TLB_HI # Set up entry high. mtc0 a2, MACH_COP_0_TLB_LOW # Set up entry low. nop tlbwi # Write the TLB mtc0 t0, MACH_COP_0_TLB_HI # Restore the PID. j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBWriteIndexed)#if 0/*-------------------------------------------------------------------------- * * MachTLBWriteRandom -- * * Write the given entry into the TLB at a random location. * * MachTLBWriteRandom(highEntry, lowEntry) * unsigned highEntry; * unsigned lowEntry; * * Results: * None. * * Side effects: * TLB entry set. * *-------------------------------------------------------------------------- */LEAF(MachTLBWriteRandom) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 v0, MACH_COP_0_TLB_HI # Save the current PID. nop mtc0 a0, MACH_COP_0_TLB_HI # Set up entry high. mtc0 a1, MACH_COP_0_TLB_LOW # Set up entry low. nop tlbwr # Write the TLB mtc0 v0, MACH_COP_0_TLB_HI # Restore the PID. j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBWriteRandom)#endif/*-------------------------------------------------------------------------- * * MachSetPID -- * * Write the given pid into the TLB pid reg. * * MachSetPID(pid) * int pid; * * Results: * None. * * Side effects: * PID set in the entry hi register. * *-------------------------------------------------------------------------- */LEAF(MachSetPID) .set noreorder sll a0, a0, VMMACH_TLB_PID_SHIFT # put PID in right spot mtc0 a0, MACH_COP_0_TLB_HI # Write the hi reg value j ra nop .set reorderEND(MachSetPID)/*-------------------------------------------------------------------------- * * MachTLBFlush -- * * Flush the "random" entries from the TLB. * * MachTLBFlush() * * Results: * None. * * Side effects: * The TLB is flushed. * *-------------------------------------------------------------------------- */LEAF(MachTLBFlush) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Save the PID li t1, MACH_CACHED_MEMORY_ADDR # invalid address mtc0 t1, MACH_COP_0_TLB_HI # Mark entry high as invalid mtc0 zero, MACH_COP_0_TLB_LOW # Zero out low entry./* * Align the starting value (t1) and the upper bound (t2). */ li t1, VMMACH_FIRST_RAND_ENTRY << VMMACH_TLB_INDEX_SHIFT li t2, VMMACH_NUM_TLB_ENTRIES << VMMACH_TLB_INDEX_SHIFT1: mtc0 t1, MACH_COP_0_TLB_INDEX # Set the index register. addu t1, t1, 1 << VMMACH_TLB_INDEX_SHIFT # Increment index. bne t1, t2, 1b tlbwi # Write the TLB entry. mtc0 t0, MACH_COP_0_TLB_HI # Restore the PID j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBFlush)#if 0/*-------------------------------------------------------------------------- * * MachTLBFlushPID -- * * Flush all entries with the given PID from the TLB. * * MachTLBFlushPID(pid) * int pid; * * Results: * None. * * Side effects: * All entries corresponding to this PID are flushed. * *-------------------------------------------------------------------------- */LEAF(MachTLBFlushPID) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Save the current PID sll a0, a0, VMMACH_TLB_PID_SHIFT # Align the pid to flush./* * Align the starting value (t1) and the upper bound (t2). */ li t1, VMMACH_FIRST_RAND_ENTRY << VMMACH_TLB_INDEX_SHIFT li t2, VMMACH_NUM_TLB_ENTRIES << VMMACH_TLB_INDEX_SHIFT mtc0 t1, MACH_COP_0_TLB_INDEX # Set the index register1: addu t1, t1, 1 << VMMACH_TLB_INDEX_SHIFT # Increment index. tlbr # Read from the TLB mfc0 t4, MACH_COP_0_TLB_HI # Fetch the hi register. nop and t4, t4, VMMACH_TLB_PID # compare PID's bne t4, a0, 2f li v0, MACH_CACHED_MEMORY_ADDR # invalid address mtc0 v0, MACH_COP_0_TLB_HI # Mark entry high as invalid mtc0 zero, MACH_COP_0_TLB_LOW # Zero out low entry. nop tlbwi # Write the entry.2: bne t1, t2, 1b mtc0 t1, MACH_COP_0_TLB_INDEX # Set the index register mtc0 t0, MACH_COP_0_TLB_HI # restore PID j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBFlushPID)#endif/*-------------------------------------------------------------------------- * * MachTLBFlushAddr -- * * Flush any TLB entries for the given address and TLB PID. * * MachTLBFlushAddr(highreg) * unsigned highreg; * * Results: * None. * * Side effects: * The process's page is flushed from the TLB. * *-------------------------------------------------------------------------- */LEAF(MachTLBFlushAddr) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Get current PID nop mtc0 a0, MACH_COP_0_TLB_HI # look for addr & PID nop tlbp # Probe for the entry. mfc0 v0, MACH_COP_0_TLB_INDEX # See what we got li t1, MACH_CACHED_MEMORY_ADDR # Load invalid entry. bltz v0, 1f # index < 0 => !found mtc0 t1, MACH_COP_0_TLB_HI # Mark entry high as invalid mtc0 zero, MACH_COP_0_TLB_LOW # Zero out low entry. nop tlbwi1: mtc0 t0, MACH_COP_0_TLB_HI # restore PID j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBFlushAddr)/*-------------------------------------------------------------------------- * * MachTLBUpdate -- * * Update the TLB if highreg is found; otherwise, enter the data. * * MachTLBUpdate(highreg, lowreg) * unsigned highreg, lowreg; * * Results: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */LEAF(MachTLBUpdate) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Save current PID nop # 2 cycles before intr disabled mtc0 a0, MACH_COP_0_TLB_HI # init high reg. nop tlbp # Probe for the entry. mfc0 v0, MACH_COP_0_TLB_INDEX # See what we got nop mtc0 a1, MACH_COP_0_TLB_LOW # init low reg. nop bltz v0, 1f # index < 0 => !found sra v0, v0, VMMACH_TLB_INDEX_SHIFT # convert index to regular num b 2f tlbwi # update slot found1: mtc0 a0, MACH_COP_0_TLB_HI # init high reg. nop tlbwr # enter into a random slot2: mtc0 t0, MACH_COP_0_TLB_HI # restore PID j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBUpdate)#if defined(DEBUG)/*-------------------------------------------------------------------------- * * MachTLBFind -- * * Search the TLB for the given entry. * * MachTLBFind(hi) * unsigned hi; * * Results: * Returns a value >= 0 if the entry was found (the index). * Returns a value < 0 if the entry was not found. * * Side effects: * tlbhi and tlblo will contain the TLB entry found. * *-------------------------------------------------------------------------- */ .comm tlbhi, 4 .comm tlblo, 4LEAF(MachTLBFind) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Get current PID nop mtc0 a0, MACH_COP_0_TLB_HI # Set up entry high. nop tlbp # Probe for the entry. mfc0 v0, MACH_COP_0_TLB_INDEX # See what we got nop bltz v0, 1f # not found nop tlbr # read TLB mfc0 t1, MACH_COP_0_TLB_HI # See what we got mfc0 t2, MACH_COP_0_TLB_LOW # See what we got sw t1, tlbhi sw t2, tlblo srl v0, v0, VMMACH_TLB_INDEX_SHIFT # convert index to regular num1: mtc0 t0, MACH_COP_0_TLB_HI # Restore current PID j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBFind)/*-------------------------------------------------------------------------- * * MachTLBRead -- * * Read the TLB entry. * * MachTLBRead(entry) * unsigned entry; * * Results: * None. * * Side effects: * tlbhi and tlblo will contain the TLB entry found. * *-------------------------------------------------------------------------- */LEAF(MachTLBRead) .set noreorder mfc0 v1, MACH_COP_0_STATUS_REG # Save the status register. mtc0 zero, MACH_COP_0_STATUS_REG # Disable interrupts mfc0 t0, MACH_COP_0_TLB_HI # Get current PID sll a0, a0, VMMACH_TLB_INDEX_SHIFT mtc0 a0, MACH_COP_0_TLB_INDEX # Set the index register nop tlbr # Read from the TLB mfc0 t3, MACH_COP_0_TLB_HI # fetch the hi entry mfc0 t4, MACH_COP_0_TLB_LOW # fetch the low entry sw t3, tlbhi sw t4, tlblo mtc0 t0, MACH_COP_0_TLB_HI # restore PID j ra mtc0 v1, MACH_COP_0_STATUS_REG # Restore the status register .set reorderEND(MachTLBRead)/*-------------------------------------------------------------------------- * * MachTLBGetPID -- * * MachTLBGetPID() * * Results: * Returns the current TLB pid reg. * * Side effects: * None. * *-------------------------------------------------------------------------- */#ifdef NOTDEFLEAF(MachTLBGetPID) .set noreorder mfc0 v0, MACH_COP_0_TLB_HI # get PID nop and v0, v0, VMMACH_TLB_PID # mask off PID j ra srl v0, v0, VMMACH_TLB_PID_SHIFT # put PID in right spot .set reorderEND(MachTLBGetPID)#endif /* NOTDEF *//* * Return the current value of the cause register. */#ifdef NOTDEFLEAF(MachGetCauseReg) .set noreorder mfc0 v0, MACH_COP_0_CAUSE_REG j ra nop .set reorderEND(MachGetCauseReg)#endif /* NOTDEF */#endif /* DEBUG *//*---------------------------------------------------------------------------- * * MachSwitchFPState -- * * Save the current state into 'from' and restore it from 'to'. * * MachSwitchFPState(from, to) * struct proc *from; * struct user *to; * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------------- */LEAF(MachSwitchFPState) .set noreorder mfc0 t1, MACH_COP_0_STATUS_REG # Save old SR li t0, MACH_SR_COP_1_BIT # enable the coprocessor mtc0 t0, MACH_COP_0_STATUS_REG beq a0, zero, 1f # skip save if NULL pointer nop/* * First read out the status register to make sure that all FP operations * have completed. */ lw a0, P_ADDR(a0) # get pointer to pcb for proc cfc1 t0, MACH_FPC_CSR # stall til FP done cfc1 t0, MACH_FPC_CSR # now get status li t3, ~MACH_SR_COP_1_BIT lw t2, U_PCB_REGS+(PS * 4)(a0) # get CPU status register sw t0, U_PCB_FPREGS+(32 * 4)(a0) # save FP status and t2, t2, t3 # clear COP_1 enable bit sw t2, U_PCB_REGS+(PS * 4)(a0) # save new status register/* * Save the floating point registers. */ swc1 $f0, U_PCB_FPREGS+(0 * 4)(a0) swc1 $f1, U_PCB_FPREGS+(1 * 4)(a0) swc1 $f2, U_PCB_FPREGS+(2 * 4)(a0) swc1 $f3, U_PCB_FPREGS+(3 * 4)(a0) swc1 $f4, U_PCB_FPREGS+(4 * 4)(a0) swc1 $f5, U_PCB_FPREGS+(5 * 4)(a0) swc1 $f6, U_PCB_FPREGS+(6 * 4)(a0) swc1 $f7, U_PCB_FPREGS+(7 * 4)(a0) swc1 $f8, U_PCB_FPREGS+(8 * 4)(a0) swc1 $f9, U_PCB_FPREGS+(9 * 4)(a0) swc1 $f10, U_PCB_FPREGS+(10 * 4)(a0) swc1 $f11, U_PCB_FPREGS+(11 * 4)(a0) swc1 $f12, U_PCB_FPREGS+(12 * 4)(a0) swc1 $f13, U_PCB_FPREGS+(13 * 4)(a0) swc1 $f14, U_PCB_FPREGS+(14 * 4)(a0) swc1 $f15, U_PCB_FPREGS+(15 * 4)(a0) swc1 $f16, U_PCB_FPREGS+(16 * 4)(a0) swc1 $f17, U_PCB_FPREGS+(17 * 4)(a0) swc1 $f18, U_PCB_FPREGS+(18 * 4)(a0) swc1 $f19, U_PCB_FPREGS+(19 * 4)(a0) swc1 $f20, U_PCB_FPREGS+(20 * 4)(a0) swc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -