[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 04/16] target/arm/arm-powerctl: Add new arm_set_cpu_o
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 04/16] target/arm/arm-powerctl: Add new arm_set_cpu_on_and_reset() |
Date: |
Thu, 28 Feb 2019 11:08:23 +0000 |
Currently the Arm arm-powerctl.h APIs allow:
* arm_set_cpu_on(), which powers on a CPU and sets its
initial PC and other startup state
* arm_reset_cpu(), which resets a CPU which is already on
(and fails if the CPU is powered off)
but there is no way to say "power on a CPU as if it had
just come out of reset and don't do anything else to it".
Add a new function arm_set_cpu_on_and_reset(), which does this.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
Message-id: address@hidden
---
target/arm/arm-powerctl.h | 16 +++++++++++
target/arm/arm-powerctl.c | 56 +++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/target/arm/arm-powerctl.h b/target/arm/arm-powerctl.h
index 04353923c06..37c8a04f0a9 100644
--- a/target/arm/arm-powerctl.h
+++ b/target/arm/arm-powerctl.h
@@ -74,4 +74,20 @@ int arm_set_cpu_off(uint64_t cpuid);
*/
int arm_reset_cpu(uint64_t cpuid);
+/*
+ * arm_set_cpu_on_and_reset:
+ * @cpuid: the id of the CPU we want to star
+ *
+ * Start the cpu designated by @cpuid and put it through its normal
+ * CPU reset process. The CPU will start in the way it is architected
+ * to start after a power-on reset.
+ *
+ * Returns: QEMU_ARM_POWERCTL_RET_SUCCESS on success.
+ * QEMU_ARM_POWERCTL_INVALID_PARAM if there is no CPU with that ID.
+ * QEMU_ARM_POWERCTL_ALREADY_ON if the CPU is already on.
+ * QEMU_ARM_POWERCTL_ON_PENDING if the CPU is already partway through
+ * powering on.
+ */
+int arm_set_cpu_on_and_reset(uint64_t cpuid);
+
#endif
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
index f9de5164e55..f77a950db67 100644
--- a/target/arm/arm-powerctl.c
+++ b/target/arm/arm-powerctl.c
@@ -228,6 +228,62 @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry,
uint64_t context_id,
return QEMU_ARM_POWERCTL_RET_SUCCESS;
}
+static void arm_set_cpu_on_and_reset_async_work(CPUState *target_cpu_state,
+ run_on_cpu_data data)
+{
+ ARMCPU *target_cpu = ARM_CPU(target_cpu_state);
+
+ /* Initialize the cpu we are turning on */
+ cpu_reset(target_cpu_state);
+ target_cpu_state->halted = 0;
+
+ /* Finally set the power status */
+ assert(qemu_mutex_iothread_locked());
+ target_cpu->power_state = PSCI_ON;
+}
+
+int arm_set_cpu_on_and_reset(uint64_t cpuid)
+{
+ CPUState *target_cpu_state;
+ ARMCPU *target_cpu;
+
+ assert(qemu_mutex_iothread_locked());
+
+ /* 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->power_state == PSCI_ON) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "[ARM]%s: CPU %" PRId64 " is already on\n",
+ __func__, cpuid);
+ return QEMU_ARM_POWERCTL_ALREADY_ON;
+ }
+
+ /*
+ * If another CPU has powered the target on we are in the state
+ * ON_PENDING and additional attempts to power on the CPU should
+ * fail (see 6.6 Implementation CPU_ON/CPU_OFF races in the PSCI
+ * spec)
+ */
+ if (target_cpu->power_state == PSCI_ON_PENDING) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "[ARM]%s: CPU %" PRId64 " is already powering on\n",
+ __func__, cpuid);
+ return QEMU_ARM_POWERCTL_ON_PENDING;
+ }
+
+ async_run_on_cpu(target_cpu_state, arm_set_cpu_on_and_reset_async_work,
+ RUN_ON_CPU_NULL);
+
+ /* We are good to go */
+ return QEMU_ARM_POWERCTL_RET_SUCCESS;
+}
+
static void arm_set_cpu_off_async_work(CPUState *target_cpu_state,
run_on_cpu_data data)
{
--
2.20.1
- [Qemu-devel] [PULL 00/16] target-arm queue, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 04/16] target/arm/arm-powerctl: Add new arm_set_cpu_on_and_reset(),
Peter Maydell <=
- [Qemu-devel] [PULL 05/16] hw/misc/iotkit-sysctl: Correct typo in INITSVTOR0 register name, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 03/16] target/arm/cpu: Allow init-svtor property to be set after realize, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 01/16] hw/misc/armsse-mhu.c: Model the SSE-200 Message Handling Unit, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 06/16] hw/arm/iotkit-sysctl: Add SSE-200 registers, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 07/16] hw/arm/iotkit-sysctl: Implement CPUWAIT and INITSVTOR*, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 02/16] hw/arm/armsse: Wire up the MHUs, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 09/16] target/arm: Use MVFR1 feature bits to gate A32/T32 FP16 instructions, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 08/16] hw/arm/armsse: Unify init-svtor and cpuwait handling, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 10/16] target/arm: Gate "miscellaneous FP" insns by ID register field, Peter Maydell, 2019/02/28
- [Qemu-devel] [PULL 11/16] Revert "arm: Allow system registers for KVM guests to be changed by QEMU code", Peter Maydell, 2019/02/28