Use a vector table for TSP entrypoints
authorAndrew Thoelke <andrew.thoelke@arm.com>
Tue, 20 May 2014 20:43:27 +0000 (21:43 +0100)
committerAndrew Thoelke <andrew.thoelke@arm.com>
Fri, 23 May 2014 07:49:36 +0000 (08:49 +0100)
The TSP has a number of entrypoints used by the TSP on different
occasions. These were provided to the TSPD as a table of function
pointers, and required the TSPD to read the entry in the table,
which is in TSP memory, in order to program the exception return
address.

Ideally, the TSPD has no access to the TSP memory.

This patch changes the table of function pointers into a vector
table of single instruction entrypoints. This allows the TSPD to
calculate the entrypoint address instead of read it.

Fixes ARM-software/tf-issues#160

Change-Id: Iec6e055d537ade78a45799fbc6f43765a4725ad3

bl32/tsp/aarch64/tsp_entrypoint.S
bl32/tsp/tsp_main.c
include/bl32/payloads/tsp.h
services/spd/tspd/tspd_main.c
services/spd/tspd/tspd_pm.c
services/spd/tspd/tspd_private.h

index 9999c432b4917a5b85861ed5f17cd812dfdc5864..8fdfbc396d14bcf2b85493252d1b74e1d8801e6f 100644 (file)
 
 
        .globl  tsp_entrypoint
-       .globl  tsp_cpu_on_entry
-       .globl  tsp_cpu_off_entry
-       .globl  tsp_cpu_suspend_entry
-       .globl  tsp_cpu_resume_entry
-       .globl  tsp_fast_smc_entry
-       .globl  tsp_std_smc_entry
-       .globl  tsp_fiq_entry
+       .globl  tsp_vector_table
 
 
 
@@ -157,6 +151,21 @@ func tsp_entrypoint
 tsp_entrypoint_panic:
        b       tsp_entrypoint_panic
 
+
+       /* -------------------------------------------
+        * Table of entrypoint vectors provided to the
+        * TSPD for the various entrypoints
+        * -------------------------------------------
+        */
+func tsp_vector_table
+       b       tsp_std_smc_entry
+       b       tsp_fast_smc_entry
+       b       tsp_cpu_on_entry
+       b       tsp_cpu_off_entry
+       b       tsp_cpu_resume_entry
+       b       tsp_cpu_suspend_entry
+       b       tsp_fiq_entry
+
        /*---------------------------------------------
         * This entrypoint is used by the TSPD when this
         * cpu is to be turned off through a CPU_OFF
index 1c3f3b9883f9fe7fcd8c83973ac6c709aa21f386..ad7ee0a2074d7b32ffb971428a12fffd837ce1f7 100644 (file)
@@ -60,22 +60,6 @@ static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
  ******************************************************************************/
 work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
 
-/*******************************************************************************
- * Single reference to the various entry points exported by the test secure
- * payload.  A single copy should suffice for all cpus as they are not expected
- * to change.
- ******************************************************************************/
-static const entry_info_t tsp_entry_info = {
-       tsp_std_smc_entry,
-       tsp_fast_smc_entry,
-       tsp_cpu_on_entry,
-       tsp_cpu_off_entry,
-       tsp_cpu_resume_entry,
-       tsp_cpu_suspend_entry,
-       tsp_fiq_entry,
-};
-
-
 /*******************************************************************************
  * The BL32 memory footprint starts with an RO sections and ends
  * with a section for coherent RAM. Use it to find the memory size
@@ -118,7 +102,7 @@ static tsp_args_t *set_smc_args(uint64_t arg0,
 /*******************************************************************************
  * TSP main entry point where it gets the opportunity to initialize its secure
  * state/applications. Once the state is initialized, it must return to the
- * SPD with a pointer to the 'tsp_entry_info' structure.
+ * SPD with a pointer to the 'tsp_vector_table' jump table.
  ******************************************************************************/
 uint64_t tsp_main(void)
 {
@@ -147,12 +131,7 @@ uint64_t tsp_main(void)
             tsp_stats[linear_id].cpu_on_count);
        spin_unlock(&console_lock);
 
