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