S32 SDK
mpu_hal.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
44 #include <stddef.h>
45 #include "mpu_hal.h"
46 
47 /*******************************************************************************
48  * Definitions
49  *******************************************************************************/
50 /* Default value of access right */
51 #define DEFAULT_ACCESS_RIGHT (0x0061F7DFU)
52 /* Default value of end address */
53 #define DEFAULT_END_ADDRESS (0x1FU)
54 
55 /*******************************************************************************
56  * Code
57  *******************************************************************************/
58 /*FUNCTION**********************************************************************
59  *
60  * Function Name : MPU_HAL_GetSlavePortErrorStatus
61  * Description : Gets the error status of a specified slave port.
62  *
63  * Implements : MPU_HAL_GetSlavePortErrorStatus_Activity
64  *END**************************************************************************/
65 bool MPU_HAL_GetSlavePortErrorStatus(const MPU_Type * const base,
66  uint8_t slaveNum)
67 {
68  uint32_t sperr;
69 
71 
72  /* The following shows the correspondence between the bit number
73  * and slave port number:
74  * Bit 31 corresponds to slave port 0.
75  * Bit 30 corresponds to slave port 1.
76  * Bit 29 corresponds to slave port 2.
77  * Bit 28 corresponds to slave port 3.
78  */
79  sperr = ((base->CESR & FEATURE_MPU_SLAVE_MASK) & (1UL << (31U - slaveNum)));
80 
81  return (sperr != 0U) ? true : false;
82 }
83 
84 /*FUNCTION**********************************************************************
85  *
86  * Function Name : MPU_HAL_GetDetailErrorAccessInfo
87  * Description : Gets MPU detail error access info.
88  *
89  * Implements : MPU_HAL_GetDetailErrorAccessInfo_Activity
90  *END**************************************************************************/
92  uint8_t slaveNum,
93  mpu_access_err_info_t *errInfoPtr)
94 {
95  uint32_t temp;
96 
98  DEV_ASSERT(errInfoPtr != NULL);
99 
100  /* Read the Error Detail Register for the slave port */
101  temp = base->EAR_EDR[slaveNum].EDR;
102 
103  /* Read Error Access Control Detail of slave port (EACD) in EDRn register:
104  * If EDRn contains a captured error and EACD is cleared, an access did not hit
105  * in any region descriptor.
106  * If only a single EACD bit is set, the protection error was caused by a single
107  * non-overlapping region descriptor.
108  * If two or more EACD bits are set, the protection error was caused by an overlapping
109  * set of region descriptors.
110  */
111  errInfoPtr->accessCtr = (uint16_t)((temp & MPU_EDR_EACD_MASK) >> MPU_EDR_EACD_SHIFT);
112 
113  /* Report Error Master Number to user */
114  errInfoPtr->master = (uint8_t)((temp & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT);
115 
116  /* Report Error Attributes to user */
118 
119  /* Report Error Read/Write to user */
121 
122  /* Report Error Address to user */
123  errInfoPtr->addr = base->EAR_EDR[slaveNum].EAR;
124 
125 #if FEATURE_MPU_HAS_PROCESS_IDENTIFIER
126  /* Report Error Process Identification to user */
127  errInfoPtr->processorIdentification = (uint8_t)((temp & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT);
128 #endif
129 
130  /* Write 1 to clear the Slave Port Error */
131  temp = ((base->CESR & ~FEATURE_MPU_SLAVE_MASK) | (1UL << (31U - slaveNum)));
132  base->CESR = temp;
133 }
134 
135 /*FUNCTION**********************************************************************
136  *
137  * Function Name : MPU_HAL_SetRegionAddr
138  * Description : Sets region start and end address.
139  * Please note that using this function will clear the valid bit of the region,
140  * and a further validation might be needed.
141  *
142  * Implements : MPU_HAL_SetRegionAddr_Activity
143  *END**************************************************************************/
144 void MPU_HAL_SetRegionAddr(MPU_Type * const base,
145  uint8_t regionNum,
146  uint32_t startAddr,
147  uint32_t endAddr)
148 {
149  DEV_ASSERT(regionNum < MPU_RGD_COUNT);
150  DEV_ASSERT(startAddr <= endAddr);
151 
152  /* Write start address to RGD_WORD0 */
153  base->RGD[regionNum].WORD0 = startAddr;
154 
155  /* Write end address to RGD_WORD1 */
156  base->RGD[regionNum].WORD1 = endAddr;
157 }
158 
159 /*FUNCTION**********************************************************************
160  *
161  * Function Name : MPU_HAL_SetLowMasterAccessRights
162  * Description : Sets access permission for master which has separated privilege rights
163  * for user and supervisor mode accesses in a specific region.
164  * Please note that using this function will clear the valid bit of the region.
165  * In order to keep the region valid,
166  * the MPU_HAL_SetAlternateLowMasterAccessRights function can be used.
167  *
168  * Implements : MPU_HAL_SetLowMasterAccessRights_Activity
169  *END**************************************************************************/
171  uint8_t regionNum,
172  uint8_t masterNum,
173  const mpu_low_masters_access_rights_t *accessRightsPtr)
174 {
175  uint32_t accRight;
176  uint32_t accMask;
177  uint32_t accShift;
178  uint32_t temp;
179 
180  DEV_ASSERT(regionNum < MPU_RGD_COUNT);
182  DEV_ASSERT(accessRightsPtr != NULL);
183 
184  /* Prepare Supervisor Mode Access Control and User Mode Access Control value */
185  accRight = MPU_RGD_WORD2_M0UM(accessRightsPtr->userAccessRights) |
186  MPU_RGD_WORD2_M0SM(accessRightsPtr->superAccessRights);
188 #if FEATURE_MPU_HAS_PROCESS_IDENTIFIER
189  if (masterNum < FEATURE_MPU_MASTER_DMA)
190  {
191  accRight |= MPU_RGD_WORD2_M0PE(accessRightsPtr->processIdentifierEnable ? 1UL : 0UL);
192  }
193  accMask |= MPU_RGD_WORD2_M0PE_MASK;
194 #endif
195 
196  /* Shift FEATURE_MPU_LOW_MASTER_CONTROL_WIDTH bit field defining separate privilege rights
197  * depend on bus master number
198  */
199  accShift = ((uint32_t)masterNum * FEATURE_MPU_LOW_MASTER_CONTROL_WIDTH);
200  accRight = accRight << accShift;
201  accMask = accMask << accShift;
202 
203  /* Set access rights */
204  temp = base->RGD[regionNum].WORD2;
205  temp = (temp & ~accMask) | accRight;
206  base->RGD[regionNum].WORD2 = temp;
207 }
208 
209 /*FUNCTION**********************************************************************
210  *
211  * Function Name : MPU_HAL_SetHighMasterAccessRights
212  * Description : Sets access permission for master which has only read and write
213  * permissions in a specific region.
214  * Please note that using this function will clear the valid bit of the region.
215  * In order to keep the region valid,
216  * the MPU_HAL_SetAlternateHighMasterAccessRights function can be used.
217  *
218  * Implements : MPU_HAL_SetHighMasterAccessRights_Activity
219  *END**************************************************************************/
221  uint8_t regionNum,
222  uint8_t masterNum,
223  const mpu_high_masters_access_rights_t *accessRightsPtr)
224 {
225  uint32_t accRight;
226  uint32_t accMask;
227  uint32_t accShift;
228  uint32_t temp;
229 
230  DEV_ASSERT(regionNum < MPU_RGD_COUNT);
233  DEV_ASSERT(accessRightsPtr != NULL);
234 
235  /* Prepare Read Enable and Write Enable value */
236  accRight = MPU_RGD_WORD2_M4RE(accessRightsPtr->readEnable ? 1UL : 0UL) |
237  MPU_RGD_WORD2_M4WE(accessRightsPtr->writeEnable ? 1UL : 0UL);
238 
239  /* Low master number is numbered from 0 so master number count will be FEATURE_MPU_MAX_LOW_MASTER_NUMBER added to 1 */
241  accMask = (MPU_RGD_WORD2_M4RE_MASK | MPU_RGD_WORD2_M4WE_MASK) << accShift;
242  accRight = accRight << accShift;
243 
244  /* Set access right */
245  temp = base->RGD[regionNum].WORD2;
246  temp = (temp & ~accMask) | accRight;
247  base->RGD[regionNum].WORD2 = temp;
248 }
249 
250 /*FUNCTION**********************************************************************
251  *
252  * Function Name : MPU_HAL_SetAlternateLowMasterAccessRights
253  * Description : Sets access permission for master which has separated privilege rights
254  * for user and supervisor mode accesses in a specific region by alternate register.
255  *
256  * Implements : MPU_HAL_SetAlternateLowMasterAccessRights_Activity
257  *END**************************************************************************/
259  uint8_t regionNum,
260  uint8_t masterNum,
261  const mpu_low_masters_access_rights_t *accessRightsPtr)
262 {
263  uint32_t accRight;
264  uint32_t accMask;
265  uint32_t accShift;
266  uint32_t temp;
267 
268  DEV_ASSERT(regionNum < MPU_RGD_COUNT);
270  DEV_ASSERT(accessRightsPtr != NULL);
271 
272  /* Prepare Supervisor Mode Access Control and User Mode Access Control value */
273  accRight = MPU_RGDAAC_M0UM(accessRightsPtr->userAccessRights) |
274  MPU_RGDAAC_M0SM(accessRightsPtr->superAccessRights);
276 #if FEATURE_MPU_HAS_PROCESS_IDENTIFIER
277  if (masterNum < FEATURE_MPU_MASTER_DMA)
278  {
279  accRight |= MPU_RGDAAC_M0PE(accessRightsPtr->processIdentifierEnable ? 1UL : 0UL);
280  }
281  accMask |= MPU_RGDAAC_M0PE_MASK;
282 #endif
283 
284  /* Shift FEATURE_MPU_LOW_MASTER_CONTROL_WIDTH-bit field defining
285  * separate privilege rights depend on bus master number
286  */
287  accShift = ((uint32_t)masterNum * FEATURE_MPU_LOW_MASTER_CONTROL_WIDTH);
288  accRight = accRight << accShift;
289  accMask = accMask << accShift;
290 
291  /* Set access rights */
292  temp = base->RGDAAC[regionNum];
293  temp = (temp & ~accMask) | accRight;
294  base->RGDAAC[regionNum] = temp;
295 }
296 
297 /*FUNCTION**********************************************************************
298  *
299  * Function Name : MPU_HAL_SetAlternateHighMasterAccessRights
300  * Description : Sets access permission for master which has only read and write
301  * permissions in a specific region by alternate register.
302  *
303  * Implements : MPU_HAL_SetAlternateHighMasterAccessRights_Activity
304  *END**************************************************************************/
306  uint8_t regionNum,
307  uint8_t masterNum,
308  const mpu_high_masters_access_rights_t *accessRightsPtr)
309 {
310  uint32_t accRight;
311  uint32_t accMask;
312  uint32_t accShift;
313  uint32_t temp;
314 
315  DEV_ASSERT(regionNum < MPU_RGD_COUNT);
318  DEV_ASSERT(accessRightsPtr != NULL);
319 
320  /* Prepare Read Enable and Write Enable value */
321  accRight = MPU_RGDAAC_M4RE(accessRightsPtr->readEnable ? 1UL : 0UL) |
322  MPU_RGDAAC_M4WE(accessRightsPtr->writeEnable ? 1UL : 0UL);
323 
324  /* Low master number is numbered from 0 so master number count will be FEATURE_MPU_MAX_LOW_MASTER_NUMBER added to 1 */
326  accMask = (MPU_RGDAAC_M4RE_MASK | MPU_RGDAAC_M4WE_MASK) << accShift;
327  accRight = accRight << accShift;
328 
329  /* Set access right */
330  temp = base->RGDAAC[regionNum];
331  temp = (temp & ~accMask) | accRight;
332  base->RGDAAC[regionNum] = temp;
333 }
334 
335 /*FUNCTION**********************************************************************
336  *
337  * Function Name : MPU_HAL_Init
338  * Description : Initialize MPU module and all regions will be invalid after cleared access permission.
339  *
340  * Implements : MPU_HAL_Init_Activity
341  *END**************************************************************************/
342 void MPU_HAL_Init(MPU_Type * const base)
343 {
344  uint8_t i;
345 
346  /* Global disable for the MPU */
347  MPU_HAL_Disable(base);
348 
349  /* Sets default access right for region 0 */
350  base->RGDAAC[0U] = DEFAULT_ACCESS_RIGHT;
351 
352  /* Clear access permission form Region 1 because the MPU includes default settings and protections for
353  * the Region Descriptor 0 (RGD0) such that the Debugger always has access to the entire address space
354  * and those rights cannot be changed by the core or any other bus master.
355  */
356  for (i = 1U; i < MPU_RGD_COUNT; i++)
357  {
359  base->RGD[i].WORD2 = 0U;
360  base->RGD[i].WORD3 = 0U;
361  }
362 }
363 
364 /*******************************************************************************
365  * EOF
366  *******************************************************************************/
#define MPU_EDR_EPID_MASK
Definition: S32K144.h:7633
#define MPU_EDR_ERW_SHIFT
Definition: S32K144.h:7622
#define MPU_EDR_EATTR_SHIFT
Definition: S32K144.h:7626
void MPU_HAL_SetAlternateHighMasterAccessRights(MPU_Type *const base, uint8_t regionNum, uint8_t masterNum, const mpu_high_masters_access_rights_t *accessRightsPtr)
Sets access permission for master which has only read and write permissions in a specific region by a...
Definition: mpu_hal.c:305
#define MPU_RGD_WORD2_M0PE(x)
Definition: S32K144.h:7663
MPU access rights for master which have only read and write permissions Implements : mpu_high_masters...
Definition: mpu_hal.h:127
struct MPU_Type::@15 RGD[MPU_RGD_COUNT]
#define DEFAULT_ACCESS_RIGHT
Definition: mpu_hal.c:51
__I uint32_t EAR
Definition: S32K144.h:7539
void MPU_HAL_SetHighMasterAccessRights(MPU_Type *const base, uint8_t regionNum, uint8_t masterNum, const mpu_high_masters_access_rights_t *accessRightsPtr)
Sets access permission for master which has only read and write permissions in a specific region...
Definition: mpu_hal.c:220
#define MPU_RGDAAC_M4RE_MASK
Definition: S32K144.h:7782
bool MPU_HAL_GetSlavePortErrorStatus(const MPU_Type *const base, uint8_t slaveNum)
Gets the error status of a specified slave port.
Definition: mpu_hal.c:65
struct MPU_Type::@14 EAR_EDR[MPU_EAR_EDR_COUNT]
#define MPU_EDR_EMN_MASK
Definition: S32K144.h:7629
#define MPU_EDR_EACD_MASK
Definition: S32K144.h:7637
#define MPU_EDR_EPID_SHIFT
Definition: S32K144.h:7634
#define MPU_EDR_EATTR_MASK
Definition: S32K144.h:7625
#define MPU_RGDAAC_M0PE(x)
Definition: S32K144.h:7749
mpu_err_access_type_t accessType
Definition: mpu_hal.h:101
#define MPU_RGD_WORD2_M4RE_MASK
Definition: S32K144.h:7696
#define MPU_RGDAAC_M0SM(x)
Definition: S32K144.h:7745
#define FEATURE_MPU_MAX_LOW_MASTER_NUMBER
#define DEFAULT_END_ADDRESS
Definition: mpu_hal.c:53
mpu_user_access_rights_t userAccessRights
Definition: mpu_hal.h:116
__IO uint32_t WORD0
Definition: S32K144.h:7548
static void MPU_HAL_Disable(MPU_Type *const base)
Disables the MPU module.
Definition: mpu_hal.h:157
#define MPU_RGDAAC_M0SM_MASK
Definition: S32K144.h:7742
#define MPU_RGDAAC_M4RE(x)
Definition: S32K144.h:7785
#define DEV_ASSERT(x)
Definition: devassert.h:78
#define MPU_RGD_WORD2_M0UM_MASK
Definition: S32K144.h:7652
uint8_t processorIdentification
Definition: mpu_hal.h:105
void MPU_HAL_SetAlternateLowMasterAccessRights(MPU_Type *const base, uint8_t regionNum, uint8_t masterNum, const mpu_low_masters_access_rights_t *accessRightsPtr)
Sets access permission for master which has separated privilege rights for user and supervisor mode a...
Definition: mpu_hal.c:258
__IO uint32_t WORD1
Definition: S32K144.h:7549
__I uint32_t EDR
Definition: S32K144.h:7542
void MPU_HAL_SetLowMasterAccessRights(MPU_Type *const base, uint8_t regionNum, uint8_t masterNum, const mpu_low_masters_access_rights_t *accessRightsPtr)
Sets access permission for master which has separated privilege rights for user and supervisor mode a...
Definition: mpu_hal.c:170
#define MPU_RGD_WORD2_M0PE_MASK
Definition: S32K144.h:7660
#define MPU_RGD_WORD2_M0UM(x)
Definition: S32K144.h:7655
#define FEATURE_MPU_HIGH_MASTER_CONTROL_WIDTH
void MPU_HAL_Init(MPU_Type *const base)
Initializes the MPU module and all regions will be invalid after cleared access permission.
Definition: mpu_hal.c:342
#define MPU_RGDAAC_M0UM(x)
Definition: S32K144.h:7741
#define MPU_RGDAAC_M0PE_MASK
Definition: S32K144.h:7746
#define MPU_RGD_COUNT
Definition: S32K144.h:7531
#define MPU_EDR_EACD_SHIFT
Definition: S32K144.h:7638
mpu_supervisor_access_rights_t superAccessRights
Definition: mpu_hal.h:117
#define MPU_RGD_WORD2_M4RE(x)
Definition: S32K144.h:7699
mpu_err_attributes_t
MPU access error attributes Implements : mpu_err_attributes_t_Class.
Definition: mpu_hal.h:57
__IO uint32_t RGDAAC[MPU_RGDAAC_COUNT]
Definition: S32K144.h:7554
#define FEATURE_MPU_SLAVE_MASK
mpu_err_attributes_t attributes
Definition: mpu_hal.h:100
MPU detail error access info Implements : mpu_access_err_info_t_Class.
Definition: mpu_hal.h:97
#define MPU_RGD_WORD2_M4WE_MASK
Definition: S32K144.h:7692
#define MPU_RGD_WORD2_M0SM(x)
Definition: S32K144.h:7659
MPU access rights for masters which have separated privilege rights for user and supervisor mode acce...
Definition: mpu_hal.h:114
#define MPU_RGD_WORD2_M0SM_MASK
Definition: S32K144.h:7656
void MPU_HAL_SetRegionAddr(MPU_Type *const base, uint8_t regionNum, uint32_t startAddr, uint32_t endAddr)
Sets region start and end address. Please note that using this function will clear the valid bit of t...
Definition: mpu_hal.c:144
__IO uint32_t WORD2
Definition: S32K144.h:7550
#define MPU_RGDAAC_M4WE(x)
Definition: S32K144.h:7781
__IO uint32_t CESR
Definition: S32K144.h:7536
#define MPU_RGDAAC_M4WE_MASK
Definition: S32K144.h:7778
#define FEATURE_MPU_LOW_MASTER_CONTROL_WIDTH
#define MPU_RGD_WORD2_M4WE(x)
Definition: S32K144.h:7695
void MPU_HAL_GetDetailErrorAccessInfo(MPU_Type *const base, uint8_t slaveNum, mpu_access_err_info_t *errInfoPtr)
Gets MPU detail error access info.
Definition: mpu_hal.c:91
#define FEATURE_MPU_MAX_HIGH_MASTER_NUMBER
#define MPU_EDR_ERW_MASK
Definition: S32K144.h:7621
uint16_t accessCtr
Definition: mpu_hal.h:102
#define FEATURE_MPU_MASTER_DMA
__IO uint32_t WORD3
Definition: S32K144.h:7551
#define MPU_RGDAAC_M0UM_MASK
Definition: S32K144.h:7738
#define FEATURE_MPU_SLAVE_COUNT
mpu_err_access_type_t
MPU access error Implements : mpu_err_access_type_t_Class.
Definition: mpu_hal.h:47
#define MPU_EDR_EMN_SHIFT
Definition: S32K144.h:7630