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