/* MPU configuration. */ void BOARD_ConfigMPU(void) { /* Disable I cache and D cache */ if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR)) { SCB_DisableICache(); } if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR)) { SCB_DisableDCache(); } /* Disable MPU */ ARM_MPU_Disable(); /* MPU configure: * Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) * API in core_cm7.h. * param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches disabled. * param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. * Use MACROS defined in core_cm7.h: ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO * Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes. * TypeExtField IsShareable IsCacheable IsBufferable Memory Attribtue Shareability Cache * 0 x 0 0 Strongly Ordered shareable * 0 x 0 1 Device shareable * 0 0 1 0 Normal not shareable Outer and inner write through no write allocate * 0 0 1 1 Normal not shareable Outer and inner write back no write allocate * 0 1 1 0 Normal shareable Outer and inner write through no write allocate * 0 1 1 1 Normal shareable Outer and inner write back no write allocate * 1 0 0 0 Normal not shareable outer and inner noncache * 1 1 0 0 Normal shareable outer and inner noncache * 1 0 1 1 Normal not shareable outer and inner write back write/read acllocate * 1 1 1 1 Normal shareable outer and inner write back write/read acllocate * 2 x 0 0 Device not shareable * Above are normal use settings, if your want to see more details or want to config different inner/outter cache policy. * please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf> * param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled. * param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in core_cm7.h. */ /* Region 0 setting: Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(0, 0xC0000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB); /* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB); /* Region 2 setting */ #if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) /* Setting Memory with Normal type, not shareable, outer/inner write back. */ MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_512MB); #else /* Setting Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB); #endif /* Region 3 setting: Memory with Device type, not shareable, non-cacheable. */ MPU->RBAR = ARM_MPU_RBAR(3, 0x00000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB); /* Region 4 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB); /* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(5, 0x20000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB); /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); /* The define sets the cacheable memory to shareable, * this suggestion is referred from chapter 2.2.1 Memory regions, * types and attributes in Cortex-M7 Devices, Generic User Guide */ #if defined(SDRAM_IS_SHAREABLE) /* Region 7 setting: Memory with Normal type, shareable, outer/inner write back, write/read allocate */ MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB); #else /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back, write/read allocate */ MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB); #endif /* Region 8 setting, set last 2MB of SDRAM can't be accessed by cache, glocal variables which are not expected to be * accessed by cache can be put here */ /* Memory with Normal type, not shareable, non-cacheable */ MPU->RBAR = ARM_MPU_RBAR(8, 0x81E00000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB); /* Enable MPU */ ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk); /* Enable I cache and D cache */ SCB_EnableDCache(); SCB_EnableICache(); }
/*----------------------------------------------------------------------------- * Test cases *----------------------------------------------------------------------------*/ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \brief Test case: TC_MPU_SetClear \details - Check if ARM_MPU_Load correctly loads MPU table to registers. */ void TC_MPU_SetClear(void) { #if defined(__MPU_PRESENT) && __MPU_PRESENT static const ARM_MPU_Region_t table[] = { { .RBAR = 0U, .RASR = 0U }, { .RBAR = ARM_MPU_RBAR(2U, 0x30000000U), .RASR = ARM_MPU_RASR(1U, ARM_MPU_AP_FULL, 0U, 0U, 0U, 0U, 0U, ARM_MPU_REGION_SIZE_128MB) }, { .RBAR = 0x50000000U, .RASR = ARM_MPU_RASR(0U, ARM_MPU_AP_FULL, 0U, 0U, 0U, 0U, 0U, ARM_MPU_REGION_SIZE_64MB) } }; #define ASSERT_MPU_REGION(rnr, region) \ MPU->RNR = rnr; \ ASSERT_TRUE((MPU->RBAR & MPU_RBAR_ADDR_Msk) == (region.RBAR & MPU_RBAR_ADDR_Msk)); \ ASSERT_TRUE(MPU->RASR == region.RASR) ClearMpu(); ARM_MPU_SetRegion(table[1].RBAR, table[1].RASR); ASSERT_MPU_REGION(1U, table[0]); ASSERT_MPU_REGION(2U, table[1]); ASSERT_MPU_REGION(3U, table[0]);