162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * MT regs definitions, follows on from mipsregs.h
462306a36Sopenharmony_ci * Copyright (C) 2004 - 2005 MIPS Technologies, Inc.  All rights reserved.
562306a36Sopenharmony_ci * Elizabeth Clarke et. al.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#ifndef _ASM_MIPSMTREGS_H
962306a36Sopenharmony_ci#define _ASM_MIPSMTREGS_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <asm/mipsregs.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#ifndef __ASSEMBLY__
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*
1662306a36Sopenharmony_ci * C macros
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define read_c0_mvpcontrol()		__read_32bit_c0_register($0, 1)
2062306a36Sopenharmony_ci#define write_c0_mvpcontrol(val)	__write_32bit_c0_register($0, 1, val)
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define read_c0_mvpconf0()		__read_32bit_c0_register($0, 2)
2362306a36Sopenharmony_ci#define read_c0_mvpconf1()		__read_32bit_c0_register($0, 3)
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define read_c0_vpecontrol()		__read_32bit_c0_register($1, 1)
2662306a36Sopenharmony_ci#define write_c0_vpecontrol(val)	__write_32bit_c0_register($1, 1, val)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define read_c0_vpeconf0()		__read_32bit_c0_register($1, 2)
2962306a36Sopenharmony_ci#define write_c0_vpeconf0(val)		__write_32bit_c0_register($1, 2, val)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define read_c0_vpeconf1()		__read_32bit_c0_register($1, 3)
3262306a36Sopenharmony_ci#define write_c0_vpeconf1(val)		__write_32bit_c0_register($1, 3, val)
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define read_c0_tcstatus()		__read_32bit_c0_register($2, 1)
3562306a36Sopenharmony_ci#define write_c0_tcstatus(val)		__write_32bit_c0_register($2, 1, val)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define read_c0_tcbind()		__read_32bit_c0_register($2, 2)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define write_c0_tchalt(val)		__write_32bit_c0_register($2, 4, val)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define read_c0_tccontext()		__read_32bit_c0_register($2, 5)
4262306a36Sopenharmony_ci#define write_c0_tccontext(val)		__write_32bit_c0_register($2, 5, val)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#else /* Assembly */
4562306a36Sopenharmony_ci/*
4662306a36Sopenharmony_ci * Macros for use in assembly language code
4762306a36Sopenharmony_ci */
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define CP0_MVPCONTROL		$0, 1
5062306a36Sopenharmony_ci#define CP0_MVPCONF0		$0, 2
5162306a36Sopenharmony_ci#define CP0_MVPCONF1		$0, 3
5262306a36Sopenharmony_ci#define CP0_VPECONTROL		$1, 1
5362306a36Sopenharmony_ci#define CP0_VPECONF0		$1, 2
5462306a36Sopenharmony_ci#define CP0_VPECONF1		$1, 3
5562306a36Sopenharmony_ci#define CP0_YQMASK		$1, 4
5662306a36Sopenharmony_ci#define CP0_VPESCHEDULE		$1, 5
5762306a36Sopenharmony_ci#define CP0_VPESCHEFBK		$1, 6
5862306a36Sopenharmony_ci#define CP0_TCSTATUS		$2, 1
5962306a36Sopenharmony_ci#define CP0_TCBIND		$2, 2
6062306a36Sopenharmony_ci#define CP0_TCRESTART		$2, 3
6162306a36Sopenharmony_ci#define CP0_TCHALT		$2, 4
6262306a36Sopenharmony_ci#define CP0_TCCONTEXT		$2, 5
6362306a36Sopenharmony_ci#define CP0_TCSCHEDULE		$2, 6
6462306a36Sopenharmony_ci#define CP0_TCSCHEFBK		$2, 7
6562306a36Sopenharmony_ci#define CP0_SRSCONF0		$6, 1
6662306a36Sopenharmony_ci#define CP0_SRSCONF1		$6, 2
6762306a36Sopenharmony_ci#define CP0_SRSCONF2		$6, 3
6862306a36Sopenharmony_ci#define CP0_SRSCONF3		$6, 4
6962306a36Sopenharmony_ci#define CP0_SRSCONF4		$6, 5
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#endif
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* MVPControl fields */
7462306a36Sopenharmony_ci#define MVPCONTROL_EVP		(_ULCAST_(1))
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define MVPCONTROL_VPC_SHIFT	1
7762306a36Sopenharmony_ci#define MVPCONTROL_VPC		(_ULCAST_(1) << MVPCONTROL_VPC_SHIFT)
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci#define MVPCONTROL_STLB_SHIFT	2
8062306a36Sopenharmony_ci#define MVPCONTROL_STLB		(_ULCAST_(1) << MVPCONTROL_STLB_SHIFT)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/* MVPConf0 fields */
8462306a36Sopenharmony_ci#define MVPCONF0_PTC_SHIFT	0
8562306a36Sopenharmony_ci#define MVPCONF0_PTC		( _ULCAST_(0xff))
8662306a36Sopenharmony_ci#define MVPCONF0_PVPE_SHIFT	10
8762306a36Sopenharmony_ci#define MVPCONF0_PVPE		( _ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT)
8862306a36Sopenharmony_ci#define MVPCONF0_TCA_SHIFT	15
8962306a36Sopenharmony_ci#define MVPCONF0_TCA		( _ULCAST_(1) << MVPCONF0_TCA_SHIFT)
9062306a36Sopenharmony_ci#define MVPCONF0_PTLBE_SHIFT	16
9162306a36Sopenharmony_ci#define MVPCONF0_PTLBE		(_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT)
9262306a36Sopenharmony_ci#define MVPCONF0_TLBS_SHIFT	29
9362306a36Sopenharmony_ci#define MVPCONF0_TLBS		(_ULCAST_(1) << MVPCONF0_TLBS_SHIFT)
9462306a36Sopenharmony_ci#define MVPCONF0_M_SHIFT	31
9562306a36Sopenharmony_ci#define MVPCONF0_M		(_ULCAST_(0x1) << MVPCONF0_M_SHIFT)
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci/* config3 fields */
9962306a36Sopenharmony_ci#define CONFIG3_MT_SHIFT	2
10062306a36Sopenharmony_ci#define CONFIG3_MT		(_ULCAST_(1) << CONFIG3_MT_SHIFT)
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* VPEControl fields (per VPE) */
10462306a36Sopenharmony_ci#define VPECONTROL_TARGTC	(_ULCAST_(0xff))
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci#define VPECONTROL_TE_SHIFT	15
10762306a36Sopenharmony_ci#define VPECONTROL_TE		(_ULCAST_(1) << VPECONTROL_TE_SHIFT)
10862306a36Sopenharmony_ci#define VPECONTROL_EXCPT_SHIFT	16
10962306a36Sopenharmony_ci#define VPECONTROL_EXCPT	(_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT)
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci/* Thread Exception Codes for EXCPT field */
11262306a36Sopenharmony_ci#define THREX_TU		0
11362306a36Sopenharmony_ci#define THREX_TO		1
11462306a36Sopenharmony_ci#define THREX_IYQ		2
11562306a36Sopenharmony_ci#define THREX_GSX		3
11662306a36Sopenharmony_ci#define THREX_YSCH		4
11762306a36Sopenharmony_ci#define THREX_GSSCH		5
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define VPECONTROL_GSI_SHIFT	20
12062306a36Sopenharmony_ci#define VPECONTROL_GSI		(_ULCAST_(1) << VPECONTROL_GSI_SHIFT)
12162306a36Sopenharmony_ci#define VPECONTROL_YSI_SHIFT	21
12262306a36Sopenharmony_ci#define VPECONTROL_YSI		(_ULCAST_(1) << VPECONTROL_YSI_SHIFT)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/* VPEConf0 fields (per VPE) */
12562306a36Sopenharmony_ci#define VPECONF0_VPA_SHIFT	0
12662306a36Sopenharmony_ci#define VPECONF0_VPA		(_ULCAST_(1) << VPECONF0_VPA_SHIFT)
12762306a36Sopenharmony_ci#define VPECONF0_MVP_SHIFT	1
12862306a36Sopenharmony_ci#define VPECONF0_MVP		(_ULCAST_(1) << VPECONF0_MVP_SHIFT)
12962306a36Sopenharmony_ci#define VPECONF0_XTC_SHIFT	21
13062306a36Sopenharmony_ci#define VPECONF0_XTC		(_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/* VPEConf1 fields (per VPE) */
13362306a36Sopenharmony_ci#define VPECONF1_NCP1_SHIFT	0
13462306a36Sopenharmony_ci#define VPECONF1_NCP1		(_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT)
13562306a36Sopenharmony_ci#define VPECONF1_NCP2_SHIFT	10
13662306a36Sopenharmony_ci#define VPECONF1_NCP2		(_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT)
13762306a36Sopenharmony_ci#define VPECONF1_NCX_SHIFT	20
13862306a36Sopenharmony_ci#define VPECONF1_NCX		(_ULCAST_(0xff) << VPECONF1_NCX_SHIFT)
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/* TCStatus fields (per TC) */
14162306a36Sopenharmony_ci#define TCSTATUS_TASID		(_ULCAST_(0xff))
14262306a36Sopenharmony_ci#define TCSTATUS_IXMT_SHIFT	10
14362306a36Sopenharmony_ci#define TCSTATUS_IXMT		(_ULCAST_(1) << TCSTATUS_IXMT_SHIFT)
14462306a36Sopenharmony_ci#define TCSTATUS_TKSU_SHIFT	11
14562306a36Sopenharmony_ci#define TCSTATUS_TKSU		(_ULCAST_(3) << TCSTATUS_TKSU_SHIFT)
14662306a36Sopenharmony_ci#define TCSTATUS_A_SHIFT	13
14762306a36Sopenharmony_ci#define TCSTATUS_A		(_ULCAST_(1) << TCSTATUS_A_SHIFT)
14862306a36Sopenharmony_ci#define TCSTATUS_DA_SHIFT	15
14962306a36Sopenharmony_ci#define TCSTATUS_DA		(_ULCAST_(1) << TCSTATUS_DA_SHIFT)
15062306a36Sopenharmony_ci#define TCSTATUS_DT_SHIFT	20
15162306a36Sopenharmony_ci#define TCSTATUS_DT		(_ULCAST_(1) << TCSTATUS_DT_SHIFT)
15262306a36Sopenharmony_ci#define TCSTATUS_TDS_SHIFT	21
15362306a36Sopenharmony_ci#define TCSTATUS_TDS		(_ULCAST_(1) << TCSTATUS_TDS_SHIFT)
15462306a36Sopenharmony_ci#define TCSTATUS_TSST_SHIFT	22
15562306a36Sopenharmony_ci#define TCSTATUS_TSST		(_ULCAST_(1) << TCSTATUS_TSST_SHIFT)
15662306a36Sopenharmony_ci#define TCSTATUS_RNST_SHIFT	23
15762306a36Sopenharmony_ci#define TCSTATUS_RNST		(_ULCAST_(3) << TCSTATUS_RNST_SHIFT)
15862306a36Sopenharmony_ci/* Codes for RNST */
15962306a36Sopenharmony_ci#define TC_RUNNING		0
16062306a36Sopenharmony_ci#define TC_WAITING		1
16162306a36Sopenharmony_ci#define TC_YIELDING		2
16262306a36Sopenharmony_ci#define TC_GATED		3
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#define TCSTATUS_TMX_SHIFT	27
16562306a36Sopenharmony_ci#define TCSTATUS_TMX		(_ULCAST_(1) << TCSTATUS_TMX_SHIFT)
16662306a36Sopenharmony_ci/* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci/* TCBind */
16962306a36Sopenharmony_ci#define TCBIND_CURVPE_SHIFT	0
17062306a36Sopenharmony_ci#define TCBIND_CURVPE		(_ULCAST_(0xf))
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci#define TCBIND_CURTC_SHIFT	21
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci#define TCBIND_CURTC		(_ULCAST_(0xff) << TCBIND_CURTC_SHIFT)
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci/* TCHalt */
17762306a36Sopenharmony_ci#define TCHALT_H		(_ULCAST_(1))
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci#ifndef __ASSEMBLY__
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic inline unsigned core_nvpes(void)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	unsigned conf0;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	if (!cpu_has_mipsmt)
18662306a36Sopenharmony_ci		return 1;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	conf0 = read_c0_mvpconf0();
18962306a36Sopenharmony_ci	return ((conf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
19062306a36Sopenharmony_ci}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistatic inline unsigned int dvpe(void)
19362306a36Sopenharmony_ci{
19462306a36Sopenharmony_ci	int res = 0;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	__asm__ __volatile__(
19762306a36Sopenharmony_ci	"	.set	push						\n"
19862306a36Sopenharmony_ci	"	.set	noreorder					\n"
19962306a36Sopenharmony_ci	"	.set	noat						\n"
20062306a36Sopenharmony_ci	"	.set	mips32r2					\n"
20162306a36Sopenharmony_ci	"	.word	0x41610001		# dvpe $1		\n"
20262306a36Sopenharmony_ci	"	move	%0, $1						\n"
20362306a36Sopenharmony_ci	"	ehb							\n"
20462306a36Sopenharmony_ci	"	.set	pop						\n"
20562306a36Sopenharmony_ci	: "=r" (res));
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	instruction_hazard();
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	return res;
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistatic inline void __raw_evpe(void)
21362306a36Sopenharmony_ci{
21462306a36Sopenharmony_ci	__asm__ __volatile__(
21562306a36Sopenharmony_ci	"	.set	push						\n"
21662306a36Sopenharmony_ci	"	.set	noreorder					\n"
21762306a36Sopenharmony_ci	"	.set	noat						\n"
21862306a36Sopenharmony_ci	"	.set	mips32r2					\n"
21962306a36Sopenharmony_ci	"	.word	0x41600021		# evpe			\n"
22062306a36Sopenharmony_ci	"	ehb							\n"
22162306a36Sopenharmony_ci	"	.set	pop						\n");
22262306a36Sopenharmony_ci}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci/* Enable virtual processor execution if previous suggested it should be.
22562306a36Sopenharmony_ci   EVPE_ENABLE to force */
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci#define EVPE_ENABLE MVPCONTROL_EVP
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic inline void evpe(int previous)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	if ((previous & MVPCONTROL_EVP))
23262306a36Sopenharmony_ci		__raw_evpe();
23362306a36Sopenharmony_ci}
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cistatic inline unsigned int dmt(void)
23662306a36Sopenharmony_ci{
23762306a36Sopenharmony_ci	int res;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	__asm__ __volatile__(
24062306a36Sopenharmony_ci	"	.set	push						\n"
24162306a36Sopenharmony_ci	"	.set	mips32r2					\n"
24262306a36Sopenharmony_ci	"	.set	noat						\n"
24362306a36Sopenharmony_ci	"	.word	0x41610BC1			# dmt $1	\n"
24462306a36Sopenharmony_ci	"	ehb							\n"
24562306a36Sopenharmony_ci	"	move	%0, $1						\n"
24662306a36Sopenharmony_ci	"	.set	pop						\n"
24762306a36Sopenharmony_ci	: "=r" (res));
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	instruction_hazard();
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	return res;
25262306a36Sopenharmony_ci}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic inline void __raw_emt(void)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	__asm__ __volatile__(
25762306a36Sopenharmony_ci	"	.set	push						\n"
25862306a36Sopenharmony_ci	"	.set	noreorder					\n"
25962306a36Sopenharmony_ci	"	.set	mips32r2					\n"
26062306a36Sopenharmony_ci	"	.word	0x41600be1			# emt		\n"
26162306a36Sopenharmony_ci	"	ehb							\n"
26262306a36Sopenharmony_ci	"	.set	pop");
26362306a36Sopenharmony_ci}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/* enable multi-threaded execution if previous suggested it should be.
26662306a36Sopenharmony_ci   EMT_ENABLE to force */
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci#define EMT_ENABLE VPECONTROL_TE
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistatic inline void emt(int previous)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	if ((previous & EMT_ENABLE))
27362306a36Sopenharmony_ci		__raw_emt();
27462306a36Sopenharmony_ci}
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistatic inline void ehb(void)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	__asm__ __volatile__(
27962306a36Sopenharmony_ci	"	.set	push					\n"
28062306a36Sopenharmony_ci	"	.set	mips32r2				\n"
28162306a36Sopenharmony_ci	"	ehb						\n"
28262306a36Sopenharmony_ci	"	.set	pop					\n");
28362306a36Sopenharmony_ci}
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci#define mftc0(rt,sel)							\
28662306a36Sopenharmony_ci({									\
28762306a36Sopenharmony_ci	 unsigned long	__res;						\
28862306a36Sopenharmony_ci									\
28962306a36Sopenharmony_ci	__asm__ __volatile__(						\
29062306a36Sopenharmony_ci	"	.set	push					\n"	\
29162306a36Sopenharmony_ci	"	.set	mips32r2				\n"	\
29262306a36Sopenharmony_ci	"	.set	noat					\n"	\
29362306a36Sopenharmony_ci	"	# mftc0 $1, $" #rt ", " #sel "			\n"	\
29462306a36Sopenharmony_ci	"	.word	0x41000800 | (" #rt " << 16) | " #sel " \n"	\
29562306a36Sopenharmony_ci	"	move	%0, $1					\n"	\
29662306a36Sopenharmony_ci	"	.set	pop					\n"	\
29762306a36Sopenharmony_ci	: "=r" (__res));						\
29862306a36Sopenharmony_ci									\
29962306a36Sopenharmony_ci	__res;								\
30062306a36Sopenharmony_ci})
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci#define mftgpr(rt)							\
30362306a36Sopenharmony_ci({									\
30462306a36Sopenharmony_ci	unsigned long __res;						\
30562306a36Sopenharmony_ci									\
30662306a36Sopenharmony_ci	__asm__ __volatile__(						\
30762306a36Sopenharmony_ci	"	.set	push					\n"	\
30862306a36Sopenharmony_ci	"	.set	noat					\n"	\
30962306a36Sopenharmony_ci	"	.set	mips32r2				\n"	\
31062306a36Sopenharmony_ci	"	# mftgpr $1," #rt "				\n"	\
31162306a36Sopenharmony_ci	"	.word	0x41000820 | (" #rt " << 16)		\n"	\
31262306a36Sopenharmony_ci	"	move	%0, $1					\n"	\
31362306a36Sopenharmony_ci	"	.set	pop					\n"	\
31462306a36Sopenharmony_ci	: "=r" (__res));						\
31562306a36Sopenharmony_ci									\
31662306a36Sopenharmony_ci	__res;								\
31762306a36Sopenharmony_ci})
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci#define mftr(rt, u, sel)							\
32062306a36Sopenharmony_ci({									\
32162306a36Sopenharmony_ci	unsigned long __res;						\
32262306a36Sopenharmony_ci									\
32362306a36Sopenharmony_ci	__asm__ __volatile__(						\
32462306a36Sopenharmony_ci	"	mftr	%0, " #rt ", " #u ", " #sel "		\n"	\
32562306a36Sopenharmony_ci	: "=r" (__res));						\
32662306a36Sopenharmony_ci									\
32762306a36Sopenharmony_ci	__res;								\
32862306a36Sopenharmony_ci})
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci#define mttgpr(rd,v)							\
33162306a36Sopenharmony_cido {									\
33262306a36Sopenharmony_ci	__asm__ __volatile__(						\
33362306a36Sopenharmony_ci	"	.set	push					\n"	\
33462306a36Sopenharmony_ci	"	.set	mips32r2				\n"	\
33562306a36Sopenharmony_ci	"	.set	noat					\n"	\
33662306a36Sopenharmony_ci	"	move	$1, %0					\n"	\
33762306a36Sopenharmony_ci	"	# mttgpr $1, " #rd "				\n"	\
33862306a36Sopenharmony_ci	"	.word	0x41810020 | (" #rd " << 11)		\n"	\
33962306a36Sopenharmony_ci	"	.set	pop					\n"	\
34062306a36Sopenharmony_ci	: : "r" (v));							\
34162306a36Sopenharmony_ci} while (0)
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci#define mttc0(rd, sel, v)							\
34462306a36Sopenharmony_ci({									\
34562306a36Sopenharmony_ci	__asm__ __volatile__(						\
34662306a36Sopenharmony_ci	"	.set	push					\n"	\
34762306a36Sopenharmony_ci	"	.set	mips32r2				\n"	\
34862306a36Sopenharmony_ci	"	.set	noat					\n"	\
34962306a36Sopenharmony_ci	"	move	$1, %0					\n"	\
35062306a36Sopenharmony_ci	"	# mttc0 %0," #rd ", " #sel "			\n"	\
35162306a36Sopenharmony_ci	"	.word	0x41810000 | (" #rd " << 11) | " #sel " \n"	\
35262306a36Sopenharmony_ci	"	.set	pop					\n"	\
35362306a36Sopenharmony_ci	:								\
35462306a36Sopenharmony_ci	: "r" (v));							\
35562306a36Sopenharmony_ci})
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci#define mttr(rd, u, sel, v)						\
35962306a36Sopenharmony_ci({									\
36062306a36Sopenharmony_ci	__asm__ __volatile__(						\
36162306a36Sopenharmony_ci	"mttr	%0," #rd ", " #u ", " #sel				\
36262306a36Sopenharmony_ci	: : "r" (v));							\
36362306a36Sopenharmony_ci})
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci#define settc(tc)							\
36762306a36Sopenharmony_cido {									\
36862306a36Sopenharmony_ci	write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \
36962306a36Sopenharmony_ci	ehb();								\
37062306a36Sopenharmony_ci} while (0)
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci/* you *must* set the target tc (settc) before trying to use these */
37462306a36Sopenharmony_ci#define read_vpe_c0_vpecontrol()	mftc0(1, 1)
37562306a36Sopenharmony_ci#define write_vpe_c0_vpecontrol(val)	mttc0(1, 1, val)
37662306a36Sopenharmony_ci#define read_vpe_c0_vpeconf0()		mftc0(1, 2)
37762306a36Sopenharmony_ci#define write_vpe_c0_vpeconf0(val)	mttc0(1, 2, val)
37862306a36Sopenharmony_ci#define read_vpe_c0_vpeconf1()		mftc0(1, 3)
37962306a36Sopenharmony_ci#define write_vpe_c0_vpeconf1(val)	mttc0(1, 3, val)
38062306a36Sopenharmony_ci#define read_vpe_c0_count()		mftc0(9, 0)
38162306a36Sopenharmony_ci#define write_vpe_c0_count(val)		mttc0(9, 0, val)
38262306a36Sopenharmony_ci#define read_vpe_c0_status()		mftc0(12, 0)
38362306a36Sopenharmony_ci#define write_vpe_c0_status(val)	mttc0(12, 0, val)
38462306a36Sopenharmony_ci#define read_vpe_c0_cause()		mftc0(13, 0)
38562306a36Sopenharmony_ci#define write_vpe_c0_cause(val)		mttc0(13, 0, val)
38662306a36Sopenharmony_ci#define read_vpe_c0_config()		mftc0(16, 0)
38762306a36Sopenharmony_ci#define write_vpe_c0_config(val)	mttc0(16, 0, val)
38862306a36Sopenharmony_ci#define read_vpe_c0_config1()		mftc0(16, 1)
38962306a36Sopenharmony_ci#define write_vpe_c0_config1(val)	mttc0(16, 1, val)
39062306a36Sopenharmony_ci#define read_vpe_c0_config7()		mftc0(16, 7)
39162306a36Sopenharmony_ci#define write_vpe_c0_config7(val)	mttc0(16, 7, val)
39262306a36Sopenharmony_ci#define read_vpe_c0_ebase()		mftc0(15, 1)
39362306a36Sopenharmony_ci#define write_vpe_c0_ebase(val)		mttc0(15, 1, val)
39462306a36Sopenharmony_ci#define write_vpe_c0_compare(val)	mttc0(11, 0, val)
39562306a36Sopenharmony_ci#define read_vpe_c0_badvaddr()		mftc0(8, 0)
39662306a36Sopenharmony_ci#define read_vpe_c0_epc()		mftc0(14, 0)
39762306a36Sopenharmony_ci#define write_vpe_c0_epc(val)		mttc0(14, 0, val)
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci/* TC */
40162306a36Sopenharmony_ci#define read_tc_c0_tcstatus()		mftc0(2, 1)
40262306a36Sopenharmony_ci#define write_tc_c0_tcstatus(val)	mttc0(2, 1, val)
40362306a36Sopenharmony_ci#define read_tc_c0_tcbind()		mftc0(2, 2)
40462306a36Sopenharmony_ci#define write_tc_c0_tcbind(val)		mttc0(2, 2, val)
40562306a36Sopenharmony_ci#define read_tc_c0_tcrestart()		mftc0(2, 3)
40662306a36Sopenharmony_ci#define write_tc_c0_tcrestart(val)	mttc0(2, 3, val)
40762306a36Sopenharmony_ci#define read_tc_c0_tchalt()		mftc0(2, 4)
40862306a36Sopenharmony_ci#define write_tc_c0_tchalt(val)		mttc0(2, 4, val)
40962306a36Sopenharmony_ci#define read_tc_c0_tccontext()		mftc0(2, 5)
41062306a36Sopenharmony_ci#define write_tc_c0_tccontext(val)	mttc0(2, 5, val)
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci/* GPR */
41362306a36Sopenharmony_ci#define read_tc_gpr_sp()		mftgpr(29)
41462306a36Sopenharmony_ci#define write_tc_gpr_sp(val)		mttgpr(29, val)
41562306a36Sopenharmony_ci#define read_tc_gpr_gp()		mftgpr(28)
41662306a36Sopenharmony_ci#define write_tc_gpr_gp(val)		mttgpr(28, val)
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci__BUILD_SET_C0(mvpcontrol)
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci#endif /* Not __ASSEMBLY__ */
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci#endif
423