Add support for the SMC Calling Convention 2.0
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Mon, 23 Apr 2018 14:43:29 +0000 (15:43 +0100)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Mon, 23 Apr 2018 14:43:29 +0000 (15:43 +0100)
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>
Makefile
bl31/aarch64/runtime_exceptions.S
common/runtime_svc.c
docs/user-guide.rst
include/common/runtime_svc.h
include/lib/smccc.h
include/lib/smccc_v1.h [new file with mode: 0644]
include/lib/smccc_v2.h [new file with mode: 0644]
make_helpers/defaults.mk

index a8378462bf81b62362302fa94448d6d728632bf0..b270e1508247be31865a04fb19f1f18f60feece4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -378,6 +378,16 @@ ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1)
 $(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
 endif
 
+# SMC Calling Convention checks
+ifneq (${SMCCC_MAJOR_VERSION},1)
+    ifneq (${SPD},none)
+        $(error "SMC Calling Convention 1.X must be used with SPDs")
+    endif
+    ifeq (${ARCH},aarch32)
+        $(error "Only SMCCC 1.X is supported in AArch32 mode.")
+    endif
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -527,6 +537,7 @@ $(eval $(call assert_boolean,BL2_IN_XIP_MEM))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
+$(eval $(call assert_numeric,SMCCC_MAJOR_VERSION))
 
 ################################################################################
 # Add definitions to the cpp preprocessor based on the current build options.
@@ -563,6 +574,7 @@ $(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS))
 $(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
 $(eval $(call add_define,RESET_TO_BL31))
 $(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
+$(eval $(call add_define,SMCCC_MAJOR_VERSION))
 $(eval $(call add_define,SPD_${SPD}))
 $(eval $(call add_define,SPIN_ON_BL1_EXIT))
 $(eval $(call add_define,TRUSTED_BOARD_BOOT))
index 60be932745161cfb0c5dd4786884c6d4acf93250..1c3ed3f338fedc85457dc140b1ee7921402a0683 100644 (file)
@@ -11,6 +11,7 @@
 #include <interrupt_mgmt.h>
 #include <platform_def.h>
 #include <runtime_svc.h>
+#include <smccc.h>
 
        .globl  runtime_exceptions
 
@@ -288,6 +289,37 @@ vector_entry serror_aarch32
        check_vector_size serror_aarch32
 
 
+       /* ---------------------------------------------------------------------
+        * This macro takes an argument in x16 that is the index in the
+        * 'rt_svc_descs_indices' array, checks that the value in the array is
+        * valid, and loads in x15 the pointer to the handler of that service.
+        * ---------------------------------------------------------------------
+        */
+       .macro  load_rt_svc_desc_pointer
+       /* Load descriptor index from array of indices */
+       adr     x14, rt_svc_descs_indices
+       ldrb    w15, [x14, x16]
+
+#if SMCCC_MAJOR_VERSION == 1
+       /* Any index greater than 127 is invalid. Check bit 7. */
+       tbnz    w15, 7, smc_unknown
+#elif SMCCC_MAJOR_VERSION == 2
+       /* Verify that the top 3 bits of the loaded index are 0 (w15 <= 31) */
+       cmp     w15, #31
+       b.hi    smc_unknown
+#endif /* SMCCC_MAJOR_VERSION */
+
+       /*
+        * Get the descriptor using the index
+        * x11 = (base + off), w15 = index
+        *
+        * handler = (base + off) + (index << log2(size))
+        */
+       adr     x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+       lsl     w10, w15, #RT_SVC_SIZE_LOG2
+       ldr     x15, [x11, w10, uxtw]
+       .endm
+
        /* ---------------------------------------------------------------------
         * The following code handles secure monitor calls.
         * Depending upon the execution state from where the SMC has been
@@ -311,48 +343,63 @@ smc_handler64:
         * now). x6 will point to the context structure (SP_EL3) and x7 will
         * contain flags we need to pass to the handler.
         *
-        * Save x4-x29 and sp_el0.  Refer to SMCCC v1.1.
+        * Save x4-x29 and sp_el0.
         */
        save_x4_to_x29_sp_el0
 
        mov     x5, xzr
        mov     x6, sp
 
+#if SMCCC_MAJOR_VERSION == 1
+
        /* Get the unique owning entity number */
        ubfx    x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
        ubfx    x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
        orr     x16, x16, x15, lsl #FUNCID_OEN_WIDTH
 
-       adr     x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+       load_rt_svc_desc_pointer
 
-       /* Load descriptor index from array of indices */
-       adr     x14, rt_svc_descs_indices
-       ldrb    w15, [x14, x16]
+#elif SMCCC_MAJOR_VERSION == 2
+
+       /* Bit 31 must be set */
+       tbz     x0, #FUNCID_TYPE_SHIFT, smc_unknown
 
        /*
-        * Restore the saved C runtime stack value which will become the new
-        * SP_EL0 i.e. EL3 runtime stack. It was saved in the 'cpu_context'
-        * structure prior to the last ERET from EL3.
+        * Check MSB of namespace to decide between compatibility/vendor and
+        * SPCI/SPRT
         */
-       ldr     x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+       tbz     x0, #(FUNCID_NAMESPACE_SHIFT + 1), compat_or_vendor
+
+       /* Namespaces SPRT and SPCI currently unimplemented */
+       b       smc_unknown
+
+compat_or_vendor:
+
+       /* Namespace is b'00 (compatibility) or b'01 (vendor) */
 
        /*
-        * Any index greater than 127 is invalid. Check bit 7 for
-        * a valid index
+        * Add the LSB of the namespace (bit [28]) to the OEN [27:24] to create
+        * a 5-bit index into the rt_svc_descs_indices array.
+        *
+        * The low 16 entries of the rt_svc_descs_indices array correspond to
+        * OENs of the compatibility namespace and the top 16 entries of the
+        * array are assigned to the vendor namespace descriptor.
         */
-       tbnz    w15, 7, smc_unknown
+       ubfx    x16, x0, #FUNCID_OEN_SHIFT, #(FUNCID_OEN_WIDTH + 1)
 
-       /* Switch to SP_EL0 */
-       msr     spsel, #0
+       load_rt_svc_desc_pointer
+
+#endif /* SMCCC_MAJOR_VERSION */
 
        /*
-        * Get the descriptor using the index
-        * x11 = (base + off), x15 = index
-        *
-        * handler = (base + off) + (index << log2(size))
+        * Restore the saved C runtime stack value which will become the new
+        * SP_EL0 i.e. EL3 runtime stack. It was saved in the 'cpu_context'
+        * structure prior to the last ERET from EL3.
         */
-       lsl     w10, w15, #RT_SVC_SIZE_LOG2
-       ldr     x15, [x11, w10, uxtw]
+       ldr     x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+
+       /* Switch to SP_EL0 */
+       msr     spsel, #0
 
        /*
         * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world
index de80f30c26b52bd86fc1a1eff7f01f24c7f448f5..f997c74a0444363e54ff51e9e3d502bff9277d8a 100644 (file)
@@ -26,8 +26,10 @@ static rt_svc_desc_t *rt_svc_descs;
                                        / sizeof(rt_svc_desc_t))
 
 /*******************************************************************************
- * Function to invoke the registered `handle` corresponding to the smc_fid.
+ * Function to invoke the registered `handle` corresponding to the smc_fid in
+ * AArch32 mode.
  ******************************************************************************/
+#if SMCCC_MAJOR_VERSION == 1
 uintptr_t handle_runtime_svc(uint32_t smc_fid,
                             void *cookie,
                             void *handle,
@@ -53,6 +55,7 @@ uintptr_t handle_runtime_svc(uint32_t smc_fid,
        return rt_svc_descs[index].handle(smc_fid, x1, x2, x3, x4, cookie,
                                                handle, flags);
 }
+#endif /* SMCCC_MAJOR_VERSION */
 
 /*******************************************************************************
  * Simple routine to sanity check a runtime service descriptor before using it
@@ -68,12 +71,17 @@ static int32_t validate_rt_svc_desc(const rt_svc_desc_t *desc)
        if (desc->end_oen >= OEN_LIMIT)
                return -EINVAL;
 
-       if (desc->call_type != SMC_TYPE_FAST &&
-                       desc->call_type != SMC_TYPE_YIELD)
+#if SMCCC_MAJOR_VERSION == 1
+       if ((desc->call_type != SMC_TYPE_FAST) &&
+           (desc->call_type != SMC_TYPE_YIELD))
                return -EINVAL;
+#elif SMCCC_MAJOR_VERSION == 2
+       if (desc->is_vendor > 1U)
+               return -EINVAL;
+#endif /* SMCCC_MAJOR_VERSION */
 
        /* A runtime service having no init or handle function doesn't make sense */
-       if (desc->init == NULL && desc->handle == NULL)
+       if ((desc->init == NULL) && (desc->handle == NULL))
                return -EINVAL;
 
        return 0;
@@ -96,7 +104,7 @@ void runtime_svc_init(void)
                        (RT_SVC_DECS_NUM < MAX_RT_SVCS));
 
        /* If no runtime services are implemented then simply bail out */
-       if (RT_SVC_DECS_NUM == 0)
+       if (RT_SVC_DECS_NUM == 0U)
                return;
 
        /* Initialise internal variables to invalid state */
@@ -140,11 +148,18 @@ void runtime_svc_init(void)
                 * descriptor which will handle the SMCs for this owning
                 * entity range.
                 */
-               start_idx = get_unique_oen(rt_svc_descs[index].start_oen,
-                               service->call_type);
-               assert(start_idx < MAX_RT_SVCS);
-               end_idx = get_unique_oen(rt_svc_descs[index].end_oen,
-                               service->call_type);
+#if SMCCC_MAJOR_VERSION == 1
+               start_idx = get_unique_oen(service->start_oen,
+                                          service->call_type);
+               end_idx = get_unique_oen(service->end_oen,
+                                        service->call_type);
+#elif SMCCC_MAJOR_VERSION == 2
+               start_idx = get_rt_desc_idx(service->start_oen,
+                                           service->is_vendor);
+               end_idx = get_rt_desc_idx(service->end_oen,
+                                         service->is_vendor);
+#endif
+               assert(start_idx <= end_idx);
                assert(end_idx < MAX_RT_SVCS);
                for (; start_idx <= end_idx; start_idx++)
                        rt_svc_descs_indices[start_idx] = index;
index f8bc4be50f12d2a3c7c1efcb2c80a828b9399f7a..aed54a63152660cd08ca703c5fc4da01fa2d63b5 100644 (file)
@@ -573,6 +573,11 @@ Common build options
    pages" section in `Firmware Design`_. This flag is disabled by default and
    affects all BL images.
 
+-  ``SMCCC_MAJOR_VERSION``: Numeric value that indicates the major version of
+   the SMC Calling Convention that the Trusted Firmware supports. The only two
+   allowed values are 1 and 2, and it defaults to 1. The minor version is
+   determined using this value.
+
 -  ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
    This build option is only valid if ``ARCH=aarch64``. The value should be
    the path to the directory containing the SPD source, relative to
index 706c2118d00b3fde16ba239515274009cedff129..b8cf8ded3ebcdaf92883cadb1696b3d8edf378b5 100644 (file)
@@ -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
 
 
 /*
- * 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
index b1d4dea8692a2016aa0c2ffaef807afa2ef4e64a..1e7af6ab8e10aa5db6c2693663eb560205a89cba 100644 (file)
@@ -9,83 +9,41 @@
 
 #include <utils_def.h>
 
-/*******************************************************************************
- * Bit definitions inside the function id as per the SMC calling convention
- ******************************************************************************/
-#define FUNCID_TYPE_SHIFT              U(31)
-#define FUNCID_CC_SHIFT                        U(30)
-#define FUNCID_OEN_SHIFT               U(24)
-#define FUNCID_NUM_SHIFT               U(0)
-
-#define FUNCID_TYPE_MASK               U(0x1)
-#define FUNCID_CC_MASK                 U(0x1)
-#define FUNCID_OEN_MASK                        U(0x3f)
-#define FUNCID_NUM_MASK                        U(0xffff)
-
-#define FUNCID_TYPE_WIDTH              U(1)
-#define FUNCID_CC_WIDTH                        U(1)
-#define FUNCID_OEN_WIDTH               U(6)
-#define FUNCID_NUM_WIDTH               U(16)
-
-#define GET_SMC_CC(id)                 ((id >> FUNCID_CC_SHIFT) & \
-                                        FUNCID_CC_MASK)
-#define GET_SMC_TYPE(id)               ((id >> FUNCID_TYPE_SHIFT) & \
-                                        FUNCID_TYPE_MASK)
-
-#define SMC_64                         U(1)
-#define SMC_32                         U(0)
-#define SMC_OK                         U(0)
-#define SMC_UNK                                -1
-#define SMC_TYPE_FAST                  ULL(1)
-#if !ERROR_DEPRECATED
-#define SMC_TYPE_STD                   ULL(0)
+#define SMCCC_VERSION_MAJOR_SHIFT      U(16)
+#define SMCCC_VERSION_MAJOR_MASK       U(0x7FFF)
+#define SMCCC_VERSION_MINOR_SHIFT      U(0)
+#define SMCCC_VERSION_MINOR_MASK       U(0xFFFF)
+#define MAKE_SMCCC_VERSION(_major, _minor) \
+       ( (((uint32_t)(_major) & SMCCC_VERSION_MAJOR_MASK) << SMCCC_VERSION_MAJOR_SHIFT) \
+       | (((uint32_t)(_minor) & SMCCC_VERSION_MINOR_MASK) << SMCCC_VERSION_MINOR_SHIFT))
+
+#if SMCCC_MAJOR_VERSION == 1
+# define SMCCC_MINOR_VERSION U(1)
+# include <smccc_v1.h>
+#elif SMCCC_MAJOR_VERSION == 2
+# define SMCCC_MINOR_VERSION U(0)
+# include <smccc_v2.h>
+#else
+# error "Unsupported version of SMCCC."
 #endif
