/* | |
* Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle | |
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. | |
* Copyright (C) 2002, 2007 Maciej W. Rozycki | |
* Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved. | |
* | |
* SPDX-License-Identifier: GPL-2.0+ | |
*/ | |
#include <asm/asm.h> | |
#include <asm/regdef.h> | |
#include <asm/mipsregs.h> | |
#include <asm/asm-offsets.h> | |
#define STATMASK 0x1f | |
.set noreorder | |
/* | |
* Macros copied and adapted from Linux MIPS | |
*/ | |
.macro SAVE_AT | |
.set push | |
.set noat | |
LONG_S $1, PT_R1(sp) | |
.set pop | |
.endm | |
.macro SAVE_TEMP | |
#if __mips_isa_rev < 6 | |
mfhi v1 | |
#endif | |
#ifdef CONFIG_32BIT | |
LONG_S $8, PT_R8(sp) | |
LONG_S $9, PT_R9(sp) | |
#endif | |
LONG_S $10, PT_R10(sp) | |
LONG_S $11, PT_R11(sp) | |
LONG_S $12, PT_R12(sp) | |
#if __mips_isa_rev < 6 | |
LONG_S v1, PT_HI(sp) | |
mflo v1 | |
#endif | |
LONG_S $13, PT_R13(sp) | |
LONG_S $14, PT_R14(sp) | |
LONG_S $15, PT_R15(sp) | |
LONG_S $24, PT_R24(sp) | |
#if __mips_isa_rev < 6 | |
LONG_S v1, PT_LO(sp) | |
#endif | |
.endm | |
.macro SAVE_STATIC | |
LONG_S $16, PT_R16(sp) | |
LONG_S $17, PT_R17(sp) | |
LONG_S $18, PT_R18(sp) | |
LONG_S $19, PT_R19(sp) | |
LONG_S $20, PT_R20(sp) | |
LONG_S $21, PT_R21(sp) | |
LONG_S $22, PT_R22(sp) | |
LONG_S $23, PT_R23(sp) | |
LONG_S $30, PT_R30(sp) | |
.endm | |
.macro SAVE_SOME | |
.set push | |
.set noat | |
PTR_SUBU k1, sp, PT_SIZE | |
LONG_S sp, PT_R29(k1) | |
move sp, k1 | |
LONG_S $3, PT_R3(sp) | |
LONG_S $0, PT_R0(sp) | |
mfc0 v1, CP0_STATUS | |
LONG_S $2, PT_R2(sp) | |
LONG_S v1, PT_STATUS(sp) | |
LONG_S $4, PT_R4(sp) | |
mfc0 v1, CP0_CAUSE | |
LONG_S $5, PT_R5(sp) | |
LONG_S v1, PT_CAUSE(sp) | |
LONG_S $6, PT_R6(sp) | |
MFC0 v1, CP0_EPC | |
LONG_S $7, PT_R7(sp) | |
#ifdef CONFIG_64BIT | |
LONG_S $8, PT_R8(sp) | |
LONG_S $9, PT_R9(sp) | |
#endif | |
LONG_S v1, PT_EPC(sp) | |
LONG_S $25, PT_R25(sp) | |
LONG_S $28, PT_R28(sp) | |
LONG_S $31, PT_R31(sp) | |
.set pop | |
.endm | |
.macro RESTORE_AT | |
.set push | |
.set noat | |
LONG_L $1, PT_R1(sp) | |
.set pop | |
.endm | |
.macro RESTORE_TEMP | |
#if __mips_isa_rev < 6 | |
LONG_L $24, PT_LO(sp) | |
mtlo $24 | |
LONG_L $24, PT_HI(sp) | |
mthi $24 | |
#endif | |
#ifdef CONFIG_32BIT | |
LONG_L $8, PT_R8(sp) | |
LONG_L $9, PT_R9(sp) | |
#endif | |
LONG_L $10, PT_R10(sp) | |
LONG_L $11, PT_R11(sp) | |
LONG_L $12, PT_R12(sp) | |
LONG_L $13, PT_R13(sp) | |
LONG_L $14, PT_R14(sp) | |
LONG_L $15, PT_R15(sp) | |
LONG_L $24, PT_R24(sp) | |
.endm | |
.macro RESTORE_STATIC | |
LONG_L $16, PT_R16(sp) | |
LONG_L $17, PT_R17(sp) | |
LONG_L $18, PT_R18(sp) | |
LONG_L $19, PT_R19(sp) | |
LONG_L $20, PT_R20(sp) | |
LONG_L $21, PT_R21(sp) | |
LONG_L $22, PT_R22(sp) | |
LONG_L $23, PT_R23(sp) | |
LONG_L $30, PT_R30(sp) | |
.endm | |
.macro RESTORE_SOME | |
.set push | |
.set reorder | |
.set noat | |
mfc0 a0, CP0_STATUS | |
ori a0, STATMASK | |
xori a0, STATMASK | |
mtc0 a0, CP0_STATUS | |
li v1, ST0_CU1 | ST0_FR | ST0_IM | |
and a0, v1 | |
LONG_L v0, PT_STATUS(sp) | |
nor v1, $0, v1 | |
and v0, v1 | |
or v0, a0 | |
mtc0 v0, CP0_STATUS | |
LONG_L v1, PT_EPC(sp) | |
MTC0 v1, CP0_EPC | |
LONG_L $31, PT_R31(sp) | |
LONG_L $28, PT_R28(sp) | |
LONG_L $25, PT_R25(sp) | |
#ifdef CONFIG_64BIT | |
LONG_L $8, PT_R8(sp) | |
LONG_L $9, PT_R9(sp) | |
#endif | |
LONG_L $7, PT_R7(sp) | |
LONG_L $6, PT_R6(sp) | |
LONG_L $5, PT_R5(sp) | |
LONG_L $4, PT_R4(sp) | |
LONG_L $3, PT_R3(sp) | |
LONG_L $2, PT_R2(sp) | |
.set pop | |
.endm | |
.macro RESTORE_SP | |
LONG_L sp, PT_R29(sp) | |
.endm | |
NESTED(except_vec3_generic, 0, sp) | |
PTR_LA k1, handle_reserved | |
jr k1 | |
nop | |
END(except_vec3_generic) | |
NESTED(except_vec_ejtag_debug, 0, sp) | |
PTR_LA k1, handle_ejtag_debug | |
jr k1 | |
nop | |
END(except_vec_ejtag_debug) | |
NESTED(handle_reserved, PT_SIZE, sp) | |
SAVE_SOME | |
SAVE_AT | |
SAVE_TEMP | |
SAVE_STATIC | |
PTR_LA t9, do_reserved | |
jr t9 | |
move a0, sp | |
END(handle_reserved) | |
NESTED(handle_ejtag_debug, PT_SIZE, sp) | |
.set push | |
.set noat | |
MTC0 k1, CP0_DESAVE | |
/* Check for SDBBP */ | |
MFC0 k1, CP0_DEBUG | |
sll k1, k1, 30 | |
bgez k1, ejtag_return | |
nop | |
SAVE_SOME | |
SAVE_AT | |
SAVE_TEMP | |
SAVE_STATIC | |
PTR_LA t9, do_ejtag_debug | |
jalr t9 | |
move a0, sp | |
RESTORE_TEMP | |
RESTORE_STATIC | |
RESTORE_AT | |
RESTORE_SOME | |
RESTORE_SP | |
ejtag_return: | |
MFC0 k1, CP0_DESAVE | |
deret | |
.set pop | |
END(handle_ejtag_debug) |