diff options
Diffstat (limited to 'hw/spapr_rtas.c')
-rw-r--r-- | hw/spapr_rtas.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c index ae18595150..81eecd0940 100644 --- a/hw/spapr_rtas.c +++ b/hw/spapr_rtas.c @@ -25,10 +25,10 @@ * */ #include "cpu.h" -#include "sysemu.h" -#include "qemu-char.h" +#include "sysemu/sysemu.h" +#include "char/char.h" #include "hw/qdev.h" -#include "device_tree.h" +#include "sysemu/device_tree.h" #include "hw/spapr.h" #include "hw/spapr_vio.h" @@ -163,6 +163,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, uint32_t nret, target_ulong rets) { target_ulong id, start, r3; + CPUState *cpu; CPUPPCState *env; if (nargs != 3 || nret != 1) { @@ -175,6 +176,8 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, r3 = rtas_ld(args, 2); for (env = first_cpu; env; env = env->next_cpu) { + cpu = ENV_GET_CPU(env); + if (env->cpu_index != id) { continue; } @@ -184,12 +187,17 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, return; } + /* This will make sure qemu state is up to date with kvm, and + * mark it dirty so our changes get flushed back before the + * new cpu enters */ + kvm_cpu_synchronize_state(env); + env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); env->nip = start; env->gpr[3] = r3; env->halted = 0; - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); rtas_st(rets, 0, 0); return; @@ -234,18 +242,27 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr, return H_PARAMETER; } -void spapr_rtas_register(const char *name, spapr_rtas_fn fn) +int spapr_rtas_register(const char *name, spapr_rtas_fn fn) { + int i; + + for (i = 0; i < (rtas_next - rtas_table); i++) { + if (strcmp(name, rtas_table[i].name) == 0) { + fprintf(stderr, "RTAS call \"%s\" registered twice\n", name); + exit(1); + } + } + assert(rtas_next < (rtas_table + TOKEN_MAX)); rtas_next->name = name; rtas_next->fn = fn; - rtas_next++; + return (rtas_next++ - rtas_table) + TOKEN_BASE; } -int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr, - target_phys_addr_t rtas_size) +int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, + hwaddr rtas_size) { int ret; int i; @@ -284,7 +301,7 @@ int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr, for (i = 0; i < TOKEN_MAX; i++) { struct rtas_call *call = &rtas_table[i]; - if (!call->fn) { + if (!call->name) { continue; } |