-#define SMC_TYPE_YIELD                 U(0)
-#define SMC_PREEMPTED                  -2
-/*******************************************************************************
- * Owning entity number definitions inside the function id as per the SMC
- * calling convention
- ******************************************************************************/
-#define OEN_ARM_START                  U(0)
-#define OEN_ARM_END                    U(0)
-#define OEN_CPU_START                  U(1)
-#define OEN_CPU_END                    U(1)
-#define OEN_SIP_START                  U(2)
-#define OEN_SIP_END                    U(2)
-#define OEN_OEM_START                  U(3)
-#define OEN_OEM_END                    U(3)
-#define OEN_STD_START                  U(4)    /* Standard Service Calls */
-#define OEN_STD_END                    U(4)
-#define OEN_TAP_START                  U(48)   /* Trusted Applications */
-#define OEN_TAP_END                    U(49)
-#define OEN_TOS_START                  U(50)   /* Trusted OS */
-#define OEN_TOS_END                    U(63)
-#define OEN_LIMIT                      U(64)
+
+/* Various flags passed to SMC handlers */
+#define SMC_FROM_SECURE                (U(0) << 0)
+#define SMC_FROM_NON_SECURE    (U(1) << 0)
 
 #ifndef __ASSEMBLY__
 
 #include <cassert.h>
 #include <stdint.h>
 
-#define SMCCC_MAJOR_VERSION U(1)
-#define SMCCC_MINOR_VERSION U(1)
-
-#define MAKE_SMCCC_VERSION(_major, _minor) (((_major) << 16) | (_minor))
-
-/* Various flags passed to SMC handlers */
-#define SMC_FROM_SECURE                (U(0) << 0)
-#define SMC_FROM_NON_SECURE    (U(1) << 0)
-
 #define is_caller_non_secure(_f)       (((_f) & SMC_FROM_NON_SECURE) != U(0))
 #define is_caller_secure(_f)           (!is_caller_non_secure(_f))
 
 /* The macro below is used to identify a Standard Service SMC call */
-#define is_std_svc_call(_fid)          ((((_fid) >> FUNCID_OEN_SHIFT) & \
-                                          FUNCID_OEN_MASK) == OEN_STD_START)
+#define is_std_svc_call(_fid)          (GET_SMC_OEN(_fid) == OEN_STD_START)
 
 /* The macro below is used to identify a Arm Architectural Service SMC call */
-#define is_arm_arch_svc_call(_fid)     ((((_fid) >> FUNCID_OEN_SHIFT) & \
-                                          FUNCID_OEN_MASK) == OEN_ARM_START)
+#define is_arm_arch_svc_call(_fid)     (GET_SMC_OEN(_fid) == OEN_ARM_START)
 
 /* The macro below is used to identify a valid Fast SMC call */
 #define is_valid_fast_smc(_fid)                ((!(((_fid) >> 16) & U(0xff))) && \
