1 /* --COPYRIGHT--,BSD 2 * Copyright (c) 2017, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * --/COPYRIGHT--*/ 32 #ifndef __MPU_H__ 33 #define __MPU_H__ 34 35 //***************************************************************************** 36 // 37 //! \addtogroup mpu_api 38 //! @{ 39 // 40 //***************************************************************************** 41 42 43 //***************************************************************************** 44 // 45 // If building with a C++ compiler, make all of the definitions in this header 46 // have a C binding. 47 // 48 //***************************************************************************** 49 #ifdef __cplusplus 50 extern "C" 51 { 52 #endif 53 54 #include <ti/devices/msp432p4xx/inc/msp.h> 55 #include <stdint.h> 56 57 //***************************************************************************** 58 // 59 // Flags that can be passed to MPU_enableModule. 60 // 61 //***************************************************************************** 62 #define MPU_CONFIG_PRIV_DEFAULT MPU_CTRL_PRIVDEFENA_Msk 63 #define MPU_CONFIG_HARDFLT_NMI MPU_CTRL_HFNMIENA_Msk 64 #define MPU_CONFIG_NONE 0 65 66 //***************************************************************************** 67 // 68 // Flags for the region size to be passed to MPU_setRegion. 69 // 70 //***************************************************************************** 71 #define MPU_RGN_SIZE_32B (4 << 1) 72 #define MPU_RGN_SIZE_64B (5 << 1) 73 #define MPU_RGN_SIZE_128B (6 << 1) 74 #define MPU_RGN_SIZE_256B (7 << 1) 75 #define MPU_RGN_SIZE_512B (8 << 1) 76 77 #define MPU_RGN_SIZE_1K (9 << 1) 78 #define MPU_RGN_SIZE_2K (10 << 1) 79 #define MPU_RGN_SIZE_4K (11 << 1) 80 #define MPU_RGN_SIZE_8K (12 << 1) 81 #define MPU_RGN_SIZE_16K (13 << 1) 82 #define MPU_RGN_SIZE_32K (14 << 1) 83 #define MPU_RGN_SIZE_64K (15 << 1) 84 #define MPU_RGN_SIZE_128K (16 << 1) 85 #define MPU_RGN_SIZE_256K (17 << 1) 86 #define MPU_RGN_SIZE_512K (18 << 1) 87 88 #define MPU_RGN_SIZE_1M (19 << 1) 89 #define MPU_RGN_SIZE_2M (20 << 1) 90 #define MPU_RGN_SIZE_4M (21 << 1) 91 #define MPU_RGN_SIZE_8M (22 << 1) 92 #define MPU_RGN_SIZE_16M (23 << 1) 93 #define MPU_RGN_SIZE_32M (24 << 1) 94 #define MPU_RGN_SIZE_64M (25 << 1) 95 #define MPU_RGN_SIZE_128M (26 << 1) 96 #define MPU_RGN_SIZE_256M (27 << 1) 97 #define MPU_RGN_SIZE_512M (28 << 1) 98 99 #define MPU_RGN_SIZE_1G (29 << 1) 100 #define MPU_RGN_SIZE_2G (30 << 1) 101 #define MPU_RGN_SIZE_4G (31 << 1) 102 103 //***************************************************************************** 104 // 105 // Flags for the permissions to be passed to MPU_setRegion. 106 // 107 //***************************************************************************** 108 #define MPU_RGN_PERM_EXEC 0x00000000 109 #define MPU_RGN_PERM_NOEXEC 0x10000000 110 #define MPU_RGN_PERM_PRV_NO_USR_NO 0x00000000 111 #define MPU_RGN_PERM_PRV_RW_USR_NO 0x01000000 112 #define MPU_RGN_PERM_PRV_RW_USR_RO 0x02000000 113 #define MPU_RGN_PERM_PRV_RW_USR_RW 0x03000000 114 #define MPU_RGN_PERM_PRV_RO_USR_NO 0x05000000 115 #define MPU_RGN_PERM_PRV_RO_USR_RO 0x06000000 116 117 //***************************************************************************** 118 // 119 // Flags for the sub-region to be passed to MPU_setRegion. 120 // 121 //***************************************************************************** 122 #define MPU_SUB_RGN_DISABLE_0 0x00000100 123 #define MPU_SUB_RGN_DISABLE_1 0x00000200 124 #define MPU_SUB_RGN_DISABLE_2 0x00000400 125 #define MPU_SUB_RGN_DISABLE_3 0x00000800 126 #define MPU_SUB_RGN_DISABLE_4 0x00001000 127 #define MPU_SUB_RGN_DISABLE_5 0x00002000 128 #define MPU_SUB_RGN_DISABLE_6 0x00004000 129 #define MPU_SUB_RGN_DISABLE_7 0x00008000 130 131 //***************************************************************************** 132 // 133 // Flags to enable or disable a region, to be passed to MPU_setRegion. 134 // 135 //***************************************************************************** 136 #define MPU_RGN_ENABLE 1 137 #define MPU_RGN_DISABLE 0 138 139 #define NVIC_MPU_TYPE_DREGION_S 8 140 141 //***************************************************************************** 142 // 143 // API Function prototypes 144 // 145 //***************************************************************************** 146 147 //***************************************************************************** 148 // 149 //! Enables and configures the MPU for use. 150 //! 151 //! \param mpuConfig is the logical OR of the possible configurations. 152 //! 153 //! This function enables the Cortex-M memory protection unit. It also 154 //! configures the default behavior when in privileged mode and while handling 155 //! a hard fault or NMI. Prior to enabling the MPU, at least one region must 156 //! be set by calling MPU_setRegion() or else by enabling the default region for 157 //! privileged mode by passing the \b MPU_CONFIG_PRIV_DEFAULT flag to 158 //! MPU_enableModule(). Once the MPU is enabled, a memory management fault is 159 //! generated for memory access violations. 160 //! 161 //! The \e mpuConfig parameter should be the logical OR of any of the 162 //! following: 163 //! 164 //! - \b MPU_CONFIG_PRIV_DEFAULT enables the default memory map when in 165 //! privileged mode and when no other regions are defined. If this option 166 //! is not enabled, then there must be at least one valid region already 167 //! defined when the MPU is enabled. 168 //! - \b MPU_CONFIG_HARDFLT_NMI enables the MPU while in a hard fault or NMI 169 //! exception handler. If this option is not enabled, then the MPU is 170 //! disabled while in one of these exception handlers and the default 171 //! memory map is applied. 172 //! - \b MPU_CONFIG_NONE chooses none of the above options. In this case, 173 //! no default memory map is provided in privileged mode, and the MPU is 174 //! not enabled in the fault handlers. 175 //! 176 //! \return None. 177 // 178 //***************************************************************************** 179 extern void MPU_enableModule(uint32_t mpuConfig); 180 181 //***************************************************************************** 182 // 183 //! Disables the MPU for use. 184 //! 185 //! This function disables the Cortex-M memory protection unit. When the 186 //! MPU is disabled, the default memory map is used and memory management 187 //! faults are not generated. 188 //! 189 //! \return None. 190 // 191 //***************************************************************************** 192 extern void MPU_disableModule(void); 193 194 //***************************************************************************** 195 // 196 //! Gets the count of regions supported by the MPU. 197 //! 198 //! This function is used to get the total number of regions that are supported 199 //! by the MPU, including regions that are already programmed. 200 //! 201 //! \return The number of memory protection regions that are available 202 //! for programming using MPU_setRegion(). 203 // 204 //***************************************************************************** 205 extern uint32_t MPU_getRegionCount(void); 206 207 //***************************************************************************** 208 // 209 //! Enables a specific region. 210 //! 211 //! \param region is the region number to enable. Valid values are between 212 //! 0 and 7 inclusively. 213 //! 214 //! This function is used to enable a memory protection region. The region 215 //! should already be configured with the MPU_setRegion() function. Once 216 //! enabled, the memory protection rules of the region are applied and access 217 //! violations cause a memory management fault. 218 //! 219 //! \return None. 220 // 221 //***************************************************************************** 222 extern void MPU_enableRegion(uint32_t region); 223 224 //***************************************************************************** 225 // 226 //! Disables a specific region. 227 //! 228 //! \param region is the region number to disable. Valid values are between 229 //! 0 and 7 inclusively. 230 //! 231 //! This function is used to disable a previously enabled memory protection 232 //! region. The region remains configured if it is not overwritten with 233 //! another call to MPU_setRegion(), and can be enabled again by calling 234 //! MPU_enableRegion(). 235 //! 236 //! \return None. 237 // 238 //***************************************************************************** 239 extern void MPU_disableRegion(uint32_t region); 240 241 //***************************************************************************** 242 // 243 //! Sets up the access rules for a specific region. 244 //! 245 //! \param region is the region number to set up. 246 //! \param addr is the base address of the region. It must be aligned 247 //! according to the size of the region specified in flags. 248 //! \param flags is a set of flags to define the attributes of the region. 249 //! 250 //! This function sets up the protection rules for a region. The region has 251 //! a base address and a set of attributes including the size. The base 252 //! address parameter, \e addr, must be aligned according to the size, and 253 //! the size must be a power of 2. 254 //! 255 //! \param region is the region number to set. Valid values are between 256 //! 0 and 7 inclusively. 257 //! 258 //! The \e flags parameter is the logical OR of all of the attributes 259 //! of the region. It is a combination of choices for region size, 260 //! execute permission, read/write permissions, disabled sub-regions, 261 //! and a flag to determine if the region is enabled. 262 //! 263 //! The size flag determines the size of a region and must be one of the 264 //! following: 265 //! 266 //! - \b MPU_RGN_SIZE_32B 267 //! - \b MPU_RGN_SIZE_64B 268 //! - \b MPU_RGN_SIZE_128B 269 //! - \b MPU_RGN_SIZE_256B 270 //! - \b MPU_RGN_SIZE_512B 271 //! - \b MPU_RGN_SIZE_1K 272 //! - \b MPU_RGN_SIZE_2K 273 //! - \b MPU_RGN_SIZE_4K 274 //! - \b MPU_RGN_SIZE_8K 275 //! - \b MPU_RGN_SIZE_16K 276 //! - \b MPU_RGN_SIZE_32K 277 //! - \b MPU_RGN_SIZE_64K 278 //! - \b MPU_RGN_SIZE_128K 279 //! - \b MPU_RGN_SIZE_256K 280 //! - \b MPU_RGN_SIZE_512K 281 //! - \b MPU_RGN_SIZE_1M 282 //! - \b MPU_RGN_SIZE_2M 283 //! - \b MPU_RGN_SIZE_4M 284 //! - \b MPU_RGN_SIZE_8M 285 //! - \b MPU_RGN_SIZE_16M 286 //! - \b MPU_RGN_SIZE_32M 287 //! - \b MPU_RGN_SIZE_64M 288 //! - \b MPU_RGN_SIZE_128M 289 //! - \b MPU_RGN_SIZE_256M 290 //! - \b MPU_RGN_SIZE_512M 291 //! - \b MPU_RGN_SIZE_1G 292 //! - \b MPU_RGN_SIZE_2G 293 //! - \b MPU_RGN_SIZE_4G 294 //! 295 //! The execute permission flag must be one of the following: 296 //! 297 //! - \b MPU_RGN_PERM_EXEC enables the region for execution of code 298 //! - \b MPU_RGN_PERM_NOEXEC disables the region for execution of code 299 //! 300 //! The read/write access permissions are applied separately for the 301 //! privileged and user modes. The read/write access flags must be one 302 //! of the following: 303 //! 304 //! - \b MPU_RGN_PERM_PRV_NO_USR_NO - no access in privileged or user mode 305 //! - \b MPU_RGN_PERM_PRV_RW_USR_NO - privileged read/write, user no access 306 //! - \b MPU_RGN_PERM_PRV_RW_USR_RO - privileged read/write, user read-only 307 //! - \b MPU_RGN_PERM_PRV_RW_USR_RW - privileged read/write, user read/write 308 //! - \b MPU_RGN_PERM_PRV_RO_USR_NO - privileged read-only, user no access 309 //! - \b MPU_RGN_PERM_PRV_RO_USR_RO - privileged read-only, user read-only 310 //! 311 //! The region is automatically divided into 8 equally-sized sub-regions by 312 //! the MPU. Sub-regions can only be used in regions of size 256 bytes 313 //! or larger. Any of these 8 sub-regions can be disabled, allowing for 314 //! creation of ``holes'' in a region which can be left open, or overlaid 315 //! by another region with different attributes. Any of the 8 sub-regions 316 //! can be disabled with a logical OR of any of the following flags: 317 //! 318 //! - \b MPU_SUB_RGN_DISABLE_0 319 //! - \b MPU_SUB_RGN_DISABLE_1 320 //! - \b MPU_SUB_RGN_DISABLE_2 321 //! - \b MPU_SUB_RGN_DISABLE_3 322 //! - \b MPU_SUB_RGN_DISABLE_4 323 //! - \b MPU_SUB_RGN_DISABLE_5 324 //! - \b MPU_SUB_RGN_DISABLE_6 325 //! - \b MPU_SUB_RGN_DISABLE_7 326 //! 327 //! Finally, the region can be initially enabled or disabled with one of 328 //! the following flags: 329 //! 330 //! - \b MPU_RGN_ENABLE 331 //! - \b MPU_RGN_DISABLE 332 //! 333 //! As an example, to set a region with the following attributes: size of 334 //! 32 KB, execution enabled, read-only for both privileged and user, one 335 //! sub-region disabled, and initially enabled; the \e flags parameter would 336 //! have the following value: 337 //! 338 //! <code> 339 //! (MPU_RGN_SIZE_32K | MPU_RGN_PERM_EXEC | MPU_RGN_PERM_PRV_RO_USR_RO | 340 //! MPU_SUB_RGN_DISABLE_2 | MPU_RGN_ENABLE) 341 //! </code> 342 //! 343 //! \note This function writes to multiple registers and is not protected 344 //! from interrupts. It is possible that an interrupt which accesses a 345 //! region may occur while that region is in the process of being changed. 346 //! The safest way to handle this is to disable a region before changing it. 347 //! Refer to the discussion of this in the API Detailed Description section. 348 //! 349 //! \return None. 350 // 351 //***************************************************************************** 352 extern void MPU_setRegion(uint32_t region, uint32_t addr, uint32_t flags); 353 354 //***************************************************************************** 355 // 356 //! Gets the current settings for a specific region. 357 //! 358 //! \param region is the region number to get. Valid values are between 359 //! 0 and 7 inclusively. 360 //! \param addr points to storage for the base address of the region. 361 //! \param pflags points to the attribute flags for the region. 362 //! 363 //! This function retrieves the configuration of a specific region. The 364 //! meanings and format of the parameters is the same as that of the 365 //! MPU_setRegion() function. 366 //! 367 //! This function can be used to save the configuration of a region for later 368 //! use with the MPU_setRegion() function. The region's enable state is 369 //! preserved in the attributes that are saved. 370 //! 371 //! \return None. 372 // 373 //***************************************************************************** 374 extern void MPU_getRegion(uint32_t region, uint32_t *addr, uint32_t *pflags); 375 376 //***************************************************************************** 377 // 378 //! Registers an interrupt handler for the memory management fault. 379 //! 380 //! \param intHandler is a pointer to the function to be called when the 381 //! memory management fault occurs. 382 //! 383 //! This function sets and enables the handler to be called when the MPU 384 //! generates a memory management fault due to a protection region access 385 //! violation. 386 //! 387 //! \sa Interrupt_registerInterrupt() for important information about 388 //! registering interrupt handlers. 389 //! 390 //! \return None. 391 // 392 //***************************************************************************** 393 extern void MPU_registerInterrupt(void (*intHandler)(void)); 394 395 //***************************************************************************** 396 // 397 //! Unregisters an interrupt handler for the memory management fault. 398 //! 399 //! This function disables and clears the handler to be called when a 400 //! memory management fault occurs. 401 //! 402 //! \sa Interrupt_registerInterrupt() for important information about 403 //! registering interrupt handlers. 404 //! 405 //! \return None. 406 // 407 //***************************************************************************** 408 extern void MPU_unregisterInterrupt(void); 409 410 //***************************************************************************** 411 // 412 //! Enables the interrupt for the memory management fault. 413 //! 414 //! \return None. 415 // 416 //***************************************************************************** 417 extern void MPU_enableInterrupt(void); 418 419 //***************************************************************************** 420 // 421 //! Disables the interrupt for the memory management fault. 422 //! 423 //! \return None. 424 // 425 //***************************************************************************** 426 extern void MPU_disableInterrupt(void); 427 428 //***************************************************************************** 429 // 430 // Mark the end of the C bindings section for C++ compilers. 431 // 432 //***************************************************************************** 433 #ifdef __cplusplus 434 } 435 #endif 436 437 //***************************************************************************** 438 // 439 // Close the Doxygen group. 440 //! @} 441 // 442 //***************************************************************************** 443 444 #endif // __MPU_H__ 445