Commit graph

21 commits

Author SHA1 Message Date
Boyan Karatotev
db5fe4f493 chore(docs): drop the "wfi" from pwr_domain_pwr_down_wfi
To allow for generic handling of a wakeup, this hook is no longer
expected to call wfi itself. Update the name everywhere to reflect this
expectation so that future platform implementers don't get misled.

Change-Id: Ic33f0b6da74592ad6778fd802c2f0b85223af614
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
2025-02-03 14:29:47 +00:00
Boyan Karatotev
45c7328c0b fix(cpus): avoid SME related loss of context on powerdown
Travis' and Gelas' TRMs tell us to disable SME (set PSTATE.{ZA, SM} to
0) when we're attempting to power down. What they don't tell us is that
if this isn't done, the powerdown request will be rejected. On the
CPU_OFF path that's not a problem - we can force SVCR to 0 and be
certain the core will power off.

On the suspend to powerdown path, however, we cannot do this. The TRM
also tells us that the sequence could also be aborted on eg. GIC
interrupts. If this were to happen when we have overwritten SVCR to 0,
upon a return to the caller they would experience a loss of context. We
know that at least Linux may call into PSCI with SVCR != 0. One option
is to save the entire SME context which would be quite expensive just to
work around. Another option is to downgrade the request to a normal
suspend when SME was left on. This option is better as this is expected
to happen rarely enough to ignore the wasted power and we don't want to
burden the generic (correct) path with needless context management.

Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
Change-Id: I698fa8490ebf51461f6aa8bba84f9827c5c46ad4
2025-02-03 14:29:47 +00:00
Boyan Karatotev
2b5e00d4ea feat(psci): allow cores to wake up from powerdown
The simplistic view of a core's powerdown sequence is that power is
atomically cut upon calling `wfi`. However, it turns out that it has
lots to do - it has to talk to the interconnect to exit coherency, clean
caches, check for RAS errors, etc. These take significant amounts of
time and are certainly not atomic. As such there is a significant window
of opportunity for external events to happen. Many of these steps are
not destructive to context, so theoretically, the core can just "give
up" half way (or roll certain actions back) and carry on running. The
point in this sequence after which roll back is not possible is called
the point of no return.

One of these actions is the checking for RAS errors. It is possible for
one to happen during this lengthy sequence, or at least remain
undiscovered until that point. If the core were to continue powerdown
when that happens, there would be no (easy) way to inform anyone about
it. Rejecting the powerdown and letting software handle the error is the
best way to implement this.

Arm cores since at least the a510 have included this exact feature. So
far it hasn't been deemed necessary to account for it in firmware due to
the low likelihood of this happening. However, events like GIC wakeup
requests are much more probable. Older cores will powerdown and
immediately power back up when this happens. Travis and Gelas include a
feature similar to the RAS case above, called powerdown abandon. The
idea is that this will improve the latency to service the interrupt by
saving on work which the core and software need to do.

So far firmware has relied on the `wfi` being the point of no return and
if it doesn't explicitly detect a pending interrupt quite early on, it
will embark onto a sequence that it expects to end with shutdown. To
accommodate for it not being a point of no return, we must undo all of
the system management we did, just like in the warm boot entrypoint.

To achieve that, the pwr_domain_pwr_down_wfi hook must not be terminal.
Most recent platforms do some platform management and finish on the
standard `wfi`, followed by a panic or an endless loop as this is
expected to not return. To make this generic, any platform that wishes
to support wakeups must instead let common code call
`psci_power_down_wfi()` right after. Besides wakeups, this lets common
code handle powerdown errata better as well.

Then, the CPU_OFF case is simple - PSCI does not allow it to return. So
the best that can be done is to attempt the `wfi` a few times (the
choice of 32 is arbitrary) in the hope that the wakeup is transient. If
it isn't, the only choice is to panic, as the system is likely to be in
a bad state, eg. interrupts weren't routed away. The same applies for
SYSTEM_OFF, SYSTEM_RESET, and SYSTEM_RESET2. There the panic won't
matter as the system is going offline one way or another. The RAS case
will be considered in a separate patch.

Now, the CPU_SUSPEND case is more involved. First, to powerdown it must
wipe its context as it is not written on warm boot. But it cannot be
overwritten in case of a wakeup. To avoid the catch 22, save a copy that
will only be used if powerdown fails. That is about 500 bytes on the
stack so it hopefully doesn't tip anyone over any limits. In future that
can be avoided by having a core manage its own context.

Second, when the core wakes up, it must undo anything it did to prepare
for poweroff, which for the cores we care about, is writing
CPUPWRCTLR_EL1.CORE_PWRDN_EN. The least intrusive for the cpu library
way of doing this is to simply call the power off hook again and have
the hook toggle the bit. If in the future there need to be more complex
sequences, their direction can be advised on the value of this bit.

