Core: Enable non-consecutive IDs for partitions

This commit eliminates the linear mapping between the secure partition
IDs and partition data indexes. To do this, the PARTITION_ID_GET(id)
macro is removed, and find_partition_record is created to search through
the services DB for the desired service.

The commit also simplifies user_service_defines.inc. From now, calling
PARTITION_DECLARE() for a partition is enough, no need to call
PARTITION_ADD()

Change-Id: I69d064f3aa3fbca8171179571ae9cec1b92fdeb4
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/secure_fw/spm/service_defs.h b/secure_fw/spm/service_defs.h
deleted file mode 100644
index 6e699c1..0000000
--- a/secure_fw/spm/service_defs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __PARTITION_DEFS_H__
-#define __PARTITION_DEFS_H__
-
-/* FixMe: allocations to be settled.
- * 8 bits reserved by TFM for secure partition Id this prototype
- */
-#define TFM_SP_BASE 256
-
-/* A reserved partition ID that is used for uninitialised data */
-#define INVALID_PARITION_ID (~0U)
-
-/* FixMe: current implementation requires consecutive IDs, no gaps */
-/* From the SPM point of view the non secure processing environment is handled
- * as a special secure partition. This simplifies the context switch
- * operations.
- */
-#define TFM_SP_NON_SECURE_ID (TFM_SP_BASE + 0)
-/* A dummy partition for TFM_SP_CORE is created to handle secure partition
- * calls done directly from the core, before NS execution started.
- */
-#define TFM_SP_CORE_ID (TFM_SP_BASE + 1)
-#define TFM_SP_STORAGE_ID (TFM_SP_BASE + 2)
-
-#ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 3)
-#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 4)
-
-/* Give SST test service next ID after core test services */
-#ifdef TFM_PARTITION_TEST_SST
-#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 5)
-#endif
-
-#elif defined(TFM_PARTITION_TEST_SST) /* CORE_TEST_SERVICES */
-/* Avoid creating a gap if core test services are not enabled */
-#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 3)
-#endif /* CORE_TEST_SERVICES */
-
-#endif /* __PARTITION_DEFS_H__ */
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index 642b577..1705de8 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -17,21 +17,21 @@
 
 struct spm_partition_db_t g_spm_partition_db = {0,};
 
-#define MPU_REGION_VENEERS   0
+#define MPU_REGION_VENEERS           0
 #define MPU_REGION_TFM_UNPRIV_CODE   1
 #define MPU_REGION_TFM_UNPRIV_DATA   2
-#define MPU_REGION_NS_DATA      3
-#define PARTITION_REGION_RO       4
-#define PARTITION_REGION_RW_STACK 5
-#define PARTITION_REGION_PERIPH   6
-#define PARTITION_REGION_SHARE    7
+#define MPU_REGION_NS_DATA           3
+#define PARTITION_REGION_RO          4
+#define PARTITION_REGION_RW_STACK    5
+#define PARTITION_REGION_PERIPH      6
+#define PARTITION_REGION_SHARE       7
 
 /* This should move to platform retarget */
 struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
 
 typedef enum {
     TFM_INIT_FAILURE,
-} ss_error_type_t;
+} sp_error_type_t;
 
 /*
  * This function is called when a secure partition causes an error.
@@ -40,7 +40,7 @@
  */
 static void tfm_spm_partition_err_handler(
     struct spm_partition_desc_t *partition,
-    ss_error_type_t err_type,
+    sp_error_type_t err_type,
     int32_t err_code)
 {
 #ifdef TFM_CORE_DEBUG
@@ -56,14 +56,58 @@
             SPM_PARTITION_STATE_CLOSED);
 }
 
+uint32_t get_partition_idx(uint32_t partition_id)
+{
+    int i;
+
+    if (partition_id == INVALID_PARTITION_ID) {
+        return SPM_INVALID_PARTITION_IDX;
+    }
+
+    for (i = 0; i < g_spm_partition_db.partition_count; ++i) {
+        if (g_spm_partition_db.partitions[i].static_data.partition_id ==
+                partition_id) {
+            return i;
+        }
+    }
+    return SPM_INVALID_PARTITION_IDX;
+}
+
 enum spm_err_t tfm_spm_db_init(void)
 {
+    struct spm_partition_desc_t *part_ptr;
+
     /* This function initialises partition db */
     g_spm_partition_db.is_init = 1;
-    g_spm_partition_db.running_partition_id = INVALID_PARITION_ID;
+    g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
+    g_spm_partition_db.partition_count = 0;
 
-    g_spm_partition_db.partition_count =
-        create_user_partition_db(&g_spm_partition_db, SPM_MAX_PARTITIONS);
+    /* There are a few partitions that are used by TF-M internally.
+     * These are explicitly added to the partition db here.
+     */
+
+    /* For the non secure Execution environment */
+    if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
+        return SPM_ERR_INVALID_CONFIG;
+    }
+    part_ptr = &(g_spm_partition_db.partitions[
+            g_spm_partition_db.partition_count]);
+    part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID;
+    part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
+    ++g_spm_partition_db.partition_count;
+
+    /* For the TF-M core environment itself */
+    if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
+        return SPM_ERR_INVALID_CONFIG;
+    }
+    part_ptr = &(g_spm_partition_db.partitions[
+            g_spm_partition_db.partition_count]);
+    part_ptr->static_data.partition_id = TFM_SP_CORE_ID;
+    part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
+    ++g_spm_partition_db.partition_count;
+
+    /* Add user-defined secure partitions */
+    #include "user_partition_defines.inc"
 
     return SPM_ERR_OK;
 }
