📄 mips.s
字号:
sd t0, CONFIG * RSIZE(a0) mfc0 t0, COP_0_TLB_XCONTEXT sd t1, LLADR * RSIZE(a0) mfc0 t1, COP_0_ECC sd t0, XCONTX * RSIZE(a0) mfc0 t0, COP_0_CACHE_ERR sd t1, ECC * RSIZE(a0) mfc0 t1, COP_0_TAG_LO sd t0, CACHER * RSIZE(a0) mfc0 t0, COP_0_TAG_HI sd t1, TAGLO * RSIZE(a0) mfc0 t1, COP_0_ERROR_PC sd t0, TAGHI * RSIZE(a0) sd t1, ERRPC * RSIZE(a0) j ra nopEND(md_fpsave)LEAF(md_fprestore) mfc0 t1, COP_0_STATUS_REG or v0, t1, SR_COP_1_BIT|SR_FR_32 mtc0 v0, COP_0_STATUS_REG NOP8 cfc1 t0, FPC_CSR /* drain FP pipeline */ FLOAD $f0, F0 * RSIZE(a0) FLOAD $f1, F1 * RSIZE(a0) FLOAD $f2, F2 * RSIZE(a0) FLOAD $f3, F3 * RSIZE(a0) FLOAD $f4, F4 * RSIZE(a0) FLOAD $f5, F5 * RSIZE(a0) FLOAD $f6, F6 * RSIZE(a0) FLOAD $f7, F7 * RSIZE(a0) FLOAD $f8, F8 * RSIZE(a0) FLOAD $f9, F9 * RSIZE(a0) FLOAD $f10, F10 * RSIZE(a0) FLOAD $f11, F11 * RSIZE(a0) FLOAD $f12, F12 * RSIZE(a0) FLOAD $f13, F13 * RSIZE(a0) FLOAD $f14, F14 * RSIZE(a0) FLOAD $f15, F15 * RSIZE(a0) FLOAD $f16, F16 * RSIZE(a0) FLOAD $f17, F17 * RSIZE(a0) FLOAD $f18, F18 * RSIZE(a0) FLOAD $f19, F19 * RSIZE(a0) FLOAD $f20, F20 * RSIZE(a0) FLOAD $f21, F21 * RSIZE(a0) FLOAD $f22, F22 * RSIZE(a0) FLOAD $f23, F23 * RSIZE(a0) FLOAD $f24, F24 * RSIZE(a0) FLOAD $f25, F25 * RSIZE(a0) FLOAD $f26, F26 * RSIZE(a0) FLOAD $f27, F27 * RSIZE(a0) FLOAD $f28, F28 * RSIZE(a0) FLOAD $f29, F29 * RSIZE(a0) FLOAD $f30, F30 * RSIZE(a0) FLOAD $f31, F31 * RSIZE(a0) LOAD t0, FSR * RSIZE(a0) ctc1 t0, FPC_CSR mtc0 t1, COP_0_STATUS_REG NOP8 j ra nopEND(md_fprestore)/* * Get CP0 count register value */LEAF(CPU_GetCOUNT) mfc0 v0, COP_0_COUNT nop j ra nopEND(CPU_GetCOUNT)/* * Modify SR value, arg 1 = set bits, arg 2 = clear bits. */LEAF(CPU_SetSR) mfc0 v0, COP_0_STATUS_REG not v1, a1 and v1, v0 or v1, a0 mtc0 v1, COP_0_STATUS_REG NOP8 j ra nopEND(CPU_SetSR)/* * Get configuration register contents. */LEAF(CPU_GetCONFIG) mfc0 v0, COP_0_CONFIG j ra nopEND(CPU_GetCONFIG)/* * Get TLB entry for given index. */LEAF(CPU_GetTLB) mtc0 a0, COP_0_TLB_INDEX NOP4 tlbr NOP4 dmfc0 v0, COP_0_TLB_HI dmfc0 v1, COP_0_TLB_LO0 dmfc0 a0, COP_0_TLB_LO1 sd v0, 8(a1) dmfc0 v0, COP_0_TLB_PG_MASK sd v1, 16(a1) sd v0, 0(a1) j ra sd a0, 24(a1)END(CPU_GetTLB)/* * Helper routine to move a quad word in one operation. */LEAF(movequad) ld v0, 0(a1) sd v0, 0(a0) j ra nopEND(movequad)/* * Helper functions to read and write using 64 bit addresses * while configured for 32 bit addresses. */LEAF(a64_read32) mfc0 v1, COP_0_STATUS_REG or v0, v1, SR_KX mtc0 v0, COP_0_STATUS_REG NOP8 lw v0, 0(a0) mtc0 v1, COP_0_STATUS_REG NOP8 jr ra nopEND(a64_read32)LEAF(a64_write32) mfc0 v1, COP_0_STATUS_REG or v0, v1, SR_KX mtc0 v0, COP_0_STATUS_REG NOP8 sw a1, 0(a0) mtc0 v1, COP_0_STATUS_REG NOP8 jr ra nopEND(a64_write32)LEAF(a64_write8) mfc0 v1, COP_0_STATUS_REG or v0, v1, SR_KX mtc0 v0, COP_0_STATUS_REG NOP8 sb a1, 0(a0) mtc0 v1, COP_0_STATUS_REG NOP8 jr ra nopEND(a64_write8)/* * Semaphore handling support. * XXX In SMP systems it appears a situation where none gets * XXX a lock due to some kind of cache snoop congestion which * XXX just throws the cachline back and forth may occur. Adding * XXX a small slightly variable delay seems to help. */LEAF(CPU_Get_Sem) li t0, 5 /* Try this number of times */1: mfc0 v0, COP_0_COUNT andi v0, 0x1f /* Create a short variable delay */2: bnez v0, 2b addiu v0, -1 ll v0, (a0) bnez v0, 3f /* Already taken */ move v1, a1 sc v1, (a0) bnez v1, 4f /* Locked */ addiu t0, -1 bnez t0, 1b /* Try again */ nop3: jr ra li v0, 0 /* Not locked */4: jr ra li v0, 1 /* Lock aquired */END(CPU_Get_Sem)/* * Return CPU type. */LEAF(md_cputype) mfc0 v0, COP_0_PRID j ra nopEND(md_cputype)/* * execute a break instruction. */LEAF(_pmon_break) break 0 j ra nopEND(_pmon_break)/* * Block I/O routines mainly used by I/O drivers. * * Args as: a0 = port * a1 = memory address * a2 = count */LEAF(insb) beq a2, zero, 2f addu a2, a11: lbu v0, 0(a0) addu a1, 1 bne a1, a2, 1b sb v0, -1(a1)2: jr ra nopEND(insb)LEAF(insw) beq a2, zero, 2f addu a2, a2 addu a2, a11: lhu v0, 0(a0) addu a1, 2 bne a1, a2, 1b sh v0, -2(a1)2: jr ra nopEND(insw)LEAF(insl) beq a2, zero, 2f sll a2, 2 addu a2, a11: lw v0, 0(a0) addu a1, 4 bne a1, a2, 1b sw v0, -4(a1)2: jr ra nopEND(insl)LEAF(outsb) beq a2, zero, 2f addu a2, a11: lbu v0, 0(a1) addu a1, 1 bne a1, a2, 1b sb v0, 0(a0)2: jr ra nopEND(outsb)LEAF(outsw) beq a2, zero, 2f addu a2, a2 li v0, 1 and v0, a1 bne v0, zero, 3f # arghh, unaligned. addu a2, a11: lhu v0, 0(a1) addu a1, 2 bne a1, a2, 1b sh v0, 0(a0)2: jr ra nop3: LWHI v0, 0(a1) LWLO v0, 3(a1) addu a1, 2 bne a1, a2, 3b sh v0, 0(a0) jr ra nopEND(outsw)LEAF(outsl) beq a2, zero, 2f sll a2, 2 li v0, 3 and v0, a1 bne v0, zero, 3f # arghh, unaligned. addu a2, a11: lw v0, 0(a1) addu a1, 4 bne a1, a2, 1b sw v0, 0(a0)2: jr ra nop3: LWHI v0, 0(a1) LWLO v0, 3(a1) addu a1, 4 bne a1, a2, 3b sw v0, 0(a0) jr ra nopEND(outsl)/* * Access function that catches bus errors. Only 32 bits. * XXX needs to be fixed for SMP. */LEAF(read32_or_trap) la v0, 1f STORE v0, on_bus_error lwu v0, (a0) sync STORE zero, on_bus_error jr ra li v0, 01: /* Bad access */ jr ra li v0, -1END(read32_or_trap)/* * Probe an address for validity. */LEAF(md_read_or_trap) la v1, bad STORE v1, on_acc_error STORE v1, on_bus_error li v0, -1 srl a1, 1 bnez a1, 1f srl a1, 1 b 6f lbu v0, (a0)1: bnez a1, 2f srl a1, 1 b 6f lhu v0, (a0)2: bnez a1, 3f srl a1, 1 b 6f lwu v0, (a0)3: bnez a1, bad nop ld v0, (a0)6: sync sd v0, on_acc_data li v0, 0bad: STORE zero, on_acc_error STORE zero, on_bus_error jr ra nopEND(md_read_or_trap)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -