diff options
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | docs/porting-guide.md | 50 | ||||
-rw-r--r-- | docs/user-guide.md | 5 | ||||
-rw-r--r-- | include/plat/common/platform.h | 7 | ||||
-rw-r--r-- | lib/psci/psci_common.c | 12 | ||||
-rw-r--r-- | lib/psci/psci_main.c | 17 | ||||
-rw-r--r-- | lib/psci/psci_off.c | 10 | ||||
-rw-r--r-- | lib/psci/psci_private.h | 15 | ||||
-rw-r--r-- | lib/psci/psci_stat.c | 65 | ||||
-rw-r--r-- | lib/psci/psci_suspend.c | 19 | ||||
-rw-r--r-- | plat/arm/common/arm_common.mk | 3 | ||||
-rw-r--r-- | plat/common/plat_psci_common.c | 119 | ||||
-rw-r--r-- | tools/cert_create/include/key.h | 1 | ||||
-rw-r--r-- | tools/cert_create/src/cert.c | 10 | ||||
-rw-r--r-- | tools/cert_create/src/ext.c | 29 | ||||
-rw-r--r-- | tools/cert_create/src/key.c | 28 | ||||
-rw-r--r-- | tools/cert_create/src/main.c | 24 | ||||
-rw-r--r-- | tools/fiptool/fiptool.c | 35 |
18 files changed, 261 insertions, 195 deletions
@@ -111,7 +111,7 @@ endif # Default build string (git branch and commit) ifeq (${BUILD_STRING},) - BUILD_STRING := $(shell git log -n 1 --pretty=format:"%h") + BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null) endif VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}(${BUILD_TYPE}):${BUILD_STRING} @@ -346,11 +346,6 @@ ifneq (${GENERATE_COT},0) endif endif -# Make sure PMF is enabled if PSCI STAT is enabled. -ifeq (${ENABLE_PSCI_STAT},1) -ENABLE_PMF := 1 -endif - ifneq (${FIP_ALIGN},0) FIP_ARGS += --align ${FIP_ALIGN} endif diff --git a/docs/porting-guide.md b/docs/porting-guide.md index e8486f12..a5e59667 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -1707,10 +1707,56 @@ level could enter. It depends on the `validate_power_state()` handler to convert the power-state parameter (possibly encoding a composite power state) passed in a PSCI `CPU_SUSPEND` call to this representation. -The following functions must be implemented to initialize PSCI functionality in -the ARM Trusted Firmware. +The following functions form part of platform port of PSCI functionality. +### Function : plat_psci_stat_accounting_start() [optional] + + Argument : const psci_power_state_t * + Return : void + +This is an optional hook that platforms can implement for residency statistics +accounting before entering a low power state. The `pwr_domain_state` field of +`state_info` (first argument) can be inspected if stat accounting is done +differently at CPU level versus higher levels. As an example, if the element at +index 0 (CPU power level) in the `pwr_domain_state` array indicates a power down +state, special hardware logic may be programmed in order to keep track of the +residency statistics. For higher levels (array indices > 0), the residency +statistics could be tracked in software using PMF. If `ENABLE_PMF` is set, the +default implementation will use PMF to capture timestamps. + +### Function : plat_psci_stat_accounting_stop() [optional] + + Argument : const psci_power_state_t * + Return : void + +This is an optional hook that platforms can implement for residency statistics +accounting after exiting from a low power state. The `pwr_domain_state` field +of `state_info` (first argument) can be inspected if stat accounting is done +differently at CPU level versus higher levels. As an example, if the element at +index 0 (CPU power level) in the `pwr_domain_state` array indicates a power down +state, special hardware logic may be programmed in order to keep track of the +residency statistics. For higher levels (array indices > 0), the residency +statistics could be tracked in software using PMF. If `ENABLE_PMF` is set, the +default implementation will use PMF to capture timestamps. + +### Function : plat_psci_stat_get_residency() [optional] + + Argument : unsigned int, const psci_power_state_t *, int + Return : u_register_t + +This is an optional interface that is is invoked after resuming from a low power +state and provides the time spent resident in that low power state by the power +domain at a particular power domain level. When a CPU wakes up from suspend, +all its parent power domain levels are also woken up. The generic PSCI code +invokes this function for each parent power domain that is resumed and it +identified by the `lvl` (first argument) parameter. The `state_info` (second +argument) describes the low power state that the power domain has resumed from. +The current CPU is the first CPU in the power domain to resume from the low +power state and the `last_cpu_idx` (third parameter) is the index of the last +CPU in the power domain to suspend and may be needed to calculate the residency +for that power domain. + ### Function : plat_get_target_pwr_state() [optional] Argument : unsigned int, const plat_local_state_t *, unsigned int diff --git a/docs/user-guide.md b/docs/user-guide.md index 99199861..a4411dd2 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -277,8 +277,9 @@ performed. * `ENABLE_PSCI_STAT`: Boolean option to enable support for optional PSCI functions `PSCI_STAT_RESIDENCY` and `PSCI_STAT_COUNT`. Default is 0. - Enabling this option enables the `ENABLE_PMF` build option as well. - The PMF is used for collecting the statistics. + In the absence of an alternate stat collection backend, `ENABLE_PMF` must + be enabled. If `ENABLE_PMF` is set, the residency statistics are tracked in + software. * `ENABLE_RUNTIME_INSTRUMENTATION`: Boolean option to enable runtime instrumentation which injects timestamp collection points into diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index f904292b..73bb6431 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -254,6 +254,11 @@ const unsigned char *plat_get_power_domain_tree_desc(void); /******************************************************************************* * Optional PSCI functions (BL31). ******************************************************************************/ +void plat_psci_stat_accounting_start(const psci_power_state_t *state_info); +void plat_psci_stat_accounting_stop(const psci_power_state_t *state_info); +u_register_t plat_psci_stat_get_residency(unsigned int lvl, + const psci_power_state_t *state_info, + int last_cpu_index); plat_local_state_t plat_get_target_pwr_state(unsigned int lvl, const plat_local_state_t *states, unsigned int ncpu); diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index 68cdd6eb..822329e6 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -760,13 +760,7 @@ void psci_warmboot_entrypoint(void) cpu_idx); #if ENABLE_PSCI_STAT - /* - * Capture power up time-stamp. - * No cache maintenance is required as caches are off - * and writes are direct to the main memory. - */ - PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR, - PMF_NO_CACHE_MAINT); + plat_psci_stat_accounting_stop(&state_info); #endif psci_get_target_local_pwr_states(end_pwrlvl, &state_info); @@ -801,7 +795,7 @@ void psci_warmboot_entrypoint(void) * Since caches are now enabled, it's necessary to do cache * maintenance before reading that same data. */ - psci_stats_update_pwr_up(end_pwrlvl, &state_info, PMF_CACHE_MAINT); + psci_stats_update_pwr_up(end_pwrlvl, &state_info); #endif /* diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c index 0a3a60ac..5e166b52 100644 --- a/lib/psci/psci_main.c +++ b/lib/psci/psci_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -117,13 +117,7 @@ int psci_cpu_suspend(unsigned int power_state, psci_set_cpu_local_state(cpu_pd_state); #if ENABLE_PSCI_STAT - /* - * Capture time-stamp before CPU standby - * No cache maintenance is needed as caches - * are ON through out the CPU standby operation. - */ - PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, - PMF_NO_CACHE_MAINT); + plat_psci_stat_accounting_start(&state_info); #endif #if ENABLE_RUNTIME_INSTRUMENTATION @@ -144,13 +138,10 @@ int psci_cpu_suspend(unsigned int power_state, #endif #if ENABLE_PSCI_STAT - /* Capture time-stamp after CPU standby */ - PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR, - PMF_NO_CACHE_MAINT); + plat_psci_stat_accounting_stop(&state_info); /* Update PSCI stats */ - psci_stats_update_pwr_up(PSCI_CPU_PWR_LVL, &state_info, - PMF_NO_CACHE_MAINT); + psci_stats_update_pwr_up(PSCI_CPU_PWR_LVL, &state_info); #endif return PSCI_E_SUCCESS; diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c index 897bf319..394aaa3b 100644 --- a/lib/psci/psci_off.c +++ b/lib/psci/psci_off.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -137,13 +137,7 @@ int psci_do_cpu_off(unsigned int end_pwrlvl) psci_plat_pm_ops->pwr_domain_off(&state_info); #if ENABLE_PSCI_STAT - /* - * Capture time-stamp while entering low power state. - * No cache maintenance needed because caches are off - * and writes are direct to main memory. - */ - PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, - PMF_NO_CACHE_MAINT); + plat_psci_stat_accounting_start(&state_info); #endif exit: diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h index 781b3b52..ca8291e4 100644 --- a/lib/psci/psci_private.h +++ b/lib/psci/psci_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -35,7 +35,6 @@ #include <bakery_lock.h> #include <bl_common.h> #include <cpu_data.h> -#include <pmf.h> #include <psci.h> #include <spinlock.h> @@ -106,15 +105,6 @@ #define is_cpu_standby_req(is_power_down_state, retn_lvl) \ (((!(is_power_down_state)) && ((retn_lvl) == 0)) ? 1 : 0) -/* Following are used as ID's to capture time-stamp */ -#define PSCI_STAT_ID_ENTER_LOW_PWR 0 -#define PSCI_STAT_ID_EXIT_LOW_PWR 1 -#define PSCI_STAT_TOTAL_IDS 2 - -/* Declare PMF service functions for PSCI */ -PMF_DECLARE_CAPTURE_TIMESTAMP(psci_svc) -PMF_DECLARE_GET_TIMESTAMP(psci_svc) - /******************************************************************************* * The following two data structures implement the power domain tree. The tree * is used to track the state of all the nodes i.e. power domain instances @@ -246,8 +236,7 @@ void __dead2 psci_system_reset(void); void psci_stats_update_pwr_down(unsigned int end_pwrlvl, const psci_power_state_t *state_info); void psci_stats_update_pwr_up(unsigned int end_pwrlvl, - const psci_power_state_t *state_info, - unsigned int flags); + const psci_power_state_t *state_info); u_register_t psci_stat_residency(u_register_t target_cpu, unsigned int power_state); u_register_t psci_stat_count(u_register_t target_cpu, diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c index ecbe592b..d8034a5d 100644 --- a/lib/psci/psci_stat.c +++ b/lib/psci/psci_stat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, 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: @@ -38,9 +38,6 @@ #define PLAT_MAX_PWR_LVL_STATES 2 #endif -/* Ticks elapsed in one second by a signal of 1 MHz */ -#define MHZ_TICKS_PER_SEC 1000000 - /* Following structure is used for PSCI STAT */ typedef struct psci_stat { u_register_t residency; @@ -62,27 +59,6 @@ static psci_stat_t psci_cpu_stat[PLATFORM_CORE_COUNT] static psci_stat_t psci_non_cpu_stat[PSCI_NUM_NON_CPU_PWR_DOMAINS] [PLAT_MAX_PWR_LVL_STATES]; -/* Register PMF PSCI service */ -PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, - PSCI_STAT_TOTAL_IDS, PMF_STORE_ENABLE) - -/* The divisor to use to convert raw timestamp into microseconds */ -u_register_t residency_div; - -/* - * This macro calculates the stats residency in microseconds, - * taking in account the wrap around condition. - */ -#define calc_stat_residency(_pwrupts, _pwrdnts, _res) \ - do { \ - if (_pwrupts < _pwrdnts) \ - _res = UINT64_MAX - _pwrdnts + _pwrupts;\ - else \ - _res = _pwrupts - _pwrdnts; \ - /* Convert timestamp into microseconds */ \ - _res = _res/residency_div; \ - } while (0) - /* * This functions returns the index into the `psci_stat_t` array given the * local power state and power domain level. If the platform implements the @@ -150,44 +126,23 @@ void psci_stats_update_pwr_down(unsigned int end_pwrlvl, * It is called with caches enabled and locks acquired(for NON-CPU domain) ******************************************************************************/ void psci_stats_update_pwr_up(unsigned int end_pwrlvl, - const psci_power_state_t *state_info, - unsigned int flags) + const psci_power_state_t *state_info) { int parent_idx, cpu_idx = plat_my_core_pos(); int lvl, stat_idx; plat_local_state_t local_state; - unsigned long long pwrup_ts = 0, pwrdn_ts = 0; u_register_t residency; assert(end_pwrlvl <= PLAT_MAX_PWR_LVL); assert(state_info); - /* Initialize the residency divisor if not already initialized */ - if (!residency_div) { - /* Pre-calculate divisor so that it can be directly used to - convert time-stamp into microseconds */ - residency_div = read_cntfrq_el0() / MHZ_TICKS_PER_SEC; - assert(residency_div); - } - - /* Get power down time-stamp for current CPU */ - PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, - cpu_idx, flags, pwrdn_ts); - - /* In the case of 1st power on just return */ - if (!pwrdn_ts) - return; - - /* Get power up time-stamp for current CPU */ - PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR, - cpu_idx, flags, pwrup_ts); - /* Get the index into the stats array */ local_state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL]; stat_idx = get_stat_idx(local_state, PSCI_CPU_PWR_LVL); - /* Calculate stats residency */ - calc_stat_residency(pwrup_ts, pwrdn_ts, residency); + /* Call into platform interface to calculate residency. */ + residency = plat_psci_stat_get_residency(PSCI_CPU_PWR_LVL, + state_info, cpu_idx); /* Update CPU stats. */ psci_cpu_stat[cpu_idx][stat_idx].residency += residency; @@ -207,10 +162,9 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl, assert(last_cpu_in_non_cpu_pd[parent_idx] != -1); - /* Get power down time-stamp for last CPU */ - PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, - last_cpu_in_non_cpu_pd[parent_idx], - flags, pwrdn_ts); + /* Call into platform interface to calculate residency. */ + residency = plat_psci_stat_get_residency(lvl, state_info, + last_cpu_in_non_cpu_pd[parent_idx]); /* Initialize back to reset value */ last_cpu_in_non_cpu_pd[parent_idx] = -1; @@ -218,9 +172,6 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl, /* Get the index into the stats array */ stat_idx = get_stat_idx(local_state, lvl); - /* Calculate stats residency */ - calc_stat_residency(pwrup_ts, pwrdn_ts, residency); - /* Update non cpu stats */ psci_non_cpu_stat[parent_idx][stat_idx].residency += residency; psci_non_cpu_stat[parent_idx][stat_idx].count++; diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c index dc2ab774..302116bd 100644 --- a/lib/psci/psci_suspend.c +++ b/lib/psci/psci_suspend.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -211,13 +211,7 @@ void psci_cpu_suspend_start(entry_point_info_t *ep, psci_plat_pm_ops->pwr_domain_suspend(state_info); #if ENABLE_PSCI_STAT - /* - * Capture time-stamp while entering low power state. - * No cache maintenance needed because caches are off - * and writes are direct to main memory. - */ - PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, - PMF_NO_CACHE_MAINT); + plat_psci_stat_accounting_start(state_info); #endif exit: @@ -257,6 +251,10 @@ exit: PMF_NO_CACHE_MAINT); #endif +#if ENABLE_PSCI_STAT + plat_psci_stat_accounting_start(state_info); +#endif + /* * We will reach here if only retention/standby states have been * requested at multiple power levels. This means that the cpu @@ -264,6 +262,11 @@ exit: */ wfi(); +#if ENABLE_PSCI_STAT + plat_psci_stat_accounting_stop(state_info); + psci_stats_update_pwr_up(end_pwrlvl, state_info); +#endif + #if ENABLE_RUNTIME_INSTRUMENTATION PMF_CAPTURE_TIMESTAMP(rt_instr_svc, RT_INSTR_EXIT_HW_LOW_PWR, diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index c2f28f98..4628a43d 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2017, 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: @@ -92,6 +92,7 @@ $(eval $(call add_define,ARM_BL31_IN_DRAM)) # Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms ENABLE_PSCI_STAT := 1 +ENABLE_PMF := 1 # On ARM platforms, separate the code and read-only data sections to allow # mapping the former as executable and the latter as execute-never. diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c index 3eb6886e..0e00faaf 100644 --- a/plat/common/plat_psci_common.c +++ b/plat/common/plat_psci_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, 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,8 +31,125 @@ #include <arch.h> #include <assert.h> #include <platform.h> +#include <pmf.h> #include <psci.h> +#if ENABLE_PSCI_STAT && ENABLE_PMF +#pragma weak plat_psci_stat_accounting_start +#pragma weak plat_psci_stat_accounting_stop +#pragma weak plat_psci_stat_get_residency + +/* Ticks elapsed in one second by a signal of 1 MHz */ +#define MHZ_TICKS_PER_SEC 1000000 + +/* Following are used as ID's to capture time-stamp */ +#define PSCI_STAT_ID_ENTER_LOW_PWR 0 +#define PSCI_STAT_ID_EXIT_LOW_PWR 1 +#define PSCI_STAT_TOTAL_IDS 2 + +PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, PSCI_STAT_TOTAL_IDS, + PMF_STORE_ENABLE) + +/* + * This function calculates the stats residency in microseconds, + * taking in account the wrap around condition. + */ +static u_register_t calc_stat_residency(unsigned long long pwrupts, + unsigned long long pwrdnts) +{ + /* The divisor to use to convert raw timestamp into microseconds. */ + u_register_t residency_div; + u_register_t res; + + /* + * Calculate divisor so that it can be directly used to + * convert time-stamp into microseconds. + */ + residency_div = read_cntfrq_el0() / MHZ_TICKS_PER_SEC; + assert(residency_div); + + if (pwrupts < pwrdnts) + res = UINT64_MAX - pwrdnts + pwrupts; + else + res = pwrupts - pwrdnts; + + return res / residency_div; +} + +/* + * Capture timestamp before entering a low power state. + * No cache maintenance is required when capturing the timestamp. + * Cache maintenance may be needed when reading these timestamps. + */ +void plat_psci_stat_accounting_start( + __unused const psci_power_state_t *state_info) +{ + assert(state_info); + PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR, + PMF_NO_CACHE_MAINT); +} + +/* + * Capture timestamp after exiting a low power state. + * No cache maintenance is required when capturing the timestamp. + * Cache maintenance may be needed when reading these timestamps. + */ +void plat_psci_stat_accounting_stop( + __unused const psci_power_state_t *state_info) +{ + assert(state_info); + PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR, + PMF_NO_CACHE_MAINT); +} + +/* + * Calculate the residency for the given level and power state + * information. + */ +u_register_t plat_psci_stat_get_residency(unsigned int lvl, + const psci_power_state_t *state_info, + int last_cpu_idx) +{ + plat_local_state_t state; + unsigned long long pwrup_ts = 0, pwrdn_ts = 0; + unsigned int pmf_flags; + + assert(lvl >= PSCI_CPU_PWR_LVL && lvl <= PLAT_MAX_PWR_LVL); + assert(state_info); + assert(last_cpu_idx >= 0 && last_cpu_idx <= PLATFORM_CORE_COUNT); + + if (lvl == PSCI_CPU_PWR_LVL) + assert(last_cpu_idx == plat_my_core_pos()); + + /* + * If power down is requested, then timestamp capture will + * be with caches OFF. Hence we have to do cache maintenance + * when reading the timestamp. + */ + state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL]; + if (is_local_state_off(state)) { + pmf_flags = PMF_CACHE_MAINT; + } else { + assert(is_local_state_retn(state)); + pmf_flags = PMF_NO_CACHE_MAINT; + } + + PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, + PSCI_STAT_ID_ENTER_LOW_PWR, + last_cpu_idx, + pmf_flags, + pwrdn_ts); + + PMF_GET_TIMESTAMP_BY_INDEX(psci_svc, + PSCI_STAT_ID_EXIT_LOW_PWR, + plat_my_core_pos(), + pmf_flags, + pwrup_ts); + + return calc_stat_residency(pwrup_ts, pwrdn_ts); +} +#endif /* ENABLE_PSCI_STAT && ENABLE_PMF */ + /* * The PSCI generic code uses this API to let the platform participate in state * coordination during a power management operation. It compares the platform diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h index f60997f0..433f72ce 100644 --- a/tools/cert_create/include/key.h +++ b/tools/cert_create/include/key.h @@ -73,6 +73,7 @@ typedef struct key_s { /* Exported API */ int key_init(void); key_t *key_get_by_opt(const char *opt); +int key_new(key_t *key); int key_create(key_t *key, int type); int key_load(key_t *key, unsigned int *err_code); int key_store(key_t *key); diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c index a559832e..375c66bf 100644 --- a/tools/cert_create/src/cert.c +++ b/tools/cert_create/src/cert.c @@ -103,10 +103,10 @@ int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) cert_t *issuer_cert = &certs[cert->issuer]; EVP_PKEY *ikey = keys[issuer_cert->key].key; X509 *issuer = issuer_cert->x; - X509 *x = NULL; - X509_EXTENSION *ex = NULL; - X509_NAME *name = NULL; - ASN1_INTEGER *sno = NULL; + X509 *x; + X509_EXTENSION *ex; + X509_NAME *name; + ASN1_INTEGER *sno; int i, num; /* Create the certificate structure */ @@ -202,7 +202,7 @@ int cert_init(void) cert_t *cert_get_by_opt(const char *opt) { - cert_t *cert = NULL; + cert_t *cert; unsigned int i; for (i = 0; i < num_certs; i++) { diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c index 3f56edb7..a50919ee 100644 --- a/tools/cert_create/src/ext.c +++ b/tools/cert_create/src/ext.c @@ -181,13 +181,13 @@ X509_EXTENSION *ext_new(int nid, int crit, unsigned char *data, int len) X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md, unsigned char *buf, size_t len) { - X509_EXTENSION *ex = NULL; - ASN1_OCTET_STRING *octet = NULL; - HASH *hash = NULL; - ASN1_OBJECT *algorithm = NULL; - X509_ALGOR *x509_algor = NULL; + X509_EXTENSION *ex; + ASN1_OCTET_STRING *octet; + HASH *hash; + ASN1_OBJECT *algorithm; + X509_ALGOR *x509_algor; unsigned char *p = NULL; - int sz = -1; + int sz; /* OBJECT_IDENTIFIER with hash algorithm */ algorithm = OBJ_nid2obj(md->type); @@ -254,16 +254,15 @@ X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md, */ X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value) { - X509_EXTENSION *ex = NULL; - ASN1_INTEGER *counter = NULL; + X509_EXTENSION *ex; + ASN1_INTEGER *counter; unsigned char *p = NULL; - int sz = -1; + int sz; /* Encode counter */ counter = ASN1_INTEGER_new(); ASN1_INTEGER_set(counter, value); - sz = i2d_ASN1_INTEGER(counter, NULL); - i2d_ASN1_INTEGER(counter, &p); + sz = i2d_ASN1_INTEGER(counter, &p); /* Create the extension */ ex = ext_new(nid, crit, p, sz); @@ -292,9 +291,9 @@ X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value) */ X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k) { - X509_EXTENSION *ex = NULL; - unsigned char *p = NULL; - int sz = -1; + X509_EXTENSION *ex; + unsigned char *p; + int sz; /* Encode key */ BIO *mem = BIO_new(BIO_s_mem()); @@ -316,7 +315,7 @@ X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k) ext_t *ext_get_by_opt(const char *opt) { - ext_t *ext = NULL; + ext_t *ext; unsigned int i; /* Sequential search. This is not a performance concern since the number diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c index a7ee7596..ce0e4da6 100644 --- a/tools/cert_create/src/key.c +++ b/tools/cert_create/src/key.c @@ -49,7 +49,7 @@ /* * Create a new key container */ -static int key_new(key_t *key) +int key_new(key_t *key) { /* Create key pair container */ key->key = EVP_PKEY_new(); @@ -62,7 +62,7 @@ static int key_new(key_t *key) static int key_create_rsa(key_t *key) { - RSA *rsa = NULL; + RSA *rsa; rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL); if (rsa == NULL) { @@ -83,7 +83,7 @@ err: #ifndef OPENSSL_NO_EC static int key_create_ecdsa(key_t *key) { - EC_KEY *ec = NULL; + EC_KEY *ec; ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (ec == NULL) { @@ -123,11 +123,6 @@ int key_create(key_t *key, int type) return 0; } - /* Create OpenSSL key container */ - if (!key_new(key)) { - return 0; - } - if (key_create_fn[type]) { return key_create_fn[type](key); } @@ -137,14 +132,8 @@ int key_create(key_t *key, int type) int key_load(key_t *key, unsigned int *err_code) { - FILE *fp = NULL; - EVP_PKEY *k = NULL; - - /* Create OpenSSL key container */ - if (!key_new(key)) { - *err_code = KEY_ERR_MALLOC; - return 0; - } + FILE *fp; + EVP_PKEY *k; if (key->fn) { /* Load key from file */ @@ -173,7 +162,7 @@ int key_load(key_t *key, unsigned int *err_code) int key_store(key_t *key) { - FILE *fp = NULL; + FILE *fp; if (key->fn) { fp = fopen(key->fn, "w"); @@ -196,7 +185,6 @@ int key_init(void) { cmd_opt_t cmd_opt; key_t *key; - int rc = 0; unsigned int i; for (i = 0; i < num_keys; i++) { @@ -211,12 +199,12 @@ int key_init(void) } } - return rc; + return 0; } key_t *key_get_by_opt(const char *opt) { - key_t *key = NULL; + key_t *key; unsigned int i; /* Sequential search. This is not a performance concern since the number diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index c58f41de..c9c96222 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -134,7 +134,6 @@ static void print_help(const char *cmd, const struct option *long_opt) printf("\t%s [OPTIONS]\n\n", cmd); printf("Available options:\n"); - i = 0; opt = long_opt; while (opt->name) { p = line; @@ -261,12 +260,12 @@ static const cmd_opt_t common_cmd_opt[] = { int main(int argc, char *argv[]) { - STACK_OF(X509_EXTENSION) * sk = NULL; - X509_EXTENSION *cert_ext = NULL; - ext_t *ext = NULL; - key_t *key = NULL; - cert_t *cert = NULL; - FILE *file = NULL; + STACK_OF(X509_EXTENSION) * sk; + X509_EXTENSION *cert_ext; + ext_t *ext; + key_t *key; + cert_t *cert; + FILE *file; int i, j, ext_nid, nvctr; int c, opt_idx = 0; const struct option *cmd_opt; @@ -367,6 +366,11 @@ int main(int argc, char *argv[]) /* Load private keys from files (or generate new ones) */ for (i = 0 ; i < num_keys ; i++) { + if (!key_new(&keys[i])) { + ERROR("Failed to allocate key container\n"); + exit(1); + } + /* First try to load the key from disk */ if (key_load(&keys[i], &err_code)) { /* Key loaded successfully */ @@ -374,11 +378,7 @@ int main(int argc, char *argv[]) } /* Key not loaded. Check the error code */ - if (err_code == KEY_ERR_MALLOC) { - /* Cannot allocate memory. Abort. */ - ERROR("Malloc error while loading '%s'\n", keys[i].fn); - exit(1); - } else if (err_code == KEY_ERR_LOAD) { + if (err_code == KEY_ERR_LOAD) { /* File exists, but it does not contain a valid private * key. Abort. */ ERROR("Error loading '%s'\n", keys[i].fn); diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c index 865aeae1..f3f831bd 100644 --- a/tools/fiptool/fiptool.c +++ b/tools/fiptool/fiptool.c @@ -52,8 +52,6 @@ #define OPT_PLAT_TOC_FLAGS 1 #define OPT_ALIGN 2 -static image_desc_t *lookup_image_desc_from_uuid(const uuid_t *uuid); -static image_t *lookup_image_from_uuid(const uuid_t *uuid); static int info_cmd(int argc, char *argv[]); static void info_usage(void); static int create_cmd(int argc, char *argv[]); @@ -822,11 +820,9 @@ static void create_usage(void) printf("\n"); printf("Options:\n"); printf(" --align <value>\t\tEach image is aligned to <value> (default: 1).\n"); - printf(" --blob uuid=...,file=...\tAdd an image with the given UUID " - "pointed to by file.\n"); - printf(" --plat-toc-flags <value>\t16-bit platform specific flag field " - "occupying bits 32-47 in 64-bit ToC header.\n"); - fputc('\n', stderr); + printf(" --blob uuid=...,file=...\tAdd an image with the given UUID pointed to by file.\n"); + printf(" --plat-toc-flags <value>\t16-bit platform specific flag field occupying bits 32-47 in 64-bit ToC header.\n"); + printf("\n"); printf("Specific images are packed with the following options:\n"); for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s FILENAME\t%s\n", toc_entry->cmdline_name, @@ -938,12 +934,10 @@ static void update_usage(void) printf("\n"); printf("Options:\n"); printf(" --align <value>\t\tEach image is aligned to <value> (default: 1).\n"); - printf(" --blob uuid=...,file=...\tAdd or update an image " - "with the given UUID pointed to by file.\n"); + printf(" --blob uuid=...,file=...\tAdd or update an image with the given UUID pointed to by file.\n"); printf(" --out FIP_FILENAME\t\tSet an alternative output FIP file.\n"); - printf(" --plat-toc-flags <value>\t16-bit platform specific flag field " - "occupying bits 32-47 in 64-bit ToC header.\n"); - fputc('\n', stderr); + printf(" --plat-toc-flags <value>\t16-bit platform specific flag field occupying bits 32-47 in 64-bit ToC header.\n"); + printf("\n"); printf("Specific images are packed with the following options:\n"); for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s FILENAME\t%s\n", toc_entry->cmdline_name, @@ -1076,17 +1070,15 @@ static void unpack_usage(void) printf("fiptool unpack [opts] FIP_FILENAME\n"); printf("\n"); printf("Options:\n"); - printf(" --blob uuid=...,file=...\tUnpack an image with the given UUID " - "to file.\n"); - printf(" --force\t\t\tIf the output file already exists, use --force to " - "overwrite it.\n"); + printf(" --blob uuid=...,file=...\tUnpack an image with the given UUID to file.\n"); + printf(" --force\t\t\tIf the output file already exists, use --force to overwrite it.\n"); printf(" --out path\t\t\tSet the output directory path.\n"); - fputc('\n', stderr); + printf("\n"); printf("Specific images are unpacked with the following options:\n"); for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s FILENAME\t%s\n", toc_entry->cmdline_name, toc_entry->name); - fputc('\n', stderr); + printf("\n"); printf("If no options are provided, all images will be unpacked.\n"); exit(1); } @@ -1207,10 +1199,9 @@ static void remove_usage(void) printf("Options:\n"); printf(" --align <value>\tEach image is aligned to <value> (default: 1).\n"); printf(" --blob uuid=...\tRemove an image with the given UUID.\n"); - printf(" --force\t\tIf the output FIP file already exists, use --force to " - "overwrite it.\n"); + printf(" --force\t\tIf the output FIP file already exists, use --force to overwrite it.\n"); printf(" --out FIP_FILENAME\tSet an alternative output FIP file.\n"); - fputc('\n', stderr); + printf("\n"); printf("Specific images are removed with the following options:\n"); for (; toc_entry->cmdline_name != NULL; toc_entry++) printf(" --%-16s\t%s\n", toc_entry->cmdline_name, @@ -1258,7 +1249,7 @@ static void usage(void) printf("usage: fiptool [--verbose] <command> [<args>]\n"); printf("Global options supported:\n"); printf(" --verbose\tEnable verbose output for all commands.\n"); - fputc('\n', stderr); + printf("\n"); printf("Commands supported:\n"); printf(" info\t\tList images contained in FIP.\n"); printf(" create\tCreate a new FIP with the given images.\n"); |