@@ -184,28 +228,26 @@
 {
     struct spm_partition_desc_t *part;
     int32_t fail_cnt = 0;
-    uint32_t i;
+    uint32_t idx;
 
     /* Call the init function for each partition */
     /* FixMe: This implementation only fits level 1 isolation.
      * On higher levels MPU (and PPC) configuration need to be in place to have
      * proper isolation during init.
      */
-    for (i = 0; i < g_spm_partition_db.partition_count; ++i) {
-        part = &g_spm_partition_db.partitions[i];
+    for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
+        part = &g_spm_partition_db.partitions[idx];
         if (part->static_data.periph_start) {
             ppc_configure_to_secure(part->static_data.periph_ppc_bank,
                     part->static_data.periph_ppc_loc);
         }
         if (part->static_data.partition_init == NULL) {
-            tfm_spm_partition_set_state(part->static_data.partition_id,
-                    SPM_PARTITION_STATE_IDLE);
+            tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
         } else {
             int32_t ret = part->static_data.partition_init();
 
             if (ret == TFM_SUCCESS) {
-                tfm_spm_partition_set_state(part->static_data.partition_id,
-                                            SPM_PARTITION_STATE_IDLE);
+                tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
             } else {
                 tfm_spm_partition_err_handler(part, TFM_INIT_FAILURE, ret);
                 fail_cnt++;
@@ -221,7 +263,7 @@
 }
 
 #if TFM_LVL != 1
-enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_id)
+enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
 {
     /* This function takes a partition id and enables the
      * SPM partition for that partition
@@ -235,7 +277,7 @@
     }
 
     /*brute force id*/
-    part = &g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)];
+    part = &g_spm_partition_db.partitions[partition_idx];
 
     mpu_armv8m_disable(&dev_mpu_s);
 
@@ -295,7 +337,7 @@
     return SPM_ERR_OK;
 }
 
-enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_id)
+enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
 {
     /* This function takes a partition id and disables the
      * SPM partition for that partition
@@ -316,7 +358,7 @@
 
     struct spm_partition_desc_t *part;
 
-    part = &g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)];
+    part = &g_spm_partition_db.partitions[partition_idx];
 
     if (part->static_data.periph_start) {
         /* Peripheral */
@@ -334,71 +376,72 @@
     return SPM_ERR_OK;
 }
 
-uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_id)
+uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
 {
-    return g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
+    return g_spm_partition_db.partitions[partition_idx].
             static_data.stack_bottom;
 }
 
-uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_id)
+uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
 {
-    return
-      g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-            static_data.stack_top;
+    return g_spm_partition_db.partitions[partition_idx].static_data.stack_top;
 }
 
-void tfm_spm_partition_set_stack(uint32_t partition_id, uint32_t stack_ptr)
+void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
 {
-    g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
+    g_spm_partition_db.partitions[partition_idx].
             runtime_data.stack_ptr = stack_ptr;
 }
 #endif
 
-
-const struct spm_partition_runtime_data_t *
-             tfm_spm_partition_get_runtime_data(uint32_t partition_id)
+uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
 {
-    return &(g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-                runtime_data);
+    return g_spm_partition_db.partitions[partition_idx].static_data.
+            partition_id;
 }
 
-void tfm_spm_partition_set_state(uint32_t partition_id, uint32_t state)
+const struct spm_partition_runtime_data_t *
+             tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
 {
-    g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-                       runtime_data.partition_state = state;
+    return &(g_spm_partition_db.partitions[partition_idx].runtime_data);
+}
+
+void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state)
+{
+    g_spm_partition_db.partitions[partition_idx].runtime_data.partition_state =
+            state;
     if (state == SPM_PARTITION_STATE_RUNNING) {
-        g_spm_partition_db.running_partition_id = partition_id;
+        g_spm_partition_db.running_partition_idx = partition_idx;
     }
 }
 
-void tfm_spm_partition_set_caller_partition_id(uint32_t partition_id,
-                                               uint32_t caller_partition_id)
+void tfm_spm_partition_set_caller_partition_id(uint32_t partition_idx,
+                                               uint32_t caller_partition_idx)
 {
-    g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-            runtime_data.caller_partition_id = caller_partition_id;
+    g_spm_partition_db.partitions[partition_idx].runtime_data.
+            caller_partition_idx = caller_partition_idx;
 }
 
