summaryrefslogtreecommitdiffstats
path: root/qemu/target-arm/psci.c
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/target-arm/psci.c
parenta14b48d18a9ed03ec191cf16b162206998a895ce (diff)
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/target-arm/psci.c')
-rw-r--r--qemu/target-arm/psci.c258
1 files changed, 0 insertions, 258 deletions
diff --git a/qemu/target-arm/psci.c b/qemu/target-arm/psci.c
deleted file mode 100644
index c55487f87..000000000
--- a/qemu/target-arm/psci.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2014 - Linaro
- * Author: Rob Herring <rob.herring@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include <cpu.h>
-#include <cpu-qom.h>
-#include <exec/helper-proto.h>
-#include <kvm-consts.h>
-#include <sysemu/sysemu.h>
-#include "internals.h"
-
-bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
-{
- /* Return true if the r0/x0 value indicates a PSCI call and
- * the exception type matches the configured PSCI conduit. This is
- * called before the SMC/HVC instruction is executed, to decide whether
- * we should treat it as a PSCI call or with the architecturally
- * defined behaviour for an SMC or HVC (which might be UNDEF or trap
- * to EL2 or to EL3).
- */
- CPUARMState *env = &cpu->env;
- uint64_t param = is_a64(env) ? env->xregs[0] : env->regs[0];
-
- switch (excp_type) {
- case EXCP_HVC:
- if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_HVC) {
- return false;
- }
- break;
- case EXCP_SMC:
- if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
- return false;
- }
- break;
- default:
- return false;
- }
-
- switch (param) {
- case QEMU_PSCI_0_2_FN_PSCI_VERSION:
- case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
- case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
- case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
- case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
- case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
- case QEMU_PSCI_0_1_FN_CPU_ON:
- case QEMU_PSCI_0_2_FN_CPU_ON:
- case QEMU_PSCI_0_2_FN64_CPU_ON:
- case QEMU_PSCI_0_1_FN_CPU_OFF:
- case QEMU_PSCI_0_2_FN_CPU_OFF:
- case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
- case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
- case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
- case QEMU_PSCI_0_1_FN_MIGRATE:
- case QEMU_PSCI_0_2_FN_MIGRATE:
- return true;
- default:
- return false;
- }
-}
-
-static CPUState *get_cpu_by_id(uint64_t id)
-{
- CPUState *cpu;
-
- CPU_FOREACH(cpu) {
- ARMCPU *armcpu = ARM_CPU(cpu);
-
- if (armcpu->mp_affinity == id) {
- return cpu;
- }
- }
-
- return NULL;
-}
-
-void arm_handle_psci_call(ARMCPU *cpu)
-{
- /*
- * This function partially implements the logic for dispatching Power State
- * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),
- * to the extent required for bringing up and taking down secondary cores,
- * and for handling reset and poweroff requests.
- * Additional information about the calling convention used is available in
- * the document 'SMC Calling Convention' (ARM DEN 0028)
- */
- CPUState *cs = CPU(cpu);
- CPUARMState *env = &cpu->env;
- uint64_t param[4];
- uint64_t context_id, mpidr;
- target_ulong entry;
- int32_t ret = 0;
- int i;
-
- for (i = 0; i < 4; i++) {
- /*
- * All PSCI functions take explicit 32-bit or native int sized
- * arguments so we can simply zero-extend all arguments regardless
- * of which exact function we are about to call.
- */
- param[i] = is_a64(env) ? env->xregs[i] : env->regs[i];
- }
-
- if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
- goto err;
- }
-
- switch (param[0]) {
- CPUState *target_cpu_state;
- ARMCPU *target_cpu;
- CPUClass *target_cpu_class;
-
- case QEMU_PSCI_0_2_FN_PSCI_VERSION:
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
- break;
- case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
- ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
- break;
- case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
- case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
- mpidr = param[1];
-
- switch (param[2]) {
- case 0:
- target_cpu_state = get_cpu_by_id(mpidr);
- if (!target_cpu_state) {
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
- break;
- }
- target_cpu = ARM_CPU(target_cpu_state);
- ret = target_cpu->powered_off ? 1 : 0;
- break;
- default:
- /* Everything above affinity level 0 is always on. */
- ret = 0;
- }
- break;
- case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
- qemu_system_reset_request();
- /* QEMU reset and shutdown are async requests, but PSCI
- * mandates that we never return from the reset/shutdown
- * call, so power the CPU off now so it doesn't execute
- * anything further.
- */
- goto cpu_off;
- case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
- qemu_system_shutdown_request();
- goto cpu_off;
- case QEMU_PSCI_0_1_FN_CPU_ON:
- case QEMU_PSCI_0_2_FN_CPU_ON:
- case QEMU_PSCI_0_2_FN64_CPU_ON:
- mpidr = param[1];
- entry = param[2];
- context_id = param[3];
-
- /* change to the cpu we are powering up */
- target_cpu_state = get_cpu_by_id(mpidr);
- if (!target_cpu_state) {
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
- break;
- }
- target_cpu = ARM_CPU(target_cpu_state);
- if (!target_cpu->powered_off) {
- ret = QEMU_PSCI_RET_ALREADY_ON;
- break;
- }
- target_cpu_class = CPU_GET_CLASS(target_cpu);
-
- /* Initialize the cpu we are turning on */
- cpu_reset(target_cpu_state);
- target_cpu->powered_off = false;
- target_cpu_state->halted = 0;
-
- /*
- * The PSCI spec mandates that newly brought up CPUs enter the
- * exception level of the caller in the same execution mode as
- * the caller, with context_id in x0/r0, respectively.
- *
- * For now, it is sufficient to assert() that CPUs come out of
- * reset in the same mode as the calling CPU, since we only
- * implement EL1, which means that
- * (a) there is no EL2 for the calling CPU to trap into to change
- * its state
- * (b) the newly brought up CPU enters EL1 immediately after coming
- * out of reset in the default state
- */
- assert(is_a64(env) == is_a64(&target_cpu->env));
- if (is_a64(env)) {
- if (entry & 1) {
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
- break;
- }
- target_cpu->env.xregs[0] = context_id;
- } else {
- target_cpu->env.regs[0] = context_id;
- target_cpu->env.thumb = entry & 1;
- }
- target_cpu_class->set_pc(target_cpu_state, entry);
-
- ret = 0;
- break;
- case QEMU_PSCI_0_1_FN_CPU_OFF:
- case QEMU_PSCI_0_2_FN_CPU_OFF:
- goto cpu_off;
- case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
- case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
- case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
- /* Affinity levels are not supported in QEMU */
- if (param[1] & 0xfffe0000) {
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
- break;
- }
- /* Powerdown is not supported, we always go into WFI */
- if (is_a64(env)) {
- env->xregs[0] = 0;
- } else {
- env->regs[0] = 0;
- }
- helper_wfi(env);
- break;
- case QEMU_PSCI_0_1_FN_MIGRATE:
- case QEMU_PSCI_0_2_FN_MIGRATE:
- ret = QEMU_PSCI_RET_NOT_SUPPORTED;
- break;
- default:
- g_assert_not_reached();
- }
-
-err:
- if (is_a64(env)) {
- env->xregs[0] = ret;
- } else {
- env->regs[0] = ret;
- }
- return;
-
-cpu_off:
- cpu->powered_off = true;
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- cpu_loop_exit(cs);
- /* notreached */
-}