Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
699dbc90 RB |
2 | /* |
3 | * MT regs definitions, follows on from mipsregs.h | |
4 | * Copyright (C) 2004 - 2005 MIPS Technologies, Inc. All rights reserved. | |
5 | * Elizabeth Clarke et. al. | |
6 | * | |
7 | */ | |
8 | #ifndef _ASM_MIPSMTREGS_H | |
9 | #define _ASM_MIPSMTREGS_H | |
10 | ||
340ee4b9 | 11 | #include <asm/mipsregs.h> |
699dbc90 RB |
12 | #include <asm/war.h> |
13 | ||
14 | #ifndef __ASSEMBLY__ | |
15 | ||
16 | /* | |
17 | * C macros | |
18 | */ | |
19 | ||
20 | #define read_c0_mvpcontrol() __read_32bit_c0_register($0, 1) | |
21 | #define write_c0_mvpcontrol(val) __write_32bit_c0_register($0, 1, val) | |
22 | ||
23 | #define read_c0_mvpconf0() __read_32bit_c0_register($0, 2) | |
24 | #define read_c0_mvpconf1() __read_32bit_c0_register($0, 3) | |
25 | ||
26 | #define read_c0_vpecontrol() __read_32bit_c0_register($1, 1) | |
27 | #define write_c0_vpecontrol(val) __write_32bit_c0_register($1, 1, val) | |
28 | ||
29 | #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) | |
30 | #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) | |
31 | ||
889a4c7b SH |
32 | #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3) |
33 | #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val) | |
34 | ||
699dbc90 RB |
35 | #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) |
36 | #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) | |
37 | ||
38 | #define read_c0_tcbind() __read_32bit_c0_register($2, 2) | |
39 | ||
27476f3b PB |
40 | #define write_c0_tchalt(val) __write_32bit_c0_register($2, 4, val) |
41 | ||
699dbc90 RB |
42 | #define read_c0_tccontext() __read_32bit_c0_register($2, 5) |
43 | #define write_c0_tccontext(val) __write_32bit_c0_register($2, 5, val) | |
44 | ||
45 | #else /* Assembly */ | |
46 | /* | |
47 | * Macros for use in assembly language code | |
48 | */ | |
49 | ||
21a151d8 RB |
50 | #define CP0_MVPCONTROL $0, 1 |
51 | #define CP0_MVPCONF0 $0, 2 | |
52 | #define CP0_MVPCONF1 $0, 3 | |
53 | #define CP0_VPECONTROL $1, 1 | |
54 | #define CP0_VPECONF0 $1, 2 | |
55 | #define CP0_VPECONF1 $1, 3 | |
56 | #define CP0_YQMASK $1, 4 | |
839efb4f | 57 | #define CP0_VPESCHEDULE $1, 5 |
21a151d8 RB |
58 | #define CP0_VPESCHEFBK $1, 6 |
59 | #define CP0_TCSTATUS $2, 1 | |
60 | #define CP0_TCBIND $2, 2 | |
61 | #define CP0_TCRESTART $2, 3 | |
62 | #define CP0_TCHALT $2, 4 | |
63 | #define CP0_TCCONTEXT $2, 5 | |
64 | #define CP0_TCSCHEDULE $2, 6 | |
65 | #define CP0_TCSCHEFBK $2, 7 | |
66 | #define CP0_SRSCONF0 $6, 1 | |
67 | #define CP0_SRSCONF1 $6, 2 | |
68 | #define CP0_SRSCONF2 $6, 3 | |
69 | #define CP0_SRSCONF3 $6, 4 | |
70 | #define CP0_SRSCONF4 $6, 5 | |
699dbc90 RB |
71 | |
72 | #endif | |
73 | ||
74 | /* MVPControl fields */ | |
75 | #define MVPCONTROL_EVP (_ULCAST_(1)) | |
76 | ||
77 | #define MVPCONTROL_VPC_SHIFT 1 | |
78 | #define MVPCONTROL_VPC (_ULCAST_(1) << MVPCONTROL_VPC_SHIFT) | |
79 | ||
80 | #define MVPCONTROL_STLB_SHIFT 2 | |
81 | #define MVPCONTROL_STLB (_ULCAST_(1) << MVPCONTROL_STLB_SHIFT) | |
82 | ||
83 | ||
84 | /* MVPConf0 fields */ | |
85 | #define MVPCONF0_PTC_SHIFT 0 | |
86 | #define MVPCONF0_PTC ( _ULCAST_(0xff)) | |
87 | #define MVPCONF0_PVPE_SHIFT 10 | |
88 | #define MVPCONF0_PVPE ( _ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT) | |
89 | #define MVPCONF0_TCA_SHIFT 15 | |
90 | #define MVPCONF0_TCA ( _ULCAST_(1) << MVPCONF0_TCA_SHIFT) | |
91 | #define MVPCONF0_PTLBE_SHIFT 16 | |
92 | #define MVPCONF0_PTLBE (_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT) | |
93 | #define MVPCONF0_TLBS_SHIFT 29 | |
94 | #define MVPCONF0_TLBS (_ULCAST_(1) << MVPCONF0_TLBS_SHIFT) | |
95 | #define MVPCONF0_M_SHIFT 31 | |
96 | #define MVPCONF0_M (_ULCAST_(0x1) << MVPCONF0_M_SHIFT) | |
97 | ||
98 | ||
99 | /* config3 fields */ | |
100 | #define CONFIG3_MT_SHIFT 2 | |
101 | #define CONFIG3_MT (_ULCAST_(1) << CONFIG3_MT_SHIFT) | |
102 | ||
103 | ||
104 | /* VPEControl fields (per VPE) */ | |
105 | #define VPECONTROL_TARGTC (_ULCAST_(0xff)) | |
106 | ||
107 | #define VPECONTROL_TE_SHIFT 15 | |
108 | #define VPECONTROL_TE (_ULCAST_(1) << VPECONTROL_TE_SHIFT) | |
109 | #define VPECONTROL_EXCPT_SHIFT 16 | |
110 | #define VPECONTROL_EXCPT (_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT) | |
111 | ||
112 | /* Thread Exception Codes for EXCPT field */ | |
113 | #define THREX_TU 0 | |
114 | #define THREX_TO 1 | |
115 | #define THREX_IYQ 2 | |
116 | #define THREX_GSX 3 | |
117 | #define THREX_YSCH 4 | |
118 | #define THREX_GSSCH 5 | |
119 | ||
120 | #define VPECONTROL_GSI_SHIFT 20 | |
121 | #define VPECONTROL_GSI (_ULCAST_(1) << VPECONTROL_GSI_SHIFT) | |
122 | #define VPECONTROL_YSI_SHIFT 21 | |
123 | #define VPECONTROL_YSI (_ULCAST_(1) << VPECONTROL_YSI_SHIFT) | |
124 | ||
125 | /* VPEConf0 fields (per VPE) */ | |
126 | #define VPECONF0_VPA_SHIFT 0 | |
127 | #define VPECONF0_VPA (_ULCAST_(1) << VPECONF0_VPA_SHIFT) | |
128 | #define VPECONF0_MVP_SHIFT 1 | |
129 | #define VPECONF0_MVP (_ULCAST_(1) << VPECONF0_MVP_SHIFT) | |
130 | #define VPECONF0_XTC_SHIFT 21 | |
131 | #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) | |
132 | ||
889a4c7b SH |
133 | /* VPEConf1 fields (per VPE) */ |
134 | #define VPECONF1_NCP1_SHIFT 0 | |
135 | #define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT) | |
136 | #define VPECONF1_NCP2_SHIFT 10 | |
137 | #define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT) | |
138 | #define VPECONF1_NCX_SHIFT 20 | |
139 | #define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT) | |
140 | ||
699dbc90 RB |
141 | /* TCStatus fields (per TC) */ |
142 | #define TCSTATUS_TASID (_ULCAST_(0xff)) | |
143 | #define TCSTATUS_IXMT_SHIFT 10 | |
144 | #define TCSTATUS_IXMT (_ULCAST_(1) << TCSTATUS_IXMT_SHIFT) | |
145 | #define TCSTATUS_TKSU_SHIFT 11 | |
146 | #define TCSTATUS_TKSU (_ULCAST_(3) << TCSTATUS_TKSU_SHIFT) | |
147 | #define TCSTATUS_A_SHIFT 13 | |
148 | #define TCSTATUS_A (_ULCAST_(1) << TCSTATUS_A_SHIFT) | |
149 | #define TCSTATUS_DA_SHIFT 15 | |
150 | #define TCSTATUS_DA (_ULCAST_(1) << TCSTATUS_DA_SHIFT) | |
151 | #define TCSTATUS_DT_SHIFT 20 | |
152 | #define TCSTATUS_DT (_ULCAST_(1) << TCSTATUS_DT_SHIFT) | |
153 | #define TCSTATUS_TDS_SHIFT 21 | |
154 | #define TCSTATUS_TDS (_ULCAST_(1) << TCSTATUS_TDS_SHIFT) | |
155 | #define TCSTATUS_TSST_SHIFT 22 | |
156 | #define TCSTATUS_TSST (_ULCAST_(1) << TCSTATUS_TSST_SHIFT) | |
157 | #define TCSTATUS_RNST_SHIFT 23 | |
158 | #define TCSTATUS_RNST (_ULCAST_(3) << TCSTATUS_RNST_SHIFT) | |
159 | /* Codes for RNST */ | |
160 | #define TC_RUNNING 0 | |
161 | #define TC_WAITING 1 | |
162 | #define TC_YIELDING 2 | |
163 | #define TC_GATED 3 | |
164 | ||
165 | #define TCSTATUS_TMX_SHIFT 27 | |
166 | #define TCSTATUS_TMX (_ULCAST_(1) << TCSTATUS_TMX_SHIFT) | |
167 | /* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */ | |
168 | ||
169 | /* TCBind */ | |
170 | #define TCBIND_CURVPE_SHIFT 0 | |
171 | #define TCBIND_CURVPE (_ULCAST_(0xf)) | |
172 | ||
173 | #define TCBIND_CURTC_SHIFT 21 | |
174 | ||
175 | #define TCBIND_CURTC (_ULCAST_(0xff) << TCBIND_CURTC_SHIFT) | |
176 | ||
177 | /* TCHalt */ | |
178 | #define TCHALT_H (_ULCAST_(1)) | |
179 | ||
180 | #ifndef __ASSEMBLY__ | |
181 | ||
968a0734 PB |
182 | static inline unsigned core_nvpes(void) |
183 | { | |
184 | unsigned conf0; | |
185 | ||
186 | if (!cpu_has_mipsmt) | |
187 | return 1; | |
188 | ||
189 | conf0 = read_c0_mvpconf0(); | |
190 | return ((conf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; | |
191 | } | |
192 | ||
699dbc90 RB |
193 | static inline unsigned int dvpe(void) |
194 | { | |
195 | int res = 0; | |
196 | ||
197 | __asm__ __volatile__( | |
198 | " .set push \n" | |
199 | " .set noreorder \n" | |
200 | " .set noat \n" | |
201 | " .set mips32r2 \n" | |
699dbc90 | 202 | " .word 0x41610001 # dvpe $1 \n" |
8f40611d | 203 | " move %0, $1 \n" |
699dbc90 RB |
204 | " ehb \n" |
205 | " .set pop \n" | |
206 | : "=r" (res)); | |
207 | ||
208 | instruction_hazard(); | |
209 | ||
210 | return res; | |
211 | } | |
212 | ||
213 | static inline void __raw_evpe(void) | |
214 | { | |
215 | __asm__ __volatile__( | |
216 | " .set push \n" | |
217 | " .set noreorder \n" | |
218 | " .set noat \n" | |
219 | " .set mips32r2 \n" | |
220 | " .word 0x41600021 # evpe \n" | |
221 | " ehb \n" | |
222 | " .set pop \n"); | |
223 | } | |
224 | ||
39b8d525 RB |
225 | /* Enable virtual processor execution if previous suggested it should be. |
226 | EVPE_ENABLE to force */ | |
699dbc90 RB |
227 | |
228 | #define EVPE_ENABLE MVPCONTROL_EVP | |
229 | ||
230 | static inline void evpe(int previous) | |
231 | { | |
232 | if ((previous & MVPCONTROL_EVP)) | |
233 | __raw_evpe(); | |
234 | } | |
235 | ||
236 | static inline unsigned int dmt(void) | |
237 | { | |
238 | int res; | |
239 | ||
240 | __asm__ __volatile__( | |
8f40611d | 241 | " .set push \n" |
699dbc90 | 242 | " .set mips32r2 \n" |
8f40611d RB |
243 | " .set noat \n" |
244 | " .word 0x41610BC1 # dmt $1 \n" | |
699dbc90 | 245 | " ehb \n" |
8f40611d RB |
246 | " move %0, $1 \n" |
247 | " .set pop \n" | |
699dbc90 RB |
248 | : "=r" (res)); |
249 | ||
250 | instruction_hazard(); | |
251 | ||
252 | return res; | |
253 | } | |
254 | ||
255 | static inline void __raw_emt(void) | |
256 | { | |
257 | __asm__ __volatile__( | |
258 | " .set noreorder \n" | |
259 | " .set mips32r2 \n" | |
2600990e | 260 | " .word 0x41600be1 # emt \n" |
699dbc90 RB |
261 | " ehb \n" |
262 | " .set mips0 \n" | |
263 | " .set reorder"); | |
264 | } | |
265 | ||
39b8d525 RB |
266 | /* enable multi-threaded execution if previous suggested it should be. |
267 | EMT_ENABLE to force */ | |
699dbc90 RB |
268 | |
269 | #define EMT_ENABLE VPECONTROL_TE | |
270 | ||
271 | static inline void emt(int previous) | |
272 | { | |
273 | if ((previous & EMT_ENABLE)) | |
274 | __raw_emt(); | |
275 | } | |
276 | ||
277 | static inline void ehb(void) | |
278 | { | |
8f40611d RB |
279 | __asm__ __volatile__( |
280 | " .set mips32r2 \n" | |
281 | " ehb \n" | |
282 | " .set mips0 \n"); | |
699dbc90 RB |
283 | } |
284 | ||
285 | #define mftc0(rt,sel) \ | |
286 | ({ \ | |
70342287 | 287 | unsigned long __res; \ |
699dbc90 RB |
288 | \ |
289 | __asm__ __volatile__( \ | |
8f40611d RB |
290 | " .set push \n" \ |
291 | " .set mips32r2 \n" \ | |
292 | " .set noat \n" \ | |
70342287 RB |
293 | " # mftc0 $1, $" #rt ", " #sel " \n" \ |
294 | " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \ | |
8f40611d RB |
295 | " move %0, $1 \n" \ |
296 | " .set pop \n" \ | |
297 | : "=r" (__res)); \ | |
699dbc90 RB |
298 | \ |
299 | __res; \ | |
300 | }) | |
301 | ||
302 | #define mftgpr(rt) \ | |
303 | ({ \ | |
304 | unsigned long __res; \ | |
305 | \ | |
306 | __asm__ __volatile__( \ | |
8f40611d | 307 | " .set push \n" \ |
41c594ab | 308 | " .set noat \n" \ |
8f40611d | 309 | " .set mips32r2 \n" \ |
41c594ab RB |
310 | " # mftgpr $1," #rt " \n" \ |
311 | " .word 0x41000820 | (" #rt " << 16) \n" \ | |
312 | " move %0, $1 \n" \ | |
8f40611d | 313 | " .set pop \n" \ |
699dbc90 RB |
314 | : "=r" (__res)); \ |
315 | \ | |
316 | __res; \ | |
317 | }) | |
318 | ||
21a151d8 | 319 | #define mftr(rt, u, sel) \ |
699dbc90 RB |
320 | ({ \ |
321 | unsigned long __res; \ | |
322 | \ | |
323 | __asm__ __volatile__( \ | |
41c594ab | 324 | " mftr %0, " #rt ", " #u ", " #sel " \n" \ |
699dbc90 RB |
325 | : "=r" (__res)); \ |
326 | \ | |
327 | __res; \ | |
328 | }) | |
329 | ||
330 | #define mttgpr(rd,v) \ | |
8f40611d | 331 | do { \ |
699dbc90 | 332 | __asm__ __volatile__( \ |
8f40611d RB |
333 | " .set push \n" \ |
334 | " .set mips32r2 \n" \ | |
335 | " .set noat \n" \ | |
336 | " move $1, %0 \n" \ | |
337 | " # mttgpr $1, " #rd " \n" \ | |
338 | " .word 0x41810020 | (" #rd " << 11) \n" \ | |
339 | " .set pop \n" \ | |
699dbc90 | 340 | : : "r" (v)); \ |
8f40611d | 341 | } while (0) |
699dbc90 | 342 | |
21a151d8 | 343 | #define mttc0(rd, sel, v) \ |
699dbc90 RB |
344 | ({ \ |
345 | __asm__ __volatile__( \ | |
8f40611d RB |
346 | " .set push \n" \ |
347 | " .set mips32r2 \n" \ | |
348 | " .set noat \n" \ | |
349 | " move $1, %0 \n" \ | |
350 | " # mttc0 %0," #rd ", " #sel " \n" \ | |
70342287 | 351 | " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \ |
8f40611d RB |
352 | " .set pop \n" \ |
353 | : \ | |
354 | : "r" (v)); \ | |
699dbc90 RB |
355 | }) |
356 | ||
357 | ||
21a151d8 | 358 | #define mttr(rd, u, sel, v) \ |
699dbc90 RB |
359 | ({ \ |
360 | __asm__ __volatile__( \ | |
361 | "mttr %0," #rd ", " #u ", " #sel \ | |
362 | : : "r" (v)); \ | |
363 | }) | |
364 | ||
365 | ||
366 | #define settc(tc) \ | |
367 | do { \ | |
368 | write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \ | |
369 | ehb(); \ | |
370 | } while (0) | |
371 | ||
372 | ||
373 | /* you *must* set the target tc (settc) before trying to use these */ | |
8f40611d RB |
374 | #define read_vpe_c0_vpecontrol() mftc0(1, 1) |
375 | #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) | |
376 | #define read_vpe_c0_vpeconf0() mftc0(1, 2) | |
377 | #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) | |
889a4c7b SH |
378 | #define read_vpe_c0_vpeconf1() mftc0(1, 3) |
379 | #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val) | |
70e46f48 RB |
380 | #define read_vpe_c0_count() mftc0(9, 0) |
381 | #define write_vpe_c0_count(val) mttc0(9, 0, val) | |
8f40611d RB |
382 | #define read_vpe_c0_status() mftc0(12, 0) |
383 | #define write_vpe_c0_status(val) mttc0(12, 0, val) | |
384 | #define read_vpe_c0_cause() mftc0(13, 0) | |
385 | #define write_vpe_c0_cause(val) mttc0(13, 0, val) | |
386 | #define read_vpe_c0_config() mftc0(16, 0) | |
387 | #define write_vpe_c0_config(val) mttc0(16, 0, val) | |
388 | #define read_vpe_c0_config1() mftc0(16, 1) | |
389 | #define write_vpe_c0_config1(val) mttc0(16, 1, val) | |
390 | #define read_vpe_c0_config7() mftc0(16, 7) | |
391 | #define write_vpe_c0_config7(val) mttc0(16, 7, val) | |
21a151d8 | 392 | #define read_vpe_c0_ebase() mftc0(15, 1) |
8f40611d RB |
393 | #define write_vpe_c0_ebase(val) mttc0(15, 1, val) |
394 | #define write_vpe_c0_compare(val) mttc0(11, 0, val) | |
2600990e RB |
395 | #define read_vpe_c0_badvaddr() mftc0(8, 0) |
396 | #define read_vpe_c0_epc() mftc0(14, 0) | |
397 | #define write_vpe_c0_epc(val) mttc0(14, 0, val) | |
699dbc90 RB |
398 | |
399 | ||
400 | /* TC */ | |
8f40611d | 401 | #define read_tc_c0_tcstatus() mftc0(2, 1) |
21a151d8 | 402 | #define write_tc_c0_tcstatus(val) mttc0(2, 1, val) |
8f40611d | 403 | #define read_tc_c0_tcbind() mftc0(2, 2) |
21a151d8 | 404 | #define write_tc_c0_tcbind(val) mttc0(2, 2, val) |
8f40611d | 405 | #define read_tc_c0_tcrestart() mftc0(2, 3) |
21a151d8 | 406 | #define write_tc_c0_tcrestart(val) mttc0(2, 3, val) |
8f40611d | 407 | #define read_tc_c0_tchalt() mftc0(2, 4) |
21a151d8 | 408 | #define write_tc_c0_tchalt(val) mttc0(2, 4, val) |
8f40611d | 409 | #define read_tc_c0_tccontext() mftc0(2, 5) |
21a151d8 | 410 | #define write_tc_c0_tccontext(val) mttc0(2, 5, val) |
699dbc90 RB |
411 | |
412 | /* GPR */ | |
8f40611d RB |
413 | #define read_tc_gpr_sp() mftgpr(29) |
414 | #define write_tc_gpr_sp(val) mttgpr(29, val) | |
415 | #define read_tc_gpr_gp() mftgpr(28) | |
416 | #define write_tc_gpr_gp(val) mttgpr(28, val) | |
699dbc90 | 417 | |
340ee4b9 | 418 | __BUILD_SET_C0(mvpcontrol) |
699dbc90 RB |
419 | |
420 | #endif /* Not __ASSEMBLY__ */ | |
421 | ||
422 | #endif |