Mistake on this page?
Report an issue in GitHub or email us
spm_db_setup.h
1 /*
2  * Copyright (c) 2018-2019, 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 Get the index of a partition.
16  *
17  * Gets the index of a partition in the partition db based on the partition ID
18  * provided as a parameter.
19  *
20  * \param[in] partition_idx The index of the partition
21  *
22  * \return \ref INVALID_PARTITION_IDX if the provided index is invalid. The
23  * index of the partition otherwise.
24  */
25 uint32_t get_partition_idx(uint32_t partition_id);
26 
28  uint32_t is_init;
29  uint32_t partition_count;
30  uint32_t running_partition_idx;
31  struct spm_partition_desc_t partitions[SPM_MAX_PARTITIONS];
32 };
33 
34 #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); \
39  } while (0)
40 
41 /* Changed from #if (TFM_LVL == 1) && !defined(TFM_PSA_API) to #if (TFM_LVL == 1) to avoid linker error.
42  TF-M build autogenerates region details (code, ro, rw, zi and stack ) using linker scripts. We do not
43  hve that in mbed-os build yet.
44 */
45 #if (TFM_LVL == 1)
46 #define PARTITION_INIT_MEMORY_DATA(data, partition)
47 #else
48 #define PARTITION_INIT_MEMORY_DATA(data, partition) \
49  do { \
50  data.code_start = PART_REGION_ADDR(partition, $$Base); \
51  data.code_limit = PART_REGION_ADDR(partition, $$Limit); \
52  data.ro_start = PART_REGION_ADDR(partition, $$RO$$Base); \
53  data.ro_limit = PART_REGION_ADDR(partition, $$RO$$Limit); \
54  data.rw_start = PART_REGION_ADDR(partition, _DATA$$RW$$Base); \
55  data.rw_limit = PART_REGION_ADDR(partition, _DATA$$RW$$Limit); \
56  data.zi_start = PART_REGION_ADDR(partition, _DATA$$ZI$$Base); \
57  data.zi_limit = PART_REGION_ADDR(partition, _DATA$$ZI$$Limit); \
58  data.stack_bottom = PART_REGION_ADDR(partition, _STACK$$ZI$$Base); \
59  data.stack_top = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
60  } while (0)
61 #endif
62 
63 #if TFM_LVL == 1
64 #define PARTITION_INIT_RUNTIME_DATA(data, partition) \
65  do { \
66  data.partition_state = SPM_PARTITION_STATE_UNINIT; \
67  } while (0)
68 #else
69 #define PARTITION_INIT_RUNTIME_DATA(data, partition) \
70  do { \
71  data.partition_state = SPM_PARTITION_STATE_UNINIT; \
72  /* The top of the stack is reserved for the iovec */ \
73  /* parameters of the service called. That's why in */ \
74  /* data.stack_ptr we extract sizeof(struct iovec_args_t) */ \
75  /* from the limit. */ \
76  data.stack_ptr = \
77  PART_REGION_ADDR(partition, _STACK$$ZI$$Limit - \
78  sizeof(struct iovec_args_t)); \
79  } while (0)
80 #endif
81 
82 #define PARTITION_DECLARE(partition, flag, type, id, priority, part_stack_size) \
83  do { \
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); \
94  int32_t flags = flag; \
95  if (tfm_memcmp(type, TFM_PARTITION_TYPE_APP, \
96  strlen(TFM_PARTITION_TYPE_APP)) == 0) { \
97  flags |= SPM_PART_FLAG_APP_ROT; \
98  } else if (tfm_memcmp(type, TFM_PARTITION_TYPE_PSA, \
99  strlen(TFM_PARTITION_TYPE_PSA)) == 0) { \
100  flags |= SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT; \
101  } else { \
102  return SPM_ERR_INVALID_CONFIG; \
103  } \
104  struct spm_partition_desc_t *part_ptr; \
105  if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
106  return SPM_ERR_INVALID_CONFIG; \
107  } \
108  __attribute__((section(".data.partitions_stacks"))) \
109  static uint8_t partition##_stack[part_stack_size] __attribute__((aligned(8))); \
110  part_ptr = &(g_spm_partition_db.partitions[ \
111  g_spm_partition_db.partition_count]); \
112  part_ptr->memory_data.stack_bottom = (uint32_t)partition##_stack; \
113  part_ptr->memory_data.stack_top = part_ptr->memory_data.stack_bottom + part_stack_size; \
114  PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags, \
115  id, priority); \
116  PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
117  PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \
118  ++g_spm_partition_db.partition_count; \
119  } while (0)
120 
121 #define PARTITION_ADD_INIT_FUNC(partition, init_func) \
122  do { \
123  extern int32_t init_func(void); \
124  uint32_t partition_idx = get_partition_idx(partition##_ID); \
125  struct spm_partition_desc_t *part_ptr = \
126  &(g_spm_partition_db.partitions[partition_idx]); \
127  part_ptr->static_data.partition_init = init_func; \
128  } while (0)
129 
130 #define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
131  do { \
132  uint32_t partition_idx = get_partition_idx(partition##_ID); \
133  struct spm_partition_desc_t *part_ptr = \
134  &(g_spm_partition_db.partitions[partition_idx]); \
135  part_ptr->platform_data = peripheral; \
136  } while (0)
137 
138 #endif /* __SPM_DB_SETUP_H__ */
Holds the fields that define a partition for SPM.
Definition: spm_db.h:56
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.