1 /*
2  * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __TFM_MULTI_CORE_H__
9 #define __TFM_MULTI_CORE_H__
10 
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 /* Follow CMSE flag definitions */
16 #define MEM_CHECK_MPU_READWRITE         (1 << 0x0)
17 #define MEM_CHECK_AU_NONSECURE          (1 << 0x1)
18 #define MEM_CHECK_MPU_UNPRIV            (1 << 0x2)
19 #define MEM_CHECK_MPU_READ              (1 << 0x3)
20 #define MEM_CHECK_MPU_NONSECURE         (1 << 0x4)
21 #define MEM_CHECK_NONSECURE             (MEM_CHECK_AU_NONSECURE | \
22                                          MEM_CHECK_MPU_NONSECURE)
23 
24 #define CLIENT_ID_OWNER_MAGIC           (void *)0xFFFFFFFF
25 
26 /* Security attributes of target memory region in memory access check. */
27 struct security_attr_info_t {
28     bool is_valid;             /* Whether the target memory region is valid */
29     bool is_secure;            /* Secure memory or non-secure memory */
30 };
31 
32 /* Memory access attributes of target memory region in memory access check. */
33 struct mem_attr_info_t {
34     bool is_mpu_enabled;       /* Whether memory protection unit(s) enabled */
35     bool is_valid;             /* Whether the target memory region is valid */
36     bool is_xn;                /* Execute Never or not */
37     bool is_priv_rd_allow;     /* Privileged read is allowed or not */
38     bool is_priv_wr_allow;     /* Privileged write is allowed or not */
39     bool is_unpriv_rd_allow;   /* Unprivileged read is allowed or not */
40     bool is_unpriv_wr_allow;   /* Unprivileged write is allowed or not */
41 };
42 
43 /**
44  * \brief Retrieve general security isolation configuration information of the
45  *        target memory region according to the system memory region layout and
46  *        fill the \ref security_attr_info_t.
47  *
48  * \param[in]  p               Base address of target memory region
49  * \param[in]  s               Size of target memory region
50  * \param[out] p_attr          Address of \ref security_attr_info_t to be filled
51  *
52  * \return void
53  *
54  * \note This function doesn't access any hardware security isolation unit.
55  */
56 void tfm_get_mem_region_security_attr(const void *p, size_t s,
57                                       struct security_attr_info_t *p_attr);
58 
59 /**
60  * \brief Retrieve general secure memory protection configuration information of
61  *        the target memory region according to the system memory region layout
62  *        and symbol addresses and fill the \ref mem_attr_info_t.
63  *
64  * \param[in]  p               Base address of target memory region
65  * \param[in]  s               Size of target memory region
66  * \param[out] p_attr          Address of \ref mem_attr_info_t to be filled
67  *
68  * \return void
69  *
70  * \note This function doesn't access any hardware memory protection unit.
71  *       The \ref is_mpu_enabled field is set to false by default.
72  */
73 void tfm_get_secure_mem_region_attr(const void *p, size_t s,
74                                     struct mem_attr_info_t *p_attr);
75 
76 /**
77  * \brief Retrieve general non-secure memory protection configuration
78  *        information of the target memory region according to the system memory
79  *        region layout and fill the \ref mem_attr_info_t.
80  *
81  * \param[in]  p               Base address of target memory region
82  * \param[in]  s               Size of target memory region
83  * \param[out] p_attr          Address of \ref mem_attr_info_t to be filled
84  *
85  * \return void
86  *
87  * \note This function doesn't access any hardware memory protection unit.
88  *       The \ref is_mpu_enabled field is set to false by default.
89  */
90 void tfm_get_ns_mem_region_attr(const void *p, size_t s,
91                                 struct mem_attr_info_t *p_attr);
92 
93 /**
94  * \brief Check whether a memory access is allowed to access to a memory range
95  *
96  * \param[in] p               The start address of the range to check
97  * \param[in] s               The size of the range to check
98  * \param[in] flags           The memory access types to be checked between
99  *                            given memory and boundaries.
100  *
101  * \return SPM_SUCCESS if the access is allowed,
102  *         SPM_ERROR_GENERIC otherwise.
103  */
104 int32_t tfm_has_access_to_region(const void *p, size_t s, uint32_t flags);
105 
106 /**
107  * \brief Initialization of the multi core communication.
108  *
109  * \retval 0                    Operation succeeded.
110  * \retval Other return code    Operation failed with an error code.
111  */
112 int32_t tfm_inter_core_comm_init(void);
113 
114 /**
115  * \brief Check whether a memory range is inside a memory region.
116  *
117  * \param[in] p             The start address of the range to check
118  * \param[in] s             The size of the range to check
119  * \param[in] region_start  The start address of the region, which should
120  *                          contain the range
121  * \param[in] region_limit  The end address of the region, which should contain
122  *                          the range
123  *
124  * \return SPM_SUCCESS if the region contains the range,
125  *         SPM_ERROR_GENERIC otherwise.
126  */
127 int32_t check_address_range(const void *p, size_t s,
128                             uintptr_t region_start,
129                             uintptr_t region_limit);
130 
131 /**
132  * \brief Register a non-secure client ID range.
133  *
134  * \param[in] owner           Identifier of the non-secure client.
135  * \param[in] client_id_base  The minimum client ID for this client.
136  * \param[in] client_id_limit The maximum client ID for this client.
137  *
138  * \return SPM_SUCCESS if the registration is successful, SPM_ERROR_GENERIC
139  *         if owner is null, or no free slots left.
140  */
141 int32_t tfm_multi_core_register_client_id_range(void *owner,
142                                                 int32_t client_id_base,
143                                                 int32_t client_id_limit);
144 
145 /**
146  * \brief Translate a non-secure client ID range.
147  *
148  * \param[in]  owner         Identifier of the non-secure client.
149  * \param[in]  client_id_in  The input client ID.
150  * \param[out] client_id_out The translated client ID. Undefined if
151  *                           SPM_ERROR_GENERIC is returned by the function
152  *
153  * \return SPM_SUCCESS if the translation is successful, SPM_ERROR_GENERIC
154  *         otherwise.
155  */
156 int32_t tfm_multi_core_hal_client_id_translate(void *owner,
157                                                int32_t client_id_in,
158                                                int32_t *client_id_out);
159 
160 #endif /* __TFM_MULTI_CORE_H__ */
161