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