-void tfm_spm_partition_set_orig_psp(uint32_t partition_id,
+void tfm_spm_partition_set_orig_psp(uint32_t partition_idx,
                                     uint32_t orig_psp)
 {
-    g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-            runtime_data.orig_psp = orig_psp;
+    g_spm_partition_db.partitions[partition_idx].runtime_data.orig_psp =
+            orig_psp;
 }
 
-void tfm_spm_partition_set_orig_psplim(uint32_t partition_id,
+void tfm_spm_partition_set_orig_psplim(uint32_t partition_idx,
                                        uint32_t orig_psplim)
 {
-    g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-            runtime_data.orig_psplim = orig_psplim;
+    g_spm_partition_db.partitions[partition_idx].runtime_data.orig_psplim =
+            orig_psplim;
 }
 
-void tfm_spm_partition_set_orig_lr(uint32_t partition_id, uint32_t orig_lr)
+void tfm_spm_partition_set_orig_lr(uint32_t partition_idx, uint32_t orig_lr)
 {
-    g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-            runtime_data.orig_lr = orig_lr;
+    g_spm_partition_db.partitions[partition_idx].runtime_data.orig_lr = orig_lr;
 }
 
-enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_id,
+enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
                                            uint32_t share)
 {
     enum spm_err_t ret = SPM_ERR_OK;
@@ -409,22 +452,21 @@
 #endif
 
     if (ret == SPM_ERR_OK) {
-        g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)].
-                runtime_data.share = share;
+        g_spm_partition_db.partitions[partition_idx].runtime_data.share = share;
     }
     return ret;
 }
 
-uint32_t tfm_spm_partition_get_running_partition_id(void)
+uint32_t tfm_spm_partition_get_running_partition_idx(void)
 {
-    return g_spm_partition_db.running_partition_id;
+    return g_spm_partition_db.running_partition_idx;
 }
 