Third, do the actual "resume". Most of the logic is already there for
the retention suspend, so that only needs a small touch up to apply to
the powerdown case as well. The missing bit is the powerdown specific
state management. Luckily, the warmboot entrypoint does exactly that
already too, so steal that and we're done.

All of this is hidden behind a FEAT_PABANDON flag since it has a large
memory and runtime cost that we don't want to burden non pabandon cores
with.

Finally, do some function renaming to better reflect their purpose and
make names a little bit more consistent.

Change-Id: I2405b59300c2e24ce02e266f91b7c51474c1145f
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
2025-02-03 14:29:47 +00:00
Boyan Karatotev
3b8021058a perf(psci): pass my_core_pos around instead of calling it repeatedly
On some platforms plat_my_core_pos is a nontrivial function that takes a
bit of time and the compiler really doesn't like to inline. In the PSCI
library, at least, we have no need to keep repeatedly calling it and we
can instead pass it around as an argument. This saves on a lot of
redundant calls, speeding the library up a bit.

Change-Id: I137f69bea80d7cac90d7a20ffe98e1ba8d77246f
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
2025-01-14 10:02:00 +00:00
Boyan Karatotev
9b1e800ef0 refactor(psci): move timestamp collection to psci_pwrdown_cpu
psci_pwrdown_cpu has two callers, both of which save timestamps meant to
measure how much time the cache maintenance operations take. Move the
timestamp collection inside to save on a bit of code duplication.

Change-Id: Ia2e7168faf7773d99b696cbdb6c98db7b58e31cf
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
2025-01-14 10:01:37 +00:00
Wing Li
d34886140c fix(psci): add optional pwr_domain_validate_suspend to plat_psci_ops_t
This patch adds a new optional member `pwr_domain_validate_suspend` to
the `plat_psci_ops_t` structure that allows a platform to optionally
perform platform specific validations in OS-initiated mode. This is
conditionally compiled into the build depending on the value of the
`PSCI_OS_INIT_MODE` build option.

In https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/17682,
the return type of the `pwr_domain_suspend` handler was updated from
`void` to `int` to allow a platform to optionally perform platform
specific validations in OS-initiated mode. However, when an error code
other than `PSCI_E_SUCCESS` is returned, the current exit path does not
undo the operations in `psci_suspend_to_pwrdown_start`, and as a result,
the system ends up in an unexpected state.

The fix in this patch prevents the need to undo the operations in
`psci_suspend_to_pwrdown_start`, by allowing the platform to first
perform any necessary platform specific validations before the PSCI
generic code proceeds to the point of no return where the CPU_SUSPEND
request is expected to complete successfully.

Change-Id: I05d92c7ea3f5364da09af630d44d78252185db20
Signed-off-by: Wing Li <wingers@google.com>
2023-05-31 23:54:19 -07:00
Varun Wadekar
6cf4ae979a feat(psci): introduce 'pwr_domain_off_early' hook
This patch introduces the 'pwr_domain_off_early'  hook for
platforms wanting to perform housekeeping steps before the
PSCI framework starts the CPU power off sequence. Platforms
might also want to use ths opportunity to ensure that the
CPU off sequence can proceed.

The PSCI framework expects a return code of PSCI_E_DENIED,
if the platform wants to halt the CPU off sequence.

Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Change-Id: I6980e84fc4d6cb80537a178d0d3d26fb28a13853
2023-04-26 09:53:10 +01:00
Pranav Madhu
65bbb9358b refactor(psci): move psci_do_pwrdown_sequence() out of private header
Move the psci_do_pwrdown_sequence() function declaration from PSCI
private header to common header. The psci_do_pwrdown_sequence is
required to support warm reset, where each CPU need to execute the
powerdown sequence.

Change-Id: I298e7a120be814941fa91c0b001002a080e56263
Signed-off-by: Pranav Madhu <pranav.madhu@arm.com>
2022-09-15 18:09:56 +05:30
Deepika Bhavnani
5b33ad174a Unify type of "cpu_idx" across PSCI module.
NOTE for platform integrators:
   API `plat_psci_stat_get_residency()` third argument
   `last_cpu_idx` is changed from "signed int" to the
   "unsigned int" type.

Issue / Trouble points
1. cpu_idx is used as mix of `unsigned int` and `signed int` in code
with typecasting at some places leading to coverity issues.

2. Underlying platform API's return cpu_idx as `unsigned int`
and comparison is performed with platform specific defines
`PLAFORM_xxx` which is not consistent

Misra Rule 10.4:
The value of a complex expression of integer type may only be cast to
a type that is narrower and of the same signedness as the underlying
type of the expression.

