📄 mips.s
字号:
/* $Id: mips.S,v 1.15 2003/08/30 15:25:05 pefo Exp $ *//* * Copyright (c) 2000 Opsycon AB (www.opsycon.se) * Copyright (c) 2000 Rtmx, Inc (www.rtmx.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for Rtmx, Inc by * Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#define DEBUG#ifndef _KERNEL#define _KERNEL#endif#include <asm.h>#include <regnum.h>#include <cpu.h>#if __mips < 3#define STORE sw /* 32 bit mode regsave instruction */#define LOAD lw /* 32 bit mode regload instruction */#define FSTORE swc1 /* 32 bit mode float register store */#define FLOAD lwc1 /* 32 bit mode float register load */#define RSIZE 4 /* 32 bit mode register size */#else#define STORE sd /* 64 bit mode regsave instruction */#define LOAD ld /* 64 bit mode regload instruction */#define FSTORE sdc1 /* 32 bit mode float register store */#define FLOAD ldc1 /* 32 bit mode float register load */#define RSIZE 8 /* 64 bit mode register size */#endif#define NOP4 nop;nop;nop;nop#define NOP8 nop;nop;nop;nop;nop;nop;nop;nop .set noreorder .data/* Register area outgoing */#if !defined(SMP) .global DBGREG .common DBGREG, 128*8#endif/* return value and jump buffer used when exiting program returns. */ .global retvalueretvalue: .word 0 .globl go_return_jump .common go_return_jump, 12*8/* * Exception trampoline copied down to RAM after initialization. */ .text .globl MipsException .globl MipsExceptionEndMipsException: .set noat la k0, exception_handler jr k0 nop .set atMipsExceptionEnd:/* * Restore register state and transfer to new PC value. */LEAF(_go)#if defined(SMP) jal md_getcpuinfoptr nop move k0, v0#else la k0, DBGREG#endif_go_saved: li v0, SR_EXL /* Precaution */ mtc0 v0, COP_0_STATUS_REG ld t0, WATCHLO * RSIZE(k0) ld t1, WATCHHI * RSIZE(k0) dmtc0 t0, COP_0_WATCH_LO mfc0 t0, COP_0_PRID dmtc0 t1, COP_0_WATCH_HI srl t1, t0, 8 bne t1, MIPS_RM7000, 1f ld t0, WATCH1 * RSIZE(k0) /* RM7000 specific */ ld t1, WATCH2 * RSIZE(k0) mtc0 t0, COP_0_WATCH_1 ld t0, WATCHM * RSIZE(k0) mtc0 t1, COP_0_WATCH_2 ld t1, PCOUNT * RSIZE(k0) mtc0 t0, COP_0_WATCH_M ld t0, PCTRL * RSIZE(k0) mtc0 t1, COP_0_PC_COUNT ld t1, ICR * RSIZE(k0) mtc0 t0, COP_0_PC_CTRL mtc0 t1, COP_0_ICR1: LOAD v0, PC * RSIZE(k0) LOAD v1, CAUSE * RSIZE(k0) dmtc0 v0, COP_0_EXC_PC LOAD v0, SR * RSIZE(k0) mtc0 v1, COP_0_CAUSE_REG or v0, SR_EXL /* Keep Exeption level status */ mtc0 v0, COP_0_STATUS_REG LOAD v0, MULHI * RSIZE(k0) LOAD v1, MULLO * RSIZE(k0) mthi v0 mtlo v1 .set noat LOAD AT, AST * RSIZE(k0) LOAD v0, V0 * RSIZE(k0) LOAD v1, V1 * RSIZE(k0) LOAD a0, A0 * RSIZE(k0) LOAD a1, A1 * RSIZE(k0) LOAD a2, A2 * RSIZE(k0) LOAD a3, A3 * RSIZE(k0) LOAD t0, T0 * RSIZE(k0) LOAD t1, T1 * RSIZE(k0) LOAD t2, T2 * RSIZE(k0) LOAD t3, T3 * RSIZE(k0) LOAD t4, T4 * RSIZE(k0) LOAD t5, T5 * RSIZE(k0) LOAD t6, T6 * RSIZE(k0) LOAD t7, T7 * RSIZE(k0) LOAD s0, S0 * RSIZE(k0) LOAD s1, S1 * RSIZE(k0) LOAD s2, S2 * RSIZE(k0) LOAD s3, S3 * RSIZE(k0) LOAD s4, S4 * RSIZE(k0) LOAD s5, S5 * RSIZE(k0) LOAD s6, S6 * RSIZE(k0) LOAD s7, S7 * RSIZE(k0) LOAD t8, T8 * RSIZE(k0) LOAD t9, T9 * RSIZE(k0) LOAD k1, K1 * RSIZE(k0) LOAD gp, GP * RSIZE(k0) LOAD sp, SP * RSIZE(k0) LOAD s8, S8 * RSIZE(k0) LOAD ra, RA * RSIZE(k0) LOAD k0, K0 * RSIZE(k0) .set at eretEND(_go)/* * Top return address set to this func so a program returning * is catched and control gracefully passed to PMON2000. */LEAF(_exit) move s0, v0 /* Save return value */#if defined(SMP) jal tgt_smpwhoami nop beqz v0, 1f nop teq zero, zero /* CPU != 0. Goto holding */ nop /*noreturn*/1:#endif sw s0, retvalue la a0, go_return_jump jal longjmp li a1, 1 /* Sanity */END(_exit)#if defined(SMP)/* * Take a snapshot of the CPU for smp forking. */ .globl _pmon_snap .globl _pmon_snap_trap_pmon_snap: li v0, 0 /* This will be the return value */_pmon_snap_trap: teq zero, zero jr ra nop#endif/* * Main exception handler. Not really a leaf routine but not a normal * function either. Save away the entire cpu state end enter exception mode. */LEAF(exception_handler) .set noat#if defined(SMP) move k1, ra jal md_k0_getcputrapsp nop move ra, k1#else la k0, start - 1024#endif STORE AT, AST * RSIZE(k0) STORE v0, V0 * RSIZE(k0) STORE v1, V1 * RSIZE(k0) STORE a0, A0 * RSIZE(k0) STORE a1, A1 * RSIZE(k0) STORE a2, A2 * RSIZE(k0) STORE a3, A3 * RSIZE(k0) STORE t0, T0 * RSIZE(k0) STORE t1, T1 * RSIZE(k0) STORE t2, T2 * RSIZE(k0) STORE t3, T3 * RSIZE(k0) STORE t4, T4 * RSIZE(k0) STORE t5, T5 * RSIZE(k0) STORE t6, T6 * RSIZE(k0) STORE t7, T7 * RSIZE(k0) STORE s0, S0 * RSIZE(k0) STORE s1, S1 * RSIZE(k0) STORE s2, S2 * RSIZE(k0) STORE s3, S3 * RSIZE(k0) STORE s4, S4 * RSIZE(k0) STORE s5, S5 * RSIZE(k0) STORE s6, S6 * RSIZE(k0) STORE s7, S7 * RSIZE(k0) STORE t8, T8 * RSIZE(k0) STORE t9, T9 * RSIZE(k0) STORE k1, K1 * RSIZE(k0) STORE gp, GP * RSIZE(k0) STORE sp, SP * RSIZE(k0) STORE s8, S8 * RSIZE(k0) STORE ra, RA * RSIZE(k0) .set at mfhi v0 mflo v1 STORE v0, MULHI * RSIZE(k0) STORE v1, MULLO * RSIZE(k0) mfc0 a0, COP_0_STATUS_REG mfc0 v1, COP_0_CAUSE_REG STORE a0, SR * RSIZE(k0) dmfc0 v0, COP_0_BAD_VADDR STORE v1, CAUSE * RSIZE(k0) dmfc0 v1, COP_0_EXC_PC STORE v0, BADVADDR * RSIZE(k0) STORE v1, PC * RSIZE(k0) dmfc0 v0, COP_0_TLB_CONTEXT dmfc0 v1, COP_0_TLB_XCONTEXT sd v0, CONTX * RSIZE(k0) sd v1, XCONTX * RSIZE(k0) dmfc0 v0, COP_0_TLB_HI dmfc0 v1, COP_0_TLB_LO0 sd v0, ENTHI * RSIZE(k0) dmfc0 v0, COP_0_TLB_LO1 sd v1, ENTLO0 * RSIZE(k0) sd v0, ENTLO1 * RSIZE(k0) dmfc0 t0, COP_0_WATCH_LO dmfc0 t1, COP_0_WATCH_HI sd t0, WATCHLO * RSIZE(k0) mfc0 t0, COP_0_PRID sd t1, WATCHHI * RSIZE(k0) dmtc0 zero, COP_0_WATCH_LO dmtc0 zero, COP_0_WATCH_HI srl t1, t0, 8 sd t0, PRID * RSIZE(k0) mfc0 t0, COP_0_CONFIG bne t1, MIPS_RM7000, 1f sd t0, CONFIG * RSIZE(k0) mfc0 t0, COP_0_WATCH_1 mfc0 t1, COP_0_WATCH_2 sd t0, WATCH1 * RSIZE(k0) mfc0 t0, COP_0_WATCH_M sd t1, WATCH2 * RSIZE(k0) mfc0 t1, COP_0_PC_COUNT sd t0, WATCHM * RSIZE(k0) mfc0 t0, COP_0_PC_CTRL sd t1, PCOUNT * RSIZE(k0) mfc0 t1, COP_0_ICR sd t0, PCTRL * RSIZE(k0) sd t1, ICR * RSIZE(k0)1: addu sp, k0, -64 /* Get a new stack */ and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_KSU_MASK | SR_INT_ENAB) mtc0 t0, COP_0_STATUS_REG NOP8 la gp, _gp jal exception move a0, k0/* We may get back here when trap was handled by MD handler */ b _go_saved addu k0, sp, 64END(exception_handler)/* * Save/restore floating point registers. * Call with a0 pointing at frame. */LEAF(md_fpsave) 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 */ cfc1 t0, FPC_CSR /* get updated status... */ FSTORE $f0, F0 * RSIZE(a0) FSTORE $f1, F1 * RSIZE(a0) FSTORE $f2, F2 * RSIZE(a0) FSTORE $f3, F3 * RSIZE(a0) FSTORE $f4, F4 * RSIZE(a0) FSTORE $f5, F5 * RSIZE(a0) FSTORE $f6, F6 * RSIZE(a0) FSTORE $f7, F7 * RSIZE(a0) FSTORE $f8, F8 * RSIZE(a0) FSTORE $f9, F9 * RSIZE(a0) FSTORE $f10, F10 * RSIZE(a0) FSTORE $f11, F11 * RSIZE(a0) FSTORE $f12, F12 * RSIZE(a0) FSTORE $f13, F13 * RSIZE(a0) FSTORE $f14, F14 * RSIZE(a0) FSTORE $f15, F15 * RSIZE(a0) FSTORE $f16, F16 * RSIZE(a0) FSTORE $f17, F17 * RSIZE(a0) FSTORE $f18, F18 * RSIZE(a0) FSTORE $f19, F19 * RSIZE(a0) FSTORE $f20, F20 * RSIZE(a0) FSTORE $f21, F21 * RSIZE(a0) FSTORE $f22, F22 * RSIZE(a0) FSTORE $f23, F23 * RSIZE(a0) FSTORE $f24, F24 * RSIZE(a0) FSTORE $f25, F25 * RSIZE(a0) FSTORE $f26, F26 * RSIZE(a0) FSTORE $f27, F27 * RSIZE(a0) FSTORE $f28, F28 * RSIZE(a0) FSTORE $f29, F29 * RSIZE(a0) FSTORE $f30, F30 * RSIZE(a0) FSTORE $f31, F31 * RSIZE(a0) STORE t0, FSR * RSIZE(a0) mtc0 t1, COP_0_STATUS_REG mfc0 t0, COP_0_TLB_RANDOM mfc0 t1, COP_0_TLB_INDEX sd t0, RANDOM * RSIZE(a0) mfc0 t0, COP_0_TLB_LO0 sd t1, INDEX * RSIZE(a0) mfc0 t1, COP_0_TLB_LO1 sd t0, ENTLO0 * RSIZE(a0) mfc0 t0, COP_0_TLB_CONTEXT sd t1, ENTLO1 * RSIZE(a0) mfc0 t1, COP_0_TLB_PG_MASK sd t0, CONTX * RSIZE(a0) mfc0 t0, COP_0_TLB_WIRED sd t1, PGMSK * RSIZE(a0) mfc0 t1, COP_0_COUNT sd t0, WIRED * RSIZE(a0) mfc0 t0, COP_0_TLB_HI sd t1, COUNT * RSIZE(a0) mfc0 t1, COP_0_COMPARE sd t0, ENTHI * RSIZE(a0) mfc0 t0, COP_0_CONFIG sd t1, COMPARE * RSIZE(a0) mfc0 t1, COP_0_LLADDR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -