1 #ifndef _PSERIES_PLPAR_WRAPPERS_H
2 #define _PSERIES_PLPAR_WRAPPERS_H
4 #include <linux/string.h>
6 #include <asm/hvcall.h>
10 /* Get state of physical CPU from query_cpu_stopped */
11 int smp_query_cpu_stopped(unsigned int pcpu
);
12 #define QCSS_STOPPED 0
13 #define QCSS_STOPPING 1
14 #define QCSS_NOT_STOPPED 2
15 #define QCSS_HARDWARE_ERROR -1
16 #define QCSS_HARDWARE_BUSY -2
18 static inline long poll_pending(void)
20 return plpar_hcall_norets(H_POLL_PENDING
);
23 static inline u8
get_cede_latency_hint(void)
25 return get_lppaca()->gpr5_dword
.fields
.cede_latency_hint
;
28 static inline void set_cede_latency_hint(u8 latency_hint
)
30 get_lppaca()->gpr5_dword
.fields
.cede_latency_hint
= latency_hint
;
33 static inline long cede_processor(void)
35 return plpar_hcall_norets(H_CEDE
);
38 static inline long extended_cede_processor(unsigned long latency_hint
)
41 u8 old_latency_hint
= get_cede_latency_hint();
43 set_cede_latency_hint(latency_hint
);
44 rc
= cede_processor();
45 set_cede_latency_hint(old_latency_hint
);
50 static inline long vpa_call(unsigned long flags
, unsigned long cpu
,
53 /* flags are in bits 16-18 (counting from most significant bit) */
54 flags
= flags
<< (63 - 18);
56 return plpar_hcall_norets(H_REGISTER_VPA
, flags
, cpu
, vpa
);
59 static inline long unregister_vpa(unsigned long cpu
)
61 return vpa_call(0x5, cpu
, 0);
64 static inline long register_vpa(unsigned long cpu
, unsigned long vpa
)
66 return vpa_call(0x1, cpu
, vpa
);
69 static inline long unregister_slb_shadow(unsigned long cpu
)
71 return vpa_call(0x7, cpu
, 0);
74 static inline long register_slb_shadow(unsigned long cpu
, unsigned long vpa
)
76 return vpa_call(0x3, cpu
, vpa
);
79 static inline long unregister_dtl(unsigned long cpu
)
81 return vpa_call(0x6, cpu
, 0);
84 static inline long register_dtl(unsigned long cpu
, unsigned long vpa
)
86 return vpa_call(0x2, cpu
, vpa
);
89 static inline long plpar_page_set_loaned(unsigned long vpa
)
91 unsigned long cmo_page_sz
= cmo_get_page_size();
95 for (i
= 0; !rc
&& i
< PAGE_SIZE
; i
+= cmo_page_sz
)
96 rc
= plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_LOANED
, vpa
+ i
, 0);
98 for (i
-= cmo_page_sz
; rc
&& i
!= 0; i
-= cmo_page_sz
)
99 plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_ACTIVE
,
100 vpa
+ i
- cmo_page_sz
, 0);
105 static inline long plpar_page_set_active(unsigned long vpa
)
107 unsigned long cmo_page_sz
= cmo_get_page_size();
111 for (i
= 0; !rc
&& i
< PAGE_SIZE
; i
+= cmo_page_sz
)
112 rc
= plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_ACTIVE
, vpa
+ i
, 0);
114 for (i
-= cmo_page_sz
; rc
&& i
!= 0; i
-= cmo_page_sz
)
115 plpar_hcall_norets(H_PAGE_INIT
, H_PAGE_SET_LOANED
,
116 vpa
+ i
- cmo_page_sz
, 0);
121 extern void vpa_init(int cpu
);
123 static inline long plpar_pte_enter(unsigned long flags
,
124 unsigned long hpte_group
, unsigned long hpte_v
,
125 unsigned long hpte_r
, unsigned long *slot
)
128 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
130 rc
= plpar_hcall(H_ENTER
, retbuf
, flags
, hpte_group
, hpte_v
, hpte_r
);
137 static inline long plpar_pte_remove(unsigned long flags
, unsigned long ptex
,
138 unsigned long avpn
, unsigned long *old_pteh_ret
,
139 unsigned long *old_ptel_ret
)
142 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
144 rc
= plpar_hcall(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
146 *old_pteh_ret
= retbuf
[0];
147 *old_ptel_ret
= retbuf
[1];
152 /* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
153 static inline long plpar_pte_remove_raw(unsigned long flags
, unsigned long ptex
,
154 unsigned long avpn
, unsigned long *old_pteh_ret
,
155 unsigned long *old_ptel_ret
)
158 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
160 rc
= plpar_hcall_raw(H_REMOVE
, retbuf
, flags
, ptex
, avpn
);
162 *old_pteh_ret
= retbuf
[0];
163 *old_ptel_ret
= retbuf
[1];
168 static inline long plpar_pte_read(unsigned long flags
, unsigned long ptex
,
169 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
172 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
174 rc
= plpar_hcall(H_READ
, retbuf
, flags
, ptex
);
176 *old_pteh_ret
= retbuf
[0];
177 *old_ptel_ret
= retbuf
[1];
182 /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
183 static inline long plpar_pte_read_raw(unsigned long flags
, unsigned long ptex
,
184 unsigned long *old_pteh_ret
, unsigned long *old_ptel_ret
)
187 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
189 rc
= plpar_hcall_raw(H_READ
, retbuf
, flags
, ptex
);
191 *old_pteh_ret
= retbuf
[0];
192 *old_ptel_ret
= retbuf
[1];
198 * plpar_pte_read_4_raw can be called in real mode.
199 * ptes must be 8*sizeof(unsigned long)
201 static inline long plpar_pte_read_4_raw(unsigned long flags
, unsigned long ptex
,
206 unsigned long retbuf
[PLPAR_HCALL9_BUFSIZE
];
208 rc
= plpar_hcall9_raw(H_READ
, retbuf
, flags
| H_READ_4
, ptex
);
210 memcpy(ptes
, retbuf
, 8*sizeof(unsigned long));
215 static inline long plpar_pte_protect(unsigned long flags
, unsigned long ptex
,
218 return plpar_hcall_norets(H_PROTECT
, flags
, ptex
, avpn
);
221 static inline long plpar_tce_get(unsigned long liobn
, unsigned long ioba
,
222 unsigned long *tce_ret
)
225 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
227 rc
= plpar_hcall(H_GET_TCE
, retbuf
, liobn
, ioba
);
229 *tce_ret
= retbuf
[0];
234 static inline long plpar_tce_put(unsigned long liobn
, unsigned long ioba
,
235 unsigned long tceval
)
237 return plpar_hcall_norets(H_PUT_TCE
, liobn
, ioba
, tceval
);
240 static inline long plpar_tce_put_indirect(unsigned long liobn
,
241 unsigned long ioba
, unsigned long page
, unsigned long count
)
243 return plpar_hcall_norets(H_PUT_TCE_INDIRECT
, liobn
, ioba
, page
, count
);
246 static inline long plpar_tce_stuff(unsigned long liobn
, unsigned long ioba
,
247 unsigned long tceval
, unsigned long count
)
249 return plpar_hcall_norets(H_STUFF_TCE
, liobn
, ioba
, tceval
, count
);
252 static inline long plpar_get_term_char(unsigned long termno
,
253 unsigned long *len_ret
, char *buf_ret
)
256 unsigned long retbuf
[PLPAR_HCALL_BUFSIZE
];
257 unsigned long *lbuf
= (unsigned long *)buf_ret
; /* TODO: alignment? */
259 rc
= plpar_hcall(H_GET_TERM_CHAR
, retbuf
, termno
);
261 *len_ret
= retbuf
[0];
268 static inline long plpar_put_term_char(unsigned long termno
, unsigned long len
,
271 unsigned long *lbuf
= (unsigned long *)buffer
; /* TODO: alignment? */
272 return plpar_hcall_norets(H_PUT_TERM_CHAR
, termno
, len
, lbuf
[0],
276 #endif /* _PSERIES_PLPAR_WRAPPERS_H */