Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 1 | PSCI Library Integration guide for Armv8-A AArch32 systems |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 2 | ========================================================== |
| 3 | |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 4 | This document describes the PSCI library interface with a focus on how to |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 5 | integrate with a suitable Trusted OS for an Armv8-A AArch32 system. The PSCI |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 6 | Library implements the PSCI Standard as described in `PSCI`_ and is meant |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 7 | to be integrated with EL3 Runtime Software which invokes the PSCI Library |
| 8 | interface appropriately. **EL3 Runtime Software** refers to software executing |
| 9 | at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/ |
| 10 | Monitor mode in AArch32, and provides runtime services to the non-secure world. |
| 11 | The runtime service request is made via SMC (Secure Monitor Call) and the call |
| 12 | must adhere to `SMCCC`_. In AArch32, EL3 Runtime Software may additionally |
| 13 | include Trusted OS functionality. A minimal AArch32 Secure Payload, SP-MIN, is |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 14 | provided in Trusted Firmware-A (TF-A) to illustrate the usage and integration |
| 15 | of the PSCI library. The description of PSCI library interface and its |
| 16 | integration with EL3 Runtime Software in this document is targeted towards |
| 17 | AArch32 systems. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 18 | |
| 19 | Generic call sequence for PSCI Library interface (AArch32) |
| 20 | ---------------------------------------------------------- |
| 21 | |
| 22 | The generic call sequence of PSCI Library interfaces (see |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 23 | `PSCI Library Interface`_) during cold boot in AArch32 |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 24 | system is described below: |
| 25 | |
| 26 | #. After cold reset, the EL3 Runtime Software performs its cold boot |
| 27 | initialization including the PSCI library pre-requisites mentioned in |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 28 | `PSCI Library Interface`_, and also the necessary platform |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 29 | setup. |
| 30 | |
| 31 | #. Call ``psci_setup()`` in Monitor mode. |
| 32 | |
| 33 | #. Optionally call ``psci_register_spd_pm_hook()`` to register callbacks to |
| 34 | do bookkeeping for the EL3 Runtime Software during power management. |
| 35 | |
| 36 | #. Call ``psci_prepare_next_non_secure_ctx()`` to initialize the non-secure CPU |
| 37 | context. |
| 38 | |
| 39 | #. Get the non-secure ``cpu_context_t`` for the current CPU by calling |
| 40 | ``cm_get_context()`` , then programming the registers in the non-secure |
| 41 | context and exiting to non-secure world. If the EL3 Runtime Software needs |
| 42 | additional configuration to be set for non-secure context, like routing |
| 43 | FIQs to the secure world, the values of the registers can be modified prior |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 44 | to programming. See `PSCI CPU context management`_ for more |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 45 | details on CPU context management. |
| 46 | |
| 47 | The generic call sequence of PSCI library interfaces during warm boot in |
| 48 | AArch32 systems is described below: |
| 49 | |
| 50 | #. After warm reset, the EL3 Runtime Software performs the necessary warm |
| 51 | boot initialization including the PSCI library pre-requisites mentioned in |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 52 | `PSCI Library Interface`_ (Note that the Data cache |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 53 | **must not** be enabled). |
| 54 | |
| 55 | #. Call ``psci_warmboot_entrypoint()`` in Monitor mode. This interface |
| 56 | initializes/restores the non-secure CPU context as well. |
| 57 | |
| 58 | #. Do step 5 of the cold boot call sequence described above. |
| 59 | |
| 60 | The generic call sequence of PSCI library interfaces on receipt of a PSCI SMC |
| 61 | on an AArch32 system is described below: |
| 62 | |
| 63 | #. On receipt of an SMC, save the register context as per `SMCCC`_. |
| 64 | |
| 65 | #. If the SMC function identifier corresponds to a SMC32 PSCI API, construct |
| 66 | the appropriate arguments and call the ``psci_smc_handler()`` interface. |
| 67 | The invocation may or may not return back to the caller depending on |
| 68 | whether the PSCI API resulted in power down of the CPU. |
| 69 | |
| 70 | #. If ``psci_smc_handler()`` returns, populate the return value in R0 (AArch32)/ |
| 71 | X0 (AArch64) and restore other registers as per `SMCCC`_. |
| 72 | |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 73 | PSCI CPU context management |
| 74 | --------------------------- |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 75 | |
| 76 | PSCI library is in charge of initializing/restoring the non-secure CPU system |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 77 | registers according to `PSCI`_ during cold/warm boot. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 78 | This is referred to as ``PSCI CPU Context Management``. Registers that need to |
| 79 | be preserved across CPU power down/power up cycles are maintained in |
| 80 | ``cpu_context_t`` data structure. The initialization of other non-secure CPU |
| 81 | system registers which do not require coordination with the EL3 Runtime |
| 82 | Software is done directly by the PSCI library (see ``cm_prepare_el3_exit()``). |
| 83 | |
| 84 | The EL3 Runtime Software is responsible for managing register context |
| 85 | during switch between Normal and Secure worlds. The register context to be |
| 86 | saved and restored depends on the mechanism used to trigger the world switch. |
| 87 | For example, if the world switch was triggered by an SMC call, then the |
| 88 | registers need to be saved and restored according to `SMCCC`_. In AArch64, |
| 89 | due to the tight integration with BL31, both BL31 and PSCI library |
| 90 | use the same ``cpu_context_t`` data structure for PSCI CPU context management |
| 91 | and register context management during world switch. This cannot be assumed |
| 92 | for AArch32 EL3 Runtime Software since most AArch32 Trusted OSes already implement |
| 93 | a mechanism for register context management during world switch. Hence, when |
| 94 | the PSCI library is integrated with a AArch32 EL3 Runtime Software, the |
| 95 | ``cpu_context_t`` is stripped down for just PSCI CPU context management. |
| 96 | |
| 97 | During cold/warm boot, after invoking appropriate PSCI library interfaces, it |
| 98 | is expected that the EL3 Runtime Software will query the ``cpu_context_t`` and |
| 99 | write appropriate values to the corresponding system registers. This mechanism |
| 100 | resolves 2 additional problems for AArch32 EL3 Runtime Software: |
| 101 | |
| 102 | #. Values for certain system registers like SCR and SCTLR cannot be |
| 103 | unilaterally determined by PSCI library and need inputs from the EL3 |
| 104 | Runtime Software. Using ``cpu_context_t`` as an intermediary data store |
| 105 | allows EL3 Runtime Software to modify the register values appropriately |
| 106 | before programming them. |
| 107 | |
| 108 | #. The PSCI library provides appropriate LR and SPSR values (entrypoint |
| 109 | information) for exit into non-secure world. Using ``cpu_context_t`` as an |
| 110 | intermediary data store allows the EL3 Runtime Software to store these |
| 111 | values safely until it is ready for exit to non-secure world. |
| 112 | |
| 113 | Currently the ``cpu_context_t`` data structure for AArch32 stores the following |
| 114 | registers: R0 - R3, LR (R14), SCR, SPSR, SCTLR. |
| 115 | |
| 116 | The EL3 Runtime Software must implement accessors to get/set pointers |
| 117 | to CPU context ``cpu_context_t`` data and these are described in |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 118 | `CPU Context management API`_. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 119 | |
| 120 | PSCI Library Interface |
| 121 | ---------------------- |
| 122 | |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 123 | The PSCI library implements the `PSCI`_. The interfaces to this library are |
| 124 | declared in ``psci_lib.h`` and are as listed below: |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 125 | |
| 126 | .. code:: c |
| 127 | |
| 128 | u_register_t psci_smc_handler(uint32_t smc_fid, u_register_t x1, |
| 129 | u_register_t x2, u_register_t x3, |
| 130 | u_register_t x4, void *cookie, |
| 131 | void *handle, u_register_t flags); |
| 132 | int psci_setup(const psci_lib_args_t *lib_args); |
| 133 | void psci_warmboot_entrypoint(void); |
| 134 | void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); |
| 135 | void psci_prepare_next_non_secure_ctx(entry_point_info_t *next_image_info); |
| 136 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 137 | The CPU context data 'cpu_context_t' is programmed to the registers differently |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 138 | when PSCI is integrated with an AArch32 EL3 Runtime Software compared to |
| 139 | when the PSCI is integrated with an AArch64 EL3 Runtime Software (BL31). For |
| 140 | example, in the case of AArch64, there is no need to retrieve ``cpu_context_t`` |
| 141 | data and program the registers as it will done implicitly as part of |
| 142 | ``el3_exit``. The description below of the PSCI interfaces is targeted at |
| 143 | integration with an AArch32 EL3 Runtime Software. |
| 144 | |
| 145 | The PSCI library is responsible for initializing/restoring the non-secure world |
| 146 | to an appropriate state after boot and may choose to directly program the |
| 147 | non-secure system registers. The PSCI generic code takes care not to directly |
| 148 | modify any of the system registers affecting the secure world and instead |
| 149 | returns the values to be programmed to these registers via ``cpu_context_t``. |
| 150 | The EL3 Runtime Software is responsible for programming those registers and |
| 151 | can use the proposed values provided in the ``cpu_context_t``, modifying the |
| 152 | values if required. |
| 153 | |
| 154 | PSCI library needs the flexibility to access both secure and non-secure |
| 155 | copies of banked registers. Hence it needs to be invoked in Monitor mode |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 156 | for AArch32 and in EL3 for AArch64. The NS bit in SCR (in AArch32) or SCR_EL3 |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 157 | (in AArch64) must be set to 0. Additional requirements for the PSCI library |
| 158 | interfaces are: |
| 159 | |
| 160 | - Instruction cache must be enabled |
| 161 | - Both IRQ and FIQ must be masked for the current CPU |
| 162 | - The page tables must be setup and the MMU enabled |
| 163 | - The C runtime environment must be setup and stack initialized |
| 164 | - The Data cache must be enabled prior to invoking any of the PSCI library |
| 165 | interfaces except for ``psci_warmboot_entrypoint()``. For |
| 166 | ``psci_warmboot_entrypoint()``, if the build option ``HW_ASSISTED_COHERENCY`` |
| 167 | is enabled however, data caches are expected to be enabled. |
| 168 | |
| 169 | Further requirements for each interface can be found in the interface |
| 170 | description. |
| 171 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 172 | Interface : psci_setup() |
| 173 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 174 | |
| 175 | :: |
| 176 | |
| 177 | Argument : const psci_lib_args_t *lib_args |
| 178 | Return : void |
| 179 | |
| 180 | This function is to be called by the primary CPU during cold boot before |
| 181 | any other interface to the PSCI library. It takes ``lib_args``, a const pointer |
| 182 | to ``psci_lib_args_t``, as the argument. The ``psci_lib_args_t`` is a versioned |
John Tsichritzis | 2bcd532 | 2019-05-13 11:20:05 +0100 | [diff] [blame] | 183 | structure and is declared in ``psci_lib.h`` header as follows: |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 184 | |
| 185 | .. code:: c |
| 186 | |
| 187 | typedef struct psci_lib_args { |
| 188 | /* The version information of PSCI Library Interface */ |
| 189 | param_header_t h; |
| 190 | /* The warm boot entrypoint function */ |
| 191 | mailbox_entrypoint_t mailbox_ep; |
| 192 | } psci_lib_args_t; |
| 193 | |
| 194 | The first field ``h``, of ``param_header_t`` type, provides the version |
| 195 | information. The second field ``mailbox_ep`` is the warm boot entrypoint address |
| 196 | and is used to configure the platform mailbox. Helper macros are provided in |
John Tsichritzis | 2bcd532 | 2019-05-13 11:20:05 +0100 | [diff] [blame] | 197 | ``psci_lib.h`` to construct the ``lib_args`` argument statically or during |
| 198 | runtime. Prior to calling the ``psci_setup()`` interface, the platform setup for |
| 199 | cold boot must have completed. Major actions performed by this interface are: |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 200 | |
| 201 | - Initializes architecture. |
| 202 | - Initializes PSCI power domain and state coordination data structures. |
| 203 | - Calls ``plat_setup_psci_ops()`` with warm boot entrypoint ``mailbox_ep`` as |
| 204 | argument. |
| 205 | - Calls ``cm_set_context_by_index()`` (see |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 206 | `CPU Context management API`_) for all the CPUs in the |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 207 | platform |
| 208 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 209 | Interface : psci_prepare_next_non_secure_ctx() |
| 210 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 211 | |
| 212 | :: |
| 213 | |
| 214 | Argument : entry_point_info_t *next_image_info |
| 215 | Return : void |
| 216 | |
| 217 | After ``psci_setup()`` and prior to exit to the non-secure world, this function |
| 218 | must be called by the EL3 Runtime Software to initialize the non-secure world |
| 219 | context. The non-secure world entrypoint information ``next_image_info`` (first |
| 220 | argument) will be used to determine the non-secure context. After this function |
| 221 | returns, the EL3 Runtime Software must retrieve the ``cpu_context_t`` (using |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 222 | cm_get_context()) for the current CPU and program the registers prior to exit |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 223 | to the non-secure world. |
| 224 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 225 | Interface : psci_register_spd_pm_hook() |
| 226 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 227 | |
| 228 | :: |
| 229 | |
| 230 | Argument : const spd_pm_ops_t * |
| 231 | Return : void |
| 232 | |
Douglas Raillard | 30d7b36 | 2017-06-28 16:14:55 +0100 | [diff] [blame] | 233 | As explained in `Secure payload power management callback`_, |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 234 | the EL3 Runtime Software may want to perform some bookkeeping during power |
| 235 | management operations. This function is used to register the ``spd_pm_ops_t`` |
| 236 | (first argument) callbacks with the PSCI library which will be called |
Paul Beesley | 1fbc97b | 2019-01-11 18:26:51 +0000 | [diff] [blame] | 237 | appropriately during power management. Calling this function is optional and |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 238 | need to be called by the primary CPU during the cold boot sequence after |
| 239 | ``psci_setup()`` has completed. |
| 240 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 241 | Interface : psci_smc_handler() |
| 242 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 243 | |
| 244 | :: |
| 245 | |
| 246 | Argument : uint32_t smc_fid, u_register_t x1, |
| 247 | u_register_t x2, u_register_t x3, |
| 248 | u_register_t x4, void *cookie, |
| 249 | void *handle, u_register_t flags |
| 250 | Return : u_register_t |
| 251 | |
| 252 | This function is the top level handler for SMCs which fall within the |
| 253 | PSCI service range specified in `SMCCC`_. The function ID ``smc_fid`` (first |
| 254 | argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th |
| 255 | arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4 |
| 256 | (in AArch64) when the SMC is received. These are the arguments to PSCI API as |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 257 | described in `PSCI`_. The 'flags' (8th argument) is a bit field parameter |
Antonio Nino Diaz | 3c817f4 | 2018-03-21 10:49:27 +0000 | [diff] [blame] | 258 | and is detailed in 'smccc.h' header. It includes whether the call is from the |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 259 | secure or non-secure world. The ``cookie`` (6th argument) and the ``handle`` |
| 260 | (7th argument) are not used and are reserved for future use. |
| 261 | |
| 262 | The return value from this interface is the return value from the underlying |
| 263 | PSCI API corresponding to ``smc_fid``. This function may not return back to the |
| 264 | caller if PSCI API causes power down of the CPU. In this case, when the CPU |
| 265 | wakes up, it will start execution from the warm reset address. |
| 266 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 267 | Interface : psci_warmboot_entrypoint() |
| 268 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 269 | |
| 270 | :: |
| 271 | |
| 272 | Argument : void |
| 273 | Return : void |
| 274 | |
| 275 | This function performs the warm boot initialization/restoration as mandated by |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 276 | `PSCI`_. For AArch32, on wakeup from power down the CPU resets to secure SVC |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 277 | mode and the EL3 Runtime Software must perform the prerequisite initializations |
| 278 | mentioned at top of this section. This function must be called with Data cache |
| 279 | disabled (unless build option ``HW_ASSISTED_COHERENCY`` is enabled) but with MMU |
| 280 | initialized and enabled. The major actions performed by this function are: |
| 281 | |
| 282 | - Invalidates the stack and enables the data cache. |
| 283 | - Initializes architecture and PSCI state coordination. |
| 284 | - Restores/Initializes the peripheral drivers to the required state via |
| 285 | appropriate ``plat_psci_ops_t`` hooks |
| 286 | - Restores the EL3 Runtime Software context via appropriate ``spd_pm_ops_t`` |
| 287 | callbacks. |
| 288 | - Restores/Initializes the non-secure context and populates the |
| 289 | ``cpu_context_t`` for the current CPU. |
| 290 | |
| 291 | Upon the return of this function, the EL3 Runtime Software must retrieve the |
| 292 | non-secure ``cpu_context_t`` using ``cm_get_context()`` and program the registers |
| 293 | prior to exit to the non-secure world. |
| 294 | |
| 295 | EL3 Runtime Software dependencies |
| 296 | --------------------------------- |
| 297 | |
| 298 | The PSCI Library includes supporting frameworks like context management, |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 299 | cpu operations (cpu_ops) and per-cpu data framework. Other helper library |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 300 | functions like bakery locks and spin locks are also included in the library. |
| 301 | The dependencies which must be fulfilled by the EL3 Runtime Software |
| 302 | for integration with PSCI library are described below. |
| 303 | |
| 304 | General dependencies |
| 305 | ~~~~~~~~~~~~~~~~~~~~ |
| 306 | |
| 307 | The PSCI library being a Multiprocessor (MP) implementation, EL3 Runtime |
| 308 | Software must provide an SMC handling framework capable of MP adhering to |
| 309 | `SMCCC`_ specification. |
| 310 | |
| 311 | The EL3 Runtime Software must also export cache maintenance primitives |
| 312 | and some helper utilities for assert, print and memory operations as listed |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 313 | below. The TF-A source tree provides implementations for all |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 314 | these functions but the EL3 Runtime Software may use its own implementation. |
| 315 | |
Antonio Nino Diaz | c0c8eb6 | 2018-08-15 17:02:28 +0100 | [diff] [blame] | 316 | **Functions : assert(), memcpy(), memset(), printf()** |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 317 | |
| 318 | These must be implemented as described in ISO C Standard. |
| 319 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 320 | **Function : flush_dcache_range()** |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 321 | |
| 322 | :: |
| 323 | |
| 324 | Argument : uintptr_t addr, size_t size |
| 325 | Return : void |
| 326 | |
| 327 | This function cleans and invalidates (flushes) the data cache for memory |
| 328 | at address ``addr`` (first argument) address and of size ``size`` (second argument). |
| 329 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 330 | **Function : inv_dcache_range()** |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 331 | |
| 332 | :: |
| 333 | |
| 334 | Argument : uintptr_t addr, size_t size |
| 335 | Return : void |
| 336 | |
| 337 | This function invalidates (flushes) the data cache for memory at address |
| 338 | ``addr`` (first argument) address and of size ``size`` (second argument). |
| 339 | |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 340 | CPU Context management API |
| 341 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 342 | |
| 343 | The CPU context management data memory is statically allocated by PSCI library |
| 344 | in BSS section. The PSCI library requires the EL3 Runtime Software to implement |
| 345 | APIs to store and retrieve pointers to this CPU context data. SP-MIN |
| 346 | demonstrates how these APIs can be implemented but the EL3 Runtime Software can |
| 347 | choose a more optimal implementation (like dedicating the secure TPIDRPRW |
| 348 | system register (in AArch32) for storing these pointers). |
| 349 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 350 | **Function : cm_set_context_by_index()** |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 351 | |
| 352 | :: |
| 353 | |
| 354 | Argument : unsigned int cpu_idx, void *context, unsigned int security_state |
| 355 | Return : void |
| 356 | |
| 357 | This function is called during cold boot when the ``psci_setup()`` PSCI library |
| 358 | interface is called. |
| 359 | |
| 360 | This function must store the pointer to the CPU context data, ``context`` (2nd |
| 361 | argument), for the specified ``security_state`` (3rd argument) and CPU identified |
| 362 | by ``cpu_idx`` (first argument). The ``security_state`` will always be non-secure |
| 363 | when called by PSCI library and this argument is retained for compatibility |
| 364 | with BL31. The ``cpu_idx`` will correspond to the index returned by the |
| 365 | ``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU. |
| 366 | |
| 367 | The actual method of storing the ``context`` pointers is implementation specific. |
| 368 | For example, SP-MIN stores the pointers in the array ``sp_min_cpu_ctx_ptr`` |
| 369 | declared in ``sp_min_main.c``. |
| 370 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 371 | **Function : cm_get_context()** |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 372 | |
| 373 | :: |
| 374 | |
| 375 | Argument : uint32_t security_state |
| 376 | Return : void * |
| 377 | |
| 378 | This function must return the pointer to the ``cpu_context_t`` structure for |
| 379 | the specified ``security_state`` (first argument) for the current CPU. The caller |
| 380 | must ensure that ``cm_set_context_by_index`` is called first and the appropriate |
| 381 | context pointers are stored prior to invoking this API. The ``security_state`` |
| 382 | will always be non-secure when called by PSCI library and this argument |
| 383 | is retained for compatibility with BL31. |
| 384 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 385 | **Function : cm_get_context_by_index()** |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 386 | |
| 387 | :: |
| 388 | |
| 389 | Argument : unsigned int cpu_idx, unsigned int security_state |
| 390 | Return : void * |
| 391 | |
| 392 | This function must return the pointer to the ``cpu_context_t`` structure for |
| 393 | the specified ``security_state`` (second argument) for the CPU identified by |
| 394 | ``cpu_idx`` (first argument). The caller must ensure that |
| 395 | ``cm_set_context_by_index`` is called first and the appropriate context |
| 396 | pointers are stored prior to invoking this API. The ``security_state`` will |
| 397 | always be non-secure when called by PSCI library and this argument is |
| 398 | retained for compatibility with BL31. The ``cpu_idx`` will correspond to the |
| 399 | index returned by the ``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU. |
| 400 | |
| 401 | Platform API |
| 402 | ~~~~~~~~~~~~ |
| 403 | |
| 404 | The platform layer abstracts the platform-specific details from the generic |
| 405 | PSCI library. The following platform APIs/macros must be defined by the EL3 |
| 406 | Runtime Software for integration with the PSCI library. |
| 407 | |
| 408 | The mandatory platform APIs are: |
| 409 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 410 | - plat_my_core_pos |
| 411 | - plat_core_pos_by_mpidr |
| 412 | - plat_get_syscnt_freq2 |
| 413 | - plat_get_power_domain_tree_desc |
| 414 | - plat_setup_psci_ops |
| 415 | - plat_reset_handler |
| 416 | - plat_panic_handler |
| 417 | - plat_get_my_stack |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 418 | |
| 419 | The mandatory platform macros are: |
| 420 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 421 | - PLATFORM_CORE_COUNT |
| 422 | - PLAT_MAX_PWR_LVL |
| 423 | - PLAT_NUM_PWR_DOMAINS |
| 424 | - CACHE_WRITEBACK_GRANULE |
| 425 | - PLAT_MAX_OFF_STATE |
| 426 | - PLAT_MAX_RET_STATE |
| 427 | - PLAT_MAX_PWR_LVL_STATES (optional) |
| 428 | - PLAT_PCPU_DATA_SIZE (optional) |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 429 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 430 | The details of these APIs/macros can be found in the :ref:`Porting Guide`. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 431 | |
| 432 | All platform specific operations for power management are done via |
| 433 | ``plat_psci_ops_t`` callbacks registered by the platform when |
| 434 | ``plat_setup_psci_ops()`` API is called. The description of each of |
| 435 | the callbacks in ``plat_psci_ops_t`` can be found in PSCI section of the |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 436 | :ref:`Porting Guide`. If any these callbacks are not registered, then the |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 437 | PSCI API associated with that callback will not be supported by PSCI |
| 438 | library. |
| 439 | |
| 440 | Secure payload power management callback |
| 441 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 442 | |
| 443 | During PSCI power management operations, the EL3 Runtime Software may |
| 444 | need to perform some bookkeeping, and PSCI library provides |
| 445 | ``spd_pm_ops_t`` callbacks for this purpose. These hooks must be |
| 446 | populated and registered by using ``psci_register_spd_pm_hook()`` PSCI |
| 447 | library interface. |
| 448 | |
| 449 | Typical bookkeeping during PSCI power management calls include save/restore |
| 450 | of the EL3 Runtime Software context. Also if the EL3 Runtime Software makes |
| 451 | use of secure interrupts, then these interrupts must also be managed |
| 452 | appropriately during CPU power down/power up. Any secure interrupt targeted |
| 453 | to the current CPU must be disabled or re-targeted to other running CPU prior |
| 454 | to power down of the current CPU. During power up, these interrupt can be |
| 455 | enabled/re-targeted back to the current CPU. |
| 456 | |
| 457 | .. code:: c |
| 458 | |
| 459 | typedef struct spd_pm_ops { |
| 460 | void (*svc_on)(u_register_t target_cpu); |
| 461 | int32_t (*svc_off)(u_register_t __unused); |
| 462 | void (*svc_suspend)(u_register_t max_off_pwrlvl); |
| 463 | void (*svc_on_finish)(u_register_t __unused); |
| 464 | void (*svc_suspend_finish)(u_register_t max_off_pwrlvl); |
| 465 | int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu); |
| 466 | int32_t (*svc_migrate_info)(u_register_t *resident_cpu); |
| 467 | void (*svc_system_off)(void); |
| 468 | void (*svc_system_reset)(void); |
| 469 | } spd_pm_ops_t; |
| 470 | |
| 471 | A brief description of each callback is given below: |
| 472 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 473 | - svc_on, svc_off, svc_on_finish |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 474 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 475 | The ``svc_on``, ``svc_off`` callbacks are called during PSCI_CPU_ON, |
| 476 | PSCI_CPU_OFF APIs respectively. The ``svc_on_finish`` is called when the |
| 477 | target CPU of PSCI_CPU_ON API powers up and executes the |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 478 | ``psci_warmboot_entrypoint()`` PSCI library interface. |
| 479 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 480 | - svc_suspend, svc_suspend_finish |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 481 | |
| 482 | The ``svc_suspend`` callback is called during power down bu either |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 483 | PSCI_SUSPEND or PSCI_SYSTEM_SUSPEND APIs. The ``svc_suspend_finish`` is |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 484 | called when the CPU wakes up from suspend and executes the |
| 485 | ``psci_warmboot_entrypoint()`` PSCI library interface. The ``max_off_pwrlvl`` |
| 486 | (first parameter) denotes the highest power domain level being powered down |
| 487 | to or woken up from suspend. |
| 488 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 489 | - svc_system_off, svc_system_reset |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 490 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 491 | These callbacks are called during PSCI_SYSTEM_OFF and PSCI_SYSTEM_RESET |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 492 | PSCI APIs respectively. |
| 493 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 494 | - svc_migrate_info |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 495 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 496 | This callback is called in response to PSCI_MIGRATE_INFO_TYPE or |
| 497 | PSCI_MIGRATE_INFO_UP_CPU APIs. The return value of this callback must |
| 498 | correspond to the return value of PSCI_MIGRATE_INFO_TYPE API as described |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 499 | in `PSCI`_. If the secure payload is a Uniprocessor (UP) |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 500 | implementation, then it must update the mpidr of the CPU it is resident in |
| 501 | via ``resident_cpu`` (first argument). The updates to ``resident_cpu`` is |
| 502 | ignored if the secure payload is a multiprocessor (MP) implementation. |
| 503 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 504 | - svc_migrate |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 505 | |
| 506 | This callback is only relevant if the secure payload in EL3 Runtime |
| 507 | Software is a Uniprocessor (UP) implementation and supports migration from |
| 508 | the current CPU ``from_cpu`` (first argument) to another CPU ``to_cpu`` |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 509 | (second argument). This callback is called in response to PSCI_MIGRATE |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 510 | API. This callback is never called if the secure payload is a |
| 511 | Multiprocessor (MP) implementation. |
| 512 | |
| 513 | CPU operations |
| 514 | ~~~~~~~~~~~~~~ |
| 515 | |
Sandrine Bailleux | 15530dd | 2019-02-08 15:26:36 +0100 | [diff] [blame] | 516 | The CPU operations (cpu_ops) framework implement power down sequence specific |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 517 | to the CPU and the details of which can be found at |
| 518 | :ref:`firmware_design_cpu_ops_fwk`. The TF-A tree implements the ``cpu_ops`` |
| 519 | for various supported CPUs and the EL3 Runtime Software needs to include the |
| 520 | required ``cpu_ops`` in its build. The start and end of the ``cpu_ops`` |
| 521 | descriptors must be exported by the EL3 Runtime Software via the |
| 522 | ``__CPU_OPS_START__`` and ``__CPU_OPS_END__`` linker symbols. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 523 | |
| 524 | The ``cpu_ops`` descriptors also include reset sequences and may include errata |
| 525 | workarounds for the CPU. The EL3 Runtime Software can choose to call this |
| 526 | during cold/warm reset if it does not implement its own reset sequence/errata |
| 527 | workarounds. |
| 528 | |
| 529 | -------------- |
| 530 | |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 531 | *Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.* |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 532 | |
Manish V Badarkhe | 9d24e9b | 2023-06-15 09:14:33 +0100 | [diff] [blame] | 533 | .. _PSCI: https://developer.arm.com/documentation/den0022/latest/ |
laurenw-arm | 03e7e61 | 2020-04-16 10:02:17 -0500 | [diff] [blame] | 534 | .. _SMCCC: https://developer.arm.com/docs/den0028/latest |