diff options
author | dp-arm <dimitris.papastamos@arm.com> | 2017-01-31 13:01:04 +0000 |
---|---|---|
committer | dp-arm <dimitris.papastamos@arm.com> | 2017-02-13 14:33:06 +0000 |
commit | 04c1db1e574604081bfdcec3d26e662535812eaa (patch) | |
tree | cf2764a5c729dd413c74f5d1abf5ea306957ea8e /lib/psci | |
parent | bab16f9912c6a2ea7600e8d713c1eebf8f0c11d7 (diff) | |
download | arm-trusted-firmware-04c1db1e574604081bfdcec3d26e662535812eaa.tar.gz |
PSCI: Decouple PSCI stat residency calculation from PMF
This patch introduces the following three platform interfaces:
* void plat_psci_stat_accounting_start(const psci_power_state_t *state_info)
This is an optional hook that platforms can implement in order
to perform accounting before entering a low power state. This
typically involves capturing a timestamp.
* void plat_psci_stat_accounting_stop(const psci_power_state_t *state_info)
This is an optional hook that platforms can implement in order
to perform accounting after exiting from a low power state. This
typically involves capturing a timestamp.
* u_register_t plat_psci_stat_get_residency(unsigned int lvl,
const psci_power_state_t *state_info,
unsigned int last_cpu_index)
This is an optional hook that platforms can implement in order
to calculate the PSCI stat residency.
If any of these interfaces are overridden by the platform, it is
recommended that all of them are.
By default `ENABLE_PSCI_STAT` is disabled. If `ENABLE_PSCI_STAT`
is set but `ENABLE_PMF` is not set then an alternative PSCI stat
collection backend must be provided. If both are set, then default
weak definitions of these functions are provided, using PMF to
calculate the residency.
NOTE: Previously, platforms did not have to explicitly set
`ENABLE_PMF` since this was automatically done by the top-level
Makefile.
Change-Id: I17b47804dea68c77bc284df15ee1ccd66bc4b79b
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
Diffstat (limited to 'lib/psci')
-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 | 10 |
6 files changed, 21 insertions, 108 deletions
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index 68cdd6eb1..822329e65 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 0a3a60ace..5e166b52d 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 897bf319a..394aaa3b1 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 781b3b526..ca8291e48 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 ecbe592b8..d8034a5d7 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 dc2ab7748..5c8c3e26a 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: |