blob: 8c59872f58ee5b36daaad8249f70e74ab03bba37 [file] [log] [blame]
Per Åstrand79929ff2021-01-26 14:42:43 +01001/*
Anton Mobergfa3e51b2021-03-31 11:05:02 +02002 * Copyright (c) 2016-2019, 2021 Arm Limited. All rights reserved.
Per Åstrand79929ff2021-01-26 14:42:43 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18 * \file mpc_sie_drv.h
19 * \brief Generic driver for ARM SIE Memory Protection
20 * Controllers (MPC).
21 */
22
23#ifndef __MPC_SIE__DRV_H__
24#define __MPC_SIE__DRV_H__
25
Per Åstrand79929ff2021-01-26 14:42:43 +010026#include <stdbool.h>
Anton Moberg908a07c2021-04-08 09:50:57 +020027#include <stdint.h>
Per Åstrand79929ff2021-01-26 14:42:43 +010028
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/* Error code returned by the driver functions */
34enum mpc_sie_error_t {
Anton Moberg908a07c2021-04-08 09:50:57 +020035 MPC_SIE_ERR_NONE, /*!< No error */
36 MPC_SIE_INVALID_ARG, /*!< MPC invalid input arguments */
37 MPC_SIE_NOT_INIT, /*!< MPC not initialized */
38 MPC_SIE_ERR_NOT_IN_RANGE, /*!< Address does not belong to a range
39 * controlled by the MPC */
40 MPC_SIE_ERR_NOT_ALIGNED, /*!< Address is not aligned on the block size
41 * of this MPC
42 */
43 MPC_SIE_ERR_INVALID_RANGE, /*!< The given address range to configure
44 * is invalid. This could be because:
45 * - The base and limit swapped
46 * - The base and limit addresses
47 * are in different ranges
48 */
Per Åstrand79929ff2021-01-26 14:42:43 +010049 MPC_SIE_ERR_RANGE_SEC_ATTR_NON_COMPATIBLE, /*!< The given range cannot be
Anton Moberg908a07c2021-04-08 09:50:57 +020050 * accessed with the wanted
51 * security attributes
52 */
53 MPC_SIE_UNSUPPORTED_HARDWARE_VERSION, /*!< MPC hardware version read from
54 * PIDR0 is not supported
55 */
56 MPC_SIE_ERR_GATING_NOT_PRESENT /*!< MPC gating not present in HW */
Per Åstrand79929ff2021-01-26 14:42:43 +010057};
58
59/* Security attribute used in various place of the API */
60enum mpc_sie_sec_attr_t {
Anton Moberg908a07c2021-04-08 09:50:57 +020061 MPC_SIE_SEC_ATTR_SECURE, /*!< Secure attribute */
62 MPC_SIE_SEC_ATTR_NONSECURE, /*!< Non-secure attribute */
Per Åstrand79929ff2021-01-26 14:42:43 +010063 /*!< Used when getting the configuration of a memory range and some blocks
64 * are secure whereas some other are non secure
65 */
66 MPC_SIE_SEC_ATTR_MIXED,
67};
68
69/* What can happen when trying to do an illegal memory access */
70enum mpc_sie_sec_resp_t {
Anton Moberg908a07c2021-04-08 09:50:57 +020071 MPC_SIE_RESP_RAZ_WI, /*!< Read As Zero, Write Ignored */
72 MPC_SIE_RESP_BUS_ERROR, /*!< Bus error */
73 MPC_SIE_RESP_WAIT_GATING_DISABLED /*!< Wait until gating is disabled */
Per Åstrand79929ff2021-01-26 14:42:43 +010074};
75
76/* Description of a memory range controlled by the MPC */
77struct mpc_sie_memory_range_t {
Anton Moberg908a07c2021-04-08 09:50:57 +020078 const uint32_t base; /*!< Base address (included in the range) */
79 const uint32_t limit; /*!< Limit address (included in the range) */
80 const uint32_t range_offset; /*!< Offset of current range area to the 0
81 * point of the whole area (the sum of the
82 * sizes of the previous memory ranges
83 * covered by the same MPC)
84 */
Per Åstrand79929ff2021-01-26 14:42:43 +010085 const enum mpc_sie_sec_attr_t attr; /*!< Optional security attribute
Anton Moberg908a07c2021-04-08 09:50:57 +020086 * needed to be matched when
87 * accessing this range.
88 * For example, the non-secure
89 * alias of a memory region can not
90 * be accessed using secure access,
91 * and configuring the MPC to
92 * secure using that range will not
93 * be permitted by the driver.
94 */
Per Åstrand79929ff2021-01-26 14:42:43 +010095};
96
97/* ARM MPC SIE device configuration structure */
98struct mpc_sie_dev_cfg_t {
Anton Moberg908a07c2021-04-08 09:50:57 +020099 const uint32_t base; /*!< MPC base address */
Per Åstrand79929ff2021-01-26 14:42:43 +0100100};
101
102/* ARM MPC SIE device data structure */
103struct mpc_sie_dev_data_t {
104 /*!< Array of pointers to memory ranges controlled by the MPC */
Anton Moberg908a07c2021-04-08 09:50:57 +0200105 const struct mpc_sie_memory_range_t **range_list;
106 uint8_t nbr_of_ranges; /*!< Number of memory ranges in the list */
107 bool is_initialized; /*!< Indicates if the MPC driver
108 * is initialized and enabled
109 */
110 uint32_t sie_version; /*!< SIE version */
Per Åstrand79929ff2021-01-26 14:42:43 +0100111};
112
113/* ARM MPC SIE device structure */
114struct mpc_sie_dev_t {
Anton Moberg908a07c2021-04-08 09:50:57 +0200115 const struct mpc_sie_dev_cfg_t *const cfg; /*!< MPC configuration */
116 struct mpc_sie_dev_data_t *const data; /*!< MPC data */
Per Åstrand79929ff2021-01-26 14:42:43 +0100117};
118
119/**
120 * \brief Initializes a MPC device.
121 *
122 * \param[in] dev MPC device \ref mpc_sie_dev_t
123 * \param[in] range_list List of memory ranges controller by the MPC
124 * (\ref mpc_sie_memory_range_t). This list can not
125 * freed after the initializations.
126 * \param[in] nbr_of_ranges Number of memory ranges
127 *
128 * \return Returns error code as specified in \ref mpc_sie_error_t
129 *
130 * \note This function doesn't check if dev is NULL.
131 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200132enum mpc_sie_error_t
133mpc_sie_init(struct mpc_sie_dev_t *dev, const struct mpc_sie_memory_range_t **range_list, uint8_t nbr_of_ranges);
Per Åstrand79929ff2021-01-26 14:42:43 +0100134
135/**
136 * \brief Gets MPC block size. All regions must be aligned on this block
137 * size (base address and limit+1 address).
138 *
139 * \param[in] dev MPC device \ref mpc_sie_dev_t
140 * \param[out] blk_size MPC block size
141 *
142 * \return Returns error code as specified in \ref mpc_sie_error_t
143 *
144 * \note This function doesn't check if dev is NULL.
145 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200146enum mpc_sie_error_t mpc_sie_get_block_size(struct mpc_sie_dev_t *dev, uint32_t *blk_size);
Per Åstrand79929ff2021-01-26 14:42:43 +0100147
148/**
149 * \brief Configures a memory region (base and limit included).
150 *
151 * \param[in] dev MPC device \ref mpc_sie_dev_t
152 * \param[in] base Base address of the region to poll. This bound is
153 * included. It does not need to be aligned in any way.
154 *
155 * \param[in] limit Limit address of the region to poll. This bound is
156 * included. (limit+1) does not need to be aligned
157 * in any way.
158 * \param[in] attr Security attribute of the region. If the region has mixed
159 * secure/non-secure, a special value is returned
160 * (\ref mpc_sie_sec_attr_t).
161 *
162 * In case base and limit+1 addresses are not aligned on
163 * the block size, the enclosing region with base and
164 * limit+1 aligned on block size will be queried.
165 * In case of early termination of the function (error), the
166 * security attribute will be set to MPC_SIE_ATTR_MIXED.
167 *
168 * \return Returns error code as specified in \ref mpc_sie_error_t
169 *
170 * \note This function doesn't check if dev is NULL.
171 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200172enum mpc_sie_error_t mpc_sie_config_region(struct mpc_sie_dev_t *dev,
Per Åstrand79929ff2021-01-26 14:42:43 +0100173 const uint32_t base,
174 const uint32_t limit,
175 enum mpc_sie_sec_attr_t attr);
176
177/**
178 * \brief Gets a memory region configuration(base and limit included).
179 *
180 * \param[in] dev MPC device \ref mpc_sie_dev_t
181 * \param[in] base Base address of the region to get the configuration.
182 * \param[in] limit Limit address of the region to get the configuration.
183 * \param[out] attr Security attribute of the region
184 * \ref mpc_sie_sec_attr_t
185 *
186 * \return Returns error code as specified in \ref mpc_sie_error_t
187 *
188 * \note This function doesn't check if dev is NULL.
189 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200190enum mpc_sie_error_t
191mpc_sie_get_region_config(struct mpc_sie_dev_t *dev, uint32_t base, uint32_t limit, enum mpc_sie_sec_attr_t *attr);
Per Åstrand79929ff2021-01-26 14:42:43 +0100192
193/**
194 * \brief Gets the MPC control value.
195 *
196 * \param[in] dev MPC device \ref mpc_sie_dev_t
197 * \param[out] ctrl_val Current MPC control value.
198 *
199 * \return Returns error code as specified in \ref mpc_sie_error_t
200 *
201 * \note This function doesn't check if dev is NULL.
202 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200203enum mpc_sie_error_t mpc_sie_get_ctrl(struct mpc_sie_dev_t *dev, uint32_t *ctrl_val);
Per Åstrand79929ff2021-01-26 14:42:43 +0100204
205/**
206 * \brief Sets the MPC control value.
207 *
208 * \param[in] dev MPC device \ref mpc_sie_dev_t
209 * \param[in] mpc_ctrl New MPC control value
210 *
211 * \return Returns error code as specified in \ref mpc_sie_error_t
212 *
213 * \note This function doesn't check if dev is NULL.
214 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200215enum mpc_sie_error_t mpc_sie_set_ctrl(struct mpc_sie_dev_t *dev, uint32_t mpc_ctrl);
Per Åstrand79929ff2021-01-26 14:42:43 +0100216
217/**
218 * \brief Gets the configured secure response.
219 *
220 * \param[in] dev MPC device \ref mpc_sie_dev_t
221 * \param[out] sec_rep Configured secure response (\ref mpc_sie_sec_resp_t).
222 *
223 * \return Returns error code as specified in \ref mpc_sie_error_t
224 *
225 * \note This function doesn't check if dev is NULL.
226 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200227enum mpc_sie_error_t mpc_sie_get_sec_resp(struct mpc_sie_dev_t *dev, enum mpc_sie_sec_resp_t *sec_rep);
Per Åstrand79929ff2021-01-26 14:42:43 +0100228
229/**
230 * \brief Sets the response type when SW asks to gate the incoming transfers.
231 *
232 * \param[in] dev MPC device \ref mpc_sie_dev_t
233 * \param[in] sec_rep Secure response to configure (\ref mpc_sie_sec_resp_t).
234 *
235 * \note This function doesn't check if dev is NULL.
236 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200237enum mpc_sie_error_t mpc_sie_set_sec_resp(struct mpc_sie_dev_t *dev, enum mpc_sie_sec_resp_t sec_rep);
Per Åstrand79929ff2021-01-26 14:42:43 +0100238
239/**
240 * \brief Enables MPC interrupt.
241 *
242 * \param[in] dev MPC device \ref mpc_sie_dev_t
243 *
244 * \return Returns error code as specified in \ref mpc_sie_error_t
245 *
246 * \note This function doesn't check if dev is NULL.
247 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200248enum mpc_sie_error_t mpc_sie_irq_enable(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100249
250/**
251 * \brief Disables MPC interrupt
252 *
253 * \param[in] dev MPC device \ref mpc_sie_dev_t
254 *
255 * \note This function doesn't check if dev is NULL.
256 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200257void mpc_sie_irq_disable(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100258
259/**
260 * \brief Clears MPC interrupt.
261 *
262 * \param[in] dev MPC device \ref mpc_sie_dev_t
263 *
264 * \note This function doesn't check if dev is NULL.
265 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200266void mpc_sie_clear_irq(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100267
268/**
269 * \brief Returns the MPC interrupt state.
270 *
271 * \param[in] dev MPC device \ref mpc_sie_dev_t
272 *
273 * \return Returns 1 if the interrupt is active, 0 otherwise.
274 *
275 * \note This function doesn't check if dev is NULL.
276 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200277uint32_t mpc_sie_irq_state(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100278
279/**
280 * \brief Locks down the MPC configuration.
281 *
282 * \param[in] dev MPC device \ref mpc_sie_dev_t
283 *
284 * \return Returns error code as specified in \ref mpc_sie_error_t
285 *
286 * \note This function doesn't check if dev is NULL.
287 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200288enum mpc_sie_error_t mpc_sie_lock_down(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100289
290/**
291 * \brief Returns if gating is present in hardware.
292 *
293 * \param[in] dev MPC device \ref mpc_sie_dev_t
294 * \param[out] gating_present Returns if gating is present in hardware.
295 *
296 * \return Returns error code as specified in \ref mpc_sie_error_t
297 *
298 * \note This function doesn't check if dev is NULL.
299 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200300enum mpc_sie_error_t mpc_sie_is_gating_present(struct mpc_sie_dev_t *dev, bool *gating_present);
Per Åstrand79929ff2021-01-26 14:42:43 +0100301
302/**
303 * \brief Returns the value of Peripheral ID 0 register.
304 *
305 * \param[in] dev MPC device \ref mpc_sie_dev_t
306 *
307 * \return Returns the value of Peripheral ID 0 register.
308 *
309 * \note This function doesn't check if dev is NULL.
310 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200311uint32_t get_sie_version(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100312
313/**
314 * \brief Reads bit indicating acknowledge for gating incoming transfers.
315 *
316 * \param[in] dev MPC device \ref mpc_sie_dev_t
317 *
318 * \return True if acknowledge is set.
319 *
320 * \note This function doesn't check if dev is NULL.
321 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200322bool mpc_sie_get_gate_ack(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100323
324/**
325 * \brief Sets bit to request for gating incoming transfers.
326 *
327 * \param[in] dev MPC device \ref mpc_sie_dev_t
328 *
329 * \note This function doesn't check if dev is NULL.
330 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200331void mpc_sie_request_gating(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100332
333/**
334 * \brief Clears bit to request for gating incoming transfers.
335 *
336 * \param[in] dev MPC device \ref mpc_sie_dev_t
337 *
338 * \note This function doesn't check if dev is NULL.
339 */
Anton Moberg908a07c2021-04-08 09:50:57 +0200340void mpc_sie_release_gating(struct mpc_sie_dev_t *dev);
Per Åstrand79929ff2021-01-26 14:42:43 +0100341
342#ifdef __cplusplus
343}
344#endif
345#endif /* __MPC_SIE_DRV_H__ */