Merge branch 'master' into for-linus
[linux-2.6] / arch / powerpc / platforms / pseries / plpar_wrappers.h
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 static inline long poll_pending(void)
8 {
9         return plpar_hcall_norets(H_POLL_PENDING);
10 }
11
12 static inline long cede_processor(void)
13 {
14         return plpar_hcall_norets(H_CEDE);
15 }
16
17 static inline long vpa_call(unsigned long flags, unsigned long cpu,
18                 unsigned long vpa)
19 {
20         /* flags are in bits 16-18 (counting from most significant bit) */
21         flags = flags << (63 - 18);
22
23         return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
24 }
25
26 static inline long unregister_vpa(unsigned long cpu, unsigned long vpa)
27 {
28         return vpa_call(0x5, cpu, vpa);
29 }
30
31 static inline long register_vpa(unsigned long cpu, unsigned long vpa)
32 {
33         return vpa_call(0x1, cpu, vpa);
34 }
35
36 static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa)
37 {
38         return vpa_call(0x7, cpu, vpa);
39 }
40
41 static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
42 {
43         return vpa_call(0x3, cpu, vpa);
44 }
45
46 static inline long unregister_dtl(unsigned long cpu, unsigned long vpa)
47 {
48         return vpa_call(0x6, cpu, vpa);
49 }
50
51 static inline long register_dtl(unsigned long cpu, unsigned long vpa)
52 {
53         return vpa_call(0x2, cpu, vpa);
54 }
55
56 static inline long plpar_page_set_loaned(unsigned long vpa)
57 {
58         unsigned long cmo_page_sz = cmo_get_page_size();
59         long rc = 0;
60         int i;
61
62         for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
63                 rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0);
64
65         for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
66                 plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE,
67                                    vpa + i - cmo_page_sz, 0);
68
69         return rc;
70 }
71
72 static inline long plpar_page_set_active(unsigned long vpa)
73 {
74         unsigned long cmo_page_sz = cmo_get_page_size();
75         long rc = 0;
76         int i;
77
78         for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
79                 rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0);
80
81         for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
82                 plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED,
83                                    vpa + i - cmo_page_sz, 0);
84
85         return rc;
86 }
87
88 extern void vpa_init(int cpu);
89
90 static inline long plpar_pte_enter(unsigned long flags,
91                 unsigned long hpte_group, unsigned long hpte_v,
92                 unsigned long hpte_r, unsigned long *slot)
93 {
94         long rc;
95         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
96
97         rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
98
99         *slot = retbuf[0];
100
101         return rc;
102 }
103
104 static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
105                 unsigned long avpn, unsigned long *old_pteh_ret,
106                 unsigned long *old_ptel_ret)
107 {
108         long rc;
109         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
110
111         rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
112
113         *old_pteh_ret = retbuf[0];
114         *old_ptel_ret = retbuf[1];
115
116         return rc;
117 }
118
119 /* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
120 static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
121                 unsigned long avpn, unsigned long *old_pteh_ret,
122                 unsigned long *old_ptel_ret)
123 {
124         long rc;
125         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
126
127         rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
128
129         *old_pteh_ret = retbuf[0];
130         *old_ptel_ret = retbuf[1];
131
132         return rc;
133 }
134
135 static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
136                 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
137 {
138         long rc;
139         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
140
141         rc = plpar_hcall(H_READ, retbuf, flags, ptex);
142
143         *old_pteh_ret = retbuf[0];
144         *old_ptel_ret = retbuf[1];
145
146         return rc;
147 }
148
149 /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
150 static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
151                 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
152 {
153         long rc;
154         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
155
156         rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
157
158         *old_pteh_ret = retbuf[0];
159         *old_ptel_ret = retbuf[1];
160
161         return rc;
162 }
163
164 static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
165                 unsigned long avpn)
166 {
167         return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
168 }
169
170 static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
171                 unsigned long *tce_ret)
172 {
173         long rc;
174         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
175
176         rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
177
178         *tce_ret = retbuf[0];
179
180         return rc;
181 }
182
183 static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
184                 unsigned long tceval)
185 {
186         return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
187 }
188
189 static inline long plpar_tce_put_indirect(unsigned long liobn,
190                 unsigned long ioba, unsigned long page, unsigned long count)
191 {
192         return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
193 }
194
195 static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
196                 unsigned long tceval, unsigned long count)
197 {
198         return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
199 }
200
201 static inline long plpar_get_term_char(unsigned long termno,
202                 unsigned long *len_ret, char *buf_ret)
203 {
204         long rc;
205         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
206         unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */
207
208         rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
209
210         *len_ret = retbuf[0];
211         lbuf[0] = retbuf[1];
212         lbuf[1] = retbuf[2];
213
214         return rc;
215 }
216
217 static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
218                 const char *buffer)
219 {
220         unsigned long *lbuf = (unsigned long *)buffer;  /* TODO: alignment? */
221         return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
222                         lbuf[1]);
223 }
224
225 static inline long plpar_eoi(unsigned long xirr)
226 {
227         return plpar_hcall_norets(H_EOI, xirr);
228 }
229
230 static inline long plpar_cppr(unsigned long cppr)
231 {
232         return plpar_hcall_norets(H_CPPR, cppr);
233 }
234
235 static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
236 {
237         return plpar_hcall_norets(H_IPI, servernum, mfrr);
238 }
239
240 static inline long plpar_xirr(unsigned long *xirr_ret)
241 {
242         long rc;
243         unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
244
245         rc = plpar_hcall(H_XIRR, retbuf);
246
247         *xirr_ret = retbuf[0];
248
249         return rc;
250 }
251
252 #endif /* _PSERIES_PLPAR_WRAPPERS_H */