1 /* 2 * Copyright (c) 2017-2024, 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 #include "tfm_hal_device_header.h" 14 15 #define PRIVILEGED_DEFAULT_ENABLE 1 16 #define PRIVILEGED_DEFAULT_DISABLE 0 17 #define HARDFAULT_NMI_ENABLE 1 18 19 /* MAIR_ATTR */ 20 #define MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL 0x04 21 #define MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX 0 22 #define MPU_ARMV8M_MAIR_ATTR_CODE_VAL 0xAA 23 #define MPU_ARMV8M_MAIR_ATTR_CODE_IDX 1 24 #define MPU_ARMV8M_MAIR_ATTR_DATA_VAL 0xFF 25 #define MPU_ARMV8M_MAIR_ATTR_DATA_IDX 2 26 #define MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_VAL 0x44 27 #define MPU_ARMV8M_MAIR_ATTR_DATANOCACHE_IDX 3 28 29 struct mpu_armv8m_dev_t { 30 const uint32_t base; 31 }; 32 33 enum mpu_armv8m_error_t { 34 MPU_ARMV8M_OK, 35 MPU_ARMV8M_ERROR 36 }; 37 38 enum mpu_armv8m_attr_exec_t { 39 MPU_ARMV8M_XN_EXEC_OK, 40 MPU_ARMV8M_XN_EXEC_NEVER 41 }; 42 43 enum mpu_armv8m_attr_access_t { 44 MPU_ARMV8M_AP_RW_PRIV_ONLY, 45 MPU_ARMV8M_AP_RW_PRIV_UNPRIV, 46 MPU_ARMV8M_AP_RO_PRIV_ONLY, 47 MPU_ARMV8M_AP_RO_PRIV_UNPRIV 48 }; 49 50 enum mpu_armv8m_attr_shared_t { 51 MPU_ARMV8M_SH_NONE, 52 MPU_ARMV8M_SH_UNUSED, 53 MPU_ARMV8M_SH_OUTER, 54 MPU_ARMV8M_SH_INNER 55 }; 56 57 struct mpu_armv8m_region_cfg_t { 58 uint32_t region_nr; 59 uint32_t region_base; 60 uint32_t region_limit; 61 uint32_t region_attridx; 62 enum mpu_armv8m_attr_exec_t attr_exec; 63 enum mpu_armv8m_attr_access_t attr_access; 64 enum mpu_armv8m_attr_shared_t attr_sh; 65 #ifdef FLOW_CONTROL 66 uint32_t flow_step_enable; 67 uint32_t flow_ctrl_enable; 68 uint32_t flow_step_check; 69 uint32_t flow_ctrl_check; 70 #endif 71 }; 72 73 struct mpu_armv8m_region_cfg_raw_t { 74 uint32_t region_nr; 75 uint32_t region_base; 76 uint32_t region_limit; 77 }; 78 79 80 /** 81 * \brief Enable MPU 82 * 83 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 84 * \param[in] privdef_en privilege default region 1:enable 0:disable 85 * \param[in] hfnmi_en mpu for hard fault & nmi 1:enable 0:disable 86 * 87 * \return Error code \ref mpu_armv8m_error_t 88 * 89 * \note This function doesn't check if dev is NULL. 90 */ 91 92 enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev, 93 uint32_t privdef_en, 94 uint32_t hfnmi_en); 95 96 /** 97 * \brief Check MPU enabled 98 * 99 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 100 * \param[in] privdef_en privilege default region 1:enable 0:disable 101 * \param[in] hfnmi_en mpu for hard fault & nmi 1:enable 0:disable 102 * 103 * \return Error code \ref mpu_armv8m_error_t 104 * 105 * \note This function doesn't check if dev is NULL. 106 */ 107 108 enum mpu_armv8m_error_t mpu_armv8m_check(struct mpu_armv8m_dev_t *dev, 109 uint32_t privdef_en, 110 uint32_t hfnmi_en); 111 112 /** 113 * \brief Disable MPU 114 * 115 * \param[in] dev MPU device \ref mpu_armv8m_dev_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_disable(struct mpu_armv8m_dev_t *dev); 122 123 /** 124 * \brief Disable MPU and clean all regions 125 * 126 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 127 * 128 * \return Error code \ref mpu_armv8m_error_t 129 * 130 * \note This function doesn't check if dev is NULL. 131 */ 132 enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev); 133 134 /** 135 * \brief Enable MPU Region 136 * 137 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 138 * \param[in] region_cfg MPU region config \ref mpu_armv8m_region_cfg_t 139 * 140 * \return Error code \ref mpu_armv8m_error_t 141 * 142 * \note This function doesn't check if dev is NULL. 143 */ 144 enum mpu_armv8m_error_t mpu_armv8m_region_enable( 145 struct mpu_armv8m_dev_t *dev, 146 struct mpu_armv8m_region_cfg_t *region_cfg); 147 148 /** 149 * \brief Check enabled MPU Region 150 * 151 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 152 * \param[in] region_cfg MPU region config \ref mpu_armv8m_region_cfg_t 153 * 154 * \return Error code \ref mpu_armv8m_error_t 155 * 156 * \note This function doesn't check if dev is NULL. 157 */ 158 enum mpu_armv8m_error_t mpu_armv8m_region_enable_check( 159 struct mpu_armv8m_dev_t *dev, 160 struct mpu_armv8m_region_cfg_t *region_cfg); 161 162 /** 163 * \brief Disable MPU Region 164 * 165 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 166 * \param[in] region_nr Region number 167 * 168 * \return Error code \ref mpu_armv8m_error_t 169 * 170 * \note This function doesn't check if dev is NULL. 171 */ 172 enum mpu_armv8m_error_t mpu_armv8m_region_disable( 173 struct mpu_armv8m_dev_t *dev, 174 uint32_t region_nr); 175 176 /** 177 * \brief Check disabled MPU Region 178 * 179 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 180 * \param[in] region_nr Region number 181 * 182 * \return Error code \ref mpu_armv8m_error_t 183 * 184 * \note This function doesn't check if dev is NULL. 185 */ 186 enum mpu_armv8m_error_t mpu_armv8m_region_disable_check( 187 struct mpu_armv8m_dev_t *dev, 188 uint32_t region_nr); 189 /** 190 * \brief Configure only MPU Region without enabling it 191 * 192 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 193 * \param[in] region_cfg MPU region config \ref mpu_armv8m_region_cfg_t 194 * 195 * \return Error code \ref arm_mpu_error_t 196 * 197 * \note This function doesn't check if dev is NULL. 198 */ 199 enum mpu_armv8m_error_t mpu_armv8m_region_config_only( 200 struct mpu_armv8m_dev_t *dev, 201 struct mpu_armv8m_region_cfg_t *region_cfg); 202 203 /** 204 * \brief Check configured only MPU Region 205 * 206 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 207 * \param[in] region_cfg MPU region config \ref mpu_armv8m_region_cfg_t 208 * 209 * \return Error code \ref arm_mpu_error_t 210 * 211 * \note This function doesn't check if dev is NULL. 212 */ 213 enum mpu_armv8m_error_t mpu_armv8m_region_config_only_check( 214 struct mpu_armv8m_dev_t *dev, 215 struct mpu_armv8m_region_cfg_t *region_cfg); 216 #endif /* __MPU_ARMV8M_DRV_H__ */ 217