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