aboutsummaryrefslogtreecommitdiff
path: root/include/common
diff options
context:
space:
mode:
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>2018-04-23 15:43:29 +0100
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>2018-04-23 15:43:29 +0100
commit2f370465241c85b2fe38a1eb69b457b9fed97207 (patch)
tree64b0944fb740af46e58216feda67cf3fbc7cd1ae /include/common
parent7f6d8f49aa916a526c2ce227606cc51eebd0c950 (diff)
downloadtrusted-firmware-a-2f370465241c85b2fe38a1eb69b457b9fed97207.tar.gz
Add support for the SMC Calling Convention 2.0
Due to differences in the bitfields of the SMC IDs, it is not possible to support SMCCC 1.X and 2.0 at the same time. The behaviour of `SMCCC_MAJOR_VERSION` has changed. Now, it is a build option that specifies the major version of the SMCCC that the Trusted Firmware supports. The only two allowed values are 1 and 2, and it defaults to 1. The value of `SMCCC_MINOR_VERSION` is derived from it. Note: Support for SMCCC v2.0 is an experimental feature to enable prototyping of secure partition specifications. Support for this convention is disabled by default and could be removed without notice. Change-Id: I88abf9ccf08e9c66a13ce55c890edea54d9f16a7 Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'include/common')
-rw-r--r--include/common/runtime_svc.h96
1 files changed, 79 insertions, 17 deletions
diff --git a/include/common/runtime_svc.h b/include/common/runtime_svc.h
index 706c2118d0..b8cf8ded3e 100644
--- a/include/common/runtime_svc.h
+++ b/include/common/runtime_svc.h
@@ -8,8 +8,9 @@
#define __RUNTIME_SVC_H__
#include <bl_common.h> /* to include exception types */
+#include <cassert.h>
#include <smccc_helpers.h> /* to include SMCCC definitions */
-
+#include <utils_def.h>
/*******************************************************************************
* Structure definition, typedefs & constants for the runtime service framework
@@ -32,11 +33,20 @@
/*
- * The function identifier has 6 bits for the owning entity number and
- * single bit for the type of smc call. When taken together these
- * values limit the maximum number of runtime services to 128.
+ * In SMCCC 1.X, the function identifier has 6 bits for the owning entity number
+ * and a single bit for the type of smc call. When taken together, those values
+ * limit the maximum number of runtime services to 128.
+ *
+ * In SMCCC 2.X the type bit is always 1 and there are only 4 OEN bits in the
+ * compatibility namespace, so the total number of services is 16. The LSB of
+ * namespace is also added to these 4 bits to make space for the vendor service
+ * handler and so the total number of runtime services is 32.
*/
+#if SMCCC_MAJOR_VERSION == 1
#define MAX_RT_SVCS 128
+#elif SMCCC_MAJOR_VERSION == 2
+#define MAX_RT_SVCS 32
+#endif
#ifndef __ASSEMBLY__
@@ -60,24 +70,62 @@ typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
typedef struct rt_svc_desc {
uint8_t start_oen;
uint8_t end_oen;
+#if SMCCC_MAJOR_VERSION == 1
uint8_t call_type;
+#elif SMCCC_MAJOR_VERSION == 2
+ uint8_t is_vendor;
+#endif
const char *name;
rt_svc_init_t init;
rt_svc_handle_t handle;
} rt_svc_desc_t;
/*
- * Convenience macro to declare a service descriptor
+ * Convenience macros to declare a service descriptor
+ */
+#if SMCCC_MAJOR_VERSION == 1
+
+#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
+ static const rt_svc_desc_t __svc_desc_ ## _name \
+ __section("rt_svc_descs") __used = { \
+ .start_oen = _start, \
+ .end_oen = _end, \
+ .call_type = _type, \
+ .name = #_name, \
+ .init = _setup, \
+ .handle = _smch \
+ }
+
+#elif SMCCC_MAJOR_VERSION == 2
+
+#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
+ static const rt_svc_desc_t __svc_desc_ ## _name \
+ __section("rt_svc_descs") __used = { \
+ .start_oen = _start, \
+ .end_oen = _end, \
+ .is_vendor = 0, \
+ .name = #_name, \
+ .init = _setup, \
+ .handle = _smch, \
+ }; \
+ CASSERT((_type) == SMC_TYPE_FAST, rt_svc_type_check_ ## _name)
+
+/*
+ * The higher 16 entries of the runtime services are used for the vendor
+ * specific descriptor.
*/
-#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
- static const rt_svc_desc_t __svc_desc_ ## _name \
- __section("rt_svc_descs") __used = { \
- .start_oen = _start, \
- .end_oen = _end, \
- .call_type = _type, \
- .name = #_name, \
- .init = _setup, \
- .handle = _smch }
+#define DECLARE_RT_SVC_VENDOR(_setup, _smch) \
+ static const rt_svc_desc_t __svc_desc_vendor \
+ __section("rt_svc_descs") __used = { \
+ .start_oen = 0, \
+ .end_oen = 15, \
+ .is_vendor = 1, \
+ .name = "vendor_rt_svc", \
+ .init = _setup, \
+ .handle = _smch, \
+ }
+
+#endif /* SMCCC_MAJOR_VERSION */
/*
* Compile time assertions related to the 'rt_svc_desc' structure to:
@@ -96,6 +144,7 @@ CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
assert_rt_svc_desc_handle_offset_mismatch);
+#if SMCCC_MAJOR_VERSION == 1
/*
* This macro combines the call type and the owning entity number corresponding
* to a runtime service to generate a unique owning entity number. This unique
@@ -112,9 +161,22 @@ CASSERT(RT_SVC_DESC_HANDLE == __builtin_offsetof(rt_svc_desc_t, handle), \
* array to invoke the corresponding runtime service handler during SMC
* handling.
*/
-#define get_unique_oen_from_smc_fid(fid) \
- get_unique_oen(((fid) >> FUNCID_OEN_SHIFT), \
- ((fid) >> FUNCID_TYPE_SHIFT))
+#define get_unique_oen_from_smc_fid(fid) \
+ get_unique_oen(GET_SMC_OEN(fid), GET_SMC_TYPE(fid))
+
+#elif SMCCC_MAJOR_VERSION == 2
+
+/*
+ * This macro combines the owning entity number corresponding to a runtime
+ * service with one extra bit for the vendor namespace to generate an index into
+ * the 'rt_svc_descs_indices' array. The entry contains the index of the service
+ * descriptor in the 'rt_svc_descs' array.
+ */
+#define get_rt_desc_idx(oen, is_vendor) \
+ (((uint32_t)(oen) & FUNCID_OEN_MASK) | \
+ (((uint32_t)(is_vendor) & 1U) << FUNCID_OEN_WIDTH))
+
+#endif
/*******************************************************************************
* Function & variable prototypes