blob: e1c53d2dfe05cfd5cf2da7a60b74d30073e83b50 [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/**
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 *
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;
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
Mate Toth-Pale1475332018-04-09 17:28:49 +020034#define PARTITION_INIT_STATIC_DATA(data, partition, flags) \
35 do { \
36 data.partition_id = partition##_ID; \
37 data.partition_flags = flags; \
38 } while (0)
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020039
40#if TFM_LVL == 1
41#define PARTITION_INIT_MEMORY_DATA(data, partition)
Mate Toth-Pale1475332018-04-09 17:28:49 +020042#else
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020043#define PARTITION_INIT_MEMORY_DATA(data, partition) \
Mate Toth-Pale1475332018-04-09 17:28:49 +020044 do { \
Mate Toth-Pale1475332018-04-09 17:28:49 +020045 data.code_start = PART_REGION_ADDR(partition, $$Base); \
46 data.code_limit = PART_REGION_ADDR(partition, $$Limit); \
47 data.ro_start = PART_REGION_ADDR(partition, $$RO$$Base); \
48 data.ro_limit = PART_REGION_ADDR(partition, $$RO$$Limit); \
49 data.rw_start = PART_REGION_ADDR(partition, _DATA$$RW$$Base); \
50 data.rw_limit = PART_REGION_ADDR(partition, _DATA$$RW$$Limit); \
51 data.zi_start = PART_REGION_ADDR(partition, _DATA$$ZI$$Base); \
52 data.zi_limit = PART_REGION_ADDR(partition, _DATA$$ZI$$Limit); \
53 data.stack_bottom = PART_REGION_ADDR(partition, _STACK$$ZI$$Base); \
54 data.stack_top = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
55 } while (0)
56#endif
57
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020058
Mate Toth-Pale1475332018-04-09 17:28:49 +020059#if TFM_LVL == 1
60#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
61 do { \
62 data.partition_state = SPM_PARTITION_STATE_UNINIT; \
63 } while (0)
64#else
65#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
66 do { \
67 data.partition_state = SPM_PARTITION_STATE_UNINIT; \
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020068 /* The top of the stack is reserved for the iovec */ \
69 /* parameters of the service called. That's why in */ \
70 /* data.stack_ptr we extract sizeof(struct iovec_args_t) */ \
71 /* from the limit. */ \
Mate Toth-Pale1475332018-04-09 17:28:49 +020072 data.stack_ptr = \
Mate Toth-Pal3db437a2018-06-22 16:15:13 +020073 PART_REGION_ADDR(partition, _STACK$$ZI$$Limit - \
74 sizeof(struct iovec_args_t)); \
Mate Toth-Pale1475332018-04-09 17:28:49 +020075 } while (0)
76#endif
77
78#define PARTITION_DECLARE(partition, flags) \
79 do { \
80 REGION_DECLARE(Image$$, partition, $$Base); \
81 REGION_DECLARE(Image$$, partition, $$Limit); \
82 REGION_DECLARE(Image$$, partition, $$RO$$Base); \
83 REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
84 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
85 REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
86 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
87 REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
88 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
89 REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020090 struct spm_partition_desc_t *part_ptr; \
Mate Toth-Pale1475332018-04-09 17:28:49 +020091 if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
92 return SPM_ERR_INVALID_CONFIG; \
93 } \
94 part_ptr = &(g_spm_partition_db.partitions[ \
95 g_spm_partition_db.partition_count]); \
96 PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags); \
97 PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +020098 PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \
Mate Toth-Pale1475332018-04-09 17:28:49 +020099 ++g_spm_partition_db.partition_count; \
100 } while (0)
101
102#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
103 do { \
104 extern int32_t init_func(void); \
105 uint32_t partition_idx = get_partition_idx(partition##_ID); \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200106 struct spm_partition_desc_t *part_ptr = \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200107 &(g_spm_partition_db.partitions[partition_idx]); \
108 part_ptr->static_data.partition_init = init_func; \
109 } while (0)
110
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200111#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200112 do { \
113 uint32_t partition_idx = get_partition_idx(partition##_ID); \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200114 struct spm_partition_desc_t *part_ptr = \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200115 &(g_spm_partition_db.partitions[partition_idx]); \
Mate Toth-Pal936c33b2018-04-10 14:02:07 +0200116 part_ptr->platform_data = peripheral; \
Mate Toth-Pale1475332018-04-09 17:28:49 +0200117 } while (0)
118
119#endif /* __SPM_DB_SETUP_H__ */