/* Copyright (c) 2017-2019 ARM Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*******************************************************************************
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * THIS FILE IS AN AUTO-GENERATED FILE - DO NOT MODIFY IT.
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * Template Version 1.0
 * Generated by tools/psa/generate_partition_code.py Version 1.1
 ******************************************************************************/

#include "cmsis.h"
#include "rtx_os.h"

#include "mbed_toolchain.h" /* For using MBED_ALIGN macro */

#include "spm_panic.h"
#include "spm_internal.h"
#include "handles_manager.h"
#include "mbed_spm_partitions.h"

#include "psa_manifest/sid.h"

extern spm_db_t g_spm;

/****************** Service Partitions ****************************************/

/* -----------------------------------------------------------------------------
 * ATTEST_SRV declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t attest_srv_thread_stack[8192] = {0};

static osRtxThread_t attest_srv_thread_cb = {0};
static const osThreadAttr_t attest_srv_thread_attr = {
    .name = "attest_srv",
    .attr_bits = 0,
    .cb_mem = &attest_srv_thread_cb,
    .cb_size = sizeof(attest_srv_thread_cb),
    .stack_mem = attest_srv_thread_stack,
    .stack_size = 8192,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t attest_srv_mutex = {0};
static const osMutexAttr_t attest_srv_mutex_attr = {
    .name = "attest_srv_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &attest_srv_mutex,
    .cb_size = sizeof(attest_srv_mutex),
};

spm_rot_service_t attest_srv_rot_services[] = {
    {
        .sid = PSA_ATTEST_GET_TOKEN_ID,
        .mask = PSA_ATTEST_GET_TOKEN,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ATTEST_GET_TOKEN_SIZE_ID,
        .mask = PSA_ATTEST_GET_TOKEN_SIZE,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ATTEST_INJECT_KEY_ID,
        .mask = PSA_ATTEST_INJECT_KEY,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

/* External SIDs used by ATTEST_SRV */
const uint32_t attest_srv_external_sids[7] = {
    PSA_CRYPTO_INIT_ID,
    PSA_HASH_ID,
    PSA_ASYMMETRIC_ID,
    PSA_KEY_MNG_ID,
    PSA_CRYPTO_FREE_ID,
    PSA_KEY_DERIVATION_ID,
    PSA_PLATFORM_LC_GET,
};

extern void attest_main(void *ptr);

void attest_srv_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&attest_srv_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition attest_srv!\n");
    }

    for (uint32_t i = 0; i < ATTEST_SRV_ROT_SRV_COUNT; ++i) {
        attest_srv_rot_services[i].partition = partition;
    }
    partition->rot_services = attest_srv_rot_services;

    partition->thread_id = osThreadNew(attest_main, NULL, &attest_srv_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition attest_srv!\n");
    }
}

/* -----------------------------------------------------------------------------
 * CRYPTO_SRV declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t crypto_srv_thread_stack[16384] = {0};

static osRtxThread_t crypto_srv_thread_cb = {0};
static const osThreadAttr_t crypto_srv_thread_attr = {
    .name = "crypto_srv",
    .attr_bits = 0,
    .cb_mem = &crypto_srv_thread_cb,
    .cb_size = sizeof(crypto_srv_thread_cb),
    .stack_mem = crypto_srv_thread_stack,
    .stack_size = 16384,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t crypto_srv_mutex = {0};
static const osMutexAttr_t crypto_srv_mutex_attr = {
    .name = "crypto_srv_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &crypto_srv_mutex,
    .cb_size = sizeof(crypto_srv_mutex),
};

spm_rot_service_t crypto_srv_rot_services[] = {
    {
        .sid = PSA_CRYPTO_INIT_ID,
        .mask = PSA_CRYPTO_INIT,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_MAC_ID,
        .mask = PSA_MAC,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_HASH_ID,
        .mask = PSA_HASH,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ASYMMETRIC_ID,
        .mask = PSA_ASYMMETRIC,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_SYMMETRIC_ID,
        .mask = PSA_SYMMETRIC,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_AEAD_ID,
        .mask = PSA_AEAD,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_KEY_MNG_ID,
        .mask = PSA_KEY_MNG,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_RNG_ID,
        .mask = PSA_RNG,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_CRYPTO_FREE_ID,
        .mask = PSA_CRYPTO_FREE,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_KEY_DERIVATION_ID,
        .mask = PSA_KEY_DERIVATION,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ENTROPY_ID,
        .mask = PSA_ENTROPY_INJECT,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

/* External SIDs used by CRYPTO_SRV */
const uint32_t crypto_srv_external_sids[4] = {
    PSA_ITS_GET,
    PSA_ITS_SET,
    PSA_ITS_INFO,
    PSA_ITS_REMOVE,
};

extern void crypto_main(void *ptr);

void crypto_srv_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&crypto_srv_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition crypto_srv!\n");
    }

    for (uint32_t i = 0; i < CRYPTO_SRV_ROT_SRV_COUNT; ++i) {
        crypto_srv_rot_services[i].partition = partition;
    }
    partition->rot_services = crypto_srv_rot_services;

    partition->thread_id = osThreadNew(crypto_main, NULL, &crypto_srv_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition crypto_srv!\n");
    }
}

/* -----------------------------------------------------------------------------
 * PLATFORM declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t platform_thread_stack[1024] = {0};

static osRtxThread_t platform_thread_cb = {0};
static const osThreadAttr_t platform_thread_attr = {
    .name = "platform",
    .attr_bits = 0,
    .cb_mem = &platform_thread_cb,
    .cb_size = sizeof(platform_thread_cb),
    .stack_mem = platform_thread_stack,
    .stack_size = 1024,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t platform_mutex = {0};
static const osMutexAttr_t platform_mutex_attr = {
    .name = "platform_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &platform_mutex,
    .cb_size = sizeof(platform_mutex),
};

spm_rot_service_t platform_rot_services[] = {
    {
        .sid = PSA_PLATFORM_LC_GET,
        .mask = PSA_PLATFORM_LC_GET_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_PLATFORM_LC_SET,
        .mask = PSA_PLATFORM_LC_SET_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_PLATFORM_SYSTEM_RESET,
        .mask = PSA_PLATFORM_SYSTEM_RESET_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

/* External SIDs used by PLATFORM */
const uint32_t platform_external_sids[1] = {
    PSA_ITS_RESET,
};

extern void platform_partition_entry(void *ptr);

void platform_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&platform_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition platform!\n");
    }

    for (uint32_t i = 0; i < PLATFORM_ROT_SRV_COUNT; ++i) {
        platform_rot_services[i].partition = partition;
    }
    partition->rot_services = platform_rot_services;

    partition->thread_id = osThreadNew(platform_partition_entry, NULL, &platform_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition platform!\n");
    }
}

/* -----------------------------------------------------------------------------
 * ITS declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t its_thread_stack[2048] = {0};

static osRtxThread_t its_thread_cb = {0};
static const osThreadAttr_t its_thread_attr = {
    .name = "its",
    .attr_bits = 0,
    .cb_mem = &its_thread_cb,
    .cb_size = sizeof(its_thread_cb),
    .stack_mem = its_thread_stack,
    .stack_size = 2048,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t its_mutex = {0};
static const osMutexAttr_t its_mutex_attr = {
    .name = "its_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &its_mutex,
    .cb_size = sizeof(its_mutex),
};

spm_rot_service_t its_rot_services[] = {
    {
        .sid = PSA_ITS_GET,
        .mask = PSA_ITS_GET_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ITS_SET,
        .mask = PSA_ITS_SET_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ITS_INFO,
        .mask = PSA_ITS_INFO_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ITS_REMOVE,
        .mask = PSA_ITS_REMOVE_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = PSA_ITS_RESET,
        .mask = PSA_ITS_RESET_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = false,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

extern void its_entry(void *ptr);

void its_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&its_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition its!\n");
    }

    for (uint32_t i = 0; i < ITS_ROT_SRV_COUNT; ++i) {
        its_rot_services[i].partition = partition;
    }
    partition->rot_services = its_rot_services;

    partition->thread_id = osThreadNew(its_entry, NULL, &its_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition its!\n");
    }
}


/****************** Test Partitions *******************************************/
#ifdef USE_PSA_TEST_PARTITIONS

#ifdef USE_CRYPTO_ACL_TEST
/* -----------------------------------------------------------------------------
 * CRYPTO_ACL_TEST declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t crypto_acl_test_thread_stack[512] = {0};

static osRtxThread_t crypto_acl_test_thread_cb = {0};
static const osThreadAttr_t crypto_acl_test_thread_attr = {
    .name = "crypto_acl_test",
    .attr_bits = 0,
    .cb_mem = &crypto_acl_test_thread_cb,
    .cb_size = sizeof(crypto_acl_test_thread_cb),
    .stack_mem = crypto_acl_test_thread_stack,
    .stack_size = 512,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t crypto_acl_test_mutex = {0};
static const osMutexAttr_t crypto_acl_test_mutex_attr = {
    .name = "crypto_acl_test_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &crypto_acl_test_mutex,
    .cb_size = sizeof(crypto_acl_test_mutex),
};

spm_rot_service_t crypto_acl_test_rot_services[] = {
    {
        .sid = CRYPTO_GENERATE_KEY,
        .mask = CRYPTO_GENERATE_KEY_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CRYPTO_OPEN_KEY,
        .mask = CRYPTO_OPEN_KEY_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CRYPTO_CLOSE_KEY,
        .mask = CRYPTO_CLOSE_KEY_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CRYPTO_DESTROY_KEY,
        .mask = CRYPTO_DESTROY_KEY_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CRYPTO_GET_KEY_ATTRIBUTES,
        .mask = CRYPTO_GET_KEY_ATTRIBUTES_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CRYPTO_IMPORT_KEY,
        .mask = CRYPTO_IMPORT_KEY_MSK,
        .partition = NULL,
        .min_version = 1,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

/* External SIDs used by CRYPTO_ACL_TEST */
const uint32_t crypto_acl_test_external_sids[1] = {
    PSA_KEY_MNG_ID,
};

extern void test_partition_main(void *ptr);

void crypto_acl_test_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&crypto_acl_test_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition crypto_acl_test!\n");
    }

    for (uint32_t i = 0; i < CRYPTO_ACL_TEST_ROT_SRV_COUNT; ++i) {
        crypto_acl_test_rot_services[i].partition = partition;
    }
    partition->rot_services = crypto_acl_test_rot_services;

    partition->thread_id = osThreadNew(test_partition_main, NULL, &crypto_acl_test_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition crypto_acl_test!\n");
    }
}

#endif  // USE_CRYPTO_ACL_TEST

#ifdef USE_CLIENT_TESTS_PART1
/* -----------------------------------------------------------------------------
 * CLIENT_TESTS_PART1 declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t client_tests_part1_thread_stack[1024] = {0};

static osRtxThread_t client_tests_part1_thread_cb = {0};
static const osThreadAttr_t client_tests_part1_thread_attr = {
    .name = "client_tests_part1",
    .attr_bits = 0,
    .cb_mem = &client_tests_part1_thread_cb,
    .cb_size = sizeof(client_tests_part1_thread_cb),
    .stack_mem = client_tests_part1_thread_stack,
    .stack_size = 1024,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t client_tests_part1_mutex = {0};
static const osMutexAttr_t client_tests_part1_mutex_attr = {
    .name = "client_tests_part1_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &client_tests_part1_mutex,
    .cb_size = sizeof(client_tests_part1_mutex),
};

spm_rot_service_t client_tests_part1_rot_services[] = {
    {
        .sid = CLIENT_TESTS_PART1_ROT_SRV1,
        .mask = PART1_ROT_SRV1_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CLIENT_TESTS_PART1_DROP_CONN,
        .mask = DROP_CONN_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = CLIENT_TESTS_PART1_SECURE_CLIENTS_ONLY,
        .mask = SECURE_CLIENTS_ONLY_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = false,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

extern void client_part_main(void *ptr);

void client_tests_part1_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&client_tests_part1_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition client_tests_part1!\n");
    }

    for (uint32_t i = 0; i < CLIENT_TESTS_PART1_ROT_SRV_COUNT; ++i) {
        client_tests_part1_rot_services[i].partition = partition;
    }
    partition->rot_services = client_tests_part1_rot_services;

    partition->thread_id = osThreadNew(client_part_main, NULL, &client_tests_part1_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition client_tests_part1!\n");
    }
}

#endif  // USE_CLIENT_TESTS_PART1

#ifdef USE_SERVER_TESTS_PART1
/* -----------------------------------------------------------------------------
 * SERVER_TESTS_PART1 declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t server_tests_part1_thread_stack[1024] = {0};

static osRtxThread_t server_tests_part1_thread_cb = {0};
static const osThreadAttr_t server_tests_part1_thread_attr = {
    .name = "server_tests_part1",
    .attr_bits = 0,
    .cb_mem = &server_tests_part1_thread_cb,
    .cb_size = sizeof(server_tests_part1_thread_cb),
    .stack_mem = server_tests_part1_thread_stack,
    .stack_size = 1024,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t server_tests_part1_mutex = {0};
static const osMutexAttr_t server_tests_part1_mutex_attr = {
    .name = "server_tests_part1_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &server_tests_part1_mutex,
    .cb_size = sizeof(server_tests_part1_mutex),
};

spm_rot_service_t server_tests_part1_rot_services[] = {
    {
        .sid = SERVER_TESTS_PART1_CONTROL,
        .mask = CONTROL_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = SERVER_TESTS_PART1_TEST,
        .mask = TEST_MSK,
        .partition = NULL,
        .min_version = 12,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

/* External SIDs used by SERVER_TESTS_PART1 */
const uint32_t server_tests_part1_external_sids[2] = {
    SERVER_TESTS_PART2_ROT_SRV_REVERSE,
    SERVER_TESTS_PART2_ROT_SRV_DB_TST,
};

extern void server_part1_main(void *ptr);

void server_tests_part1_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&server_tests_part1_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition server_tests_part1!\n");
    }

    for (uint32_t i = 0; i < SERVER_TESTS_PART1_ROT_SRV_COUNT; ++i) {
        server_tests_part1_rot_services[i].partition = partition;
    }
    partition->rot_services = server_tests_part1_rot_services;

    partition->thread_id = osThreadNew(server_part1_main, NULL, &server_tests_part1_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition server_tests_part1!\n");
    }
}

#endif  // USE_SERVER_TESTS_PART1

#ifdef USE_SERVER_TESTS_PART2
/* -----------------------------------------------------------------------------
 * SERVER_TESTS_PART2 declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t server_tests_part2_thread_stack[1024] = {0};

static osRtxThread_t server_tests_part2_thread_cb = {0};
static const osThreadAttr_t server_tests_part2_thread_attr = {
    .name = "server_tests_part2",
    .attr_bits = 0,
    .cb_mem = &server_tests_part2_thread_cb,
    .cb_size = sizeof(server_tests_part2_thread_cb),
    .stack_mem = server_tests_part2_thread_stack,
    .stack_size = 1024,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t server_tests_part2_mutex = {0};
static const osMutexAttr_t server_tests_part2_mutex_attr = {
    .name = "server_tests_part2_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &server_tests_part2_mutex,
    .cb_size = sizeof(server_tests_part2_mutex),
};

spm_rot_service_t server_tests_part2_rot_services[] = {
    {
        .sid = SERVER_TESTS_PART2_ROT_SRV_REVERSE,
        .mask = ROT_SRV_REVERSE_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = false,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
    {
        .sid = SERVER_TESTS_PART2_ROT_SRV_DB_TST,
        .mask = ROT_SRV_DB_TST_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_STRICT,
        .allow_nspe = false,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

extern void server_part2_main(void *ptr);

void server_tests_part2_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&server_tests_part2_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition server_tests_part2!\n");
    }

    for (uint32_t i = 0; i < SERVER_TESTS_PART2_ROT_SRV_COUNT; ++i) {
        server_tests_part2_rot_services[i].partition = partition;
    }
    partition->rot_services = server_tests_part2_rot_services;

    partition->thread_id = osThreadNew(server_part2_main, NULL, &server_tests_part2_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition server_tests_part2!\n");
    }
}

#endif  // USE_SERVER_TESTS_PART2

#ifdef USE_SMOKE_TESTS_PART1
/* -----------------------------------------------------------------------------
 * SMOKE_TESTS_PART1 declarations
 * -------------------------------------------------------------------------- */
MBED_ALIGN(8) static uint8_t smoke_tests_part1_thread_stack[512] = {0};

