1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_POWERPC_PLPAR_WRAPPERS_H
3 #define _ASM_POWERPC_PLPAR_WRAPPERS_H
5 #ifdef CONFIG_PPC_PSERIES
7 #include <linux/string.h>
8 #include <linux/irqflags.h>
10 #include <asm/hvcall.h>
14 static inline long poll_pending(void)
16 return plpar_hcall_norets(H_POLL_PENDING
);
19 static inline u8
get_cede_latency_hint(void)
21 return get_lppaca()->cede_latency_hint
;
24 static inline void set_cede_latency_hint(u8 latency_hint
)
26 get_lppaca()->cede_latency_hint
= latency_hint
;
29 static inline long cede_processor(void)
31 return plpar_hcall_norets(H_CEDE
);
34 static inline long extended_cede_processor(unsigned long latency_hint
)
37 u8 old_latency_hint
= get_cede_latency_hint();
39 set_cede_latency_hint(latency_hint
);
41 rc
= cede_processor();
42 #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
43 /* Ensure that H_CEDE returns with IRQs on */
44 if (WARN_ON(!(mfmsr() & MSR_EE
)))
48 set_cede_latency_hint(old_latency_hint
);
53 static inline long vpa_call(unsigned long flags
, unsigned long cpu
,
56 flags
= flags
<< H_VPA_FUNC_SHIFT
;
58 return plpar_hcall_norets(H_REGISTER_VPA
, flags
, cpu
, vpa
);
61 static inline long unregister_vpa(unsigned long cpu
)
63 return vpa_call(H_VPA_DEREG_VPA
, cpu
, 0);
66 static inline long register_vpa(unsigned long cpu
, unsigned long vpa
)
68 return vpa_call(H_VPA_REG_VPA
, cpu
, vpa
);
71 static inline long unregister_slb_shadow(unsigned long cpu
)
73 return vpa_call(H_VPA_DEREG_SLB
, cpu
, 0);
76 static inline long register_slb_shadow(unsigned long cpu
, unsigned long vpa
)
78 return vpa_call(H_VPA_REG_SLB
, cpu
, vpa
);
81 static inline long unregister_dtl(unsigned long cpu
)
83 return vpa_call(H_VPA_DEREG_DTL
, cpu
, 0);
86 static inline long register_dtl(unsigned long cpu
, unsigned long vpa
)
88 return vpa_call(H_VPA_REG_DTL
, cpu
, vpa
);
91 extern void vpa_init(int cpu
);
93 static inline long plpar_pte_enter(unsigned long flags
,
94 unsigned long hpte_group
, unsigned long hpte_v
,
95 unsigned long hpte_r
, unsigned long *slot
)
98 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
100 rc
= plpar_hcall(H_ENTER
, retbuf
, flags
, hpte_group
, hpte_v
, hpte_r
);
107 static inline long plpar_pte_remove(unsigned long flags
, unsigned long ptex
,
108 unsigned long avpn
, unsigned long *old_pteh_ret
,
109 unsigned long *old_ptel_ret
)
112 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
114 rc
= plpar_hcall(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
116 *old_pteh_ret
= retbuf
[0];
117 *old_ptel_ret
= retbuf
[1];
122 /* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
123 static inline long plpar_pte_remove_raw(unsigned long flags
, unsigned long ptex
,
124 unsigned long avpn
, unsigned long *old_pteh_ret
,
125 unsigned long *old_ptel_ret
)
128 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
130 rc
= plpar_hcall_raw(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
132 *old_pteh_ret
= retbuf
[0];
133 *old_ptel_ret
= retbuf
[1];
138 static inline long plpar_pte_read(unsigned long flags
, unsigned long ptex
,
139 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
142 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
144 rc
= plpar_hcall(H_READ
, retbuf
, flags
, ptex
);
146 *old_pteh_ret
= retbuf
[0];
147 *old_ptel_ret
= retbuf
[1];
152 /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
153 static inline long plpar_pte_read_raw(unsigned long flags
, unsigned long ptex
,
154 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
157 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
159 rc
= plpar_hcall_raw(H_READ
, retbuf
, flags
, ptex
);
161 *old_pteh_ret
= retbuf
[0];
162 *old_ptel_ret
= retbuf
[1];
168 * ptes must be 8*sizeof(unsigned long)
170 static inline long plpar_pte_read_4(unsigned long flags
, unsigned long ptex
,
175 unsigned long retbuf
[PLPAR_HCALL9_BUFSIZE
];
177 rc
= plpar_hcall9(H_READ
, retbuf
, flags
| H_READ_4
, ptex
);
179 memcpy(ptes
, retbuf
, 8*sizeof(unsigned long));
185 * plpar_pte_read_4_raw can be called in real mode.
186 * ptes must be 8*sizeof(unsigned long)
188 static inline long plpar_pte_read_4_raw(unsigned long flags
, unsigned long ptex
,
193 unsigned long retbuf
[PLPAR_HCALL9_BUFSIZE
];
195 rc
= plpar_hcall9_raw(H_READ
, retbuf
, flags
| H_READ_4
, ptex
);
197 memcpy(ptes
, retbuf
, 8*sizeof(unsigned long));
202 static inline long plpar_pte_protect(unsigned long flags
, unsigned long ptex
,
205 return plpar_hcall_norets(H_PROTECT
, flags
, ptex
, avpn
);
208 static inline long plpar_resize_hpt_prepare(unsigned long flags
,
211 return plpar_hcall_norets(H_RESIZE_HPT_PREPARE
, flags
, shift
);
214 static inline long plpar_resize_hpt_commit(unsigned long flags
,
217 return plpar_hcall_norets(H_RESIZE_HPT_COMMIT
, flags
, shift
);
220 static inline long plpar_tce_get(unsigned long liobn
, unsigned long ioba
,
221 unsigned long *tce_ret
)
224 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
226 rc
= plpar_hcall(H_GET_TCE
, retbuf
, liobn
, ioba
);
228 *tce_ret
= retbuf
[0];
233 static inline long plpar_tce_put(unsigned long liobn
, unsigned long ioba
,
234 unsigned long tceval
)
236 return plpar_hcall_norets(H_PUT_TCE
, liobn
, ioba
, tceval
);
239 static inline long plpar_tce_put_indirect(unsigned long liobn
,
240 unsigned long ioba
, unsigned long page
, unsigned long count
)
242 return plpar_hcall_norets(H_PUT_TCE_INDIRECT
, liobn
, ioba
, page
, count
);
245 static inline long plpar_tce_stuff(unsigned long liobn
, unsigned long ioba
,
246 unsigned long tceval
, unsigned long count
)
248 return plpar_hcall_norets(H_STUFF_TCE
, liobn
, ioba
, tceval
, count
);
251 /* Set various resource mode parameters */
252 static inline long plpar_set_mode(unsigned long mflags
, unsigned long resource
,
253 unsigned long value1
, unsigned long value2
)
255 return plpar_hcall_norets(H_SET_MODE
, mflags
, resource
, value1
, value2
);
259 * Enable relocation on exceptions on this partition
261 * Note: this call has a partition wide scope and can take a while to complete.
262 * If it returns H_LONG_BUSY_* it should be retried periodically until it
265 static inline long enable_reloc_on_exceptions(void)
267 /* mflags = 3: Exceptions at 0xC000000000004000 */
268 return plpar_set_mode(3, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE
, 0, 0);
272 * Disable relocation on exceptions on this partition
274 * Note: this call has a partition wide scope and can take a while to complete.
275 * If it returns H_LONG_BUSY_* it should be retried periodically until it
278 static inline long disable_reloc_on_exceptions(void) {
279 return plpar_set_mode(0, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE
, 0, 0);
283 * Take exceptions in big endian mode on this partition
285 * Note: this call has a partition wide scope and can take a while to complete.
286 * If it returns H_LONG_BUSY_* it should be retried periodically until it
289 static inline long enable_big_endian_exceptions(void)
291 /* mflags = 0: big endian exceptions */
292 return plpar_set_mode(0, H_SET_MODE_RESOURCE_LE
, 0, 0);
296 * Take exceptions in little endian mode on this partition
298 * Note: this call has a partition wide scope and can take a while to complete.
299 * If it returns H_LONG_BUSY_* it should be retried periodically until it
302 static inline long enable_little_endian_exceptions(void)
304 /* mflags = 1: little endian exceptions */
305 return plpar_set_mode(1, H_SET_MODE_RESOURCE_LE
, 0, 0);
308 static inline long plpar_set_ciabr(unsigned long ciabr
)
310 return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_CIABR
, ciabr
, 0);
313 static inline long plpar_set_watchpoint0(unsigned long dawr0
, unsigned long dawrx0
)
315 return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR
, dawr0
, dawrx0
);
318 static inline long plpar_signal_sys_reset(long cpu
)
320 return plpar_hcall_norets(H_SIGNAL_SYS_RESET
, cpu
);
323 static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result
*p
)
325 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
328 rc
= plpar_hcall(H_GET_CPU_CHARACTERISTICS
, retbuf
);
329 if (rc
== H_SUCCESS
) {
330 p
->character
= retbuf
[0];
331 p
->behaviour
= retbuf
[1];
337 #else /* !CONFIG_PPC_PSERIES */
339 static inline long plpar_set_ciabr(unsigned long ciabr
)
344 static inline long plpar_pte_read_4(unsigned long flags
, unsigned long ptex
,
349 #endif /* CONFIG_PPC_PSERIES */
351 #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */