-
Notifications
You must be signed in to change notification settings - Fork 656
/
Copy pathscb.c
154 lines (133 loc) · 3.46 KB
/
scb.c
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
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM Cortex-M System Control Block interface
*
*
* Most of the SCB interface consists of simple bit-flipping methods, and is
* implemented as inline functions in scb.h. This module thus contains only data
* definitions and more complex routines, if needed.
*/
#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/barrier.h>
#include <cmsis_core.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/cache.h>
#include <zephyr/arch/cache.h>
#if defined(CONFIG_CPU_HAS_NXP_SYSMPU)
#include <fsl_sysmpu.h>
#endif
/**
*
* @brief Reset the system
*
* This routine resets the processor.
*
*/
void __weak sys_arch_reboot(int type)
{
ARG_UNUSED(type);
NVIC_SystemReset();
}
#if defined(CONFIG_ARM_MPU)
#if defined(CONFIG_CPU_HAS_ARM_MPU)
/**
*
* @brief Clear all MPU region configuration
*
* This routine clears all ARM MPU region configuration.
*
*/
void z_arm_clear_arm_mpu_config(void)
{
int i;
int num_regions =
((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos);
for (i = 0; i < num_regions; i++) {
ARM_MPU_ClrRegion(i);
}
}
#elif CONFIG_CPU_HAS_NXP_SYSMPU
void z_arm_clear_arm_mpu_config(void)
{
int i;
int num_regions = FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT;
SYSMPU_Enable(SYSMPU, false);
/* NXP MPU region 0 is reserved for the debugger */
for (i = 1; i < num_regions; i++) {
SYSMPU_RegionEnable(SYSMPU, i, false);
}
}
#endif /* CONFIG_CPU_HAS_NXP_SYSMPU */
#endif /* CONFIG_ARM_MPU */
#if defined(CONFIG_INIT_ARCH_HW_AT_BOOT)
/**
*
* @brief Reset system control blocks and core registers
*
* This routine resets Cortex-M system control block
* components and core registers.
*
*/
void z_arm_init_arch_hw_at_boot(void)
{
/* Disable interrupts */
__disable_irq();
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
__set_FAULTMASK(0);
#endif
/* Initialize System Control Block components */
#if defined(CONFIG_ARM_MPU)
/* Clear MPU region configuration */
z_arm_clear_arm_mpu_config();
#endif /* CONFIG_ARM_MPU */
/* Disable NVIC interrupts */
for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
}
/* Clear pending NVIC interrupts */
for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICPR); i++) {
NVIC->ICPR[i] = 0xFFFFFFFF;
}
#if defined(CONFIG_ARCH_CACHE)
#if defined(CONFIG_DCACHE)
/* Reset D-Cache settings. If the D-Cache was enabled,
* SCB_DisableDCache() takes care of cleaning and invalidating it.
* If it was already disabled, just call SCB_InvalidateDCache() to
* reset it to a known clean state.
*/
if (SCB->CCR & SCB_CCR_DC_Msk) {
/*
* Do not use sys_cache_data_disable at this point, but instead
* the architecture specific function. This ensures that the
* cache is disabled although CONFIG_CACHE_MANAGEMENT might be
* disabled.
*/
SCB_DisableDCache();
} else {
SCB_InvalidateDCache();
}
#endif /* CONFIG_DCACHE */
#if defined(CONFIG_ICACHE)
/*
* Reset I-Cache settings.
* Do not use sys_cache_data_disable at this point, but instead
* the architecture specific function. This ensures that the
* cache is disabled although CONFIG_CACHE_MANAGEMENT might be
* disabled.
*/
SCB_DisableICache();
#endif /* CONFIG_ICACHE */
#endif /* CONFIG_ARCH_CACHE */
/* Restore Interrupts */
__enable_irq();
barrier_dsync_fence_full();
barrier_isync_fence_full();
}
#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */