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