Commit | Line | Data |
---|---|---|
7f65afb9 PB |
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 | ||
1db1af84 PB |
15 | extern void _save_msa(struct task_struct *); |
16 | extern void _restore_msa(struct task_struct *); | |
17 | ||
7f65afb9 PB |
18 | static inline void enable_msa(void) |
19 | { | |
20 | if (cpu_has_msa) { | |
21 | set_c0_config5(MIPS_CONF5_MSAEN); | |
22 | enable_fpu_hazard(); | |
23 | } | |
24 | } | |
25 | ||
26 | static inline void disable_msa(void) | |
27 | { | |
28 | if (cpu_has_msa) { | |
29 | clear_c0_config5(MIPS_CONF5_MSAEN); | |
30 | disable_fpu_hazard(); | |
31 | } | |
32 | } | |
33 | ||
34 | static inline int is_msa_enabled(void) | |
35 | { | |
36 | if (!cpu_has_msa) | |
37 | return 0; | |
38 | ||
39 | return read_c0_config5() & MIPS_CONF5_MSAEN; | |
40 | } | |
41 | ||
1db1af84 PB |
42 | static inline int thread_msa_context_live(void) |
43 | { | |
44 | /* | |
45 | * Check cpu_has_msa only if it's a constant. This will allow the | |
46 | * compiler to optimise out code for CPUs without MSA without adding | |
47 | * an extra redundant check for CPUs with MSA. | |
48 | */ | |
49 | if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa) | |
50 | return 0; | |
51 | ||
52 | return test_thread_flag(TIF_MSA_CTX_LIVE); | |
53 | } | |
54 | ||
55 | static inline void save_msa(struct task_struct *t) | |
56 | { | |
57 | if (cpu_has_msa) | |
58 | _save_msa(t); | |
59 | } | |
60 | ||
61 | static inline void restore_msa(struct task_struct *t) | |
62 | { | |
63 | if (cpu_has_msa) | |
64 | _restore_msa(t); | |
65 | } | |
66 | ||
7f65afb9 PB |
67 | #ifdef TOOLCHAIN_SUPPORTS_MSA |
68 | ||
69 | #define __BUILD_MSA_CTL_REG(name, cs) \ | |
70 | static inline unsigned int read_msa_##name(void) \ | |
71 | { \ | |
72 | unsigned int reg; \ | |
73 | __asm__ __volatile__( \ | |
74 | " .set push\n" \ | |
75 | " .set msa\n" \ | |
76 | " cfcmsa %0, $" #cs "\n" \ | |
77 | " .set pop\n" \ | |
78 | : "=r"(reg)); \ | |
79 | return reg; \ | |
80 | } \ | |
81 | \ | |
82 | static inline void write_msa_##name(unsigned int val) \ | |
83 | { \ | |
84 | __asm__ __volatile__( \ | |
85 | " .set push\n" \ | |
86 | " .set msa\n" \ | |
25198235 | 87 | " ctcmsa $" #cs ", %0\n" \ |
7f65afb9 PB |
88 | " .set pop\n" \ |
89 | : : "r"(val)); \ | |
90 | } | |
91 | ||
92 | #else /* !TOOLCHAIN_SUPPORTS_MSA */ | |
93 | ||
94 | /* | |
95 | * Define functions using .word for the c[ft]cmsa instructions in order to | |
96 | * allow compilation with toolchains that do not support MSA. Once all | |
97 | * toolchains in use support MSA these can be removed. | |
98 | */ | |
d96cc3d1 SH |
99 | #ifdef CONFIG_CPU_MICROMIPS |
100 | #define CFC_MSA_INSN 0x587e0056 | |
101 | #define CTC_MSA_INSN 0x583e0816 | |
102 | #else | |
103 | #define CFC_MSA_INSN 0x787e0059 | |
104 | #define CTC_MSA_INSN 0x783e0819 | |
105 | #endif | |
7f65afb9 PB |
106 | |
107 | #define __BUILD_MSA_CTL_REG(name, cs) \ | |
108 | static inline unsigned int read_msa_##name(void) \ | |
109 | { \ | |
110 | unsigned int reg; \ | |
111 | __asm__ __volatile__( \ | |
112 | " .set push\n" \ | |
113 | " .set noat\n" \ | |
d96cc3d1 SH |
114 | " .insn\n" \ |
115 | " .word #CFC_MSA_INSN | (" #cs " << 11)\n" \ | |
7f65afb9 PB |
116 | " move %0, $1\n" \ |
117 | " .set pop\n" \ | |
118 | : "=r"(reg)); \ | |
119 | return reg; \ | |
120 | } \ | |
121 | \ | |
122 | static inline void write_msa_##name(unsigned int val) \ | |
123 | { \ | |
124 | __asm__ __volatile__( \ | |
125 | " .set push\n" \ | |
126 | " .set noat\n" \ | |
127 | " move $1, %0\n" \ | |
d96cc3d1 SH |
128 | " .insn\n" \ |
129 | " .word #CTC_MSA_INSN | (" #cs " << 6)\n" \ | |
7f65afb9 PB |
130 | " .set pop\n" \ |
131 | : : "r"(val)); \ | |
132 | } | |
133 | ||
134 | #endif /* !TOOLCHAIN_SUPPORTS_MSA */ | |
135 | ||
136 | #define MSA_IR 0 | |
137 | #define MSA_CSR 1 | |
138 | #define MSA_ACCESS 2 | |
139 | #define MSA_SAVE 3 | |
140 | #define MSA_MODIFY 4 | |
141 | #define MSA_REQUEST 5 | |
142 | #define MSA_MAP 6 | |
143 | #define MSA_UNMAP 7 | |
144 | ||
145 | __BUILD_MSA_CTL_REG(ir, 0) | |
146 | __BUILD_MSA_CTL_REG(csr, 1) | |
147 | __BUILD_MSA_CTL_REG(access, 2) | |
148 | __BUILD_MSA_CTL_REG(save, 3) | |
149 | __BUILD_MSA_CTL_REG(modify, 4) | |
150 | __BUILD_MSA_CTL_REG(request, 5) | |
151 | __BUILD_MSA_CTL_REG(map, 6) | |
152 | __BUILD_MSA_CTL_REG(unmap, 7) | |
153 | ||
154 | /* MSA Implementation Register (MSAIR) */ | |
155 | #define MSA_IR_REVB 0 | |
156 | #define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB) | |
157 | #define MSA_IR_PROCB 8 | |
158 | #define MSA_IR_PROCF (_ULCAST_(0xff) << MSA_IR_PROCB) | |
159 | #define MSA_IR_WRPB 16 | |
160 | #define MSA_IR_WRPF (_ULCAST_(0x1) << MSA_IR_WRPB) | |
161 | ||
162 | /* MSA Control & Status Register (MSACSR) */ | |
163 | #define MSA_CSR_RMB 0 | |
164 | #define MSA_CSR_RMF (_ULCAST_(0x3) << MSA_CSR_RMB) | |
165 | #define MSA_CSR_RM_NEAREST 0 | |
166 | #define MSA_CSR_RM_TO_ZERO 1 | |
167 | #define MSA_CSR_RM_TO_POS 2 | |
168 | #define MSA_CSR_RM_TO_NEG 3 | |
169 | #define MSA_CSR_FLAGSB 2 | |
170 | #define MSA_CSR_FLAGSF (_ULCAST_(0x1f) << MSA_CSR_FLAGSB) | |
171 | #define MSA_CSR_FLAGS_IB 2 | |
172 | #define MSA_CSR_FLAGS_IF (_ULCAST_(0x1) << MSA_CSR_FLAGS_IB) | |
173 | #define MSA_CSR_FLAGS_UB 3 | |
174 | #define MSA_CSR_FLAGS_UF (_ULCAST_(0x1) << MSA_CSR_FLAGS_UB) | |
175 | #define MSA_CSR_FLAGS_OB 4 | |
176 | #define MSA_CSR_FLAGS_OF (_ULCAST_(0x1) << MSA_CSR_FLAGS_OB) | |
177 | #define MSA_CSR_FLAGS_ZB 5 | |
178 | #define MSA_CSR_FLAGS_ZF (_ULCAST_(0x1) << MSA_CSR_FLAGS_ZB) | |
179 | #define MSA_CSR_FLAGS_VB 6 | |
180 | #define MSA_CSR_FLAGS_VF (_ULCAST_(0x1) << MSA_CSR_FLAGS_VB) | |
181 | #define MSA_CSR_ENABLESB 7 | |
182 | #define MSA_CSR_ENABLESF (_ULCAST_(0x1f) << MSA_CSR_ENABLESB) | |
183 | #define MSA_CSR_ENABLES_IB 7 | |
184 | #define MSA_CSR_ENABLES_IF (_ULCAST_(0x1) << MSA_CSR_ENABLES_IB) | |
185 | #define MSA_CSR_ENABLES_UB 8 | |
186 | #define MSA_CSR_ENABLES_UF (_ULCAST_(0x1) << MSA_CSR_ENABLES_UB) | |
187 | #define MSA_CSR_ENABLES_OB 9 | |
188 | #define MSA_CSR_ENABLES_OF (_ULCAST_(0x1) << MSA_CSR_ENABLES_OB) | |
189 | #define MSA_CSR_ENABLES_ZB 10 | |
190 | #define MSA_CSR_ENABLES_ZF (_ULCAST_(0x1) << MSA_CSR_ENABLES_ZB) | |
191 | #define MSA_CSR_ENABLES_VB 11 | |
192 | #define MSA_CSR_ENABLES_VF (_ULCAST_(0x1) << MSA_CSR_ENABLES_VB) | |
193 | #define MSA_CSR_CAUSEB 12 | |
194 | #define MSA_CSR_CAUSEF (_ULCAST_(0x3f) << MSA_CSR_CAUSEB) | |
195 | #define MSA_CSR_CAUSE_IB 12 | |
196 | #define MSA_CSR_CAUSE_IF (_ULCAST_(0x1) << MSA_CSR_CAUSE_IB) | |
197 | #define MSA_CSR_CAUSE_UB 13 | |
198 | #define MSA_CSR_CAUSE_UF (_ULCAST_(0x1) << MSA_CSR_CAUSE_UB) | |
199 | #define MSA_CSR_CAUSE_OB 14 | |
200 | #define MSA_CSR_CAUSE_OF (_ULCAST_(0x1) << MSA_CSR_CAUSE_OB) | |
201 | #define MSA_CSR_CAUSE_ZB 15 | |
202 | #define MSA_CSR_CAUSE_ZF (_ULCAST_(0x1) << MSA_CSR_CAUSE_ZB) | |
203 | #define MSA_CSR_CAUSE_VB 16 | |
204 | #define MSA_CSR_CAUSE_VF (_ULCAST_(0x1) << MSA_CSR_CAUSE_VB) | |
205 | #define MSA_CSR_CAUSE_EB 17 | |
206 | #define MSA_CSR_CAUSE_EF (_ULCAST_(0x1) << MSA_CSR_CAUSE_EB) | |
207 | #define MSA_CSR_NXB 18 | |
208 | #define MSA_CSR_NXF (_ULCAST_(0x1) << MSA_CSR_NXB) | |
209 | #define MSA_CSR_FSB 24 | |
210 | #define MSA_CSR_FSF (_ULCAST_(0x1) << MSA_CSR_FSB) | |
211 | ||
212 | #endif /* _ASM_MSA_H */ |