Revision 39ac8455 hw/spapr_hcall.c
b/hw/spapr_hcall.c | ||
---|---|---|
248 | 248 |
return H_SUCCESS; |
249 | 249 |
} |
250 | 250 |
|
251 |
spapr_hcall_fn hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; |
|
251 |
static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr, |
|
252 |
target_ulong opcode, target_ulong *args) |
|
253 |
{ |
|
254 |
target_ulong rtas_r3 = args[0]; |
|
255 |
uint32_t token = ldl_phys(rtas_r3); |
|
256 |
uint32_t nargs = ldl_phys(rtas_r3 + 4); |
|
257 |
uint32_t nret = ldl_phys(rtas_r3 + 8); |
|
258 |
|
|
259 |
return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12, |
|
260 |
nret, rtas_r3 + 12 + 4*nargs); |
|
261 |
} |
|
262 |
|
|
263 |
spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; |
|
264 |
spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE]; |
|
252 | 265 |
|
253 | 266 |
void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) |
254 | 267 |
{ |
255 |
spapr_hcall_fn old_fn; |
|
268 |
spapr_hcall_fn *slot; |
|
269 |
|
|
270 |
if (opcode <= MAX_HCALL_OPCODE) { |
|
271 |
assert((opcode & 0x3) == 0); |
|
256 | 272 |
|
257 |
assert(opcode <= MAX_HCALL_OPCODE); |
|
258 |
assert((opcode & 0x3) == 0); |
|
273 |
slot = &papr_hypercall_table[opcode / 4]; |
|
274 |
} else { |
|
275 |
assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX)); |
|
259 | 276 |
|
260 |
old_fn = hypercall_table[opcode / 4]; |
|
261 | 277 |
|
262 |
assert(!old_fn || (fn == old_fn)); |
|
278 |
slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE]; |
|
279 |
} |
|
263 | 280 |
|
264 |
hypercall_table[opcode / 4] = fn; |
|
281 |
assert(!(*slot) || (fn == *slot)); |
|
282 |
*slot = fn; |
|
265 | 283 |
} |
266 | 284 |
|
267 | 285 |
target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, |
... | ... | |
274 | 292 |
|
275 | 293 |
if ((opcode <= MAX_HCALL_OPCODE) |
276 | 294 |
&& ((opcode & 0x3) == 0)) { |
277 |
spapr_hcall_fn fn = hypercall_table[opcode / 4]; |
|
295 |
spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; |
|
296 |
|
|
297 |
if (fn) { |
|
298 |
return fn(env, spapr, opcode, args); |
|
299 |
} |
|
300 |
} else if ((opcode >= KVMPPC_HCALL_BASE) && |
|
301 |
(opcode <= KVMPPC_HCALL_MAX)) { |
|
302 |
spapr_hcall_fn fn = kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE]; |
|
278 | 303 |
|
279 | 304 |
if (fn) { |
280 | 305 |
return fn(env, spapr, opcode, args); |
... | ... | |
291 | 316 |
spapr_register_hypercall(H_ENTER, h_enter); |
292 | 317 |
spapr_register_hypercall(H_REMOVE, h_remove); |
293 | 318 |
spapr_register_hypercall(H_PROTECT, h_protect); |
319 |
|
|
320 |
/* qemu/KVM-PPC specific hcalls */ |
|
321 |
spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas); |
|
294 | 322 |
} |
295 | 323 |
device_init(hypercall_init); |
Also available in: Unified diff