1*91f16700SchasingluluEL3 Runtime Service Writer's Guide 2*91f16700Schasinglulu===================================================== 3*91f16700Schasinglulu 4*91f16700SchasingluluIntroduction 5*91f16700Schasinglulu------------ 6*91f16700Schasinglulu 7*91f16700SchasingluluThis document describes how to add a runtime service to the EL3 Runtime 8*91f16700SchasingluluFirmware component of Trusted Firmware-A (TF-A), BL31. 9*91f16700Schasinglulu 10*91f16700SchasingluluSoftware executing in the normal world and in the trusted world at exception 11*91f16700Schasinglululevels lower than EL3 will request runtime services using the Secure Monitor 12*91f16700SchasingluluCall (SMC) instruction. These requests will follow the convention described in 13*91f16700Schasingluluthe SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function 14*91f16700Schasingluluidentifiers to each SMC request and describes how arguments are passed and 15*91f16700Schasingluluresults are returned. 16*91f16700Schasinglulu 17*91f16700SchasingluluSMC Functions are grouped together based on the implementor of the service, for 18*91f16700Schasingluluexample a subset of the Function IDs are designated as "OEM Calls" (see `SMCCC`_ 19*91f16700Schasinglulufor full details). The EL3 runtime services framework in BL31 enables the 20*91f16700Schasingluluindependent implementation of services for each group, which are then compiled 21*91f16700Schasingluluinto the BL31 image. This simplifies the integration of common software from 22*91f16700SchasingluluArm to support `PSCI`_, Secure Monitor for a Trusted OS and SoC specific 23*91f16700Schasinglulusoftware. The common runtime services framework ensures that SMC Functions are 24*91f16700Schasingluludispatched to their respective service implementation - the 25*91f16700Schasinglulu:ref:`Firmware Design` document provides details of how this is achieved. 26*91f16700Schasinglulu 27*91f16700SchasingluluThe interface and operation of the runtime services depends heavily on the 28*91f16700Schasingluluconcepts and definitions described in the `SMCCC`_, in particular SMC Function 29*91f16700SchasingluluIDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and 30*91f16700SchasingluluSMC64 calling conventions. Please refer to that document for a full explanation 31*91f16700Schasingluluof these terms. 32*91f16700Schasinglulu 33*91f16700SchasingluluOwning Entities, Call Types and Function IDs 34*91f16700Schasinglulu-------------------------------------------- 35*91f16700Schasinglulu 36*91f16700SchasingluluThe SMC Function Identifier includes a OEN field. These values and their 37*91f16700Schasinglulumeaning are described in `SMCCC`_ and summarized in table 1 below. Some entities 38*91f16700Schasingluluare allocated a range of of OENs. The OEN must be interpreted in conjunction 39*91f16700Schasingluluwith the SMC call type, which is either *Fast* or *Yielding*. Fast calls are 40*91f16700Schasingluluuninterruptible whereas Yielding calls can be pre-empted. The majority of 41*91f16700SchasingluluOwning Entities only have allocated ranges for Fast calls: Yielding calls are 42*91f16700Schasinglulureserved exclusively for Trusted OS providers or for interoperability with 43*91f16700Schasinglululegacy 32-bit software that predates the `SMCCC`_. 44*91f16700Schasinglulu 45*91f16700Schasinglulu:: 46*91f16700Schasinglulu 47*91f16700Schasinglulu Type OEN Service 48*91f16700Schasinglulu Fast 0 Arm Architecture calls 49*91f16700Schasinglulu Fast 1 CPU Service calls 50*91f16700Schasinglulu Fast 2 SiP Service calls 51*91f16700Schasinglulu Fast 3 OEM Service calls 52*91f16700Schasinglulu Fast 4 Standard Service calls 53*91f16700Schasinglulu Fast 5-47 Reserved for future use 54*91f16700Schasinglulu Fast 48-49 Trusted Application calls 55*91f16700Schasinglulu Fast 50-63 Trusted OS calls 56*91f16700Schasinglulu 57*91f16700Schasinglulu Yielding 0- 1 Reserved for existing Armv7-A calls 58*91f16700Schasinglulu Yielding 2-63 Trusted OS Standard Calls 59*91f16700Schasinglulu 60*91f16700Schasinglulu*Table 1: Service types and their corresponding Owning Entity Numbers* 61*91f16700Schasinglulu 62*91f16700SchasingluluEach individual entity can allocate the valid identifiers within the entity 63*91f16700Schasinglulurange as they need - it is not necessary to coordinate with other entities of 64*91f16700Schasingluluthe same type. For example, two SoC providers can use the same Function ID 65*91f16700Schasingluluwithin the SiP Service calls OEN range to mean different things - as these 66*91f16700Schasinglulucalls should be specific to the SoC. The Standard Runtime Calls OEN is used for 67*91f16700Schasingluluservices defined by Arm standards, such as `PSCI`_. 68*91f16700Schasinglulu 69*91f16700SchasingluluThe SMC Function ID also indicates whether the call has followed the SMC32 70*91f16700Schasinglulucalling convention, where all parameters are 32-bit, or the SMC64 calling 71*91f16700Schasingluluconvention, where the parameters are 64-bit. The framework identifies and 72*91f16700Schasinglulurejects invalid calls that use the SMC64 calling convention but that originate 73*91f16700Schasinglulufrom an AArch32 caller. 74*91f16700Schasinglulu 75*91f16700SchasingluluThe EL3 runtime services framework uses the call type and OEN to identify a 76*91f16700Schasingluluspecific handler for each SMC call, but it is expected that an individual 77*91f16700Schasingluluhandler will be responsible for all SMC Functions within a given service type. 78*91f16700Schasinglulu 79*91f16700SchasingluluGetting started 80*91f16700Schasinglulu--------------- 81*91f16700Schasinglulu 82*91f16700SchasingluluTF-A has a ``services`` directory in the source tree under which 83*91f16700Schasinglulueach owning entity can place the implementation of its runtime service. The 84*91f16700Schasinglulu`PSCI`_ implementation is located here in the ``lib/psci`` directory. 85*91f16700Schasinglulu 86*91f16700SchasingluluRuntime service sources will need to include the ``runtime_svc.h`` header file. 87*91f16700Schasinglulu 88*91f16700SchasingluluRegistering a runtime service 89*91f16700Schasinglulu----------------------------- 90*91f16700Schasinglulu 91*91f16700SchasingluluA runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying 92*91f16700Schasingluluthe name of the service, the range of OENs covered, the type of service and 93*91f16700Schasingluluinitialization and call handler functions. 94*91f16700Schasinglulu 95*91f16700Schasinglulu.. code:: c 96*91f16700Schasinglulu 97*91f16700Schasinglulu #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) 98*91f16700Schasinglulu 99*91f16700Schasinglulu- ``_name`` is used to identify the data structure declared by this macro, and 100*91f16700Schasinglulu is also used for diagnostic purposes 101*91f16700Schasinglulu 102*91f16700Schasinglulu- ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in 103*91f16700Schasinglulu ``smccc.h`` 104*91f16700Schasinglulu 105*91f16700Schasinglulu- ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD`` 106*91f16700Schasinglulu 107*91f16700Schasinglulu- ``_setup`` is the initialization function with the ``rt_svc_init`` signature: 108*91f16700Schasinglulu 109*91f16700Schasinglulu .. code:: c 110*91f16700Schasinglulu 111*91f16700Schasinglulu typedef int32_t (*rt_svc_init)(void); 112*91f16700Schasinglulu 113*91f16700Schasinglulu- ``_smch`` is the SMC handler function with the ``rt_svc_handle`` signature: 114*91f16700Schasinglulu 115*91f16700Schasinglulu .. code:: c 116*91f16700Schasinglulu 117*91f16700Schasinglulu typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid, 118*91f16700Schasinglulu u_register_t x1, u_register_t x2, 119*91f16700Schasinglulu u_register_t x3, u_register_t x4, 120*91f16700Schasinglulu void *cookie, 121*91f16700Schasinglulu void *handle, 122*91f16700Schasinglulu u_register_t flags); 123*91f16700Schasinglulu 124*91f16700SchasingluluDetails of the requirements and behavior of the two callbacks is provided in 125*91f16700Schasingluluthe following sections. 126*91f16700Schasinglulu 127*91f16700SchasingluluDuring initialization the services framework validates each declared service 128*91f16700Schasingluluto ensure that the following conditions are met: 129*91f16700Schasinglulu 130*91f16700Schasinglulu#. The ``_start`` OEN is not greater than the ``_end`` OEN 131*91f16700Schasinglulu#. The ``_end`` OEN does not exceed the maximum OEN value (63) 132*91f16700Schasinglulu#. The ``_type`` is one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD`` 133*91f16700Schasinglulu#. ``_setup`` and ``_smch`` routines have been specified 134*91f16700Schasinglulu 135*91f16700Schasinglulu``std_svc_setup.c`` provides an example of registering a runtime service: 136*91f16700Schasinglulu 137*91f16700Schasinglulu.. code:: c 138*91f16700Schasinglulu 139*91f16700Schasinglulu /* Register Standard Service Calls as runtime service */ 140*91f16700Schasinglulu DECLARE_RT_SVC( 141*91f16700Schasinglulu std_svc, 142*91f16700Schasinglulu OEN_STD_START, 143*91f16700Schasinglulu OEN_STD_END, 144*91f16700Schasinglulu SMC_TYPE_FAST, 145*91f16700Schasinglulu std_svc_setup, 146*91f16700Schasinglulu std_svc_smc_handler 147*91f16700Schasinglulu ); 148*91f16700Schasinglulu 149*91f16700SchasingluluInitializing a runtime service 150*91f16700Schasinglulu------------------------------ 151*91f16700Schasinglulu 152*91f16700SchasingluluRuntime services are initialized once, during cold boot, by the primary CPU 153*91f16700Schasingluluafter platform and architectural initialization is complete. The framework 154*91f16700Schasingluluperforms basic validation of the declared service before calling 155*91f16700Schasingluluthe service initialization function (``_setup`` in the declaration). This 156*91f16700Schasinglulufunction must carry out any essential EL3 initialization prior to receiving a 157*91f16700SchasingluluSMC Function call via the handler function. 158*91f16700Schasinglulu 159*91f16700SchasingluluOn success, the initialization function must return ``0``. Any other return value 160*91f16700Schasingluluwill cause the framework to issue a diagnostic: 161*91f16700Schasinglulu 162*91f16700Schasinglulu:: 163*91f16700Schasinglulu 164*91f16700Schasinglulu Error initializing runtime service <name of the service> 165*91f16700Schasinglulu 166*91f16700Schasingluluand then ignore the service - the system will continue to boot but SMC calls 167*91f16700Schasingluluwill not be passed to the service handler and instead return the *Unknown SMC 168*91f16700SchasingluluFunction ID* result ``0xFFFFFFFF``. 169*91f16700Schasinglulu 170*91f16700SchasingluluIf the system must not be allowed to proceed without the service, the 171*91f16700Schasingluluinitialization function must itself cause the firmware boot to be halted. 172*91f16700Schasinglulu 173*91f16700SchasingluluIf the service uses per-CPU data this must either be initialized for all CPUs 174*91f16700Schasingluluduring this call, or be done lazily when a CPU first issues an SMC call to that 175*91f16700Schasingluluservice. 176*91f16700Schasinglulu 177*91f16700SchasingluluHandling runtime service requests 178*91f16700Schasinglulu--------------------------------- 179*91f16700Schasinglulu 180*91f16700SchasingluluSMC calls for a service are forwarded by the framework to the service's SMC 181*91f16700Schasingluluhandler function (``_smch`` in the service declaration). This function must have 182*91f16700Schasingluluthe following signature: 183*91f16700Schasinglulu 184*91f16700Schasinglulu.. code:: c 185*91f16700Schasinglulu 186*91f16700Schasinglulu typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid, 187*91f16700Schasinglulu u_register_t x1, u_register_t x2, 188*91f16700Schasinglulu u_register_t x3, u_register_t x4, 189*91f16700Schasinglulu void *cookie, 190*91f16700Schasinglulu void *handle, 191*91f16700Schasinglulu u_register_t flags); 192*91f16700Schasinglulu 193*91f16700SchasingluluThe handler is responsible for: 194*91f16700Schasinglulu 195*91f16700Schasinglulu#. Determining that ``smc_fid`` is a valid and supported SMC Function ID, 196*91f16700Schasinglulu otherwise completing the request with the *Unknown SMC Function ID*: 197*91f16700Schasinglulu 198*91f16700Schasinglulu .. code:: c 199*91f16700Schasinglulu 200*91f16700Schasinglulu SMC_RET1(handle, SMC_UNK); 201*91f16700Schasinglulu 202*91f16700Schasinglulu#. Determining if the requested function is valid for the calling security 203*91f16700Schasinglulu state. SMC Calls can be made from Non-secure, Secure or Realm worlds and 204*91f16700Schasinglulu the framework will forward all calls to the service handler. 205*91f16700Schasinglulu 206*91f16700Schasinglulu The ``flags`` parameter to this function indicates the caller security state 207*91f16700Schasinglulu in bits 0 and 5. The ``is_caller_secure(flags)``, ``is_caller_non_secure(flags)`` 208*91f16700Schasinglulu and ``is_caller_realm(flags)`` helper functions can be used to determine whether 209*91f16700Schasinglulu the caller's security state is Secure, Non-secure or Realm respectively. 210*91f16700Schasinglulu 211*91f16700Schasinglulu If invalid, the request should be completed with: 212*91f16700Schasinglulu 213*91f16700Schasinglulu .. code:: c 214*91f16700Schasinglulu 215*91f16700Schasinglulu SMC_RET1(handle, SMC_UNK); 216*91f16700Schasinglulu 217*91f16700Schasinglulu#. Truncating parameters for calls made using the SMC32 calling convention. 218*91f16700Schasinglulu Such calls can be determined by checking the CC field in bit[30] of the 219*91f16700Schasinglulu ``smc_fid`` parameter, for example by using: 220*91f16700Schasinglulu 221*91f16700Schasinglulu :: 222*91f16700Schasinglulu 223*91f16700Schasinglulu if (GET_SMC_CC(smc_fid) == SMC_32) ... 224*91f16700Schasinglulu 225*91f16700Schasinglulu For such calls, the upper bits of the parameters x1-x4 and the saved 226*91f16700Schasinglulu parameters X5-X7 are UNDEFINED and must be explicitly ignored by the 227*91f16700Schasinglulu handler. This can be done by truncating the values to a suitable 32-bit 228*91f16700Schasinglulu integer type before use, for example by ensuring that functions defined 229*91f16700Schasinglulu to handle individual SMC Functions use appropriate 32-bit parameters. 230*91f16700Schasinglulu 231*91f16700Schasinglulu#. Providing the service requested by the SMC Function, utilizing the 232*91f16700Schasinglulu immediate parameters x1-x4 and/or the additional saved parameters X5-X7. 233*91f16700Schasinglulu The latter can be retrieved using the ``SMC_GET_GP(handle, ref)`` function, 234*91f16700Schasinglulu supplying the appropriate ``CTX_GPREG_Xn`` reference, e.g. 235*91f16700Schasinglulu 236*91f16700Schasinglulu .. code:: c 237*91f16700Schasinglulu 238*91f16700Schasinglulu uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6); 239*91f16700Schasinglulu 240*91f16700Schasinglulu#. Implementing the standard SMC32 Functions that provide information about 241*91f16700Schasinglulu the implementation of the service. These are the Call Count, Implementor 242*91f16700Schasinglulu UID and Revision Details for each service documented in section 6 of the 243*91f16700Schasinglulu `SMCCC`_. 244*91f16700Schasinglulu 245*91f16700Schasinglulu TF-A expects owning entities to follow this recommendation. 246*91f16700Schasinglulu 247*91f16700Schasinglulu#. Returning the result to the caller. Based on `SMCCC`_ spec, results are 248*91f16700Schasinglulu returned in W0-W7(X0-X7) registers for SMC32(SMC64) calls from AArch64 249*91f16700Schasinglulu state. Results are returned in R0-R7 registers for SMC32 calls from AArch32 250*91f16700Schasinglulu state. The framework provides a family of macros to set the multi-register 251*91f16700Schasinglulu return value and complete the handler: 252*91f16700Schasinglulu 253*91f16700Schasinglulu .. code:: c 254*91f16700Schasinglulu 255*91f16700Schasinglulu AArch64 state: 256*91f16700Schasinglulu 257*91f16700Schasinglulu SMC_RET1(handle, x0); 258*91f16700Schasinglulu SMC_RET2(handle, x0, x1); 259*91f16700Schasinglulu SMC_RET3(handle, x0, x1, x2); 260*91f16700Schasinglulu SMC_RET4(handle, x0, x1, x2, x3); 261*91f16700Schasinglulu SMC_RET5(handle, x0, x1, x2, x3, x4); 262*91f16700Schasinglulu SMC_RET6(handle, x0, x1, x2, x3, x4, x5); 263*91f16700Schasinglulu SMC_RET7(handle, x0, x1, x2, x3, x4, x5, x6); 264*91f16700Schasinglulu SMC_RET8(handle, x0, x1, x2, x3, x4, x5, x6, x7); 265*91f16700Schasinglulu 266*91f16700Schasinglulu AArch32 state: 267*91f16700Schasinglulu 268*91f16700Schasinglulu SMC_RET1(handle, r0); 269*91f16700Schasinglulu SMC_RET2(handle, r0, r1); 270*91f16700Schasinglulu SMC_RET3(handle, r0, r1, r2); 271*91f16700Schasinglulu SMC_RET4(handle, r0, r1, r2, r3); 272*91f16700Schasinglulu SMC_RET5(handle, r0, r1, r2, r3, r4); 273*91f16700Schasinglulu SMC_RET6(handle, r0, r1, r2, r3, r4, r5); 274*91f16700Schasinglulu SMC_RET7(handle, r0, r1, r2, r3, r4, r5, r6); 275*91f16700Schasinglulu SMC_RET8(handle, r0, r1, r2, r3, r4, r5, r6, r7); 276*91f16700Schasinglulu 277*91f16700SchasingluluThe ``cookie`` parameter to the handler is reserved for future use and can be 278*91f16700Schasingluluignored. The ``handle`` is returned by the SMC handler - completion of the 279*91f16700Schasingluluhandler function must always be via one of the ``SMC_RETn()`` macros. 280*91f16700Schasinglulu 281*91f16700Schasinglulu.. note:: 282*91f16700Schasinglulu The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow 283*91f16700Schasinglulu all of the above requirements yet. 284*91f16700Schasinglulu 285*91f16700SchasingluluServices that contain multiple sub-services 286*91f16700Schasinglulu------------------------------------------- 287*91f16700Schasinglulu 288*91f16700SchasingluluIt is possible that a single owning entity implements multiple sub-services. For 289*91f16700Schasingluluexample, the Standard calls service handles ``0x84000000``-``0x8400FFFF`` and 290*91f16700Schasinglulu``0xC4000000``-``0xC400FFFF`` functions. Within that range, the `PSCI`_ service 291*91f16700Schasingluluhandles the ``0x84000000``-``0x8400001F`` and ``0xC4000000``-``0xC400001F`` functions. 292*91f16700SchasingluluIn that respect, `PSCI`_ is a 'sub-service' of the Standard calls service. In 293*91f16700Schasinglulufuture, there could be additional such sub-services in the Standard calls 294*91f16700Schasingluluservice which perform independent functions. 295*91f16700Schasinglulu 296*91f16700SchasingluluIn this situation it may be valuable to introduce a second level framework to 297*91f16700Schasingluluenable independent implementation of sub-services. Such a framework might look 298*91f16700Schasingluluvery similar to the current runtime services framework, but using a different 299*91f16700Schasinglulupart of the SMC Function ID to identify the sub-service. TF-A does not provide 300*91f16700Schasinglulusuch a framework at present. 301*91f16700Schasinglulu 302*91f16700SchasingluluSecure-EL1 Payload Dispatcher service (SPD) 303*91f16700Schasinglulu------------------------------------------- 304*91f16700Schasinglulu 305*91f16700SchasingluluServices that handle SMC Functions targeting a Trusted OS, Trusted Application, 306*91f16700Schasingluluor other Secure-EL1 Payload are special. These services need to manage the 307*91f16700SchasingluluSecure-EL1 context, provide the *Secure Monitor* functionality of switching 308*91f16700Schasinglulubetween the normal and secure worlds, deliver SMC Calls through to Secure-EL1 309*91f16700Schasingluluand generally manage the Secure-EL1 Payload through CPU power-state transitions. 310*91f16700Schasinglulu 311*91f16700SchasingluluTODO: Provide details of the additional work required to implement a SPD and 312*91f16700Schasingluluthe BL31 support for these services. Or a reference to the document that will 313*91f16700Schasingluluprovide this information.... 314*91f16700Schasinglulu 315*91f16700Schasinglulu-------------- 316*91f16700Schasinglulu 317*91f16700Schasinglulu*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.* 318*91f16700Schasinglulu 319*91f16700Schasinglulu.. _SMCCC: https://developer.arm.com/docs/den0028/latest 320*91f16700Schasinglulu.. _PSCI: https://developer.arm.com/documentation/den0022/latest/ 321