STM32L443xx HAL User Manual
stm32l4xx_hal_firewall.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_firewall.c
00004   * @author  MCD Application Team
00005   * @brief   FIREWALL HAL module driver.
00006   *          This file provides firmware functions to manage the Firewall
00007   *          Peripheral initialization and enabling.
00008   *
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * Copyright (c) 2017 STMicroelectronics.
00013   * All rights reserved.
00014   *
00015   * This software is licensed under terms that can be found in the LICENSE file
00016   * in the root directory of this software component.
00017   * If no LICENSE file comes with this software, it is provided AS-IS.
00018   *
00019   ******************************************************************************
00020   @verbatim
00021  ===============================================================================
00022                         ##### How to use this driver #####
00023  ===============================================================================
00024   [..]
00025     The FIREWALL HAL driver can be used as follows:
00026 
00027     (#) Declare a FIREWALL_InitTypeDef initialization structure.
00028 
00029     (#) Resort to HAL_FIREWALL_Config() API to initialize the Firewall
00030 
00031     (#) Enable the FIREWALL in calling HAL_FIREWALL_EnableFirewall() API
00032 
00033     (#) To ensure that any code executed outside the protected segment closes the
00034         FIREWALL, the user must set the flag FIREWALL_PRE_ARM_SET in calling
00035         __HAL_FIREWALL_PREARM_ENABLE() macro if called within a protected code segment
00036         or
00037         HAL_FIREWALL_EnablePreArmFlag() API if called outside of protected code segment
00038         after HAL_FIREWALL_Config() call.
00039 
00040 
00041   @endverbatim
00042   ******************************************************************************
00043   */
00044 
00045 /* Includes ------------------------------------------------------------------*/
00046 #include "stm32l4xx_hal.h"
00047 
00048 /** @addtogroup STM32L4xx_HAL_Driver
00049   * @{
00050   */
00051 
00052 /** @defgroup FIREWALL FIREWALL
00053   * @brief HAL FIREWALL module driver
00054   * @{
00055   */
00056 #ifdef HAL_FIREWALL_MODULE_ENABLED
00057 
00058 /* Private typedef -----------------------------------------------------------*/
00059 /* Private define ------------------------------------------------------------*/
00060 /* Private macro -------------------------------------------------------------*/
00061 /* Private variables ---------------------------------------------------------*/
00062 /* Private function prototypes -----------------------------------------------*/
00063 /* Private functions ---------------------------------------------------------*/
00064 
00065 
00066 /** @defgroup FIREWALL_Exported_Functions FIREWALL Exported Functions
00067   * @{
00068   */
00069 
00070 /** @defgroup FIREWALL_Exported_Functions_Group1 Initialization Functions
00071   * @brief    Initialization and Configuration Functions
00072   *
00073 @verbatim
00074 ===============================================================================
00075             ##### Initialization and Configuration functions #####
00076  ===============================================================================
00077     [..]
00078     This subsection provides the functions allowing to initialize the Firewall.
00079     Initialization is done by HAL_FIREWALL_Config():
00080 
00081       (+) Enable the Firewall clock thru __HAL_RCC_FIREWALL_CLK_ENABLE() macro.
00082 
00083       (+) Set the protected code segment address start and length.
00084 
00085       (+) Set the protected non-volatile and/or volatile data segments
00086           address starts and lengths if applicable.
00087 
00088       (+) Set the volatile data segment execution and sharing status.
00089 
00090       (+) Length must be set to 0 for an unprotected segment.
00091 
00092 @endverbatim
00093   * @{
00094   */
00095 
00096 /**
00097   * @brief Initialize the Firewall according to the FIREWALL_InitTypeDef structure parameters.
00098   * @param fw_init: Firewall initialization structure
00099   * @note  The API returns HAL_ERROR if the Firewall is already enabled.
00100   * @retval HAL status
00101   */
00102 HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)
00103 {
00104   /* Check the Firewall initialization structure allocation */
00105   if(fw_init == NULL)
00106   {
00107     return HAL_ERROR;
00108   }
00109 
00110   /* Enable Firewall clock */
00111   __HAL_RCC_FIREWALL_CLK_ENABLE();
00112 
00113   /* Make sure that Firewall is not enabled already */
00114   if (__HAL_FIREWALL_IS_ENABLED() != RESET)
00115   {
00116     return HAL_ERROR;
00117   }
00118 
00119   /* Check Firewall configuration addresses and lengths when segment is protected */
00120   /* Code segment */
00121   if (fw_init->CodeSegmentLength != 0U)
00122   {
00123     assert_param(IS_FIREWALL_CODE_SEGMENT_ADDRESS(fw_init->CodeSegmentStartAddress));
00124     assert_param(IS_FIREWALL_CODE_SEGMENT_LENGTH(fw_init->CodeSegmentStartAddress, fw_init->CodeSegmentLength));
00125     /* Make sure that NonVDataSegmentLength is properly set to prevent code segment access */
00126     if (fw_init->NonVDataSegmentLength < 0x100U)
00127     {
00128       return HAL_ERROR;
00129     }
00130   }
00131   /* Non volatile data segment */
00132   if (fw_init->NonVDataSegmentLength != 0U)
00133   {
00134     assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_ADDRESS(fw_init->NonVDataSegmentStartAddress));
00135     assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_LENGTH(fw_init->NonVDataSegmentStartAddress, fw_init->NonVDataSegmentLength));
00136   }
00137   /* Volatile data segment */
00138   if (fw_init->VDataSegmentLength != 0U)
00139   {
00140     assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_ADDRESS(fw_init->VDataSegmentStartAddress));
00141     assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_LENGTH(fw_init->VDataSegmentStartAddress, fw_init->VDataSegmentLength));
00142   }
00143 
00144   /* Check Firewall Configuration Register parameters */
00145   assert_param(IS_FIREWALL_VOLATILEDATA_EXECUTE(fw_init->VolatileDataExecution));
00146   assert_param(IS_FIREWALL_VOLATILEDATA_SHARE(fw_init->VolatileDataShared));
00147 
00148 
00149    /* Configuration */
00150 
00151   /* Protected code segment start address configuration */
00152   WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress));
00153         /* Protected code segment length configuration */
00154   WRITE_REG(FIREWALL->CSL, (FW_CSL_LENG & fw_init->CodeSegmentLength));
00155 
00156   /* Protected non volatile data segment start address configuration */
00157   WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress));
00158         /* Protected non volatile data segment length configuration */
00159   WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength));
00160 
00161   /* Protected volatile data segment start address configuration */
00162   WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress));
00163         /* Protected volatile data segment length configuration */
00164   WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength));
00165 
00166   /* Set Firewall Configuration Register VDE and VDS bits
00167      (volatile data execution and shared configuration) */
00168   MODIFY_REG(FIREWALL->CR, FW_CR_VDS|FW_CR_VDE, fw_init->VolatileDataExecution|fw_init->VolatileDataShared);
00169 
00170   return HAL_OK;
00171 }
00172 
00173 /**
00174   * @brief Retrieve the Firewall configuration.
00175   * @param fw_config: Firewall configuration, type is same as initialization structure
00176   * @note This API can't be executed inside a code area protected by the Firewall
00177   *       when the Firewall is enabled
00178   * @note If NVDSL register is different from 0, that is, if the non volatile data segment
00179   *       is defined, this API can't be executed when the Firewall is enabled.
00180   * @note User should resort to __HAL_FIREWALL_GET_PREARM() macro to retrieve FPA bit status
00181   * @retval None
00182   */
00183 void HAL_FIREWALL_GetConfig(FIREWALL_InitTypeDef * fw_config)
00184 {
00185 
00186   /* Enable Firewall clock, in case no Firewall configuration has been carried
00187      out up to this point */
00188   __HAL_RCC_FIREWALL_CLK_ENABLE();
00189 
00190   /* Retrieve code segment protection setting */
00191   fw_config->CodeSegmentStartAddress = (READ_REG(FIREWALL->CSSA) & FW_CSSA_ADD);
00192   fw_config->CodeSegmentLength = (READ_REG(FIREWALL->CSL) & FW_CSL_LENG);
00193 
00194   /* Retrieve non volatile data segment protection setting */
00195   fw_config->NonVDataSegmentStartAddress = (READ_REG(FIREWALL->NVDSSA) & FW_NVDSSA_ADD);
00196   fw_config->NonVDataSegmentLength = (READ_REG(FIREWALL->NVDSL) & FW_NVDSL_LENG);
00197 
00198   /* Retrieve volatile data segment protection setting */
00199   fw_config->VDataSegmentStartAddress = (READ_REG(FIREWALL->VDSSA) & FW_VDSSA_ADD);
00200   fw_config->VDataSegmentLength = (READ_REG(FIREWALL->VDSL) & FW_VDSL_LENG);
00201 
00202   /* Retrieve volatile data execution setting */
00203   fw_config->VolatileDataExecution = (READ_REG(FIREWALL->CR) & FW_CR_VDE);
00204 
00205   /* Retrieve volatile data shared setting */
00206   fw_config->VolatileDataShared = (READ_REG(FIREWALL->CR) & FW_CR_VDS);
00207 
00208   return;
00209 }
00210 
00211 
00212 
00213 /**
00214   * @brief Enable FIREWALL.
00215   * @note Firewall is enabled in clearing FWDIS bit of SYSCFG CFGR1 register.
00216   *       Once enabled, the Firewall cannot be disabled by software. Only a
00217   *       system reset can set again FWDIS bit.
00218   * @retval None
00219   */
00220 void HAL_FIREWALL_EnableFirewall(void)
00221 {
00222   /* Clears FWDIS bit of SYSCFG CFGR1 register */
00223   CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_FWDIS);
00224 
00225 }
00226 
00227 /**
00228   * @brief Enable FIREWALL pre arm.
00229   * @note When FPA bit is set, any code executed outside the protected segment
00230   *       will close the Firewall.
00231   * @note This API provides the same service as __HAL_FIREWALL_PREARM_ENABLE() macro
00232   *       but can't be executed inside a code area protected by the Firewall.
00233   * @note When the Firewall is disabled, user can resort to HAL_FIREWALL_EnablePreArmFlag() API any time.
00234   * @note When the Firewall is enabled and NVDSL register is equal to 0 (that is,
00235   *       when the non volatile data segment is not defined),
00236   *        **  this API can be executed when the Firewall is closed
00237   *        **  when the Firewall is opened, user should resort to
00238   *            __HAL_FIREWALL_PREARM_ENABLE() macro instead
00239   * @note When the Firewall is enabled and  NVDSL register is different from 0
00240   *       (that is, when the non volatile data segment is defined)
00241   *       **  FW_CR register can be accessed only when the Firewall is opened:
00242   *           user should resort to  __HAL_FIREWALL_PREARM_ENABLE() macro instead.
00243   * @retval None
00244   */
00245 void HAL_FIREWALL_EnablePreArmFlag(void)
00246 {
00247   /* Set FPA bit */
00248   SET_BIT(FIREWALL->CR, FW_CR_FPA);
00249 }
00250 
00251 
00252 /**
00253   * @brief Disable FIREWALL pre arm.
00254   * @note When FPA bit is reset, any code executed outside the protected segment
00255   *       when the Firewall is opened will generate a system reset.
00256   * @note This API provides the same service as __HAL_FIREWALL_PREARM_DISABLE() macro
00257   *       but can't be executed inside a code area protected by the Firewall.
00258   * @note When the Firewall is disabled, user can resort to HAL_FIREWALL_EnablePreArmFlag() API any time.
00259   * @note When the Firewall is enabled and NVDSL register is equal to 0 (that is,
00260   *       when the non volatile data segment is not defined),
00261   *        **  this API can be executed when the Firewall is closed
00262   *        **  when the Firewall is opened, user should resort to
00263   *            __HAL_FIREWALL_PREARM_DISABLE() macro instead
00264   * @note When the Firewall is enabled and  NVDSL register is different from 0
00265   *       (that is, when the non volatile data segment is defined)
00266   *       **  FW_CR register can be accessed only when the Firewall is opened:
00267   *           user should resort to  __HAL_FIREWALL_PREARM_DISABLE() macro instead.
00268 
00269   * @retval None
00270   */
00271 void HAL_FIREWALL_DisablePreArmFlag(void)
00272 {
00273   /* Clear FPA bit */
00274   CLEAR_BIT(FIREWALL->CR, FW_CR_FPA);
00275 }
00276 
00277 /**
00278   * @}
00279   */
00280 
00281 /**
00282   * @}
00283   */
00284 
00285 #endif /* HAL_FIREWALL_MODULE_ENABLED */
00286 /**
00287   * @}
00288   */
00289 
00290 /**
00291   * @}
00292   */