-void tfm_spm_partition_cleanup_context(uint32_t partition_id)
+void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
 {
     struct spm_partition_desc_t *partition =
-            &g_spm_partition_db.partitions[PARTITION_ID_GET(partition_id)];
-    partition->runtime_data.caller_partition_id = 0;
+            &(g_spm_partition_db.partitions[partition_idx]);
+    partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
     partition->runtime_data.orig_psp = 0;
     partition->runtime_data.orig_psplim = 0;
     partition->runtime_data.orig_lr = 0;
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index 039506c..fced5d1 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -9,9 +9,11 @@
 #define __SPM_API_H__
 
 /* This file contains the apis exported by the SPM to tfm core */
-#include "service_defs.h"
+#include "spm_partition_defs.h"
 #include "secure_fw/core/tfm_secure_api.h"
 
+#define SPM_INVALID_PARTITION_IDX     (~0U)
+
 enum spm_err_t {
     SPM_ERR_OK = 0,
     SPM_ERR_PARTITION_DB_NOT_INIT,
@@ -34,7 +36,7 @@
  */
 struct spm_partition_runtime_data_t {
     uint32_t partition_state;
-    uint32_t caller_partition_id;
+    uint32_t caller_partition_idx;
     uint32_t orig_psp;
     uint32_t orig_psplim;
     uint32_t orig_lr;
@@ -44,145 +46,167 @@
 #endif
 };
 
+
 /**
- * \brief Configure isolated sandbox for a partition
+ * \brief Returns the index of the partition with the given partition ID.
  *
  * \param[in] partition_id     Partition id
  *
+ * \return the partition idx if partition_id is valid,
+ *         \ref SPM_INVALID_PARTITION_IDX othervise
+ */
+uint32_t get_partition_idx(uint32_t partition_id);
+
+/**
+ * \brief Configure isolated sandbox for a partition
+ *
+ * \param[in] partition_idx     Partition index
+ *
  * \return Error code \ref spm_err_t
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_id);
+enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx);
 
 /**
  * \brief Deconfigure sandbox for a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx     Partition index
  *
  * \return Error code \ref spm_err_t
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_id);
+enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
 
 /**
  * \brief Get bottom of stack region for a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx     Partition index
  *
  * \return Stack region bottom value
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_id);
+uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
 
 /**
  * \brief Get top of stack region for a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx     Partition index
  *
  * \return Stack region top value
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_id);
+uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
+
+/**
+ * \brief Get the id of the partition for its index from the db
+ *
+ * \param[in] partition_idx     Partition index
+ *
+ * \return Partition ID for that partition
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
 
 /**
  * \brief Get the current runtime data of a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx     Partition index
  *
  * \return The runtime data of the specified partition
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
 const struct spm_partition_runtime_data_t *
-             tfm_spm_partition_get_runtime_data(uint32_t partition_id);
+             tfm_spm_partition_get_runtime_data(uint32_t partition_idx);
 
 /**
- * \brief Returns the id of the partition that has running state
+ * \brief Returns the index of the partition that has running state
  *
- * \return The Id of the partition with the running state, if there is any set.
- *         0 otherwise.
+ * \return The index of the partition with the running state, if there is any
+ *         set. 0 otherwise.
  */
-uint32_t tfm_spm_partition_get_running_partition_id(void);
+uint32_t tfm_spm_partition_get_running_partition_idx(void);
 
 /**
  * \brief Save stack pointer for partition in database
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx  Partition index
  * \param[in] stack_ptr      Stack pointer to be stored
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
 void tfm_spm_partition_set_stack(uint32_t partition_id, uint32_t stack_ptr);
 
 /**
  * \brief Set the current state of a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx  Partition index
  * \param[in] state          The state to be set
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  * \note The \ref state has to have the value set of \ref spm_part_state_t.
  */
-void tfm_spm_partition_set_state(uint32_t partition_id, uint32_t state);
+void tfm_spm_partition_set_state(uint32_t partition_idx, uint32_t state);
 
 /**
  * \brief Set the caller partition Id for a given partition
  *
- * \param[in] partition_id         Partition id
+ * \param[in] partition_idx        Partition index
  * \param[in] caller_partition_id  The Id of the caller partition
  *
  * \note This function doesn't check if any of the partition_ids is valid.
  */
-void tfm_spm_partition_set_caller_partition_id(uint32_t partition_id,
+void tfm_spm_partition_set_caller_partition_id(uint32_t partition_idx,
                                            uint32_t caller_partition_id);
 
 /**
  * \brief Set the original PSP value of a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx  Partition index
  * \param[in] orig_psp       The PSP value to set
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-void tfm_spm_partition_set_orig_psp(uint32_t partition_id, uint32_t orig_psp);
+void tfm_spm_partition_set_orig_psp(uint32_t partition_idx, uint32_t orig_psp);
 
 /**
  * \brief Set the original PSP limit value of a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx  Partition index
  * \param[in] orig_psplim    The PSP limit value to set
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-void tfm_spm_partition_set_orig_psplim(uint32_t partition_id,
+void tfm_spm_partition_set_orig_psplim(uint32_t partition_idx,
                                        uint32_t orig_psplim);
 
 /**
  * \brief Set the original link register value of a partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx  Partition index
  * \param[in] orig_lr        The link register value to set
  *
  * \note This function doesn't check if partition_id is valid.
  */
-void tfm_spm_partition_set_orig_lr(uint32_t partition_id, uint32_t orig_lr);
+void tfm_spm_partition_set_orig_lr(uint32_t partition_idx, uint32_t orig_lr);
 
 /**
  * \brief Set the buffer share region of the partition
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx  Partition index
  * \param[in] share          The buffer share region to be set
  *
  * \return Error code \ref spm_err_t
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  * \note share has to have the value set of \ref tfm_buffer_share_region_e
  */
-enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_id,
+enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
                                            uint32_t share);
 
 /**
@@ -209,10 +233,10 @@
 /**
  * \brief Clears the context info from the database for a partition.
  *
- * \param[in] partition_id     Partition id
+ * \param[in] partition_idx     Partition index
  *
- * \note This function doesn't check if partition_id is valid.
+ * \note This function doesn't check if partition_idx is valid.
  */
-void tfm_spm_partition_cleanup_context(uint32_t partition_id);
+void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
 
 #endif /*__SPM_API_H__ */
diff --git a/secure_fw/spm/spm_db.h b/secure_fw/spm/spm_db.h
index 01aed35..45b6871 100644
--- a/secure_fw/spm/spm_db.h
+++ b/secure_fw/spm/spm_db.h
@@ -5,10 +5,13 @@
  *
  */
 
-#ifndef __SPM_SPM_DB_H__
-#define __SPM_SPM_DB_H__
+#ifndef __SPM_DB_H__
+#define __SPM_DB_H__
 
 #include <stdint.h>
+#include "platform_retarget.h"
+#include "target_cfg.h"
+#include "spm_partition_defs.h"
 
 /* This limit is only used to define the size of the database reserved for
  * partitions. There's no requirement that it match the number of partitions
@@ -16,7 +19,10 @@
  */
 #define SPM_MAX_PARTITIONS (6)
 
-#define PARTITION_ID_GET(id)      (id - TFM_SP_BASE)
+struct spm_partition_desc_t;
+struct spm_partition_db_t;
+
+uint32_t get_partition_idx(uint32_t partition_id);
 
 typedef int32_t(*sp_init_function)(void);
 
@@ -49,7 +55,7 @@
 struct spm_partition_db_t {
     uint32_t is_init;
     uint32_t partition_count;
-    uint32_t running_partition_id;
+    uint32_t running_partition_idx;
     struct spm_partition_desc_t partitions[SPM_MAX_PARTITIONS];
 };
 
@@ -64,164 +70,104 @@
     (uint32_t)&REGION_NAME(Image$$, partition, region)
 #endif
 
-#define PARTITION_DECLARE(partition)                       \
-    REGION_DECLARE(Image$$, partition, $$Base);            \
-    REGION_DECLARE(Image$$, partition, $$Limit);           \
-    REGION_DECLARE(Image$$, partition, $$RO$$Base);        \
-    REGION_DECLARE(Image$$, partition, $$RO$$Limit);       \
-    REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base);   \
-    REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit);  \
-    REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base);   \
-    REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit);  \
-    REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base);  \
-    REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
-
 
 #if TFM_LVL == 1
