Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/platforms/pseries/plpar_wrappers.h
10818 views
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 */
8
int 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
15
static inline long poll_pending(void)
16
{
17
return plpar_hcall_norets(H_POLL_PENDING);
18
}
19
20
static inline u8 get_cede_latency_hint(void)
21
{
22
return get_lppaca()->gpr5_dword.fields.cede_latency_hint;
23
}
24
25
static inline void set_cede_latency_hint(u8 latency_hint)
26
{
27
get_lppaca()->gpr5_dword.fields.cede_latency_hint = latency_hint;
28
}
29
30
static inline long cede_processor(void)
31
{
32
return plpar_hcall_norets(H_CEDE);
33
}
34
35
static 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
47
static 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
56
static inline long unregister_vpa(unsigned long cpu, unsigned long vpa)
57
{
58
return vpa_call(0x5, cpu, vpa);
59
}
60
61
static inline long register_vpa(unsigned long cpu, unsigned long vpa)
62
{
63
return vpa_call(0x1, cpu, vpa);
64
}
65
66
static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa)
67
{
68
return vpa_call(0x7, cpu, vpa);
69
}
70
71
static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
72
{
73
return vpa_call(0x3, cpu, vpa);
74
}
75
76
static inline long unregister_dtl(unsigned long cpu, unsigned long vpa)
77
{
78
return vpa_call(0x6, cpu, vpa);
79
}
80
81
static inline long register_dtl(unsigned long cpu, unsigned long vpa)
82
{
83
return vpa_call(0x2, cpu, vpa);
84
}
85
86
static 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
102
static 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
118
extern void vpa_init(int cpu);
119
120
static 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
134
static 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 */
150
static 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
165
static 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 */
180
static 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
*/
198
static 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
212
static 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
218
static 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
231
static 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
237
static 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
243
static 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
249
static 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
265
static 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
273
#endif /* _PSERIES_PLPAR_WRAPPERS_H */
274
275