blob: 5c6d1b4dfde27c58d5d64f96944a027e2403a7da [file] [log] [blame]
Miklos Balint386b8b52017-11-29 13:12:32 +00001/*
Mate Toth-Pal65291f32018-02-23 14:35:22 +01002 * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
Miklos Balint386b8b52017-11-29 13:12:32 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef __SPM_SPM_DB_H__
9#define __SPM_SPM_DB_H__
10
11#include <stdint.h>
12
13/* This limit is only used to define the size of the database reserved for
Mate Toth-Pal349714a2018-02-23 15:30:24 +010014 * partitions. There's no requirement that it match the number of partitions
Miklos Balint386b8b52017-11-29 13:12:32 +000015 * that get registered in a specific build
16 */
Mate Toth-Pal349714a2018-02-23 15:30:24 +010017#define SPM_MAX_PARTITIONS (6)
Miklos Balint386b8b52017-11-29 13:12:32 +000018
Mate Toth-Pal349714a2018-02-23 15:30:24 +010019#define PARTITION_ID_GET(id) (id - TFM_SP_BASE)
Miklos Balint386b8b52017-11-29 13:12:32 +000020
Mate Toth-Pal349714a2018-02-23 15:30:24 +010021typedef int32_t(*sp_init_function)(void);
Miklos Balint386b8b52017-11-29 13:12:32 +000022
23#if TFM_LVL == 1
Mate Toth-Pal349714a2018-02-23 15:30:24 +010024struct spm_partition_region_t {
25 uint32_t partition_id;
26 uint32_t partition_state;
27 uint32_t caller_partition_id;
Mate Toth-Pal65291f32018-02-23 14:35:22 +010028 uint32_t orig_psp;
29 uint32_t orig_psplim;
30 uint32_t orig_lr;
31 uint32_t share;
Miklos Balint386b8b52017-11-29 13:12:32 +000032 uint32_t stack_ptr;
33 uint32_t periph_start;
34 uint32_t periph_limit;
35 uint16_t periph_ppc_bank;
36 uint16_t periph_ppc_loc;
Mate Toth-Pal349714a2018-02-23 15:30:24 +010037 sp_init_function partition_init;
Miklos Balint386b8b52017-11-29 13:12:32 +000038};
39#else
Mate Toth-Pal349714a2018-02-23 15:30:24 +010040struct spm_partition_region_t {
41 uint32_t partition_id;
42 uint32_t partition_state;
43 uint32_t caller_partition_id;
Mate Toth-Pal65291f32018-02-23 14:35:22 +010044 uint32_t orig_psp;
45 uint32_t orig_psplim;
46 uint32_t orig_lr;
47 uint32_t share;
Miklos Balint386b8b52017-11-29 13:12:32 +000048 uint32_t code_start;
49 uint32_t code_limit;
50 uint32_t ro_start;
51 uint32_t ro_limit;
52 uint32_t rw_start;
53 uint32_t rw_limit;
54 uint32_t zi_start;
55 uint32_t zi_limit;
56 uint32_t stack_bottom;
57 uint32_t stack_top;
58 uint32_t stack_ptr;
59 uint32_t periph_start;
60 uint32_t periph_limit;
61 uint16_t periph_ppc_bank;
62 uint16_t periph_ppc_loc;
Mate Toth-Pal349714a2018-02-23 15:30:24 +010063 sp_init_function partition_init;
Miklos Balint386b8b52017-11-29 13:12:32 +000064};
65#endif
66
Mate Toth-Pal349714a2018-02-23 15:30:24 +010067struct spm_partition_db_t {
Miklos Balint386b8b52017-11-29 13:12:32 +000068 uint32_t is_init;
Mate Toth-Pal349714a2018-02-23 15:30:24 +010069 uint32_t partition_count;
70 uint32_t running_partition_id;
71 struct spm_partition_region_t partitions[SPM_MAX_PARTITIONS];
Miklos Balint386b8b52017-11-29 13:12:32 +000072};
73
Mate Toth-Pal349714a2018-02-23 15:30:24 +010074/* Macros to pick linker symbols and allow to form the partition data base */
Miklos Balint386b8b52017-11-29 13:12:32 +000075#define REGION(a, b, c) a##b##c
76#define REGION_NAME(a, b, c) REGION(a, b, c)
77#if TFM_LVL == 1
78#define REGION_DECLARE(a, b, c)
79#else
80#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
81#endif
82
Mate Toth-Pal349714a2018-02-23 15:30:24 +010083#define PARTITION_DECLARE(partition) \
84 REGION_DECLARE(Image$$, partition, $$Base); \
85 REGION_DECLARE(Image$$, partition, $$Limit); \
86 REGION_DECLARE(Image$$, partition, $$RO$$Base); \
87 REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
88 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
89 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
90 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
91 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
92 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
93 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
Miklos Balint386b8b52017-11-29 13:12:32 +000094
95
96#if TFM_LVL == 1
Mate Toth-Pal349714a2018-02-23 15:30:24 +010097#define PARTITION_ADD(partition) { \
98 if (index >= max_partitions) { \
99 return max_partitions; \
100 } \
101 db_ptr = (uint32_t *)&(db->partitions[index]); \
102 *db_ptr++ = partition##_ID; \
103 *db_ptr++ = SPM_PARTITION_STATE_UNINIT; /* partition_state */ \
104 *db_ptr++ = 0U; /* caller partition id */ \
105 *db_ptr++ = 0U; /* original psp */ \
106 *db_ptr++ = 0U; /* original psplim */ \
107 *db_ptr++ = 0U; /* original lr */ \
108 *db_ptr++ = 0U; /* share */ \
109 *db_ptr++ = 0U; /* stack pointer on partition enter */ \
110 *db_ptr++ = 0U; /* peripheral start */ \
111 *db_ptr++ = 0U; /* peripheral limit */ \
112 *db_ptr++ = 0U; /* uint16_t[2] peripheral bank/loc */ \
113 *db_ptr++ = 0U; /* partition init function*/ \
114 index++; \
Miklos Balint386b8b52017-11-29 13:12:32 +0000115 }
116#else
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100117#define PARTITION_ADD(partition) { \
118 if (index >= max_partitions) { \
119 return max_partitions; \
120 } \
121 db_ptr = (uint32_t *)&(db->partitions[index]); \
122 *db_ptr++ = partition##_ID; \
123 *db_ptr++ = SPM_PARTITION_STATE_UNINIT; /* partition_state */ \
124 *db_ptr++ = 0U; /* caller partition id */ \
125 *db_ptr++ = 0U; /* original psp */ \
126 *db_ptr++ = 0U; /* original psplim */ \
127 *db_ptr++ = 0U; /* original lr */ \
128 *db_ptr++ = 0U; /* share */ \
129 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, $$Base); \
130 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, $$Limit); \
131 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, $$RO$$Base); \
132 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, $$RO$$Limit); \
133 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _DATA$$RW$$Base); \
134 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _DATA$$RW$$Limit); \
135 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _DATA$$ZI$$Base); \
136 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _DATA$$ZI$$Limit); \
137 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _STACK$$ZI$$Base); \
138 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _STACK$$ZI$$Limit); \
139 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, partition, _STACK$$ZI$$Limit); \
140 *db_ptr++ = 0U; /* peripheral start */ \
141 *db_ptr++ = 0U; /* peripheral limit */ \
142 *db_ptr++ = 0U; /* uint16_t[2] peripheral bank/loc */ \
143 *db_ptr++ = 0U; /* partition init function*/ \
144 index++; \
Miklos Balint386b8b52017-11-29 13:12:32 +0000145}
146#endif
147
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100148#if TFM_LVL == 1
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100149#define DUMMY_PARTITION_ADD(partition) { \
150 if (index >= max_partitions) { \
151 return max_partitions; \
152 } \
153 db_ptr = (uint32_t *)&(db->partitions[index]); \
154 *db_ptr++ = partition##_ID; \
155 *db_ptr++ = SPM_PARTITION_STATE_UNINIT; /* partition_state */ \
156 *db_ptr++ = 0U; /* caller partition id */ \
157 *db_ptr++ = 0U; /* original psp */ \
158 *db_ptr++ = 0U; /* original psplim */ \
159 *db_ptr++ = 0U; /* original lr */ \
160 *db_ptr++ = 0U; /* share */ \
161 *db_ptr++ = 0U; /* stack pointer on partition enter */ \
162 *db_ptr++ = 0U; /* peripheral start */ \
163 *db_ptr++ = 0U; /* peripheral limit */ \
164 *db_ptr++ = 0U; /* uint16_t[2] peripheral bank/loc */ \
165 *db_ptr++ = 0U; /* partition init function*/ \
166 index++; \
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100167 }
168#else
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100169#define DUMMY_PARTITION_ADD(partition) { \
170 if (index >= max_partitions) { \
171 return max_partitions; \
172 } \
173 db_ptr = (uint32_t *)&(db->partitions[index]); \
174 *db_ptr++ = partition##_ID; \
175 *db_ptr++ = SPM_PARTITION_STATE_UNINIT; /* partition_state */ \
176 *db_ptr++ = 0U; /* caller partition id */ \
177 *db_ptr++ = 0U; /* original_psp */ \
178 *db_ptr++ = 0U; /* original_psplim */ \
179 *db_ptr++ = 0U; /* original_lr */ \
180 *db_ptr++ = 0U; /* share */ \
181 *db_ptr++ = 0U; \
182 *db_ptr++ = 0U; \
183 *db_ptr++ = 0U; \
184 *db_ptr++ = 0U; \
185 *db_ptr++ = 0U; \
186 *db_ptr++ = 0U; \
187 *db_ptr++ = 0U; \
188 *db_ptr++ = 0U; \
189 *db_ptr++ = 0U; \
190 *db_ptr++ = 0U; \
191 *db_ptr++ = 0U; \
192 *db_ptr++ = 0U; /* peripheral start */ \
193 *db_ptr++ = 0U; /* peripheral limit */ \
194 *db_ptr++ = 0U; /* uint16_t[2] peripheral bank/loc */ \
195 *db_ptr++ = 0U; /* partition init function*/ \
196 index++; \
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100197}
198#endif
199
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100200#define PARTITION_ADD_PERIPHERAL(partition, start, limit, bank, loc) { \
201 db_ptr = \
202 (uint32_t *)&(db->partitions[PARTITION_ID_GET(partition##_ID)]);\
203 ((struct spm_partition_region_t *)db_ptr)->periph_start = start; \
204 ((struct spm_partition_region_t *)db_ptr)->periph_limit = limit; \
205 ((struct spm_partition_region_t *)db_ptr)->periph_ppc_bank = bank; \
206 ((struct spm_partition_region_t *)db_ptr)->periph_ppc_loc = loc; \
Miklos Balint386b8b52017-11-29 13:12:32 +0000207 }
208
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100209#define PARTITION_ADD_INIT_FUNC(partition, init_func) { \
210 extern int32_t init_func(void); \
211 db_ptr = \
212 (uint32_t *)&(db->partitions[PARTITION_ID_GET(partition##_ID)]);\
213 ((struct spm_partition_region_t *)db_ptr)->partition_init = init_func; \
Miklos Balint386b8b52017-11-29 13:12:32 +0000214 }
215
216/*This file is meant to be included twice*/
217#include "user_service_defines.inc"
218
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100219struct spm_partition_db_t;
Miklos Balint386b8b52017-11-29 13:12:32 +0000220
Mate Toth-Pal349714a2018-02-23 15:30:24 +0100221uint32_t create_user_partition_db(struct spm_partition_db_t *db,
222 uint32_t max_partitions)
Miklos Balint386b8b52017-11-29 13:12:32 +0000223{
224 uint32_t index = 0;
225 uint32_t *db_ptr;
226
227#include "user_service_defines.inc"
228
229 return index;
230}
231
232#endif /* __SPM_SPM_DB_H__ */