diff options
author | Paul Burton <paul.burton@imgtec.com> | 2014-01-27 10:23:09 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-03-26 18:09:10 -0400 |
commit | 7f65afb97f279d9d02d0779384e8bd5ace064dea (patch) | |
tree | dc478d16bb3d470e5dcd4b167c969656ac7a874e | |
parent | 02987633df7ba2f62967791dda816eb191d1add3 (diff) |
MIPS: Add MSA register definitions & access
This patch introduces definitions for the MSA control registers and
functions which allow access to both the control & vector registers. If
the toolchain being used to build the kernel includes support for MSA
then this patch will make use of that support & use MSA instructions
directly. However toolchain support for MSA is very new & far from a
point where it can be reasonably expected that everyone building the
kernel uses a toolchain with support. Thus fallbacks using .word
assembler directives are also provided for now as a temporary measure.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6429/
Patchwork: https://patchwork.linux-mips.org/patch/6607/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/include/asm/asmmacro.h | 121 | ||||
-rw-r--r-- | arch/mips/include/asm/mipsregs.h | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/msa.h | 175 |
4 files changed, 302 insertions, 0 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9b8556de9993..1a5b4032cb66 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -119,6 +119,11 @@ cflags-$(CONFIG_CPU_MICROMIPS) += $(call cc-option,-mmicromips) | |||
119 | cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ | 119 | cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ |
120 | -fno-omit-frame-pointer | 120 | -fno-omit-frame-pointer |
121 | 121 | ||
122 | ifeq ($(CONFIG_CPU_HAS_MSA),y) | ||
123 | toolchain-msa := $(call cc-option-yn,-mhard-float -mfp64 -mmsa) | ||
124 | cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA | ||
125 | endif | ||
126 | |||
122 | # | 127 | # |
123 | # CPU-dependent compiler/assembler options for optimization. | 128 | # CPU-dependent compiler/assembler options for optimization. |
124 | # | 129 | # |
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 63cf43472814..f571db371b3e 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h | |||
@@ -207,4 +207,125 @@ | |||
207 | .word 0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel) | 207 | .word 0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel) |
208 | .endm | 208 | .endm |
209 | 209 | ||
210 | #ifdef TOOLCHAIN_SUPPORTS_MSA | ||
211 | .macro ld_d wd, off, base | ||
212 | .set push | ||
213 | .set mips32r2 | ||
214 | .set msa | ||
215 | ld.d $w\wd, \off(\base) | ||
216 | .set pop | ||
217 | .endm | ||
218 | |||
219 | .macro st_d wd, off, base | ||
220 | .set push | ||
221 | .set mips32r2 | ||
222 | .set msa | ||
223 | st.d $w\wd, \off(\base) | ||
224 | .set pop | ||
225 | .endm | ||
226 | |||
227 | .macro copy_u_w rd, ws, n | ||
228 | .set push | ||
229 | .set mips32r2 | ||
230 | .set msa | ||
231 | copy_u.w \rd, $w\ws[\n] | ||
232 | .set pop | ||
233 | .endm | ||
234 | |||
235 | .macro copy_u_d rd, ws, n | ||
236 | .set push | ||
237 | .set mips64r2 | ||
238 | .set msa | ||
239 | copy_u.d \rd, $w\ws[\n] | ||
240 | .set pop | ||
241 | .endm | ||
242 | |||
243 | .macro insert_w wd, n, rs | ||
244 | .set push | ||
245 | .set mips32r2 | ||
246 | .set msa | ||
247 | insert.w $w\wd[\n], \rs | ||
248 | .set pop | ||
249 | .endm | ||
250 | |||
251 | .macro insert_d wd, n, rs | ||
252 | .set push | ||
253 | .set mips64r2 | ||
254 | .set msa | ||
255 | insert.d $w\wd[\n], \rs | ||
256 | .set pop | ||
257 | .endm | ||
258 | #else | ||
259 | /* | ||
260 | * Temporary until all toolchains in use include MSA support. | ||
261 | */ | ||
262 | .macro cfcmsa rd, cs | ||
263 | .set push | ||
264 | .set noat | ||
265 | .word 0x787e0059 | (\cs << 11) | ||
266 | move \rd, $1 | ||
267 | .set pop | ||
268 | .endm | ||
269 | |||
270 | .macro ctcmsa cd, rs | ||
271 | .set push | ||
272 | .set noat | ||
273 | move $1, \rs | ||
274 | .word 0x783e0819 | (\cd << 6) | ||
275 | .set pop | ||
276 | .endm | ||
277 | |||
278 | .macro ld_d wd, off, base | ||
279 | .set push | ||
280 | .set noat | ||
281 | add $1, \base, \off | ||
282 | .word 0x78000823 | (\wd << 6) | ||
283 | .set pop | ||
284 | .endm | ||
285 | |||
286 | .macro st_d wd, off, base | ||
287 | .set push | ||
288 | .set noat | ||
289 | add $1, \base, \off | ||
290 | .word 0x78000827 | (\wd << 6) | ||
291 | .set pop | ||
292 | .endm | ||
293 | |||
294 | .macro copy_u_w rd, ws, n | ||
295 | .set push | ||
296 | .set noat | ||
297 | .word 0x78f00059 | (\n << 16) | (\ws << 11) | ||
298 | /* move triggers an assembler bug... */ | ||
299 | or \rd, $1, zero | ||
300 | .set pop | ||
301 | .endm | ||
302 | |||
303 | .macro copy_u_d rd, ws, n | ||
304 | .set push | ||
305 | .set noat | ||
306 | .word 0x78f80059 | (\n << 16) | (\ws << 11) | ||
307 | /* move triggers an assembler bug... */ | ||
308 | or \rd, $1, zero | ||
309 | .set pop | ||
310 | .endm | ||
311 | |||
312 | .macro insert_w wd, n, rs | ||
313 | .set push | ||
314 | .set noat | ||
315 | /* move triggers an assembler bug... */ | ||
316 | or $1, \rs, zero | ||
317 | .word 0x79300819 | (\n << 16) | (\wd << 6) | ||
318 | .set pop | ||
319 | .endm | ||
320 | |||
321 | .macro insert_d wd, n, rs | ||
322 | .set push | ||
323 | .set noat | ||
324 | /* move triggers an assembler bug... */ | ||
325 | or $1, \rs, zero | ||
326 | .word 0x79380819 | (\n << 16) | (\wd << 6) | ||
327 | .set pop | ||
328 | .endm | ||
329 | #endif | ||
330 | |||
210 | #endif /* _ASM_ASMMACRO_H */ | 331 | #endif /* _ASM_ASMMACRO_H */ |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index dde6a786307a..3e025b5311db 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -1904,6 +1904,7 @@ change_c0_##name(unsigned int change, unsigned int newbits) \ | |||
1904 | __BUILD_SET_C0(status) | 1904 | __BUILD_SET_C0(status) |
1905 | __BUILD_SET_C0(cause) | 1905 | __BUILD_SET_C0(cause) |
1906 | __BUILD_SET_C0(config) | 1906 | __BUILD_SET_C0(config) |
1907 | __BUILD_SET_C0(config5) | ||
1907 | __BUILD_SET_C0(intcontrol) | 1908 | __BUILD_SET_C0(intcontrol) |
1908 | __BUILD_SET_C0(intctl) | 1909 | __BUILD_SET_C0(intctl) |
1909 | __BUILD_SET_C0(srsmap) | 1910 | __BUILD_SET_C0(srsmap) |
diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h new file mode 100644 index 000000000000..0a614fb83348 --- /dev/null +++ b/arch/mips/include/asm/msa.h | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Imagination Technologies | ||
3 | * Author: Paul Burton <paul.burton@imgtec.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | */ | ||
10 | #ifndef _ASM_MSA_H | ||
11 | #define _ASM_MSA_H | ||
12 | |||
13 | #include <asm/mipsregs.h> | ||
14 | |||
15 | static inline void enable_msa(void) | ||
16 | { | ||
17 | if (cpu_has_msa) { | ||
18 | set_c0_config5(MIPS_CONF5_MSAEN); | ||
19 | enable_fpu_hazard(); | ||
20 | } | ||
21 | } | ||
22 | |||
23 | static inline void disable_msa(void) | ||
24 | { | ||
25 | if (cpu_has_msa) { | ||
26 | clear_c0_config5(MIPS_CONF5_MSAEN); | ||
27 | disable_fpu_hazard(); | ||
28 | } | ||
29 | } | ||
30 | |||
31 | static inline int is_msa_enabled(void) | ||
32 | { | ||
33 | if (!cpu_has_msa) | ||
34 | return 0; | ||
35 | |||
36 | return read_c0_config5() & MIPS_CONF5_MSAEN; | ||
37 | } | ||
38 | |||
39 | #ifdef TOOLCHAIN_SUPPORTS_MSA | ||
40 | |||
41 | #define __BUILD_MSA_CTL_REG(name, cs) \ | ||
42 | static inline unsigned int read_msa_##name(void) \ | ||
43 | { \ | ||
44 | unsigned int reg; \ | ||
45 | __asm__ __volatile__( \ | ||
46 | " .set push\n" \ | ||
47 | " .set msa\n" \ | ||
48 | " cfcmsa %0, $" #cs "\n" \ | ||
49 | " .set pop\n" \ | ||
50 | : "=r"(reg)); \ | ||
51 | return reg; \ | ||
52 | } \ | ||
53 | \ | ||
54 | static inline void write_msa_##name(unsigned int val) \ | ||
55 | { \ | ||
56 | __asm__ __volatile__( \ | ||
57 | " .set push\n" \ | ||
58 | " .set msa\n" \ | ||
59 | " cfcmsa $" #cs ", %0\n" \ | ||
60 | " .set pop\n" \ | ||
61 | : : "r"(val)); \ | ||
62 | } | ||
63 | |||
64 | #else /* !TOOLCHAIN_SUPPORTS_MSA */ | ||
65 | |||
66 | /* | ||
67 | * Define functions using .word for the c[ft]cmsa instructions in order to | ||
68 | * allow compilation with toolchains that do not support MSA. Once all | ||
69 | * toolchains in use support MSA these can be removed. | ||
70 | */ | ||
71 | |||
72 | #define __BUILD_MSA_CTL_REG(name, cs) \ | ||
73 | static inline unsigned int read_msa_##name(void) \ | ||
74 | { \ | ||
75 | unsigned int reg; \ | ||
76 | __asm__ __volatile__( \ | ||
77 | " .set push\n" \ | ||
78 | " .set noat\n" \ | ||
79 | " .word 0x787e0059 | (" #cs " << 11)\n" \ | ||
80 | " move %0, $1\n" \ | ||
81 | " .set pop\n" \ | ||
82 | : "=r"(reg)); \ | ||
83 | return reg; \ | ||
84 | } \ | ||
85 | \ | ||
86 | static inline void write_msa_##name(unsigned int val) \ | ||
87 | { \ | ||
88 | __asm__ __volatile__( \ | ||
89 | " .set push\n" \ | ||
90 | " .set noat\n" \ | ||
91 | " move $1, %0\n" \ | ||
92 | " .word 0x783e0819 | (" #cs " << 6)\n" \ | ||
93 | " .set pop\n" \ | ||
94 | : : "r"(val)); \ | ||
95 | } | ||
96 | |||
97 | #endif /* !TOOLCHAIN_SUPPORTS_MSA */ | ||
98 | |||
99 | #define MSA_IR 0 | ||
100 | #define MSA_CSR 1 | ||
101 | #define MSA_ACCESS 2 | ||
102 | #define MSA_SAVE 3 | ||
103 | #define MSA_MODIFY 4 | ||
104 | #define MSA_REQUEST 5 | ||
105 | #define MSA_MAP 6 | ||
106 | #define MSA_UNMAP 7 | ||
107 | |||
108 | __BUILD_MSA_CTL_REG(ir, 0) | ||
109 | __BUILD_MSA_CTL_REG(csr, 1) | ||
110 | __BUILD_MSA_CTL_REG(access, 2) | ||
111 | __BUILD_MSA_CTL_REG(save, 3) | ||
112 | __BUILD_MSA_CTL_REG(modify, 4) | ||
113 | __BUILD_MSA_CTL_REG(request, 5) | ||
114 | __BUILD_MSA_CTL_REG(map, 6) | ||
115 | __BUILD_MSA_CTL_REG(unmap, 7) | ||
116 | |||
117 | /* MSA Implementation Register (MSAIR) */ | ||
118 | #define MSA_IR_REVB 0 | ||
119 | #define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB) | ||
120 | #define MSA_IR_PROCB 8 | ||
121 | #define MSA_IR_PROCF (_ULCAST_(0xff) << MSA_IR_PROCB) | ||
122 | #define MSA_IR_WRPB 16 | ||
123 | #define MSA_IR_WRPF (_ULCAST_(0x1) << MSA_IR_WRPB) | ||
124 | |||
125 | /* MSA Control & Status Register (MSACSR) */ | ||
126 | #define MSA_CSR_RMB 0 | ||
127 | #define MSA_CSR_RMF (_ULCAST_(0x3) << MSA_CSR_RMB) | ||
128 | #define MSA_CSR_RM_NEAREST 0 | ||
129 | #define MSA_CSR_RM_TO_ZERO 1 | ||
130 | #define MSA_CSR_RM_TO_POS 2 | ||
131 | #define MSA_CSR_RM_TO_NEG 3 | ||
132 | #define MSA_CSR_FLAGSB 2 | ||
133 | #define MSA_CSR_FLAGSF (_ULCAST_(0x1f) << MSA_CSR_FLAGSB) | ||
134 | #define MSA_CSR_FLAGS_IB 2 | ||
135 | #define MSA_CSR_FLAGS_IF (_ULCAST_(0x1) << MSA_CSR_FLAGS_IB) | ||
136 | #define MSA_CSR_FLAGS_UB 3 | ||
137 | #define MSA_CSR_FLAGS_UF (_ULCAST_(0x1) << MSA_CSR_FLAGS_UB) | ||
138 | #define MSA_CSR_FLAGS_OB 4 | ||
139 | #define MSA_CSR_FLAGS_OF (_ULCAST_(0x1) << MSA_CSR_FLAGS_OB) | ||
140 | #define MSA_CSR_FLAGS_ZB 5 | ||
141 | #define MSA_CSR_FLAGS_ZF (_ULCAST_(0x1) << MSA_CSR_FLAGS_ZB) | ||
142 | #define MSA_CSR_FLAGS_VB 6 | ||
143 | #define MSA_CSR_FLAGS_VF (_ULCAST_(0x1) << MSA_CSR_FLAGS_VB) | ||
144 | #define MSA_CSR_ENABLESB 7 | ||
145 | #define MSA_CSR_ENABLESF (_ULCAST_(0x1f) << MSA_CSR_ENABLESB) | ||
146 | #define MSA_CSR_ENABLES_IB 7 | ||
147 | #define MSA_CSR_ENABLES_IF (_ULCAST_(0x1) << MSA_CSR_ENABLES_IB) | ||
148 | #define MSA_CSR_ENABLES_UB 8 | ||
149 | #define MSA_CSR_ENABLES_UF (_ULCAST_(0x1) << MSA_CSR_ENABLES_UB) | ||
150 | #define MSA_CSR_ENABLES_OB 9 | ||
151 | #define MSA_CSR_ENABLES_OF (_ULCAST_(0x1) << MSA_CSR_ENABLES_OB) | ||
152 | #define MSA_CSR_ENABLES_ZB 10 | ||
153 | #define MSA_CSR_ENABLES_ZF (_ULCAST_(0x1) << MSA_CSR_ENABLES_ZB) | ||
154 | #define MSA_CSR_ENABLES_VB 11 | ||
155 | #define MSA_CSR_ENABLES_VF (_ULCAST_(0x1) << MSA_CSR_ENABLES_VB) | ||
156 | #define MSA_CSR_CAUSEB 12 | ||
157 | #define MSA_CSR_CAUSEF (_ULCAST_(0x3f) << MSA_CSR_CAUSEB) | ||
158 | #define MSA_CSR_CAUSE_IB 12 | ||
159 | #define MSA_CSR_CAUSE_IF (_ULCAST_(0x1) << MSA_CSR_CAUSE_IB) | ||
160 | #define MSA_CSR_CAUSE_UB 13 | ||
161 | #define MSA_CSR_CAUSE_UF (_ULCAST_(0x1) << MSA_CSR_CAUSE_UB) | ||
162 | #define MSA_CSR_CAUSE_OB 14 | ||
163 | #define MSA_CSR_CAUSE_OF (_ULCAST_(0x1) << MSA_CSR_CAUSE_OB) | ||
164 | #define MSA_CSR_CAUSE_ZB 15 | ||
165 | #define MSA_CSR_CAUSE_ZF (_ULCAST_(0x1) << MSA_CSR_CAUSE_ZB) | ||
166 | #define MSA_CSR_CAUSE_VB 16 | ||
167 | #define MSA_CSR_CAUSE_VF (_ULCAST_(0x1) << MSA_CSR_CAUSE_VB) | ||
168 | #define MSA_CSR_CAUSE_EB 17 | ||
169 | #define MSA_CSR_CAUSE_EF (_ULCAST_(0x1) << MSA_CSR_CAUSE_EB) | ||
170 | #define MSA_CSR_NXB 18 | ||
171 | #define MSA_CSR_NXF (_ULCAST_(0x1) << MSA_CSR_NXB) | ||
172 | #define MSA_CSR_FSB 24 | ||
173 | #define MSA_CSR_FSF (_ULCAST_(0x1) << MSA_CSR_FSB) | ||
174 | |||
175 | #endif /* _ASM_MSA_H */ | ||