1 /* 2 * Copyright (c) 2017-2023, 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 #include "fih.h" 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 #define PRIVILEGED_DEFAULT_ENABLE 1 19 #define HARDFAULT_NMI_ENABLE 1 20 21 /* MAIR_ATTR */ 22 #define MPU_ARMV8M_MAIR_ATTR_DEVICE_VAL 0x04 23 #define MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX 0 24 #define MPU_ARMV8M_MAIR_ATTR_CODE_VAL 0xAA 25 #define MPU_ARMV8M_MAIR_ATTR_CODE_IDX 1 26 #define MPU_ARMV8M_MAIR_ATTR_DATA_VAL 0xFF 27 #define MPU_ARMV8M_MAIR_ATTR_DATA_IDX 2 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 #ifdef TFM_PXN_ENABLE 58 enum mpu_armv8m_attr_priv_exec_t { 59 MPU_ARMV8M_PRIV_EXEC_OK, 60 MPU_ARMV8M_PRIV_EXEC_NEVER 61 }; 62 #endif 63 64 struct mpu_armv8m_region_cfg_t { 65 uint32_t region_nr; 66 uint32_t region_base; 67 uint32_t region_limit; 68 uint32_t region_attridx; 69 enum mpu_armv8m_attr_exec_t attr_exec; 70 enum mpu_armv8m_attr_access_t attr_access; 71 enum mpu_armv8m_attr_shared_t attr_sh; 72 #ifdef TFM_PXN_ENABLE 73 enum mpu_armv8m_attr_priv_exec_t attr_pxn; 74 #endif 75 }; 76 77 struct mpu_armv8m_region_cfg_raw_t { 78 uint32_t region_nr; 79 uint32_t region_base; 80 uint32_t region_limit; 81 }; 82 83 84 /** 85 * \brief Enable MPU 86 * 87 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 88 * \param[in] privdef_en privilege default region 1:enable 0:disable 89 * \param[in] hfnmi_en mpu for hard fault & nmi 1:enable 0:disable 90 * 91 * \return Error code \ref mpu_armv8m_error_t 92 * 93 * \note This function doesn't check if dev is NULL. 94 */ 95 FIH_RET_TYPE(enum mpu_armv8m_error_t) mpu_armv8m_enable( 96 struct mpu_armv8m_dev_t *dev, 97 uint32_t privdef_en, 98 uint32_t hfnmi_en); 99 100 /** 101 * \brief Disable MPU 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_disable(struct mpu_armv8m_dev_t *dev); 110 111 /** 112 * \brief Disable MPU and clean all regions 113 * 114 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 115 * 116 * \return Error code \ref mpu_armv8m_error_t 117 * 118 * \note This function doesn't check if dev is NULL. 119 */ 120 enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev); 121 122 /** 123 * \brief Enable MPU Region 124 * 125 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 126 * \param[in] region_cfg MPU region config \ref mpu_armv8m_region_cfg_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 FIH_RET_TYPE(enum mpu_armv8m_error_t) mpu_armv8m_region_enable( 133 struct mpu_armv8m_dev_t *dev, 134 struct mpu_armv8m_region_cfg_t *region_cfg); 135 136 /** 137 * \brief Disable MPU Region 138 * 139 * \param[in] dev MPU device \ref mpu_armv8m_dev_t 140 * \param[in] region_nr Region number 141 * 142 * \return Error code \ref mpu_armv8m_error_t 143 * 144 * \note This function doesn't check if dev is NULL. 145 */ 146 FIH_RET_TYPE(enum mpu_armv8m_error_t) mpu_armv8m_region_disable( 147 struct mpu_armv8m_dev_t *dev, 148 uint32_t region_nr); 149 150 #ifdef __cplusplus 151 } 152 #endif 153 154 #endif /* __MPU_ARMV8M_DRV_H__ */ 155