1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_firewall.c
4 * @author MCD Application Team
5 * @brief FIREWALL HAL module driver.
6 * This file provides firmware functions to manage the Firewall
7 * Peripheral initialization and enabling.
8 *
9 ******************************************************************************
10 * @attention
11 *
12 * Copyright (c) 2017 STMicroelectronics.
13 * All rights reserved.
14 *
15 * This software is licensed under terms that can be found in the LICENSE file
16 * in the root directory of this software component.
17 * If no LICENSE file comes with this software, it is provided AS-IS.
18 *
19 ******************************************************************************
20 @verbatim
21 ===============================================================================
22 ##### How to use this driver #####
23 ===============================================================================
24 [..]
25 The FIREWALL HAL driver can be used as follows:
26
27 (#) Declare a FIREWALL_InitTypeDef initialization structure.
28
29 (#) Resort to HAL_FIREWALL_Config() API to initialize the Firewall
30
31 (#) Enable the FIREWALL in calling HAL_FIREWALL_EnableFirewall() API
32
33 (#) To ensure that any code executed outside the protected segment closes the
34 FIREWALL, the user must set the flag FIREWALL_PRE_ARM_SET in calling
35 __HAL_FIREWALL_PREARM_ENABLE() macro if called within a protected code segment
36 or
37 HAL_FIREWALL_EnablePreArmFlag() API if called outside of protected code segment
38 after HAL_FIREWALL_Config() call.
39
40
41 @endverbatim
42 ******************************************************************************
43 */
44
45 /* Includes ------------------------------------------------------------------*/
46 #include "stm32l4xx_hal.h"
47
48 /** @addtogroup STM32L4xx_HAL_Driver
49 * @{
50 */
51
52 /** @defgroup FIREWALL FIREWALL
53 * @brief HAL FIREWALL module driver
54 * @{
55 */
56 #ifdef HAL_FIREWALL_MODULE_ENABLED
57
58 /* Private typedef -----------------------------------------------------------*/
59 /* Private define ------------------------------------------------------------*/
60 /* Private macro -------------------------------------------------------------*/
61 /* Private variables ---------------------------------------------------------*/
62 /* Private function prototypes -----------------------------------------------*/
63 /* Private functions ---------------------------------------------------------*/
64
65
66 /** @defgroup FIREWALL_Exported_Functions FIREWALL Exported Functions
67 * @{
68 */
69
70 /** @defgroup FIREWALL_Exported_Functions_Group1 Initialization Functions
71 * @brief Initialization and Configuration Functions
72 *
73 @verbatim
74 ===============================================================================
75 ##### Initialization and Configuration functions #####
76 ===============================================================================
77 [..]
78 This subsection provides the functions allowing to initialize the Firewall.
79 Initialization is done by HAL_FIREWALL_Config():
80
81 (+) Enable the Firewall clock through __HAL_RCC_FIREWALL_CLK_ENABLE() macro.
82
83 (+) Set the protected code segment address start and length.
84
85 (+) Set the protected non-volatile and/or volatile data segments
86 address starts and lengths if applicable.
87
88 (+) Set the volatile data segment execution and sharing status.
89
90 (+) Length must be set to 0 for an unprotected segment.
91
92 @endverbatim
93 * @{
94 */
95
96 /**
97 * @brief Initialize the Firewall according to the FIREWALL_InitTypeDef structure parameters.
98 * @param fw_init: Firewall initialization structure
99 * @note The API returns HAL_ERROR if the Firewall is already enabled.
100 * @retval HAL status
101 */
HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)102 HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)
103 {
104 /* Check the Firewall initialization structure allocation */
105 if(fw_init == NULL)
106 {
107 return HAL_ERROR;
108 }
109
110 /* Enable Firewall clock */
111 __HAL_RCC_FIREWALL_CLK_ENABLE();
112
113 /* Make sure that Firewall is not enabled already */
114 if (__HAL_FIREWALL_IS_ENABLED() != RESET)
115 {
116 return HAL_ERROR;
117 }
118
119 /* Check Firewall configuration addresses and lengths when segment is protected */
120 /* Code segment */
121 if (fw_init->CodeSegmentLength != 0U)
122 {
123 assert_param(IS_FIREWALL_CODE_SEGMENT_ADDRESS(fw_init->CodeSegmentStartAddress));
124 assert_param(IS_FIREWALL_CODE_SEGMENT_LENGTH(fw_init->CodeSegmentStartAddress, fw_init->CodeSegmentLength));
125 /* Make sure that NonVDataSegmentLength is properly set to prevent code segment access */
126 if (fw_init->NonVDataSegmentLength < 0x100U)
127 {
128 return HAL_ERROR;
129 }
130 }
131 /* Non volatile data segment */
132 if (fw_init->NonVDataSegmentLength != 0U)
133 {
134 assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_ADDRESS(fw_init->NonVDataSegmentStartAddress));
135 assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_LENGTH(fw_init->NonVDataSegmentStartAddress, fw_init->NonVDataSegmentLength));
136 }
137 /* Volatile data segment */
138 if (fw_init->VDataSegmentLength != 0U)
139 {
140 assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_ADDRESS(fw_init->VDataSegmentStartAddress));
141 assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_LENGTH(fw_init->VDataSegmentStartAddress, fw_init->VDataSegmentLength));
142 }
143
144 /* Check Firewall Configuration Register parameters */
145 assert_param(IS_FIREWALL_VOLATILEDATA_EXECUTE(fw_init->VolatileDataExecution));
146 assert_param(IS_FIREWALL_VOLATILEDATA_SHARE(fw_init->VolatileDataShared));
147
148
149 /* Configuration */
150
151 /* Protected code segment start address configuration */
152 WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress));
153 /* Protected code segment length configuration */
154 WRITE_REG(FIREWALL->CSL, (FW_CSL_LENG & fw_init->CodeSegmentLength));
155
156 /* Protected non volatile data segment start address configuration */
157 WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress));
158 /* Protected non volatile data segment length configuration */
159 WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength));
160
161 /* Protected volatile data segment start address configuration */
162 WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress));
163 /* Protected volatile data segment length configuration */
164 WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength));
165
166 /* Set Firewall Configuration Register VDE and VDS bits
167 (volatile data execution and shared configuration) */
168 MODIFY_REG(FIREWALL->CR, FW_CR_VDS|FW_CR_VDE, fw_init->VolatileDataExecution|fw_init->VolatileDataShared);
169
170 return HAL_OK;
171 }
172
173 /**
174 * @brief Retrieve the Firewall configuration.
175 * @param fw_config: Firewall configuration, type is same as initialization structure
176 * @note This API can't be executed inside a code area protected by the Firewall
177 * when the Firewall is enabled
178 * @note If NVDSL register is different from 0, that is, if the non volatile data segment
179 * is defined, this API can't be executed when the Firewall is enabled.
180 * @note User should resort to __HAL_FIREWALL_GET_PREARM() macro to retrieve FPA bit status
181 * @retval None
182 */
HAL_FIREWALL_GetConfig(FIREWALL_InitTypeDef * fw_config)183 void HAL_FIREWALL_GetConfig(FIREWALL_InitTypeDef * fw_config)
184 {
185
186 /* Enable Firewall clock, in case no Firewall configuration has been carried
187 out up to this point */
188 __HAL_RCC_FIREWALL_CLK_ENABLE();
189
190 /* Retrieve code segment protection setting */
191 fw_config->CodeSegmentStartAddress = (READ_REG(FIREWALL->CSSA) & FW_CSSA_ADD);
192 fw_config->CodeSegmentLength = (READ_REG(FIREWALL->CSL) & FW_CSL_LENG);
193
194 /* Retrieve non volatile data segment protection setting */
195 fw_config->NonVDataSegmentStartAddress = (READ_REG(FIREWALL->NVDSSA) & FW_NVDSSA_ADD);
196 fw_config->NonVDataSegmentLength = (READ_REG(FIREWALL->NVDSL) & FW_NVDSL_LENG);
197
198 /* Retrieve volatile data segment protection setting */
199 fw_config->VDataSegmentStartAddress = (READ_REG(FIREWALL->VDSSA) & FW_VDSSA_ADD);
200 fw_config->VDataSegmentLength = (READ_REG(FIREWALL->VDSL) & FW_VDSL_LENG);
201
202 /* Retrieve volatile data execution setting */
203 fw_config->VolatileDataExecution = (READ_REG(FIREWALL->CR) & FW_CR_VDE);
204
205 /* Retrieve volatile data shared setting */
206 fw_config->VolatileDataShared = (READ_REG(FIREWALL->CR) & FW_CR_VDS);
207
208 return;
209 }
210
211
212
213 /**
214 * @brief Enable FIREWALL.
215 * @note Firewall is enabled in clearing FWDIS bit of SYSCFG CFGR1 register.
216 * Once enabled, the Firewall cannot be disabled by software. Only a
217 * system reset can set again FWDIS bit.
218 * @retval None
219 */
HAL_FIREWALL_EnableFirewall(void)220 void HAL_FIREWALL_EnableFirewall(void)
221 {
222 /* Clears FWDIS bit of SYSCFG CFGR1 register */
223 CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_FWDIS);
224
225 }
226
227 /**
228 * @brief Enable FIREWALL pre arm.
229 * @note When FPA bit is set, any code executed outside the protected segment
230 * will close the Firewall.
231 * @note This API provides the same service as __HAL_FIREWALL_PREARM_ENABLE() macro
232 * but can't be executed inside a code area protected by the Firewall.
233 * @note When the Firewall is disabled, user can resort to HAL_FIREWALL_EnablePreArmFlag() API any time.
234 * @note When the Firewall is enabled and NVDSL register is equal to 0 (that is,
235 * when the non volatile data segment is not defined),
236 * ** this API can be executed when the Firewall is closed
237 * ** when the Firewall is opened, user should resort to
238 * __HAL_FIREWALL_PREARM_ENABLE() macro instead
239 * @note When the Firewall is enabled and NVDSL register is different from 0
240 * (that is, when the non volatile data segment is defined)
241 * ** FW_CR register can be accessed only when the Firewall is opened:
242 * user should resort to __HAL_FIREWALL_PREARM_ENABLE() macro instead.
243 * @retval None
244 */
HAL_FIREWALL_EnablePreArmFlag(void)245 void HAL_FIREWALL_EnablePreArmFlag(void)
246 {
247 /* Set FPA bit */
248 SET_BIT(FIREWALL->CR, FW_CR_FPA);
249 }
250
251
252 /**
253 * @brief Disable FIREWALL pre arm.
254 * @note When FPA bit is reset, any code executed outside the protected segment
255 * when the Firewall is opened will generate a system reset.
256 * @note This API provides the same service as __HAL_FIREWALL_PREARM_DISABLE() macro
257 * but can't be executed inside a code area protected by the Firewall.
258 * @note When the Firewall is disabled, user can resort to HAL_FIREWALL_EnablePreArmFlag() API any time.
259 * @note When the Firewall is enabled and NVDSL register is equal to 0 (that is,
260 * when the non volatile data segment is not defined),
261 * ** this API can be executed when the Firewall is closed
262 * ** when the Firewall is opened, user should resort to
263 * __HAL_FIREWALL_PREARM_DISABLE() macro instead
264 * @note When the Firewall is enabled and NVDSL register is different from 0
265 * (that is, when the non volatile data segment is defined)
266 * ** FW_CR register can be accessed only when the Firewall is opened:
267 * user should resort to __HAL_FIREWALL_PREARM_DISABLE() macro instead.
268
269 * @retval None
270 */
HAL_FIREWALL_DisablePreArmFlag(void)271 void HAL_FIREWALL_DisablePreArmFlag(void)
272 {
273 /* Clear FPA bit */
274 CLEAR_BIT(FIREWALL->CR, FW_CR_FPA);
275 }
276
277 /**
278 * @}
279 */
280
281 /**
282 * @}
283 */
284
285 #endif /* HAL_FIREWALL_MODULE_ENABLED */
286 /**
287 * @}
288 */
289
290 /**
291 * @}
292 */
293