diff --git a/include/lib/smccc_v1.h b/include/lib/smccc_v1.h
new file mode 100644 (file)
index 0000000..8718d15
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SMCCC_V1_H
+#define SMCCC_V1_H
+
+#ifndef __SMCCC_H__
+#error "This file must only be included from smccc.h"
+#endif
+
+/*******************************************************************************
+ * Bit definitions inside the function id as per the SMC calling convention
+ ******************************************************************************/
+#define FUNCID_TYPE_SHIFT              U(31)
+#define FUNCID_TYPE_MASK               U(0x1)
+#define FUNCID_TYPE_WIDTH              U(1)
+
+#define FUNCID_CC_SHIFT                        U(30)
+#define FUNCID_CC_MASK                 U(0x1)
+#define FUNCID_CC_WIDTH                        U(1)
+
+#define FUNCID_OEN_SHIFT               U(24)
+#define FUNCID_OEN_MASK                        U(0x3f)
+#define FUNCID_OEN_WIDTH               U(6)
+
+#define FUNCID_NUM_SHIFT               U(0)
+#define FUNCID_NUM_MASK                        U(0xffff)
+#define FUNCID_NUM_WIDTH               U(16)
+
+#define GET_SMC_TYPE(id)               (((id) >> FUNCID_TYPE_SHIFT) & \
+                                        FUNCID_TYPE_MASK)
+#define GET_SMC_CC(id)                 (((id) >> FUNCID_CC_SHIFT) & \
+                                        FUNCID_CC_MASK)
+#define GET_SMC_OEN(id)                        (((id) >> FUNCID_OEN_SHIFT) & \
+                                        FUNCID_OEN_MASK)
+
+/*******************************************************************************
+ * Owning entity number definitions inside the function id as per the SMC
+ * calling convention
+ ******************************************************************************/
+#define OEN_ARM_START                  U(0)
+#define OEN_ARM_END                    U(0)
+#define OEN_CPU_START                  U(1)
+#define OEN_CPU_END                    U(1)
+#define OEN_SIP_START                  U(2)
+#define OEN_SIP_END                    U(2)
+#define OEN_OEM_START                  U(3)
+#define OEN_OEM_END                    U(3)
+#define OEN_STD_START                  U(4)    /* Standard Service Calls */
+#define OEN_STD_END                    U(4)
+#define OEN_STD_HYP_START              U(5)    /* Standard Hypervisor Service calls */
+#define OEN_STD_HYP_END                        U(5)
+#define OEN_VEN_HYP_START              U(6)    /* Vendor Hypervisor Service calls */
+#define OEN_VEN_HYP_END                        U(6)
+#define OEN_TAP_START                  U(48)   /* Trusted Applications */
+#define OEN_TAP_END                    U(49)
+#define OEN_TOS_START                  U(50)   /* Trusted OS */
+#define OEN_TOS_END                    U(63)
+#define OEN_LIMIT                      U(64)
+
+/* Flags and error codes */
+#define SMC_64                         U(1)
+#define SMC_32                         U(0)
+
+#define SMC_TYPE_FAST                  ULL(1)
+#if !ERROR_DEPRECATED
+#define SMC_TYPE_STD                   ULL(0)
+#endif
+#define SMC_TYPE_YIELD                 ULL(0)
+
+#define SMC_OK                         ULL(0)
+#define SMC_UNK                                -1
+#define SMC_PREEMPTED                  -2      /* Not defined by the SMCCC */
+
+#endif /* SMCCC_V1_H */
diff --git a/include/lib/smccc_v2.h b/include/lib/smccc_v2.h
new file mode 100644 (file)
index 0000000..628c160
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SMCCC_V2_H
+#define SMCCC_V2_H
+
+#ifndef __SMCCC_H__
+#error "This file must only be included from smccc.h"
+#endif
+
+/*******************************************************************************
+ * Bit definitions inside the function id as per the SMC calling convention
+ ******************************************************************************/
+#define FUNCID_TYPE_SHIFT              U(31)
+#define FUNCID_TYPE_MASK               U(0x1)
+#define FUNCID_TYPE_WIDTH              U(1)
+
+#define FUNCID_CC_SHIFT                        U(30)
+#define FUNCID_CC_MASK                 U(0x1)
+#define FUNCID_CC_WIDTH                        U(1)
+
+#define FUNCID_NAMESPACE_SHIFT         U(28)
+#define FUNCID_NAMESPACE_MASK          U(0x3)
+#define FUNCID_NAMESPACE_WIDTH         U(2)
+
+#define FUNCID_OEN_SHIFT               U(24)
+#define FUNCID_OEN_MASK                        U(0xf)
+#define FUNCID_OEN_WIDTH               U(4)
+
+#define FUNCID_NUM_SHIFT               U(0)
+#define FUNCID_NUM_MASK                        U(0xffff)
+#define FUNCID_NUM_WIDTH               U(16)
+
+#define GET_SMC_TYPE(id)               (((id) >> FUNCID_TYPE_SHIFT) & \
+                                        FUNCID_TYPE_MASK)
+#define GET_SMC_CC(id)                 (((id) >> FUNCID_CC_SHIFT) & \
+                                        FUNCID_CC_MASK)
+#define GET_SMC_NAMESPACE(id)          (((id) >> FUNCID_NAMESPACE_SHIFT) & \
+                                        FUNCID_NAMESPACE_MASK)
+#define GET_SMC_OEN(id)                        (((id) >> FUNCID_OEN_SHIFT) & \
+                                        FUNCID_OEN_MASK)
+
+/*******************************************************************************
+ * Owning entity number definitions inside the function id as per the SMC
+ * calling convention
+ ******************************************************************************/
+#define OEN_ARM_START                  U(0)
+#define OEN_ARM_END                    U(0)
+#define OEN_CPU_START                  U(1)
+#define OEN_CPU_END                    U(1)
+#define OEN_SIP_START                  U(2)
+#define OEN_SIP_END                    U(2)
+#define OEN_OEM_START                  U(3)
+#define OEN_OEM_END                    U(3)
+#define OEN_STD_START                  U(4)    /* Standard Service Calls */
+#define OEN_STD_END                    U(4)
+#define OEN_STD_HYP_START              U(5)    /* Standard Hypervisor Service calls */
+#define OEN_STD_HYP_END                        U(5)
+#define OEN_VEN_HYP_START              U(6)    /* Vendor Hypervisor Service calls */
+#define OEN_VEN_HYP_END                        U(6)
+#define OEN_LIMIT                      U(16)
+
+/*******************************************************************************
+ * Service namespaces as per the SMC Calling Convention v2.X
+ ******************************************************************************/
+#define FUNCID_NAMESPACE_START         U(0)
+#define FUNCID_NAMESPACE_COMPAT                U(0)
+#define FUNCID_NAMESPACE_VENDOR                U(1)
+#define FUNCID_NAMESPACE_SPRT          U(2)
+#define FUNCID_NAMESPACE_SPCI          U(3)
+#define FUNCID_NAMESPACE_LIMIT         U(4)
+
+/* Flags and error codes */
+#define SMC_64                         U(1)
+#define SMC_32                         U(0)
+
+#define SMC_TYPE_FAST                  ULL(1)
+
+#define SMC_OK                         ULL(0)
+#define SMC_UNK                                -1
+
+#endif /* SMCCC_V2_H */
index 77eb157c69f5282e230ff2afbdb49cc9765355ca..9e95cd5ac03426b00ab80f6fc57077c743f4d758 100644 (file)
@@ -133,6 +133,9 @@ SDEI_SUPPORT                := 0
 # platform Makefile is free to override this value.
 SEPARATE_CODE_AND_RODATA       := 0
 
+# Default to SMCCC Version 1.X
+SMCCC_MAJOR_VERSION            := 1
+
 # SPD choice
 SPD                            := none