unsignedint cpu_id; struct psci_boot_args *boot_args; struct kvm_nvhe_init_params *init_params; int ret;
/* * Find the logical CPU ID for the given MPIDR. The search set is * the set of CPUs that were online at the point of KVM initialization. * Booting other CPUs is rejected because their cpufeatures were not * checked against the finalized capabilities. This could be relaxed * by doing the feature checks in hyp.
*/
cpu_id = find_cpu_id(mpidr); if (cpu_id == INVALID_CPU_ID) return PSCI_RET_INVALID_PARAMS;
/* * No need to acquire a lock before writing to boot_args because a core * can only suspend itself. Racy CPU_ON calls use a separate struct.
*/
boot_args->pc = pc;
boot_args->r0 = r0;
/* * Will either return if shallow sleep state, or wake up into the entry * point if it is a deep sleep state.
*/ return psci_call(func_id, power_state,
__hyp_pa(&kvm_hyp_cpu_resume),
__hyp_pa(init_params));
}
/* * No need to acquire a lock before writing to boot_args because a core * can only suspend itself. Racy CPU_ON calls use a separate struct.
*/
boot_args->pc = pc;
boot_args->r0 = r0;
/* Will only return on error. */ return psci_call(func_id,
__hyp_pa(&kvm_hyp_cpu_resume),
__hyp_pa(init_params), 0);
}
staticunsignedlong psci_0_1_handler(u64 func_id, struct kvm_cpu_context *host_ctxt)
{ if (is_psci_0_1(cpu_off, func_id) || is_psci_0_1(migrate, func_id)) return psci_forward(host_ctxt); if (is_psci_0_1(cpu_on, func_id)) return psci_cpu_on(func_id, host_ctxt); if (is_psci_0_1(cpu_suspend, func_id)) return psci_cpu_suspend(func_id, host_ctxt);
return PSCI_RET_NOT_SUPPORTED;
}
staticunsignedlong psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ctxt)
{ switch (func_id) { case PSCI_0_2_FN_PSCI_VERSION: case PSCI_0_2_FN_CPU_OFF: case PSCI_0_2_FN64_AFFINITY_INFO: case PSCI_0_2_FN64_MIGRATE: case PSCI_0_2_FN_MIGRATE_INFO_TYPE: case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: return psci_forward(host_ctxt); /* * SYSTEM_OFF/RESET should not return according to the spec. * Allow it so as to stay robust to broken firmware.
*/ case PSCI_0_2_FN_SYSTEM_OFF: case PSCI_0_2_FN_SYSTEM_RESET: return psci_forward(host_ctxt); case PSCI_0_2_FN64_CPU_SUSPEND: return psci_cpu_suspend(func_id, host_ctxt); case PSCI_0_2_FN64_CPU_ON: return psci_cpu_on(func_id, host_ctxt); default: return PSCI_RET_NOT_SUPPORTED;
}
}
staticunsignedlong psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ctxt)
{ switch (func_id) { case PSCI_1_0_FN_PSCI_FEATURES: case PSCI_1_0_FN_SET_SUSPEND_MODE: case PSCI_1_1_FN64_SYSTEM_RESET2: case PSCI_1_3_FN_SYSTEM_OFF2: case PSCI_1_3_FN64_SYSTEM_OFF2: return psci_forward(host_ctxt); case PSCI_1_0_FN64_SYSTEM_SUSPEND: return psci_system_suspend(func_id, host_ctxt); default: return psci_0_2_handler(func_id, host_ctxt);
}
}
switch (kvm_host_psci_config.version) { case PSCI_VERSION(0, 1): if (!is_psci_0_1_call(func_id)) returnfalse;
ret = psci_0_1_handler(func_id, host_ctxt); break; case PSCI_VERSION(0, 2): if (!is_psci_0_2_call(func_id)) returnfalse;
ret = psci_0_2_handler(func_id, host_ctxt); break; default: if (!is_psci_0_2_call(func_id)) returnfalse;
ret = psci_1_0_handler(func_id, host_ctxt); break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.