1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_POWERPC_PLPAR_WRAPPERS_H
3 #define _ASM_POWERPC_PLPAR_WRAPPERS_H
5 #include <linux/string.h>
6 #include <linux/irqflags.h>
8 #include <asm/hvcall.h>
12 /* Get state of physical CPU from query_cpu_stopped */
13 int smp_query_cpu_stopped(unsigned int pcpu
);
14 #define QCSS_STOPPED 0
15 #define QCSS_STOPPING 1
16 #define QCSS_NOT_STOPPED 2
17 #define QCSS_HARDWARE_ERROR -1
18 #define QCSS_HARDWARE_BUSY -2
20 static inline long poll_pending(void)
22 return plpar_hcall_norets(H_POLL_PENDING
);
25 static inline u8
get_cede_latency_hint(void)
27 return get_lppaca()->cede_latency_hint
;
30 static inline void set_cede_latency_hint(u8 latency_hint
)
32 get_lppaca()->cede_latency_hint
= latency_hint
;
35 static inline long cede_processor(void)
37 return plpar_hcall_norets(H_CEDE
);
40 static inline long extended_cede_processor(unsigned long latency_hint
)
43 u8 old_latency_hint
= get_cede_latency_hint();
45 set_cede_latency_hint(latency_hint
);
47 rc
= cede_processor();
48 #ifdef CONFIG_TRACE_IRQFLAGS
49 /* Ensure that H_CEDE returns with IRQs on */
50 if (WARN_ON(!(mfmsr() & MSR_EE
)))
54 set_cede_latency_hint(old_latency_hint
);
59 static inline long vpa_call(unsigned long flags
, unsigned long cpu
,
62 flags
= flags
<< H_VPA_FUNC_SHIFT
;
64 return plpar_hcall_norets(H_REGISTER_VPA
, flags
, cpu
, vpa
);
67 static inline long unregister_vpa(unsigned long cpu
)
69 return vpa_call(H_VPA_DEREG_VPA
, cpu
, 0);
72 static inline long register_vpa(unsigned long cpu
, unsigned long vpa
)
74 return vpa_call(H_VPA_REG_VPA
, cpu
, vpa
);
77 static inline long unregister_slb_shadow(unsigned long cpu
)
79 return vpa_call(H_VPA_DEREG_SLB
, cpu
, 0);
82 static inline long register_slb_shadow(unsigned long cpu
, unsigned long vpa
)
84 return vpa_call(H_VPA_REG_SLB
, cpu
, vpa
);
87 static inline long unregister_dtl(unsigned long cpu
)
89 return vpa_call(H_VPA_DEREG_DTL
, cpu
, 0);
92 static inline long register_dtl(unsigned long cpu
, unsigned long vpa
)
94 return vpa_call(H_VPA_REG_DTL
, cpu
, vpa
);
97 extern void vpa_init(int cpu
);
99 static inline long plpar_pte_enter(unsigned long flags
,
100 unsigned long hpte_group
, unsigned long hpte_v
,
101 unsigned long hpte_r
, unsigned long *slot
)
104 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
106 rc
= plpar_hcall(H_ENTER
, retbuf
, flags
, hpte_group
, hpte_v
, hpte_r
);
113 static inline long plpar_pte_remove(unsigned long flags
, unsigned long ptex
,
114 unsigned long avpn
, unsigned long *old_pteh_ret
,
115 unsigned long *old_ptel_ret
)
118 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
120 rc
= plpar_hcall(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
122 *old_pteh_ret
= retbuf
[0];
123 *old_ptel_ret
= retbuf
[1];
128 /* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
129 static inline long plpar_pte_remove_raw(unsigned long flags
, unsigned long ptex
,
130 unsigned long avpn
, unsigned long *old_pteh_ret
,
131 unsigned long *old_ptel_ret
)
134 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
136 rc
= plpar_hcall_raw(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
138 *old_pteh_ret
= retbuf
[0];
139 *old_ptel_ret
= retbuf
[1];
144 static inline long plpar_pte_read(unsigned long flags
, unsigned long ptex
,
145 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
148 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
150 rc
= plpar_hcall(H_READ
, retbuf
, flags
, ptex
);
152 *old_pteh_ret
= retbuf
[0];
153 *old_ptel_ret
= retbuf
[1];
158 /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
159 static inline long plpar_pte_read_raw(unsigned long flags
, unsigned long ptex
,
160 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
163 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
165 rc
= plpar_hcall_raw(H_READ
, retbuf
, flags
, ptex
);
167 *old_pteh_ret
= retbuf
[0];
168 *old_ptel_ret
= retbuf
[1];
174 * ptes must be 8*sizeof(unsigned long)
176 static inline long plpar_pte_read_4(unsigned long flags
, unsigned long ptex
,
181 unsigned long retbuf
[PLPAR_HCALL9_BUFSIZE
];
183 rc
= plpar_hcall9(H_READ
, retbuf
, flags
| H_READ_4
, ptex
);
185 memcpy(ptes
, retbuf
, 8*sizeof(unsigned long));
191 * plpar_pte_read_4_raw can be called in real mode.
192 * ptes must be 8*sizeof(unsigned long)
194 static inline long plpar_pte_read_4_raw(unsigned long flags
, unsigned long ptex
,
199 unsigned long retbuf
[PLPAR_HCALL9_BUFSIZE
];
201 rc
= plpar_hcall9_raw(H_READ
, retbuf
, flags
| H_READ_4
, ptex
);
203 memcpy(ptes
, retbuf
, 8*sizeof(unsigned long));
208 static inline long plpar_pte_protect(unsigned long flags
, unsigned long ptex
,
211 return plpar_hcall_norets(H_PROTECT
, flags
, ptex
, avpn
);
214 static inline long plpar_resize_hpt_prepare(unsigned long flags
,
217 return plpar_hcall_norets(H_RESIZE_HPT_PREPARE
, flags
, shift
);
220 static inline long plpar_resize_hpt_commit(unsigned long flags
,
223 return plpar_hcall_norets(H_RESIZE_HPT_COMMIT
, flags
, shift
);
226 static inline long plpar_tce_get(unsigned long liobn
, unsigned long ioba
,
227 unsigned long *tce_ret
)
230 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
232 rc
= plpar_hcall(H_GET_TCE
, retbuf
, liobn
, ioba
);
234 *tce_ret
= retbuf
[0];
239 static inline long plpar_tce_put(unsigned long liobn
, unsigned long ioba
,
240 unsigned long tceval
)
242 return plpar_hcall_norets(H_PUT_TCE
, liobn
, ioba
, tceval
);
245 static inline long plpar_tce_put_indirect(unsigned long liobn
,
246 unsigned long ioba
, unsigned long page
, unsigned long count
)
248 return plpar_hcall_norets(H_PUT_TCE_INDIRECT
, liobn
, ioba
, page
, count
);
251 static inline long plpar_tce_stuff(unsigned long liobn
, unsigned long ioba
,
252 unsigned long tceval
, unsigned long count
)
254 return plpar_hcall_norets(H_STUFF_TCE
, liobn
, ioba
, tceval
, count
);
257 /* Set various resource mode parameters */
258 static inline long plpar_set_mode(unsigned long mflags
, unsigned long resource
,
259 unsigned long value1
, unsigned long value2
)
261 return plpar_hcall_norets(H_SET_MODE
, mflags
, resource
, value1
, value2
);
265 * Enable relocation on exceptions on this partition
267 * Note: this call has a partition wide scope and can take a while to complete.
268 * If it returns H_LONG_BUSY_* it should be retried periodically until it
271 static inline long enable_reloc_on_exceptions(void)
273 /* mflags = 3: Exceptions at 0xC000000000004000 */
274 return plpar_set_mode(3, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE
, 0, 0);
278 * Disable relocation on exceptions on this partition
280 * Note: this call has a partition wide scope and can take a while to complete.
281 * If it returns H_LONG_BUSY_* it should be retried periodically until it
284 static inline long disable_reloc_on_exceptions(void) {
285 return plpar_set_mode(0, H_SET_MODE_RESOURCE_ADDR_TRANS_MODE
, 0, 0);
289 * Take exceptions in big endian mode on this partition
291 * Note: this call has a partition wide scope and can take a while to complete.
292 * If it returns H_LONG_BUSY_* it should be retried periodically until it
295 static inline long enable_big_endian_exceptions(void)
297 /* mflags = 0: big endian exceptions */
298 return plpar_set_mode(0, H_SET_MODE_RESOURCE_LE
, 0, 0);
302 * Take exceptions in little endian mode on this partition
304 * Note: this call has a partition wide scope and can take a while to complete.
305 * If it returns H_LONG_BUSY_* it should be retried periodically until it
308 static inline long enable_little_endian_exceptions(void)
310 /* mflags = 1: little endian exceptions */
311 return plpar_set_mode(1, H_SET_MODE_RESOURCE_LE
, 0, 0);
314 static inline long plapr_set_ciabr(unsigned long ciabr
)
316 return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_CIABR
, ciabr
, 0);
319 static inline long plapr_set_watchpoint0(unsigned long dawr0
, unsigned long dawrx0
)
321 return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR
, dawr0
, dawrx0
);
324 static inline long plapr_signal_sys_reset(long cpu
)
326 return plpar_hcall_norets(H_SIGNAL_SYS_RESET
, cpu
);
329 static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result
*p
)
331 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
334 rc
= plpar_hcall(H_GET_CPU_CHARACTERISTICS
, retbuf
);
335 if (rc
== H_SUCCESS
) {
336 p
->character
= retbuf
[0];
337 p
->behaviour
= retbuf
[1];
343 #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */