blob: 31696dce3c2cd11fd1d915072a4347cc5e950c4f [file] [log] [blame]
Mate Toth-Pale1475332018-04-09 17:28:49 +02001/*
Gyorgy Szing40a7af02019-02-06 14:19:47 +01002 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
Mate Toth-Pale1475332018-04-09 17:28:49 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef __SPM_DB_SETUP_H__
9#define __SPM_DB_SETUP_H__
10
11#include <stdint.h>
12#include "spm_db.h"
13
14/**
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020015 * \brief Get the index of a partition.
Mate Toth-Pale1475332018-04-09 17:28:49 +020016 *
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020017 * Gets the index of a partition in the partition db based on the partition ID
18 * provided as a parameter.
Mate Toth-Pale1475332018-04-09 17:28:49 +020019 *
Gyorgy Szing40a7af02019-02-06 14:19:47 +010020 * \param[in] partition_idx The index of the partition
Mate Toth-Pale1475332018-04-09 17:28:49 +020021 *
Gyorgy Szing40a7af02019-02-06 14:19:47 +010022 * \return \ref INVALID_PARTITION_IDX if the provided index is invalid. The
23 * index of the partition otherwise.
Mate Toth-Pale1475332018-04-09 17:28:49 +020024 */
25uint32_t get_partition_idx(uint32_t partition_id);
26
27struct spm_partition_db_t {
28 uint32_t is_init;
29 uint32_t partition_count;
30 uint32_t running_partition_idx;
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020031 struct spm_partition_desc_t partitions[SPM_MAX_PARTITIONS];
Mate Toth-Pale1475332018-04-09 17:28:49 +020032};
33
Edison Aibb614aa2018-11-21 15:15:00 +080034#define PARTITION_INIT_STATIC_DATA(data, partition, flags, id, priority) \
35 do { \
36 data.partition_id = partition##_ID; \
37 data.partition_flags = flags; \
38 data.partition_priority = TFM_PRIORITY(priority); \
Mate Toth-Pale1475332018-04-09 17:28:49 +020039 } while (0)
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020040
Miklos Balintdd02bb32019-05-26 21:13:12 +020041#if (TFM_LVL == 1) && !defined(TFM_PSA_API)
42#define PARTITION_INIT_MEMORY_DATA(data, partition)
43#else
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020044#define PARTITION_INIT_MEMORY_DATA(data, partition) \
Mate Toth-Pale1475332018-04-09 17:28:49 +020045 do { \
Mate Toth-Pale1475332018-04-09 17:28:49 +020046 data.code_start = PART_REGION_ADDR(partition, $$Base); \
47 data.code_limit = PART_REGION_ADDR(partition, $$Limit); \
48 data.ro_start = PART_REGION_ADDR(partition, $$RO$$Base); \
49 data.ro_limit = PART_REGION_ADDR(partition, $$RO$$Limit); \
50 data.rw_start = PART_REGION_ADDR(partition, _DATA$$RW$$Base); \
51 data.rw_limit = PART_REGION_ADDR(partition, _DATA$$RW$$Limit); \
52 data.zi_start = PART_REGION_ADDR(partition, _DATA$$ZI$$Base); \
53 data.zi_limit = PART_REGION_ADDR(partition, _DATA$$ZI$$Limit); \
54 data.stack_bottom = PART_REGION_ADDR(partition, _STACK$$ZI$$Base); \
55 data.stack_top = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
56 } while (0)
Miklos Balintdd02bb32019-05-26 21:13:12 +020057#endif
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020058
Mate Toth-Pal4341de02018-10-02 12:55:47 +020059/* The max size of the context stack can be calculated as a function of the IRQ
60 * count of the secure partition:
61 *
62 * max_stack_size = intr_ctx_size + (IRQ_CNT * (intr_ctx_size + hndl_ctx_size))
63 *
64 * where:
65 * intr_ctx: Frame pushed when the partition is interrupted
66 * hndl_ctx: Frame pushed when the partition is handling an interrupt
67 */
68#define DECLARE_CONTEXT_STACK(partition) \
69 static uint32_t ctx_stack_ptr_##partition[ \
70 (sizeof(struct interrupted_ctx_stack_frame_t) + \
71 (TFM_PARTITION_##partition##_IRQ_COUNT) * ( \
72 sizeof(struct interrupted_ctx_stack_frame_t) + \
73 sizeof(struct handler_ctx_stack_frame_t) \
74 )) / sizeof(uint32_t)]
75
Mate Toth-Pale1475332018-04-09 17:28:49 +020076#if TFM_LVL == 1
Mate Toth-Pal4341de02018-10-02 12:55:47 +020077#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
78 do { \
79 DECLARE_CONTEXT_STACK(partition); \
80 data.partition_state = SPM_PARTITION_STATE_UNINIT; \
81 data.ctx_stack_ptr = ctx_stack_ptr_##partition; \
Mate Toth-Pale1475332018-04-09 17:28:49 +020082 } while (0)
83#else
84#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
85 do { \
Mate Toth-Pal4341de02018-10-02 12:55:47 +020086 DECLARE_CONTEXT_STACK(partition); \
87 data.partition_state = SPM_PARTITION_STATE_UNINIT; \
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020088 /* The top of the stack is reserved for the iovec */ \
89 /* parameters of the service called. That's why in */ \
90 /* data.stack_ptr we extract sizeof(struct iovec_args_t) */ \
91 /* from the limit. */ \
Mate Toth-Pal4341de02018-10-02 12:55:47 +020092 data.stack_ptr = \
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020093 PART_REGION_ADDR(partition, _STACK$$ZI$$Limit - \
94 sizeof(struct iovec_args_t)); \
Mate Toth-Pal4341de02018-10-02 12:55:47 +020095 data.ctx_stack_ptr = ctx_stack_ptr_##partition; \
Mate Toth-Pale1475332018-04-09 17:28:49 +020096 } while (0)
97#endif
98
Edison Aibb614aa2018-11-21 15:15:00 +080099#define PARTITION_DECLARE(partition, flag, type, id, priority) \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200100 do { \
101 REGION_DECLARE(Image$$, partition, $$Base); \
102 REGION_DECLARE(Image$$, partition, $$Limit); \
103 REGION_DECLARE(Image$$, partition, $$RO$$Base); \
104 REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
105 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
106 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
107 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
108 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
109 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
110 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
Edison Aibb614aa2018-11-21 15:15:00 +0800111 int32_t flags = flag; \
112 if (tfm_memcmp(type, TFM_PARTITION_TYPE_APP, \
113 strlen(TFM_PARTITION_TYPE_APP)) == 0) { \
114 flags |= SPM_PART_FLAG_APP_ROT; \
115 } else if (tfm_memcmp(type, TFM_PARTITION_TYPE_PSA, \
116 strlen(TFM_PARTITION_TYPE_PSA)) == 0) { \
117 flags |= SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT; \
118 } else { \
119 return SPM_ERR_INVALID_CONFIG; \
120 } \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200121 struct spm_partition_desc_t *part_ptr; \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200122 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
123 return SPM_ERR_INVALID_CONFIG; \
124 } \
125 part_ptr = &(g_spm_partition_db.partitions[ \
126 g_spm_partition_db.partition_count]); \
Edison Aibb614aa2018-11-21 15:15:00 +0800127 PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags, \
128 id, priority); \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200129 PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200130 PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200131 ++g_spm_partition_db.partition_count; \
132 } while (0)
133
Hugues de Valonf704c802019-02-19 14:51:41 +0000134#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
135 do { \
136 extern int32_t init_func(void); \
137 uint32_t partition_idx = get_partition_idx(partition##_ID); \
138 struct spm_partition_desc_t *part_ptr = \
139 &(g_spm_partition_db.partitions[partition_idx]); \
140 part_ptr->static_data.partition_init = init_func; \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200141 } while (0)
142
Hugues de Valonf704c802019-02-19 14:51:41 +0000143#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
144 do { \
145 uint32_t partition_idx = get_partition_idx(partition##_ID); \
146 struct spm_partition_desc_t *part_ptr = \
147 &(g_spm_partition_db.partitions[partition_idx]); \
148 part_ptr->platform_data = peripheral; \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200149 } while (0)
150
151#endif /* __SPM_DB_SETUP_H__ */