-#define PARTITION_INIT_STATIC_DATA(data, partition) \
-    data.partition_id    = partition##_ID;          \
-    data.periph_start    = 0U;                      \
-    data.periph_limit    = 0U;                      \
-    data.periph_ppc_bank = 0U;                      \
-    data.periph_ppc_loc  = 0U;                      \
-    data.partition_init  = 0U
+#define PARTITION_INIT_STATIC_DATA(data, partition)     \
+    do {                                                \
+        data.partition_id    = partition##_ID;          \
+        data.periph_start    = 0U;                      \
+        data.periph_limit    = 0U;                      \
+        data.periph_ppc_bank = 0U;                      \
+        data.periph_ppc_loc  = 0U;                      \
+        data.partition_init  = 0U;                      \
+    } while (0)
 #else
-#define PARTITION_INIT_STATIC_DATA(data, partition)                        \
-    data.partition_id    = partition##_ID;                                 \
-    data.code_start      = PART_REGION_ADDR(partition, $$Base);            \
-    data.code_limit      = PART_REGION_ADDR(partition, $$Limit);           \
-    data.ro_start        = PART_REGION_ADDR(partition, $$RO$$Base);        \
-    data.ro_limit        = PART_REGION_ADDR(partition, $$RO$$Limit);       \
-    data.rw_start        = PART_REGION_ADDR(partition, _DATA$$RW$$Base);   \
-    data.rw_limit        = PART_REGION_ADDR(partition, _DATA$$RW$$Limit);  \
-    data.zi_start        = PART_REGION_ADDR(partition, _DATA$$ZI$$Base);   \
-    data.zi_limit        = PART_REGION_ADDR(partition, _DATA$$ZI$$Limit);  \
-    data.stack_bottom    = PART_REGION_ADDR(partition, _STACK$$ZI$$Base);  \
-    data.stack_top       = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
-    data.periph_start    = 0U;                                             \
-    data.periph_limit    = 0U;                                             \
-    data.periph_ppc_bank = 0U;                                             \
-    data.periph_ppc_loc  = 0U;                                             \
-    data.partition_init  = 0U
+#define PARTITION_INIT_STATIC_DATA(data, partition)                            \
+    do {                                                                       \
+        data.partition_id    = partition##_ID;                                 \
+        data.code_start      = PART_REGION_ADDR(partition, $$Base);            \
+        data.code_limit      = PART_REGION_ADDR(partition, $$Limit);           \
+        data.ro_start        = PART_REGION_ADDR(partition, $$RO$$Base);        \
+        data.ro_limit        = PART_REGION_ADDR(partition, $$RO$$Limit);       \
+        data.rw_start        = PART_REGION_ADDR(partition, _DATA$$RW$$Base);   \
+        data.rw_limit        = PART_REGION_ADDR(partition, _DATA$$RW$$Limit);  \
+        data.zi_start        = PART_REGION_ADDR(partition, _DATA$$ZI$$Base);   \
+        data.zi_limit        = PART_REGION_ADDR(partition, _DATA$$ZI$$Limit);  \
+        data.stack_bottom    = PART_REGION_ADDR(partition, _STACK$$ZI$$Base);  \
+        data.stack_top       = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
+        data.periph_start    = 0U;                                             \
+        data.periph_limit    = 0U;                                             \
+        data.periph_ppc_bank = 0U;                                             \
+        data.periph_ppc_loc  = 0U;                                             \
+        data.partition_init  = 0U;                                             \
+    } while (0)
 #endif
 
 #if TFM_LVL == 1
-#define DUMMY_PARTITION_INIT_STATIC_DATA(data, partition)                     \
-        /* In case of TFM_LVL1 the static data is initialised the same way */ \
-        PARTITION_INIT_STATIC_DATA(data, partition)
+#define PARTITION_INIT_RUNTIME_DATA(data, partition)            \
+    do {                                                        \
+        data.partition_state      = SPM_PARTITION_STATE_UNINIT; \
+        data.caller_partition_idx = 0U;                         \
+        data.orig_psp             = 0U;                         \
+        data.orig_psplim          = 0U;                         \
+        data.orig_lr              = 0U;                         \
+        data.share                = 0U;                         \
+    } while (0)
 #else
