/* * Copyright (C) 2016 Loci Controls Inc. * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup cpu_cortexm_common * @{ * * @file mpu.h * @brief Cortex-M Memory Protection Unit (MPU) Driver Header File * * @author Ian Martin * * @} */ #ifndef MPU_H #define MPU_H #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief Number of MPU regions available (will vary depending on the Cortex-M version) */ #define MPU_NUM_REGIONS ( (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos ) /** * @brief Access Permission words */ enum { AP_NO_NO = 0, /**< no access for all levels */ AP_RW_NO = 1, /**< read/write for privileged level, no access from user level */ AP_RW_RO = 2, /**< read/write for privileged level, read-only for user level */ AP_RW_RW = 3, /**< read/write for all levels */ AP_RO_NO = 5, /**< read-only for privileged level, no access from user level */ AP_RO_RO = 6, /**< read-only for all levels */ }; /** * @brief MPU region sizes */ enum { MPU_SIZE_32B = 4, /**< 32 bytes */ MPU_SIZE_64B = 5, /**< 64 bytes */ MPU_SIZE_128B = 6, /**< 128 bytes */ MPU_SIZE_256B = 7, /**< 256 bytes */ MPU_SIZE_512B = 8, /**< 512 bytes */ MPU_SIZE_1K = 9, /**< 1 kilobytes */ MPU_SIZE_2K = 10, /**< 2 kilobytes */ MPU_SIZE_4K = 11, /**< 4 kilobytes */ MPU_SIZE_8K = 12, /**< 8 kilobytes */ MPU_SIZE_16K = 13, /**< 16 kilobytes */ MPU_SIZE_32K = 14, /**< 32 kilobytes */ MPU_SIZE_64K = 15, /**< 64 kilobytes */ MPU_SIZE_128K = 16, /**< 128 kilobytes */ MPU_SIZE_256K = 17, /**< 256 kilobytes */ MPU_SIZE_512K = 18, /**< 512 kilobytes */ MPU_SIZE_1M = 19, /**< 1 megabytes */ MPU_SIZE_2M = 20, /**< 2 megabytes */ MPU_SIZE_4M = 21, /**< 4 megabytes */ MPU_SIZE_8M = 22, /**< 8 megabytes */ MPU_SIZE_16M = 23, /**< 16 megabytes */ MPU_SIZE_32M = 24, /**< 32 megabytes */ MPU_SIZE_64M = 25, /**< 64 megabytes */ MPU_SIZE_128M = 26, /**< 128 megabytes */ MPU_SIZE_256M = 27, /**< 256 megabytes */ MPU_SIZE_512M = 28, /**< 512 megabytes */ MPU_SIZE_1G = 29, /**< 1 gigabytes */ MPU_SIZE_2G = 30, /**< 2 gigabytes */ MPU_SIZE_4G = 31, /**< 4 gigabytes */ }; /** * @brief convert a region size code to a size in bytes * * @param[in] size region size code, e.g. MPU_SIZE_32B * * @return region size in bytes */ #define MPU_SIZE_TO_BYTES(size) ( (uintptr_t)1 << ((size) + 1) ) /** * @brief generate an MPU attribute word suitable for writing to the RASR register * * @param[in] xn eXecute Never flag (forbids instruction fetches) * @param[in] ap Access Permission word, e.g. AP_RO_RO * @param[in] tex Type Extension Field * @param[in] c Cacheable bit * @param[in] b Bufferable bit * @param[in] s Sub-Region Disable (SRD) field * @param[in] size region size code, e.g. MPU_SIZE_32B * * @return combined region attribute word */ static inline uint32_t MPU_ATTR( uint32_t xn, uint32_t ap, uint32_t tex, uint32_t c, uint32_t b, uint32_t s, uint32_t size) { return (xn << 28) | (ap << 24) | (tex << 19) | (s << 18) | (c << 17) | (b << 16) | (size << 1); } /** * @brief disable the MPU * * @return 0 on success * @return <0 on failure or no MPU present */ int mpu_disable(void); /** * @brief enable the MPU * * @return 0 on success * @return <0 on failure or no MPU present */ int mpu_enable(void); /** * @brief test if the MPU is enabled * * @return true if enabled * @return false if disabled */ bool mpu_enabled(void); /** * @brief configure the base address and attributes for an MPU region * * @param[in] region MPU region to configure (0 <= @p region < MPU_NUM_REGIONS) * @param[in] base base address in RAM (aligned to the size specified within @p attr) * @param[in] attr attribute word generated by MPU_ATTR() * * @return 0 on success * @return <0 on failure or no MPU present */ int mpu_configure(uint_fast8_t region, uintptr_t base, uint_fast32_t attr); #ifdef __cplusplus } #endif #endif /* MPU_H */