18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_PLPAR_WRAPPERS_H
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_PLPAR_WRAPPERS_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_PSERIES
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/string.h>
88c2ecf20Sopenharmony_ci#include <linux/irqflags.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/hvcall.h>
118c2ecf20Sopenharmony_ci#include <asm/paca.h>
128c2ecf20Sopenharmony_ci#include <asm/lppaca.h>
138c2ecf20Sopenharmony_ci#include <asm/page.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic inline long poll_pending(void)
168c2ecf20Sopenharmony_ci{
178c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_POLL_PENDING);
188c2ecf20Sopenharmony_ci}
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic inline u8 get_cede_latency_hint(void)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	return get_lppaca()->cede_latency_hint;
238c2ecf20Sopenharmony_ci}
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistatic inline void set_cede_latency_hint(u8 latency_hint)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	get_lppaca()->cede_latency_hint = latency_hint;
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistatic inline long cede_processor(void)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_CEDE);
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic inline long extended_cede_processor(unsigned long latency_hint)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	long rc;
388c2ecf20Sopenharmony_ci	u8 old_latency_hint = get_cede_latency_hint();
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	set_cede_latency_hint(latency_hint);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	rc = cede_processor();
438c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
448c2ecf20Sopenharmony_ci	/* Ensure that H_CEDE returns with IRQs on */
458c2ecf20Sopenharmony_ci	if (WARN_ON(!(mfmsr() & MSR_EE)))
468c2ecf20Sopenharmony_ci		__hard_irq_enable();
478c2ecf20Sopenharmony_ci#endif
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	set_cede_latency_hint(old_latency_hint);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	return rc;
528c2ecf20Sopenharmony_ci}
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic inline long vpa_call(unsigned long flags, unsigned long cpu,
558c2ecf20Sopenharmony_ci		unsigned long vpa)
568c2ecf20Sopenharmony_ci{
578c2ecf20Sopenharmony_ci	flags = flags << H_VPA_FUNC_SHIFT;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic inline long unregister_vpa(unsigned long cpu)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	return vpa_call(H_VPA_DEREG_VPA, cpu, 0);
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistatic inline long register_vpa(unsigned long cpu, unsigned long vpa)
688c2ecf20Sopenharmony_ci{
698c2ecf20Sopenharmony_ci	return vpa_call(H_VPA_REG_VPA, cpu, vpa);
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic inline long unregister_slb_shadow(unsigned long cpu)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci	return vpa_call(H_VPA_DEREG_SLB, cpu, 0);
758c2ecf20Sopenharmony_ci}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistatic inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
788c2ecf20Sopenharmony_ci{
798c2ecf20Sopenharmony_ci	return vpa_call(H_VPA_REG_SLB, cpu, vpa);
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistatic inline long unregister_dtl(unsigned long cpu)
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci	return vpa_call(H_VPA_DEREG_DTL, cpu, 0);
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic inline long register_dtl(unsigned long cpu, unsigned long vpa)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	return vpa_call(H_VPA_REG_DTL, cpu, vpa);
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciextern void vpa_init(int cpu);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic inline long plpar_pte_enter(unsigned long flags,
958c2ecf20Sopenharmony_ci		unsigned long hpte_group, unsigned long hpte_v,
968c2ecf20Sopenharmony_ci		unsigned long hpte_r, unsigned long *slot)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	long rc;
998c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	*slot = retbuf[0];
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	return rc;
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
1098c2ecf20Sopenharmony_ci		unsigned long avpn, unsigned long *old_pteh_ret,
1108c2ecf20Sopenharmony_ci		unsigned long *old_ptel_ret)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	long rc;
1138c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	*old_pteh_ret = retbuf[0];
1188c2ecf20Sopenharmony_ci	*old_ptel_ret = retbuf[1];
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	return rc;
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
1248c2ecf20Sopenharmony_cistatic inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
1258c2ecf20Sopenharmony_ci		unsigned long avpn, unsigned long *old_pteh_ret,
1268c2ecf20Sopenharmony_ci		unsigned long *old_ptel_ret)
1278c2ecf20Sopenharmony_ci{
1288c2ecf20Sopenharmony_ci	long rc;
1298c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	*old_pteh_ret = retbuf[0];
1348c2ecf20Sopenharmony_ci	*old_ptel_ret = retbuf[1];
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	return rc;
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
1408c2ecf20Sopenharmony_ci		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	long rc;
1438c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	rc = plpar_hcall(H_READ, retbuf, flags, ptex);
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	*old_pteh_ret = retbuf[0];
1488c2ecf20Sopenharmony_ci	*old_ptel_ret = retbuf[1];
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	return rc;
1518c2ecf20Sopenharmony_ci}
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
1548c2ecf20Sopenharmony_cistatic inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
1558c2ecf20Sopenharmony_ci		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	long rc;
1588c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	*old_pteh_ret = retbuf[0];
1638c2ecf20Sopenharmony_ci	*old_ptel_ret = retbuf[1];
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	return rc;
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci/*
1698c2ecf20Sopenharmony_ci * ptes must be 8*sizeof(unsigned long)
1708c2ecf20Sopenharmony_ci */
1718c2ecf20Sopenharmony_cistatic inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
1728c2ecf20Sopenharmony_ci				    unsigned long *ptes)
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci{
1758c2ecf20Sopenharmony_ci	long rc;
1768c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	rc = plpar_hcall9(H_READ, retbuf, flags | H_READ_4, ptex);
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	memcpy(ptes, retbuf, 8*sizeof(unsigned long));
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	return rc;
1838c2ecf20Sopenharmony_ci}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci/*
1868c2ecf20Sopenharmony_ci * plpar_pte_read_4_raw can be called in real mode.
1878c2ecf20Sopenharmony_ci * ptes must be 8*sizeof(unsigned long)
1888c2ecf20Sopenharmony_ci */
1898c2ecf20Sopenharmony_cistatic inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
1908c2ecf20Sopenharmony_ci					unsigned long *ptes)
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci	long rc;
1948c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	memcpy(ptes, retbuf, 8*sizeof(unsigned long));
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	return rc;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
2048c2ecf20Sopenharmony_ci		unsigned long avpn)
2058c2ecf20Sopenharmony_ci{
2068c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic inline long plpar_resize_hpt_prepare(unsigned long flags,
2108c2ecf20Sopenharmony_ci					    unsigned long shift)
2118c2ecf20Sopenharmony_ci{
2128c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_RESIZE_HPT_PREPARE, flags, shift);
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_cistatic inline long plpar_resize_hpt_commit(unsigned long flags,
2168c2ecf20Sopenharmony_ci					   unsigned long shift)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_RESIZE_HPT_COMMIT, flags, shift);
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_cistatic inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
2228c2ecf20Sopenharmony_ci		unsigned long *tce_ret)
2238c2ecf20Sopenharmony_ci{
2248c2ecf20Sopenharmony_ci	long rc;
2258c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	*tce_ret = retbuf[0];
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	return rc;
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
2358c2ecf20Sopenharmony_ci		unsigned long tceval)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
2388c2ecf20Sopenharmony_ci}
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_cistatic inline long plpar_tce_put_indirect(unsigned long liobn,
2418c2ecf20Sopenharmony_ci		unsigned long ioba, unsigned long page, unsigned long count)
2428c2ecf20Sopenharmony_ci{
2438c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
2448c2ecf20Sopenharmony_ci}
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_cistatic inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
2478c2ecf20Sopenharmony_ci		unsigned long tceval, unsigned long count)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
2508c2ecf20Sopenharmony_ci}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci/* Set various resource mode parameters */
2538c2ecf20Sopenharmony_cistatic inline long plpar_set_mode(unsigned long mflags, unsigned long resource,
2548c2ecf20Sopenharmony_ci		unsigned long value1, unsigned long value2)
2558c2ecf20Sopenharmony_ci{
2568c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_SET_MODE, mflags, resource, value1, value2);
2578c2ecf20Sopenharmony_ci}
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci/*
2608c2ecf20Sopenharmony_ci * Enable relocation on exceptions on this partition
2618c2ecf20Sopenharmony_ci *
2628c2ecf20Sopenharmony_ci * Note: this call has a partition wide scope and can take a while to complete.
2638c2ecf20Sopenharmony_ci * If it returns H_LONG_BUSY_* it should be retried periodically until it
2648c2ecf20Sopenharmony_ci * returns H_SUCCESS.
2658c2ecf20Sopenharmony_ci */
2668c2ecf20Sopenharmony_cistatic inline long enable_reloc_on_exceptions(void)
2678c2ecf20Sopenharmony_ci{
2688c2ecf20Sopenharmony_ci	/* mflags = 3: Exceptions at 0xC000000000004000 */
2698c2ecf20Sopenharmony_ci	return plpar_set_mode(3, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE, 0, 0);
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci/*
2738c2ecf20Sopenharmony_ci * Disable relocation on exceptions on this partition
2748c2ecf20Sopenharmony_ci *
2758c2ecf20Sopenharmony_ci * Note: this call has a partition wide scope and can take a while to complete.
2768c2ecf20Sopenharmony_ci * If it returns H_LONG_BUSY_* it should be retried periodically until it
2778c2ecf20Sopenharmony_ci * returns H_SUCCESS.
2788c2ecf20Sopenharmony_ci */
2798c2ecf20Sopenharmony_cistatic inline long disable_reloc_on_exceptions(void) {
2808c2ecf20Sopenharmony_ci	return plpar_set_mode(0, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE, 0, 0);
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci/*
2848c2ecf20Sopenharmony_ci * Take exceptions in big endian mode on this partition
2858c2ecf20Sopenharmony_ci *
2868c2ecf20Sopenharmony_ci * Note: this call has a partition wide scope and can take a while to complete.
2878c2ecf20Sopenharmony_ci * If it returns H_LONG_BUSY_* it should be retried periodically until it
2888c2ecf20Sopenharmony_ci * returns H_SUCCESS.
2898c2ecf20Sopenharmony_ci */
2908c2ecf20Sopenharmony_cistatic inline long enable_big_endian_exceptions(void)
2918c2ecf20Sopenharmony_ci{
2928c2ecf20Sopenharmony_ci	/* mflags = 0: big endian exceptions */
2938c2ecf20Sopenharmony_ci	return plpar_set_mode(0, H_SET_MODE_RESOURCE_LE, 0, 0);
2948c2ecf20Sopenharmony_ci}
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci/*
2978c2ecf20Sopenharmony_ci * Take exceptions in little endian mode on this partition
2988c2ecf20Sopenharmony_ci *
2998c2ecf20Sopenharmony_ci * Note: this call has a partition wide scope and can take a while to complete.
3008c2ecf20Sopenharmony_ci * If it returns H_LONG_BUSY_* it should be retried periodically until it
3018c2ecf20Sopenharmony_ci * returns H_SUCCESS.
3028c2ecf20Sopenharmony_ci */
3038c2ecf20Sopenharmony_cistatic inline long enable_little_endian_exceptions(void)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	/* mflags = 1: little endian exceptions */
3068c2ecf20Sopenharmony_ci	return plpar_set_mode(1, H_SET_MODE_RESOURCE_LE, 0, 0);
3078c2ecf20Sopenharmony_ci}
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_cistatic inline long plpar_set_ciabr(unsigned long ciabr)
3108c2ecf20Sopenharmony_ci{
3118c2ecf20Sopenharmony_ci	return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_CIABR, ciabr, 0);
3128c2ecf20Sopenharmony_ci}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_cistatic inline long plpar_set_watchpoint0(unsigned long dawr0, unsigned long dawrx0)
3158c2ecf20Sopenharmony_ci{
3168c2ecf20Sopenharmony_ci	return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR0, dawr0, dawrx0);
3178c2ecf20Sopenharmony_ci}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cistatic inline long plpar_set_watchpoint1(unsigned long dawr1, unsigned long dawrx1)
3208c2ecf20Sopenharmony_ci{
3218c2ecf20Sopenharmony_ci	return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR1, dawr1, dawrx1);
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic inline long plpar_signal_sys_reset(long cpu)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu);
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cistatic inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
3328c2ecf20Sopenharmony_ci	long rc;
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf);
3358c2ecf20Sopenharmony_ci	if (rc == H_SUCCESS) {
3368c2ecf20Sopenharmony_ci		p->character = retbuf[0];
3378c2ecf20Sopenharmony_ci		p->behaviour = retbuf[1];
3388c2ecf20Sopenharmony_ci	}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	return rc;
3418c2ecf20Sopenharmony_ci}
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci/*
3448c2ecf20Sopenharmony_ci * Wrapper to H_RPT_INVALIDATE hcall that handles return values appropriately
3458c2ecf20Sopenharmony_ci *
3468c2ecf20Sopenharmony_ci * - Returns H_SUCCESS on success
3478c2ecf20Sopenharmony_ci * - For H_BUSY return value, we retry the hcall.
3488c2ecf20Sopenharmony_ci * - For any other hcall failures, attempt a full flush once before
3498c2ecf20Sopenharmony_ci *   resorting to BUG().
3508c2ecf20Sopenharmony_ci *
3518c2ecf20Sopenharmony_ci * Note: This hcall is expected to fail only very rarely. The correct
3528c2ecf20Sopenharmony_ci * error recovery of killing the process/guest will be eventually
3538c2ecf20Sopenharmony_ci * needed.
3548c2ecf20Sopenharmony_ci */
3558c2ecf20Sopenharmony_cistatic inline long pseries_rpt_invalidate(u32 pid, u64 target, u64 type,
3568c2ecf20Sopenharmony_ci					  u64 page_sizes, u64 start, u64 end)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	long rc;
3598c2ecf20Sopenharmony_ci	unsigned long all;
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	while (true) {
3628c2ecf20Sopenharmony_ci		rc = plpar_hcall_norets(H_RPT_INVALIDATE, pid, target, type,
3638c2ecf20Sopenharmony_ci					page_sizes, start, end);
3648c2ecf20Sopenharmony_ci		if (rc == H_BUSY) {
3658c2ecf20Sopenharmony_ci			cpu_relax();
3668c2ecf20Sopenharmony_ci			continue;
3678c2ecf20Sopenharmony_ci		} else if (rc == H_SUCCESS)
3688c2ecf20Sopenharmony_ci			return rc;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci		/* Flush request failed, try with a full flush once */
3718c2ecf20Sopenharmony_ci		if (type & H_RPTI_TYPE_NESTED)
3728c2ecf20Sopenharmony_ci			all = H_RPTI_TYPE_NESTED | H_RPTI_TYPE_NESTED_ALL;
3738c2ecf20Sopenharmony_ci		else
3748c2ecf20Sopenharmony_ci			all = H_RPTI_TYPE_ALL;
3758c2ecf20Sopenharmony_ciretry:
3768c2ecf20Sopenharmony_ci		rc = plpar_hcall_norets(H_RPT_INVALIDATE, pid, target,
3778c2ecf20Sopenharmony_ci					all, page_sizes, 0, -1UL);
3788c2ecf20Sopenharmony_ci		if (rc == H_BUSY) {
3798c2ecf20Sopenharmony_ci			cpu_relax();
3808c2ecf20Sopenharmony_ci			goto retry;
3818c2ecf20Sopenharmony_ci		} else if (rc == H_SUCCESS)
3828c2ecf20Sopenharmony_ci			return rc;
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci		BUG();
3858c2ecf20Sopenharmony_ci	}
3868c2ecf20Sopenharmony_ci}
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci#else /* !CONFIG_PPC_PSERIES */
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_cistatic inline long plpar_set_ciabr(unsigned long ciabr)
3918c2ecf20Sopenharmony_ci{
3928c2ecf20Sopenharmony_ci	return 0;
3938c2ecf20Sopenharmony_ci}
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_cistatic inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
3968c2ecf20Sopenharmony_ci				    unsigned long *ptes)
3978c2ecf20Sopenharmony_ci{
3988c2ecf20Sopenharmony_ci	return 0;
3998c2ecf20Sopenharmony_ci}
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_cistatic inline long pseries_rpt_invalidate(u32 pid, u64 target, u64 type,
4028c2ecf20Sopenharmony_ci					  u64 page_sizes, u64 start, u64 end)
4038c2ecf20Sopenharmony_ci{
4048c2ecf20Sopenharmony_ci	return 0;
4058c2ecf20Sopenharmony_ci}
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_PSERIES */
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
410