target/arm: Support PSCI 1.1 and SMCCC 1.0
Support the latest PSCI on TCG and HVF. A 64-bit function called from AArch32 now returns NOT_SUPPORTED, which is necessary to adhere to SMC Calling Convention 1.0. It is still not compliant with SMCCC 1.3 since they do not implement mandatory functions. Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com> Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> [PMM: update MISMATCH_CHECK checks on PSCI_VERSION macros to match] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
d8bdf97972
commit
0dc71c701c
@ -488,9 +488,15 @@ static void fdt_add_psci_node(void *fdt)
|
||||
}
|
||||
|
||||
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));
|
||||
if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
|
||||
armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
|
||||
if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
|
||||
const char comp[] = "arm,psci-0.2\0arm,psci";
|
||||
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
|
||||
} else {
|
||||
const char comp[] = "arm,psci-1.0\0arm,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)) {
|
||||
|
@ -1110,11 +1110,12 @@ static void arm_cpu_initfn(Object *obj)
|
||||
* picky DTB consumer will also provide a helpful error message.
|
||||
*/
|
||||
cpu->dtb_compatible = "qemu,unknown";
|
||||
cpu->psci_version = 1; /* By default assume PSCI v0.1 */
|
||||
cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */
|
||||
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
|
||||
|
||||
if (tcg_enabled() || hvf_enabled()) {
|
||||
cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
|
||||
/* TCG and HVF implement PSCI 1.1 */
|
||||
cpu->psci_version = QEMU_PSCI_VERSION_1_1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -678,7 +678,7 @@ static bool hvf_handle_psci_call(CPUState *cpu)
|
||||
|
||||
switch (param[0]) {
|
||||
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
|
||||
ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
|
||||
ret = QEMU_PSCI_VERSION_1_1;
|
||||
break;
|
||||
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
|
||||
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
|
||||
@ -746,6 +746,31 @@ static bool hvf_handle_psci_call(CPUState *cpu)
|
||||
case QEMU_PSCI_0_2_FN_MIGRATE:
|
||||
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
|
||||
break;
|
||||
case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
|
||||
switch (param[1]) {
|
||||
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_1_0_FN_PSCI_FEATURES:
|
||||
ret = 0;
|
||||
break;
|
||||
case QEMU_PSCI_0_1_FN_MIGRATE:
|
||||
case QEMU_PSCI_0_2_FN_MIGRATE:
|
||||
default:
|
||||
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -77,6 +77,8 @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE);
|
||||
#define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4)
|
||||
#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5)
|
||||
|
||||
#define QEMU_PSCI_1_0_FN_PSCI_FEATURES QEMU_PSCI_0_2_FN(10)
|
||||
|
||||
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);
|
||||
@ -84,18 +86,21 @@ 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);
|
||||
MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
|
||||
|
||||
/* PSCI v0.2 return values used by TCG emulation of PSCI */
|
||||
|
||||
/* No Trusted OS migration to worry about when offlining CPUs */
|
||||
#define QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED 2
|
||||
|
||||
/* We implement version 0.2 only */
|
||||
#define QEMU_PSCI_0_2_RET_VERSION_0_2 2
|
||||
#define QEMU_PSCI_VERSION_0_1 0x00001
|
||||
#define QEMU_PSCI_VERSION_0_2 0x00002
|
||||
#define QEMU_PSCI_VERSION_1_1 0x10001
|
||||
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
|
||||
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2,
|
||||
(PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2)));
|
||||
/* We don't bother to check every possible version value */
|
||||
MISMATCH_CHECK(QEMU_PSCI_VERSION_0_2, PSCI_VERSION(0, 2));
|
||||
MISMATCH_CHECK(QEMU_PSCI_VERSION_1_1, PSCI_VERSION(1, 1));
|
||||
|
||||
/* PSCI return values (inclusive of all PSCI versions) */
|
||||
#define QEMU_PSCI_RET_SUCCESS 0
|
||||
|
@ -864,7 +864,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
|
||||
}
|
||||
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
|
||||
cpu->psci_version = 2;
|
||||
cpu->psci_version = QEMU_PSCI_VERSION_0_2;
|
||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
|
||||
}
|
||||
if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||
|
@ -57,7 +57,7 @@ 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),
|
||||
* Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.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
|
||||
@ -80,7 +80,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
|
||||
}
|
||||
|
||||
if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {
|
||||
ret = QEMU_PSCI_RET_INVALID_PARAMS;
|
||||
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ void arm_handle_psci_call(ARMCPU *cpu)
|
||||
ARMCPU *target_cpu;
|
||||
|
||||
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
|
||||
ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
|
||||
ret = QEMU_PSCI_VERSION_1_1;
|
||||
break;
|
||||
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
|
||||
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
|
||||
@ -170,6 +170,35 @@ void arm_handle_psci_call(ARMCPU *cpu)
|
||||
}
|
||||
helper_wfi(env, 4);
|
||||
break;
|
||||
case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
|
||||
switch (param[1]) {
|
||||
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_1_0_FN_PSCI_FEATURES:
|
||||
if (!(param[1] & QEMU_PSCI_0_2_64BIT) || is_a64(env)) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case QEMU_PSCI_0_1_FN_MIGRATE:
|
||||
case QEMU_PSCI_0_2_FN_MIGRATE:
|
||||
default:
|
||||
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case QEMU_PSCI_0_1_FN_MIGRATE:
|
||||
case QEMU_PSCI_0_2_FN_MIGRATE:
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user