xref: /linux/arch/alpha/include/asm/pal.h (revision cc04a46f11ea046ed53e2c832ae29e4790f7e35f)
1 #ifndef __ALPHA_PAL_H
2 #define __ALPHA_PAL_H
3 
4 #include <uapi/asm/pal.h>
5 
6 #ifndef __ASSEMBLY__
7 
8 extern void halt(void) __attribute__((noreturn));
9 #define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
10 
11 #define imb() \
12 __asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory")
13 
14 #define draina() \
15 __asm__ __volatile__ ("call_pal %0 #draina" : : "i" (PAL_draina) : "memory")
16 
17 #define __CALL_PAL_R0(NAME, TYPE)				\
18 extern inline TYPE NAME(void)					\
19 {								\
20 	register TYPE __r0 __asm__("$0");			\
21 	__asm__ __volatile__(					\
22 		"call_pal %1 # " #NAME				\
23 		:"=r" (__r0)					\
24 		:"i" (PAL_ ## NAME)				\
25 		:"$1", "$16", "$22", "$23", "$24", "$25");	\
26 	return __r0;						\
27 }
28 
29 #define __CALL_PAL_W1(NAME, TYPE0)				\
30 extern inline void NAME(TYPE0 arg0)				\
31 {								\
32 	register TYPE0 __r16 __asm__("$16") = arg0;		\
33 	__asm__ __volatile__(					\
34 		"call_pal %1 # "#NAME				\
35 		: "=r"(__r16)					\
36 		: "i"(PAL_ ## NAME), "0"(__r16)			\
37 		: "$1", "$22", "$23", "$24", "$25");		\
38 }
39 
40 #define __CALL_PAL_W2(NAME, TYPE0, TYPE1)			\
41 extern inline void NAME(TYPE0 arg0, TYPE1 arg1)			\
42 {								\
43 	register TYPE0 __r16 __asm__("$16") = arg0;		\
44 	register TYPE1 __r17 __asm__("$17") = arg1;		\
45 	__asm__ __volatile__(					\
46 		"call_pal %2 # "#NAME				\
47 		: "=r"(__r16), "=r"(__r17)			\
48 		: "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17)	\
49 		: "$1", "$22", "$23", "$24", "$25");		\
50 }
51 
52 #define __CALL_PAL_RW1(NAME, RTYPE, TYPE0)			\
53 extern inline RTYPE NAME(TYPE0 arg0)				\
54 {								\
55 	register RTYPE __r0 __asm__("$0");			\
56 	register TYPE0 __r16 __asm__("$16") = arg0;		\
57 	__asm__ __volatile__(					\
58 		"call_pal %2 # "#NAME				\
59 		: "=r"(__r16), "=r"(__r0)			\
60 		: "i"(PAL_ ## NAME), "0"(__r16)			\
61 		: "$1", "$22", "$23", "$24", "$25");		\
62 	return __r0;						\
63 }
64 
65 #define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1)		\
66 extern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1)		\
67 {								\
68 	register RTYPE __r0 __asm__("$0");			\
69 	register TYPE0 __r16 __asm__("$16") = arg0;		\
70 	register TYPE1 __r17 __asm__("$17") = arg1;		\
71 	__asm__ __volatile__(					\
72 		"call_pal %3 # "#NAME				\
73 		: "=r"(__r16), "=r"(__r17), "=r"(__r0)		\
74 		: "i"(PAL_ ## NAME), "0"(__r16), "1"(__r17)	\
75 		: "$1", "$22", "$23", "$24", "$25");		\
76 	return __r0;						\
77 }
78 
79 __CALL_PAL_W1(cflush, unsigned long);
80 __CALL_PAL_R0(rdmces, unsigned long);
81 __CALL_PAL_R0(rdps, unsigned long);
82 __CALL_PAL_R0(rdusp, unsigned long);
83 __CALL_PAL_RW1(swpipl, unsigned long, unsigned long);
84 __CALL_PAL_R0(whami, unsigned long);
85 __CALL_PAL_W2(wrent, void*, unsigned long);
86 __CALL_PAL_W1(wripir, unsigned long);
87 __CALL_PAL_W1(wrkgp, unsigned long);
88 __CALL_PAL_W1(wrmces, unsigned long);
89 __CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
90 __CALL_PAL_W1(wrusp, unsigned long);
91 __CALL_PAL_W1(wrvptptr, unsigned long);
92 __CALL_PAL_RW1(wtint, unsigned long, unsigned long);
93 
94 /*
95  * TB routines..
96  */
97 #define __tbi(nr,arg,arg1...)					\
98 ({								\
99 	register unsigned long __r16 __asm__("$16") = (nr);	\
100 	register unsigned long __r17 __asm__("$17"); arg;	\
101 	__asm__ __volatile__(					\
102 		"call_pal %3 #__tbi"				\
103 		:"=r" (__r16),"=r" (__r17)			\
104 		:"0" (__r16),"i" (PAL_tbi) ,##arg1		\
105 		:"$0", "$1", "$22", "$23", "$24", "$25");	\
106 })
107 
108 #define tbi(x,y)	__tbi(x,__r17=(y),"1" (__r17))
109 #define tbisi(x)	__tbi(1,__r17=(x),"1" (__r17))
110 #define tbisd(x)	__tbi(2,__r17=(x),"1" (__r17))
111 #define tbis(x)		__tbi(3,__r17=(x),"1" (__r17))
112 #define tbiap()		__tbi(-1, /* no second argument */)
113 #define tbia()		__tbi(-2, /* no second argument */)
114 
115 /*
116  * QEMU Cserv routines..
117  */
118 
119 static inline unsigned long
120 qemu_get_walltime(void)
121 {
122 	register unsigned long v0 __asm__("$0");
123 	register unsigned long a0 __asm__("$16") = 3;
124 
125 	asm("call_pal %2 # cserve get_time"
126 	    : "=r"(v0), "+r"(a0)
127 	    : "i"(PAL_cserve)
128 	    : "$17", "$18", "$19", "$20", "$21");
129 
130 	return v0;
131 }
132 
133 static inline unsigned long
134 qemu_get_alarm(void)
135 {
136 	register unsigned long v0 __asm__("$0");
137 	register unsigned long a0 __asm__("$16") = 4;
138 
139 	asm("call_pal %2 # cserve get_alarm"
140 	    : "=r"(v0), "+r"(a0)
141 	    : "i"(PAL_cserve)
142 	    : "$17", "$18", "$19", "$20", "$21");
143 
144 	return v0;
145 }
146 
147 static inline void
148 qemu_set_alarm_rel(unsigned long expire)
149 {
150 	register unsigned long a0 __asm__("$16") = 5;
151 	register unsigned long a1 __asm__("$17") = expire;
152 
153 	asm volatile("call_pal %2 # cserve set_alarm_rel"
154 		     : "+r"(a0), "+r"(a1)
155 		     : "i"(PAL_cserve)
156 		     : "$0", "$18", "$19", "$20", "$21");
157 }
158 
159 static inline void
160 qemu_set_alarm_abs(unsigned long expire)
161 {
162 	register unsigned long a0 __asm__("$16") = 6;
163 	register unsigned long a1 __asm__("$17") = expire;
164 
165 	asm volatile("call_pal %2 # cserve set_alarm_abs"
166 		     : "+r"(a0), "+r"(a1)
167 		     : "i"(PAL_cserve)
168 		     : "$0", "$18", "$19", "$20", "$21");
169 }
170 
171 static inline unsigned long
172 qemu_get_vmtime(void)
173 {
174 	register unsigned long v0 __asm__("$0");
175 	register unsigned long a0 __asm__("$16") = 7;
176 
177 	asm("call_pal %2 # cserve get_time"
178 	    : "=r"(v0), "+r"(a0)
179 	    : "i"(PAL_cserve)
180 	    : "$17", "$18", "$19", "$20", "$21");
181 
182 	return v0;
183 }
184 
185 #endif /* !__ASSEMBLY__ */
186 #endif /* __ALPHA_PAL_H */
187