1 EL3 Runtime Service Writer's Guide
2 =====================================================
7 This document describes how to add a runtime service to the EL3 Runtime
8 Firmware component of Trusted Firmware-A (TF-A), BL31.
10 Software executing in the normal world and in the trusted world at exception
11 levels lower than EL3 will request runtime services using the Secure Monitor
12 Call (SMC) instruction. These requests will follow the convention described in
13 the SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function
14 identifiers to each SMC request and describes how arguments are passed and
17 SMC Functions are grouped together based on the implementor of the service, for
18 example a subset of the Function IDs are designated as "OEM Calls" (see `SMCCC`_
19 for full details). The EL3 runtime services framework in BL31 enables the
20 independent implementation of services for each group, which are then compiled
21 into the BL31 image. This simplifies the integration of common software from
22 Arm to support `PSCI`_, Secure Monitor for a Trusted OS and SoC specific
23 software. The common runtime services framework ensures that SMC Functions are
24 dispatched to their respective service implementation - the `Firmware Design`_
25 provides details of how this is achieved.
27 The interface and operation of the runtime services depends heavily on the
28 concepts and definitions described in the `SMCCC`_, in particular SMC Function
29 IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and
30 SMC64 calling conventions. Please refer to that document for a full explanation
33 Owning Entities, Call Types and Function IDs
34 --------------------------------------------
36 The SMC Function Identifier includes a OEN field. These values and their
37 meaning are described in `SMCCC`_ and summarized in table 1 below. Some entities
38 are allocated a range of of OENs. The OEN must be interpreted in conjunction
39 with the SMC call type, which is either *Fast* or *Yielding*. Fast calls are
40 uninterruptible whereas Yielding calls can be pre-empted. The majority of
41 Owning Entities only have allocated ranges for Fast calls: Yielding calls are
42 reserved exclusively for Trusted OS providers or for interoperability with
43 legacy 32-bit software that predates the `SMCCC`_.
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
57 Yielding 0- 1 Reserved for existing Armv7-A calls
58 Yielding 2-63 Trusted OS Standard Calls
60 *Table 1: Service types and their corresponding Owning Entity Numbers*
62 Each individual entity can allocate the valid identifiers within the entity
63 range as they need - it is not necessary to coordinate with other entities of
64 the same type. For example, two SoC providers can use the same Function ID
65 within the SiP Service calls OEN range to mean different things - as these
66 calls should be specific to the SoC. The Standard Runtime Calls OEN is used for
67 services defined by Arm standards, such as `PSCI`_.
69 The SMC Function ID also indicates whether the call has followed the SMC32
70 calling convention, where all parameters are 32-bit, or the SMC64 calling
71 convention, where the parameters are 64-bit. The framework identifies and
72 rejects invalid calls that use the SMC64 calling convention but that originate
73 from an AArch32 caller.
75 The EL3 runtime services framework uses the call type and OEN to identify a
76 specific handler for each SMC call, but it is expected that an individual
77 handler will be responsible for all SMC Functions within a given service type.
82 TF-A has a `services`_ directory in the source tree under which
83 each owning entity can place the implementation of its runtime service. The
84 `PSCI`_ implementation is located here in the `lib/psci`_ directory.
86 Runtime service sources will need to include the `runtime_svc.h`_ header file.
88 Registering a runtime service
89 -----------------------------
91 A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
92 the name of the service, the range of OENs covered, the type of service and
93 initialization and call handler functions.
97 #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
99 - ``_name`` is used to identify the data structure declared by this macro, and
100 is also used for diagnostic purposes
102 - ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in
105 - ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
107 - ``_setup`` is the initialization function with the ``rt_svc_init`` signature:
111 typedef int32_t (*rt_svc_init)(void);
113 - ``_smch`` is the SMC handler function with the ``rt_svc_handle`` signature:
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,
124 Details of the requirements and behavior of the two callbacks is provided in
125 the following sections.
127 During initialization the services framework validates each declared service
128 to ensure that the following conditions are met:
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
135 `std_svc_setup.c`_ provides an example of registering a runtime service:
139 /* Register Standard Service Calls as runtime service */
149 Initializing a runtime service
150 ------------------------------
152 Runtime services are initialized once, during cold boot, by the primary CPU
153 after platform and architectural initialization is complete. The framework
154 performs basic validation of the declared service before calling
155 the service initialization function (``_setup`` in the declaration). This
156 function must carry out any essential EL3 initialization prior to receiving a
157 SMC Function call via the handler function.
159 On success, the initialization function must return ``0``. Any other return value
160 will cause the framework to issue a diagnostic:
164 Error initializing runtime service <name of the service>
166 and then ignore the service - the system will continue to boot but SMC calls
167 will not be passed to the service handler and instead return the *Unknown SMC
168 Function ID* result ``0xFFFFFFFF``.
170 If the system must not be allowed to proceed without the service, the
171 initialization function must itself cause the firmware boot to be halted.
173 If the service uses per-CPU data this must either be initialized for all CPUs
174 during this call, or be done lazily when a CPU first issues an SMC call to that
177 Handling runtime service requests
178 ---------------------------------
180 SMC calls for a service are forwarded by the framework to the service's SMC
181 handler function (``_smch`` in the service declaration). This function must have
182 the following signature:
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,
193 The handler is responsible for:
195 #. Determining that ``smc_fid`` is a valid and supported SMC Function ID,
196 otherwise completing the request with the *Unknown SMC Function ID*:
200 SMC_RET1(handle, SMC_UNK);
202 #. Determining if the requested function is valid for the calling security
203 state. SMC Calls can be made from both the normal and trusted worlds and
204 the framework will forward all calls to the service handler.
206 The ``flags`` parameter to this function indicates the caller security state
207 in bit[0], where a value of ``1`` indicates a non-secure caller. The
208 ``is_caller_secure(flags)`` and ``is_caller_non_secure(flags)`` can be used to
211 If invalid, the request should be completed with:
215 SMC_RET1(handle, SMC_UNK);
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:
223 if (GET_SMC_CC(smc_fid) == SMC_32) ...
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.
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.
238 uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
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
245 TF-A expects owning entities to follow this recommendation.
247 #. Returning the result to the caller. The `SMCCC`_ allows for up to 256 bits
248 of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The
249 framework provides a family of macros to set the multi-register return
250 value and complete the handler:
254 SMC_RET1(handle, x0);
255 SMC_RET2(handle, x0, x1);
256 SMC_RET3(handle, x0, x1, x2);
257 SMC_RET4(handle, x0, x1, x2, x3);
259 The ``cookie`` parameter to the handler is reserved for future use and can be
260 ignored. The ``handle`` is returned by the SMC handler - completion of the
261 handler function must always be via one of the ``SMC_RETn()`` macros.
264 The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
265 all of the above requirements yet.
267 Services that contain multiple sub-services
268 -------------------------------------------
270 It is possible that a single owning entity implements multiple sub-services. For
271 example, the Standard calls service handles ``0x84000000``-``0x8400FFFF`` and
272 ``0xC4000000``-``0xC400FFFF`` functions. Within that range, the `PSCI`_ service
273 handles the ``0x84000000``-``0x8400001F`` and ``0xC4000000``-``0xC400001F`` functions.
274 In that respect, `PSCI`_ is a 'sub-service' of the Standard calls service. In
275 future, there could be additional such sub-services in the Standard calls
276 service which perform independent functions.
278 In this situation it may be valuable to introduce a second level framework to
279 enable independent implementation of sub-services. Such a framework might look
280 very similar to the current runtime services framework, but using a different
281 part of the SMC Function ID to identify the sub-service. TF-A does not provide
282 such a framework at present.
284 Secure-EL1 Payload Dispatcher service (SPD)
285 -------------------------------------------
287 Services that handle SMC Functions targeting a Trusted OS, Trusted Application,
288 or other Secure-EL1 Payload are special. These services need to manage the
289 Secure-EL1 context, provide the *Secure Monitor* functionality of switching
290 between the normal and secure worlds, deliver SMC Calls through to Secure-EL1
291 and generally manage the Secure-EL1 Payload through CPU power-state transitions.
293 TODO: Provide details of the additional work required to implement a SPD and
294 the BL31 support for these services. Or a reference to the document that will
295 provide this information....
299 *Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
301 .. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
302 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
303 .. _Firmware Design: ../design/firmware-design.rst
304 .. _services: ../../services
305 .. _lib/psci: ../../lib/psci
306 .. _runtime_svc.h: ../../include/common/runtime_svc.h
307 .. _smccc.h: ../../include/lib/smccc.h
308 .. _std_svc_setup.c: ../../services/std_svc/std_svc_setup.c