1#ifndef _PSERIES_PLPAR_WRAPPERS_H 2#define _PSERIES_PLPAR_WRAPPERS_H 3 4#include <asm/hvcall.h> 5#include <asm/page.h> 6 7/* Get state of physical CPU from query_cpu_stopped */ 8int smp_query_cpu_stopped(unsigned int pcpu); 9#define QCSS_STOPPED 0 10#define QCSS_STOPPING 1 11#define QCSS_NOT_STOPPED 2 12#define QCSS_HARDWARE_ERROR -1 13#define QCSS_HARDWARE_BUSY -2 14 15static inline long poll_pending(void) 16{ 17 return plpar_hcall_norets(H_POLL_PENDING); 18} 19 20static inline u8 get_cede_latency_hint(void) 21{ 22 return get_lppaca()->gpr5_dword.fields.cede_latency_hint; 23} 24 25static inline void set_cede_latency_hint(u8 latency_hint) 26{ 27 get_lppaca()->gpr5_dword.fields.cede_latency_hint = latency_hint; 28} 29 30static inline long cede_processor(void) 31{ 32 return plpar_hcall_norets(H_CEDE); 33} 34 35static inline long extended_cede_processor(unsigned long latency_hint) 36{ 37 long rc; 38 u8 old_latency_hint = get_cede_latency_hint(); 39 40 set_cede_latency_hint(latency_hint); 41 rc = cede_processor(); 42 set_cede_latency_hint(old_latency_hint); 43 44 return rc; 45} 46 47static inline long vpa_call(unsigned long flags, unsigned long cpu, 48 unsigned long vpa) 49{ 50 /* flags are in bits 16-18 (counting from most significant bit) */ 51 flags = flags << (63 - 18); 52 53 return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); 54} 55 56static inline long unregister_vpa(unsigned long cpu, unsigned long vpa) 57{ 58 return vpa_call(0x5, cpu, vpa); 59} 60 61static inline long register_vpa(unsigned long cpu, unsigned long vpa) 62{ 63 return vpa_call(0x1, cpu, vpa); 64} 65 66static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa) 67{ 68 return vpa_call(0x7, cpu, vpa); 69} 70 71static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) 72{ 73 return vpa_call(0x3, cpu, vpa); 74} 75 76static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) 77{ 78 return vpa_call(0x6, cpu, vpa); 79} 80 81static inline long register_dtl(unsigned long cpu, unsigned long vpa) 82{ 83 return vpa_call(0x2, cpu, vpa); 84} 85 86static inline long plpar_page_set_loaned(unsigned long vpa) 87{ 88 unsigned long cmo_page_sz = cmo_get_page_size(); 89 long rc = 0; 90 int i; 91 92 for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz) 93 rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0); 94 95 for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz) 96 plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, 97 vpa + i - cmo_page_sz, 0); 98 99 return rc; 100} 101 102static inline long plpar_page_set_active(unsigned long vpa) 103{ 104 unsigned long cmo_page_sz = cmo_get_page_size(); 105 long rc = 0; 106 int i; 107 108 for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz) 109 rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0); 110 111 for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz) 112 plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, 113 vpa + i - cmo_page_sz, 0); 114 115 return rc; 116} 117 118extern void vpa_init(int cpu); 119 120static inline long plpar_pte_enter(unsigned long flags, 121 unsigned long hpte_group, unsigned long hpte_v, 122 unsigned long hpte_r, unsigned long *slot) 123{ 124 long rc; 125 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 126 127 rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r); 128 129 *slot = retbuf[0]; 130 131 return rc; 132} 133 134static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, 135 unsigned long avpn, unsigned long *old_pteh_ret, 136 unsigned long *old_ptel_ret) 137{ 138 long rc; 139 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 140 141 rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn); 142 143 *old_pteh_ret = retbuf[0]; 144 *old_ptel_ret = retbuf[1]; 145 146 return rc; 147} 148 149/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */ 150static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex, 151 unsigned long avpn, unsigned long *old_pteh_ret, 152 unsigned long *old_ptel_ret) 153{ 154 long rc; 155 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 156 157 rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn); 158 159 *old_pteh_ret = retbuf[0]; 160 *old_ptel_ret = retbuf[1]; 161 162 return rc; 163} 164 165static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, 166 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) 167{ 168 long rc; 169 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 170 171 rc = plpar_hcall(H_READ, retbuf, flags, ptex); 172 173 *old_pteh_ret = retbuf[0]; 174 *old_ptel_ret = retbuf[1]; 175 176 return rc; 177} 178 179/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */ 180static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, 181 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) 182{ 183 long rc; 184 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 185 186 rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex); 187 188 *old_pteh_ret = retbuf[0]; 189 *old_ptel_ret = retbuf[1]; 190 191 return rc; 192} 193 194/* 195 * plpar_pte_read_4_raw can be called in real mode. 196 * ptes must be 8*sizeof(unsigned long) 197 */ 198static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex, 199 unsigned long *ptes) 200 201{ 202 long rc; 203 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; 204 205 rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex); 206 207 memcpy(ptes, retbuf, 8*sizeof(unsigned long)); 208 209 return rc; 210} 211 212static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, 213 unsigned long avpn) 214{ 215 return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn); 216} 217 218static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, 219 unsigned long *tce_ret) 220{ 221 long rc; 222 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 223 224 rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba); 225 226 *tce_ret = retbuf[0]; 227 228 return rc; 229} 230 231static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, 232 unsigned long tceval) 233{ 234 return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval); 235} 236 237static inline long plpar_tce_put_indirect(unsigned long liobn, 238 unsigned long ioba, unsigned long page, unsigned long count) 239{ 240 return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count); 241} 242 243static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba, 244 unsigned long tceval, unsigned long count) 245{ 246 return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count); 247} 248 249static inline long plpar_get_term_char(unsigned long termno, 250 unsigned long *len_ret, char *buf_ret) 251{ 252 long rc; 253 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 254 unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ 255 256 rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno); 257 258 *len_ret = retbuf[0]; 259 lbuf[0] = retbuf[1]; 260 lbuf[1] = retbuf[2]; 261 262 return rc; 263} 264 265static inline long plpar_put_term_char(unsigned long termno, unsigned long len, 266 const char *buffer) 267{ 268 unsigned long *lbuf = (unsigned long *)buffer; /* TODO: alignment? */ 269 return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0], 270 lbuf[1]); 271} 272 273static inline long plpar_eoi(unsigned long xirr) 274{ 275 return plpar_hcall_norets(H_EOI, xirr); 276} 277 278static inline long plpar_cppr(unsigned long cppr) 279{ 280 return plpar_hcall_norets(H_CPPR, cppr); 281} 282 283static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr) 284{ 285 return plpar_hcall_norets(H_IPI, servernum, mfrr); 286} 287 288static inline long plpar_xirr(unsigned long *xirr_ret, unsigned char cppr) 289{ 290 long rc; 291 unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 292 293 rc = plpar_hcall(H_XIRR, retbuf, cppr); 294 295 *xirr_ret = retbuf[0]; 296 297 return rc; 298} 299 300#endif /* _PSERIES_PLPAR_WRAPPERS_H */ 301