1 /*
2  * Copyright (c) 2013-2014 Wind River Systems, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief ARM Cortex-M System Control Block interface
10  *
11  *
12  * Most of the SCB interface consists of simple bit-flipping methods, and is
13  * implemented as inline functions in scb.h. This module thus contains only data
14  * definitions and more complex routines, if needed.
15  */
16 
17 #include <zephyr/kernel.h>
18 #include <zephyr/arch/cpu.h>
19 #include <zephyr/sys/util.h>
20 #include <zephyr/sys/barrier.h>
21 #include <cmsis_core.h>
22 #include <zephyr/linker/linker-defs.h>
23 #include <zephyr/cache.h>
24 
25 #if defined(CONFIG_CPU_HAS_NXP_MPU)
26 #include <fsl_sysmpu.h>
27 #endif
28 
29 /**
30  *
31  * @brief Reset the system
32  *
33  * This routine resets the processor.
34  *
35  */
36 
sys_arch_reboot(int type)37 void __weak sys_arch_reboot(int type)
38 {
39 	ARG_UNUSED(type);
40 
41 	NVIC_SystemReset();
42 }
43 
44 #if defined(CONFIG_ARM_MPU)
45 #if defined(CONFIG_CPU_HAS_ARM_MPU)
46 /**
47  *
48  * @brief Clear all MPU region configuration
49  *
50  * This routine clears all ARM MPU region configuration.
51  *
52  */
z_arm_clear_arm_mpu_config(void)53 void z_arm_clear_arm_mpu_config(void)
54 {
55 	int i;
56 
57 	int num_regions =
58 		((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos);
59 
60 	for (i = 0; i < num_regions; i++) {
61 		ARM_MPU_ClrRegion(i);
62 	}
63 }
64 #elif CONFIG_CPU_HAS_NXP_MPU
z_arm_clear_arm_mpu_config(void)65 void z_arm_clear_arm_mpu_config(void)
66 {
67 	int i;
68 
69 	int num_regions = FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT;
70 
71 	SYSMPU_Enable(SYSMPU, false);
72 
73 	/* NXP MPU region 0 is reserved for the debugger */
74 	for (i = 1; i < num_regions; i++) {
75 		SYSMPU_RegionEnable(SYSMPU, i, false);
76 	}
77 }
78 #endif /* CONFIG_CPU_HAS_NXP_MPU */
79 #endif /* CONFIG_ARM_MPU */
80 
81 #if defined(CONFIG_INIT_ARCH_HW_AT_BOOT)
82 /**
83  *
84  * @brief Reset system control blocks and core registers
85  *
86  * This routine resets Cortex-M system control block
87  * components and core registers.
88  *
89  */
z_arm_init_arch_hw_at_boot(void)90 void z_arm_init_arch_hw_at_boot(void)
91 {
92     /* Disable interrupts */
93 	__disable_irq();
94 
95 #if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
96 	__set_FAULTMASK(0);
97 #endif
98 
99 	/* Initialize System Control Block components */
100 
101 #if defined(CONFIG_ARM_MPU)
102 	/* Clear MPU region configuration */
103 	z_arm_clear_arm_mpu_config();
104 #endif /* CONFIG_ARM_MPU */
105 
106 	/* Disable NVIC interrupts */
107 	for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
108 		NVIC->ICER[i] = 0xFFFFFFFF;
109 	}
110 	/* Clear pending NVIC interrupts */
111 	for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICPR); i++) {
112 		NVIC->ICPR[i] = 0xFFFFFFFF;
113 	}
114 
115 #if defined(CONFIG_ARCH_CACHE)
116 #if defined(CONFIG_DCACHE)
117 	/* Reset D-Cache settings. If the D-Cache was enabled,
118 	 * SCB_DisableDCache() takes care of cleaning and invalidating it.
119 	 * If it was already disabled, just call SCB_InvalidateDCache() to
120 	 * reset it to a known clean state.
121 	 */
122 	if (SCB->CCR & SCB_CCR_DC_Msk) {
123 		sys_cache_data_disable();
124 	} else {
125 		sys_cache_data_invd_all();
126 	}
127 #endif /* CONFIG_DCACHE */
128 
129 #if defined(CONFIG_ICACHE)
130 	/* Reset I-Cache settings. */
131 	sys_cache_instr_disable();
132 #endif /* CONFIG_ICACHE */
133 #endif /* CONFIG_ARCH_CACHE */
134 
135 	/* Restore Interrupts */
136 	__enable_irq();
137 
138 	barrier_dsync_fence_full();
139 	barrier_isync_fence_full();
140 }
141 #endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */
142