blob: 4862798c0c7a64852eb767c3b158ab8e20d84123 [file] [log] [blame]
Mate Toth-Pale1475332018-04-09 17:28:49 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
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/**
15 * \brief Return the index of a partition.
16 *
17 * Returns the index of a partition in the partition db based on the partition
18 * ID provided as a parameter.
19 *
20 * \param[in] partition_id The ID of the partition
21 *
22 * \return \ref INVALID_PARTITION_IDX if the provided ID is invalid. The index
23 * of the partition otherwise.
24 */
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;
31 struct tfm_spm_partition_desc_t partitions[SPM_MAX_PARTITIONS];
32};
33
34/* Macros to pick linker symbols and allow to form the partition data base */
35#define REGION(a, b, c) a##b##c
36#define REGION_NAME(a, b, c) REGION(a, b, c)
37#if TFM_LVL == 1
38#define REGION_DECLARE(a, b, c)
39#else
40#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
41#define PART_REGION_ADDR(partition, region) \
42 (uint32_t)&REGION_NAME(Image$$, partition, region)
43#endif
44
45
46#if TFM_LVL == 1
47#define PARTITION_INIT_STATIC_DATA(data, partition, flags) \
48 do { \
49 data.partition_id = partition##_ID; \
50 data.partition_flags = flags; \
51 } while (0)
52#else
53#define PARTITION_INIT_STATIC_DATA(data, partition, flags) \
54 do { \
55 data.partition_id = partition##_ID; \
56 data.partition_flags = flags; \
57 data.code_start = PART_REGION_ADDR(partition, $$Base); \
58 data.code_limit = PART_REGION_ADDR(partition, $$Limit); \
59 data.ro_start = PART_REGION_ADDR(partition, $$RO$$Base); \
60 data.ro_limit = PART_REGION_ADDR(partition, $$RO$$Limit); \
61 data.rw_start = PART_REGION_ADDR(partition, _DATA$$RW$$Base); \
62 data.rw_limit = PART_REGION_ADDR(partition, _DATA$$RW$$Limit); \
63 data.zi_start = PART_REGION_ADDR(partition, _DATA$$ZI$$Base); \
64 data.zi_limit = PART_REGION_ADDR(partition, _DATA$$ZI$$Limit); \
65 data.stack_bottom = PART_REGION_ADDR(partition, _STACK$$ZI$$Base); \
66 data.stack_top = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
67 } while (0)
68#endif
69
70#if TFM_LVL == 1
71#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
72 do { \
73 data.partition_state = SPM_PARTITION_STATE_UNINIT; \
74 } while (0)
75#else
76#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
77 do { \
78 data.partition_state = SPM_PARTITION_STATE_UNINIT; \
79 data.stack_ptr = \
80 PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
81 } while (0)
82#endif
83
84#define PARTITION_DECLARE(partition, flags) \
85 do { \
86 REGION_DECLARE(Image$$, partition, $$Base); \
87 REGION_DECLARE(Image$$, partition, $$Limit); \
88 REGION_DECLARE(Image$$, partition, $$RO$$Base); \
89 REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
90 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
91 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
92 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
93 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
94 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
95 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
96 struct tfm_spm_partition_desc_t *part_ptr; \
97 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
98 return SPM_ERR_INVALID_CONFIG; \
99 } \
100 part_ptr = &(g_spm_partition_db.partitions[ \
101 g_spm_partition_db.partition_count]); \
102 PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags); \
103 PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
104 ++g_spm_partition_db.partition_count; \
105 } while (0)
106
107#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
108 do { \
109 extern int32_t init_func(void); \
110 uint32_t partition_idx = get_partition_idx(partition##_ID); \
111 struct tfm_spm_partition_desc_t *part_ptr = \
112 &(g_spm_partition_db.partitions[partition_idx]); \
113 part_ptr->static_data.partition_init = init_func; \
114 } while (0)
115
116#define PARTITION_ADD_PERIPHERAL(partition, start, limit, bank, loc) \
117 do { \
118 uint32_t partition_idx = get_partition_idx(partition##_ID); \
119 struct tfm_spm_partition_desc_t *part_ptr = \
120 &(g_spm_partition_db.partitions[partition_idx]); \
121 part_ptr->platform_data.periph_start = start; \
122 part_ptr->platform_data.periph_limit = limit; \
123 part_ptr->platform_data.periph_ppc_bank = bank; \
124 part_ptr->platform_data.periph_ppc_loc = loc; \
125 } while (0)
126
127#endif /* __SPM_DB_SETUP_H__ */