blob: cb3dd3a4af8eff507d54e1badf78f0748d3862f6 [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
14 * services. There's no requirement that it match the number of services
15 * that get registered in a specific build
16 */
17#define SPM_MAX_SERVICES (6)
18
19#define SERVICE_ID_GET(id) (id - TFM_SEC_FUNC_BASE)
20
21typedef int32_t(*ss_init_function)(void);
22
23#if TFM_LVL == 1
24struct spm_service_region_t {
25 uint32_t service_id;
Mate Toth-Pal65291f32018-02-23 14:35:22 +010026 uint32_t service_state;
27 uint32_t caller_service_id;
28 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;
37 ss_init_function service_init;
38};
39#else
40struct spm_service_region_t {
41 uint32_t service_id;
Mate Toth-Pal65291f32018-02-23 14:35:22 +010042 uint32_t service_state;
43 uint32_t caller_service_id;
44 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;
63 ss_init_function service_init;
64};
65#endif
66
67struct spm_service_db_t {
68 uint32_t is_init;
69 uint32_t services_count;
Mate Toth-Pal65291f32018-02-23 14:35:22 +010070 uint32_t running_service_id;
Miklos Balint386b8b52017-11-29 13:12:32 +000071 struct spm_service_region_t services[SPM_MAX_SERVICES];
72};
73
74/* Macros to pick linker symbols and allow to form the service data base */
75#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
83#define SERVICE_DECLARE(service) \
84 REGION_DECLARE(Image$$, service, $$Base); \
85 REGION_DECLARE(Image$$, service, $$Limit); \
86 REGION_DECLARE(Image$$, service, $$RO$$Base); \
87 REGION_DECLARE(Image$$, service, $$RO$$Limit); \
88 REGION_DECLARE(Image$$, service, _DATA$$RW$$Base); \
89 REGION_DECLARE(Image$$, service, _DATA$$RW$$Limit); \
90 REGION_DECLARE(Image$$, service, _DATA$$ZI$$Base); \
91 REGION_DECLARE(Image$$, service, _DATA$$ZI$$Limit); \
92 REGION_DECLARE(Image$$, service, _STACK$$ZI$$Base); \
93 REGION_DECLARE(Image$$, service, _STACK$$ZI$$Limit); \
94
95
96#if TFM_LVL == 1
97#define SERVICE_ADD(service) { \
98 if (index >= max_services) { \
99 return max_services; \
100 } \
101 db_ptr = (uint32_t *)&(db->services[index]); \
102 *db_ptr++ = service##_ID; \
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100103 *db_ptr++ = SPM_PART_STATE_UNINIT; /* service_state */ \
104 *db_ptr++ = 0U; /* caller service id */ \
105 *db_ptr++ = 0U; /* original psp */ \
106 *db_ptr++ = 0U; /* original psplim */ \
107 *db_ptr++ = 0U; /* original lr */ \
108 *db_ptr++ = 0U; /* share */ \
Miklos Balint386b8b52017-11-29 13:12:32 +0000109 *db_ptr++ = 0U; /* stack pointer on service 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; /* service init function*/ \
114 index++; \
115 }
116#else
117#define SERVICE_ADD(service) { \
118 if (index >= max_services) { \
119 return max_services; \
120 } \
121 db_ptr = (uint32_t *)&(db->services[index]); \
122 *db_ptr++ = service##_ID; \
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100123 *db_ptr++ = SPM_PART_STATE_UNINIT; /* service_state */ \
124 *db_ptr++ = 0U; /* caller service id */ \
125 *db_ptr++ = 0U; /* original psp */ \
126 *db_ptr++ = 0U; /* original psplim */ \
127 *db_ptr++ = 0U; /* original lr */ \
128 *db_ptr++ = 0U; /* share */ \
Miklos Balint386b8b52017-11-29 13:12:32 +0000129 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, $$Base); \
130 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, $$Limit); \
131 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, $$RO$$Base); \
132 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, $$RO$$Limit); \
133 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _DATA$$RW$$Base); \
134 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _DATA$$RW$$Limit); \
135 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _DATA$$ZI$$Base); \
136 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _DATA$$ZI$$Limit); \
137 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _STACK$$ZI$$Base); \
138 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _STACK$$ZI$$Limit); \
139 *db_ptr++ = (uint32_t)&REGION_NAME(Image$$, service, _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; /* service init function*/ \
144 index++; \
145}
146#endif
147
Mate Toth-Pal65291f32018-02-23 14:35:22 +0100148#if TFM_LVL == 1
149#define DUMMY_SERVICE_ADD(service) { \
150 if (index >= max_services) { \
151 return max_services; \
152 } \
153 db_ptr = (uint32_t *)&(db->services[index]); \
154 *db_ptr++ = service##_ID; \
155 *db_ptr++ = SPM_PART_STATE_UNINIT; /* service_state */ \
156 *db_ptr++ = 0U; /* caller service 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 service 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; /* service init function*/ \
166 index++; \
167 }
168#else
169#define DUMMY_SERVICE_ADD(service) { \
170 if (index >= max_services) { \
171 return max_services; \
172 } \
173 db_ptr = (uint32_t *)&(db->services[index]); \
174 *db_ptr++ = service##_ID; \
175 *db_ptr++ = SPM_PART_STATE_UNINIT; /* service_state */ \
176 *db_ptr++ = 0U; /* caller service 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; /* service init function*/ \
196 index++; \
197}
198#endif
199
Miklos Balint386b8b52017-11-29 13:12:32 +0000200#define SERVICE_ADD_PERIPHERAL(service, start, limit, bank, loc) { \
201 db_ptr = (uint32_t *)&(db->services[SERVICE_ID_GET(service##_ID)]); \
202 ((struct spm_service_region_t *)db_ptr)->periph_start = start; \
203 ((struct spm_service_region_t *)db_ptr)->periph_limit = limit; \
204 ((struct spm_service_region_t *)db_ptr)->periph_ppc_bank = bank; \
205 ((struct spm_service_region_t *)db_ptr)->periph_ppc_loc = loc; \
206 }
207
208#define SERVICE_ADD_INIT_FUNC(service, init_func) { \
209 extern int32_t init_func(void); \
210 db_ptr = (uint32_t *)&(db->services[SERVICE_ID_GET(service##_ID)]); \
211 ((struct spm_service_region_t *)db_ptr)->service_init = init_func; \
212 }
213
214/*This file is meant to be included twice*/
215#include "user_service_defines.inc"
216
217struct spm_service_db_t;
218
219uint32_t create_user_service_db(struct spm_service_db_t *db,
220 uint32_t max_services)
221{
222 uint32_t index = 0;
223 uint32_t *db_ptr;
224
225#include "user_service_defines.inc"
226
227 return index;
228}
229
230#endif /* __SPM_SPM_DB_H__ */