Linux Audio

Check our new training course

Loading...
  1#ifndef _PSERIES_PLPAR_WRAPPERS_H
  2#define _PSERIES_PLPAR_WRAPPERS_H
  3
  4#include <linux/string.h>
  5
  6#include <asm/hvcall.h>
  7#include <asm/paca.h>
  8#include <asm/page.h>
  9
 10/* Get state of physical CPU from query_cpu_stopped */
 11int smp_query_cpu_stopped(unsigned int pcpu);
 12#define QCSS_STOPPED 0
 13#define QCSS_STOPPING 1
 14#define QCSS_NOT_STOPPED 2
 15#define QCSS_HARDWARE_ERROR -1
 16#define QCSS_HARDWARE_BUSY -2
 17
 18static inline long poll_pending(void)
 19{
 20	return plpar_hcall_norets(H_POLL_PENDING);
 21}
 22
 23static inline u8 get_cede_latency_hint(void)
 24{
 25	return get_lppaca()->cede_latency_hint;
 26}
 27
 28static inline void set_cede_latency_hint(u8 latency_hint)
 29{
 30	get_lppaca()->cede_latency_hint = latency_hint;
 31}
 32
 33static inline long cede_processor(void)
 34{
 35	return plpar_hcall_norets(H_CEDE);
 36}
 37
 38static inline long extended_cede_processor(unsigned long latency_hint)
 39{
 40	long rc;
 41	u8 old_latency_hint = get_cede_latency_hint();
 42
 43	set_cede_latency_hint(latency_hint);
 44	rc = cede_processor();
 45	set_cede_latency_hint(old_latency_hint);
 46
 47	return rc;
 48}
 49
 50static inline long vpa_call(unsigned long flags, unsigned long cpu,
 51		unsigned long vpa)
 52{
 53	/* flags are in bits 16-18 (counting from most significant bit) */
 54	flags = flags << (63 - 18);
 55
 56	return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
 57}
 58
 59static inline long unregister_vpa(unsigned long cpu)
 60{
 61	return vpa_call(0x5, cpu, 0);
 62}
 63
 64static inline long register_vpa(unsigned long cpu, unsigned long vpa)
 65{
 66	return vpa_call(0x1, cpu, vpa);
 67}
 68
 69static inline long unregister_slb_shadow(unsigned long cpu)
 70{
 71	return vpa_call(0x7, cpu, 0);
 72}
 73
 74static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
 75{
 76	return vpa_call(0x3, cpu, vpa);
 77}
 78
 79static inline long unregister_dtl(unsigned long cpu)
 80{
 81	return vpa_call(0x6, cpu, 0);
 82}
 83
 84static inline long register_dtl(unsigned long cpu, unsigned long vpa)
 85{
 86	return vpa_call(0x2, cpu, vpa);
 87}
 88
 89static inline long plpar_page_set_loaned(unsigned long vpa)
 90{
 91	unsigned long cmo_page_sz = cmo_get_page_size();
 92	long rc = 0;
 93	int i;
 94
 95	for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
 96		rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0);
 97
 98	for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
 99		plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE,
100				   vpa + i - cmo_page_sz, 0);
101
102	return rc;
103}
104
105static inline long plpar_page_set_active(unsigned long vpa)
106{
107	unsigned long cmo_page_sz = cmo_get_page_size();
108	long rc = 0;
109	int i;
110
111	for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
112		rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0);
113
114	for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
115		plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED,
116				   vpa + i - cmo_page_sz, 0);
117
118	return rc;
119}
120
121extern void vpa_init(int cpu);
122
123static inline long plpar_pte_enter(unsigned long flags,
124		unsigned long hpte_group, unsigned long hpte_v,
125		unsigned long hpte_r, unsigned long *slot)
126{
127	long rc;
128	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
129
130	rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
131
132	*slot = retbuf[0];
133
134	return rc;
135}
136
137static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
138		unsigned long avpn, unsigned long *old_pteh_ret,
139		unsigned long *old_ptel_ret)
140{
141	long rc;
142	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
143
144	rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
145
146	*old_pteh_ret = retbuf[0];
147	*old_ptel_ret = retbuf[1];
148
149	return rc;
150}
151
152/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
153static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
154		unsigned long avpn, unsigned long *old_pteh_ret,
155		unsigned long *old_ptel_ret)
156{
157	long rc;
158	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
159
160	rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
161
162	*old_pteh_ret = retbuf[0];
163	*old_ptel_ret = retbuf[1];
164
165	return rc;
166}
167
168static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
169		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
170{
171	long rc;
172	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
173
174	rc = plpar_hcall(H_READ, retbuf, flags, ptex);
175
176	*old_pteh_ret = retbuf[0];
177	*old_ptel_ret = retbuf[1];
178
179	return rc;
180}
181
182/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
183static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
184		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
185{
186	long rc;
187	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
188
189	rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
190
191	*old_pteh_ret = retbuf[0];
192	*old_ptel_ret = retbuf[1];
193
194	return rc;
195}
196
197/*
198 * plpar_pte_read_4_raw can be called in real mode.
199 * ptes must be 8*sizeof(unsigned long)
200 */
201static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
202					unsigned long *ptes)
203
204{
205	long rc;
206	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
207
208	rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
209
210	memcpy(ptes, retbuf, 8*sizeof(unsigned long));
211
212	return rc;
213}
214
215static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
216		unsigned long avpn)
217{
218	return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
219}
220
221static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
222		unsigned long *tce_ret)
223{
224	long rc;
225	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
226
227	rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
228
229	*tce_ret = retbuf[0];
230
231	return rc;
232}
233
234static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
235		unsigned long tceval)
236{
237	return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
238}
239
240static inline long plpar_tce_put_indirect(unsigned long liobn,
241		unsigned long ioba, unsigned long page, unsigned long count)
242{
243	return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
244}
245
246static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
247		unsigned long tceval, unsigned long count)
248{
249	return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
250}
251
252static inline long plpar_get_term_char(unsigned long termno,
253		unsigned long *len_ret, char *buf_ret)
254{
255	long rc;
256	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
257	unsigned long *lbuf = (unsigned long *)buf_ret;	/* TODO: alignment? */
258
259	rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
260
261	*len_ret = retbuf[0];
262	lbuf[0] = retbuf[1];
263	lbuf[1] = retbuf[2];
264
265	return rc;
266}
267
268static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
269		const char *buffer)
270{
271	unsigned long *lbuf = (unsigned long *)buffer;	/* TODO: alignment? */
272	return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
273			lbuf[1]);
274}
275
276#endif /* _PSERIES_PLPAR_WRAPPERS_H */