-       /*
-        * TODO: There is a massive assumption that the SPD and SP can see each
-        * other's memory without issues so it is safe to pass pointers to
-        * internal memory. Replace this with a shared communication buffer.
-        */
-       return (uint64_t) &tsp_entry_info;
+       return (uint64_t) &tsp_vector_table;
 }
 
 /*******************************************************************************
index 2e32c77e5a50141e58a308cab0bae02d7af18b99..9239ba4ab12c61600a9c30c1875c583dea18daef 100644 (file)
 #include <spinlock.h>
 #include <stdint.h>
 
-typedef void (*tsp_generic_fptr_t)(uint64_t arg0,
-                                  uint64_t arg1,
-                                  uint64_t arg2,
-                                  uint64_t arg3,
-                                  uint64_t arg4,
-                                  uint64_t arg5,
-                                  uint64_t arg6,
-                                  uint64_t arg7);
-
-typedef struct entry_info {
-       tsp_generic_fptr_t std_smc_entry;
-       tsp_generic_fptr_t fast_smc_entry;
-       tsp_generic_fptr_t cpu_on_entry;
-       tsp_generic_fptr_t cpu_off_entry;
-       tsp_generic_fptr_t cpu_resume_entry;
-       tsp_generic_fptr_t cpu_suspend_entry;
-       tsp_generic_fptr_t fiq_entry;
-} entry_info_t;
+typedef uint32_t tsp_vector_isn_t;
+
+typedef struct tsp_vectors {
+       tsp_vector_isn_t std_smc_entry;
+       tsp_vector_isn_t fast_smc_entry;
+       tsp_vector_isn_t cpu_on_entry;
+       tsp_vector_isn_t cpu_off_entry;
+       tsp_vector_isn_t cpu_resume_entry;
+       tsp_vector_isn_t cpu_suspend_entry;
+       tsp_vector_isn_t fiq_entry;
+} tsp_vectors_t;
 
 typedef struct work_statistics {
        uint32_t fiq_count;             /* Number of FIQs on this cpu */
@@ -166,38 +159,6 @@ CASSERT(TSP_ARGS_SIZE == sizeof(tsp_args_t), assert_sp_args_size_mismatch);
 
 extern void tsp_get_magic(uint64_t args[4]);
 
-extern void tsp_fiq_entry(uint64_t arg0,
-                               uint64_t arg1,
-                               uint64_t arg2,
-                               uint64_t arg3,
-                               uint64_t arg4,
-                               uint64_t arg5,
-                               uint64_t arg6,
-                               uint64_t arg7);
-extern void tsp_std_smc_entry(uint64_t arg0,
-                               uint64_t arg1,
-                               uint64_t arg2,
-                               uint64_t arg3,
-                               uint64_t arg4,
-                               uint64_t arg5,
-                               uint64_t arg6,
-                               uint64_t arg7);
-extern void tsp_fast_smc_entry(uint64_t arg0,
-                               uint64_t arg1,
-                               uint64_t arg2,
-                               uint64_t arg3,
-                               uint64_t arg4,
-                               uint64_t arg5,
-                               uint64_t arg6,
-                               uint64_t arg7);
-extern void tsp_cpu_resume_entry(uint64_t arg0,
-                                uint64_t arg1,
-                                uint64_t arg2,
-                                uint64_t arg3,
-                                uint64_t arg4,
-                                uint64_t arg5,
-                                uint64_t arg6,
-                                uint64_t arg7);
 extern tsp_args_t *tsp_cpu_resume_main(uint64_t arg0,
                                     uint64_t arg1,
                                     uint64_t arg2,
@@ -206,14 +167,6 @@ extern tsp_args_t *tsp_cpu_resume_main(uint64_t arg0,
                                     uint64_t arg5,
                                     uint64_t arg6,
                                     uint64_t arg7);
-extern void tsp_cpu_suspend_entry(uint64_t arg0,
-                                 uint64_t arg1,
-                                 uint64_t arg2,
-                                 uint64_t arg3,
-                                 uint64_t arg4,
-                                 uint64_t arg5,
-                                 uint64_t arg6,
-                                 uint64_t arg7);
 extern tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
                                      uint64_t arg1,
                                      uint64_t arg2,
@@ -222,23 +175,7 @@ extern tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
                                      uint64_t arg5,
                                      uint64_t arg6,
                                      uint64_t arg7);
-extern void tsp_cpu_on_entry(uint64_t arg0,
-                            uint64_t arg1,
-                            uint64_t arg2,
-                            uint64_t arg3,
-                            uint64_t arg4,
-                            uint64_t arg5,
-                            uint64_t arg6,
-                            uint64_t arg7);
 extern tsp_args_t *tsp_cpu_on_main(void);
-extern void tsp_cpu_off_entry(uint64_t arg0,
-                             uint64_t arg1,
-                             uint64_t arg2,
-                             uint64_t arg3,
-                             uint64_t arg4,
-                             uint64_t arg5,
-                             uint64_t arg6,
-                             uint64_t arg7);
 extern tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
                                  uint64_t arg1,
                                  uint64_t arg2,
@@ -261,6 +198,10 @@ extern void tsp_update_sync_fiq_stats(uint32_t type, uint64_t elr_el3);
 /* Data structure to keep track of TSP statistics */
 extern spinlock_t console_lock;
 extern work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
+
+/* Vector table of jumps */
+extern tsp_vectors_t tsp_vector_table;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __BL2_H__ */
index ec2d334da09c1d742072b7e29e2b836e594fd01c..1dbe6ba08f8d3f4060a53d6752991294ae8cbfe6 100644 (file)
 #include "tspd_private.h"
 
 /*******************************************************************************
- * Single structure to hold information about the various entry points into the
- * Secure Payload. It is initialised once on the primary core after a cold boot.
+ * Address of the entrypoint vector table in the Secure Payload. It is
+ * initialised once on the primary core after a cold boot.
  ******************************************************************************/
