1 #ifndef _ASM_POWERPC_PLPAR_WRAPPERS_H
2 #define _ASM_POWERPC_PLPAR_WRAPPERS_H
4 #include <linux/string.h>
5 #include <linux/irqflags.h>
7 #include <asm/hvcall.h>
11 /* Get state of physical CPU from query_cpu_stopped */
12 int smp_query_cpu_stopped(unsigned int pcpu
);
13 #define QCSS_STOPPED 0
14 #define QCSS_STOPPING 1
15 #define QCSS_NOT_STOPPED 2
16 #define QCSS_HARDWARE_ERROR -1
17 #define QCSS_HARDWARE_BUSY -2
19 static inline long poll_pending(void)
21 return plpar_hcall_norets(H_POLL_PENDING
);
24 static inline u8
get_cede_latency_hint(void)
26 return get_lppaca()->cede_latency_hint
;
29 static inline void set_cede_latency_hint(u8 latency_hint
)
31 get_lppaca()->cede_latency_hint
= latency_hint
;
34 static inline long cede_processor(void)
36 return plpar_hcall_norets(H_CEDE
);
39 static inline long extended_cede_processor(unsigned long latency_hint
)
42 u8 old_latency_hint
= get_cede_latency_hint();
44 set_cede_latency_hint(latency_hint
);
46 rc
= cede_processor();
47 #ifdef CONFIG_TRACE_IRQFLAGS
48 /* Ensure that H_CEDE returns with IRQs on */
49 if (WARN_ON(!(mfmsr() & MSR_EE
)))
53 set_cede_latency_hint(old_latency_hint
);
58 static inline long vpa_call(unsigned long flags
, unsigned long cpu
,
61 flags
= flags
<< H_VPA_FUNC_SHIFT
;
63 return plpar_hcall_norets(H_REGISTER_VPA
, flags
, cpu
, vpa
);
66 static inline long unregister_vpa(unsigned long cpu
)
68 return vpa_call(H_VPA_DEREG_VPA
, cpu
, 0);
71 static inline long register_vpa(unsigned long cpu
, unsigned long vpa
)
73 return vpa_call(H_VPA_REG_VPA
, cpu
, vpa
);
76 static inline long unregister_slb_shadow(unsigned long cpu
)
78 return vpa_call(H_VPA_DEREG_SLB
, cpu
, 0);
81 static inline long register_slb_shadow(unsigned long cpu
, unsigned long vpa
)
83 return vpa_call(H_VPA_REG_SLB
, cpu
, vpa
);
86 static inline long unregister_dtl(unsigned long cpu
)
88 return vpa_call(H_VPA_DEREG_DTL
, cpu
, 0);
91 static inline long register_dtl(unsigned long cpu
, unsigned long vpa
)
93 return vpa_call(H_VPA_REG_DTL
, cpu
, vpa
);
96 static inline long plpar_page_set_loaned(unsigned long vpa
)
98 unsigned long cmo_page_sz
= cmo_get_page_size();
102 for (i
= 0; !rc
&& i
< PAGE_SIZE
; i
+= cmo_page_sz
)
103 rc
= plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_LOANED
, vpa
+ i
, 0);
105 for (i
-= cmo_page_sz
; rc
&& i
!= 0; i
-= cmo_page_sz
)
106 plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_ACTIVE
,
107 vpa
+ i
- cmo_page_sz
, 0);
112 static inline long plpar_page_set_active(unsigned long vpa
)
114 unsigned long cmo_page_sz
= cmo_get_page_size();
118 for (i
= 0; !rc
&& i
< PAGE_SIZE
; i
+= cmo_page_sz
)
119 rc
= plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_ACTIVE
, vpa
+ i
, 0);
121 for (i
-= cmo_page_sz
; rc
&& i
!= 0; i
-= cmo_page_sz
)
122 plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_LOANED
,
123 vpa
+ i
- cmo_page_sz
, 0);
128 extern void vpa_init(int cpu
);
130 static inline long plpar_pte_enter(unsigned long flags
,
131 unsigned long hpte_group
, unsigned long hpte_v
,
132 unsigned long hpte_r
, unsigned long *slot
)
135 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
137 rc
= plpar_hcall(H_ENTER
, retbuf
, flags
, hpte_group
, hpte_v
, hpte_r
);
144 static inline long plpar_pte_remove(unsigned long flags
, unsigned long ptex
,
145 unsigned long avpn
, unsigned long *old_pteh_ret
,
146 unsigned long *old_ptel_ret
)
149 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
151 rc
= plpar_hcall(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
153 *old_pteh_ret
= retbuf
[0];
154 *old_ptel_ret
= retbuf
[1];
159 /* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
160 static inline long plpar_pte_remove_raw(unsigned long flags
, unsigned long ptex
,
161 unsigned long avpn
, unsigned long *old_pteh_ret
,
162 unsigned long *old_ptel_ret
)
165 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
167 rc
= plpar_hcall_raw(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
169 *old_pteh_ret
= retbuf
[0];
170 *old_ptel_ret
= retbuf
[1];
175 static inline long plpar_pte_read(unsigned long flags
, unsigned long ptex
,
176 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
179 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
181 rc
= plpar_hcall(H_READ
, retbuf
, flags
, ptex
);
183 *old_pteh_ret
= retbuf
[0];
184 *old_ptel_ret
= retbuf
[1];
189 /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
190 static inline long plpar_pte_read_raw(unsigned long flags
, unsigned long ptex
,
191 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
194 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
196 rc
= plpar_hcall_raw(H_READ
, retbuf
, flags
, ptex
);
198 *old_pteh_ret
= retbuf
[0];
199 *old_ptel_ret
= retbuf
[1];
205 * plpar_pte_read_4_raw can be called in real mode.
206 * ptes must be 8*sizeof(unsigned long)
208 static inline long plpar_pte_read_4_raw(unsigned long flags
, unsigned long ptex
,
213 unsigned long retbuf
[PLPAR_HCALL9_BUFSIZE
];
215 rc
= plpar_hcall9_raw(H_READ
, retbuf
, flags
| H_READ_4
, ptex
);
217 memcpy(ptes
, retbuf
, 8*sizeof(unsigned long));
222 static inline long plpar_pte_protect(unsigned long flags
, unsigned long ptex
,
225 return plpar_hcall_norets(H_PROTECT
, flags
, ptex
, avpn
);
228 static inline long plpar_tce_get(unsigned long liobn
, unsigned long ioba
,
229 unsigned long *tce_ret
)
232 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
234 rc
= plpar_hcall(H_GET_TCE
, retbuf
, liobn
, ioba
);
236 *tce_ret
= retbuf
[0];
241 static inline long plpar_tce_put(unsigned long liobn
, unsigned long ioba
,
242 unsigned long tceval
)
244 return plpar_hcall_norets(H_PUT_TCE
, liobn
, ioba
, tceval
);
247 static inline long plpar_tce_put_indirect(unsigned long liobn
,
248 unsigned long ioba
, unsigned long page
, unsigned long count
)
250 return plpar_hcall_norets(H_PUT_TCE_INDIRECT
, liobn
, ioba
, page
, count
);
253 static inline long plpar_tce_stuff(unsigned long liobn
, unsigned long ioba
,
254 unsigned long tceval
, unsigned long count
)
256 return plpar_hcall_norets(H_STUFF_TCE
, liobn
, ioba
, tceval
, count
);
259 /* Set various resource mode parameters */
260 static inline long plpar_set_mode(unsigned long mflags
, unsigned long resource
,
261 unsigned long value1
, unsigned long value2
)
263 return plpar_hcall_norets(H_SET_MODE
, mflags
, resource
, value1
, value2
);
267 * Enable relocation on exceptions on this partition
269 * Note: this call has a partition wide scope and can take a while to complete.
270 * If it returns H_LONG_BUSY_* it should be retried periodically until it
273 static inline long enable_reloc_on_exceptions(void)
275 /* mflags = 3: Exceptions at 0xC000000000004000 */
276 return plpar_set_mode(3, 3, 0, 0);
280 * Disable relocation on exceptions on this partition
282 * Note: this call has a partition wide scope and can take a while to complete.
283 * If it returns H_LONG_BUSY_* it should be retried periodically until it
286 static inline long disable_reloc_on_exceptions(void) {
287 return plpar_set_mode(0, 3, 0, 0);
291 * Take exceptions in big endian mode on this partition
293 * Note: this call has a partition wide scope and can take a while to complete.
294 * If it returns H_LONG_BUSY_* it should be retried periodically until it
297 static inline long enable_big_endian_exceptions(void)
299 /* mflags = 0: big endian exceptions */
300 return plpar_set_mode(0, 4, 0, 0);
304 * Take exceptions in little endian mode on this partition
306 * Note: this call has a partition wide scope and can take a while to complete.
307 * If it returns H_LONG_BUSY_* it should be retried periodically until it
310 static inline long enable_little_endian_exceptions(void)
312 /* mflags = 1: little endian exceptions */
313 return plpar_set_mode(1, 4, 0, 0);
316 static inline long plapr_set_ciabr(unsigned long ciabr
)
318 return plpar_set_mode(0, 1, ciabr
, 0);
321 static inline long plapr_set_watchpoint0(unsigned long dawr0
, unsigned long dawrx0
)
323 return plpar_set_mode(0, 2, dawr0
, dawrx0
);
326 #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */