fsl_sysmpu.h 19.3 KB
Newer Older
T
tanek liang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
/*
 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _FSL_SYSMPU_H_
#define _FSL_SYSMPU_H_

#include "fsl_common.h"

/*!
 * @addtogroup sysmpu
 * @{
 */


/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @name Driver version */
/*@{*/
/*! @brief SYSMPU driver version 2.2.0. */
#define FSL_SYSMPU_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/

/*! @brief define the start master port with read and write attributes. */
#define SYSMPU_MASTER_RWATTRIBUTE_START_PORT (4)

/*! @brief SYSMPU the bit shift for masters with privilege rights: read write and execute. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n) (n * 6)

/*! @brief SYSMPU masters with read, write and execute rights bit mask. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(n) (0x1Fu << SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))

/*! @brief SYSMPU masters with read, write and execute rights bit width. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER_WIDTH 5

/*! @brief SYSMPU masters with read, write and execute rights priority setting. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER(n, x) \
    (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))) & SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(n))

/*! @brief SYSMPU masters with read, write and execute rights process enable bit shift. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n) (n * 6 + SYSMPU_REGION_RWXRIGHTS_MASTER_WIDTH)

/*! @brief SYSMPU masters with read, write and execute rights process enable bit mask. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n) (0x1u << SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))

/*! @brief SYSMPU masters with read, write and execute rights process enable setting. */
#define SYSMPU_REGION_RWXRIGHTS_MASTER_PE(n, x) \
    (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))) & SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n))

/*! @brief SYSMPU masters with normal read write permission bit shift. */
#define SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n) ((n - SYSMPU_MASTER_RWATTRIBUTE_START_PORT) * 2 + 24)

/*! @brief SYSMPU masters with normal read write rights bit mask. */
#define SYSMPU_REGION_RWRIGHTS_MASTER_MASK(n) (0x3u << SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n))

/*! @brief SYSMPU masters with normal read write rights priority setting. */
#define SYSMPU_REGION_RWRIGHTS_MASTER(n, x) \
    (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n))) & SYSMPU_REGION_RWRIGHTS_MASTER_MASK(n))


/*! @brief Describes the number of SYSMPU regions. */
typedef enum _sysmpu_region_total_num
{
    kSYSMPU_8Regions = 0x0U,  /*!< SYSMPU supports 8 regions.  */
    kSYSMPU_12Regions = 0x1U, /*!< SYSMPU supports 12 regions. */
    kSYSMPU_16Regions = 0x2U  /*!< SYSMPU supports 16 regions. */
} sysmpu_region_total_num_t;

/*! @brief SYSMPU slave port number. */
typedef enum _sysmpu_slave
{
    kSYSMPU_Slave0 = 0U, /*!< SYSMPU slave port 0. */
    kSYSMPU_Slave1 = 1U, /*!< SYSMPU slave port 1. */
    kSYSMPU_Slave2 = 2U, /*!< SYSMPU slave port 2. */
    kSYSMPU_Slave3 = 3U, /*!< SYSMPU slave port 3. */
    kSYSMPU_Slave4 = 4U, /*!< SYSMPU slave port 4. */
#if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 5
    kSYSMPU_Slave5 = 5U, /*!< SYSMPU slave port 5. */
#endif
#if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 6
    kSYSMPU_Slave6 = 6U, /*!< SYSMPU slave port 6. */
#endif
#if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 7
    kSYSMPU_Slave7 = 7U, /*!< SYSMPU slave port 7. */
#endif
} sysmpu_slave_t;

/*! @brief SYSMPU error access control detail. */
typedef enum _sysmpu_err_access_control
{
    kSYSMPU_NoRegionHit = 0U,        /*!< No region hit error. */
    kSYSMPU_NoneOverlappRegion = 1U, /*!< Access single region error. */
    kSYSMPU_OverlappRegion = 2U      /*!< Access overlapping region error. */
} sysmpu_err_access_control_t;

/*! @brief SYSMPU error access type. */
typedef enum _sysmpu_err_access_type
{
    kSYSMPU_ErrTypeRead = 0U, /*!< SYSMPU error access type --- read.  */
    kSYSMPU_ErrTypeWrite = 1U /*!< SYSMPU error access type --- write. */
} sysmpu_err_access_type_t;

/*! @brief SYSMPU access error attributes.*/
typedef enum _sysmpu_err_attributes
{
    kSYSMPU_InstructionAccessInUserMode = 0U,       /*!< Access instruction error in user mode. */
    kSYSMPU_DataAccessInUserMode = 1U,              /*!< Access data error in user mode. */
    kSYSMPU_InstructionAccessInSupervisorMode = 2U, /*!< Access instruction error in supervisor mode. */
    kSYSMPU_DataAccessInSupervisorMode = 3U         /*!< Access data error in supervisor mode. */
} sysmpu_err_attributes_t;

/*! @brief SYSMPU access rights in supervisor mode for bus master 0 ~ 3. */
typedef enum _sysmpu_supervisor_access_rights
{
    kSYSMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */
    kSYSMPU_SupervisorReadExecute = 1U,      /*!< Read and execute operations are allowed in supervisor mode. */
    kSYSMPU_SupervisorReadWrite = 2U,        /*!< Read write operations are allowed in supervisor mode. */
    kSYSMPU_SupervisorEqualToUsermode = 3U   /*!< Access permission equal to user mode. */
} sysmpu_supervisor_access_rights_t;

/*! @brief SYSMPU access rights in user mode for bus master 0 ~ 3. */
typedef enum _sysmpu_user_access_rights
{
    kSYSMPU_UserNoAccessRights = 0U,  /*!< No access allowed in user mode.  */
    kSYSMPU_UserExecute = 1U,         /*!< Execute operation is allowed in user mode. */
    kSYSMPU_UserWrite = 2U,           /*!< Write operation is allowed in user mode. */
    kSYSMPU_UserWriteExecute = 3U,    /*!< Write and execute operations are allowed in user mode. */
    kSYSMPU_UserRead = 4U,            /*!< Read is allowed in user mode. */
    kSYSMPU_UserReadExecute = 5U,     /*!< Read and execute operations are allowed in user mode. */
    kSYSMPU_UserReadWrite = 6U,       /*!< Read and write operations are allowed in user mode. */
    kSYSMPU_UserReadWriteExecute = 7U /*!< Read write and execute operations are allowed in user mode. */
} sysmpu_user_access_rights_t;

/*! @brief SYSMPU hardware basic information. */
typedef struct _sysmpu_hardware_info
{
    uint8_t hardwareRevisionLevel;         /*!< Specifies the SYSMPU's hardware and definition reversion level. */
    uint8_t slavePortsNumbers;             /*!< Specifies the number of slave ports connected to SYSMPU. */
    sysmpu_region_total_num_t regionsNumbers; /*!< Indicates the number of region descriptors implemented. */
} sysmpu_hardware_info_t;

/*! @brief SYSMPU detail error access information. */
typedef struct _sysmpu_access_err_info
{
    uint32_t master;                        /*!< Access error master. */
    sysmpu_err_attributes_t attributes;        /*!< Access error attributes. */
    sysmpu_err_access_type_t accessType;       /*!< Access error type. */
    sysmpu_err_access_control_t accessControl; /*!< Access error control. */
    uint32_t address;                       /*!< Access error address. */
#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER
    uint8_t processorIdentification; /*!< Access error processor identification. */
#endif                               /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */
} sysmpu_access_err_info_t;

/*! @brief SYSMPU read/write/execute rights control for bus master 0 ~ 3. */
typedef struct _sysmpu_rwxrights_master_access_control
{
    sysmpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */
    sysmpu_user_access_rights_t userAccessRights;        /*!< Master access rights in user mode. */
#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER
    bool processIdentifierEnable; /*!< Enables or disables process identifier. */
#endif                            /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */
} sysmpu_rwxrights_master_access_control_t;

/*! @brief SYSMPU read/write access control for bus master 4 ~ 7. */
typedef struct _sysmpu_rwrights_master_access_control
{
    bool writeEnable; /*!< Enables or disables write permission. */
    bool readEnable;  /*!< Enables or disables read permission.  */
} sysmpu_rwrights_master_access_control_t;

/*!
 * @brief SYSMPU region configuration structure.
 *
 * This structure is used to configure the regionNum region.
 * The accessRights1[0] ~ accessRights1[3] are used to configure the bus master
 * 0 ~ 3 with the privilege rights setting. The accessRights2[0] ~ accessRights2[3]
 * are used to configure the high master 4 ~ 7 with the normal read write permission.
 * The master port assignment is the chip configuration. Normally, the core is the
 * master 0, debugger is the master 1.
 * Note that the SYSMPU assigns a priority scheme where the debugger is treated as the highest
 * priority master followed by the core and then all the remaining masters.
 * SYSMPU protection does not allow writes from the core to affect the "regionNum 0" start
 * and end address nor the permissions associated with the debugger. It can only write
 * the permission fields associated with the other masters. This protection guarantees that
 * the debugger always has access to the entire address space and those rights can't
 * be changed by the core or any other bus master. Prepare
 * the region configuration when regionNum is 0.
 */
typedef struct _sysmpu_region_config
{
    uint32_t regionNum;    /*!< SYSMPU region number, range form 0 ~ FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1. */
    uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by SYSMPU. The actual
                              start address is 0-modulo-32 byte address.  */
    uint32_t endAddress; /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by SYSMPU. The actual end
                          address is 31-modulo-32 byte address. */
    sysmpu_rwxrights_master_access_control_t accessRights1[4]; /*!< Masters with read, write and execute rights setting. */
    sysmpu_rwrights_master_access_control_t accessRights2[4];  /*!< Masters with normal read write rights setting. */
#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER
    uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */
    uint8_t
        processIdMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier. */
#endif                 /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */
} sysmpu_region_config_t;

/*!
 * @brief The configuration structure for the SYSMPU initialization.
 *
 * This structure is used when calling the SYSMPU_Init function.
 */
typedef struct _sysmpu_config
{
    sysmpu_region_config_t regionConfig; /*!< Region access permission. */
    struct _sysmpu_config *next;         /*!< Pointer to the next structure. */
} sysmpu_config_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */

/*!
 * @name Initialization and deinitialization
 * @{
 */

/*!
 * @brief Initializes the SYSMPU with the user configuration structure.
 *
 * This function configures the SYSMPU module with the user-defined configuration.
 *
 * @param base     SYSMPU peripheral base address.
 * @param config   The pointer to the configuration structure.
 */
void SYSMPU_Init(SYSMPU_Type *base, const sysmpu_config_t *config);

/*!
 * @brief Deinitializes the SYSMPU regions.
 *
 * @param base     SYSMPU peripheral base address.
 */
void SYSMPU_Deinit(SYSMPU_Type *base);

/* @}*/

/*!
 * @name Basic Control Operations
 * @{
 */

/*!
 * @brief Enables/disables the SYSMPU globally.
 *
 * Call this API to enable or disable the SYSMPU module.
 *
 * @param base     SYSMPU peripheral base address.
 * @param enable   True enable SYSMPU, false disable SYSMPU.
 */
static inline void SYSMPU_Enable(SYSMPU_Type *base, bool enable)
{
    if (enable)
    {
        /* Enable the SYSMPU globally. */
        base->CESR |= SYSMPU_CESR_VLD_MASK;
    }
    else
    { /* Disable the SYSMPU globally. */
        base->CESR &= ~SYSMPU_CESR_VLD_MASK;
    }
}

/*!
 * @brief Enables/disables the SYSMPU for a special region.
 *
 * When SYSMPU is enabled, call this API to disable an unused region
 * of an enabled SYSMPU. Call this API to minimize the power dissipation.
 *
 * @param base     SYSMPU peripheral base address.
 * @param number   SYSMPU region number.
 * @param enable   True enable the special region SYSMPU, false disable the special region SYSMPU.
 */
static inline void SYSMPU_RegionEnable(SYSMPU_Type *base, uint32_t number, bool enable)
{
    if (enable)
    {
        /* Enable the #number region SYSMPU. */
        base->WORD[number][3] |= SYSMPU_WORD_VLD_MASK;
    }
    else
    { /* Disable the #number region SYSMPU. */
        base->WORD[number][3] &= ~SYSMPU_WORD_VLD_MASK;
    }
}

/*!
 * @brief Gets the SYSMPU basic hardware information.
 *
 * @param base           SYSMPU peripheral base address.
 * @param hardwareInform The pointer to the SYSMPU hardware information structure. See "sysmpu_hardware_info_t".
 */
void SYSMPU_GetHardwareInfo(SYSMPU_Type *base, sysmpu_hardware_info_t *hardwareInform);

/*!
 * @brief Sets the SYSMPU region.
 *
 * Note: Due to the SYSMPU protection, the region number 0 does not allow writes from
 * core to affect the start and end address nor the permissions associated with
 * the debugger. It can only write the permission fields associated
 * with the other masters.
 *
 * @param base          SYSMPU peripheral base address.
 * @param regionConfig  The pointer to the SYSMPU user configuration structure. See "sysmpu_region_config_t".
 */
void SYSMPU_SetRegionConfig(SYSMPU_Type *base, const sysmpu_region_config_t *regionConfig);

/*!
 * @brief Sets the region start and end address.
 *
 * Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by SYSMPU.
 * The actual start address by SYSMPU is 0-modulo-32 byte address.
 * Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by SYSMPU.
 * The end address used by the SYSMPU is 31-modulo-32 byte address.
 * Note: Due to the SYSMPU protection, the startAddr and endAddr can't be
 * changed by the core when regionNum is 0.
 *
 * @param base          SYSMPU peripheral base address.
 * @param regionNum     SYSMPU region number. The range is from 0 to
 * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1.
 * @param startAddr     Region start address.
 * @param endAddr       Region end address.
 */
void SYSMPU_SetRegionAddr(SYSMPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr);

/*!
 * @brief Sets the SYSMPU region access rights for masters with read, write, and execute rights.
 * The SYSMPU access rights depend on two board classifications of bus masters.
 * The privilege rights masters and the normal rights masters.
 * The privilege rights masters have the read, write, and execute access rights.
 * Except the normal read and write rights, the execute rights are also
 * allowed for these masters. The privilege rights masters normally range from
 * bus masters 0 - 3. However, the maximum master number is device-specific.
 * See the "SYSMPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX".
 * The normal rights masters access rights control see
 * "SYSMPU_SetRegionRwMasterAccessRights()".
 *
 * @param base          SYSMPU peripheral base address.
 * @param regionNum     SYSMPU region number. Should range from 0 to
 * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1.
 * @param masterNum     SYSMPU bus master number. Should range from 0 to
 * SYSMPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX.
 * @param accessRights  The pointer to the SYSMPU access rights configuration. See "sysmpu_rwxrights_master_access_control_t".
 */
void SYSMPU_SetRegionRwxMasterAccessRights(SYSMPU_Type *base,
                                        uint32_t regionNum,
                                        uint32_t masterNum,
                                        const sysmpu_rwxrights_master_access_control_t *accessRights);
#if FSL_FEATURE_SYSMPU_MASTER_COUNT > 4
/*!
 * @brief Sets the SYSMPU region access rights for masters with read and write rights.
 * The SYSMPU access rights depend on two board classifications of bus masters.
 * The privilege rights masters and the normal rights masters.
 * The normal rights masters only have the read and write access permissions.
 * The privilege rights access control see "SYSMPU_SetRegionRwxMasterAccessRights".
 *
 * @param base          SYSMPU peripheral base address.
 * @param regionNum     SYSMPU region number. The range is from 0 to
 * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1.
 * @param masterNum     SYSMPU bus master number. Should range from SYSMPU_MASTER_RWATTRIBUTE_START_PORT
 * to ~ FSL_FEATURE_SYSMPU_MASTER_COUNT - 1.
 * @param accessRights  The pointer to the SYSMPU access rights configuration. See "sysmpu_rwrights_master_access_control_t".
 */
void SYSMPU_SetRegionRwMasterAccessRights(SYSMPU_Type *base,
                                       uint32_t regionNum,
                                       uint32_t masterNum,
                                       const sysmpu_rwrights_master_access_control_t *accessRights);
#endif  /* FSL_FEATURE_SYSMPU_MASTER_COUNT > 4 */
/*!
 * @brief Gets the numbers of slave ports where errors occur.
 *
 * @param base       SYSMPU peripheral base address.
 * @param slaveNum   SYSMPU slave port number.
 * @return The slave ports error status.
 *         true  - error happens in this slave port.
 *         false - error didn't happen in this slave port.
 */
bool SYSMPU_GetSlavePortErrorStatus(SYSMPU_Type *base, sysmpu_slave_t slaveNum);

/*!
 * @brief Gets the SYSMPU detailed error access information.
 *
 * @param base       SYSMPU peripheral base address.
 * @param slaveNum   SYSMPU slave port number.
 * @param errInform  The pointer to the SYSMPU access error information. See "sysmpu_access_err_info_t".
 */
void SYSMPU_GetDetailErrorAccessInfo(SYSMPU_Type *base, sysmpu_slave_t slaveNum, sysmpu_access_err_info_t *errInform);

/* @} */

#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* _FSL_SYSMPU_H_ */