1 /***************************************************************************//**
2  * @file
3  * @brief Memory protection unit (MPU) peripheral API
4  * @author Energy Micro AS
5  * @version 3.0.0
6  *******************************************************************************
7  * @section License
8  * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
9  *******************************************************************************
10  *
11  * Permission is granted to anyone to use this software for any purpose,
12  * including commercial applications, and to alter it and redistribute it
13  * freely, subject to the following restrictions:
14  *
15  * 1. The origin of this software must not be misrepresented; you must not
16  *    claim that you wrote the original software.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  *    misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  *
21  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
22  * obligation to support this Software. Energy Micro AS is providing the
23  * Software "AS IS", with no express or implied warranties of any kind,
24  * including, but not limited to, any implied warranties of merchantability
25  * or fitness for any particular purpose or warranties against infringement
26  * of any proprietary rights of a third party.
27  *
28  * Energy Micro AS will not be liable for any consequential, incidental, or
29  * special damages, or any other relief, or for any claim by any third party,
30  * arising from your use of this Software.
31  *
32  ******************************************************************************/
33 #ifndef __EM_MPU_H
34 #define __EM_MPU_H
35 
36 #include "em_part.h"
37 
38 #if defined(__MPU_PRESENT) && (__MPU_PRESENT == 1)
39 #include "em_assert.h"
40 
41 #include <stdbool.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /***************************************************************************//**
48  * @addtogroup EM_Library
49  * @{
50  ******************************************************************************/
51 
52 /***************************************************************************//**
53  * @addtogroup MPU
54  * @{
55  ******************************************************************************/
56 
57 /** @anchor MPU_CTRL_PRIVDEFENA
58  *  Argument to MPU_enable(). Enables priviledged
59  *  access to default memory map.                                            */
60 #define MPU_CTRL_PRIVDEFENA    MPU_CTRL_PRIVDEFENA_Msk
61 
62 /** @anchor MPU_CTRL_HFNMIENA
63  *  Argument to MPU_enable(). Enables MPU during hard fault,
64  *  NMI, and FAULTMASK handlers.                                             */
65 #define MPU_CTRL_HFNMIENA      MPU_CTRL_HFNMIENA_Msk
66 
67 /*******************************************************************************
68  ********************************   ENUMS   ************************************
69  ******************************************************************************/
70 
71 /**
72  * Size of an MPU region.
73  */
74 typedef enum
75 {
76   mpuRegionSize32b   = 4,        /**< 32   byte region size. */
77   mpuRegionSize64b   = 5,        /**< 64   byte region size. */
78   mpuRegionSize128b  = 6,        /**< 128  byte region size. */
79   mpuRegionSize256b  = 7,        /**< 256  byte region size. */
80   mpuRegionSize512b  = 8,        /**< 512  byte region size. */
81   mpuRegionSize1Kb   = 9,        /**< 1K   byte region size. */
82   mpuRegionSize2Kb   = 10,       /**< 2K   byte region size. */
83   mpuRegionSize4Kb   = 11,       /**< 4K   byte region size. */
84   mpuRegionSize8Kb   = 12,       /**< 8K   byte region size. */
85   mpuRegionSize16Kb  = 13,       /**< 16K  byte region size. */
86   mpuRegionSize32Kb  = 14,       /**< 32K  byte region size. */
87   mpuRegionSize64Kb  = 15,       /**< 64K  byte region size. */
88   mpuRegionSize128Kb = 16,       /**< 128K byte region size. */
89   mpuRegionSize256Kb = 17,       /**< 256K byte region size. */
90   mpuRegionSize512Kb = 18,       /**< 512K byte region size. */
91   mpuRegionSize1Mb   = 19,       /**< 1M   byte region size. */
92   mpuRegionSize2Mb   = 20,       /**< 2M   byte region size. */
93   mpuRegionSize4Mb   = 21,       /**< 4M   byte region size. */
94   mpuRegionSize8Mb   = 22,       /**< 8M   byte region size. */
95   mpuRegionSize16Mb  = 23,       /**< 16M  byte region size. */
96   mpuRegionSize32Mb  = 24,       /**< 32M  byte region size. */
97   mpuRegionSize64Mb  = 25,       /**< 64M  byte region size. */
98   mpuRegionSize128Mb = 26,       /**< 128M byte region size. */
99   mpuRegionSize256Mb = 27,       /**< 256M byte region size. */
100   mpuRegionSize512Mb = 28,       /**< 512M byte region size. */
101   mpuRegionSize1Gb   = 29,       /**< 1G   byte region size. */
102   mpuRegionSize2Gb   = 30,       /**< 2G   byte region size. */
103   mpuRegionSize4Gb   = 31        /**< 4G   byte region size. */
104 } MPU_RegionSize_TypeDef;
105 
106 /**
107  * MPU region access permission attributes.
108  */
109 typedef enum
110 {
111   mpuRegionNoAccess     = 0,  /**< No access what so ever.                   */
112   mpuRegionApPRw        = 1,  /**< Priviledged state R/W only.               */
113   mpuRegionApPRwURo     = 2,  /**< Priviledged state R/W, User state R only. */
114   mpuRegionApFullAccess = 3,  /**< R/W in Priviledged and User state.        */
115   mpuRegionApPRo        = 5,  /**< Priviledged R only.                       */
116   mpuRegionApPRo_URo    = 6   /**< R only in Priviledged and User state.     */
117 } MPU_RegionAp_TypeDef;
118 
119 
120 /*******************************************************************************
121  *******************************   STRUCTS   ***********************************
122  ******************************************************************************/
123 
124 /** MPU Region init structure. */
125 typedef struct
126 {
127   bool                   regionEnable;     /**< MPU region enable.                */
128   uint8_t                regionNo;         /**< MPU region number.                */
129   uint32_t               baseAddress;      /**< Region baseaddress.               */
130   MPU_RegionSize_TypeDef size;             /**< Memory region size.               */
131   MPU_RegionAp_TypeDef   accessPermission; /**< Memory access permissions.   */
132   bool                   disableExec;      /**< Disable execution.                */
133   bool                   shareable;        /**< Memory shareable attribute.       */
134   bool                   cacheable;        /**< Memory cacheable attribute.       */
135   bool                   bufferable;       /**< Memory bufferable attribute.      */
136   uint8_t                srd;              /**< Memory subregion disable bits.    */
137   uint8_t                tex;              /**< Memory type extension attributes. */
138 } MPU_RegionInit_TypeDef;
139 
140 /** Default configuration of MPU region init structure for flash memory.     */
141 #define MPU_INIT_FLASH_DEFAULT                                  \
142   {                                                             \
143     true,                   /* Enable MPU region.            */ \
144     0,                      /* MPU Region number.            */ \
145     FLASH_MEM_BASE,         /* Flash base address.           */ \
146     mpuRegionSize1Mb,       /* Size - Set to max. */ \
147     mpuRegionApFullAccess,  /* Access permissions.           */ \
148     false,                  /* Execution allowed.            */ \
149     false,                  /* Not shareable.                */ \
150     true,                   /* Cacheable.                    */ \
151     false,                  /* Not bufferable.               */ \
152     0,                      /* No subregions.                */ \
153     0                       /* No TEX attributes.            */ \
154   }
155 
156 
157 /** Default configuration of MPU region init structure for sram memory.      */
158 #define MPU_INIT_SRAM_DEFAULT                                   \
159   {                                                             \
160     true,                   /* Enable MPU region.            */ \
161     1,                      /* MPU Region number.            */ \
162     RAM_MEM_BASE,           /* SRAM base address.            */ \
163     mpuRegionSize128Kb,     /* Size - Set to max. */ \
164     mpuRegionApFullAccess,  /* Access permissions.           */ \
165     false,                  /* Execution allowed.            */ \
166     true,                   /* Shareable.                    */ \
167     true,                   /* Cacheable.                    */ \
168     false,                  /* Not bufferable.               */ \
169     0,                      /* No subregions.                */ \
170     0                       /* No TEX attributes.            */ \
171   }
172 
173 
174 /** Default configuration of MPU region init structure for onchip peripherals.*/
175 #define MPU_INIT_PERIPHERAL_DEFAULT                             \
176   {                                                             \
177     true,                   /* Enable MPU region.            */ \
178     0,                      /* MPU Region number.            */ \
179     0,                      /* Region base address.          */ \
180     mpuRegionSize32b,       /* Size - Set to minimum         */ \
181     mpuRegionApFullAccess,  /* Access permissions.           */ \
182     true,                   /* Execution not allowed.        */ \
183     true,                   /* Shareable.                    */ \
184     false,                  /* Not cacheable.                */ \
185     true,                   /* Bufferable.                   */ \
186     0,                      /* No subregions.                */ \
187     0                       /* No TEX attributes.            */ \
188   }
189 
190 
191 /*******************************************************************************
192  *****************************   PROTOTYPES   **********************************
193  ******************************************************************************/
194 
195 
196 void MPU_ConfigureRegion(const MPU_RegionInit_TypeDef *init);
197 
198 
199 /***************************************************************************//**
200  * @brief
201  *   Disable the MPU
202  * @details
203  *   Disable MPU and MPU fault exceptions.
204  ******************************************************************************/
MPU_Disable(void)205 __STATIC_INLINE void MPU_Disable(void)
206 {
207   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;      /* Disable fault exceptions */
208   MPU->CTRL  &= ~MPU_CTRL_ENABLE_Msk;            /* Disable the MPU */
209 }
210 
211 
212 /***************************************************************************//**
213  * @brief
214  *   Enable the MPU
215  * @details
216  *   Enable MPU and MPU fault exceptions.
217  * @param[in] flags
218  *   Use a logical OR of @ref MPU_CTRL_PRIVDEFENA and
219  *   @ref MPU_CTRL_HFNMIENA as needed.
220  ******************************************************************************/
MPU_Enable(uint32_t flags)221 __STATIC_INLINE void MPU_Enable(uint32_t flags)
222 {
223   EFM_ASSERT(!(flags & ~(MPU_CTRL_PRIVDEFENA_Msk |
224                          MPU_CTRL_HFNMIENA_Msk |
225                          MPU_CTRL_ENABLE_Msk)));
226 
227   MPU->CTRL   = flags | MPU_CTRL_ENABLE_Msk;     /* Enable the MPU */
228   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;       /* Enable fault exceptions */
229 }
230 
231 
232 /** @} (end addtogroup MPU) */
233 /** @} (end addtogroup EM_Library) */
234 
235 #ifdef __cplusplus
236 }
237 #endif
238 
239 #endif /* defined(__MPU_PRESENT) && (EBI_COUNT == 1) */
240 
241 #endif /* __EM_MPU_H */
242