1 /*
2  * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __MPU_ARMV8M_DRV_H__
9 #define __MPU_ARMV8M_DRV_H__
10 
11 #include <stdint.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 #define PRIVILEGED_DEFAULT_ENABLE 1
18 #define HARDFAULT_NMI_ENABLE      1
19 
20 /* MAIR_ATTR */
21 #define MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL      0x04
22 #define MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX      0
23 #define MPU_ARMV8M_MAIR_ATTR_CODE_VAL        0xAA
24 #define MPU_ARMV8M_MAIR_ATTR_CODE_IDX        1
25 #define MPU_ARMV8M_MAIR_ATTR_DATA_VAL        0xFF
26 #define MPU_ARMV8M_MAIR_ATTR_DATA_IDX        2
27 
28 struct mpu_armv8m_dev_t {
29     const uint32_t base;
30 };
31 
32 enum mpu_armv8m_error_t {
33     MPU_ARMV8M_OK,
34     MPU_ARMV8M_ERROR
35 };
36 
37 enum mpu_armv8m_attr_exec_t {
38     MPU_ARMV8M_XN_EXEC_OK,
39     MPU_ARMV8M_XN_EXEC_NEVER
40 };
41 
42 enum mpu_armv8m_attr_access_t {
43     MPU_ARMV8M_AP_RW_PRIV_ONLY,
44     MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
45     MPU_ARMV8M_AP_RO_PRIV_ONLY,
46     MPU_ARMV8M_AP_RO_PRIV_UNPRIV
47 };
48 
49 enum mpu_armv8m_attr_shared_t {
50     MPU_ARMV8M_SH_NONE,
51     MPU_ARMV8M_SH_UNUSED,
52     MPU_ARMV8M_SH_OUTER,
53     MPU_ARMV8M_SH_INNER
54 };
55 
56 struct mpu_armv8m_region_cfg_t {
57     uint32_t region_nr;
58     uint32_t region_base;
59     uint32_t region_limit;
60     uint32_t region_attridx;
61     enum mpu_armv8m_attr_exec_t     attr_exec;
62     enum mpu_armv8m_attr_access_t   attr_access;
63     enum mpu_armv8m_attr_shared_t   attr_sh;
64 };
65 
66 struct mpu_armv8m_region_cfg_raw_t {
67     uint32_t region_nr;
68     uint32_t region_base;
69     uint32_t region_limit;
70 };
71 
72 
73 /**
74  * \brief Enable MPU
75  *
76  * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
77  * \param[in] privdef_en     privilege default region 1:enable 0:disable
78  * \param[in] hfnmi_en       mpu for hard fault & nmi  1:enable 0:disable
79  *
80  * \return Error code \ref mpu_armv8m_error_t
81  *
82  * \note This function doesn't check if dev is NULL.
83  */
84 
85 enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
86                                           uint32_t privdef_en,
87                                           uint32_t hfnmi_en);
88 
89 /**
90  * \brief Disable MPU
91  *
92  * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
93  *
94  * \return Error code \ref mpu_armv8m_error_t
95  *
96  * \note This function doesn't check if dev is NULL.
97  */
98 enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev);
99 
100 /**
101  * \brief Disable MPU and clean all regions
102  *
103  * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
104  *
105  * \return Error code \ref mpu_armv8m_error_t
106  *
107  * \note This function doesn't check if dev is NULL.
108  */
109 enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev);
110 
111 /**
112  * \brief Enable MPU Region
113  *
114  * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
115  * \param[in] region_cfg     MPU region config \ref mpu_armv8m_region_cfg_t
116  *
117  * \return Error code \ref mpu_armv8m_error_t
118  *
119  * \note This function doesn't check if dev is NULL.
120  */
121 enum mpu_armv8m_error_t mpu_armv8m_region_enable(
122                                 struct mpu_armv8m_dev_t *dev,
123                                 struct mpu_armv8m_region_cfg_t *region_cfg);
124 
125 /**
126  * \brief Disable MPU Region
127  *
128  * \param[in] dev            MPU device \ref mpu_armv8m_dev_t
129  * \param[in] region_nr            Region number
130  *
131  * \return Error code \ref mpu_armv8m_error_t
132  *
133  * \note This function doesn't check if dev is NULL.
134  */
135 enum mpu_armv8m_error_t mpu_armv8m_region_disable(
136                                 struct mpu_armv8m_dev_t *dev,
137                                 uint32_t region_nr);
138 
139 #ifdef __cplusplus
140 }
141 #endif
142 
143 #endif /* __MPU_ARMV8M_DRV_H__ */
144