1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef FSL_SYSMPU_H_
10 #define FSL_SYSMPU_H_
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup sysmpu
16  * @{
17  */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 /*! @name Driver version */
24 /*! @{ */
25 /*! @brief SYSMPU driver version 2.2.3. */
26 #define FSL_SYSMPU_DRIVER_VERSION (MAKE_VERSION(2, 2, 3))
27 /*! @} */
28 
29 /*! @brief define the start master port with read and write attributes. */
30 #define SYSMPU_MASTER_RWATTRIBUTE_START_PORT (4U)
31 
32 /*! @brief SYSMPU the bit shift for masters with privilege rights: read write and execute. */
33 #define SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n) ((n)*6U)
34 
35 /*! @brief SYSMPU masters with read, write and execute rights bit mask. */
36 #define SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(n) (0x1FUL << SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))
37 
38 /*! @brief SYSMPU masters with read, write and execute rights bit width. */
39 #define SYSMPU_REGION_RWXRIGHTS_MASTER_WIDTH 5U
40 
41 /*! @brief SYSMPU masters with read, write and execute rights priority setting. */
42 #define SYSMPU_REGION_RWXRIGHTS_MASTER(n, x) \
43     (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))) & SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(n))
44 
45 /*! @brief SYSMPU masters with read, write and execute rights process enable bit shift. */
46 #define SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n) ((n)*6U + SYSMPU_REGION_RWXRIGHTS_MASTER_WIDTH)
47 
48 /*! @brief SYSMPU masters with read, write and execute rights process enable bit mask. */
49 #define SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n) (0x1UL << SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))
50 
51 /*! @brief SYSMPU masters with read, write and execute rights process enable setting. */
52 #define SYSMPU_REGION_RWXRIGHTS_MASTER_PE(n, x)                                    \
53     (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))) & \
54      SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n))
55 
56 /*! @brief SYSMPU masters with normal read write permission bit shift. */
57 #define SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n) (((n)-SYSMPU_MASTER_RWATTRIBUTE_START_PORT) * 2U + 24U)
58 
59 /*! @brief SYSMPU masters with normal read write rights bit mask. */
60 #define SYSMPU_REGION_RWRIGHTS_MASTER_MASK(n) (0x3UL << SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n))
61 
62 /*! @brief SYSMPU masters with normal read write rights priority setting. */
63 #define SYSMPU_REGION_RWRIGHTS_MASTER(n, x) \
64     (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n))) & SYSMPU_REGION_RWRIGHTS_MASTER_MASK(n))
65 
66 /*! @brief Describes the number of SYSMPU regions. */
67 typedef enum _sysmpu_region_total_num
68 {
69     kSYSMPU_8Regions  = 0x0U, /*!< SYSMPU supports 8 regions.  */
70     kSYSMPU_12Regions = 0x1U, /*!< SYSMPU supports 12 regions. */
71     kSYSMPU_16Regions = 0x2U  /*!< SYSMPU supports 16 regions. */
72 } sysmpu_region_total_num_t;
73 
74 /*! @brief SYSMPU slave port number. */
75 typedef enum _sysmpu_slave
76 {
77     kSYSMPU_Slave0 = 0U, /*!< SYSMPU slave port 0. */
78     kSYSMPU_Slave1 = 1U, /*!< SYSMPU slave port 1. */
79     kSYSMPU_Slave2 = 2U, /*!< SYSMPU slave port 2. */
80     kSYSMPU_Slave3 = 3U, /*!< SYSMPU slave port 3. */
81     kSYSMPU_Slave4 = 4U, /*!< SYSMPU slave port 4. */
82 #if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 5
83     kSYSMPU_Slave5 = 5U, /*!< SYSMPU slave port 5. */
84 #endif
85 #if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 6
86     kSYSMPU_Slave6 = 6U, /*!< SYSMPU slave port 6. */
87 #endif
88 #if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 7
89     kSYSMPU_Slave7 = 7U, /*!< SYSMPU slave port 7. */
90 #endif
91 } sysmpu_slave_t;
92 
93 /*! @brief SYSMPU error access control detail. */
94 typedef enum _sysmpu_err_access_control
95 {
96     kSYSMPU_NoRegionHit        = 0U, /*!< No region hit error. */
97     kSYSMPU_NoneOverlappRegion = 1U, /*!< Access single region error. */
98     kSYSMPU_OverlappRegion     = 2U  /*!< Access overlapping region error. */
99 } sysmpu_err_access_control_t;
100 
101 /*! @brief SYSMPU error access type. */
102 typedef enum _sysmpu_err_access_type
103 {
104     kSYSMPU_ErrTypeRead  = 0U, /*!< SYSMPU error access type --- read.  */
105     kSYSMPU_ErrTypeWrite = 1U  /*!< SYSMPU error access type --- write. */
106 } sysmpu_err_access_type_t;
107 
108 /*! @brief SYSMPU access error attributes.*/
109 typedef enum _sysmpu_err_attributes
110 {
111     kSYSMPU_InstructionAccessInUserMode       = 0U, /*!< Access instruction error in user mode. */
112     kSYSMPU_DataAccessInUserMode              = 1U, /*!< Access data error in user mode. */
113     kSYSMPU_InstructionAccessInSupervisorMode = 2U, /*!< Access instruction error in supervisor mode. */
114     kSYSMPU_DataAccessInSupervisorMode        = 3U  /*!< Access data error in supervisor mode. */
115 } sysmpu_err_attributes_t;
116 
117 /*! @brief SYSMPU access rights in supervisor mode for bus master 0 ~ 3. */
118 typedef enum _sysmpu_supervisor_access_rights
119 {
120     kSYSMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */
121     kSYSMPU_SupervisorReadExecute      = 1U, /*!< Read and execute operations are allowed in supervisor mode. */
122     kSYSMPU_SupervisorReadWrite        = 2U, /*!< Read write operations are allowed in supervisor mode. */
123     kSYSMPU_SupervisorEqualToUsermode  = 3U  /*!< Access permission equal to user mode. */
124 } sysmpu_supervisor_access_rights_t;
125 
126 /*! @brief SYSMPU access rights in user mode for bus master 0 ~ 3. */
127 typedef enum _sysmpu_user_access_rights
128 {
129     kSYSMPU_UserNoAccessRights   = 0U, /*!< No access allowed in user mode.  */
130     kSYSMPU_UserExecute          = 1U, /*!< Execute operation is allowed in user mode. */
131     kSYSMPU_UserWrite            = 2U, /*!< Write operation is allowed in user mode. */
132     kSYSMPU_UserWriteExecute     = 3U, /*!< Write and execute operations are allowed in user mode. */
133     kSYSMPU_UserRead             = 4U, /*!< Read is allowed in user mode. */
134     kSYSMPU_UserReadExecute      = 5U, /*!< Read and execute operations are allowed in user mode. */
135     kSYSMPU_UserReadWrite        = 6U, /*!< Read and write operations are allowed in user mode. */
136     kSYSMPU_UserReadWriteExecute = 7U  /*!< Read write and execute operations are allowed in user mode. */
137 } sysmpu_user_access_rights_t;
138 
139 /*! @brief SYSMPU hardware basic information. */
140 typedef struct _sysmpu_hardware_info
141 {
142     uint8_t hardwareRevisionLevel;            /*!< Specifies the SYSMPU's hardware and definition reversion level. */
143     uint8_t slavePortsNumbers;                /*!< Specifies the number of slave ports connected to SYSMPU. */
144     sysmpu_region_total_num_t regionsNumbers; /*!< Indicates the number of region descriptors implemented. */
145 } sysmpu_hardware_info_t;
146 
147 /*! @brief SYSMPU detail error access information. */
148 typedef struct _sysmpu_access_err_info
149 {
150     uint32_t master;                           /*!< Access error master. */
151     sysmpu_err_attributes_t attributes;        /*!< Access error attributes. */
152     sysmpu_err_access_type_t accessType;       /*!< Access error type. */
153     sysmpu_err_access_control_t accessControl; /*!< Access error control. */
154     uint32_t address;                          /*!< Access error address. */
155 #if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER
156     uint8_t processorIdentification; /*!< Access error processor identification. */
157 #endif                               /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */
158 } sysmpu_access_err_info_t;
159 
160 /*! @brief SYSMPU read/write/execute rights control for bus master 0 ~ 3. */
161 typedef struct _sysmpu_rwxrights_master_access_control
162 {
163     sysmpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */
164     sysmpu_user_access_rights_t userAccessRights;        /*!< Master access rights in user mode. */
165 #if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER
166     bool processIdentifierEnable; /*!< Enables or disables process identifier. */
167 #endif                            /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */
168 } sysmpu_rwxrights_master_access_control_t;
169 
170 /*! @brief SYSMPU read/write access control for bus master 4 ~ 7. */
171 typedef struct _sysmpu_rwrights_master_access_control
172 {
173     bool writeEnable; /*!< Enables or disables write permission. */
174     bool readEnable;  /*!< Enables or disables read permission.  */
175 } sysmpu_rwrights_master_access_control_t;
176 
177 /*!
178  * @brief SYSMPU region configuration structure.
179  *
180  * This structure is used to configure the regionNum region.
181  * The accessRights1[0] ~ accessRights1[3] are used to configure the bus master
182  * 0 ~ 3 with the privilege rights setting. The accessRights2[0] ~ accessRights2[3]
183  * are used to configure the high master 4 ~ 7 with the normal read write permission.
184  * The master port assignment is the chip configuration. Normally, the core is the
185  * master 0, debugger is the master 1.
186  * Note that the SYSMPU assigns a priority scheme where the debugger is treated as the highest
187  * priority master followed by the core and then all the remaining masters.
188  * SYSMPU protection does not allow writes from the core to affect the "regionNum 0" start
189  * and end address nor the permissions associated with the debugger. It can only write
190  * the permission fields associated with the other masters. This protection guarantees that
191  * the debugger always has access to the entire address space and those rights can't
192  * be changed by the core or any other bus master. Prepare
193  * the region configuration when regionNum is 0.
194  */
195 typedef struct _sysmpu_region_config
196 {
197     uint32_t regionNum;    /*!< SYSMPU region number, range form 0 ~ FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1. */
198     uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by SYSMPU. The
199                               actual start address is 0-modulo-32 byte address.  */
200     uint32_t endAddress;   /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by SYSMPU. The actual
201                             end   address is 31-modulo-32 byte address. */
202     sysmpu_rwxrights_master_access_control_t
203         accessRights1[4]; /*!< Masters with read, write and execute rights setting. */
204     sysmpu_rwrights_master_access_control_t accessRights2[4]; /*!< Masters with normal read write rights setting. */
205 #if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER
206     uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */
207     uint8_t
208         processIdMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier. */
209 #endif                 /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */
210 } sysmpu_region_config_t;
211 
212 /*!
213  * @brief The configuration structure for the SYSMPU initialization.
214  *
215  * This structure is used when calling the SYSMPU_Init function.
216  */
217 typedef struct _sysmpu_config
218 {
219     sysmpu_region_config_t regionConfig; /*!< Region access permission. */
220     struct _sysmpu_config *next;         /*!< Pointer to the next structure. */
221 } sysmpu_config_t;
222 
223 /*******************************************************************************
224  * API
225  ******************************************************************************/
226 
227 #if defined(__cplusplus)
228 extern "C" {
229 #endif /* _cplusplus */
230 
231 /*!
232  * @name Initialization and deinitialization
233  * @{
234  */
235 
236 /*!
237  * @brief Initializes the SYSMPU with the user configuration structure.
238  *
239  * This function configures the SYSMPU module with the user-defined configuration.
240  *
241  * @param base     SYSMPU peripheral base address.
242  * @param config   The pointer to the configuration structure.
243  */
244 void SYSMPU_Init(SYSMPU_Type *base, const sysmpu_config_t *config);
245 
246 /*!
247  * @brief Deinitializes the SYSMPU regions.
248  *
249  * @param base     SYSMPU peripheral base address.
250  */
251 void SYSMPU_Deinit(SYSMPU_Type *base);
252 
253 /*! @} */
254 
255 /*!
256  * @name Basic Control Operations
257  * @{
258  */
259 
260 /*!
261  * @brief Enables/disables the SYSMPU globally.
262  *
263  * Call this API to enable or disable the SYSMPU module.
264  *
265  * @param base     SYSMPU peripheral base address.
266  * @param enable   True enable SYSMPU, false disable SYSMPU.
267  */
SYSMPU_Enable(SYSMPU_Type * base,bool enable)268 static inline void SYSMPU_Enable(SYSMPU_Type *base, bool enable)
269 {
270     if (enable)
271     {
272         /* Enable the SYSMPU globally. */
273         base->CESR |= SYSMPU_CESR_VLD_MASK;
274     }
275     else
276     { /* Disable the SYSMPU globally. */
277         base->CESR &= ~SYSMPU_CESR_VLD_MASK;
278     }
279 }
280 
281 /*!
282  * @brief Enables/disables the SYSMPU for a special region.
283  *
284  * When SYSMPU is enabled, call this API to disable an unused region
285  * of an enabled SYSMPU. Call this API to minimize the power dissipation.
286  *
287  * @param base     SYSMPU peripheral base address.
288  * @param number   SYSMPU region number.
289  * @param enable   True enable the special region SYSMPU, false disable the special region SYSMPU.
290  */
SYSMPU_RegionEnable(SYSMPU_Type * base,uint32_t number,bool enable)291 static inline void SYSMPU_RegionEnable(SYSMPU_Type *base, uint32_t number, bool enable)
292 {
293     if (enable)
294     {
295         /* Enable the #number region SYSMPU. */
296         base->WORD[number][3] |= SYSMPU_WORD_VLD_MASK;
297     }
298     else
299     { /* Disable the #number region SYSMPU. */
300         base->WORD[number][3] &= ~SYSMPU_WORD_VLD_MASK;
301     }
302 }
303 
304 /*!
305  * @brief Gets the SYSMPU basic hardware information.
306  *
307  * @param base           SYSMPU peripheral base address.
308  * @param hardwareInform The pointer to the SYSMPU hardware information structure. See "sysmpu_hardware_info_t".
309  */
310 void SYSMPU_GetHardwareInfo(SYSMPU_Type *base, sysmpu_hardware_info_t *hardwareInform);
311 
312 /*!
313  * @brief Sets the SYSMPU region.
314  *
315  * Note: Due to the SYSMPU protection, the region number 0 does not allow writes from
316  * core to affect the start and end address nor the permissions associated with
317  * the debugger. It can only write the permission fields associated
318  * with the other masters.
319  *
320  * @param base          SYSMPU peripheral base address.
321  * @param regionConfig  The pointer to the SYSMPU user configuration structure. See "sysmpu_region_config_t".
322  */
323 void SYSMPU_SetRegionConfig(SYSMPU_Type *base, const sysmpu_region_config_t *regionConfig);
324 
325 /*!
326  * @brief Sets the region start and end address.
327  *
328  * Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by SYSMPU.
329  * The actual start address by SYSMPU is 0-modulo-32 byte address.
330  * Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by SYSMPU.
331  * The end address used by the SYSMPU is 31-modulo-32 byte address.
332  * Note: Due to the SYSMPU protection, the startAddr and endAddr can't be
333  * changed by the core when regionNum is 0.
334  *
335  * @param base          SYSMPU peripheral base address.
336  * @param regionNum     SYSMPU region number. The range is from 0 to
337  * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1.
338  * @param startAddr     Region start address.
339  * @param endAddr       Region end address.
340  */
341 void SYSMPU_SetRegionAddr(SYSMPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr);
342 
343 /*!
344  * @brief Sets the SYSMPU region access rights for masters with read, write, and execute rights.
345  * The SYSMPU access rights depend on two board classifications of bus masters.
346  * The privilege rights masters and the normal rights masters.
347  * The privilege rights masters have the read, write, and execute access rights.
348  * Except the normal read and write rights, the execute rights are also
349  * allowed for these masters. The privilege rights masters normally range from
350  * bus masters 0 - 3. However, the maximum master number is device-specific.
351  * See the "SYSMPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX".
352  * The normal rights masters access rights control see
353  * "SYSMPU_SetRegionRwMasterAccessRights()".
354  *
355  * @param base          SYSMPU peripheral base address.
356  * @param regionNum     SYSMPU region number. Should range from 0 to
357  * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1.
358  * @param masterNum     SYSMPU bus master number. Should range from 0 to
359  * SYSMPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX.
360  * @param accessRights  The pointer to the SYSMPU access rights configuration. See
361  * "sysmpu_rwxrights_master_access_control_t".
362  */
363 void SYSMPU_SetRegionRwxMasterAccessRights(SYSMPU_Type *base,
364                                            uint32_t regionNum,
365                                            uint32_t masterNum,
366                                            const sysmpu_rwxrights_master_access_control_t *accessRights);
367 #if FSL_FEATURE_SYSMPU_MASTER_COUNT > 4
368 /*!
369  * @brief Sets the SYSMPU region access rights for masters with read and write rights.
370  * The SYSMPU access rights depend on two board classifications of bus masters.
371  * The privilege rights masters and the normal rights masters.
372  * The normal rights masters only have the read and write access permissions.
373  * The privilege rights access control see "SYSMPU_SetRegionRwxMasterAccessRights".
374  *
375  * @param base          SYSMPU peripheral base address.
376  * @param regionNum     SYSMPU region number. The range is from 0 to
377  * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1.
378  * @param masterNum     SYSMPU bus master number. Should range from SYSMPU_MASTER_RWATTRIBUTE_START_PORT
379  * to ~ FSL_FEATURE_SYSMPU_MASTER_COUNT - 1.
380  * @param accessRights  The pointer to the SYSMPU access rights configuration. See
381  * "sysmpu_rwrights_master_access_control_t".
382  */
383 void SYSMPU_SetRegionRwMasterAccessRights(SYSMPU_Type *base,
384                                           uint32_t regionNum,
385                                           uint32_t masterNum,
386                                           const sysmpu_rwrights_master_access_control_t *accessRights);
387 #endif /* FSL_FEATURE_SYSMPU_MASTER_COUNT > 4 */
388 /*!
389  * @brief Gets the numbers of slave ports where errors occur.
390  *
391  * @param base       SYSMPU peripheral base address.
392  * @param slaveNum   SYSMPU slave port number.
393  * @return The slave ports error status.
394  *         true  - error happens in this slave port.
395  *         false - error didn't happen in this slave port.
396  */
397 bool SYSMPU_GetSlavePortErrorStatus(SYSMPU_Type *base, sysmpu_slave_t slaveNum);
398 
399 /*!
400  * @brief Gets the SYSMPU detailed error access information.
401  *
402  * @param base       SYSMPU peripheral base address.
403  * @param slaveNum   SYSMPU slave port number.
404  * @param errInform  The pointer to the SYSMPU access error information. See "sysmpu_access_err_info_t".
405  */
406 void SYSMPU_GetDetailErrorAccessInfo(SYSMPU_Type *base, sysmpu_slave_t slaveNum, sysmpu_access_err_info_t *errInform);
407 
408 /*! @} */
409 
410 #if defined(__cplusplus)
411 }
412 #endif
413 
414 /*! @}*/
415 
416 #endif /* FSL_SYSMPU_H_ */
417