stm32l4xx_hal_firewall.c 11 KB

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