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