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