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