18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __ALPHA_PAL_H
38c2ecf20Sopenharmony_ci#define __ALPHA_PAL_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <uapi/asm/pal.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ciextern void halt(void) __attribute__((noreturn));
108c2ecf20Sopenharmony_ci#define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define imb() \
138c2ecf20Sopenharmony_ci__asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory")
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define draina() \
168c2ecf20Sopenharmony_ci__asm__ __volatile__ ("call_pal %0 #draina" : : "i" (PAL_draina) : "memory")
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define __CALL_PAL_R0(NAME, TYPE)				\
198c2ecf20Sopenharmony_ciextern inline TYPE NAME(void)					\
208c2ecf20Sopenharmony_ci{								\
218c2ecf20Sopenharmony_ci	register TYPE __r0 __asm__("$0");			\
228c2ecf20Sopenharmony_ci	__asm__ __volatile__(					\
238c2ecf20Sopenharmony_ci		"call_pal %1 # " #NAME				\
248c2ecf20Sopenharmony_ci		:"=r" (__r0)					\
258c2ecf20Sopenharmony_ci		:"i" (PAL_ ## NAME)				\
268c2ecf20Sopenharmony_ci		:"$1", "$16", "$22", "$23", "$24", "$25");	\
278c2ecf20Sopenharmony_ci	return __r0;						\
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define __CALL_PAL_W1(NAME, TYPE0)				\
318c2ecf20Sopenharmony_ciextern inline void NAME(TYPE0 arg0)				\
328c2ecf20Sopenharmony_ci{								\
338c2ecf20Sopenharmony_ci	register TYPE0 __r16 __asm__("$16") = arg0;		\
348c2ecf20Sopenharmony_ci	__asm__ __volatile__(					\
358c2ecf20Sopenharmony_ci		"call_pal %1 # "#NAME				\
368c2ecf20Sopenharmony_ci		: "=r"(__r16)					\
378c2ecf20Sopenharmony_ci		: "i"(PAL_ ## NAME), "0"(__r16)			\
388c2ecf20Sopenharmony_ci		: "$1", "$22", "$23", "$24", "$25");		\
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define __CALL_PAL_W2(NAME, TYPE0, TYPE1)			\
428c2ecf20Sopenharmony_ciextern inline void NAME(TYPE0 arg0, TYPE1 arg1)			\
438c2ecf20Sopenharmony_ci{								\
448c2ecf20Sopenharmony_ci	register TYPE0 __r16 __asm__("$16") = arg0;		\
458c2ecf20Sopenharmony_ci	register TYPE1 __r17 __asm__("$17") = arg1;		\
468c2ecf20Sopenharmony_ci	__asm__ __volatile__(					\
478c2ecf20Sopenharmony_ci		"call_pal %2 # "#NAME				\
488c2ecf20Sopenharmony_ci		: "=r"(__r16), "=r"(__r17)			\
498c2ecf20Sopenharmony_ci		: "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17)	\
508c2ecf20Sopenharmony_ci		: "$1", "$22", "$23", "$24", "$25");		\
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define __CALL_PAL_RW1(NAME, RTYPE, TYPE0)			\
548c2ecf20Sopenharmony_ciextern inline RTYPE NAME(TYPE0 arg0)				\
558c2ecf20Sopenharmony_ci{								\
568c2ecf20Sopenharmony_ci	register RTYPE __r0 __asm__("$0");			\
578c2ecf20Sopenharmony_ci	register TYPE0 __r16 __asm__("$16") = arg0;		\
588c2ecf20Sopenharmony_ci	__asm__ __volatile__(					\
598c2ecf20Sopenharmony_ci		"call_pal %2 # "#NAME				\
608c2ecf20Sopenharmony_ci		: "=r"(__r16), "=r"(__r0)			\
618c2ecf20Sopenharmony_ci		: "i"(PAL_ ## NAME), "0"(__r16)			\
628c2ecf20Sopenharmony_ci		: "$1", "$22", "$23", "$24", "$25");		\
638c2ecf20Sopenharmony_ci	return __r0;						\
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1)		\
678c2ecf20Sopenharmony_ciextern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1)		\
688c2ecf20Sopenharmony_ci{								\
698c2ecf20Sopenharmony_ci	register RTYPE __r0 __asm__("$0");			\
708c2ecf20Sopenharmony_ci	register TYPE0 __r16 __asm__("$16") = arg0;		\
718c2ecf20Sopenharmony_ci	register TYPE1 __r17 __asm__("$17") = arg1;		\
728c2ecf20Sopenharmony_ci	__asm__ __volatile__(					\
738c2ecf20Sopenharmony_ci		"call_pal %3 # "#NAME				\
748c2ecf20Sopenharmony_ci		: "=r"(__r16), "=r"(__r17), "=r"(__r0)		\
758c2ecf20Sopenharmony_ci		: "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17)	\
768c2ecf20Sopenharmony_ci		: "$1", "$22", "$23", "$24", "$25");		\
778c2ecf20Sopenharmony_ci	return __r0;						\
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci__CALL_PAL_W1(cflush, unsigned long);
818c2ecf20Sopenharmony_ci__CALL_PAL_R0(rdmces, unsigned long);
828c2ecf20Sopenharmony_ci__CALL_PAL_R0(rdps, unsigned long);
838c2ecf20Sopenharmony_ci__CALL_PAL_R0(rdusp, unsigned long);
848c2ecf20Sopenharmony_ci__CALL_PAL_RW1(swpipl, unsigned long, unsigned long);
858c2ecf20Sopenharmony_ci__CALL_PAL_R0(whami, unsigned long);
868c2ecf20Sopenharmony_ci__CALL_PAL_W2(wrent, void*, unsigned long);
878c2ecf20Sopenharmony_ci__CALL_PAL_W1(wripir, unsigned long);
888c2ecf20Sopenharmony_ci__CALL_PAL_W1(wrkgp, unsigned long);
898c2ecf20Sopenharmony_ci__CALL_PAL_W1(wrmces, unsigned long);
908c2ecf20Sopenharmony_ci__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
918c2ecf20Sopenharmony_ci__CALL_PAL_W1(wrusp, unsigned long);
928c2ecf20Sopenharmony_ci__CALL_PAL_W1(wrvptptr, unsigned long);
938c2ecf20Sopenharmony_ci__CALL_PAL_RW1(wtint, unsigned long, unsigned long);
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/*
968c2ecf20Sopenharmony_ci * TB routines..
978c2ecf20Sopenharmony_ci */
988c2ecf20Sopenharmony_ci#define __tbi(nr,arg,arg1...)					\
998c2ecf20Sopenharmony_ci({								\
1008c2ecf20Sopenharmony_ci	register unsigned long __r16 __asm__("$16") = (nr);	\
1018c2ecf20Sopenharmony_ci	register unsigned long __r17 __asm__("$17"); arg;	\
1028c2ecf20Sopenharmony_ci	__asm__ __volatile__(					\
1038c2ecf20Sopenharmony_ci		"call_pal %3 #__tbi"				\
1048c2ecf20Sopenharmony_ci		:"=r" (__r16),"=r" (__r17)			\
1058c2ecf20Sopenharmony_ci		:"0" (__r16),"i" (PAL_tbi) ,##arg1		\
1068c2ecf20Sopenharmony_ci		:"$0", "$1", "$22", "$23", "$24", "$25");	\
1078c2ecf20Sopenharmony_ci})
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci#define tbi(x,y)	__tbi(x,__r17=(y),"1" (__r17))
1108c2ecf20Sopenharmony_ci#define tbisi(x)	__tbi(1,__r17=(x),"1" (__r17))
1118c2ecf20Sopenharmony_ci#define tbisd(x)	__tbi(2,__r17=(x),"1" (__r17))
1128c2ecf20Sopenharmony_ci#define tbis(x)		__tbi(3,__r17=(x),"1" (__r17))
1138c2ecf20Sopenharmony_ci#define tbiap()		__tbi(-1, /* no second argument */)
1148c2ecf20Sopenharmony_ci#define tbia()		__tbi(-2, /* no second argument */)
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/*
1178c2ecf20Sopenharmony_ci * QEMU Cserv routines..
1188c2ecf20Sopenharmony_ci */
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistatic inline unsigned long
1218c2ecf20Sopenharmony_ciqemu_get_walltime(void)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	register unsigned long v0 __asm__("$0");
1248c2ecf20Sopenharmony_ci	register unsigned long a0 __asm__("$16") = 3;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	asm("call_pal %2 # cserve get_time"
1278c2ecf20Sopenharmony_ci	    : "=r"(v0), "+r"(a0)
1288c2ecf20Sopenharmony_ci	    : "i"(PAL_cserve)
1298c2ecf20Sopenharmony_ci	    : "$17", "$18", "$19", "$20", "$21");
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	return v0;
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cistatic inline unsigned long
1358c2ecf20Sopenharmony_ciqemu_get_alarm(void)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	register unsigned long v0 __asm__("$0");
1388c2ecf20Sopenharmony_ci	register unsigned long a0 __asm__("$16") = 4;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	asm("call_pal %2 # cserve get_alarm"
1418c2ecf20Sopenharmony_ci	    : "=r"(v0), "+r"(a0)
1428c2ecf20Sopenharmony_ci	    : "i"(PAL_cserve)
1438c2ecf20Sopenharmony_ci	    : "$17", "$18", "$19", "$20", "$21");
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	return v0;
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic inline void
1498c2ecf20Sopenharmony_ciqemu_set_alarm_rel(unsigned long expire)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	register unsigned long a0 __asm__("$16") = 5;
1528c2ecf20Sopenharmony_ci	register unsigned long a1 __asm__("$17") = expire;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	asm volatile("call_pal %2 # cserve set_alarm_rel"
1558c2ecf20Sopenharmony_ci		     : "+r"(a0), "+r"(a1)
1568c2ecf20Sopenharmony_ci		     : "i"(PAL_cserve)
1578c2ecf20Sopenharmony_ci		     : "$0", "$18", "$19", "$20", "$21");
1588c2ecf20Sopenharmony_ci}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistatic inline void
1618c2ecf20Sopenharmony_ciqemu_set_alarm_abs(unsigned long expire)
1628c2ecf20Sopenharmony_ci{
1638c2ecf20Sopenharmony_ci	register unsigned long a0 __asm__("$16") = 6;
1648c2ecf20Sopenharmony_ci	register unsigned long a1 __asm__("$17") = expire;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	asm volatile("call_pal %2 # cserve set_alarm_abs"
1678c2ecf20Sopenharmony_ci		     : "+r"(a0), "+r"(a1)
1688c2ecf20Sopenharmony_ci		     : "i"(PAL_cserve)
1698c2ecf20Sopenharmony_ci		     : "$0", "$18", "$19", "$20", "$21");
1708c2ecf20Sopenharmony_ci}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_cistatic inline unsigned long
1738c2ecf20Sopenharmony_ciqemu_get_vmtime(void)
1748c2ecf20Sopenharmony_ci{
1758c2ecf20Sopenharmony_ci	register unsigned long v0 __asm__("$0");
1768c2ecf20Sopenharmony_ci	register unsigned long a0 __asm__("$16") = 7;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	asm("call_pal %2 # cserve get_time"
1798c2ecf20Sopenharmony_ci	    : "=r"(v0), "+r"(a0)
1808c2ecf20Sopenharmony_ci	    : "i"(PAL_cserve)
1818c2ecf20Sopenharmony_ci	    : "$17", "$18", "$19", "$20", "$21");
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	return v0;
1848c2ecf20Sopenharmony_ci}
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */
1878c2ecf20Sopenharmony_ci#endif /* __ALPHA_PAL_H */
188