MIPS: bugfix: missed cache flush of TLB refill handler
[cascardo/linux.git] / arch / mips / include / asm / asmmacro.h
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2003 Ralf Baechle
7  */
8 #ifndef _ASM_ASMMACRO_H
9 #define _ASM_ASMMACRO_H
10
11 #include <asm/hazards.h>
12 #include <asm/asm-offsets.h>
13
14 #ifdef CONFIG_32BIT
15 #include <asm/asmmacro-32.h>
16 #endif
17 #ifdef CONFIG_64BIT
18 #include <asm/asmmacro-64.h>
19 #endif
20
21 #ifdef CONFIG_CPU_MIPSR2
22         .macro  local_irq_enable reg=t0
23         ei
24         irq_enable_hazard
25         .endm
26
27         .macro  local_irq_disable reg=t0
28         di
29         irq_disable_hazard
30         .endm
31 #else
32         .macro  local_irq_enable reg=t0
33         mfc0    \reg, CP0_STATUS
34         ori     \reg, \reg, 1
35         mtc0    \reg, CP0_STATUS
36         irq_enable_hazard
37         .endm
38
39         .macro  local_irq_disable reg=t0
40 #ifdef CONFIG_PREEMPT
41         lw      \reg, TI_PRE_COUNT($28)
42         addi    \reg, \reg, 1
43         sw      \reg, TI_PRE_COUNT($28)
44 #endif
45         mfc0    \reg, CP0_STATUS
46         ori     \reg, \reg, 1
47         xori    \reg, \reg, 1
48         mtc0    \reg, CP0_STATUS
49         irq_disable_hazard
50 #ifdef CONFIG_PREEMPT
51         lw      \reg, TI_PRE_COUNT($28)
52         addi    \reg, \reg, -1
53         sw      \reg, TI_PRE_COUNT($28)
54 #endif
55         .endm
56 #endif /* CONFIG_CPU_MIPSR2 */
57
58         .macro  fpu_save_16even thread tmp=t0
59         cfc1    \tmp, fcr31
60         sdc1    $f0,  THREAD_FPR0_LS64(\thread)
61         sdc1    $f2,  THREAD_FPR2_LS64(\thread)
62         sdc1    $f4,  THREAD_FPR4_LS64(\thread)
63         sdc1    $f6,  THREAD_FPR6_LS64(\thread)
64         sdc1    $f8,  THREAD_FPR8_LS64(\thread)
65         sdc1    $f10, THREAD_FPR10_LS64(\thread)
66         sdc1    $f12, THREAD_FPR12_LS64(\thread)
67         sdc1    $f14, THREAD_FPR14_LS64(\thread)
68         sdc1    $f16, THREAD_FPR16_LS64(\thread)
69         sdc1    $f18, THREAD_FPR18_LS64(\thread)
70         sdc1    $f20, THREAD_FPR20_LS64(\thread)
71         sdc1    $f22, THREAD_FPR22_LS64(\thread)
72         sdc1    $f24, THREAD_FPR24_LS64(\thread)
73         sdc1    $f26, THREAD_FPR26_LS64(\thread)
74         sdc1    $f28, THREAD_FPR28_LS64(\thread)
75         sdc1    $f30, THREAD_FPR30_LS64(\thread)
76         sw      \tmp, THREAD_FCR31(\thread)
77         .endm
78
79         .macro  fpu_save_16odd thread
80         .set    push
81         .set    mips64r2
82         sdc1    $f1,  THREAD_FPR1_LS64(\thread)
83         sdc1    $f3,  THREAD_FPR3_LS64(\thread)
84         sdc1    $f5,  THREAD_FPR5_LS64(\thread)
85         sdc1    $f7,  THREAD_FPR7_LS64(\thread)
86         sdc1    $f9,  THREAD_FPR9_LS64(\thread)
87         sdc1    $f11, THREAD_FPR11_LS64(\thread)
88         sdc1    $f13, THREAD_FPR13_LS64(\thread)
89         sdc1    $f15, THREAD_FPR15_LS64(\thread)
90         sdc1    $f17, THREAD_FPR17_LS64(\thread)
91         sdc1    $f19, THREAD_FPR19_LS64(\thread)
92         sdc1    $f21, THREAD_FPR21_LS64(\thread)
93         sdc1    $f23, THREAD_FPR23_LS64(\thread)
94         sdc1    $f25, THREAD_FPR25_LS64(\thread)
95         sdc1    $f27, THREAD_FPR27_LS64(\thread)
96         sdc1    $f29, THREAD_FPR29_LS64(\thread)
97         sdc1    $f31, THREAD_FPR31_LS64(\thread)
98         .set    pop
99         .endm
100
101         .macro  fpu_save_double thread status tmp
102 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
103         sll     \tmp, \status, 5
104         bgez    \tmp, 10f
105         fpu_save_16odd \thread
106 10:
107 #endif
108         fpu_save_16even \thread \tmp
109         .endm
110
111         .macro  fpu_restore_16even thread tmp=t0
112         lw      \tmp, THREAD_FCR31(\thread)
113         ldc1    $f0,  THREAD_FPR0_LS64(\thread)
114         ldc1    $f2,  THREAD_FPR2_LS64(\thread)
115         ldc1    $f4,  THREAD_FPR4_LS64(\thread)
116         ldc1    $f6,  THREAD_FPR6_LS64(\thread)
117         ldc1    $f8,  THREAD_FPR8_LS64(\thread)
118         ldc1    $f10, THREAD_FPR10_LS64(\thread)
119         ldc1    $f12, THREAD_FPR12_LS64(\thread)
120         ldc1    $f14, THREAD_FPR14_LS64(\thread)
121         ldc1    $f16, THREAD_FPR16_LS64(\thread)
122         ldc1    $f18, THREAD_FPR18_LS64(\thread)
123         ldc1    $f20, THREAD_FPR20_LS64(\thread)
124         ldc1    $f22, THREAD_FPR22_LS64(\thread)
125         ldc1    $f24, THREAD_FPR24_LS64(\thread)
126         ldc1    $f26, THREAD_FPR26_LS64(\thread)
127         ldc1    $f28, THREAD_FPR28_LS64(\thread)
128         ldc1    $f30, THREAD_FPR30_LS64(\thread)
129         ctc1    \tmp, fcr31
130         .endm
131
132         .macro  fpu_restore_16odd thread
133         .set    push
134         .set    mips64r2
135         ldc1    $f1,  THREAD_FPR1_LS64(\thread)
136         ldc1    $f3,  THREAD_FPR3_LS64(\thread)
137         ldc1    $f5,  THREAD_FPR5_LS64(\thread)
138         ldc1    $f7,  THREAD_FPR7_LS64(\thread)
139         ldc1    $f9,  THREAD_FPR9_LS64(\thread)
140         ldc1    $f11, THREAD_FPR11_LS64(\thread)
141         ldc1    $f13, THREAD_FPR13_LS64(\thread)
142         ldc1    $f15, THREAD_FPR15_LS64(\thread)
143         ldc1    $f17, THREAD_FPR17_LS64(\thread)
144         ldc1    $f19, THREAD_FPR19_LS64(\thread)
145         ldc1    $f21, THREAD_FPR21_LS64(\thread)
146         ldc1    $f23, THREAD_FPR23_LS64(\thread)
147         ldc1    $f25, THREAD_FPR25_LS64(\thread)
148         ldc1    $f27, THREAD_FPR27_LS64(\thread)
149         ldc1    $f29, THREAD_FPR29_LS64(\thread)
150         ldc1    $f31, THREAD_FPR31_LS64(\thread)
151         .set    pop
152         .endm
153
154         .macro  fpu_restore_double thread status tmp
155 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
156         sll     \tmp, \status, 5
157         bgez    \tmp, 10f                               # 16 register mode?
158
159         fpu_restore_16odd \thread
160 10:
161 #endif
162         fpu_restore_16even \thread \tmp
163         .endm
164
165 #ifdef CONFIG_CPU_MIPSR2
166         .macro  _EXT    rd, rs, p, s
167         ext     \rd, \rs, \p, \s
168         .endm
169 #else /* !CONFIG_CPU_MIPSR2 */
170         .macro  _EXT    rd, rs, p, s
171         srl     \rd, \rs, \p
172         andi    \rd, \rd, (1 << \s) - 1
173         .endm
174 #endif /* !CONFIG_CPU_MIPSR2 */
175
176 /*
177  * Temporary until all gas have MT ASE support
178  */
179         .macro  DMT     reg=0
180         .word   0x41600bc1 | (\reg << 16)
181         .endm
182
183         .macro  EMT     reg=0
184         .word   0x41600be1 | (\reg << 16)
185         .endm
186
187         .macro  DVPE    reg=0
188         .word   0x41600001 | (\reg << 16)
189         .endm
190
191         .macro  EVPE    reg=0
192         .word   0x41600021 | (\reg << 16)
193         .endm
194
195         .macro  MFTR    rt=0, rd=0, u=0, sel=0
196          .word  0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
197         .endm
198
199         .macro  MTTR    rt=0, rd=0, u=0, sel=0
200          .word  0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
201         .endm
202
203 #ifdef TOOLCHAIN_SUPPORTS_MSA
204         .macro  ld_d    wd, off, base
205         .set    push
206         .set    mips32r2
207         .set    msa
208         ld.d    $w\wd, \off(\base)
209         .set    pop
210         .endm
211
212         .macro  st_d    wd, off, base
213         .set    push
214         .set    mips32r2
215         .set    msa
216         st.d    $w\wd, \off(\base)
217         .set    pop
218         .endm
219
220         .macro  copy_u_w        rd, ws, n
221         .set    push
222         .set    mips32r2
223         .set    msa
224         copy_u.w \rd, $w\ws[\n]
225         .set    pop
226         .endm
227
228         .macro  copy_u_d        rd, ws, n
229         .set    push
230         .set    mips64r2
231         .set    msa
232         copy_u.d \rd, $w\ws[\n]
233         .set    pop
234         .endm
235
236         .macro  insert_w        wd, n, rs
237         .set    push
238         .set    mips32r2
239         .set    msa
240         insert.w $w\wd[\n], \rs
241         .set    pop
242         .endm
243
244         .macro  insert_d        wd, n, rs
245         .set    push
246         .set    mips64r2
247         .set    msa
248         insert.d $w\wd[\n], \rs
249         .set    pop
250         .endm
251 #else
252
253 #ifdef CONFIG_CPU_MICROMIPS
254 #define CFC_MSA_INSN            0x587e0056
255 #define CTC_MSA_INSN            0x583e0816
256 #define LDD_MSA_INSN            0x58000837
257 #define STD_MSA_INSN            0x5800083f
258 #define COPY_UW_MSA_INSN        0x58f00056
259 #define COPY_UD_MSA_INSN        0x58f80056
260 #define INSERT_W_MSA_INSN       0x59300816
261 #define INSERT_D_MSA_INSN       0x59380816
262 #else
263 #define CFC_MSA_INSN            0x787e0059
264 #define CTC_MSA_INSN            0x783e0819
265 #define LDD_MSA_INSN            0x78000823
266 #define STD_MSA_INSN            0x78000827
267 #define COPY_UW_MSA_INSN        0x78f00059
268 #define COPY_UD_MSA_INSN        0x78f80059
269 #define INSERT_W_MSA_INSN       0x79300819
270 #define INSERT_D_MSA_INSN       0x79380819
271 #endif
272
273         /*
274          * Temporary until all toolchains in use include MSA support.
275          */
276         .macro  cfcmsa  rd, cs
277         .set    push
278         .set    noat
279         .insn
280         .word   CFC_MSA_INSN | (\cs << 11)
281         move    \rd, $1
282         .set    pop
283         .endm
284
285         .macro  ctcmsa  cd, rs
286         .set    push
287         .set    noat
288         move    $1, \rs
289         .word   CTC_MSA_INSN | (\cd << 6)
290         .set    pop
291         .endm
292
293         .macro  ld_d    wd, off, base
294         .set    push
295         .set    noat
296         add     $1, \base, \off
297         .word   LDD_MSA_INSN | (\wd << 6)
298         .set    pop
299         .endm
300
301         .macro  st_d    wd, off, base
302         .set    push
303         .set    noat
304         add     $1, \base, \off
305         .word   STD_MSA_INSN | (\wd << 6)
306         .set    pop
307         .endm
308
309         .macro  copy_u_w        rd, ws, n
310         .set    push
311         .set    noat
312         .insn
313         .word   COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
314         /* move triggers an assembler bug... */
315         or      \rd, $1, zero
316         .set    pop
317         .endm
318
319         .macro  copy_u_d        rd, ws, n
320         .set    push
321         .set    noat
322         .insn
323         .word   COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
324         /* move triggers an assembler bug... */
325         or      \rd, $1, zero
326         .set    pop
327         .endm
328
329         .macro  insert_w        wd, n, rs
330         .set    push
331         .set    noat
332         /* move triggers an assembler bug... */
333         or      $1, \rs, zero
334         .word   INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
335         .set    pop
336         .endm
337
338         .macro  insert_d        wd, n, rs
339         .set    push
340         .set    noat
341         /* move triggers an assembler bug... */
342         or      $1, \rs, zero
343         .word   INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
344         .set    pop
345         .endm
346 #endif
347
348         .macro  msa_save_all    thread
349         st_d    0, THREAD_FPR0, \thread
350         st_d    1, THREAD_FPR1, \thread
351         st_d    2, THREAD_FPR2, \thread
352         st_d    3, THREAD_FPR3, \thread
353         st_d    4, THREAD_FPR4, \thread
354         st_d    5, THREAD_FPR5, \thread
355         st_d    6, THREAD_FPR6, \thread
356         st_d    7, THREAD_FPR7, \thread
357         st_d    8, THREAD_FPR8, \thread
358         st_d    9, THREAD_FPR9, \thread
359         st_d    10, THREAD_FPR10, \thread
360         st_d    11, THREAD_FPR11, \thread
361         st_d    12, THREAD_FPR12, \thread
362         st_d    13, THREAD_FPR13, \thread
363         st_d    14, THREAD_FPR14, \thread
364         st_d    15, THREAD_FPR15, \thread
365         st_d    16, THREAD_FPR16, \thread
366         st_d    17, THREAD_FPR17, \thread
367         st_d    18, THREAD_FPR18, \thread
368         st_d    19, THREAD_FPR19, \thread
369         st_d    20, THREAD_FPR20, \thread
370         st_d    21, THREAD_FPR21, \thread
371         st_d    22, THREAD_FPR22, \thread
372         st_d    23, THREAD_FPR23, \thread
373         st_d    24, THREAD_FPR24, \thread
374         st_d    25, THREAD_FPR25, \thread
375         st_d    26, THREAD_FPR26, \thread
376         st_d    27, THREAD_FPR27, \thread
377         st_d    28, THREAD_FPR28, \thread
378         st_d    29, THREAD_FPR29, \thread
379         st_d    30, THREAD_FPR30, \thread
380         st_d    31, THREAD_FPR31, \thread
381         .endm
382
383         .macro  msa_restore_all thread
384         ld_d    0, THREAD_FPR0, \thread
385         ld_d    1, THREAD_FPR1, \thread
386         ld_d    2, THREAD_FPR2, \thread
387         ld_d    3, THREAD_FPR3, \thread
388         ld_d    4, THREAD_FPR4, \thread
389         ld_d    5, THREAD_FPR5, \thread
390         ld_d    6, THREAD_FPR6, \thread
391         ld_d    7, THREAD_FPR7, \thread
392         ld_d    8, THREAD_FPR8, \thread
393         ld_d    9, THREAD_FPR9, \thread
394         ld_d    10, THREAD_FPR10, \thread
395         ld_d    11, THREAD_FPR11, \thread
396         ld_d    12, THREAD_FPR12, \thread
397         ld_d    13, THREAD_FPR13, \thread
398         ld_d    14, THREAD_FPR14, \thread
399         ld_d    15, THREAD_FPR15, \thread
400         ld_d    16, THREAD_FPR16, \thread
401         ld_d    17, THREAD_FPR17, \thread
402         ld_d    18, THREAD_FPR18, \thread
403         ld_d    19, THREAD_FPR19, \thread
404         ld_d    20, THREAD_FPR20, \thread
405         ld_d    21, THREAD_FPR21, \thread
406         ld_d    22, THREAD_FPR22, \thread
407         ld_d    23, THREAD_FPR23, \thread
408         ld_d    24, THREAD_FPR24, \thread
409         ld_d    25, THREAD_FPR25, \thread
410         ld_d    26, THREAD_FPR26, \thread
411         ld_d    27, THREAD_FPR27, \thread
412         ld_d    28, THREAD_FPR28, \thread
413         ld_d    29, THREAD_FPR29, \thread
414         ld_d    30, THREAD_FPR30, \thread
415         ld_d    31, THREAD_FPR31, \thread
416         .endm
417
418 #endif /* _ASM_ASMMACRO_H */