/* * @brief MPU default configuration * * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ static int arm_mpu_init(struct device *arg) { u32_t r_index; if (mpu_config.num_regions > _get_num_regions()) { /* Attempt to configure more MPU regions than * what is supported by hardware. As this operation * is executed during system (pre-kernel) initialization, * we want to ensure we can detect an attempt to * perform invalid configuration. */ __ASSERT(0, "Request to configure: %u regions (supported: %u)\n", mpu_config.num_regions, _get_num_regions() ); return -1; } SYS_LOG_DBG("total region count: %d", _get_num_regions()); arm_core_mpu_disable(); /* Architecture-specific configuration */ _mpu_init(); /* Configure regions */ for (r_index = 0; r_index < mpu_config.num_regions; r_index++) { _region_init(r_index, &mpu_config.mpu_regions[r_index]); } #if defined(CONFIG_APPLICATION_MEMORY) u32_t index, size; struct arm_mpu_region region_conf; /* configure app data portion */ index = _get_region_index_by_type(THREAD_APP_DATA_REGION); size = (u32_t)&__app_ram_end - (u32_t)&__app_ram_start; _get_region_attr_by_type(®ion_conf.attr, THREAD_APP_DATA_REGION, (u32_t)&__app_ram_start, size); region_conf.base = (u32_t)&__app_ram_start; if (size > 0) { _region_init(index, ®ion_conf); } #endif arm_core_mpu_enable(); /* Sanity check for number of regions in Cortex-M0+, M3, and M4. */ #if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M3) || \ defined(CONFIG_CPU_CORTEX_M4) __ASSERT( (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos == 8, "Invalid number of MPU regions\n"); #endif return 0; }
/* * @brief MPU default configuration * * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ static int arm_mpu_init(struct device *arg) { u32_t r_index; if (mpu_config.num_regions > get_num_regions()) { /* Attempt to configure more MPU regions than * what is supported by hardware. As this operation * is executed during system (pre-kernel) initialization, * we want to ensure we can detect an attempt to * perform invalid configuration. */ __ASSERT(0, "Request to configure: %u regions (supported: %u)\n", mpu_config.num_regions, get_num_regions() ); return -1; } LOG_DBG("total region count: %d", get_num_regions()); arm_core_mpu_disable(); /* Architecture-specific configuration */ mpu_init(); /* Program fixed regions configured at SOC definition. */ for (r_index = 0U; r_index < mpu_config.num_regions; r_index++) { region_init(r_index, &mpu_config.mpu_regions[r_index]); } /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; arm_core_mpu_enable(); /* Sanity check for number of regions in Cortex-M0+, M3, and M4. */ #if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M3) || \ defined(CONFIG_CPU_CORTEX_M4) __ASSERT( (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos == 8, "Invalid number of MPU regions\n"); #elif defined(DT_NUM_MPU_REGIONS) __ASSERT( (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos == DT_NUM_MPU_REGIONS, "Invalid number of MPU regions\n"); #endif /* CORTEX_M0PLUS || CPU_CORTEX_M3 || CPU_CORTEX_M4 */ return 0; }
/* * @brief MPU default configuration * * This function provides the default configuration mechanism for the Memory * Protection Unit (MPU). */ static int nxp_mpu_init(struct device *arg) { ARG_UNUSED(arg); u32_t r_index; if (mpu_config.num_regions > _get_num_regions()) { /* Attempt to configure more MPU regions than * what is supported by hardware. As this operation * may be executed during system (pre-kernel) initialization, * we want to ensure we can detect an attempt to * perform invalid configuration. */ __ASSERT(0, "Request to configure: %u regions (supported: %u)\n", mpu_config.num_regions, _get_num_regions() ); return -1; } LOG_DBG("total region count: %d", _get_num_regions()); arm_core_mpu_disable(); /* Architecture-specific configuration */ _mpu_init(); /* Program fixed regions configured at SOC definition. */ for (r_index = 0U; r_index < mpu_config.num_regions; r_index++) { _region_init(r_index, &mpu_config.mpu_regions[r_index]); } /* Update the number of programmed MPU regions. */ static_regions_num = mpu_config.num_regions; arm_core_mpu_enable(); return 0; }
/* This internal function programs the dynamic MPU regions. * * It returns the number of MPU region indices configured. * * Note: * If the dynamic MPU regions configuration has not been successfully * performed, the error signal is propagated to the caller of the function. */ static int _mpu_configure_dynamic_mpu_regions(const struct k_mem_partition dynamic_regions[], u8_t regions_num) { /* Reset MPU regions inside which dynamic memory regions may * be programmed. * * Re-programming these regions will temporarily leave memory areas * outside all MPU regions. * This might trigger memory faults if ISRs occurring during * re-programming perform access in those areas. */ arm_core_mpu_disable(); _region_init(mpu_config.sram_region, (const struct nxp_mpu_region *) &mpu_config.mpu_regions[mpu_config.sram_region]); arm_core_mpu_enable(); u32_t mpu_reg_index = static_regions_num; /* In NXP MPU architecture the dynamic regions are * programmed on top of existing SRAM region configuration. */ mpu_reg_index = _mpu_configure_regions(dynamic_regions, regions_num, mpu_reg_index, false); if (mpu_reg_index != -EINVAL) { /* Disable the non-programmed MPU regions. */ for (int i = mpu_reg_index; i < _get_num_regions(); i++) { LOG_DBG("disable region 0x%x", i); /* Disable region */ SYSMPU->WORD[i][0] = 0; SYSMPU->WORD[i][1] = 0; SYSMPU->WORD[i][2] = 0; SYSMPU->WORD[i][3] = 0; } } return mpu_reg_index; }