2d6d7b0c18ec3d35802180cd07dc4625fda56ae9
[platform/kernel/u-boot.git] / arch / mips / lib / genex.S
1 /*
2  * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
3  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
4  * Copyright (C) 2002, 2007  Maciej W. Rozycki
5  * Copyright (C) 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <asm/asm.h>
11 #include <asm/regdef.h>
12 #include <asm/mipsregs.h>
13 #include <asm/asm-offsets.h>
14
15 #define STATMASK 0x1f
16
17         .set    noreorder
18
19         /*
20          * Macros copied and adapted from Linux MIPS
21          */
22         .macro  SAVE_AT
23         .set    push
24         .set    noat
25         LONG_S  $1, PT_R1(sp)
26         .set    pop
27         .endm
28
29         .macro  SAVE_TEMP
30 #if __mips_isa_rev < 6
31         mfhi    v1
32 #endif
33 #ifdef CONFIG_32BIT
34         LONG_S  $8, PT_R8(sp)
35         LONG_S  $9, PT_R9(sp)
36 #endif
37         LONG_S  $10, PT_R10(sp)
38         LONG_S  $11, PT_R11(sp)
39         LONG_S  $12, PT_R12(sp)
40 #if __mips_isa_rev < 6
41         LONG_S  v1, PT_HI(sp)
42         mflo    v1
43 #endif
44         LONG_S  $13, PT_R13(sp)
45         LONG_S  $14, PT_R14(sp)
46         LONG_S  $15, PT_R15(sp)
47         LONG_S  $24, PT_R24(sp)
48 #if __mips_isa_rev < 6
49         LONG_S  v1, PT_LO(sp)
50 #endif
51         .endm
52
53         .macro  SAVE_STATIC
54         LONG_S  $16, PT_R16(sp)
55         LONG_S  $17, PT_R17(sp)
56         LONG_S  $18, PT_R18(sp)
57         LONG_S  $19, PT_R19(sp)
58         LONG_S  $20, PT_R20(sp)
59         LONG_S  $21, PT_R21(sp)
60         LONG_S  $22, PT_R22(sp)
61         LONG_S  $23, PT_R23(sp)
62         LONG_S  $30, PT_R30(sp)
63         .endm
64
65         .macro  SAVE_SOME
66         .set    push
67         .set    noat
68         PTR_SUBU k1, sp, PT_SIZE
69         LONG_S  sp, PT_R29(k1)
70         move    sp, k1
71
72         LONG_S  $3, PT_R3(sp)
73         LONG_S  $0, PT_R0(sp)
74         mfc0    v1, CP0_STATUS
75         LONG_S  $2, PT_R2(sp)
76         LONG_S  v1, PT_STATUS(sp)
77         LONG_S  $4, PT_R4(sp)
78         mfc0    v1, CP0_CAUSE
79         LONG_S  $5, PT_R5(sp)
80         LONG_S  v1, PT_CAUSE(sp)
81         LONG_S  $6, PT_R6(sp)
82         MFC0    v1, CP0_EPC
83         LONG_S  $7, PT_R7(sp)
84 #ifdef CONFIG_64BIT
85         LONG_S  $8, PT_R8(sp)
86         LONG_S  $9, PT_R9(sp)
87 #endif
88         LONG_S  v1, PT_EPC(sp)
89         LONG_S  $25, PT_R25(sp)
90         LONG_S  $28, PT_R28(sp)
91         LONG_S  $31, PT_R31(sp)
92         .set    pop
93         .endm
94
95         .macro  RESTORE_AT
96         .set    push
97         .set    noat
98         LONG_L  $1,  PT_R1(sp)
99         .set    pop
100         .endm
101
102         .macro  RESTORE_TEMP
103 #if __mips_isa_rev < 6
104         LONG_L  $24, PT_LO(sp)
105         mtlo    $24
106         LONG_L  $24, PT_HI(sp)
107         mthi    $24
108 #endif
109 #ifdef CONFIG_32BIT
110         LONG_L  $8, PT_R8(sp)
111         LONG_L  $9, PT_R9(sp)
112 #endif
113         LONG_L  $10, PT_R10(sp)
114         LONG_L  $11, PT_R11(sp)
115         LONG_L  $12, PT_R12(sp)
116         LONG_L  $13, PT_R13(sp)
117         LONG_L  $14, PT_R14(sp)
118         LONG_L  $15, PT_R15(sp)
119         LONG_L  $24, PT_R24(sp)
120         .endm
121
122         .macro  RESTORE_STATIC
123         LONG_L  $16, PT_R16(sp)
124         LONG_L  $17, PT_R17(sp)
125         LONG_L  $18, PT_R18(sp)
126         LONG_L  $19, PT_R19(sp)
127         LONG_L  $20, PT_R20(sp)
128         LONG_L  $21, PT_R21(sp)
129         LONG_L  $22, PT_R22(sp)
130         LONG_L  $23, PT_R23(sp)
131         LONG_L  $30, PT_R30(sp)
132         .endm
133
134         .macro  RESTORE_SOME
135         .set    push
136         .set    reorder
137         .set    noat
138         mfc0    a0, CP0_STATUS
139         ori     a0, STATMASK
140         xori    a0, STATMASK
141         mtc0    a0, CP0_STATUS
142         li      v1, ST0_CU1 | ST0_FR | ST0_IM
143         and     a0, v1
144         LONG_L  v0, PT_STATUS(sp)
145         nor     v1, $0, v1
146         and     v0, v1
147         or      v0, a0
148         mtc0    v0, CP0_STATUS
149         LONG_L  v1, PT_EPC(sp)
150         MTC0    v1, CP0_EPC
151         LONG_L  $31, PT_R31(sp)
152         LONG_L  $28, PT_R28(sp)
153         LONG_L  $25, PT_R25(sp)
154 #ifdef CONFIG_64BIT
155         LONG_L  $8, PT_R8(sp)
156         LONG_L  $9, PT_R9(sp)
157 #endif
158         LONG_L  $7,  PT_R7(sp)
159         LONG_L  $6,  PT_R6(sp)
160         LONG_L  $5,  PT_R5(sp)
161         LONG_L  $4,  PT_R4(sp)
162         LONG_L  $3,  PT_R3(sp)
163         LONG_L  $2,  PT_R2(sp)
164         .set    pop
165         .endm
166
167         .macro  RESTORE_SP
168         LONG_L  sp, PT_R29(sp)
169         .endm
170
171 NESTED(except_vec3_generic, 0, sp)
172         PTR_LA  k1, handle_reserved
173         jr      k1
174          nop
175         END(except_vec3_generic)
176
177 NESTED(except_vec_ejtag_debug, 0, sp)
178         PTR_LA  k1, handle_ejtag_debug
179         jr      k1
180          nop
181         END(except_vec_ejtag_debug)
182
183 NESTED(handle_reserved, PT_SIZE, sp)
184         SAVE_SOME
185         SAVE_AT
186         SAVE_TEMP
187         SAVE_STATIC
188
189         PTR_LA  t9, do_reserved
190         jr      t9
191          move   a0, sp
192         END(handle_reserved)
193
194 NESTED(handle_ejtag_debug, PT_SIZE, sp)
195         .set    push
196         .set    noat
197         MTC0    k1, CP0_DESAVE
198
199         /* Check for SDBBP */
200         MFC0    k1, CP0_DEBUG
201         sll     k1, k1, 30
202         bgez    k1, ejtag_return
203          nop
204
205         SAVE_SOME
206         SAVE_AT
207         SAVE_TEMP
208         SAVE_STATIC
209
210         PTR_LA  t9, do_ejtag_debug
211         jalr    t9
212          move   a0, sp
213
214         RESTORE_TEMP
215         RESTORE_STATIC
216         RESTORE_AT
217         RESTORE_SOME
218         RESTORE_SP
219
220 ejtag_return:
221         MFC0    k1, CP0_DESAVE
222         deret
223         .set pop
224         END(handle_ejtag_debug)