-#define DUMMY_PARTITION_INIT_STATIC_DATA(data, partition) \
-    data.partition_id    = partition##_ID;                \
-    data.code_start      = 0U;                            \
-    data.code_limit      = 0U;                            \
-    data.ro_start        = 0U;                            \
-    data.ro_limit        = 0U;                            \
-    data.rw_start        = 0U;                            \
-    data.rw_limit        = 0U;                            \
-    data.zi_start        = 0U;                            \
-    data.zi_limit        = 0U;                            \
-    data.stack_bottom    = 0U;                            \
-    data.stack_top       = 0U;                            \
-    data.periph_start    = 0U;                            \
-    data.periph_limit    = 0U;                            \
-    data.periph_ppc_bank = 0U;                            \
-    data.periph_ppc_loc  = 0U;                            \
-    data.partition_init  = 0U
+#define PARTITION_INIT_RUNTIME_DATA(data, partition)                \
+    do {                                                            \
+        data.partition_state      = SPM_PARTITION_STATE_UNINIT;     \
+        data.caller_partition_idx = 0U;                             \
+        data.orig_psp             = 0U;                             \
+        data.orig_psplim          = 0U;                             \
+        data.orig_lr              = 0U;                             \
+        data.share                = 0U;                             \
+        data.stack_ptr            =                                 \
+                PART_REGION_ADDR(partition, _STACK$$ZI$$Limit);     \
+    } while (0)
 #endif
 
+#define PARTITION_DECLARE(partition)                                    \
+    do {                                                                \
+        REGION_DECLARE(Image$$, partition, $$Base);                     \
+        REGION_DECLARE(Image$$, partition, $$Limit);                    \
+        REGION_DECLARE(Image$$, partition, $$RO$$Base);                 \
+        REGION_DECLARE(Image$$, partition, $$RO$$Limit);                \
+        REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base);            \
+        REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit);           \
+        REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base);            \
+        REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit);           \
+        REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base);           \
+        REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit);          \
+        struct spm_partition_desc_t *part_ptr;                          \
+        if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
+            return SPM_ERR_INVALID_CONFIG;                              \
+        }                                                               \
+        part_ptr = &(g_spm_partition_db.partitions[                     \
+            g_spm_partition_db.partition_count]);                       \
+        PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition);   \
+        PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
+        ++g_spm_partition_db.partition_count;                           \
+    } while (0)
 
