static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_, sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { target_ulong id; PowerPCCPU *cpu; if (nargs != 1 || nret != 2) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } id = rtas_ld(args, 0); cpu = ppc_get_vcpu_by_dt_id(id); if (cpu != NULL) { if (CPU(cpu)->halted) { rtas_st(rets, 1, 0); } else { rtas_st(rets, 1, 2); } rtas_st(rets, 0, RTAS_OUT_SUCCESS); return; } /* Didn't find a matching cpu */ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); }
static int get_cpu_index_by_dt_id(int cpu_dt_id) { PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id); if (cpu) { return cpu->parent_obj.cpu_index; } return -1; }
static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { target_ulong id, start, r3; PowerPCCPU *cpu; if (nargs != 3 || nret != 1) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } id = rtas_ld(args, 0); start = rtas_ld(args, 1); r3 = rtas_ld(args, 2); cpu = ppc_get_vcpu_by_dt_id(id); if (cpu != NULL) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; if (!cs->halted) { rtas_st(rets, 0, RTAS_OUT_HW_ERROR); 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(cs); env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); env->nip = start; env->gpr[3] = r3; cs->halted = 0; qemu_cpu_kick(cs); rtas_st(rets, 0, RTAS_OUT_SUCCESS); return; } /* Didn't find a matching cpu */ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); }