Based on above points, cpu_idx is kept as `unsigned int` to match
the API's and low-level functions and platform defines are updated
where ever required

Signed-off-by: Deepika Bhavnani <deepika.bhavnani@arm.com>
Change-Id: Ib26fd16e420c35527204b126b9b91e8babcc3a5c
2020-01-10 17:11:51 +00:00
Andrew F. Davis
74d27d0062 PSCI: Lookup list of parent nodes to lock only once
When acquiring or releasing the power domain locks for a given CPU the
parent nodes are looked up by walking the up the PD tree list on both the
acquire and release path, only one set of lookups is needed. Fetch the
parent nodes first and pass this list into both the acquire and release
functions to avoid the double lookup.

This also allows us to not have to do this lookup after coherency has
been exited during the core power down sequence. The shared struct
psci_cpu_pd_nodes is not placed in coherent memory like is done
for psci_non_cpu_pd_nodes and doing so would negatively affect
performance. With this patch we remove the need to have it in coherent
memory by moving the access out of psci_release_pwr_domain_locks().

Signed-off-by: Andrew F. Davis <afd@ti.com>
Change-Id: I7b9cfa9d31148dea0f5e21091c8b45ef7fe4c4ab
2019-06-06 11:31:47 -04:00
Antonio Nino Diaz
09d40e0e08 Sanitise includes across codebase
Enforce full include path for includes. Deprecate old paths.

The following folders inside include/lib have been left unchanged:

- include/lib/cpus/${ARCH}
- include/lib/el3_runtime/${ARCH}

The reason for this change is that having a global namespace for
includes isn't a good idea. It defeats one of the advantages of having
folders and it introduces problems that are sometimes subtle (because
you may not know the header you are actually including if there are two
of them).

