diff options
author | Achin Gupta <achin.gupta@arm.com> | 2015-08-17 14:56:31 +0100 |
---|---|---|
committer | Achin Gupta <achin.gupta@arm.com> | 2015-08-17 14:56:31 +0100 |
commit | 432b9905d5e8bcf47a077bcda97f98538cee1034 (patch) | |
tree | 92c5b288144be3e9139c8f0aadff31e2d66641cd /include | |
parent | 9caf7e36711bc1387dd4d9fe381e6dffca498ebb (diff) | |
parent | 9d070b9928b874700395ca48780ce2c88b70e588 (diff) |
Merge pull request #361 from achingupta/for_sm/psci_proto_v5
For sm/psci proto v5
Diffstat (limited to 'include')
-rw-r--r-- | include/bl31/context_mgmt.h | 19 | ||||
-rw-r--r-- | include/bl31/cpu_data.h | 8 | ||||
-rw-r--r-- | include/bl31/services/psci.h | 218 | ||||
-rw-r--r-- | include/bl31/services/psci_compat.h | 116 | ||||
-rw-r--r-- | include/common/asm_macros.S | 39 | ||||
-rw-r--r-- | include/common/el3_common_macros.S | 11 | ||||
-rw-r--r-- | include/plat/arm/common/arm_def.h | 37 | ||||
-rw-r--r-- | include/plat/arm/common/plat_arm.h | 39 | ||||
-rw-r--r-- | include/plat/arm/css/common/css_def.h | 3 | ||||
-rw-r--r-- | include/plat/common/common_def.h | 11 | ||||
-rw-r--r-- | include/plat/common/platform.h | 50 |
11 files changed, 450 insertions, 101 deletions
diff --git a/include/bl31/context_mgmt.h b/include/bl31/context_mgmt.h index 6e82fb70..1ef40766 100644 --- a/include/bl31/context_mgmt.h +++ b/include/bl31/context_mgmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,6 +31,7 @@ #ifndef __CM_H__ #define __CM_H__ +#include <common_def.h> #include <cpu_data.h> #include <stdint.h> @@ -43,13 +44,23 @@ struct entry_point_info; * Function & variable prototypes ******************************************************************************/ void cm_init(void); -void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state); +void *cm_get_context_by_mpidr(uint64_t mpidr, + uint32_t security_state) __warn_deprecated; static inline void *cm_get_context(uint32_t security_state); void cm_set_context_by_mpidr(uint64_t mpidr, void *context, - uint32_t security_state); + uint32_t security_state) __warn_deprecated; +void *cm_get_context_by_index(unsigned int cpu_idx, + unsigned int security_state); +void cm_set_context_by_index(unsigned int cpu_idx, + void *context, + unsigned int security_state); static inline void cm_set_context(void *context, uint32_t security_state); -void cm_init_context(uint64_t mpidr, const struct entry_point_info *ep); +void cm_init_context(uint64_t mpidr, + const struct entry_point_info *ep) __warn_deprecated; +void cm_init_my_context(const struct entry_point_info *ep); +void cm_init_context_by_index(unsigned int cpu_idx, + const struct entry_point_info *ep); void cm_prepare_el3_exit(uint32_t security_state); void cm_el1_sysregs_context_save(uint32_t security_state); void cm_el1_sysregs_context_restore(uint32_t security_state); diff --git a/include/bl31/cpu_data.h b/include/bl31/cpu_data.h index 50f509bb..2b506c73 100644 --- a/include/bl31/cpu_data.h +++ b/include/bl31/cpu_data.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -103,7 +103,6 @@ CASSERT(CPU_DATA_CPU_OPS_PTR == __builtin_offsetof assert_cpu_data_cpu_ops_ptr_offset_mismatch); struct cpu_data *_cpu_data_by_index(uint32_t cpu_index); -struct cpu_data *_cpu_data_by_mpidr(uint64_t mpidr); /* Return the cpu_data structure for the current CPU. */ static inline struct cpu_data *_cpu_data(void) @@ -123,12 +122,13 @@ void init_cpu_ops(void); #define set_cpu_data(_m, _v) _cpu_data()->_m = _v #define get_cpu_data_by_index(_ix, _m) _cpu_data_by_index(_ix)->_m #define set_cpu_data_by_index(_ix, _m, _v) _cpu_data_by_index(_ix)->_m = _v -#define get_cpu_data_by_mpidr(_id, _m) _cpu_data_by_mpidr(_id)->_m -#define set_cpu_data_by_mpidr(_id, _m, _v) _cpu_data_by_mpidr(_id)->_m = _v #define flush_cpu_data(_m) flush_dcache_range((uint64_t) \ &(_cpu_data()->_m), \ sizeof(_cpu_data()->_m)) +#define inv_cpu_data(_m) inv_dcache_range((uint64_t) \ + &(_cpu_data()->_m), \ + sizeof(_cpu_data()->_m)) #define flush_cpu_data_by_index(_ix, _m) \ flush_dcache_range((uint64_t) \ &(_cpu_data_by_index(_ix)->_m), \ diff --git a/include/bl31/services/psci.h b/include/bl31/services/psci.h index dd1891c6..004dd614 100644 --- a/include/bl31/services/psci.h +++ b/include/bl31/services/psci.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -32,17 +32,33 @@ #define __PSCI_H__ #include <bakery_lock.h> -#include <platform_def.h> /* for PLATFORM_NUM_AFFS */ +#include <platform_def.h> /* for PLAT_NUM_PWR_DOMAINS */ +#if ENABLE_PLAT_COMPAT +#include <psci_compat.h> +#endif /******************************************************************************* - * Number of affinity instances whose state this psci imp. can track + * Number of power domains whose state this psci imp. can track ******************************************************************************/ -#ifdef PLATFORM_NUM_AFFS -#define PSCI_NUM_AFFS PLATFORM_NUM_AFFS +#ifdef PLAT_NUM_PWR_DOMAINS +#define PSCI_NUM_PWR_DOMAINS PLAT_NUM_PWR_DOMAINS #else -#define PSCI_NUM_AFFS (2 * PLATFORM_CORE_COUNT) +#define PSCI_NUM_PWR_DOMAINS (2 * PLATFORM_CORE_COUNT) #endif +#define PSCI_NUM_NON_CPU_PWR_DOMAINS (PSCI_NUM_PWR_DOMAINS - \ + PLATFORM_CORE_COUNT) + +/* This is the power level corresponding to a CPU */ +#define PSCI_CPU_PWR_LVL 0 + +/* + * The maximum power level supported by PSCI. Since PSCI CPU_SUSPEND + * uses the old power_state parameter format which has 2 bits to specify the + * power level, this constant is defined to be 3. + */ +#define PSCI_MAX_PWR_LVL 3 + /******************************************************************************* * Defines for runtime services func ids ******************************************************************************/ @@ -84,27 +100,35 @@ * PSCI CPU_SUSPEND 'power_state' parameter specific defines ******************************************************************************/ #define PSTATE_ID_SHIFT 0 -#define PSTATE_TYPE_SHIFT 16 -#define PSTATE_AFF_LVL_SHIFT 24 +#if PSCI_EXTENDED_STATE_ID +#define PSTATE_VALID_MASK 0xB0000000 +#define PSTATE_TYPE_SHIFT 30 +#define PSTATE_ID_MASK 0xfffffff +#else +#define PSTATE_VALID_MASK 0xFCFE0000 +#define PSTATE_TYPE_SHIFT 16 +#define PSTATE_PWR_LVL_SHIFT 24 #define PSTATE_ID_MASK 0xffff -#define PSTATE_TYPE_MASK 0x1 -#define PSTATE_AFF_LVL_MASK 0x3 -#define PSTATE_VALID_MASK 0xFCFE0000 +#define PSTATE_PWR_LVL_MASK 0x3 + +#define psci_get_pstate_pwrlvl(pstate) (((pstate) >> PSTATE_PWR_LVL_SHIFT) & \ + PSTATE_PWR_LVL_MASK) +#define psci_make_powerstate(state_id, type, pwrlvl) \ + (((state_id) & PSTATE_ID_MASK) << PSTATE_ID_SHIFT) |\ + (((type) & PSTATE_TYPE_MASK) << PSTATE_TYPE_SHIFT) |\ + (((pwrlvl) & PSTATE_PWR_LVL_MASK) << PSTATE_PWR_LVL_SHIFT) +#endif /* __PSCI_EXTENDED_STATE_ID__ */ #define PSTATE_TYPE_STANDBY 0x0 #define PSTATE_TYPE_POWERDOWN 0x1 +#define PSTATE_TYPE_MASK 0x1 #define psci_get_pstate_id(pstate) (((pstate) >> PSTATE_ID_SHIFT) & \ PSTATE_ID_MASK) #define psci_get_pstate_type(pstate) (((pstate) >> PSTATE_TYPE_SHIFT) & \ PSTATE_TYPE_MASK) -#define psci_get_pstate_afflvl(pstate) (((pstate) >> PSTATE_AFF_LVL_SHIFT) & \ - PSTATE_AFF_LVL_MASK) -#define psci_make_powerstate(state_id, type, afflvl) \ - (((state_id) & PSTATE_ID_MASK) << PSTATE_ID_SHIFT) |\ - (((type) & PSTATE_TYPE_MASK) << PSTATE_TYPE_SHIFT) |\ - (((afflvl) & PSTATE_AFF_LVL_MASK) << PSTATE_AFF_LVL_SHIFT) +#define psci_check_power_state(pstate) ((pstate) & PSTATE_VALID_MASK) /******************************************************************************* * PSCI CPU_FEATURES feature flag specific defines @@ -113,6 +137,11 @@ #define FF_PSTATE_SHIFT 1 #define FF_PSTATE_ORIG 0 #define FF_PSTATE_EXTENDED 1 +#if PSCI_EXTENDED_STATE_ID +#define FF_PSTATE FF_PSTATE_EXTENDED +#else +#define FF_PSTATE FF_PSTATE_ORIG +#endif /* Features flags for CPU SUSPEND OS Initiated mode support. Bits [0:0] */ #define FF_MODE_SUPPORT_SHIFT 0 @@ -136,33 +165,74 @@ #define PSCI_E_INTERN_FAIL -6 #define PSCI_E_NOT_PRESENT -7 #define PSCI_E_DISABLED -8 +#define PSCI_E_INVALID_ADDRESS -9 -/******************************************************************************* - * PSCI affinity state related constants. An affinity instance could be present - * or absent physically to cater for asymmetric topologies. If present then it - * could in one of the 4 further defined states. - ******************************************************************************/ -#define PSCI_STATE_SHIFT 1 -#define PSCI_STATE_MASK 0xff +#define PSCI_INVALID_MPIDR ~((u_register_t)0) -#define PSCI_AFF_ABSENT 0x0 -#define PSCI_AFF_PRESENT 0x1 -#define PSCI_STATE_ON 0x0 -#define PSCI_STATE_OFF 0x1 -#define PSCI_STATE_ON_PENDING 0x2 -#define PSCI_STATE_SUSPEND 0x3 +#ifndef __ASSEMBLY__ -#define PSCI_INVALID_DATA -1 +#include <stdint.h> +#include <types.h> -#define get_phys_state(x) (x != PSCI_STATE_ON ? \ - PSCI_STATE_OFF : PSCI_STATE_ON) +/* + * These are the states reported by the PSCI_AFFINITY_INFO API for the specified + * CPU. The definitions of these states can be found in Section 5.7.1 in the + * PSCI specification (ARM DEN 0022C). + */ +typedef enum { + AFF_STATE_ON = 0, + AFF_STATE_OFF = 1, + AFF_STATE_ON_PENDING = 2 +} aff_info_state_t; -#define psci_validate_power_state(pstate) (pstate & PSTATE_VALID_MASK) +/* + * Macro to represent invalid affinity level within PSCI. + */ +#define PSCI_INVALID_PWR_LVL (PLAT_MAX_PWR_LVL + 1) +/* + * Type for representing the local power state at a particular level. + */ +typedef uint8_t plat_local_state_t; -#ifndef __ASSEMBLY__ +/* The local state macro used to represent RUN state. */ +#define PSCI_LOCAL_STATE_RUN 0 -#include <stdint.h> +/* + * Macro to test whether the plat_local_state is RUN state + */ +#define is_local_state_run(plat_local_state) \ + ((plat_local_state) == PSCI_LOCAL_STATE_RUN) + +/* + * Macro to test whether the plat_local_state is RETENTION state + */ +#define is_local_state_retn(plat_local_state) \ + (((plat_local_state) > PSCI_LOCAL_STATE_RUN) && \ + ((plat_local_state) <= PLAT_MAX_RET_STATE)) + +/* + * Macro to test whether the plat_local_state is OFF state + */ +#define is_local_state_off(plat_local_state) \ + (((plat_local_state) > PLAT_MAX_RET_STATE) && \ + ((plat_local_state) <= PLAT_MAX_OFF_STATE)) + +/***************************************************************************** + * This data structure defines the representation of the power state parameter + * for its exchange between the generic PSCI code and the platform port. For + * example, it is used by the platform port to specify the requested power + * states during a power management operation. It is used by the generic code to + * inform the platform about the target power states that each level should + * enter. + ****************************************************************************/ +typedef struct psci_power_state { + /* + * The pwr_domain_state[] stores the local power state at each level + * for the CPU. + */ + plat_local_state_t pwr_domain_state[PLAT_MAX_PWR_LVL + 1]; +} psci_power_state_t; /******************************************************************************* * Structure used to store per-cpu information relevant to the PSCI service. @@ -170,11 +240,19 @@ * this information will not reside on a cache line shared with another cpu. ******************************************************************************/ typedef struct psci_cpu_data { - uint32_t power_state; - uint32_t max_phys_off_afflvl; /* Highest affinity level in physically - powered off state */ + /* State as seen by PSCI Affinity Info API */ + aff_info_state_t aff_info_state; + + /* + * Highest power level which takes part in a power management + * operation. + */ + unsigned char target_pwrlvl; + + /* The local power state of this CPU */ + plat_local_state_t local_state; #if !USE_COHERENT_MEM - bakery_info_t pcpu_bakery_info[PSCI_NUM_AFFS]; + bakery_info_t pcpu_bakery_info[PSCI_NUM_NON_CPU_PWR_DOMAINS]; #endif } psci_cpu_data_t; @@ -182,25 +260,22 @@ typedef struct psci_cpu_data { * Structure populated by platform specific code to export routines which * perform common low level pm functions ******************************************************************************/ -typedef struct plat_pm_ops { - void (*affinst_standby)(unsigned int power_state); - int (*affinst_on)(unsigned long mpidr, - unsigned long sec_entrypoint, - unsigned int afflvl, - unsigned int state); - void (*affinst_off)(unsigned int afflvl, unsigned int state); - void (*affinst_suspend)(unsigned long sec_entrypoint, - unsigned int afflvl, - unsigned int state); - void (*affinst_on_finish)(unsigned int afflvl, unsigned int state); - void (*affinst_suspend_finish)(unsigned int afflvl, - unsigned int state); +typedef struct plat_psci_ops { + void (*cpu_standby)(plat_local_state_t cpu_state); + int (*pwr_domain_on)(u_register_t mpidr); + void (*pwr_domain_off)(const psci_power_state_t *target_state); + void (*pwr_domain_suspend)(const psci_power_state_t *target_state); + void (*pwr_domain_on_finish)(const psci_power_state_t *target_state); + void (*pwr_domain_suspend_finish)( + const psci_power_state_t *target_state); void (*system_off)(void) __dead2; void (*system_reset)(void) __dead2; - int (*validate_power_state)(unsigned int power_state); - int (*validate_ns_entrypoint)(unsigned long ns_entrypoint); - unsigned int (*get_sys_suspend_power_state)(void); -} plat_pm_ops_t; + int (*validate_power_state)(unsigned int power_state, + psci_power_state_t *req_state); + int (*validate_ns_entrypoint)(uintptr_t ns_entrypoint); + void (*get_sys_suspend_power_state)( + psci_power_state_t *req_state); +} plat_psci_ops_t; /******************************************************************************* * Optional structure populated by the Secure Payload Dispatcher to be given a @@ -224,22 +299,23 @@ typedef struct spd_pm_ops { * Function & Data prototypes ******************************************************************************/ unsigned int psci_version(void); -int psci_affinity_info(unsigned long, unsigned int); -int psci_migrate(unsigned long); +int psci_cpu_on(u_register_t target_cpu, + uintptr_t entrypoint, + u_register_t context_id); +int psci_cpu_suspend(unsigned int power_state, + uintptr_t entrypoint, + u_register_t context_id); +int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id); +int psci_cpu_off(void); +int psci_affinity_info(u_register_t target_affinity, + unsigned int lowest_affinity_level); +int psci_migrate(u_register_t target_cpu); int psci_migrate_info_type(void); long psci_migrate_info_up_cpu(void); -int psci_cpu_on(unsigned long, - unsigned long, - unsigned long); +int psci_features(unsigned int psci_fid); void __dead2 psci_power_down_wfi(void); -void psci_aff_on_finish_entry(void); -void psci_aff_suspend_finish_entry(void); +void psci_entrypoint(void); void psci_register_spd_pm_hook(const spd_pm_ops_t *); -int psci_get_suspend_stateid_by_mpidr(unsigned long); -int psci_get_suspend_stateid(void); -int psci_get_suspend_afflvl(void); -uint32_t psci_get_max_phys_off_afflvl(void); - uint64_t psci_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, @@ -250,10 +326,8 @@ uint64_t psci_smc_handler(uint32_t smc_fid, uint64_t flags); /* PSCI setup function */ -int32_t psci_setup(void); - +int psci_setup(void); #endif /*__ASSEMBLY__*/ - #endif /* __PSCI_H__ */ diff --git a/include/bl31/services/psci_compat.h b/include/bl31/services/psci_compat.h new file mode 100644 index 00000000..24bd8dcc --- /dev/null +++ b/include/bl31/services/psci_compat.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PSCI_COMPAT_H__ +#define __PSCI_COMPAT_H__ + +#include <arch.h> +#include <platform_def.h> + +#ifndef __ASSEMBLY__ +/* + * The below declarations are to enable compatibility for the platform ports + * using the old platform interface and psci helpers. + */ +#define PLAT_MAX_PWR_LVL PLATFORM_MAX_AFFLVL +#define PLAT_NUM_PWR_DOMAINS PLATFORM_NUM_AFFS + +/******************************************************************************* + * PSCI affinity related constants. An affinity instance could + * be present or absent physically to cater for asymmetric topologies. + ******************************************************************************/ +#define PSCI_AFF_ABSENT 0x0 +#define PSCI_AFF_PRESENT 0x1 + +#define PSCI_STATE_ON 0x0 +#define PSCI_STATE_OFF 0x1 +#define PSCI_STATE_ON_PENDING 0x2 +#define PSCI_STATE_SUSPEND 0x3 + +/* + * Using the compatibility platform interfaces means that the local states + * used in psci_power_state_t need to only convey whether its power down + * or standby state. The onus is on the platform port to do the right thing + * including the state coordination in case multiple power down states are + * involved. Hence if we assume 3 generic states viz, run, standby and + * power down, we can assign 1 and 2 to standby and power down respectively. + */ +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE 2 + +/* + * Macro to represent invalid affinity level within PSCI. + */ +#define PSCI_INVALID_DATA -1 + +#define psci_get_pstate_afflvl(pstate) psci_get_pstate_pwrlvl(pstate) + +/* + * This array stores the 'power_state' requests of each CPU during + * CPU_SUSPEND and SYSTEM_SUSPEND which will be populated by the + * compatibility layer when appropriate platform hooks are invoked. + */ +extern unsigned int psci_power_state_compat[PLATFORM_CORE_COUNT]; + +/******************************************************************************* + * Structure populated by platform specific code to export routines which + * perform common low level pm functions + ******************************************************************************/ +typedef struct plat_pm_ops { + void (*affinst_standby)(unsigned int power_state); + int (*affinst_on)(unsigned long mpidr, + unsigned long sec_entrypoint, + unsigned int afflvl, + unsigned int state); + void (*affinst_off)(unsigned int afflvl, unsigned int state); + void (*affinst_suspend)(unsigned long sec_entrypoint, + unsigned int afflvl, + unsigned int state); + void (*affinst_on_finish)(unsigned int afflvl, unsigned int state); + void (*affinst_suspend_finish)(unsigned int afflvl, + unsigned int state); + void (*system_off)(void) __dead2; + void (*system_reset)(void) __dead2; + int (*validate_power_state)(unsigned int power_state); + int (*validate_ns_entrypoint)(unsigned long ns_entrypoint); + unsigned int (*get_sys_suspend_power_state)(void); +} plat_pm_ops_t; + +/******************************************************************************* + * Function & Data prototypes to enable compatibility for older platform ports + ******************************************************************************/ +int psci_get_suspend_stateid_by_mpidr(unsigned long); +int psci_get_suspend_stateid(void); +int psci_get_suspend_powerstate(void); +unsigned int psci_get_max_phys_off_afflvl(void); +int psci_get_suspend_afflvl(void); + +#endif /* ____ASSEMBLY__ */ +#endif /* __PSCI_COMPAT_H__ */ diff --git a/include/common/asm_macros.S b/include/common/asm_macros.S index 45058a60..128259f1 100644 --- a/include/common/asm_macros.S +++ b/include/common/asm_macros.S @@ -100,6 +100,29 @@ .endm /* + * Theses macros are used to create function labels for deprecated + * APIs. If WARN_DEPRECATED is non zero, the callers of these APIs + * will fail to link and cause build failure. + */ +#if WARN_DEPRECATED + .macro func_deprecated _name + func deprecated\_name + .endm + + .macro endfunc_deprecated _name + endfunc deprecated\_name + .endm +#else + .macro func_deprecated _name + func \_name + .endm + + .macro endfunc_deprecated _name + endfunc \_name + .endm +#endif + + /* * This macro declares an array of 1 or more stacks, properly * aligned and in the requested section */ @@ -115,6 +138,7 @@ .space ((\_count) * (\_size)), 0 .endm +#if ENABLE_PLAT_COMPAT /* * This macro calculates the base address of an MP stack using the * platform_get_core_pos() index, the name of the stack storage and @@ -129,6 +153,21 @@ mov x1, #\_size madd x0, x0, x1, x2 .endm +#endif + + /* + * This macro calculates the base address of the current CPU's MP stack + * using the plat_my_core_pos() index, the name of the stack storage + * and the size of each stack + * Out: X0 = physical address of stack base + * Clobber: X30, X1, X2 + */ + .macro get_my_mp_stack _name, _size + bl plat_my_core_pos + ldr x2, =(\_name + \_size) + mov x1, #\_size + madd x0, x0, x1, x2 + .endm /* * This macro calculates the base address of a UP stack using the diff --git a/include/common/el3_common_macros.S b/include/common/el3_common_macros.S index eb033a6e..7946e728 100644 --- a/include/common/el3_common_macros.S +++ b/include/common/el3_common_macros.S @@ -164,8 +164,7 @@ * then it means it is a warm boot so jump to this address. * ------------------------------------------------------------- */ - mrs x0, mpidr_el1 - bl platform_get_entrypoint + bl plat_get_my_entrypoint cbz x0, do_cold_boot br x0 @@ -181,9 +180,8 @@ * of that state and allows entry into the OS. * ------------------------------------------------------------- */ - mrs x0, mpidr_el1 - bl platform_is_primary_cpu - cbnz x0, do_primary_cold_boot + bl plat_is_my_cpu_primary + cbnz w0, do_primary_cold_boot /* This is a cold boot on a secondary CPU */ bl plat_secondary_cold_boot_setup @@ -249,8 +247,7 @@ * moment. * --------------------------------------------------------------------- */ - mrs x0, mpidr_el1 - bl platform_set_stack + bl plat_set_my_stack .endm #endif /* __EL3_COMMON_MACROS_S__ */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 4447af2c..377bfaa2 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -30,6 +30,7 @@ #ifndef __ARM_DEF_H__ #define __ARM_DEF_H__ +#include <arch.h> #include <common_def.h> #include <platform_def.h> #include <tbbr_img_def.h> @@ -47,6 +48,25 @@ #define ARM_CACHE_WRITEBACK_SHIFT 6 +/* + * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The + * power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define ARM_PWR_LVL0 MPIDR_AFFLVL0 +#define ARM_PWR_LVL1 MPIDR_AFFLVL1 + +/* + * Macros for local power states in ARM platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define ARM_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define ARM_LOCAL_STATE_RET 1 +/* Local power state for OFF/power-down. Valid for CPU and cluster power + domains */ +#define ARM_LOCAL_STATE_OFF 2 + /* Memory location options for TSP */ #define ARM_TRUSTED_SRAM_ID 0 #define ARM_TRUSTED_DRAM_ID 1 @@ -163,9 +183,22 @@ #define ADDR_SPACE_SIZE (1ull << 32) -#define PLATFORM_NUM_AFFS (ARM_CLUSTER_COUNT + \ +#define PLAT_NUM_PWR_DOMAINS (ARM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) -#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL1 +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + +/* + * This macro defines the deepest retention state possible. A higher state + * id will represent an invalid or a power down state. + */ +#define PLAT_MAX_RET_STATE ARM_LOCAL_STATE_RET + +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF + #define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER0_CORE_COUNT + \ PLAT_ARM_CLUSTER1_CORE_COUNT) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index d7eaac1d..823212cb 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -148,6 +148,35 @@ CASSERT(PLAT_PCPU_DATA_SIZE == sizeof(arm_cpu_data_t), #endif /* IMAGE_BL31 */ +#if ARM_RECOM_STATE_ID_ENC +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define ARM_LOCAL_PSTATE_WIDTH 4 +#define ARM_LOCAL_PSTATE_MASK ((1 << ARM_LOCAL_PSTATE_WIDTH) - 1) + +/* Macros to construct the composite power state */ + +/* Make composite power state parameter till power level 0 */ +#if PSCI_EXTENDED_STATE_ID + +#define arm_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT)) +#else +#define arm_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | \ + ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \ + ((type) << PSTATE_TYPE_SHIFT)) +#endif /* __PSCI_EXTENDED_STATE_ID__ */ + +/* Make composite power state parameter till power level 1 */ +#define arm_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \ + (((lvl1_state) << ARM_LOCAL_PSTATE_WIDTH) | \ + arm_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type)) + +#endif /* __ARM_RECOM_STATE_ID_ENC__ */ + /* CCI utility functions */ void arm_cci_init(void); @@ -159,8 +188,12 @@ void arm_io_setup(void); void arm_tzc_setup(void); /* PM utility functions */ -int32_t arm_do_affinst_actions(unsigned int afflvl, unsigned int state); -int arm_validate_power_state(unsigned int power_state); +int arm_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state); +int arm_validate_ns_entrypoint(uintptr_t entrypoint); + +/* Topology utility function */ +int arm_check_mpidr(u_register_t mpidr); /* BL1 utility functions */ void arm_bl1_early_platform_setup(void); @@ -199,7 +232,7 @@ int plat_arm_get_alt_image_source( unsigned int image_id, uintptr_t *dev_handle, uintptr_t *image_spec); -void plat_arm_topology_setup(void); +unsigned int plat_arm_calc_core_pos(u_register_t mpidr); #endif /* __PLAT_ARM_H__ */ diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index 268438ff..e3dd2b0f 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -39,8 +39,7 @@ *************************************************************************/ #define MHU_PAYLOAD_CACHED 0 -#define TRUSTED_MAILBOXES_BASE ARM_TRUSTED_SRAM_BASE -#define TRUSTED_MAILBOX_SHIFT 4 +#define TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE #define NSROM_BASE 0x1f000000 #define NSROM_SIZE 0x00001000 diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index 1b3203e1..077080df 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -67,6 +67,17 @@ #define MAKE_ULL(x) x #endif +/* + * Macros to wrap declarations of deprecated APIs within Trusted Firmware. + * The callers of these APIs will continue to compile as long as the build + * flag WARN_DEPRECATED is zero. Else the compiler will emit a warning + * when the callers of these APIs are compiled. + */ +#if WARN_DEPRECATED +#define __warn_deprecated __attribute__ ((deprecated)) +#else +#define __warn_deprecated +#endif #endif /* __COMMON_DEF_H__ */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 469d46b6..8071f394 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,13 +31,14 @@ #ifndef __PLATFORM_H__ #define __PLATFORM_H__ +#include <psci.h> #include <stdint.h> +#include <types.h> /******************************************************************************* * Forward declarations ******************************************************************************/ -struct plat_pm_ops; struct meminfo; struct image_info; struct entry_point_info; @@ -59,6 +60,8 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, uintptr_t *image_spec); unsigned long plat_get_ns_image_entrypoint(void); +unsigned int plat_my_core_pos(void); +int plat_core_pos_by_mpidr(u_register_t mpidr); /******************************************************************************* * Mandatory interrupt management functions @@ -74,8 +77,7 @@ uint32_t plat_interrupt_type_to_line(uint32_t type, /******************************************************************************* * Optional common functions (may be overridden) ******************************************************************************/ -unsigned int platform_get_core_pos(unsigned long mpidr); -unsigned long platform_get_stack(unsigned long mpidr); +unsigned long plat_get_my_stack(void); void plat_report_exception(unsigned long); int plat_crash_console_init(void); int plat_crash_console_putc(int c); @@ -181,9 +183,16 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type); /******************************************************************************* * Mandatory PSCI functions (BL3-1) ******************************************************************************/ -int platform_setup_pm(const struct plat_pm_ops **); -unsigned int plat_get_aff_count(unsigned int, unsigned long); -unsigned int plat_get_aff_state(unsigned int, unsigned long); +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const struct plat_psci_ops **); +const unsigned char *plat_get_power_domain_tree_desc(void); + +/******************************************************************************* + * Optional PSCI functions (BL3-1). + ******************************************************************************/ +plat_local_state_t plat_get_target_pwr_state(unsigned int lvl, + const plat_local_state_t *states, + unsigned int ncpu); /******************************************************************************* * Optional BL3-1 functions (may be overridden) @@ -201,4 +210,31 @@ void bl32_plat_enable_mmu(uint32_t flags); int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, unsigned int *flags); +#if ENABLE_PLAT_COMPAT +/* + * The below declarations are to enable compatibility for the platform ports + * using the old platform interface. + */ + +/******************************************************************************* + * Optional common functions (may be overridden) + ******************************************************************************/ +unsigned int platform_get_core_pos(unsigned long mpidr); + +/******************************************************************************* + * Mandatory PSCI Compatibility functions (BL3-1) + ******************************************************************************/ +int platform_setup_pm(const plat_pm_ops_t **); + +unsigned int plat_get_aff_count(unsigned int, unsigned long); +unsigned int plat_get_aff_state(unsigned int, unsigned long); +#else +/* + * The below function enable Trusted Firmware components like SPDs which + * haven't migrated to the new platform API to compile on platforms which + * have the compatibility layer disabled. + */ +unsigned int platform_get_core_pos(unsigned long mpidr) __warn_deprecated; + +#endif /* __ENABLE_PLAT_COMPAT__ */ #endif /* __PLATFORM_H__ */ |