-entry_info_t *tsp_entry_info;
+tsp_vectors_t *tsp_vectors;
 
 /*******************************************************************************
  * Array to keep track of per-cpu Secure Payload state
@@ -127,7 +127,7 @@ static uint64_t tspd_sel1_interrupt_handler(uint32_t id,
                    SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
        SMC_SET_EL3(&tsp_ctx->cpu_ctx,
                    CTX_ELR_EL3,
-                   (uint64_t) tsp_entry_info->fiq_entry);
+                   (uint64_t) &tsp_vectors->fiq_entry);
        cm_el1_sysregs_context_restore(SECURE);
        cm_set_next_eret_context(SECURE);
 
@@ -370,8 +370,8 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
                 * Stash the SP entry points information. This is done
                 * only once on the primary cpu
                 */
-               assert(tsp_entry_info == NULL);
-               tsp_entry_info = (entry_info_t *) x1;
+               assert(tsp_vectors == NULL);
+               tsp_vectors = (tsp_vectors_t *) x1;
 
                /*
                 * SP reports completion. The SPD must have initiated
@@ -465,11 +465,11 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
                         */
                        if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {
                                cm_set_elr_el3(SECURE, (uint64_t)
-                                               tsp_entry_info->fast_smc_entry);
+                                               &tsp_vectors->fast_smc_entry);
                        } else {
                                set_std_smc_active_flag(tsp_ctx->state);
                                cm_set_elr_el3(SECURE, (uint64_t)
-                                               tsp_entry_info->std_smc_entry);
+                                               &tsp_vectors->std_smc_entry);
                        }
 
                        cm_el1_sysregs_context_restore(SECURE);
index d99aa2224cf7d010932300eb75e1a106c603c822..2f204494529319e68c458a9df1df827e7f961828 100644 (file)
@@ -55,11 +55,11 @@ static int32_t tspd_cpu_off_handler(uint64_t cookie)
        uint32_t linear_id = platform_get_core_pos(mpidr);
        tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
 
-       assert(tsp_entry_info);
+       assert(tsp_vectors);
        assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
 
        /* Program the entry point and enter the TSP */
-       cm_set_elr_el3(SECURE, (uint64_t) tsp_entry_info->cpu_off_entry);
+       cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_off_entry);
        rc = tspd_synchronous_sp_entry(tsp_ctx);
 
        /*
@@ -89,14 +89,14 @@ static void tspd_cpu_suspend_handler(uint64_t power_state)
        uint32_t linear_id = platform_get_core_pos(mpidr);
        tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
 
-       assert(tsp_entry_info);
+       assert(tsp_vectors);
        assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
 
        /* Program the entry point, power_state parameter and enter the TSP */
        write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
                      CTX_GPREG_X0,
                      power_state);
-       cm_set_elr_el3(SECURE, (uint64_t) tsp_entry_info->cpu_suspend_entry);
+       cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_suspend_entry);
        rc = tspd_synchronous_sp_entry(tsp_ctx);
 
        /*
@@ -123,11 +123,11 @@ static void tspd_cpu_on_finish_handler(uint64_t cookie)
        uint32_t linear_id = platform_get_core_pos(mpidr);
        tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
 
-       assert(tsp_entry_info);
+       assert(tsp_vectors);
        assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_OFF);
 
        /* Initialise this cpu's secure context */
-       tspd_init_secure_context((uint64_t) tsp_entry_info->cpu_on_entry,
+       tspd_init_secure_context((uint64_t) &tsp_vectors->cpu_on_entry,
                                TSP_AARCH64,
                                mpidr,
                                tsp_ctx);
@@ -158,14 +158,14 @@ static void tspd_cpu_suspend_finish_handler(uint64_t suspend_level)
        uint32_t linear_id = platform_get_core_pos(mpidr);
        tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
 
-       assert(tsp_entry_info);
+       assert(tsp_vectors);
        assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_SUSPEND);
 
        /* Program the entry point, suspend_level and enter the SP */
        write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
                      CTX_GPREG_X0,
                      suspend_level);
-       cm_set_elr_el3(SECURE, (uint64_t) tsp_entry_info->cpu_resume_entry);
+       cm_set_elr_el3(SECURE, (uint64_t) &tsp_vectors->cpu_resume_entry);
        rc = tspd_synchronous_sp_entry(tsp_ctx);
 
        /*
index 7395bb9eea25245eee6556a4ff6feaea7468b1a9..fbb0388710a85bba13d770dcd00ac46eae10c39b 100644 (file)
@@ -183,7 +183,7 @@ extern const spd_pm_ops_t tspd_pm;
 /*******************************************************************************
  * Forward declarations
  ******************************************************************************/
-struct entry_info;
+struct tsp_vectors;
 
 /*******************************************************************************
  * Function & Data prototypes
@@ -197,7 +197,7 @@ extern int32_t tspd_init_secure_context(uint64_t entrypoint,
                                        uint64_t mpidr,
                                        tsp_context_t *tsp_ctx);
 extern tsp_context_t tspd_sp_context[TSPD_CORE_COUNT];
-extern struct entry_info *tsp_entry_info;
+extern struct tsp_vectors *tsp_vectors;
 #endif /*__ASSEMBLY__*/
 
 #endif /* __TSPD_PRIVATE_H__ */