1PSCI Library Integration guide for ARMv8-A AArch32 systems 2========================================================== 3 4 5.. section-numbering:: 6 :suffix: . 7 8.. contents:: 9 10This document describes the PSCI library interface with a focus on how to 11integrate with a suitable Trusted OS for an ARMv8-A AArch32 system. The PSCI 12Library implements the PSCI Standard as described in `PSCI spec`_ and is meant 13to be integrated with EL3 Runtime Software which invokes the PSCI Library 14interface appropriately. **EL3 Runtime Software** refers to software executing 15at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/ 16Monitor mode in AArch32, and provides runtime services to the non-secure world. 17The runtime service request is made via SMC (Secure Monitor Call) and the call 18must adhere to `SMCCC`_. In AArch32, EL3 Runtime Software may additionally 19include Trusted OS functionality. A minimal AArch32 Secure Payload, SP-MIN, is 20provided in ARM Trusted Firmware to illustrate the usage and integration of the 21PSCI library. The description of PSCI library interface and its integration 22with EL3 Runtime Software in this document is targeted towards AArch32 systems. 23 24Generic call sequence for PSCI Library interface (AArch32) 25---------------------------------------------------------- 26 27The generic call sequence of PSCI Library interfaces (see 28`PSCI Library Interface`_) during cold boot in AArch32 29system 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 33 `PSCI Library Interface`_, and also the necessary platform 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 49 to programming. See `PSCI CPU context management`_ for more 50 details on CPU context management. 51 52The generic call sequence of PSCI library interfaces during warm boot in 53AArch32 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 57 `PSCI Library Interface`_ (Note that the Data cache 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 65The generic call sequence of PSCI library interfaces on receipt of a PSCI SMC 66on 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 78PSCI CPU context management 79--------------------------- 80 81PSCI library is in charge of initializing/restoring the non-secure CPU system 82registers according to `PSCI specification`_ during cold/warm boot. 83This is referred to as ``PSCI CPU Context Management``. Registers that need to 84be preserved across CPU power down/power up cycles are maintained in 85``cpu_context_t`` data structure. The initialization of other non-secure CPU 86system registers which do not require coordination with the EL3 Runtime 87Software is done directly by the PSCI library (see ``cm_prepare_el3_exit()``). 88 89The EL3 Runtime Software is responsible for managing register context 90during switch between Normal and Secure worlds. The register context to be 91saved and restored depends on the mechanism used to trigger the world switch. 92For example, if the world switch was triggered by an SMC call, then the 93registers need to be saved and restored according to `SMCCC`_. In AArch64, 94due to the tight integration with BL31, both BL31 and PSCI library 95use the same ``cpu_context_t`` data structure for PSCI CPU context management 96and register context management during world switch. This cannot be assumed 97for AArch32 EL3 Runtime Software since most AArch32 Trusted OSes already implement 98a mechanism for register context management during world switch. Hence, when 99the 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 102During cold/warm boot, after invoking appropriate PSCI library interfaces, it 103is expected that the EL3 Runtime Software will query the ``cpu_context_t`` and 104write appropriate values to the corresponding system registers. This mechanism 105resolves 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 118Currently the ``cpu_context_t`` data structure for AArch32 stores the following 119registers: R0 - R3, LR (R14), SCR, SPSR, SCTLR. 120 121The EL3 Runtime Software must implement accessors to get/set pointers 122to CPU context ``cpu_context_t`` data and these are described in 123`CPU Context management API`_. 124 125PSCI Library Interface 126---------------------- 127 128The PSCI library implements the `PSCI Specification`_. The interfaces 129to 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 142The CPU context data 'cpu\_context\_t' is programmed to the registers differently 143when PSCI is integrated with an AArch32 EL3 Runtime Software compared to 144when the PSCI is integrated with an AArch64 EL3 Runtime Software (BL31). For 145example, in the case of AArch64, there is no need to retrieve ``cpu_context_t`` 146data 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 148integration with an AArch32 EL3 Runtime Software. 149 150The PSCI library is responsible for initializing/restoring the non-secure world 151to an appropriate state after boot and may choose to directly program the 152non-secure system registers. The PSCI generic code takes care not to directly 153modify any of the system registers affecting the secure world and instead 154returns the values to be programmed to these registers via ``cpu_context_t``. 155The EL3 Runtime Software is responsible for programming those registers and 156can use the proposed values provided in the ``cpu_context_t``, modifying the 157values if required. 158 159PSCI library needs the flexibility to access both secure and non-secure 160copies of banked registers. Hence it needs to be invoked in Monitor mode 161for 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 163interfaces 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 174Further requirements for each interface can be found in the interface 175description. 176 177Interface : psci\_setup() 178~~~~~~~~~~~~~~~~~~~~~~~~~ 179 180:: 181 182 Argument : const psci_lib_args_t *lib_args 183 Return : void 184 185This function is to be called by the primary CPU during cold boot before 186any other interface to the PSCI library. It takes ``lib_args``, a const pointer 187to ``psci_lib_args_t``, as the argument. The ``psci_lib_args_t`` is a versioned 188structure 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 199The first field ``h``, of ``param_header_t`` type, provides the version 200information. The second field ``mailbox_ep`` is the warm boot entrypoint address 201and is used to configure the platform mailbox. Helper macros are provided in 202psci.h to construct the ``lib_args`` argument statically or during runtime. Prior 203to calling the ``psci_setup()`` interface, the platform setup for cold boot 204must 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 211 `CPU Context management API`_) for all the CPUs in the 212 platform 213 214Interface : psci\_prepare\_next\_non\_secure\_ctx() 215~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216 217:: 218 219 Argument : entry_point_info_t *next_image_info 220 Return : void 221 222After ``psci_setup()`` and prior to exit to the non-secure world, this function 223must be called by the EL3 Runtime Software to initialize the non-secure world 224context. The non-secure world entrypoint information ``next_image_info`` (first 225argument) will be used to determine the non-secure context. After this function 226returns, the EL3 Runtime Software must retrieve the ``cpu_context_t`` (using 227cm\_get\_context()) for the current CPU and program the registers prior to exit 228to the non-secure world. 229 230Interface : psci\_register\_spd\_pm\_hook() 231~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 232 233:: 234 235 Argument : const spd_pm_ops_t * 236 Return : void 237 238As explained in `Secure payload power management callback`_, 239the EL3 Runtime Software may want to perform some bookkeeping during power 240management operations. This function is used to register the ``spd_pm_ops_t`` 241(first argument) callbacks with the PSCI library which will be called 242ppropriately during power management. Calling this function is optional and 243need to be called by the primary CPU during the cold boot sequence after 244``psci_setup()`` has completed. 245 246Interface : 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 257This function is the top level handler for SMCs which fall within the 258PSCI service range specified in `SMCCC`_. The function ID ``smc_fid`` (first 259argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th 260arguments), 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 262described in `PSCI spec`_. The 'flags' (8th argument) is a bit field parameter 263and is detailed in 'smcc.h' header. It includes whether the call is from the 264secure or non-secure world. The ``cookie`` (6th argument) and the ``handle`` 265(7th argument) are not used and are reserved for future use. 266 267The return value from this interface is the return value from the underlying 268PSCI API corresponding to ``smc_fid``. This function may not return back to the 269caller if PSCI API causes power down of the CPU. In this case, when the CPU 270wakes up, it will start execution from the warm reset address. 271 272Interface : psci\_warmboot\_entrypoint() 273~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 274 275:: 276 277 Argument : void 278 Return : void 279 280This 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 282mode and the EL3 Runtime Software must perform the prerequisite initializations 283mentioned at top of this section. This function must be called with Data cache 284disabled (unless build option ``HW_ASSISTED_COHERENCY`` is enabled) but with MMU 285initialized 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 296Upon the return of this function, the EL3 Runtime Software must retrieve the 297non-secure ``cpu_context_t`` using ``cm_get_context()`` and program the registers 298prior to exit to the non-secure world. 299 300EL3 Runtime Software dependencies 301--------------------------------- 302 303The PSCI Library includes supporting frameworks like context management, 304cpu operations (cpu\_ops) and per-cpu data framework. Other helper library 305functions like bakery locks and spin locks are also included in the library. 306The dependencies which must be fulfilled by the EL3 Runtime Software 307for integration with PSCI library are described below. 308 309General dependencies 310~~~~~~~~~~~~~~~~~~~~ 311 312The PSCI library being a Multiprocessor (MP) implementation, EL3 Runtime 313Software must provide an SMC handling framework capable of MP adhering to 314`SMCCC`_ specification. 315 316The EL3 Runtime Software must also export cache maintenance primitives 317and some helper utilities for assert, print and memory operations as listed 318below. The ARM Trusted Firmware source tree provides implementations for all 319these functions but the EL3 Runtime Software may use its own implementation. 320 321**Functions : assert(), memcpy(), memset** 322 323These 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 332This function cleans and invalidates (flushes) the data cache for memory 333at 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 342This 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 352This function will be called by the PSCI library on encountering a critical 353failure that cannot be recovered from. This function **must not** return. 354 355**Function : tf\_printf()** 356 357This is printf-compatible function, but unlike printf, it does not return any 358value. The ARM Trusted Firmware source tree provides an implementation which 359is optimized for stack usage and supports only a subset of format specifiers. 360The details of the format specifiers supported can be found in the 361``tf_printf.c`` file in ARM Trusted Firmware source tree. 362 363CPU Context management API 364~~~~~~~~~~~~~~~~~~~~~~~~~~ 365 366The CPU context management data memory is statically allocated by PSCI library 367in BSS section. The PSCI library requires the EL3 Runtime Software to implement 368APIs to store and retrieve pointers to this CPU context data. SP-MIN 369demonstrates how these APIs can be implemented but the EL3 Runtime Software can 370choose a more optimal implementation (like dedicating the secure TPIDRPRW 371system 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 380This function is called during cold boot when the ``psci_setup()`` PSCI library 381interface is called. 382 383This function must store the pointer to the CPU context data, ``context`` (2nd 384argument), for the specified ``security_state`` (3rd argument) and CPU identified 385by ``cpu_idx`` (first argument). The ``security_state`` will always be non-secure 386when called by PSCI library and this argument is retained for compatibility 387with BL31. The ``cpu_idx`` will correspond to the index returned by the 388``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU. 389 390The actual method of storing the ``context`` pointers is implementation specific. 391For example, SP-MIN stores the pointers in the array ``sp_min_cpu_ctx_ptr`` 392declared in ``sp_min_main.c``. 393 394**Function : cm\_get\_context()** 395 396:: 397 398 Argument : uint32_t security_state 399 Return : void * 400 401This function must return the pointer to the ``cpu_context_t`` structure for 402the specified ``security_state`` (first argument) for the current CPU. The caller 403must ensure that ``cm_set_context_by_index`` is called first and the appropriate 404context pointers are stored prior to invoking this API. The ``security_state`` 405will always be non-secure when called by PSCI library and this argument 406is 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 415This function must return the pointer to the ``cpu_context_t`` structure for 416the 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 419pointers are stored prior to invoking this API. The ``security_state`` will 420always be non-secure when called by PSCI library and this argument is 421retained for compatibility with BL31. The ``cpu_idx`` will correspond to the 422index returned by the ``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU. 423 424Platform API 425~~~~~~~~~~~~ 426 427The platform layer abstracts the platform-specific details from the generic 428PSCI library. The following platform APIs/macros must be defined by the EL3 429Runtime Software for integration with the PSCI library. 430 431The 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 442The 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 453The details of these APIs/macros can be found in `Porting Guide`_. 454 455All 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 458the 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 460PSCI API associated with that callback will not be supported by PSCI 461library. 462 463Secure payload power management callback 464~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 465 466During PSCI power management operations, the EL3 Runtime Software may 467need to perform some bookkeeping, and PSCI library provides 468``spd_pm_ops_t`` callbacks for this purpose. These hooks must be 469populated and registered by using ``psci_register_spd_pm_hook()`` PSCI 470library interface. 471 472Typical bookkeeping during PSCI power management calls include save/restore 473of the EL3 Runtime Software context. Also if the EL3 Runtime Software makes 474use of secure interrupts, then these interrupts must also be managed 475appropriately during CPU power down/power up. Any secure interrupt targeted 476to the current CPU must be disabled or re-targeted to other running CPU prior 477to power down of the current CPU. During power up, these interrupt can be 478enabled/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 494A 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 536CPU operations 537~~~~~~~~~~~~~~ 538 539The CPU operations (cpu\_ops) framework implement power down sequence specific 540to the CPU and the details of which can be found in the ``CPU specific operations framework`` section of `Firmware Design`_. The ARM Trusted Firmware 541tree implements the ``cpu_ops`` for various supported CPUs and the EL3 Runtime 542Software needs to include the required ``cpu_ops`` in its build. The start and 543end of the ``cpu_ops`` descriptors must be exported by the EL3 Runtime Software 544via the ``__CPU_OPS_START__`` and ``__CPU_OPS_END__`` linker symbols. 545 546The ``cpu_ops`` descriptors also include reset sequences and may include errata 547workarounds for the CPU. The EL3 Runtime Software can choose to call this 548during cold/warm reset if it does not implement its own reset sequence/errata 549workarounds. 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 557.. _PSCI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf 558.. _PSCI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf 559.. _Porting Guide: porting-guide.rst 560.. _Firmware Design: ./firmware-design.rst 561