[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/3] xen/arm: vpsci: Move PSCI function dispatching from vsmc.c to vpsci.c
On 24.01.18 20:34, Julien Grall wrote: At the moment PSCI function dispatching is done in vsmc.c and the function implementation in vpsci.c. Some bits of the implementation is even done in vsmc.c (see PSCI_SYSTEM_RESET). This means that it is difficult to follow the implementation and also requires to export functions for each PSCI functions. Therefore move PSCI dispatching in two new functions do_psci_0_1_call and do_psci_0_2_call. The former will handle PSCI 0.1 call while the latter 0.2 or later call. Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> --- xen/arch/arm/vpsci.c | 141 ++++++++++++++++++++++++++++++++++++++++----- xen/arch/arm/vsmc.c | 95 ++---------------------------- xen/include/asm-arm/psci.h | 21 +------ 3 files changed, 135 insertions(+), 122 deletions(-) diff --git a/xen/arch/arm/vpsci.c b/xen/arch/arm/vpsci.c index 979d32ed6d..b3ee193621 100644 --- a/xen/arch/arm/vpsci.c +++ b/xen/arch/arm/vpsci.c @@ -91,12 +91,12 @@ static int do_common_cpu_on(register_t target_cpu, register_t entry_point, return PSCI_SUCCESS; }-int32_t do_psci_cpu_on(uint32_t vcpuid, register_t entry_point)+static int32_t do_psci_cpu_on(uint32_t vcpuid, register_t entry_point) { return do_common_cpu_on(vcpuid, entry_point, 0 , PSCI_VERSION(0, 1)); }-int32_t do_psci_cpu_off(uint32_t power_state)+static int32_t do_psci_cpu_off(uint32_t power_state) { struct vcpu *v = current; if ( !test_and_set_bit(_VPF_down, &v->pause_flags) ) @@ -104,13 +104,14 @@ int32_t do_psci_cpu_off(uint32_t power_state) return PSCI_SUCCESS; }-uint32_t do_psci_0_2_version(void)+static uint32_t do_psci_0_2_version(void) { return PSCI_VERSION(0, 2); }-register_t do_psci_0_2_cpu_suspend(uint32_t power_state, register_t entry_point,- register_t context_id) +static register_t do_psci_0_2_cpu_suspend(uint32_t power_state, + register_t entry_point, + register_t context_id) { struct vcpu *v = current;@@ -123,13 +124,14 @@ register_t do_psci_0_2_cpu_suspend(uint32_t power_state, register_t entry_point,return PSCI_SUCCESS; }-int32_t do_psci_0_2_cpu_off(void)+static int32_t do_psci_0_2_cpu_off(void) { return do_psci_cpu_off(0); }-int32_t do_psci_0_2_cpu_on(register_t target_cpu, register_t entry_point,- register_t context_id) +static int32_t do_psci_0_2_cpu_on(register_t target_cpu, + register_t entry_point, + register_t context_id) { return do_common_cpu_on(target_cpu, entry_point, context_id, PSCI_VERSION(0, 2)); @@ -144,8 +146,8 @@ static const unsigned long target_affinity_mask[] = { #endif };-int32_t do_psci_0_2_affinity_info(register_t target_affinity,- uint32_t lowest_affinity_level) +static int32_t do_psci_0_2_affinity_info(register_t target_affinity, + uint32_t lowest_affinity_level) { struct domain *d = current->domain; struct vcpu *v; @@ -172,23 +174,136 @@ int32_t do_psci_0_2_affinity_info(register_t target_affinity, return PSCI_0_2_AFFINITY_LEVEL_OFF; }-uint32_t do_psci_0_2_migrate_info_type(void)+static uint32_t do_psci_0_2_migrate_info_type(void) { return PSCI_0_2_TOS_MP_OR_NOT_PRESENT; }-void do_psci_0_2_system_off( void )+static void do_psci_0_2_system_off( void ) { struct domain *d = current->domain; domain_shutdown(d,SHUTDOWN_poweroff); }-void do_psci_0_2_system_reset(void)+static void do_psci_0_2_system_reset(void) { struct domain *d = current->domain; domain_shutdown(d,SHUTDOWN_reboot); }+#define PSCI_SET_RESULT(reg, val) set_user_reg(reg, 0, val)+#define PSCI_ARG(reg, n) get_user_reg(reg, n) + +#ifdef CONFIG_ARM_64 +#define PSCI_ARG32(reg, n) (uint32_t)(get_user_reg(reg, n)) +#else +#define PSCI_ARG32(reg, n) PSCI_ARG(reg, n) +#endif + +/* + * PSCI 0.1 calls. It will return false if the function ID is not + * handled. + */ +bool do_psci_0_1_call(struct cpu_user_regs *regs, uint32_t fid) +{ + switch ( (uint32_t)get_user_reg(regs, 0) ) + { + case PSCI_cpu_off: + { + uint32_t pstate = PSCI_ARG32(regs, 1); + + perfc_incr(vpsci_cpu_off); + PSCI_SET_RESULT(regs, do_psci_cpu_off(pstate)); + return true; + } + case PSCI_cpu_on: + { + uint32_t vcpuid = PSCI_ARG32(regs, 1); + register_t epoint = PSCI_ARG(regs, 2); + + perfc_incr(vpsci_cpu_on); + PSCI_SET_RESULT(regs, do_psci_cpu_on(vcpuid, epoint)); + return true; + } + default: + return false; + } +} + +/* + * PSCI 0.2 or later calls. It will return false if the function ID is + * not handled. + */ +bool do_psci_0_2_call(struct cpu_user_regs *regs, uint32_t fid) +{ + switch ( fid ) + { + case PSCI_0_2_FN32(PSCI_VERSION): + perfc_incr(vpsci_version); + PSCI_SET_RESULT(regs, do_psci_0_2_version()); + return true; + + case PSCI_0_2_FN32(CPU_OFF): + perfc_incr(vpsci_cpu_off); + PSCI_SET_RESULT(regs, do_psci_0_2_cpu_off()); + return true; + + case PSCI_0_2_FN32(MIGRATE_INFO_TYPE): + perfc_incr(vpsci_migrate_info_type); + PSCI_SET_RESULT(regs, do_psci_0_2_migrate_info_type()); + return true; + + case PSCI_0_2_FN32(SYSTEM_OFF): + perfc_incr(vpsci_system_off); + do_psci_0_2_system_off(); + PSCI_SET_RESULT(regs, PSCI_INTERNAL_FAILURE); + return true; + + case PSCI_0_2_FN32(SYSTEM_RESET): + perfc_incr(vpsci_system_reset); + do_psci_0_2_system_reset(); + PSCI_SET_RESULT(regs, PSCI_INTERNAL_FAILURE); + return true; + + case PSCI_0_2_FN32(CPU_ON): + case PSCI_0_2_FN64(CPU_ON): + { + register_t vcpuid = PSCI_ARG(regs, 1); + register_t epoint = PSCI_ARG(regs, 2); + register_t cid = PSCI_ARG(regs, 3); + + perfc_incr(vpsci_cpu_on); + PSCI_SET_RESULT(regs, do_psci_0_2_cpu_on(vcpuid, epoint, cid)); + return true; + } + + case PSCI_0_2_FN32(CPU_SUSPEND): + case PSCI_0_2_FN64(CPU_SUSPEND): + { + uint32_t pstate = PSCI_ARG32(regs, 1); + register_t epoint = PSCI_ARG(regs, 2); + register_t cid = PSCI_ARG(regs, 3); + + perfc_incr(vpsci_cpu_suspend); + PSCI_SET_RESULT(regs, do_psci_0_2_cpu_suspend(pstate, epoint, cid)); + return true; + } + + case PSCI_0_2_FN32(AFFINITY_INFO): + case PSCI_0_2_FN64(AFFINITY_INFO): + { + register_t taff = PSCI_ARG(regs, 1); + uint32_t laff = PSCI_ARG32(regs, 2); + + perfc_incr(vpsci_cpu_affinity_info); + PSCI_SET_RESULT(regs, do_psci_0_2_affinity_info(taff, laff)); + return true; + } + default: + return false; + } +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c index 7ca2880173..9b48d52896 100644 --- a/xen/arch/arm/vsmc.c +++ b/xen/arch/arm/vsmc.c @@ -100,41 +100,13 @@ static bool handle_hypervisor(struct cpu_user_regs *regs) } }-#define PSCI_SET_RESULT(reg, val) set_user_reg(reg, 0, val)-#define PSCI_ARG(reg, n) get_user_reg(reg, n) - -#ifdef CONFIG_ARM_64 -#define PSCI_ARG32(reg, n) (uint32_t)(get_user_reg(reg, n)) -#else -#define PSCI_ARG32(reg, n) PSCI_ARG(reg, n) -#endif - /* Existing (pre SMCCC) APIs. This includes PSCI 0.1 interface */ static bool handle_existing_apis(struct cpu_user_regs *regs) { /* Only least 32 bits are significant (ARM DEN 0028B, page 12) */ - switch ( (uint32_t)get_user_reg(regs, 0) ) - { - case PSCI_cpu_off: - { - uint32_t pstate = PSCI_ARG32(regs, 1); - - perfc_incr(vpsci_cpu_off); - PSCI_SET_RESULT(regs, do_psci_cpu_off(pstate)); - return true; - } - case PSCI_cpu_on: - { - uint32_t vcpuid = PSCI_ARG32(regs, 1); - register_t epoint = PSCI_ARG(regs, 2); + uint32_t fid = (uint32_t)get_user_reg(regs, 0);- perfc_incr(vpsci_cpu_on);- PSCI_SET_RESULT(regs, do_psci_cpu_on(vcpuid, epoint)); - return true; - } - default: - return false; - } + return do_psci_0_1_call(regs, fid); }/* PSCI 0.2 interface and other Standard Secure Calls */@@ -142,70 +114,11 @@ static bool handle_sssc(struct cpu_user_regs *regs) { uint32_t fid = (uint32_t)get_user_reg(regs, 0);- switch ( fid )- { - case PSCI_0_2_FN32(PSCI_VERSION): - perfc_incr(vpsci_version); - PSCI_SET_RESULT(regs, do_psci_0_2_version()); + if ( do_psci_0_2_call(regs, fid) ) return true;- case PSCI_0_2_FN32(CPU_OFF):- perfc_incr(vpsci_cpu_off); - PSCI_SET_RESULT(regs, do_psci_0_2_cpu_off()); - return true; - - case PSCI_0_2_FN32(MIGRATE_INFO_TYPE): - perfc_incr(vpsci_migrate_info_type); - PSCI_SET_RESULT(regs, do_psci_0_2_migrate_info_type()); - return true; - - case PSCI_0_2_FN32(SYSTEM_OFF): - perfc_incr(vpsci_system_off); - do_psci_0_2_system_off(); - PSCI_SET_RESULT(regs, PSCI_INTERNAL_FAILURE); - return true; - - case PSCI_0_2_FN32(SYSTEM_RESET): - perfc_incr(vpsci_system_reset); - do_psci_0_2_system_reset(); - PSCI_SET_RESULT(regs, PSCI_INTERNAL_FAILURE); - return true; - - case PSCI_0_2_FN32(CPU_ON): - case PSCI_0_2_FN64(CPU_ON): - { - register_t vcpuid = PSCI_ARG(regs, 1); - register_t epoint = PSCI_ARG(regs, 2); - register_t cid = PSCI_ARG(regs, 3); - - perfc_incr(vpsci_cpu_on); - PSCI_SET_RESULT(regs, do_psci_0_2_cpu_on(vcpuid, epoint, cid)); - return true; - } - - case PSCI_0_2_FN32(CPU_SUSPEND): - case PSCI_0_2_FN64(CPU_SUSPEND): - { - uint32_t pstate = PSCI_ARG32(regs, 1); - register_t epoint = PSCI_ARG(regs, 2); - register_t cid = PSCI_ARG(regs, 3); - - perfc_incr(vpsci_cpu_suspend); - PSCI_SET_RESULT(regs, do_psci_0_2_cpu_suspend(pstate, epoint, cid)); - return true; - } - - case PSCI_0_2_FN32(AFFINITY_INFO): - case PSCI_0_2_FN64(AFFINITY_INFO): + switch ( fid ) { - register_t taff = PSCI_ARG(regs, 1); - uint32_t laff = PSCI_ARG32(regs, 2); - - perfc_incr(vpsci_cpu_affinity_info); - PSCI_SET_RESULT(regs, do_psci_0_2_affinity_info(taff, laff)); - return true; - } - case ARM_SMCCC_FUNC_CALL_COUNT(STANDARD): return fill_function_call_count(regs, SSSC_SMCCC_FUNCTION_COUNT); Now definition SSSC_SMCCC_FUNCTION_COUNT depends on code in vscpi.c.Maybe it is time to introduce function get_psci_0_2_fn_count() and use it there, what do you think? diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.hindex f7e2139031..3075c998f3 100644 --- a/xen/include/asm-arm/psci.h +++ b/xen/include/asm-arm/psci.h @@ -22,24 +22,9 @@ int call_psci_cpu_on(int cpu); void call_psci_system_off(void); void call_psci_system_reset(void);-/* functions to handle guest PSCI requests */-int32_t do_psci_cpu_on(uint32_t vcpuid, register_t entry_point); -int32_t do_psci_cpu_off(uint32_t power_state); -int32_t do_psci_cpu_suspend(uint32_t power_state, register_t entry_point); -int32_t do_psci_migrate(uint32_t vcpuid); - -/* PSCI 0.2 functions to handle guest PSCI requests */ -uint32_t do_psci_0_2_version(void); -register_t do_psci_0_2_cpu_suspend(uint32_t power_state, register_t entry_point, - register_t context_id); -int32_t do_psci_0_2_cpu_off(void); -int32_t do_psci_0_2_cpu_on(register_t target_cpu, register_t entry_point, - register_t context_id); -int32_t do_psci_0_2_affinity_info(register_t target_affinity, - uint32_t lowest_affinity_level); -uint32_t do_psci_0_2_migrate_info_type(void); -void do_psci_0_2_system_off(void); -void do_psci_0_2_system_reset(void); +/* Functions handle PSCI calls from the guests */ +bool do_psci_0_1_call(struct cpu_user_regs *regs, uint32_t fid); +bool do_psci_0_2_call(struct cpu_user_regs *regs, uint32_t fid);/* PSCI v0.2 interface */#define PSCI_0_2_FN32(name) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |