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