-#if TFM_LVL == 1
-#define PARTITION_INIT_RUNTIME_DATA(data, partition)                           \
-    data.partition_state     = SPM_PARTITION_STATE_UNINIT;                     \
-    data.caller_partition_id = 0U;                                             \
-    data.orig_psp            = 0U;                                             \
-    data.orig_psplim         = 0U;                                             \
-    data.orig_lr             = 0U;                                             \
-    data.share               = 0U
-#else
-#define PARTITION_INIT_RUNTIME_DATA(data, partition)                           \
-    data.partition_state     = SPM_PARTITION_STATE_UNINIT;                     \
-    data.caller_partition_id = 0U;                                             \
-    data.orig_psp            = 0U;                                             \
-    data.orig_psplim         = 0U;                                             \
-    data.orig_lr             = 0U;                                             \
-    data.share               = 0U;                                             \
-    data.stack_ptr           = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit)
-#endif
+#define PARTITION_ADD_INIT_FUNC(partition, init_func)                 \
+    do {                                                              \
+        extern int32_t init_func(void);                               \
+        uint32_t partition_idx = get_partition_idx(partition##_ID);   \
+        struct spm_partition_desc_t *part_ptr =                       \
+            &(g_spm_partition_db.partitions[partition_idx]);          \
+        part_ptr->static_data.partition_init = init_func;             \
+    } while (0)
 
-#if TFM_LVL == 1
-#define DUMMY_PARTITION_INIT_RUNTIME_DATA(data, partition) \
-    data.partition_state     = SPM_PARTITION_STATE_UNINIT; \
-    data.caller_partition_id = 0U;                         \
-    data.orig_psp            = 0U;                         \
-    data.orig_psplim         = 0U;                         \
-    data.orig_lr             = 0U;                         \
-    data.share               = 0U
-#else
-#define DUMMY_PARTITION_INIT_RUNTIME_DATA(data, partition) \
-    data.partition_state     = SPM_PARTITION_STATE_UNINIT; \
-    data.caller_partition_id = 0U;                         \
-    data.orig_psp            = 0U;                         \
-    data.orig_psplim         = 0U;                         \
-    data.orig_lr             = 0U;                         \
-    data.share               = 0U;                         \
-    data.stack_ptr           = 0U
-#endif
+#define PARTITION_ADD_PERIPHERAL(partition, start, limit, bank, loc)   \
+    do {                                                               \
+        uint32_t partition_idx = get_partition_idx(partition##_ID);    \
+        struct spm_partition_desc_t *part_ptr =                        \
+            &(g_spm_partition_db.partitions[partition_idx]);           \
+        part_ptr->static_data.periph_start = start;                    \
+        part_ptr->static_data.periph_limit = limit;                    \
+        part_ptr->static_data.periph_ppc_bank = bank;                  \
+        part_ptr->static_data.periph_ppc_loc = loc;                    \
+    } while (0)
 
-#define PARTITION_ADD(partition) {                                      \
-    if (index >= max_partitions) {                                      \
-        return max_partitions;                                          \
-    }                                                                   \
-    part_ptr = (struct spm_partition_desc_t *)&(db->partitions[index]); \
-    PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition);       \
-    PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition);     \
-    index++;                                                            \
-    }
-
-#define DUMMY_PARTITION_ADD(partition) {                                  \
-    if (index >= max_partitions) {                                        \
-        return max_partitions;                                            \
-    }                                                                     \
-    part_ptr = (struct spm_partition_desc_t *)&(db->partitions[index]);   \
-    DUMMY_PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition);   \
-    /* The runtime data is the same for the dummy partitions*/            \
-    DUMMY_PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
-    index++;                                                              \
-    }
-
-#define PARTITION_ADD_PERIPHERAL(partition, start, limit, bank, loc) {  \
-        part_ptr = &(db->partitions[PARTITION_ID_GET(partition##_ID)]); \
-        ((struct spm_partition_desc_t *)part_ptr)->                     \
-               static_data.periph_start = start;                        \
-        ((struct spm_partition_desc_t *)part_ptr)->                     \
-               static_data.periph_limit = limit;                        \
-        ((struct spm_partition_desc_t *)part_ptr)->                     \
-               static_data.periph_ppc_bank = bank;                      \
-        ((struct spm_partition_desc_t *)part_ptr)->                     \
-               static_data.periph_ppc_loc = loc;                        \
-    }
-
-#define PARTITION_ADD_INIT_FUNC(partition, init_func) {                 \
-        extern int32_t init_func(void);                                 \
-        part_ptr = &(db->partitions[PARTITION_ID_GET(partition##_ID)]); \
-        ((struct spm_partition_desc_t *)part_ptr)->                     \
-               static_data.partition_init = init_func;                  \
-    }
-
-/*This file is meant to be included twice*/
-#include "user_service_defines.inc"
-
-struct spm_partition_db_t;
-
-uint32_t create_user_partition_db(struct spm_partition_db_t *db,
-                                uint32_t max_partitions)
-{
-    uint32_t index = 0;
-    struct spm_partition_desc_t *part_ptr;
-
-#include "user_service_defines.inc"
-
-    return index;
-}
-
-#endif /* __SPM_SPM_DB_H__ */
+#endif /* __SPM_DB_H__ */
diff --git a/secure_fw/spm/spm_partition_defs.h b/secure_fw/spm/spm_partition_defs.h
new file mode 100644
index 0000000..4cf6420
--- /dev/null
+++ b/secure_fw/spm/spm_partition_defs.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __SPM_PARTITION_DEFS_H__
+#define __SPM_PARTITION_DEFS_H__
+
+/* FixMe: allocations to be settled.
+ * 8 bits reserved by TFM for secure partition Id in this prototype
+ */
+#define TFM_SP_BASE 256
+
+/* A reserved partition ID that is used for uninitialised data */
+#define INVALID_PARTITION_ID (~0U)
+
+/* ***** partition ID-s internal to the TFM ***** */
+/* From the SPM point of view the non secure processing environment is handled
+ * as a special secure partition. This simplifies the context switch
+ * operations.
+ */
+#define TFM_SP_NON_SECURE_ID (0)
+/* A dummy partition for TFM_SP_CORE is created to handle secure partition
+ * calls done directly from the core, before NS execution started.
+ */
+#define TFM_SP_CORE_ID (1)
+
+#ifdef TFM_PARTITION_TEST_CORE
+#define TFM_SP_CORE_TEST_ID (2)
+#define TFM_SP_CORE_TEST_2_ID (3)
+#endif /* TFM_PARTITION_TEST_CORE */
+
+/* Give SST test service next ID after core test services */
+#ifdef TFM_PARTITION_TEST_SST
+#define TFM_SP_SST_TEST_PARTITION_ID (4)
+#endif /* TFM_PARTITION_TEST_SST */
+
+/* ***** Normal partition ID-s ***** */
+#define TFM_SP_STORAGE_ID (TFM_SP_BASE)
+
+#endif /* __SPM_PARTITION_DEFS_H__ */
diff --git a/secure_fw/spm/user_partition_defines.inc b/secure_fw/spm/user_partition_defines.inc
new file mode 100644
index 0000000..6a387fe
--- /dev/null
+++ b/secure_fw/spm/user_partition_defines.inc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __USER_PARTITION_DEFINES_INC__
+#define __USER_PARTITION_DEFINES_INC__
+
+/* PARTITION_DECLARE have to be called for a service, before calling
+ * any of PARTITION_ADD_INIT_FUNC or PARTITION_ADD_PERIPHERAL
+ */
+
+#ifdef TFM_PARTITION_TEST_CORE
+/****************************** TFM_SP_CORE_TEST ******************************/
+PARTITION_DECLARE(TFM_SP_CORE_TEST);
+PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST, core_test_init);
+PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST,
+    MPS2_IO_FPGAIO_BASE_S, MPS2_IO_FPGAIO_BASE_S + 0xFFF,
+    PPC_SP_APB_PPC_EXP2, CMSDK_FPGA_IO_PPC_POS);
+
+/***************************** TFM_SP_CORE_TEST_2 *****************************/
+PARTITION_DECLARE(TFM_SP_CORE_TEST_2);
+PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST_2, core_test_2_init);
+#endif /* TFM_PARTITION_TEST_CORE */
+
+/******************************* TFM_SP_STORAGE *******************************/
+PARTITION_DECLARE(TFM_SP_STORAGE);
+PARTITION_ADD_INIT_FUNC(TFM_SP_STORAGE, sst_am_prepare);
+
+#ifdef TFM_PARTITION_TEST_SST
+/**************************** TFM_SP_SST_TEST_PARTITION ***********************/
+PARTITION_DECLARE(TFM_SP_SST_TEST_PARTITION);
+PARTITION_ADD_INIT_FUNC(TFM_SP_SST_TEST_PARTITION, sst_test_service_init);
+#endif /* TFM_PARTITION_TEST_SST */
+
+#endif /* __USER_PARTITION_DEFINES_INC__ */
diff --git a/secure_fw/spm/user_service_defines.inc b/secure_fw/spm/user_service_defines.inc
deleted file mode 100644
index 023835e..0000000
--- a/secure_fw/spm/user_service_defines.inc
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-/* The file is meant to be included twice */
-#ifndef __SPM_DECLARE_USER_PARTITIONS__
-#define __SPM_DECLARE_USER_PARTITIONS__
-
-#include "platform_retarget.h"
-#include "target_cfg.h"
-#include "service_defs.h"
-
-/* TFM_SP_NON_SECURE and TFM_SP_CORE are not real partitions, we
- * only created them to have an entry for them in the database. They don't have
- * their dedicated sections in the scatter file, so no symbols are needed to
- * be declared.
- */
-/* PARTITION_DECLARE(TFM_SP_NON_SECURE) */
-/* PARTITION_DECLARE(TFM_SP_CORE) */
-PARTITION_DECLARE(TFM_SP_STORAGE)
-
-#ifdef TFM_PARTITION_TEST_CORE
-PARTITION_DECLARE(TFM_SP_CORE_TEST)
-PARTITION_DECLARE(TFM_SP_CORE_TEST_2)
-#endif /* TFM_PARTITION_TEST_CORE */
-
-#ifdef TFM_PARTITION_TEST_SST
-PARTITION_DECLARE(TFM_SP_SST_TEST_PARTITION)
-#endif /* TFM_PARTITION_TEST_SST */
-
-#elif !defined(__SPM_ADD_USER_PARTITIONS__) /*__SPM_DECLARE_USER_PARTITIONS__*/
-#define __SPM_ADD_USER_PARTITIONS__
-
-/* Order must be same as id!!! */
-DUMMY_PARTITION_ADD(TFM_SP_NON_SECURE)
-DUMMY_PARTITION_ADD(TFM_SP_CORE)
-PARTITION_ADD(TFM_SP_STORAGE)
-
-#ifdef TFM_PARTITION_TEST_CORE
-PARTITION_ADD(TFM_SP_CORE_TEST)
-PARTITION_ADD(TFM_SP_CORE_TEST_2)
-#endif /* TFM_PARTITION_TEST_CORE */
-
-#ifdef TFM_PARTITION_TEST_SST
-PARTITION_ADD(TFM_SP_SST_TEST_PARTITION)
-#endif /* TFM_PARTITION_TEST_SST */
-
-PARTITION_ADD_INIT_FUNC(TFM_SP_STORAGE, sst_am_prepare)
-
-#ifdef TFM_PARTITION_TEST_CORE
-PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST, core_test_init)
-PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST,
-    MPS2_IO_FPGAIO_BASE_S, MPS2_IO_FPGAIO_BASE_S + 0xFFF,
-    PPC_SP_APB_PPC_EXP2, CMSDK_FPGA_IO_PPC_POS)
-PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST_2, core_test_2_init)
-#endif /* TFM_PARTITION_TEST_CORE */
-
-#ifdef TFM_PARTITION_TEST_SST
-PARTITION_ADD_INIT_FUNC(TFM_SP_SST_TEST_PARTITION, sst_test_service_init)
-#endif /* TFM_PARTITION_TEST_SST */
-
-#else /* __SPM_ADD_USER_PARTITIONS__ */
-#error "unexpected inclusion of the file"
-#endif /* __SPM_ADD_USER_PARTITIONS__ */