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>&copy; 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