xref: /rk3399_ARM-atf/docs/getting_started/rt-svc-writers-guide.rst (revision be5b1e22346c6d8ce4b0c56604c99f7a9d3676cc)
18aa05055SPaul BeesleyEL3 Runtime Service Writer's Guide
240d553cfSPaul Beesley=====================================================
340d553cfSPaul Beesley
440d553cfSPaul BeesleyIntroduction
540d553cfSPaul Beesley------------
640d553cfSPaul Beesley
740d553cfSPaul BeesleyThis document describes how to add a runtime service to the EL3 Runtime
840d553cfSPaul BeesleyFirmware component of Trusted Firmware-A (TF-A), BL31.
940d553cfSPaul Beesley
1040d553cfSPaul BeesleySoftware executing in the normal world and in the trusted world at exception
1140d553cfSPaul Beesleylevels lower than EL3 will request runtime services using the Secure Monitor
1240d553cfSPaul BeesleyCall (SMC) instruction. These requests will follow the convention described in
1340d553cfSPaul Beesleythe SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function
1440d553cfSPaul Beesleyidentifiers to each SMC request and describes how arguments are passed and
1540d553cfSPaul Beesleyresults are returned.
1640d553cfSPaul Beesley
1740d553cfSPaul BeesleySMC Functions are grouped together based on the implementor of the service, for
1840d553cfSPaul Beesleyexample a subset of the Function IDs are designated as "OEM Calls" (see `SMCCC`_
1940d553cfSPaul Beesleyfor full details). The EL3 runtime services framework in BL31 enables the
2040d553cfSPaul Beesleyindependent implementation of services for each group, which are then compiled
2140d553cfSPaul Beesleyinto the BL31 image. This simplifies the integration of common software from
2240d553cfSPaul BeesleyArm to support `PSCI`_, Secure Monitor for a Trusted OS and SoC specific
2340d553cfSPaul Beesleysoftware. The common runtime services framework ensures that SMC Functions are
2434760951SPaul Beesleydispatched to their respective service implementation - the
2534760951SPaul Beesley:ref:`Firmware Design` document provides details of how this is achieved.
2640d553cfSPaul Beesley
2740d553cfSPaul BeesleyThe interface and operation of the runtime services depends heavily on the
2840d553cfSPaul Beesleyconcepts and definitions described in the `SMCCC`_, in particular SMC Function
2940d553cfSPaul BeesleyIDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and
3040d553cfSPaul BeesleySMC64 calling conventions. Please refer to that document for a full explanation
3140d553cfSPaul Beesleyof these terms.
3240d553cfSPaul Beesley
3340d553cfSPaul BeesleyOwning Entities, Call Types and Function IDs
3440d553cfSPaul Beesley--------------------------------------------
3540d553cfSPaul Beesley
3640d553cfSPaul BeesleyThe SMC Function Identifier includes a OEN field. These values and their
3740d553cfSPaul Beesleymeaning are described in `SMCCC`_ and summarized in table 1 below. Some entities
3840d553cfSPaul Beesleyare allocated a range of of OENs. The OEN must be interpreted in conjunction
3940d553cfSPaul Beesleywith the SMC call type, which is either *Fast* or *Yielding*. Fast calls are
4040d553cfSPaul Beesleyuninterruptible whereas Yielding calls can be pre-empted. The majority of
4140d553cfSPaul BeesleyOwning Entities only have allocated ranges for Fast calls: Yielding calls are
4240d553cfSPaul Beesleyreserved exclusively for Trusted OS providers or for interoperability with
4340d553cfSPaul Beesleylegacy 32-bit software that predates the `SMCCC`_.
4440d553cfSPaul Beesley
4540d553cfSPaul Beesley::
4640d553cfSPaul Beesley
4740d553cfSPaul Beesley    Type       OEN     Service
4840d553cfSPaul Beesley    Fast        0      Arm Architecture calls
4940d553cfSPaul Beesley    Fast        1      CPU Service calls
5040d553cfSPaul Beesley    Fast        2      SiP Service calls
5140d553cfSPaul Beesley    Fast        3      OEM Service calls
52*be5b1e22SGovindraj Raja    Fast        4      Standard Secure Service calls
53*be5b1e22SGovindraj Raja    Fast        5      Standard Hypervisor Service Calls
54*be5b1e22SGovindraj Raja    Fast        6      Vendor Specific Hypervisor Service Calls
55*be5b1e22SGovindraj Raja    Fast        7      Vendor Specific EL3 Monitor Calls
56*be5b1e22SGovindraj Raja    Fast       8-47    Reserved for future use
5740d553cfSPaul Beesley    Fast      48-49    Trusted Application calls
5840d553cfSPaul Beesley    Fast      50-63    Trusted OS calls
5940d553cfSPaul Beesley
6040d553cfSPaul Beesley    Yielding   0- 1    Reserved for existing Armv7-A calls
6140d553cfSPaul Beesley    Yielding   2-63    Trusted OS Standard Calls
6240d553cfSPaul Beesley
6340d553cfSPaul Beesley*Table 1: Service types and their corresponding Owning Entity Numbers*
6440d553cfSPaul Beesley
6540d553cfSPaul BeesleyEach individual entity can allocate the valid identifiers within the entity
6640d553cfSPaul Beesleyrange as they need - it is not necessary to coordinate with other entities of
6740d553cfSPaul Beesleythe same type. For example, two SoC providers can use the same Function ID
6840d553cfSPaul Beesleywithin the SiP Service calls OEN range to mean different things - as these
6940d553cfSPaul Beesleycalls should be specific to the SoC. The Standard Runtime Calls OEN is used for
7040d553cfSPaul Beesleyservices defined by Arm standards, such as `PSCI`_.
7140d553cfSPaul Beesley
7240d553cfSPaul BeesleyThe SMC Function ID also indicates whether the call has followed the SMC32
7340d553cfSPaul Beesleycalling convention, where all parameters are 32-bit, or the SMC64 calling
7440d553cfSPaul Beesleyconvention, where the parameters are 64-bit. The framework identifies and
7540d553cfSPaul Beesleyrejects invalid calls that use the SMC64 calling convention but that originate
7640d553cfSPaul Beesleyfrom an AArch32 caller.
7740d553cfSPaul Beesley
7840d553cfSPaul BeesleyThe EL3 runtime services framework uses the call type and OEN to identify a
7940d553cfSPaul Beesleyspecific handler for each SMC call, but it is expected that an individual
8040d553cfSPaul Beesleyhandler will be responsible for all SMC Functions within a given service type.
8140d553cfSPaul Beesley
8240d553cfSPaul BeesleyGetting started
8340d553cfSPaul Beesley---------------
8440d553cfSPaul Beesley
8534760951SPaul BeesleyTF-A has a ``services`` directory in the source tree under which
8640d553cfSPaul Beesleyeach owning entity can place the implementation of its runtime service. The
8734760951SPaul Beesley`PSCI`_ implementation is located here in the ``lib/psci`` directory.
8840d553cfSPaul Beesley
8934760951SPaul BeesleyRuntime service sources will need to include the ``runtime_svc.h`` header file.
9040d553cfSPaul Beesley
9140d553cfSPaul BeesleyRegistering a runtime service
9240d553cfSPaul Beesley-----------------------------
9340d553cfSPaul Beesley
9440d553cfSPaul BeesleyA runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
9540d553cfSPaul Beesleythe name of the service, the range of OENs covered, the type of service and
9640d553cfSPaul Beesleyinitialization and call handler functions.
9740d553cfSPaul Beesley
9829c02529SPaul Beesley.. code:: c
9940d553cfSPaul Beesley
10040d553cfSPaul Beesley    #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
10140d553cfSPaul Beesley
10240d553cfSPaul Beesley-  ``_name`` is used to identify the data structure declared by this macro, and
10340d553cfSPaul Beesley   is also used for diagnostic purposes
10440d553cfSPaul Beesley
10540d553cfSPaul Beesley-  ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in
10634760951SPaul Beesley   ``smccc.h``
10740d553cfSPaul Beesley
10840d553cfSPaul Beesley-  ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
10940d553cfSPaul Beesley
11040d553cfSPaul Beesley-  ``_setup`` is the initialization function with the ``rt_svc_init`` signature:
11140d553cfSPaul Beesley
11240d553cfSPaul Beesley   .. code:: c
11340d553cfSPaul Beesley
11440d553cfSPaul Beesley       typedef int32_t (*rt_svc_init)(void);
11540d553cfSPaul Beesley
11640d553cfSPaul Beesley-  ``_smch`` is the SMC handler function with the ``rt_svc_handle`` signature:
11740d553cfSPaul Beesley
11840d553cfSPaul Beesley   .. code:: c
11940d553cfSPaul Beesley
12040d553cfSPaul Beesley       typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
12140d553cfSPaul Beesley                                         u_register_t x1, u_register_t x2,
12240d553cfSPaul Beesley                                         u_register_t x3, u_register_t x4,
12340d553cfSPaul Beesley                                         void *cookie,
12440d553cfSPaul Beesley                                         void *handle,
12540d553cfSPaul Beesley                                         u_register_t flags);
12640d553cfSPaul Beesley
12740d553cfSPaul BeesleyDetails of the requirements and behavior of the two callbacks is provided in
12840d553cfSPaul Beesleythe following sections.
12940d553cfSPaul Beesley
13040d553cfSPaul BeesleyDuring initialization the services framework validates each declared service
13140d553cfSPaul Beesleyto ensure that the following conditions are met:
13240d553cfSPaul Beesley
13340d553cfSPaul Beesley#. The ``_start`` OEN is not greater than the ``_end`` OEN
13440d553cfSPaul Beesley#. The ``_end`` OEN does not exceed the maximum OEN value (63)
13540d553cfSPaul Beesley#. The ``_type`` is one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
13640d553cfSPaul Beesley#. ``_setup`` and ``_smch`` routines have been specified
13740d553cfSPaul Beesley
13834760951SPaul Beesley``std_svc_setup.c`` provides an example of registering a runtime service:
13940d553cfSPaul Beesley
14040d553cfSPaul Beesley.. code:: c
14140d553cfSPaul Beesley
14240d553cfSPaul Beesley    /* Register Standard Service Calls as runtime service */
14340d553cfSPaul Beesley    DECLARE_RT_SVC(
14440d553cfSPaul Beesley            std_svc,
14540d553cfSPaul Beesley            OEN_STD_START,
14640d553cfSPaul Beesley            OEN_STD_END,
14740d553cfSPaul Beesley            SMC_TYPE_FAST,
14840d553cfSPaul Beesley            std_svc_setup,
14940d553cfSPaul Beesley            std_svc_smc_handler
15040d553cfSPaul Beesley    );
15140d553cfSPaul Beesley
15240d553cfSPaul BeesleyInitializing a runtime service
15340d553cfSPaul Beesley------------------------------
15440d553cfSPaul Beesley
15540d553cfSPaul BeesleyRuntime services are initialized once, during cold boot, by the primary CPU
15640d553cfSPaul Beesleyafter platform and architectural initialization is complete. The framework
15740d553cfSPaul Beesleyperforms basic validation of the declared service before calling
15840d553cfSPaul Beesleythe service initialization function (``_setup`` in the declaration). This
15940d553cfSPaul Beesleyfunction must carry out any essential EL3 initialization prior to receiving a
16040d553cfSPaul BeesleySMC Function call via the handler function.
16140d553cfSPaul Beesley
16240d553cfSPaul BeesleyOn success, the initialization function must return ``0``. Any other return value
16340d553cfSPaul Beesleywill cause the framework to issue a diagnostic:
16440d553cfSPaul Beesley
16540d553cfSPaul Beesley::
16640d553cfSPaul Beesley
16740d553cfSPaul Beesley    Error initializing runtime service <name of the service>
16840d553cfSPaul Beesley
16940d553cfSPaul Beesleyand then ignore the service - the system will continue to boot but SMC calls
17040d553cfSPaul Beesleywill not be passed to the service handler and instead return the *Unknown SMC
17140d553cfSPaul BeesleyFunction ID* result ``0xFFFFFFFF``.
17240d553cfSPaul Beesley
17340d553cfSPaul BeesleyIf the system must not be allowed to proceed without the service, the
17440d553cfSPaul Beesleyinitialization function must itself cause the firmware boot to be halted.
17540d553cfSPaul Beesley
17640d553cfSPaul BeesleyIf the service uses per-CPU data this must either be initialized for all CPUs
17740d553cfSPaul Beesleyduring this call, or be done lazily when a CPU first issues an SMC call to that
17840d553cfSPaul Beesleyservice.
17940d553cfSPaul Beesley
18040d553cfSPaul BeesleyHandling runtime service requests
18140d553cfSPaul Beesley---------------------------------
18240d553cfSPaul Beesley
18340d553cfSPaul BeesleySMC calls for a service are forwarded by the framework to the service's SMC
18440d553cfSPaul Beesleyhandler function (``_smch`` in the service declaration). This function must have
18540d553cfSPaul Beesleythe following signature:
18640d553cfSPaul Beesley
18740d553cfSPaul Beesley.. code:: c
18840d553cfSPaul Beesley
18940d553cfSPaul Beesley    typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
19040d553cfSPaul Beesley                                       u_register_t x1, u_register_t x2,
19140d553cfSPaul Beesley                                       u_register_t x3, u_register_t x4,
19240d553cfSPaul Beesley                                       void *cookie,
19340d553cfSPaul Beesley                                       void *handle,
19440d553cfSPaul Beesley                                       u_register_t flags);
19540d553cfSPaul Beesley
19640d553cfSPaul BeesleyThe handler is responsible for:
19740d553cfSPaul Beesley
19840d553cfSPaul Beesley#. Determining that ``smc_fid`` is a valid and supported SMC Function ID,
19940d553cfSPaul Beesley   otherwise completing the request with the *Unknown SMC Function ID*:
20040d553cfSPaul Beesley
20140d553cfSPaul Beesley   .. code:: c
20240d553cfSPaul Beesley
20340d553cfSPaul Beesley       SMC_RET1(handle, SMC_UNK);
20440d553cfSPaul Beesley
20540d553cfSPaul Beesley#. Determining if the requested function is valid for the calling security
2067446c266SZelalem Aweke   state. SMC Calls can be made from Non-secure, Secure or Realm worlds and
20740d553cfSPaul Beesley   the framework will forward all calls to the service handler.
20840d553cfSPaul Beesley
20940d553cfSPaul Beesley   The ``flags`` parameter to this function indicates the caller security state
2107446c266SZelalem Aweke   in bits 0 and 5. The ``is_caller_secure(flags)``, ``is_caller_non_secure(flags)``
2117446c266SZelalem Aweke   and ``is_caller_realm(flags)`` helper functions can be used to determine whether
2127446c266SZelalem Aweke   the caller's security state is Secure, Non-secure or Realm respectively.
21340d553cfSPaul Beesley
21440d553cfSPaul Beesley   If invalid, the request should be completed with:
21540d553cfSPaul Beesley
21640d553cfSPaul Beesley   .. code:: c
21740d553cfSPaul Beesley
21840d553cfSPaul Beesley       SMC_RET1(handle, SMC_UNK);
21940d553cfSPaul Beesley
22040d553cfSPaul Beesley#. Truncating parameters for calls made using the SMC32 calling convention.
22140d553cfSPaul Beesley   Such calls can be determined by checking the CC field in bit[30] of the
22240d553cfSPaul Beesley   ``smc_fid`` parameter, for example by using:
22340d553cfSPaul Beesley
22440d553cfSPaul Beesley   ::
22540d553cfSPaul Beesley
22640d553cfSPaul Beesley       if (GET_SMC_CC(smc_fid) == SMC_32) ...
22740d553cfSPaul Beesley
22840d553cfSPaul Beesley   For such calls, the upper bits of the parameters x1-x4 and the saved
22940d553cfSPaul Beesley   parameters X5-X7 are UNDEFINED and must be explicitly ignored by the
23040d553cfSPaul Beesley   handler. This can be done by truncating the values to a suitable 32-bit
23140d553cfSPaul Beesley   integer type before use, for example by ensuring that functions defined
23240d553cfSPaul Beesley   to handle individual SMC Functions use appropriate 32-bit parameters.
23340d553cfSPaul Beesley
23440d553cfSPaul Beesley#. Providing the service requested by the SMC Function, utilizing the
23540d553cfSPaul Beesley   immediate parameters x1-x4 and/or the additional saved parameters X5-X7.
23640d553cfSPaul Beesley   The latter can be retrieved using the ``SMC_GET_GP(handle, ref)`` function,
23740d553cfSPaul Beesley   supplying the appropriate ``CTX_GPREG_Xn`` reference, e.g.
23840d553cfSPaul Beesley
23940d553cfSPaul Beesley   .. code:: c
24040d553cfSPaul Beesley
24140d553cfSPaul Beesley       uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
24240d553cfSPaul Beesley
24340d553cfSPaul Beesley#. Implementing the standard SMC32 Functions that provide information about
24440d553cfSPaul Beesley   the implementation of the service. These are the Call Count, Implementor
24540d553cfSPaul Beesley   UID and Revision Details for each service documented in section 6 of the
24640d553cfSPaul Beesley   `SMCCC`_.
24740d553cfSPaul Beesley
24840d553cfSPaul Beesley   TF-A expects owning entities to follow this recommendation.
24940d553cfSPaul Beesley
250e34cc0ceSMadhukar Pappireddy#. Returning the result to the caller. Based on `SMCCC`_ spec, results are
251e34cc0ceSMadhukar Pappireddy   returned in W0-W7(X0-X7) registers for SMC32(SMC64) calls from AArch64
252e34cc0ceSMadhukar Pappireddy   state. Results are returned in R0-R7 registers for SMC32 calls from AArch32
253e34cc0ceSMadhukar Pappireddy   state. The framework provides a family of macros to set the multi-register
254e34cc0ceSMadhukar Pappireddy   return value and complete the handler:
25540d553cfSPaul Beesley
25640d553cfSPaul Beesley   .. code:: c
25740d553cfSPaul Beesley
258e34cc0ceSMadhukar Pappireddy       AArch64 state:
259e34cc0ceSMadhukar Pappireddy
26040d553cfSPaul Beesley       SMC_RET1(handle, x0);
26140d553cfSPaul Beesley       SMC_RET2(handle, x0, x1);
26240d553cfSPaul Beesley       SMC_RET3(handle, x0, x1, x2);
26340d553cfSPaul Beesley       SMC_RET4(handle, x0, x1, x2, x3);
264e34cc0ceSMadhukar Pappireddy       SMC_RET5(handle, x0, x1, x2, x3, x4);
265e34cc0ceSMadhukar Pappireddy       SMC_RET6(handle, x0, x1, x2, x3, x4, x5);
266e34cc0ceSMadhukar Pappireddy       SMC_RET7(handle, x0, x1, x2, x3, x4, x5, x6);
267e34cc0ceSMadhukar Pappireddy       SMC_RET8(handle, x0, x1, x2, x3, x4, x5, x6, x7);
268e34cc0ceSMadhukar Pappireddy
269e34cc0ceSMadhukar Pappireddy       AArch32 state:
270e34cc0ceSMadhukar Pappireddy
271e34cc0ceSMadhukar Pappireddy       SMC_RET1(handle, r0);
272e34cc0ceSMadhukar Pappireddy       SMC_RET2(handle, r0, r1);
273e34cc0ceSMadhukar Pappireddy       SMC_RET3(handle, r0, r1, r2);
274e34cc0ceSMadhukar Pappireddy       SMC_RET4(handle, r0, r1, r2, r3);
275e34cc0ceSMadhukar Pappireddy       SMC_RET5(handle, r0, r1, r2, r3, r4);
276e34cc0ceSMadhukar Pappireddy       SMC_RET6(handle, r0, r1, r2, r3, r4, r5);
277e34cc0ceSMadhukar Pappireddy       SMC_RET7(handle, r0, r1, r2, r3, r4, r5, r6);
278e34cc0ceSMadhukar Pappireddy       SMC_RET8(handle, r0, r1, r2, r3, r4, r5, r6, r7);
27940d553cfSPaul Beesley
28040d553cfSPaul BeesleyThe ``cookie`` parameter to the handler is reserved for future use and can be
28140d553cfSPaul Beesleyignored. The ``handle`` is returned by the SMC handler - completion of the
28240d553cfSPaul Beesleyhandler function must always be via one of the ``SMC_RETn()`` macros.
28340d553cfSPaul Beesley
284e1c5026aSPaul Beesley.. note::
285e1c5026aSPaul Beesley   The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
28640d553cfSPaul Beesley   all of the above requirements yet.
28740d553cfSPaul Beesley
28840d553cfSPaul BeesleyServices that contain multiple sub-services
28940d553cfSPaul Beesley-------------------------------------------
29040d553cfSPaul Beesley
29140d553cfSPaul BeesleyIt is possible that a single owning entity implements multiple sub-services. For
29240d553cfSPaul Beesleyexample, the Standard calls service handles ``0x84000000``-``0x8400FFFF`` and
29340d553cfSPaul Beesley``0xC4000000``-``0xC400FFFF`` functions. Within that range, the `PSCI`_ service
29440d553cfSPaul Beesleyhandles the ``0x84000000``-``0x8400001F`` and ``0xC4000000``-``0xC400001F`` functions.
29540d553cfSPaul BeesleyIn that respect, `PSCI`_ is a 'sub-service' of the Standard calls service. In
29640d553cfSPaul Beesleyfuture, there could be additional such sub-services in the Standard calls
29740d553cfSPaul Beesleyservice which perform independent functions.
29840d553cfSPaul Beesley
29940d553cfSPaul BeesleyIn this situation it may be valuable to introduce a second level framework to
30040d553cfSPaul Beesleyenable independent implementation of sub-services. Such a framework might look
30140d553cfSPaul Beesleyvery similar to the current runtime services framework, but using a different
30240d553cfSPaul Beesleypart of the SMC Function ID to identify the sub-service. TF-A does not provide
30340d553cfSPaul Beesleysuch a framework at present.
30440d553cfSPaul Beesley
30540d553cfSPaul BeesleySecure-EL1 Payload Dispatcher service (SPD)
30640d553cfSPaul Beesley-------------------------------------------
30740d553cfSPaul Beesley
30840d553cfSPaul BeesleyServices that handle SMC Functions targeting a Trusted OS, Trusted Application,
30940d553cfSPaul Beesleyor other Secure-EL1 Payload are special. These services need to manage the
31040d553cfSPaul BeesleySecure-EL1 context, provide the *Secure Monitor* functionality of switching
31140d553cfSPaul Beesleybetween the normal and secure worlds, deliver SMC Calls through to Secure-EL1
31240d553cfSPaul Beesleyand generally manage the Secure-EL1 Payload through CPU power-state transitions.
31340d553cfSPaul Beesley
31440d553cfSPaul BeesleyTODO: Provide details of the additional work required to implement a SPD and
31540d553cfSPaul Beesleythe BL31 support for these services. Or a reference to the document that will
31640d553cfSPaul Beesleyprovide this information....
31740d553cfSPaul Beesley
31840d553cfSPaul Beesley--------------
31940d553cfSPaul Beesley
320*be5b1e22SGovindraj Raja*Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.*
32140d553cfSPaul Beesley
3223ba55a3cSlaurenw-arm.. _SMCCC: https://developer.arm.com/docs/den0028/latest
3233be6b4fbSManish V Badarkhe.. _PSCI: https://developer.arm.com/documentation/den0022/latest/
324