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