1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2212bebb4SDeepthi Dharwar #ifndef _ASM_POWERPC_PLPAR_WRAPPERS_H
3212bebb4SDeepthi Dharwar #define _ASM_POWERPC_PLPAR_WRAPPERS_H
4212bebb4SDeepthi Dharwar
55017e875SMichael Ellerman #ifdef CONFIG_PPC_PSERIES
65017e875SMichael Ellerman
7212bebb4SDeepthi Dharwar #include <linux/string.h>
8212bebb4SDeepthi Dharwar #include <linux/irqflags.h>
9*19d31c5fSJordan Niethe #include <linux/delay.h>
10212bebb4SDeepthi Dharwar
11212bebb4SDeepthi Dharwar #include <asm/hvcall.h>
12212bebb4SDeepthi Dharwar #include <asm/paca.h>
131aa00066SMichael Ellerman #include <asm/lppaca.h>
14212bebb4SDeepthi Dharwar #include <asm/page.h>
15212bebb4SDeepthi Dharwar
poll_pending(void)16212bebb4SDeepthi Dharwar static inline long poll_pending(void)
17212bebb4SDeepthi Dharwar {
18212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_POLL_PENDING);
19212bebb4SDeepthi Dharwar }
20212bebb4SDeepthi Dharwar
cede_processor(void)21212bebb4SDeepthi Dharwar static inline long cede_processor(void)
22212bebb4SDeepthi Dharwar {
237058f4b1SNicholas Piggin /*
247058f4b1SNicholas Piggin * We cannot call tracepoints inside RCU idle regions which
257058f4b1SNicholas Piggin * means we must not trace H_CEDE.
267058f4b1SNicholas Piggin */
277058f4b1SNicholas Piggin return plpar_hcall_norets_notrace(H_CEDE);
28212bebb4SDeepthi Dharwar }
29212bebb4SDeepthi Dharwar
vpa_call(unsigned long flags,unsigned long cpu,unsigned long vpa)30212bebb4SDeepthi Dharwar static inline long vpa_call(unsigned long flags, unsigned long cpu,
31212bebb4SDeepthi Dharwar unsigned long vpa)
32212bebb4SDeepthi Dharwar {
33212bebb4SDeepthi Dharwar flags = flags << H_VPA_FUNC_SHIFT;
34212bebb4SDeepthi Dharwar
35212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
36212bebb4SDeepthi Dharwar }
37212bebb4SDeepthi Dharwar
unregister_vpa(unsigned long cpu)38212bebb4SDeepthi Dharwar static inline long unregister_vpa(unsigned long cpu)
39212bebb4SDeepthi Dharwar {
40212bebb4SDeepthi Dharwar return vpa_call(H_VPA_DEREG_VPA, cpu, 0);
41212bebb4SDeepthi Dharwar }
42212bebb4SDeepthi Dharwar
register_vpa(unsigned long cpu,unsigned long vpa)43212bebb4SDeepthi Dharwar static inline long register_vpa(unsigned long cpu, unsigned long vpa)
44212bebb4SDeepthi Dharwar {
45212bebb4SDeepthi Dharwar return vpa_call(H_VPA_REG_VPA, cpu, vpa);
46212bebb4SDeepthi Dharwar }
47212bebb4SDeepthi Dharwar
unregister_slb_shadow(unsigned long cpu)48212bebb4SDeepthi Dharwar static inline long unregister_slb_shadow(unsigned long cpu)
49212bebb4SDeepthi Dharwar {
50212bebb4SDeepthi Dharwar return vpa_call(H_VPA_DEREG_SLB, cpu, 0);
51212bebb4SDeepthi Dharwar }
52212bebb4SDeepthi Dharwar
register_slb_shadow(unsigned long cpu,unsigned long vpa)53212bebb4SDeepthi Dharwar static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
54212bebb4SDeepthi Dharwar {
55212bebb4SDeepthi Dharwar return vpa_call(H_VPA_REG_SLB, cpu, vpa);
56212bebb4SDeepthi Dharwar }
57212bebb4SDeepthi Dharwar
unregister_dtl(unsigned long cpu)58212bebb4SDeepthi Dharwar static inline long unregister_dtl(unsigned long cpu)
59212bebb4SDeepthi Dharwar {
60212bebb4SDeepthi Dharwar return vpa_call(H_VPA_DEREG_DTL, cpu, 0);
61212bebb4SDeepthi Dharwar }
62212bebb4SDeepthi Dharwar
register_dtl(unsigned long cpu,unsigned long vpa)63212bebb4SDeepthi Dharwar static inline long register_dtl(unsigned long cpu, unsigned long vpa)
64212bebb4SDeepthi Dharwar {
65212bebb4SDeepthi Dharwar return vpa_call(H_VPA_REG_DTL, cpu, vpa);
66212bebb4SDeepthi Dharwar }
67212bebb4SDeepthi Dharwar
68212bebb4SDeepthi Dharwar extern void vpa_init(int cpu);
69212bebb4SDeepthi Dharwar
plpar_pte_enter(unsigned long flags,unsigned long hpte_group,unsigned long hpte_v,unsigned long hpte_r,unsigned long * slot)70212bebb4SDeepthi Dharwar static inline long plpar_pte_enter(unsigned long flags,
71212bebb4SDeepthi Dharwar unsigned long hpte_group, unsigned long hpte_v,
72212bebb4SDeepthi Dharwar unsigned long hpte_r, unsigned long *slot)
73212bebb4SDeepthi Dharwar {
74212bebb4SDeepthi Dharwar long rc;
75212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
76212bebb4SDeepthi Dharwar
77212bebb4SDeepthi Dharwar rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
78212bebb4SDeepthi Dharwar
79212bebb4SDeepthi Dharwar *slot = retbuf[0];
80212bebb4SDeepthi Dharwar
81212bebb4SDeepthi Dharwar return rc;
82212bebb4SDeepthi Dharwar }
83212bebb4SDeepthi Dharwar
plpar_pte_remove(unsigned long flags,unsigned long ptex,unsigned long avpn,unsigned long * old_pteh_ret,unsigned long * old_ptel_ret)84212bebb4SDeepthi Dharwar static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
85212bebb4SDeepthi Dharwar unsigned long avpn, unsigned long *old_pteh_ret,
86212bebb4SDeepthi Dharwar unsigned long *old_ptel_ret)
87212bebb4SDeepthi Dharwar {
88212bebb4SDeepthi Dharwar long rc;
89212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
90212bebb4SDeepthi Dharwar
91212bebb4SDeepthi Dharwar rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
92212bebb4SDeepthi Dharwar
93212bebb4SDeepthi Dharwar *old_pteh_ret = retbuf[0];
94212bebb4SDeepthi Dharwar *old_ptel_ret = retbuf[1];
95212bebb4SDeepthi Dharwar
96212bebb4SDeepthi Dharwar return rc;
97212bebb4SDeepthi Dharwar }
98212bebb4SDeepthi Dharwar
99212bebb4SDeepthi Dharwar /* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
plpar_pte_remove_raw(unsigned long flags,unsigned long ptex,unsigned long avpn,unsigned long * old_pteh_ret,unsigned long * old_ptel_ret)100212bebb4SDeepthi Dharwar static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
101212bebb4SDeepthi Dharwar unsigned long avpn, unsigned long *old_pteh_ret,
102212bebb4SDeepthi Dharwar unsigned long *old_ptel_ret)
103212bebb4SDeepthi Dharwar {
104212bebb4SDeepthi Dharwar long rc;
105212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
106212bebb4SDeepthi Dharwar
107212bebb4SDeepthi Dharwar rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
108212bebb4SDeepthi Dharwar
109212bebb4SDeepthi Dharwar *old_pteh_ret = retbuf[0];
110212bebb4SDeepthi Dharwar *old_ptel_ret = retbuf[1];
111212bebb4SDeepthi Dharwar
112212bebb4SDeepthi Dharwar return rc;
113212bebb4SDeepthi Dharwar }
114212bebb4SDeepthi Dharwar
plpar_pte_read(unsigned long flags,unsigned long ptex,unsigned long * old_pteh_ret,unsigned long * old_ptel_ret)115212bebb4SDeepthi Dharwar static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
116212bebb4SDeepthi Dharwar unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
117212bebb4SDeepthi Dharwar {
118212bebb4SDeepthi Dharwar long rc;
119212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
120212bebb4SDeepthi Dharwar
121212bebb4SDeepthi Dharwar rc = plpar_hcall(H_READ, retbuf, flags, ptex);
122212bebb4SDeepthi Dharwar
123212bebb4SDeepthi Dharwar *old_pteh_ret = retbuf[0];
124212bebb4SDeepthi Dharwar *old_ptel_ret = retbuf[1];
125212bebb4SDeepthi Dharwar
126212bebb4SDeepthi Dharwar return rc;
127212bebb4SDeepthi Dharwar }
128212bebb4SDeepthi Dharwar
129212bebb4SDeepthi Dharwar /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
plpar_pte_read_raw(unsigned long flags,unsigned long ptex,unsigned long * old_pteh_ret,unsigned long * old_ptel_ret)130212bebb4SDeepthi Dharwar static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
131212bebb4SDeepthi Dharwar unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
132212bebb4SDeepthi Dharwar {
133212bebb4SDeepthi Dharwar long rc;
134212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
135212bebb4SDeepthi Dharwar
136212bebb4SDeepthi Dharwar rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
137212bebb4SDeepthi Dharwar
138212bebb4SDeepthi Dharwar *old_pteh_ret = retbuf[0];
139212bebb4SDeepthi Dharwar *old_ptel_ret = retbuf[1];
140212bebb4SDeepthi Dharwar
141212bebb4SDeepthi Dharwar return rc;
142212bebb4SDeepthi Dharwar }
143212bebb4SDeepthi Dharwar
144212bebb4SDeepthi Dharwar /*
1454ad90c86SAneesh Kumar K.V * ptes must be 8*sizeof(unsigned long)
1464ad90c86SAneesh Kumar K.V */
plpar_pte_read_4(unsigned long flags,unsigned long ptex,unsigned long * ptes)1474ad90c86SAneesh Kumar K.V static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
1484ad90c86SAneesh Kumar K.V unsigned long *ptes)
1494ad90c86SAneesh Kumar K.V
1504ad90c86SAneesh Kumar K.V {
1514ad90c86SAneesh Kumar K.V long rc;
1524ad90c86SAneesh Kumar K.V unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
1534ad90c86SAneesh Kumar K.V
1544ad90c86SAneesh Kumar K.V rc = plpar_hcall9(H_READ, retbuf, flags | H_READ_4, ptex);
1554ad90c86SAneesh Kumar K.V
1564ad90c86SAneesh Kumar K.V memcpy(ptes, retbuf, 8*sizeof(unsigned long));
1574ad90c86SAneesh Kumar K.V
1584ad90c86SAneesh Kumar K.V return rc;
1594ad90c86SAneesh Kumar K.V }
1604ad90c86SAneesh Kumar K.V
1614ad90c86SAneesh Kumar K.V /*
162212bebb4SDeepthi Dharwar * plpar_pte_read_4_raw can be called in real mode.
163212bebb4SDeepthi Dharwar * ptes must be 8*sizeof(unsigned long)
164212bebb4SDeepthi Dharwar */
plpar_pte_read_4_raw(unsigned long flags,unsigned long ptex,unsigned long * ptes)165212bebb4SDeepthi Dharwar static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
166212bebb4SDeepthi Dharwar unsigned long *ptes)
167212bebb4SDeepthi Dharwar
168212bebb4SDeepthi Dharwar {
169212bebb4SDeepthi Dharwar long rc;
170212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
171212bebb4SDeepthi Dharwar
172212bebb4SDeepthi Dharwar rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
173212bebb4SDeepthi Dharwar
174212bebb4SDeepthi Dharwar memcpy(ptes, retbuf, 8*sizeof(unsigned long));
175212bebb4SDeepthi Dharwar
176212bebb4SDeepthi Dharwar return rc;
177212bebb4SDeepthi Dharwar }
178212bebb4SDeepthi Dharwar
plpar_pte_protect(unsigned long flags,unsigned long ptex,unsigned long avpn)179212bebb4SDeepthi Dharwar static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
180212bebb4SDeepthi Dharwar unsigned long avpn)
181212bebb4SDeepthi Dharwar {
182212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
183212bebb4SDeepthi Dharwar }
184212bebb4SDeepthi Dharwar
plpar_resize_hpt_prepare(unsigned long flags,unsigned long shift)18564b40ffbSDavid Gibson static inline long plpar_resize_hpt_prepare(unsigned long flags,
18664b40ffbSDavid Gibson unsigned long shift)
18764b40ffbSDavid Gibson {
18864b40ffbSDavid Gibson return plpar_hcall_norets(H_RESIZE_HPT_PREPARE, flags, shift);
18964b40ffbSDavid Gibson }
19064b40ffbSDavid Gibson
plpar_resize_hpt_commit(unsigned long flags,unsigned long shift)19164b40ffbSDavid Gibson static inline long plpar_resize_hpt_commit(unsigned long flags,
19264b40ffbSDavid Gibson unsigned long shift)
19364b40ffbSDavid Gibson {
19464b40ffbSDavid Gibson return plpar_hcall_norets(H_RESIZE_HPT_COMMIT, flags, shift);
19564b40ffbSDavid Gibson }
19664b40ffbSDavid Gibson
plpar_tce_get(unsigned long liobn,unsigned long ioba,unsigned long * tce_ret)197212bebb4SDeepthi Dharwar static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
198212bebb4SDeepthi Dharwar unsigned long *tce_ret)
199212bebb4SDeepthi Dharwar {
200212bebb4SDeepthi Dharwar long rc;
201212bebb4SDeepthi Dharwar unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
202212bebb4SDeepthi Dharwar
203212bebb4SDeepthi Dharwar rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
204212bebb4SDeepthi Dharwar
205212bebb4SDeepthi Dharwar *tce_ret = retbuf[0];
206212bebb4SDeepthi Dharwar
207212bebb4SDeepthi Dharwar return rc;
208212bebb4SDeepthi Dharwar }
209212bebb4SDeepthi Dharwar
plpar_tce_put(unsigned long liobn,unsigned long ioba,unsigned long tceval)210212bebb4SDeepthi Dharwar static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
211212bebb4SDeepthi Dharwar unsigned long tceval)
212212bebb4SDeepthi Dharwar {
213212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
214212bebb4SDeepthi Dharwar }
215212bebb4SDeepthi Dharwar
plpar_tce_put_indirect(unsigned long liobn,unsigned long ioba,unsigned long page,unsigned long count)216212bebb4SDeepthi Dharwar static inline long plpar_tce_put_indirect(unsigned long liobn,
217212bebb4SDeepthi Dharwar unsigned long ioba, unsigned long page, unsigned long count)
218212bebb4SDeepthi Dharwar {
219212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
220212bebb4SDeepthi Dharwar }
221212bebb4SDeepthi Dharwar
plpar_tce_stuff(unsigned long liobn,unsigned long ioba,unsigned long tceval,unsigned long count)222212bebb4SDeepthi Dharwar static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
223212bebb4SDeepthi Dharwar unsigned long tceval, unsigned long count)
224212bebb4SDeepthi Dharwar {
225212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
226212bebb4SDeepthi Dharwar }
227212bebb4SDeepthi Dharwar
228212bebb4SDeepthi Dharwar /* Set various resource mode parameters */
plpar_set_mode(unsigned long mflags,unsigned long resource,unsigned long value1,unsigned long value2)229212bebb4SDeepthi Dharwar static inline long plpar_set_mode(unsigned long mflags, unsigned long resource,
230212bebb4SDeepthi Dharwar unsigned long value1, unsigned long value2)
231212bebb4SDeepthi Dharwar {
232212bebb4SDeepthi Dharwar return plpar_hcall_norets(H_SET_MODE, mflags, resource, value1, value2);
233212bebb4SDeepthi Dharwar }
234212bebb4SDeepthi Dharwar
235212bebb4SDeepthi Dharwar /*
236212bebb4SDeepthi Dharwar * Enable relocation on exceptions on this partition
237212bebb4SDeepthi Dharwar *
238212bebb4SDeepthi Dharwar * Note: this call has a partition wide scope and can take a while to complete.
239212bebb4SDeepthi Dharwar * If it returns H_LONG_BUSY_* it should be retried periodically until it
240212bebb4SDeepthi Dharwar * returns H_SUCCESS.
241212bebb4SDeepthi Dharwar */
enable_reloc_on_exceptions(void)242212bebb4SDeepthi Dharwar static inline long enable_reloc_on_exceptions(void)
243212bebb4SDeepthi Dharwar {
244212bebb4SDeepthi Dharwar /* mflags = 3: Exceptions at 0xC000000000004000 */
24560666de2SMichael Neuling return plpar_set_mode(3, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE, 0, 0);
246212bebb4SDeepthi Dharwar }
247212bebb4SDeepthi Dharwar
248212bebb4SDeepthi Dharwar /*
249212bebb4SDeepthi Dharwar * Disable relocation on exceptions on this partition
250212bebb4SDeepthi Dharwar *
251212bebb4SDeepthi Dharwar * Note: this call has a partition wide scope and can take a while to complete.
252212bebb4SDeepthi Dharwar * If it returns H_LONG_BUSY_* it should be retried periodically until it
253212bebb4SDeepthi Dharwar * returns H_SUCCESS.
254212bebb4SDeepthi Dharwar */
disable_reloc_on_exceptions(void)255212bebb4SDeepthi Dharwar static inline long disable_reloc_on_exceptions(void) {
25660666de2SMichael Neuling return plpar_set_mode(0, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE, 0, 0);
257212bebb4SDeepthi Dharwar }
258212bebb4SDeepthi Dharwar
259e844b1eeSAnton Blanchard /*
260e844b1eeSAnton Blanchard * Take exceptions in big endian mode on this partition
261e844b1eeSAnton Blanchard *
262e844b1eeSAnton Blanchard * Note: this call has a partition wide scope and can take a while to complete.
263e844b1eeSAnton Blanchard * If it returns H_LONG_BUSY_* it should be retried periodically until it
264e844b1eeSAnton Blanchard * returns H_SUCCESS.
265e844b1eeSAnton Blanchard */
enable_big_endian_exceptions(void)266e844b1eeSAnton Blanchard static inline long enable_big_endian_exceptions(void)
267e844b1eeSAnton Blanchard {
268e844b1eeSAnton Blanchard /* mflags = 0: big endian exceptions */
26960666de2SMichael Neuling return plpar_set_mode(0, H_SET_MODE_RESOURCE_LE, 0, 0);
270e844b1eeSAnton Blanchard }
271e844b1eeSAnton Blanchard
272e844b1eeSAnton Blanchard /*
273e844b1eeSAnton Blanchard * Take exceptions in little endian mode on this partition
274e844b1eeSAnton Blanchard *
275e844b1eeSAnton Blanchard * Note: this call has a partition wide scope and can take a while to complete.
276e844b1eeSAnton Blanchard * If it returns H_LONG_BUSY_* it should be retried periodically until it
277e844b1eeSAnton Blanchard * returns H_SUCCESS.
278e844b1eeSAnton Blanchard */
enable_little_endian_exceptions(void)279e844b1eeSAnton Blanchard static inline long enable_little_endian_exceptions(void)
280e844b1eeSAnton Blanchard {
281e844b1eeSAnton Blanchard /* mflags = 1: little endian exceptions */
28260666de2SMichael Neuling return plpar_set_mode(1, H_SET_MODE_RESOURCE_LE, 0, 0);
283e844b1eeSAnton Blanchard }
284e844b1eeSAnton Blanchard
plpar_set_ciabr(unsigned long ciabr)2857c09c186SMichael Ellerman static inline long plpar_set_ciabr(unsigned long ciabr)
286212bebb4SDeepthi Dharwar {
28760666de2SMichael Neuling return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_CIABR, ciabr, 0);
288212bebb4SDeepthi Dharwar }
289212bebb4SDeepthi Dharwar
plpar_set_watchpoint0(unsigned long dawr0,unsigned long dawrx0)2907c09c186SMichael Ellerman static inline long plpar_set_watchpoint0(unsigned long dawr0, unsigned long dawrx0)
291212bebb4SDeepthi Dharwar {
2926f3fe297SRavi Bangoria return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR0, dawr0, dawrx0);
293212bebb4SDeepthi Dharwar }
294212bebb4SDeepthi Dharwar
plpar_set_watchpoint1(unsigned long dawr1,unsigned long dawrx1)29503f3e54aSRavi Bangoria static inline long plpar_set_watchpoint1(unsigned long dawr1, unsigned long dawrx1)
29603f3e54aSRavi Bangoria {
29703f3e54aSRavi Bangoria return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR1, dawr1, dawrx1);
29803f3e54aSRavi Bangoria }
29903f3e54aSRavi Bangoria
plpar_signal_sys_reset(long cpu)3007c09c186SMichael Ellerman static inline long plpar_signal_sys_reset(long cpu)
30153ce2996SNicholas Piggin {
30253ce2996SNicholas Piggin return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu);
30353ce2996SNicholas Piggin }
30453ce2996SNicholas Piggin
plpar_get_cpu_characteristics(struct h_cpu_char_result * p)305191eccb1SMichael Neuling static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p)
306191eccb1SMichael Neuling {
307191eccb1SMichael Neuling unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
308191eccb1SMichael Neuling long rc;
309191eccb1SMichael Neuling
310191eccb1SMichael Neuling rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf);
311191eccb1SMichael Neuling if (rc == H_SUCCESS) {
312191eccb1SMichael Neuling p->character = retbuf[0];
313191eccb1SMichael Neuling p->behaviour = retbuf[1];
314191eccb1SMichael Neuling }
315191eccb1SMichael Neuling
316191eccb1SMichael Neuling return rc;
317191eccb1SMichael Neuling }
318191eccb1SMichael Neuling
plpar_guest_create(unsigned long flags,unsigned long * guest_id)319*19d31c5fSJordan Niethe static inline long plpar_guest_create(unsigned long flags, unsigned long *guest_id)
320*19d31c5fSJordan Niethe {
321*19d31c5fSJordan Niethe unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
322*19d31c5fSJordan Niethe unsigned long token;
323*19d31c5fSJordan Niethe long rc;
324*19d31c5fSJordan Niethe
325*19d31c5fSJordan Niethe token = -1UL;
326*19d31c5fSJordan Niethe do {
327*19d31c5fSJordan Niethe rc = plpar_hcall(H_GUEST_CREATE, retbuf, flags, token);
328*19d31c5fSJordan Niethe if (rc == H_SUCCESS)
329*19d31c5fSJordan Niethe *guest_id = retbuf[0];
330*19d31c5fSJordan Niethe
331*19d31c5fSJordan Niethe if (rc == H_BUSY) {
332*19d31c5fSJordan Niethe token = retbuf[0];
333*19d31c5fSJordan Niethe cond_resched();
334*19d31c5fSJordan Niethe }
335*19d31c5fSJordan Niethe
336*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
337*19d31c5fSJordan Niethe token = retbuf[0];
338*19d31c5fSJordan Niethe msleep(get_longbusy_msecs(rc));
339*19d31c5fSJordan Niethe rc = H_BUSY;
340*19d31c5fSJordan Niethe }
341*19d31c5fSJordan Niethe
342*19d31c5fSJordan Niethe } while (rc == H_BUSY);
343*19d31c5fSJordan Niethe
344*19d31c5fSJordan Niethe return rc;
345*19d31c5fSJordan Niethe }
346*19d31c5fSJordan Niethe
plpar_guest_create_vcpu(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id)347*19d31c5fSJordan Niethe static inline long plpar_guest_create_vcpu(unsigned long flags,
348*19d31c5fSJordan Niethe unsigned long guest_id,
349*19d31c5fSJordan Niethe unsigned long vcpu_id)
350*19d31c5fSJordan Niethe {
351*19d31c5fSJordan Niethe long rc;
352*19d31c5fSJordan Niethe
353*19d31c5fSJordan Niethe do {
354*19d31c5fSJordan Niethe rc = plpar_hcall_norets(H_GUEST_CREATE_VCPU, 0, guest_id, vcpu_id);
355*19d31c5fSJordan Niethe
356*19d31c5fSJordan Niethe if (rc == H_BUSY)
357*19d31c5fSJordan Niethe cond_resched();
358*19d31c5fSJordan Niethe
359*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
360*19d31c5fSJordan Niethe msleep(get_longbusy_msecs(rc));
361*19d31c5fSJordan Niethe rc = H_BUSY;
362*19d31c5fSJordan Niethe }
363*19d31c5fSJordan Niethe
364*19d31c5fSJordan Niethe } while (rc == H_BUSY);
365*19d31c5fSJordan Niethe
366*19d31c5fSJordan Niethe return rc;
367*19d31c5fSJordan Niethe }
368*19d31c5fSJordan Niethe
plpar_guest_set_state(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id,unsigned long data_buffer,unsigned long data_size,unsigned long * failed_index)369*19d31c5fSJordan Niethe static inline long plpar_guest_set_state(unsigned long flags,
370*19d31c5fSJordan Niethe unsigned long guest_id,
371*19d31c5fSJordan Niethe unsigned long vcpu_id,
372*19d31c5fSJordan Niethe unsigned long data_buffer,
373*19d31c5fSJordan Niethe unsigned long data_size,
374*19d31c5fSJordan Niethe unsigned long *failed_index)
375*19d31c5fSJordan Niethe {
376*19d31c5fSJordan Niethe unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
377*19d31c5fSJordan Niethe long rc;
378*19d31c5fSJordan Niethe
379*19d31c5fSJordan Niethe while (true) {
380*19d31c5fSJordan Niethe rc = plpar_hcall(H_GUEST_SET_STATE, retbuf, flags, guest_id,
381*19d31c5fSJordan Niethe vcpu_id, data_buffer, data_size);
382*19d31c5fSJordan Niethe
383*19d31c5fSJordan Niethe if (rc == H_BUSY) {
384*19d31c5fSJordan Niethe cpu_relax();
385*19d31c5fSJordan Niethe continue;
386*19d31c5fSJordan Niethe }
387*19d31c5fSJordan Niethe
388*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
389*19d31c5fSJordan Niethe mdelay(get_longbusy_msecs(rc));
390*19d31c5fSJordan Niethe continue;
391*19d31c5fSJordan Niethe }
392*19d31c5fSJordan Niethe
393*19d31c5fSJordan Niethe if (rc == H_INVALID_ELEMENT_ID)
394*19d31c5fSJordan Niethe *failed_index = retbuf[0];
395*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_SIZE)
396*19d31c5fSJordan Niethe *failed_index = retbuf[0];
397*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_VALUE)
398*19d31c5fSJordan Niethe *failed_index = retbuf[0];
399*19d31c5fSJordan Niethe
400*19d31c5fSJordan Niethe break;
401*19d31c5fSJordan Niethe }
402*19d31c5fSJordan Niethe
403*19d31c5fSJordan Niethe return rc;
404*19d31c5fSJordan Niethe }
405*19d31c5fSJordan Niethe
plpar_guest_get_state(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id,unsigned long data_buffer,unsigned long data_size,unsigned long * failed_index)406*19d31c5fSJordan Niethe static inline long plpar_guest_get_state(unsigned long flags,
407*19d31c5fSJordan Niethe unsigned long guest_id,
408*19d31c5fSJordan Niethe unsigned long vcpu_id,
409*19d31c5fSJordan Niethe unsigned long data_buffer,
410*19d31c5fSJordan Niethe unsigned long data_size,
411*19d31c5fSJordan Niethe unsigned long *failed_index)
412*19d31c5fSJordan Niethe {
413*19d31c5fSJordan Niethe unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
414*19d31c5fSJordan Niethe long rc;
415*19d31c5fSJordan Niethe
416*19d31c5fSJordan Niethe while (true) {
417*19d31c5fSJordan Niethe rc = plpar_hcall(H_GUEST_GET_STATE, retbuf, flags, guest_id,
418*19d31c5fSJordan Niethe vcpu_id, data_buffer, data_size);
419*19d31c5fSJordan Niethe
420*19d31c5fSJordan Niethe if (rc == H_BUSY) {
421*19d31c5fSJordan Niethe cpu_relax();
422*19d31c5fSJordan Niethe continue;
423*19d31c5fSJordan Niethe }
424*19d31c5fSJordan Niethe
425*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
426*19d31c5fSJordan Niethe mdelay(get_longbusy_msecs(rc));
427*19d31c5fSJordan Niethe continue;
428*19d31c5fSJordan Niethe }
429*19d31c5fSJordan Niethe
430*19d31c5fSJordan Niethe if (rc == H_INVALID_ELEMENT_ID)
431*19d31c5fSJordan Niethe *failed_index = retbuf[0];
432*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_SIZE)
433*19d31c5fSJordan Niethe *failed_index = retbuf[0];
434*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_VALUE)
435*19d31c5fSJordan Niethe *failed_index = retbuf[0];
436*19d31c5fSJordan Niethe
437*19d31c5fSJordan Niethe break;
438*19d31c5fSJordan Niethe }
439*19d31c5fSJordan Niethe
440*19d31c5fSJordan Niethe return rc;
441*19d31c5fSJordan Niethe }
442*19d31c5fSJordan Niethe
plpar_guest_run_vcpu(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id,int * trap,unsigned long * failed_index)443*19d31c5fSJordan Niethe static inline long plpar_guest_run_vcpu(unsigned long flags, unsigned long guest_id,
444*19d31c5fSJordan Niethe unsigned long vcpu_id, int *trap,
445*19d31c5fSJordan Niethe unsigned long *failed_index)
446*19d31c5fSJordan Niethe {
447*19d31c5fSJordan Niethe unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
448*19d31c5fSJordan Niethe long rc;
449*19d31c5fSJordan Niethe
450*19d31c5fSJordan Niethe rc = plpar_hcall(H_GUEST_RUN_VCPU, retbuf, flags, guest_id, vcpu_id);
451*19d31c5fSJordan Niethe if (rc == H_SUCCESS)
452*19d31c5fSJordan Niethe *trap = retbuf[0];
453*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_ID)
454*19d31c5fSJordan Niethe *failed_index = retbuf[0];
455*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_SIZE)
456*19d31c5fSJordan Niethe *failed_index = retbuf[0];
457*19d31c5fSJordan Niethe else if (rc == H_INVALID_ELEMENT_VALUE)
458*19d31c5fSJordan Niethe *failed_index = retbuf[0];
459*19d31c5fSJordan Niethe
460*19d31c5fSJordan Niethe return rc;
461*19d31c5fSJordan Niethe }
462*19d31c5fSJordan Niethe
plpar_guest_delete(unsigned long flags,u64 guest_id)463*19d31c5fSJordan Niethe static inline long plpar_guest_delete(unsigned long flags, u64 guest_id)
464*19d31c5fSJordan Niethe {
465*19d31c5fSJordan Niethe long rc;
466*19d31c5fSJordan Niethe
467*19d31c5fSJordan Niethe do {
468*19d31c5fSJordan Niethe rc = plpar_hcall_norets(H_GUEST_DELETE, flags, guest_id);
469*19d31c5fSJordan Niethe if (rc == H_BUSY)
470*19d31c5fSJordan Niethe cond_resched();
471*19d31c5fSJordan Niethe
472*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
473*19d31c5fSJordan Niethe msleep(get_longbusy_msecs(rc));
474*19d31c5fSJordan Niethe rc = H_BUSY;
475*19d31c5fSJordan Niethe }
476*19d31c5fSJordan Niethe
477*19d31c5fSJordan Niethe } while (rc == H_BUSY);
478*19d31c5fSJordan Niethe
479*19d31c5fSJordan Niethe return rc;
480*19d31c5fSJordan Niethe }
481*19d31c5fSJordan Niethe
plpar_guest_set_capabilities(unsigned long flags,unsigned long capabilities)482*19d31c5fSJordan Niethe static inline long plpar_guest_set_capabilities(unsigned long flags,
483*19d31c5fSJordan Niethe unsigned long capabilities)
484*19d31c5fSJordan Niethe {
485*19d31c5fSJordan Niethe unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
486*19d31c5fSJordan Niethe long rc;
487*19d31c5fSJordan Niethe
488*19d31c5fSJordan Niethe do {
489*19d31c5fSJordan Niethe rc = plpar_hcall(H_GUEST_SET_CAPABILITIES, retbuf, flags, capabilities);
490*19d31c5fSJordan Niethe if (rc == H_BUSY)
491*19d31c5fSJordan Niethe cond_resched();
492*19d31c5fSJordan Niethe
493*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
494*19d31c5fSJordan Niethe msleep(get_longbusy_msecs(rc));
495*19d31c5fSJordan Niethe rc = H_BUSY;
496*19d31c5fSJordan Niethe }
497*19d31c5fSJordan Niethe } while (rc == H_BUSY);
498*19d31c5fSJordan Niethe
499*19d31c5fSJordan Niethe return rc;
500*19d31c5fSJordan Niethe }
501*19d31c5fSJordan Niethe
plpar_guest_get_capabilities(unsigned long flags,unsigned long * capabilities)502*19d31c5fSJordan Niethe static inline long plpar_guest_get_capabilities(unsigned long flags,
503*19d31c5fSJordan Niethe unsigned long *capabilities)
504*19d31c5fSJordan Niethe {
505*19d31c5fSJordan Niethe unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
506*19d31c5fSJordan Niethe long rc;
507*19d31c5fSJordan Niethe
508*19d31c5fSJordan Niethe do {
509*19d31c5fSJordan Niethe rc = plpar_hcall(H_GUEST_GET_CAPABILITIES, retbuf, flags);
510*19d31c5fSJordan Niethe if (rc == H_BUSY)
511*19d31c5fSJordan Niethe cond_resched();
512*19d31c5fSJordan Niethe
513*19d31c5fSJordan Niethe if (H_IS_LONG_BUSY(rc)) {
514*19d31c5fSJordan Niethe msleep(get_longbusy_msecs(rc));
515*19d31c5fSJordan Niethe rc = H_BUSY;
516*19d31c5fSJordan Niethe }
517*19d31c5fSJordan Niethe } while (rc == H_BUSY);
518*19d31c5fSJordan Niethe
519*19d31c5fSJordan Niethe if (rc == H_SUCCESS)
520*19d31c5fSJordan Niethe *capabilities = retbuf[0];
521*19d31c5fSJordan Niethe
522*19d31c5fSJordan Niethe return rc;
523*19d31c5fSJordan Niethe }
524*19d31c5fSJordan Niethe
525dd3d9aa5SNicholas Piggin /*
526dd3d9aa5SNicholas Piggin * Wrapper to H_RPT_INVALIDATE hcall that handles return values appropriately
527dd3d9aa5SNicholas Piggin *
528dd3d9aa5SNicholas Piggin * - Returns H_SUCCESS on success
529dd3d9aa5SNicholas Piggin * - For H_BUSY return value, we retry the hcall.
530dd3d9aa5SNicholas Piggin * - For any other hcall failures, attempt a full flush once before
531dd3d9aa5SNicholas Piggin * resorting to BUG().
532dd3d9aa5SNicholas Piggin *
533dd3d9aa5SNicholas Piggin * Note: This hcall is expected to fail only very rarely. The correct
534dd3d9aa5SNicholas Piggin * error recovery of killing the process/guest will be eventually
535dd3d9aa5SNicholas Piggin * needed.
536dd3d9aa5SNicholas Piggin */
pseries_rpt_invalidate(u64 pid,u64 target,u64 type,u64 page_sizes,u64 start,u64 end)537dfcaacc8SJordan Niethe static inline long pseries_rpt_invalidate(u64 pid, u64 target, u64 type,
538dd3d9aa5SNicholas Piggin u64 page_sizes, u64 start, u64 end)
539dd3d9aa5SNicholas Piggin {
540dd3d9aa5SNicholas Piggin long rc;
541dd3d9aa5SNicholas Piggin unsigned long all;
542dd3d9aa5SNicholas Piggin
543dd3d9aa5SNicholas Piggin while (true) {
544dd3d9aa5SNicholas Piggin rc = plpar_hcall_norets(H_RPT_INVALIDATE, pid, target, type,
545dd3d9aa5SNicholas Piggin page_sizes, start, end);
546dd3d9aa5SNicholas Piggin if (rc == H_BUSY) {
547dd3d9aa5SNicholas Piggin cpu_relax();
548dd3d9aa5SNicholas Piggin continue;
549dd3d9aa5SNicholas Piggin } else if (rc == H_SUCCESS)
550dd3d9aa5SNicholas Piggin return rc;
551dd3d9aa5SNicholas Piggin
552dd3d9aa5SNicholas Piggin /* Flush request failed, try with a full flush once */
553dd3d9aa5SNicholas Piggin if (type & H_RPTI_TYPE_NESTED)
554dd3d9aa5SNicholas Piggin all = H_RPTI_TYPE_NESTED | H_RPTI_TYPE_NESTED_ALL;
555dd3d9aa5SNicholas Piggin else
556dd3d9aa5SNicholas Piggin all = H_RPTI_TYPE_ALL;
557dd3d9aa5SNicholas Piggin retry:
558dd3d9aa5SNicholas Piggin rc = plpar_hcall_norets(H_RPT_INVALIDATE, pid, target,
559dd3d9aa5SNicholas Piggin all, page_sizes, 0, -1UL);
560dd3d9aa5SNicholas Piggin if (rc == H_BUSY) {
561dd3d9aa5SNicholas Piggin cpu_relax();
562dd3d9aa5SNicholas Piggin goto retry;
563dd3d9aa5SNicholas Piggin } else if (rc == H_SUCCESS)
564dd3d9aa5SNicholas Piggin return rc;
565dd3d9aa5SNicholas Piggin
566dd3d9aa5SNicholas Piggin BUG();
567dd3d9aa5SNicholas Piggin }
568dd3d9aa5SNicholas Piggin }
569dd3d9aa5SNicholas Piggin
570ab83dc79SMichael Ellerman #else /* !CONFIG_PPC_PSERIES */
571ab83dc79SMichael Ellerman
plpar_set_ciabr(unsigned long ciabr)572ab83dc79SMichael Ellerman static inline long plpar_set_ciabr(unsigned long ciabr)
573ab83dc79SMichael Ellerman {
574ab83dc79SMichael Ellerman return 0;
575ab83dc79SMichael Ellerman }
57665e701b2SChristophe Leroy
plpar_pte_read_4(unsigned long flags,unsigned long ptex,unsigned long * ptes)57765e701b2SChristophe Leroy static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
57865e701b2SChristophe Leroy unsigned long *ptes)
57965e701b2SChristophe Leroy {
58065e701b2SChristophe Leroy return 0;
58165e701b2SChristophe Leroy }
582dd3d9aa5SNicholas Piggin
pseries_rpt_invalidate(u64 pid,u64 target,u64 type,u64 page_sizes,u64 start,u64 end)583dfcaacc8SJordan Niethe static inline long pseries_rpt_invalidate(u64 pid, u64 target, u64 type,
584dd3d9aa5SNicholas Piggin u64 page_sizes, u64 start, u64 end)
585dd3d9aa5SNicholas Piggin {
586dd3d9aa5SNicholas Piggin return 0;
587dd3d9aa5SNicholas Piggin }
588dd3d9aa5SNicholas Piggin
plpar_guest_create_vcpu(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id)589*19d31c5fSJordan Niethe static inline long plpar_guest_create_vcpu(unsigned long flags,
590*19d31c5fSJordan Niethe unsigned long guest_id,
591*19d31c5fSJordan Niethe unsigned long vcpu_id)
592*19d31c5fSJordan Niethe {
593*19d31c5fSJordan Niethe return 0;
594*19d31c5fSJordan Niethe }
595*19d31c5fSJordan Niethe
plpar_guest_get_state(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id,unsigned long data_buffer,unsigned long data_size,unsigned long * failed_index)596*19d31c5fSJordan Niethe static inline long plpar_guest_get_state(unsigned long flags,
597*19d31c5fSJordan Niethe unsigned long guest_id,
598*19d31c5fSJordan Niethe unsigned long vcpu_id,
599*19d31c5fSJordan Niethe unsigned long data_buffer,
600*19d31c5fSJordan Niethe unsigned long data_size,
601*19d31c5fSJordan Niethe unsigned long *failed_index)
602*19d31c5fSJordan Niethe {
603*19d31c5fSJordan Niethe return 0;
604*19d31c5fSJordan Niethe }
605*19d31c5fSJordan Niethe
plpar_guest_set_state(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id,unsigned long data_buffer,unsigned long data_size,unsigned long * failed_index)606*19d31c5fSJordan Niethe static inline long plpar_guest_set_state(unsigned long flags,
607*19d31c5fSJordan Niethe unsigned long guest_id,
608*19d31c5fSJordan Niethe unsigned long vcpu_id,
609*19d31c5fSJordan Niethe unsigned long data_buffer,
610*19d31c5fSJordan Niethe unsigned long data_size,
611*19d31c5fSJordan Niethe unsigned long *failed_index)
612*19d31c5fSJordan Niethe {
613*19d31c5fSJordan Niethe return 0;
614*19d31c5fSJordan Niethe }
615*19d31c5fSJordan Niethe
plpar_guest_run_vcpu(unsigned long flags,unsigned long guest_id,unsigned long vcpu_id,int * trap,unsigned long * failed_index)616*19d31c5fSJordan Niethe static inline long plpar_guest_run_vcpu(unsigned long flags, unsigned long guest_id,
617*19d31c5fSJordan Niethe unsigned long vcpu_id, int *trap,
618*19d31c5fSJordan Niethe unsigned long *failed_index)
619*19d31c5fSJordan Niethe {
620*19d31c5fSJordan Niethe return 0;
621*19d31c5fSJordan Niethe }
622*19d31c5fSJordan Niethe
plpar_guest_create(unsigned long flags,unsigned long * guest_id)623*19d31c5fSJordan Niethe static inline long plpar_guest_create(unsigned long flags, unsigned long *guest_id)
624*19d31c5fSJordan Niethe {
625*19d31c5fSJordan Niethe return 0;
626*19d31c5fSJordan Niethe }
627*19d31c5fSJordan Niethe
plpar_guest_delete(unsigned long flags,u64 guest_id)628*19d31c5fSJordan Niethe static inline long plpar_guest_delete(unsigned long flags, u64 guest_id)
629*19d31c5fSJordan Niethe {
630*19d31c5fSJordan Niethe return 0;
631*19d31c5fSJordan Niethe }
632*19d31c5fSJordan Niethe
plpar_guest_get_capabilities(unsigned long flags,unsigned long * capabilities)633*19d31c5fSJordan Niethe static inline long plpar_guest_get_capabilities(unsigned long flags,
634*19d31c5fSJordan Niethe unsigned long *capabilities)
635*19d31c5fSJordan Niethe {
636*19d31c5fSJordan Niethe return 0;
637*19d31c5fSJordan Niethe }
638*19d31c5fSJordan Niethe
plpar_guest_set_capabilities(unsigned long flags,unsigned long capabilities)639*19d31c5fSJordan Niethe static inline long plpar_guest_set_capabilities(unsigned long flags,
640*19d31c5fSJordan Niethe unsigned long capabilities)
641*19d31c5fSJordan Niethe {
642*19d31c5fSJordan Niethe return 0;
643*19d31c5fSJordan Niethe }
644*19d31c5fSJordan Niethe
6455017e875SMichael Ellerman #endif /* CONFIG_PPC_PSERIES */
6465017e875SMichael Ellerman
647212bebb4SDeepthi Dharwar #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
648