diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8f3f6071b9..bd206a019a 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -194,20 +194,41 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi) /* No PSCI for TCG yet */ if (kvm_enabled()) { + uint32_t cpu_suspend_fn; + uint32_t cpu_off_fn; + uint32_t cpu_on_fn; + uint32_t migrate_fn; + qemu_fdt_add_subnode(fdt, "/psci"); if (armcpu->psci_version == 2) { const char comp[] = "arm,psci-0.2\0arm,psci"; qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); + + cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; + if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { + cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND; + cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON; + migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE; + } else { + cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND; + cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON; + migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE; + } } else { qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci"); + + cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND; + cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF; + cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON; + migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE; } qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc"); - qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", - QEMU_PSCI_0_1_FN_CPU_SUSPEND); - qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", QEMU_PSCI_0_1_FN_CPU_OFF); - qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", QEMU_PSCI_0_1_FN_CPU_ON); - qemu_fdt_setprop_cell(fdt, "/psci", "migrate", QEMU_PSCI_0_1_FN_MIGRATE); + + qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn); + qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn); + qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn); + qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn); } } diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h index bcad7ba800..091c1267d6 100644 --- a/target-arm/kvm-consts.h +++ b/target-arm/kvm-consts.h @@ -17,6 +17,7 @@ #ifdef CONFIG_KVM #include "qemu/compiler.h" #include +#include #define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(X != Y) @@ -50,6 +51,32 @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF) MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_ON, KVM_PSCI_FN_CPU_ON) MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE) +#define QEMU_PSCI_0_2_FN_BASE 0x84000000 +#define QEMU_PSCI_0_2_FN(n) (QEMU_PSCI_0_2_FN_BASE + (n)) + +#define QEMU_PSCI_0_2_64BIT 0x40000000 +#define QEMU_PSCI_0_2_FN64_BASE \ + (QEMU_PSCI_0_2_FN_BASE + QEMU_PSCI_0_2_64BIT) +#define QEMU_PSCI_0_2_FN64(n) (QEMU_PSCI_0_2_FN64_BASE + (n)) + +#define QEMU_PSCI_0_2_FN_CPU_SUSPEND QEMU_PSCI_0_2_FN(1) +#define QEMU_PSCI_0_2_FN_CPU_OFF QEMU_PSCI_0_2_FN(2) +#define QEMU_PSCI_0_2_FN_CPU_ON QEMU_PSCI_0_2_FN(3) +#define QEMU_PSCI_0_2_FN_MIGRATE QEMU_PSCI_0_2_FN(5) + +#define QEMU_PSCI_0_2_FN64_CPU_SUSPEND QEMU_PSCI_0_2_FN64(1) +#define QEMU_PSCI_0_2_FN64_CPU_OFF QEMU_PSCI_0_2_FN64(2) +#define QEMU_PSCI_0_2_FN64_CPU_ON QEMU_PSCI_0_2_FN64(3) +#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5) + +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE) + /* Note that KVM uses overlapping values for AArch32 and AArch64 * target CPU numbers. AArch32 targets: */