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