static osRtxThread_t smoke_tests_part1_thread_cb = {0};
static const osThreadAttr_t smoke_tests_part1_thread_attr = {
    .name = "smoke_tests_part1",
    .attr_bits = 0,
    .cb_mem = &smoke_tests_part1_thread_cb,
    .cb_size = sizeof(smoke_tests_part1_thread_cb),
    .stack_mem = smoke_tests_part1_thread_stack,
    .stack_size = 512,
    .priority = osPriorityNormal,
    .tz_module = 0,
    .reserved = 0
};

static osRtxMutex_t smoke_tests_part1_mutex = {0};
static const osMutexAttr_t smoke_tests_part1_mutex_attr = {
    .name = "smoke_tests_part1_mutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust,
    .cb_mem = &smoke_tests_part1_mutex,
    .cb_size = sizeof(smoke_tests_part1_mutex),
};

spm_rot_service_t smoke_tests_part1_rot_services[] = {
    {
        .sid = SMOKE_TESTS_PART1_ROT_SRV1,
        .mask = ROT_SRV1_MSK,
        .partition = NULL,
        .min_version = 5,
        .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED,
        .allow_nspe = true,
        .queue = {
            .head = NULL,
            .tail = NULL
        }
    },
};

extern void smoke_part_main(void *ptr);

void smoke_tests_part1_init(spm_partition_t *partition)
{
    if (NULL == partition) {
        SPM_PANIC("partition is NULL!\n");
    }

    partition->mutex = osMutexNew(&smoke_tests_part1_mutex_attr);
    if (NULL == partition->mutex) {
        SPM_PANIC("Failed to create mutex for secure partition smoke_tests_part1!\n");
    }

    for (uint32_t i = 0; i < SMOKE_TESTS_PART1_ROT_SRV_COUNT; ++i) {
        smoke_tests_part1_rot_services[i].partition = partition;
    }
    partition->rot_services = smoke_tests_part1_rot_services;

    partition->thread_id = osThreadNew(smoke_part_main, NULL, &smoke_tests_part1_thread_attr);
    if (NULL == partition->thread_id) {
        SPM_PANIC("Failed to create start main thread of partition smoke_tests_part1!\n");
    }
}

#endif  // USE_SMOKE_TESTS_PART1

#endif  // USE_PSA_TEST_PARTITIONS