For example, this patch had to be created because two headers were
called the same way: e0ea0928d5 ("Fix gpio includes of mt8173 platform
to avoid collision."). More recently, this patch has had similar
problems: 46f9b2c3a2 ("drivers: add tzc380 support").

This problem was introduced in commit 4ecca33988 ("Move include and
source files to logical locations"). At that time, there weren't too
many headers so it wasn't a real issue. However, time has shown that
this creates problems.

Platforms that want to preserve the way they include headers may add the
removed paths to PLAT_INCLUDES, but this is discouraged.

Change-Id: I39dc53ed98f9e297a5966e723d1936d6ccf2fc8f
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
2019-01-04 10:43:17 +00:00
Antonio Nino Diaz
621d64f89b PSCI: Fix MISRA defects in ON/OFF/SUSPEND/SYSTEM_OFF
Fix violations of MISRA C-2012 Rules 8.13, 10.1, 10.3, 17.7 and 20.7.

Change-Id: I6f45a1069b742aebf9e1d6a403717b1522083f51
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
2018-07-24 09:19:04 +01:00
Roberto Vargas
216e58a312 Reduce time lock in psci_do_cpu_off
psci_set_power_off_state only initializes a local variable, so there
isn't any reason why it should be done while the lock is held.

Change-Id: I1c62f4cd5d860d102532e5a5350152180d41d127
Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
2017-09-06 14:48:15 +01:00
Varun Wadekar
6311f63de0 Tegra: enable 'signed-comparison' compilation warning/errors
This patch enables the 'sign-compare' flag, to enable warning/errors
for comparisons between signed/unsigned variables. The warning has
been enabled for all the Tegra platforms, to start with.

Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
2017-06-14 14:59:07 -07:00
dp-arm
82cb2c1ad9 Use SPDX license identifiers
To make software license auditing simpler, use SPDX[0] license
identifiers instead of duplicating the license text in every file.

NOTE: Files that have been imported by FreeBSD have not been modified.

[0]: https://spdx.org/

Change-Id: I80a00e1f641b8cc075ca5a95b10607ed9ed8761a
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
2017-05-03 09:39:28 +01:00
Jeenu Viswambharan
b0408e87f7 PSCI: Optimize call paths if all participants are cache-coherent
The current PSCI implementation can apply certain optimizations upon the
assumption that all PSCI participants are cache-coherent.

  - Skip performing cache maintenance during power-up.

  - Skip performing cache maintenance during power-down:

    At present, on the power-down path, CPU driver disables caches and
    MMU, and performs cache maintenance in preparation for powering down
    the CPU. This means that PSCI must perform additional cache
    maintenance on the extant stack for correct functioning.

    If all participating CPUs are cache-coherent, CPU driver would
    neither disable MMU nor perform cache maintenance. The CPU being
    powered down, therefore, remain cache-coherent throughout all PSCI
    call paths. This in turn means that PSCI cache maintenance
    operations are not required during power down.

  - Choose spin locks instead of bakery locks:

    The current PSCI implementation must synchronize both cache-coherent
    and non-cache-coherent participants. Mutual exclusion primitives are
    not guaranteed to function on non-coherent memory. For this reason,
    the current PSCI implementation had to resort to bakery locks.

    If all participants are cache-coherent, the implementation can
    enable MMU and data caches early, and substitute bakery locks for
    spin locks. Spin locks make use of architectural mutual exclusion
    primitives, and are lighter and faster.

The optimizations are applied when HW_ASSISTED_COHERENCY build option is
enabled, as it's expected that all PSCI participants are cache-coherent
in those systems.

Change-Id: Iac51c3ed318ea7e2120f6b6a46fd2db2eae46ede
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
2017-03-02 11:00:20 +00:00
Jeenu Viswambharan
a10d3632ac PSCI: Introduce cache and barrier wrappers
The PSCI implementation performs cache maintenance operations on its
data structures to ensure their visibility to both cache-coherent and
non-cache-coherent participants. These cache maintenance operations
can be skipped if all PSCI participants are cache-coherent. When
HW_ASSISTED_COHERENCY build option is enabled, we assume PSCI
participants are cache-coherent.

For usage abstraction, this patch introduces wrappers for PSCI cache
maintenance and barrier operations used for state coordination: they are
effectively NOPs when HW_ASSISTED_COHERENCY is enabled, but are
applied otherwise.

Also refactor local state usage and associated cache operations to make
it clearer.

Change-Id: I77f17a90cba41085b7188c1345fe5731c99fad87
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
2017-03-02 11:00:20 +00:00
dp-arm
04c1db1e57 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>
2017-02-13 14:33:06 +00:00
dp-arm
7941816a34 Add two timestamps to measure PSCI cache flush overhead
Testing showed that the time spent in a cluster power down
operation is dominated by cache flushes.  Add two more timestamps
in runtime instrumentation to keep track of the time spent
flushing the L1/L2 caches.

Change-Id: I4c5a04e7663543225a85d3c6b271d7b706deffc4
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
2016-12-14 09:53:14 +00:00
dp-arm
872be88a29 Add PMF instrumentation points in TF
In order to quantify the overall time spent in the PSCI software
implementation, an initial collection of PMF instrumentation points
has been added.

Instrumentation has been added to the following code paths:

- Entry to PSCI SMC handler.  The timestamp is captured as early
  as possible during the runtime exception and stored in memory
  before entering the PSCI SMC handler.

- Exit from PSCI SMC handler.  The timestamp is captured after
  normal return from the PSCI SMC handler or if a low power state
  was requested it is captured in the bl31 warm boot path before
  return to normal world.

- Entry to low power state.  The timestamp is captured before entry
  to a low power state which implies either standby or power down.
  As these power states are mutually exclusive, only one timestamp
  is defined to describe both.  It is possible to differentiate between
  the two power states using the PSCI STAT interface.

- Exit from low power state.  The timestamp is captured after a standby
  or power up operation has completed.

To calculate the number of cycles spent running code in Trusted Firmware
one can perform the following calculation:

(exit_psci - enter_psci) - (exit_low_pwr - enter_low_pwr).

The resulting number of cycles can be converted to time given the
frequency of the counter.

Change-Id: Ie3b8f3d16409b6703747093b3a2d5c7429ad0166
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
2016-10-12 15:36:49 +01:00
Soby Mathew
532ed61838 Introduce el3_runtime and PSCI libraries
This patch moves the PSCI services and BL31 frameworks like context
management and per-cpu data into new library components `PSCI` and
`el3_runtime` respectively. This enables PSCI to be built independently from
BL31. A new `psci_lib.mk` makefile is introduced which adds the relevant
PSCI library sources and gets included by `bl31.mk`. Other changes which
are done as part of this patch are:

* The runtime services framework is now moved to the `common/` folder to
  enable reuse.
* The `asm_macros.S` and `assert_macros.S` helpers are moved to architecture
  specific folder.
* The `plat_psci_common.c` is moved from the `plat/common/aarch64/` folder
  to `plat/common` folder. The original file location now has a stub which
  just includes the file from new location to maintain platform compatibility.

Most of the changes wouldn't affect platform builds as they just involve
changes to the generic bl1.mk and bl31.mk makefiles.

NOTE: THE `plat_psci_common.c` FILE HAS MOVED LOCATION AND THE STUB FILE AT
THE ORIGINAL LOCATION IS NOW DEPRECATED. PLATFORMS SHOULD MODIFY THEIR
MAKEFILES TO INCLUDE THE FILE FROM THE NEW LOCATION.

Change-Id: I6bd87d5b59424995c6a65ef8076d4fda91ad5e86
2016-07-18 17:52:15 +01:00
Renamed from services/std_svc/psci/psci_off.c (Browse further)