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#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 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 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 40#define write_c0_tchalt(val) __write_32bit_c0_register($2, 4, val) 41 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 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 57#define CP0_VPESCHEDULE $1, 5 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 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 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 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 182static 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 193static 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" 202 " .word 0x41610001 # dvpe $1 \n" 203 " move %0, $1 \n" 204 " ehb \n" 205 " .set pop \n" 206 : "=r" (res)); 207 208 instruction_hazard(); 209 210 return res; 211} 212 213static 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 225/* Enable virtual processor execution if previous suggested it should be. 226 EVPE_ENABLE to force */ 227 228#define EVPE_ENABLE MVPCONTROL_EVP 229 230static inline void evpe(int previous) 231{ 232 if ((previous & MVPCONTROL_EVP)) 233 __raw_evpe(); 234} 235 236static inline unsigned int dmt(void) 237{ 238 int res; 239 240 __asm__ __volatile__( 241 " .set push \n" 242 " .set mips32r2 \n" 243 " .set noat \n" 244 " .word 0x41610BC1 # dmt $1 \n" 245 " ehb \n" 246 " move %0, $1 \n" 247 " .set pop \n" 248 : "=r" (res)); 249 250 instruction_hazard(); 251 252 return res; 253} 254 255static inline void __raw_emt(void) 256{ 257 __asm__ __volatile__( 258 " .set push \n" 259 " .set noreorder \n" 260 " .set mips32r2 \n" 261 " .word 0x41600be1 # emt \n" 262 " ehb \n" 263 " .set pop"); 264} 265 266/* enable multi-threaded execution if previous suggested it should be. 267 EMT_ENABLE to force */ 268 269#define EMT_ENABLE VPECONTROL_TE 270 271static inline void emt(int previous) 272{ 273 if ((previous & EMT_ENABLE)) 274 __raw_emt(); 275} 276 277static inline void ehb(void) 278{ 279 __asm__ __volatile__( 280 " .set push \n" 281 " .set mips32r2 \n" 282 " ehb \n" 283 " .set pop \n"); 284} 285 286#define mftc0(rt,sel) \ 287({ \ 288 unsigned long __res; \ 289 \ 290 __asm__ __volatile__( \ 291 " .set push \n" \ 292 " .set mips32r2 \n" \ 293 " .set noat \n" \ 294 " # mftc0 $1, $" #rt ", " #sel " \n" \ 295 " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \ 296 " move %0, $1 \n" \ 297 " .set pop \n" \ 298 : "=r" (__res)); \ 299 \ 300 __res; \ 301}) 302 303#define mftgpr(rt) \ 304({ \ 305 unsigned long __res; \ 306 \ 307 __asm__ __volatile__( \ 308 " .set push \n" \ 309 " .set noat \n" \ 310 " .set mips32r2 \n" \ 311 " # mftgpr $1," #rt " \n" \ 312 " .word 0x41000820 | (" #rt " << 16) \n" \ 313 " move %0, $1 \n" \ 314 " .set pop \n" \ 315 : "=r" (__res)); \ 316 \ 317 __res; \ 318}) 319 320#define mftr(rt, u, sel) \ 321({ \ 322 unsigned long __res; \ 323 \ 324 __asm__ __volatile__( \ 325 " mftr %0, " #rt ", " #u ", " #sel " \n" \ 326 : "=r" (__res)); \ 327 \ 328 __res; \ 329}) 330 331#define mttgpr(rd,v) \ 332do { \ 333 __asm__ __volatile__( \ 334 " .set push \n" \ 335 " .set mips32r2 \n" \ 336 " .set noat \n" \ 337 " move $1, %0 \n" \ 338 " # mttgpr $1, " #rd " \n" \ 339 " .word 0x41810020 | (" #rd " << 11) \n" \ 340 " .set pop \n" \ 341 : : "r" (v)); \ 342} while (0) 343 344#define mttc0(rd, sel, v) \ 345({ \ 346 __asm__ __volatile__( \ 347 " .set push \n" \ 348 " .set mips32r2 \n" \ 349 " .set noat \n" \ 350 " move $1, %0 \n" \ 351 " # mttc0 %0," #rd ", " #sel " \n" \ 352 " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \ 353 " .set pop \n" \ 354 : \ 355 : "r" (v)); \ 356}) 357 358 359#define mttr(rd, u, sel, v) \ 360({ \ 361 __asm__ __volatile__( \ 362 "mttr %0," #rd ", " #u ", " #sel \ 363 : : "r" (v)); \ 364}) 365 366 367#define settc(tc) \ 368do { \ 369 write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \ 370 ehb(); \ 371} while (0) 372 373 374/* you *must* set the target tc (settc) before trying to use these */ 375#define read_vpe_c0_vpecontrol() mftc0(1, 1) 376#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) 377#define read_vpe_c0_vpeconf0() mftc0(1, 2) 378#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) 379#define read_vpe_c0_vpeconf1() mftc0(1, 3) 380#define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val) 381#define read_vpe_c0_count() mftc0(9, 0) 382#define write_vpe_c0_count(val) mttc0(9, 0, val) 383#define read_vpe_c0_status() mftc0(12, 0) 384#define write_vpe_c0_status(val) mttc0(12, 0, val) 385#define read_vpe_c0_cause() mftc0(13, 0) 386#define write_vpe_c0_cause(val) mttc0(13, 0, val) 387#define read_vpe_c0_config() mftc0(16, 0) 388#define write_vpe_c0_config(val) mttc0(16, 0, val) 389#define read_vpe_c0_config1() mftc0(16, 1) 390#define write_vpe_c0_config1(val) mttc0(16, 1, val) 391#define read_vpe_c0_config7() mftc0(16, 7) 392#define write_vpe_c0_config7(val) mttc0(16, 7, val) 393#define read_vpe_c0_ebase() mftc0(15, 1) 394#define write_vpe_c0_ebase(val) mttc0(15, 1, val) 395#define write_vpe_c0_compare(val) mttc0(11, 0, val) 396#define read_vpe_c0_badvaddr() mftc0(8, 0) 397#define read_vpe_c0_epc() mftc0(14, 0) 398#define write_vpe_c0_epc(val) mttc0(14, 0, val) 399 400 401/* TC */ 402#define read_tc_c0_tcstatus() mftc0(2, 1) 403#define write_tc_c0_tcstatus(val) mttc0(2, 1, val) 404#define read_tc_c0_tcbind() mftc0(2, 2) 405#define write_tc_c0_tcbind(val) mttc0(2, 2, val) 406#define read_tc_c0_tcrestart() mftc0(2, 3) 407#define write_tc_c0_tcrestart(val) mttc0(2, 3, val) 408#define read_tc_c0_tchalt() mftc0(2, 4) 409#define write_tc_c0_tchalt(val) mttc0(2, 4, val) 410#define read_tc_c0_tccontext() mftc0(2, 5) 411#define write_tc_c0_tccontext(val) mttc0(2, 5, val) 412 413/* GPR */ 414#define read_tc_gpr_sp() mftgpr(29) 415#define write_tc_gpr_sp(val) mttgpr(29, val) 416#define read_tc_gpr_gp() mftgpr(28) 417#define write_tc_gpr_gp(val) mttgpr(28, val) 418 419__BUILD_SET_C0(mvpcontrol) 420 421#endif /* Not __ASSEMBLY__ */ 422 423#endif 424