/****************** SPM DB initialization *************************************/
spm_partition_t g_partitions[] = {
    /* ATTEST_SRV */
    {
        .partition_id = ATTEST_SRV_ID,
        .thread_id = 0,
        .flags = ATTEST_SRV_WAIT_ANY_SID_MSK | ATTEST_SRV_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = ATTEST_SRV_ROT_SRV_COUNT,
        .extern_sids = attest_srv_external_sids,
        .extern_sids_count = ATTEST_SRV_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },

    /* CRYPTO_SRV */
    {
        .partition_id = CRYPTO_SRV_ID,
        .thread_id = 0,
        .flags = CRYPTO_SRV_WAIT_ANY_SID_MSK | CRYPTO_SRV_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = CRYPTO_SRV_ROT_SRV_COUNT,
        .extern_sids = crypto_srv_external_sids,
        .extern_sids_count = CRYPTO_SRV_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },

    /* PLATFORM */
    {
        .partition_id = PLATFORM_ID,
        .thread_id = 0,
        .flags = PLATFORM_WAIT_ANY_SID_MSK | PLATFORM_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = PLATFORM_ROT_SRV_COUNT,
        .extern_sids = platform_external_sids,
        .extern_sids_count = PLATFORM_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },

    /* ITS */
    {
        .partition_id = ITS_ID,
        .thread_id = 0,
        .flags = ITS_WAIT_ANY_SID_MSK | ITS_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = ITS_ROT_SRV_COUNT,
        .extern_sids = NULL,
        .extern_sids_count = ITS_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },

#ifdef USE_PSA_TEST_PARTITIONS

#ifdef USE_CRYPTO_ACL_TEST /* CRYPTO_ACL_TEST */
    {
        .partition_id = CRYPTO_ACL_TEST_ID,
        .thread_id = 0,
        .flags = CRYPTO_ACL_TEST_WAIT_ANY_SID_MSK | CRYPTO_ACL_TEST_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = CRYPTO_ACL_TEST_ROT_SRV_COUNT,
        .extern_sids = crypto_acl_test_external_sids,
        .extern_sids_count = CRYPTO_ACL_TEST_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },
#endif  // USE_CRYPTO_ACL_TEST

#ifdef USE_CLIENT_TESTS_PART1 /* CLIENT_TESTS_PART1 */
    {
        .partition_id = CLIENT_TESTS_PART1_ID,
        .thread_id = 0,
        .flags = CLIENT_TESTS_PART1_WAIT_ANY_SID_MSK | CLIENT_TESTS_PART1_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = CLIENT_TESTS_PART1_ROT_SRV_COUNT,
        .extern_sids = NULL,
        .extern_sids_count = CLIENT_TESTS_PART1_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },
#endif  // USE_CLIENT_TESTS_PART1

#ifdef USE_SERVER_TESTS_PART1 /* SERVER_TESTS_PART1 */
    {
        .partition_id = SERVER_TESTS_PART1_ID,
        .thread_id = 0,
        .flags = SERVER_TESTS_PART1_WAIT_ANY_SID_MSK | SERVER_TESTS_PART1_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = SERVER_TESTS_PART1_ROT_SRV_COUNT,
        .extern_sids = server_tests_part1_external_sids,
        .extern_sids_count = SERVER_TESTS_PART1_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },
#endif  // USE_SERVER_TESTS_PART1

#ifdef USE_SERVER_TESTS_PART2 /* SERVER_TESTS_PART2 */
    {
        .partition_id = SERVER_TESTS_PART2_ID,
        .thread_id = 0,
        .flags = SERVER_TESTS_PART2_WAIT_ANY_SID_MSK | SERVER_TESTS_PART2_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = SERVER_TESTS_PART2_ROT_SRV_COUNT,
        .extern_sids = NULL,
        .extern_sids_count = SERVER_TESTS_PART2_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },
#endif  // USE_SERVER_TESTS_PART2

#ifdef USE_SMOKE_TESTS_PART1 /* SMOKE_TESTS_PART1 */
    {
        .partition_id = SMOKE_TESTS_PART1_ID,
        .thread_id = 0,
        .flags = SMOKE_TESTS_PART1_WAIT_ANY_SID_MSK | SMOKE_TESTS_PART1_WAIT_ANY_IRQ_MSK,
        .rot_services = NULL,
        .rot_services_count = SMOKE_TESTS_PART1_ROT_SRV_COUNT,
        .extern_sids = NULL,
        .extern_sids_count = SMOKE_TESTS_PART1_EXT_ROT_SRV_COUNT,
        .irq_mapper = NULL,
    },
#endif  // USE_SMOKE_TESTS_PART1

#endif  // USE_PSA_TEST_PARTITIONS

};

/****************** MMIO regions **********************************************/
const mem_region_t *mem_regions = NULL;
const uint32_t mem_region_count = 0;

/****************** Partitions init function  *********************************/
uint32_t init_partitions(spm_partition_t **partitions)
{
    uint32_t partition_idx = 0;

    if (NULL == partitions) {
        SPM_PANIC("partitions is NULL!\n");
    }

    attest_srv_init(&(g_partitions[partition_idx++]));
    crypto_srv_init(&(g_partitions[partition_idx++]));
    platform_init(&(g_partitions[partition_idx++]));
    its_init(&(g_partitions[partition_idx++]));

#ifdef USE_PSA_TEST_PARTITIONS

#ifdef USE_CRYPTO_ACL_TEST
    crypto_acl_test_init(&(g_partitions[partition_idx++]));
#endif  // USE_CRYPTO_ACL_TEST

#ifdef USE_CLIENT_TESTS_PART1
    client_tests_part1_init(&(g_partitions[partition_idx++]));
#endif  // USE_CLIENT_TESTS_PART1

#ifdef USE_SERVER_TESTS_PART1
    server_tests_part1_init(&(g_partitions[partition_idx++]));
#endif  // USE_SERVER_TESTS_PART1

#ifdef USE_SERVER_TESTS_PART2
    server_tests_part2_init(&(g_partitions[partition_idx++]));
#endif  // USE_SERVER_TESTS_PART2

#ifdef USE_SMOKE_TESTS_PART1
    smoke_tests_part1_init(&(g_partitions[partition_idx++]));
#endif  // USE_SMOKE_TESTS_PART1

#endif  // USE_PSA_TEST_PARTITIONS

    *partitions = g_partitions;
    return partition_idx;
}

