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