aboutsummaryrefslogtreecommitdiff
path: root/target-arm/arm-powerctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/arm-powerctl.c')
-rw-r--r--target-arm/arm-powerctl.c228
1 files changed, 0 insertions, 228 deletions
diff --git a/target-arm/arm-powerctl.c b/target-arm/arm-powerctl.c
deleted file mode 100644
index fbb7a15daa..0000000000
--- a/target-arm/arm-powerctl.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * QEMU support -- ARM Power Control specific functions.
- *
- * Copyright (c) 2016 Jean-Christophe Dubois
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "cpu-qom.h"
-#include "internals.h"
-#include "arm-powerctl.h"
-#include "qemu/log.h"
-#include "exec/exec-all.h"
-
-#ifndef DEBUG_ARM_POWERCTL
-#define DEBUG_ARM_POWERCTL 0
-#endif
-
-#define DPRINTF(fmt, args...) \
- do { \
- if (DEBUG_ARM_POWERCTL) { \
- fprintf(stderr, "[ARM]%s: " fmt , __func__, ##args); \
- } \
- } while (0)
-
-CPUState *arm_get_cpu_by_id(uint64_t id)
-{
- CPUState *cpu;
-
- DPRINTF("cpu %" PRId64 "\n", id);
-
- CPU_FOREACH(cpu) {
- ARMCPU *armcpu = ARM_CPU(cpu);
-
- if (armcpu->mp_affinity == id) {
- return cpu;
- }
- }
-
- qemu_log_mask(LOG_GUEST_ERROR,
- "[ARM]%s: Requesting unknown CPU %" PRId64 "\n",
- __func__, id);
-
- return NULL;
-}
-
-int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id,
- uint32_t target_el, bool target_aa64)
-{
- CPUState *target_cpu_state;
- ARMCPU *target_cpu;
-
- DPRINTF("cpu %" PRId64 " (EL %d, %s) @ 0x%" PRIx64 " with R0 = 0x%" PRIx64
- "\n", cpuid, target_el, target_aa64 ? "aarch64" : "aarch32", entry,
- context_id);
-
- /* requested EL level need to be in the 1 to 3 range */
- assert((target_el > 0) && (target_el < 4));
-
- if (target_aa64 && (entry & 3)) {
- /*
- * if we are booting in AArch64 mode then "entry" needs to be 4 bytes
- * aligned.
- */
- return QEMU_ARM_POWERCTL_INVALID_PARAM;
- }
-
- /* Retrieve the cpu we are powering up */
- target_cpu_state = arm_get_cpu_by_id(cpuid);
- if (!target_cpu_state) {
- /* The cpu was not found */
- return QEMU_ARM_POWERCTL_INVALID_PARAM;
- }
-
- target_cpu = ARM_CPU(target_cpu_state);
- if (!target_cpu->powered_off) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "[ARM]%s: CPU %" PRId64 " is already on\n",
- __func__, cpuid);
- return QEMU_ARM_POWERCTL_ALREADY_ON;
- }
-
- /*
- * The newly brought CPU is requested to enter the exception level
- * "target_el" and be in the requested mode (AArch64 or AArch32).
- */
-
- if (((target_el == 3) && !arm_feature(&target_cpu->env, ARM_FEATURE_EL3)) ||
- ((target_el == 2) && !arm_feature(&target_cpu->env, ARM_FEATURE_EL2))) {
- /*
- * The CPU does not support requested level
- */
- return QEMU_ARM_POWERCTL_INVALID_PARAM;
- }
-
- if (!target_aa64 && arm_feature(&target_cpu->env, ARM_FEATURE_AARCH64)) {
- /*
- * For now we don't support booting an AArch64 CPU in AArch32 mode
- * TODO: We should add this support later
- */
- qemu_log_mask(LOG_UNIMP,
- "[ARM]%s: Starting AArch64 CPU %" PRId64
- " in AArch32 mode is not supported yet\n",
- __func__, cpuid);
- return QEMU_ARM_POWERCTL_INVALID_PARAM;
- }
-
- /* Initialize the cpu we are turning on */
- cpu_reset(target_cpu_state);
- target_cpu->powered_off = false;
- target_cpu_state->halted = 0;
-
- if (target_aa64) {
- if ((target_el < 3) && arm_feature(&target_cpu->env, ARM_FEATURE_EL3)) {
- /*
- * As target mode is AArch64, we need to set lower
- * exception level (the requested level 2) to AArch64
- */
- target_cpu->env.cp15.scr_el3 |= SCR_RW;
- }
-
- if ((target_el < 2) && arm_feature(&target_cpu->env, ARM_FEATURE_EL2)) {
- /*
- * As target mode is AArch64, we need to set lower
- * exception level (the requested level 1) to AArch64
- */
- target_cpu->env.cp15.hcr_el2 |= HCR_RW;
- }
-
- target_cpu->env.pstate = aarch64_pstate_mode(target_el, true);
- } else {
- /* We are requested to boot in AArch32 mode */
- static uint32_t mode_for_el[] = { 0,
- ARM_CPU_MODE_SVC,
- ARM_CPU_MODE_HYP,
- ARM_CPU_MODE_SVC };
-
- cpsr_write(&target_cpu->env, mode_for_el[target_el], CPSR_M,
- CPSRWriteRaw);
- }
-
- if (target_el == 3) {
- /* Processor is in secure mode */
- target_cpu->env.cp15.scr_el3 &= ~SCR_NS;
- } else {
- /* Processor is not in secure mode */
- target_cpu->env.cp15.scr_el3 |= SCR_NS;
- }
-
- /* We check if the started CPU is now at the correct level */
- assert(target_el == arm_current_el(&target_cpu->env));
-
- if (target_aa64) {
- target_cpu->env.xregs[0] = context_id;
- target_cpu->env.thumb = false;
- } else {
- target_cpu->env.regs[0] = context_id;
- target_cpu->env.thumb = entry & 1;
- entry &= 0xfffffffe;
- }
-
- /* Start the new CPU at the requested address */
- cpu_set_pc(target_cpu_state, entry);
-
- qemu_cpu_kick(target_cpu_state);
-
- /* We are good to go */
- return QEMU_ARM_POWERCTL_RET_SUCCESS;
-}
-
-int arm_set_cpu_off(uint64_t cpuid)
-{
- CPUState *target_cpu_state;
- ARMCPU *target_cpu;
-
- DPRINTF("cpu %" PRId64 "\n", cpuid);
-
- /* change to the cpu we are powering up */
- target_cpu_state = arm_get_cpu_by_id(cpuid);
- if (!target_cpu_state) {
- return QEMU_ARM_POWERCTL_INVALID_PARAM;
- }
- target_cpu = ARM_CPU(target_cpu_state);
- if (target_cpu->powered_off) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "[ARM]%s: CPU %" PRId64 " is already off\n",
- __func__, cpuid);
- return QEMU_ARM_POWERCTL_IS_OFF;
- }
-
- target_cpu->powered_off = true;
- target_cpu_state->halted = 1;
- target_cpu_state->exception_index = EXCP_HLT;
- cpu_loop_exit(target_cpu_state);
- /* notreached */
-
- return QEMU_ARM_POWERCTL_RET_SUCCESS;
-}
-
-int arm_reset_cpu(uint64_t cpuid)
-{
- CPUState *target_cpu_state;
- ARMCPU *target_cpu;
-
- DPRINTF("cpu %" PRId64 "\n", cpuid);
-
- /* change to the cpu we are resetting */
- target_cpu_state = arm_get_cpu_by_id(cpuid);
- if (!target_cpu_state) {
- return QEMU_ARM_POWERCTL_INVALID_PARAM;
- }
- target_cpu = ARM_CPU(target_cpu_state);
- if (target_cpu->powered_off) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "[ARM]%s: CPU %" PRId64 " is off\n",
- __func__, cpuid);
- return QEMU_ARM_POWERCTL_IS_OFF;
- }
-
- /* Reset the cpu */
- cpu_reset(target_cpu_state);
-
- return QEMU_ARM_POWERCTL_RET_SUCCESS;
-}