diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1995-11-14 08:00:00 +0000 |
commit | e7c2a72e2680827d6a733931273a93461c0d8d1b (patch) | |
tree | c9abeda78ef7504062bb2e816bcf3e3c9d680112 /arch/mips/kernel/gdb-low.S | |
parent | ec6044459060a8c9ce7f64405c465d141898548c (diff) |
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'arch/mips/kernel/gdb-low.S')
-rw-r--r-- | arch/mips/kernel/gdb-low.S | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S new file mode 100644 index 000000000..ea775e732 --- /dev/null +++ b/arch/mips/kernel/gdb-low.S @@ -0,0 +1,300 @@ +/* + * arch/mips/kernel/gdb-low.S + * + * gdb-low.S contains the low-level trap handler for the GDB stub. + * + * Copyright (C) 1995 Andreas Busse + */ + +#include <linux/sys.h> + +#include <asm/asm.h> +#include <asm/segment.h> +#include <asm/mipsregs.h> +#include <asm/mipsconfig.h> +#include <asm/stackframe.h> +#include <asm/gdb-stub.h> + +/* + * The low level trap handler + */ + .align 5 + NESTED(trap_low, GDB_FR_SIZE, sp) + .set noat + .set noreorder + + mfc0 k0,CP0_STATUS + sll k0,3 /* extract cu0 bit */ + bltz k0,1f + move k1,sp + + /* + * Called from user mode, new stack + */ + lui k1,%hi(kernelsp) + lw k1,%lo(kernelsp)(k1) +1: move k0,sp + subu sp,k1,GDB_FR_SIZE + sw k0,GDB_FR_REG29(sp) + sw v0,GDB_FR_REG2(sp) + +/* + * first save the CP0 and special registers + */ + + mfc0 v0,CP0_STATUS + sw v0,GDB_FR_STATUS(sp) + mfc0 v0,CP0_CAUSE + sw v0,GDB_FR_CAUSE(sp) + mfc0 v0,CP0_EPC + sw v0,GDB_FR_EPC(sp) + mfc0 v0,CP0_BADVADDR + sw v0,GDB_FR_BADVADDR(sp) + mfhi v0 + sw v0,GDB_FR_HI(sp) + mflo v0 + sw v0,GDB_FR_LO(sp) + +/* + * Now the integer registers + */ + + sw zero,GDB_FR_REG0(sp) /* I know... */ + sw $1,GDB_FR_REG1(sp) + /* v0 already saved */ + sw v1,GDB_FR_REG3(sp) + sw a0,GDB_FR_REG4(sp) + sw a1,GDB_FR_REG5(sp) + sw a2,GDB_FR_REG6(sp) + sw a3,GDB_FR_REG7(sp) + sw t0,GDB_FR_REG8(sp) + sw t1,GDB_FR_REG9(sp) + sw t2,GDB_FR_REG10(sp) + sw t3,GDB_FR_REG11(sp) + sw t4,GDB_FR_REG12(sp) + sw t5,GDB_FR_REG13(sp) + sw t6,GDB_FR_REG14(sp) + sw t7,GDB_FR_REG15(sp) + sw s0,GDB_FR_REG16(sp) + sw s1,GDB_FR_REG17(sp) + sw s2,GDB_FR_REG18(sp) + sw s3,GDB_FR_REG19(sp) + sw s4,GDB_FR_REG20(sp) + sw s5,GDB_FR_REG21(sp) + sw s6,GDB_FR_REG22(sp) + sw s7,GDB_FR_REG23(sp) + sw t8,GDB_FR_REG24(sp) + sw t9,GDB_FR_REG25(sp) + sw k0,GDB_FR_REG26(sp) + sw k1,GDB_FR_REG27(sp) + sw gp,GDB_FR_REG28(sp) + /* sp already saved */ + sw fp,GDB_FR_REG30(sp) + sw ra,GDB_FR_REG31(sp) + + STI /* disable interrupts */ + +/* + * Followed by the floating point registers + */ + mfc0 v0,CP0_STATUS /* check if the FPU is enabled */ + srl v0,v0,16 + andi v0,v0,(ST0_CU1 >> 16) + beqz v0,2f /* disabled, skip */ + nop + + swc1 $0,GDB_FR_FPR0(sp) + swc1 $1,GDB_FR_FPR1(sp) + swc1 $2,GDB_FR_FPR2(sp) + swc1 $3,GDB_FR_FPR3(sp) + swc1 $4,GDB_FR_FPR4(sp) + swc1 $5,GDB_FR_FPR5(sp) + swc1 $6,GDB_FR_FPR6(sp) + swc1 $7,GDB_FR_FPR7(sp) + swc1 $8,GDB_FR_FPR8(sp) + swc1 $9,GDB_FR_FPR9(sp) + swc1 $10,GDB_FR_FPR10(sp) + swc1 $11,GDB_FR_FPR11(sp) + swc1 $12,GDB_FR_FPR12(sp) + swc1 $13,GDB_FR_FPR13(sp) + swc1 $14,GDB_FR_FPR14(sp) + swc1 $15,GDB_FR_FPR15(sp) + swc1 $16,GDB_FR_FPR16(sp) + swc1 $17,GDB_FR_FPR17(sp) + swc1 $18,GDB_FR_FPR18(sp) + swc1 $19,GDB_FR_FPR19(sp) + swc1 $20,GDB_FR_FPR20(sp) + swc1 $21,GDB_FR_FPR21(sp) + swc1 $22,GDB_FR_FPR22(sp) + swc1 $23,GDB_FR_FPR23(sp) + swc1 $24,GDB_FR_FPR24(sp) + swc1 $25,GDB_FR_FPR25(sp) + swc1 $26,GDB_FR_FPR26(sp) + swc1 $27,GDB_FR_FPR27(sp) + swc1 $28,GDB_FR_FPR28(sp) + swc1 $29,GDB_FR_FPR29(sp) + swc1 $30,GDB_FR_FPR30(sp) + swc1 $31,GDB_FR_FPR31(sp) + +/* + * FPU control registers + */ + + mfc1 v0,CP1_STATUS + sw v0,GDB_FR_FSR(sp) + mfc1 v0,CP1_REVISION + sw v0,GDB_FR_FIR(sp) + +/* + * current stack frame ptr + */ + +2: sw sp,GDB_FR_FRP(sp) + +/* + * CP0 registers (R4000/R4400 unused registers skipped) + */ + + mfc0 v0,CP0_INDEX + sw v0,GDB_FR_CP0_INDEX(sp) + mfc0 v0,CP0_RANDOM + sw v0,GDB_FR_CP0_RANDOM(sp) + mfc0 v0,CP0_ENTRYLO0 + sw v0,GDB_FR_CP0_ENTRYLO0(sp) + mfc0 v0,CP0_ENTRYLO1 + sw v0,GDB_FR_CP0_ENTRYLO1(sp) + mfc0 v0,CP0_PAGEMASK + sw v0,GDB_FR_CP0_PAGEMASK(sp) + mfc0 v0,CP0_WIRED + sw v0,GDB_FR_CP0_WIRED(sp) + mfc0 v0,CP0_ENTRYHI + sw v0,GDB_FR_CP0_ENTRYHI(sp) + mfc0 v0,CP0_PRID + sw v0,GDB_FR_CP0_PRID(sp) + + .set at + +/* + * continue with the higher level handler + */ + + move a0,sp + jal handle_exception + nop + +/* + * restore all writable registers, in reverse order + */ + + .set noat + + lw v0,GDB_FR_CP0_ENTRYHI(sp) + lw v1,GDB_FR_CP0_WIRED(sp) + mtc0 v0,CP0_ENTRYHI + mtc0 v1,CP0_WIRED + lw v0,GDB_FR_CP0_PAGEMASK(sp) + lw v1,GDB_FR_CP0_ENTRYLO1(sp) + mtc0 v0,CP0_PAGEMASK + mtc0 v1,CP0_ENTRYLO1 + lw v0,GDB_FR_CP0_ENTRYLO0(sp) + lw v1,GDB_FR_CP0_INDEX(sp) + mtc0 v0,CP0_ENTRYLO0 + mtc0 v1,CP0_INDEX + +/* + * Next, the floating point registers + */ + mfc0 v0,CP0_STATUS /* check if the FPU is enabled */ + srl v0,v0,16 + andi v0,v0,(ST0_CU1 >> 16) + beqz v0,3f /* disabled, skip */ + nop + + lwc1 $31,GDB_FR_FPR31(sp) + lwc1 $30,GDB_FR_FPR30(sp) + lwc1 $29,GDB_FR_FPR29(sp) + lwc1 $28,GDB_FR_FPR28(sp) + lwc1 $27,GDB_FR_FPR27(sp) + lwc1 $26,GDB_FR_FPR26(sp) + lwc1 $25,GDB_FR_FPR25(sp) + lwc1 $24,GDB_FR_FPR24(sp) + lwc1 $23,GDB_FR_FPR23(sp) + lwc1 $22,GDB_FR_FPR22(sp) + lwc1 $21,GDB_FR_FPR21(sp) + lwc1 $20,GDB_FR_FPR20(sp) + lwc1 $19,GDB_FR_FPR19(sp) + lwc1 $18,GDB_FR_FPR18(sp) + lwc1 $17,GDB_FR_FPR17(sp) + lwc1 $16,GDB_FR_FPR16(sp) + lwc1 $15,GDB_FR_FPR15(sp) + lwc1 $14,GDB_FR_FPR14(sp) + lwc1 $13,GDB_FR_FPR13(sp) + lwc1 $12,GDB_FR_FPR12(sp) + lwc1 $11,GDB_FR_FPR11(sp) + lwc1 $10,GDB_FR_FPR10(sp) + lwc1 $9,GDB_FR_FPR9(sp) + lwc1 $8,GDB_FR_FPR8(sp) + lwc1 $7,GDB_FR_FPR7(sp) + lwc1 $6,GDB_FR_FPR6(sp) + lwc1 $5,GDB_FR_FPR5(sp) + lwc1 $4,GDB_FR_FPR4(sp) + lwc1 $3,GDB_FR_FPR3(sp) + lwc1 $2,GDB_FR_FPR2(sp) + lwc1 $1,GDB_FR_FPR1(sp) + lwc1 $0,GDB_FR_FPR0(sp) + +/* + * Now the CP0 and integer registers + */ + +3: mfc0 t0,CP0_STATUS + ori t0,0x1f + xori t0,0x1f + mtc0 t0,CP0_STATUS + + lw v0,GDB_FR_STATUS(sp) + lw v1,GDB_FR_EPC(sp) + mtc0 v0,CP0_STATUS + mtc0 v1,CP0_EPC + lw v0,GDB_FR_HI(sp) + lw v1,GDB_FR_LO(sp) + mthi v0 + mtlo v0 + lw ra,GDB_FR_REG31(sp) + lw fp,GDB_FR_REG30(sp) + lw gp,GDB_FR_REG28(sp) + lw k1,GDB_FR_REG27(sp) + lw k0,GDB_FR_REG26(sp) + lw t9,GDB_FR_REG25(sp) + lw t8,GDB_FR_REG24(sp) + lw s7,GDB_FR_REG23(sp) + lw s6,GDB_FR_REG22(sp) + lw s5,GDB_FR_REG21(sp) + lw s4,GDB_FR_REG20(sp) + lw s3,GDB_FR_REG19(sp) + lw s2,GDB_FR_REG18(sp) + lw s1,GDB_FR_REG17(sp) + lw s0,GDB_FR_REG16(sp) + lw t7,GDB_FR_REG15(sp) + lw t6,GDB_FR_REG14(sp) + lw t5,GDB_FR_REG13(sp) + lw t4,GDB_FR_REG12(sp) + lw t3,GDB_FR_REG11(sp) + lw t2,GDB_FR_REG10(sp) + lw t1,GDB_FR_REG9(sp) + lw t0,GDB_FR_REG8(sp) + lw a3,GDB_FR_REG7(sp) + lw a2,GDB_FR_REG6(sp) + lw a1,GDB_FR_REG5(sp) + lw a0,GDB_FR_REG4(sp) + lw v1,GDB_FR_REG3(sp) + lw v0,GDB_FR_REG2(sp) + lw $1,GDB_FR_REG1(sp) + lw sp,GDB_FR_REG29(sp) /* Deallocate stack */ + + ERET + .set at + .set reorder + END(trap_low) + +/* end of file gdb-low.S */ |