1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_hal_gtzc.c
4   * @author  MCD Application Team
5   * @brief   GTZC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of GTZC peripheral:
8   *           + TZSC Initialization and Configuration functions
9   *           + MPCBB Initialization and Configuration functions
10   *           + TZSC and MPCBB Lock functions
11   *           + TZIC Initialization and Configuration functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2022 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                 ##### GTZC main features #####
27   ==============================================================================
28   [..]
29     (+) Global TrustZone Controller (GTZC) composed of three sub-blocks:
30       (++) TZSC: TrustZone security controller
31             This sub-block defines the secure/privileged state of master and slave
32             peripherals.
33       (++) MPCBB: Block-Based memory protection controller
34             This sub-block defines the secure/privileged state of all blocks
35             (512-byte pages) of the associated SRAM.
36       (++) TZIC: TrustZone illegal access controller
37             This sub-block gathers all illegal access events in the system and
38             generates a secure interrupt towards NVIC.
39 
40     (+) These sub-blocks are used to configure TrustZone system security in
41         a product having bus agents with programmable-security and privileged
42         attributes (securable) such as:
43       (++) on-chip RAM with programmable secure and/or privilege blocks (pages)
44       (++) AHB and APB peripherals with programmable security and/or privilege access
45       (++) AHB master granted as secure and/or privilege
46       (++) off-chip memories with secure and/or privilege areas
47 
48   [..]
49     (+) TZIC accessible only with secure privileged transactions.
50     (+) Secure and non-secure access supported for privileged and unprivileged
51         part of TZSC and MPCBB
52     (+) Set of registers to define product security settings:
53       (++) Secure and privilege blocks for internal memories
54       (++) Secure and privilege regions for external memories
55       (++) Secure and privileged access mode for securable peripherals
56 
57   ==============================================================================
58                          ##### How to use this driver #####
59   ==============================================================================
60   [..]
61     The GTZC HAL driver can be used as follows:
62 
63     (#) Configure or get back securable peripherals attributes using
64         HAL_GTZC_TZSC_ConfigPeriphAttributes() / HAL_GTZC_TZSC_GetConfigPeriphAttributes()
65 
66     (#) Lock TZSC sub-block or get lock status using HAL_GTZC_TZSC_Lock() /
67         HAL_GTZC_TZSC_GetLock()
68 
69     (#) Configure or get back MPCBB memories complete configuration using
70         HAL_GTZC_MPCBB_ConfigMem() / HAL_GTZC_MPCBB_GetConfigMem()
71 
72     (#) Configure or get back MPCBB memories attributes using
73         HAL_GTZC_MPCBB_ConfigMemAttributes() / HAL_GTZC_MPCBB_GetConfigMemAttributes()
74 
75     (#) Lock MPCBB configuration or get lock status using HAL_GTZC_MPCBB_Lock() /
76         HAL_GTZC_MPCBB_GetLock()
77 
78     (#) Lock MPCBB super-blocks or get lock status using HAL_GTZC_MPCBB_LockConfig() /
79         HAL_GTZC_MPCBB_GetLockConfig()
80 
81     (#) Illegal access detection can be configured through TZIC sub-block using
82         following functions: HAL_GTZC_TZIC_DisableIT() / HAL_GTZC_TZIC_EnableIT()
83 
84     (#) Illegal access flags can be retrieved through HAL_GTZC_TZIC_GetFlag() and
85         HAL_GTZC_TZIC_ClearFlag() functions
86 
87     (#) Illegal access interrupt service routines are served by HAL_GTZC_IRQHandler()
88         and user can add his own code using HAL_GTZC_TZIC_Callback()
89 
90   @endverbatim
91   */
92 
93 /* Includes ------------------------------------------------------------------*/
94 #include "stm32wbaxx_hal.h"
95 
96 /** @addtogroup STM32WBAxx_HAL_Driver
97   * @{
98   */
99 
100 #if defined(GTZC_TZSC) && defined(HAL_GTZC_MODULE_ENABLED)
101 
102 /** @defgroup GTZC GTZC
103   * @brief GTZC HAL module driver
104   * @{
105   */
106 
107 /* Private typedef -----------------------------------------------------------*/
108 /* Private constants ---------------------------------------------------------*/
109 
110 /** @defgroup GTZC_Private_Constants GTZC Private Constants
111   * @{
112   */
113 
114 /* Definitions for GTZC TZSC & TZIC ALL register values */
115 /* TZSC1 / TZIC1 instances */
116 #define TZSC1_SECCFGR1_ALL       (0x000222C3UL)
117 #if defined (STM32WBA54xx) || defined (STM32WBA55xx)
118 #define TZSC1_SECCFGR2_ALL       (0x018F00EBUL)
119 #define TZSC1_SECCFGR3_ALL       (0x01C17858UL)
120 #else
121 #define TZSC1_SECCFGR2_ALL       (0x010F006BUL)
122 #define TZSC1_SECCFGR3_ALL       (0x00C17858UL)
123 #endif /* STM32WBA54xx || STM32WBA55xx */
124 
125 #define TZSC1_PRIVCFGR1_ALL      (0x000222C3UL)
126 #if defined (STM32WBA54xx) || defined (STM32WBA55xx)
127 #define TZSC1_PRIVCFGR2_ALL      (0x018F00EBUL)
128 #define TZSC1_PRIVCFGR3_ALL      (0x01C17858UL)
129 #else
130 #define TZSC1_PRIVCFGR2_ALL      (0x010F006BUL)
131 #define TZSC1_PRIVCFGR3_ALL      (0x00C17858UL)
132 #endif /* STM32WBA54xx || STM32WBA55xx */
133 
134 #define TZIC1_IER1_ALL           (0x000222C3UL)
135 #if defined (STM32WBA54xx) || defined (STM32WBA55xx)
136 #define TZIC1_IER2_ALL           (0x018F00EBUL)
137 #define TZIC1_IER3_ALL           (0x01C1F858UL)
138 #else
139 #define TZIC1_IER2_ALL           (0x010F006BUL)
140 #define TZIC1_IER3_ALL           (0x00C1F858UL)
141 #endif /* STM32WBA54xx || STM32WBA55xx */
142 #define TZIC1_IER4_ALL           (0xC3C0EF87UL)
143 
144 #define TZIC1_FCR1_ALL           (0x000222C3UL)
145 #if defined (STM32WBA54xx) || defined (STM32WBA55xx)
146 #define TZIC1_FCR2_ALL           (0x018F00EBUL)
147 #define TZIC1_FCR3_ALL           (0x01C1F858UL)
148 #else
149 #define TZIC1_FCR2_ALL           (0x010F006BUL)
150 #define TZIC1_FCR3_ALL           (0x00C1F858UL)
151 #endif /* STM32WBA54xx || STM32WBA55xx */
152 #define TZIC1_FCR4_ALL           (0xC3C0EF87UL)
153 
154 /**
155   * @}
156   */
157 
158 /* Private macros ------------------------------------------------------------*/
159 
160 /** @defgroup GTZC_Private_Macros GTZC Private Macros
161   * @{
162   */
163 
164 #define IS_ADDRESS_IN(mem, address)\
165   (   (   ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_NS(mem) )                                \
166           && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_NS(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) )  \
167       || (   ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_S(mem) )                                \
168              && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_S(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) ) )
169 
170 #define IS_ADDRESS_IN_S(mem, address)\
171   (   ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_S(mem) )                                \
172       && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_S(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) )
173 
174 #define IS_ADDRESS_IN_NS(mem, address)\
175   (   ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_NS(mem) )                                \
176       && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_NS(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) )
177 
178 /* MISRA C:2012 Rule-20.10 deviation granted to use the definition of GTZC_BASE_ADDRESS() */
179 #define GTZC_BASE_ADDRESS(mem)\
180   ( mem ## _BASE )
181 
182 /**
183   * @}
184   */
185 
186 /* Private variables ---------------------------------------------------------*/
187 /* Private function prototypes -----------------------------------------------*/
188 /* Exported functions --------------------------------------------------------*/
189 
190 /** @defgroup GTZC_Exported_Functions GTZC Exported Functions
191   * @{
192   */
193 
194 /** @defgroup GTZC_Exported_Functions_Group1  TZSC Configuration functions
195   * @brief    TZSC Configuration functions
196   *
197   @verbatim
198   ==============================================================================
199             ##### TZSC Configuration functions #####
200   ==============================================================================
201   [..]
202     This section provides functions allowing to configure TZSC
203     TZSC: TrustZone Security Controller
204 @endverbatim
205   * @{
206   */
207 
208 /**
209   * @brief  Configure TZSC on a single peripheral or on all peripherals.
210   * @note   Secure and non-secure attributes can only be set from the secure
211   *         state when the system implements the security (TZEN=1).
212   * @note   Privilege and non-privilege attributes can only be set from the
213   *         privilege state when TZEN=0 or TZEN=1
214   * @note   Security and privilege attributes can be set independently.
215   * @note   Default state is non-secure and unprivileged access allowed.
216   * @param  PeriphId Peripheral identifier
217   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId.
218   *         Use GTZC_PERIPH_ALL to select all peripherals.
219   * @param  PeriphAttributes Peripheral attributes, see @ref GTZC_TZSC_PeriphAttributes.
220   * @retval HAL status.
221   */
HAL_GTZC_TZSC_ConfigPeriphAttributes(uint32_t PeriphId,uint32_t PeriphAttributes)222 HAL_StatusTypeDef HAL_GTZC_TZSC_ConfigPeriphAttributes(uint32_t PeriphId,
223                                                        uint32_t PeriphAttributes)
224 {
225   uint32_t register_address;
226 
227   /* check entry parameters */
228   if ((PeriphAttributes > (GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV))
229       || (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZSC_PERIPH_NUMBER)
230       || (((PeriphId & GTZC_PERIPH_ALL) != 0U)
231           && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U)))
232   {
233     return HAL_ERROR;
234   }
235 
236   if ((PeriphId & GTZC_PERIPH_ALL) != 0U)
237   {
238     /* special case where same attributes are applied to all peripherals */
239 
240 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
241     /* secure configuration */
242     if ((PeriphAttributes & GTZC_TZSC_PERIPH_SEC) == GTZC_TZSC_PERIPH_SEC)
243     {
244       SET_BIT(GTZC_TZSC->SECCFGR1, TZSC1_SECCFGR1_ALL);
245       SET_BIT(GTZC_TZSC->SECCFGR2, TZSC1_SECCFGR2_ALL);
246       SET_BIT(GTZC_TZSC->SECCFGR3, TZSC1_SECCFGR3_ALL);
247     }
248     else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NSEC) == GTZC_TZSC_PERIPH_NSEC)
249     {
250       CLEAR_BIT(GTZC_TZSC->SECCFGR1, TZSC1_SECCFGR1_ALL);
251       CLEAR_BIT(GTZC_TZSC->SECCFGR2, TZSC1_SECCFGR2_ALL);
252       CLEAR_BIT(GTZC_TZSC->SECCFGR3, TZSC1_SECCFGR3_ALL);
253     }
254     else
255     {
256       /* do nothing */
257     }
258 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
259 
260     /* privilege configuration */
261     if ((PeriphAttributes & GTZC_TZSC_PERIPH_PRIV) == GTZC_TZSC_PERIPH_PRIV)
262     {
263       SET_BIT(GTZC_TZSC->PRIVCFGR1, TZSC1_PRIVCFGR1_ALL);
264       SET_BIT(GTZC_TZSC->PRIVCFGR2, TZSC1_PRIVCFGR2_ALL);
265       SET_BIT(GTZC_TZSC->PRIVCFGR3, TZSC1_PRIVCFGR3_ALL);
266     }
267     else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NPRIV) == GTZC_TZSC_PERIPH_NPRIV)
268     {
269       CLEAR_BIT(GTZC_TZSC->PRIVCFGR1, TZSC1_PRIVCFGR1_ALL);
270       CLEAR_BIT(GTZC_TZSC->PRIVCFGR2, TZSC1_PRIVCFGR2_ALL);
271       CLEAR_BIT(GTZC_TZSC->PRIVCFGR3, TZSC1_PRIVCFGR3_ALL);
272     }
273     else
274     {
275       /* do nothing */
276     }
277   }
278   else
279   {
280     /* common case where only one peripheral is configured */
281 
282 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
283     /* secure configuration */
284     register_address = (uint32_t) &(GTZC_TZSC->SECCFGR1)
285                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
286     if ((PeriphAttributes & GTZC_TZSC_PERIPH_SEC) == GTZC_TZSC_PERIPH_SEC)
287     {
288       SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
289     }
290     else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NSEC) == GTZC_TZSC_PERIPH_NSEC)
291     {
292       CLEAR_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
293     }
294     else
295     {
296       /* do nothing */
297     }
298 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
299 
300     /* privilege configuration */
301     register_address = (uint32_t) &(GTZC_TZSC->PRIVCFGR1)
302                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
303     if ((PeriphAttributes & GTZC_TZSC_PERIPH_PRIV) == GTZC_TZSC_PERIPH_PRIV)
304     {
305       SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
306     }
307     else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NPRIV) == GTZC_TZSC_PERIPH_NPRIV)
308     {
309       CLEAR_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
310     }
311     else
312     {
313       /* do nothing */
314     }
315   }
316   return HAL_OK;
317 }
318 
319 /**
320   * @brief  Get TZSC configuration on a single peripheral or on all peripherals.
321   * @param  PeriphId Peripheral identifier.
322   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId.
323   *         Use GTZC_PERIPH_ALL to select all peripherals.
324   * @param  PeriphAttributes Peripheral attribute pointer.
325   *         This parameter can be a value of @ref GTZC_TZSC_PeriphAttributes.
326   *         If PeriphId target a single peripheral, pointer on a single element.
327   *         If all peripherals selected (GTZC_PERIPH_ALL), pointer to an array of
328   *         GTZC_TZSC_PERIPH_NUMBER elements is to be provided.
329   * @retval HAL status.
330   */
HAL_GTZC_TZSC_GetConfigPeriphAttributes(uint32_t PeriphId,uint32_t * PeriphAttributes)331 HAL_StatusTypeDef HAL_GTZC_TZSC_GetConfigPeriphAttributes(uint32_t PeriphId,
332                                                           uint32_t *PeriphAttributes)
333 {
334   uint32_t i;
335   uint32_t reg_value;
336   uint32_t register_address;
337 
338   /* check entry parameters */
339   if ((PeriphAttributes == NULL)
340       || (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZSC_PERIPH_NUMBER)
341       || (((PeriphId & GTZC_PERIPH_ALL) != 0U)
342           && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U)))
343   {
344     return HAL_ERROR;
345   }
346 
347   if ((PeriphId & GTZC_PERIPH_ALL) != 0U)
348   {
349     /* get secure configuration: read each register and deploy each bit value
350      * of corresponding index in the destination array
351      */
352     reg_value = READ_REG(GTZC_TZSC->SECCFGR1);
353     for (i = 0U; i < 32U; i++)
354     {
355       if (((reg_value & (1UL << i)) >> i) != 0U)
356       {
357         PeriphAttributes[i] = GTZC_TZSC_PERIPH_SEC;
358       }
359       else
360       {
361         PeriphAttributes[i] = GTZC_TZSC_PERIPH_NSEC;
362       }
363     }
364 
365     reg_value = READ_REG(GTZC_TZSC->SECCFGR2);
366     for (i = 32U; i < 64U; i++)
367     {
368       if (((reg_value & (1UL << (i - 32U))) >> (i - 32U)) != 0U)
369       {
370         PeriphAttributes[i] = GTZC_TZSC_PERIPH_SEC;
371       }
372       else
373       {
374         PeriphAttributes[i] = GTZC_TZSC_PERIPH_NSEC;
375       }
376     }
377 
378     reg_value = READ_REG(GTZC_TZSC->SECCFGR3);
379     for (i = 64U; i < GTZC_TZSC_PERIPH_NUMBER; i++)
380     {
381       if (((reg_value & (1UL << (i - 64U))) >> (i - 64U)) != 0U)
382       {
383         PeriphAttributes[i] = GTZC_TZSC_PERIPH_SEC;
384       }
385       else
386       {
387         PeriphAttributes[i] = GTZC_TZSC_PERIPH_NSEC;
388       }
389     }
390 
391     /* get privilege configuration: read each register and deploy each bit value
392      * of corresponding index in the destination array
393      */
394     reg_value = READ_REG(GTZC_TZSC->PRIVCFGR1);
395     for (i = 0U; i < 32U; i++)
396     {
397       if (((reg_value & (1UL << i)) >> i) != 0U)
398       {
399         PeriphAttributes[i] |= GTZC_TZSC_PERIPH_PRIV;
400       }
401       else
402       {
403         PeriphAttributes[i] |= GTZC_TZSC_PERIPH_NPRIV;
404       }
405     }
406 
407     reg_value = READ_REG(GTZC_TZSC->PRIVCFGR2);
408     for (i = 32U; i < 64U; i++)
409     {
410       if (((reg_value & (1UL << (i - 32U))) >> (i - 32U)) != 0U)
411       {
412         PeriphAttributes[i] |= GTZC_TZSC_PERIPH_PRIV;
413       }
414       else
415       {
416         PeriphAttributes[i] |= GTZC_TZSC_PERIPH_NPRIV;
417       }
418     }
419 
420     reg_value = READ_REG(GTZC_TZSC->PRIVCFGR3);
421     for (i = 64U; i < GTZC_TZSC_PERIPH_NUMBER; i++)
422     {
423       if (((reg_value & (1UL << (i - 64U))) >> (i - 64U)) != 0U)
424       {
425         PeriphAttributes[i] |= GTZC_TZSC_PERIPH_PRIV;
426       }
427       else
428       {
429         PeriphAttributes[i] |= GTZC_TZSC_PERIPH_NPRIV;
430       }
431     }
432 
433   }
434   else
435   {
436     /* common case where only one peripheral is configured */
437 
438     /* secure configuration */
439     register_address = (uint32_t) &(GTZC_TZSC->SECCFGR1)
440                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
441 
442     if (((READ_BIT(*(__IO uint32_t *)register_address,
443                    1UL << GTZC_GET_PERIPH_POS(PeriphId))) >> GTZC_GET_PERIPH_POS(PeriphId))
444         != 0U)
445     {
446       *PeriphAttributes = GTZC_TZSC_PERIPH_SEC;
447     }
448     else
449     {
450       *PeriphAttributes = GTZC_TZSC_PERIPH_NSEC;
451     }
452 
453     /* privilege configuration */
454     register_address = (uint32_t) &(GTZC_TZSC->PRIVCFGR1)
455                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
456     if (((READ_BIT(*(__IO uint32_t *)register_address,
457                    1UL << GTZC_GET_PERIPH_POS(PeriphId))) >> GTZC_GET_PERIPH_POS(PeriphId))
458         != 0U)
459     {
460       *PeriphAttributes |= GTZC_TZSC_PERIPH_PRIV;
461     }
462     else
463     {
464       *PeriphAttributes |= GTZC_TZSC_PERIPH_NPRIV;
465     }
466   }
467   return HAL_OK;
468 }
469 
470 /**
471   * @}
472   */
473 
474 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
475 
476 /** @defgroup GTZC_Exported_Functions_Group3 TZSC Lock functions
477   * @brief    TZSC Lock functions
478   *
479   @verbatim
480   ==============================================================================
481                    ##### TZSC Lock functions #####
482   ==============================================================================
483   [..]
484     This section provides functions allowing to manage the TZSC (TrustZone
485     Security Controller) lock. It includes lock enable, and current value read.
486 @endverbatim
487   * @{
488   */
489 
490 /**
491   * @brief  Lock TZSC configuration.
492   * @note   This function locks the configuration of TZSC_SECCFGRx and TZSC_PRIVCFGRx
493   *         registers until next reset
494   * @param  TZSC_Instance TZSC sub-block instance.
495   */
HAL_GTZC_TZSC_Lock(GTZC_TZSC_TypeDef * TZSC_Instance)496 void HAL_GTZC_TZSC_Lock(GTZC_TZSC_TypeDef *TZSC_Instance)
497 {
498   SET_BIT(TZSC_Instance->CR, GTZC_TZSC_CR_LCK_Msk);
499 }
500 
501 /**
502   * @brief  Get TZSC configuration lock state.
503   * @param  TZSC_Instance TZSC sub-block instance.
504   * @retval Lock State (GTZC_TZSC_LOCK_OFF or GTZC_TZSC_LOCK_ON)
505   */
HAL_GTZC_TZSC_GetLock(const GTZC_TZSC_TypeDef * TZSC_Instance)506 uint32_t HAL_GTZC_TZSC_GetLock(const GTZC_TZSC_TypeDef *TZSC_Instance)
507 {
508   return READ_BIT(TZSC_Instance->CR, GTZC_TZSC_CR_LCK_Msk);
509 }
510 
511 /**
512   * @}
513   */
514 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
515 
516 /** @defgroup GTZC_Exported_Functions_Group4 MPCBB Configuration functions
517   * @brief    MPCBB Configuration functions
518   *
519   @verbatim
520   ==============================================================================
521             ##### MPCBB Configuration functions #####
522   ==============================================================================
523   [..]
524     This section provides functions allowing to configure MPCBB
525     MPCBB is  Memory Protection Controller Block Base
526 @endverbatim
527   * @{
528   */
529 
530 /**
531   * @brief  Set a complete MPCBB configuration on the SRAM passed as parameter.
532   * @param  MemBaseAddress MPCBB identifier.
533   * @param  pMPCBB_desc pointer to MPCBB descriptor.
534   *         The structure description is available in @ref GTZC_Exported_Types.
535   * @retval HAL status.
536   */
HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress,const MPCBB_ConfigTypeDef * pMPCBB_desc)537 HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress,
538                                            const MPCBB_ConfigTypeDef *pMPCBB_desc)
539 {
540   GTZC_MPCBB_TypeDef *mpcbb_ptr;
541   uint32_t reg_value;
542   uint32_t mem_size;
543   uint32_t size_in_superblocks;
544   uint32_t i;
545 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
546   uint32_t size_mask;
547 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
548 
549   /* check entry parameters */
550   if ((!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
551        &&  !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
552        && !(IS_GTZC_BASE_ADDRESS(SRAM6, MemBaseAddress)))
553       || ((pMPCBB_desc->SecureRWIllegalMode
554            != GTZC_MPCBB_SRWILADIS_ENABLE)
555           && (pMPCBB_desc->SecureRWIllegalMode
556               != GTZC_MPCBB_SRWILADIS_DISABLE))
557       || ((pMPCBB_desc->InvertSecureState
558            != GTZC_MPCBB_INVSECSTATE_NOT_INVERTED)
559           && (pMPCBB_desc->InvertSecureState
560               != GTZC_MPCBB_INVSECSTATE_INVERTED)))
561   {
562     return HAL_ERROR;
563   }
564 
565   /* write InvertSecureState and SecureRWIllegalMode properties */
566   /* assume their Position/Mask is identical for all sub-blocks */
567   reg_value = pMPCBB_desc->InvertSecureState;
568   reg_value |= pMPCBB_desc->SecureRWIllegalMode;
569   if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
570   {
571     mpcbb_ptr = GTZC_MPCBB1;
572     mem_size = GTZC_MEM_SIZE(SRAM1);
573   }
574   else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
575   {
576     mpcbb_ptr = GTZC_MPCBB2;
577     mem_size = GTZC_MEM_SIZE(SRAM2);
578   }
579   else
580   {
581     /* Here MemBaseAddress is inside SRAM6 (parameter already checked) */
582     mpcbb_ptr = GTZC_MPCBB6;
583     mem_size = GTZC_MEM_SIZE(SRAM6);
584   }
585 
586   /* translate mem_size in number of super-blocks  */
587   size_in_superblocks = (mem_size / GTZC_MPCBB_SUPERBLOCK_SIZE);
588 
589   /* write PRIVCFGR register information */
590   for (i = 0U; i < size_in_superblocks; i++)
591   {
592     WRITE_REG(mpcbb_ptr->PRIVCFGR[i],
593               pMPCBB_desc->AttributeConfig.MPCBB_PrivConfig_array[i]);
594   }
595 
596 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
597   /* write SECCFGR register information */
598   for (i = 0U; i < size_in_superblocks; i++)
599   {
600     WRITE_REG(mpcbb_ptr->SECCFGR[i],
601               pMPCBB_desc->AttributeConfig.MPCBB_SecConfig_array[i]);
602   }
603 
604   /* write configuration and lock register information */
605   MODIFY_REG(mpcbb_ptr->CR,
606              GTZC_MPCBB_CR_INVSECSTATE_Msk | GTZC_MPCBB_CR_SRWILADIS_Msk, reg_value);
607   size_mask = (1UL << size_in_superblocks) - 1U;
608   /* limitation: code not portable with memory > 512K */
609   MODIFY_REG(mpcbb_ptr->CFGLOCK, size_mask, pMPCBB_desc->AttributeConfig.MPCBB_LockConfig_array[0]);
610 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
611 
612   return HAL_OK;
613 }
614 
615 /**
616   * @brief  Get a complete MPCBB configuration on the SRAM passed as parameter.
617   * @param  MemBaseAddress MPCBB identifier.
618   * @param  pMPCBB_desc pointer to a MPCBB descriptor.
619   *         The structure description is available in @ref GTZC_Exported_Types.
620   * @retval HAL status.
621   */
HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress,MPCBB_ConfigTypeDef * pMPCBB_desc)622 HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress,
623                                               MPCBB_ConfigTypeDef *pMPCBB_desc)
624 {
625   GTZC_MPCBB_TypeDef *mpcbb_ptr;
626   uint32_t mem_size;
627   uint32_t size_in_superblocks;
628   uint32_t i;
629 
630   /* check entry parameters */
631   if (!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
632       && !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
633       && !(IS_GTZC_BASE_ADDRESS(SRAM6, MemBaseAddress)))
634   {
635     return HAL_ERROR;
636   }
637 
638   /* read InvertSecureState and SecureRWIllegalMode properties */
639   /* assume their Position/Mask is identical for all sub-blocks */
640   if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
641   {
642     mpcbb_ptr = GTZC_MPCBB1;
643     mem_size = GTZC_MEM_SIZE(SRAM1);
644   }
645   else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
646   {
647     mpcbb_ptr = GTZC_MPCBB2;
648     mem_size = GTZC_MEM_SIZE(SRAM2);
649   }
650   else
651   {
652     mpcbb_ptr = GTZC_MPCBB6;
653     mem_size = GTZC_MEM_SIZE(SRAM6);
654   }
655 
656   /* translate mem_size in number of super-blocks  */
657   size_in_superblocks = (mem_size / GTZC_MPCBB_SUPERBLOCK_SIZE);
658 
659 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
660   uint32_t reg_value;
661   uint32_t size_mask;
662 
663   /* read configuration and lock register information */
664   reg_value = READ_REG(mpcbb_ptr->CR);
665   pMPCBB_desc->InvertSecureState = (reg_value & GTZC_MPCBB_CR_INVSECSTATE_Msk);
666   pMPCBB_desc->SecureRWIllegalMode = (reg_value & GTZC_MPCBB_CR_SRWILADIS_Msk);
667   size_mask = (1UL << size_in_superblocks) - 1U;
668   /* limitation: code not portable with memory > 512K */
669   pMPCBB_desc->AttributeConfig.MPCBB_LockConfig_array[0] = READ_REG(mpcbb_ptr->CFGLOCK)
670                                                            & size_mask;
671 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
672 
673   /* read SECCFGR / PRIVCFGR registers information */
674   for (i = 0U; i < size_in_superblocks; i++)
675   {
676     pMPCBB_desc->AttributeConfig.MPCBB_SecConfig_array[i] = mpcbb_ptr->SECCFGR[i];
677     pMPCBB_desc->AttributeConfig.MPCBB_PrivConfig_array[i] = mpcbb_ptr->PRIVCFGR[i];
678   }
679 
680   return HAL_OK;
681 }
682 
683 /**
684   * @brief  Set a MPCBB attribute configuration on the SRAM passed as parameter
685   *         for a number of blocks.
686   * @param  MemAddress MPCBB identifier, and start block to configure
687   *         (must be 512 Bytes aligned).
688   * @param  NbBlocks Number of blocks to configure
689   *         (Block size is 512 Bytes).
690   * @param  pMemAttributes pointer to an array (containing "NbBlocks" elements),
691   *         with each element must be GTZC_MCPBB_BLOCK_NSEC or GTZC_MCPBB_BLOCK_SEC,
692   *         and GTZC_MCPBB_BLOCK_NPRIV or GTZC_MCPBB_BLOCK_PRIV.
693   * @retval HAL status.
694   */
HAL_GTZC_MPCBB_ConfigMemAttributes(uint32_t MemAddress,uint32_t NbBlocks,const uint32_t * pMemAttributes)695 HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMemAttributes(uint32_t MemAddress,
696                                                      uint32_t NbBlocks,
697                                                      const uint32_t *pMemAttributes)
698 {
699   GTZC_MPCBB_TypeDef *mpcbb_ptr;
700   uint32_t base_address;
701   uint32_t end_address;
702   uint32_t block_start;
703   uint32_t offset_reg_start;
704   uint32_t offset_bit_start;
705   uint32_t i;
706   uint32_t do_attr_change;
707 
708   /* firstly check that MemAddress is well 512 Bytes aligned */
709   if ((MemAddress % GTZC_MPCBB_BLOCK_SIZE) != 0U)
710   {
711     return HAL_ERROR;
712   }
713 
714   /* check entry parameters and deduce physical base address */
715   end_address = MemAddress + (NbBlocks * GTZC_MPCBB_BLOCK_SIZE) - 1U;
716   if (((IS_ADDRESS_IN_NS(SRAM1, MemAddress))
717        && (IS_ADDRESS_IN_NS(SRAM1, end_address))) != 0U)
718   {
719     mpcbb_ptr = GTZC_MPCBB1;
720     base_address = SRAM1_BASE_NS;
721   }
722 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
723   else if (((IS_ADDRESS_IN_S(SRAM1, MemAddress))
724             && (IS_ADDRESS_IN_S(SRAM1, end_address))) != 0U)
725   {
726     mpcbb_ptr = GTZC_MPCBB1;
727     base_address = SRAM1_BASE_S;
728   }
729 #endif /* #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
730   else if (((IS_ADDRESS_IN_NS(SRAM2, MemAddress))
731             && (IS_ADDRESS_IN_NS(SRAM2, end_address))) != 0U)
732   {
733     mpcbb_ptr = GTZC_MPCBB2;
734     base_address = SRAM2_BASE_NS;
735   }
736 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
737   else if (((IS_ADDRESS_IN_S(SRAM2, MemAddress))
738             && (IS_ADDRESS_IN_S(SRAM2, end_address))) != 0U)
739   {
740     mpcbb_ptr = GTZC_MPCBB2;
741     base_address = SRAM2_BASE_S;
742   }
743 #endif /* #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
744   else if (((IS_ADDRESS_IN_NS(SRAM6, MemAddress))
745             && (IS_ADDRESS_IN_NS(SRAM6, end_address))) != 0U)
746   {
747     mpcbb_ptr = GTZC_MPCBB6;
748     base_address = SRAM6_BASE_NS;
749   }
750 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
751   else if (((IS_ADDRESS_IN_S(SRAM6, MemAddress))
752             && (IS_ADDRESS_IN_S(SRAM6, end_address))) != 0U)
753   {
754     mpcbb_ptr = GTZC_MPCBB6;
755     base_address = SRAM6_BASE_S;
756   }
757 #endif /* #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
758   else
759   {
760     return HAL_ERROR;
761   }
762 
763   /* get start coordinates of the configuration */
764   block_start = (MemAddress - base_address) / GTZC_MPCBB_BLOCK_SIZE;
765   offset_reg_start = block_start / 32U;
766   offset_bit_start = block_start % 32U;
767 
768   for (i = 0U; i < NbBlocks; i++)
769   {
770     /* Indicate change done for protection attributes */
771     do_attr_change = 0U;
772 
773 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
774     /* secure configuration */
775     if ((pMemAttributes[i] & GTZC_MCPBB_BLOCK_SEC) == GTZC_MCPBB_BLOCK_SEC)
776     {
777       SET_BIT(mpcbb_ptr->SECCFGR[offset_reg_start],
778               1UL << (offset_bit_start % 32U));
779       do_attr_change = 1U;
780     }
781     else if ((pMemAttributes[i] & GTZC_MCPBB_BLOCK_NSEC) == GTZC_MCPBB_BLOCK_NSEC)
782     {
783       CLEAR_BIT(mpcbb_ptr->SECCFGR[offset_reg_start],
784                 1UL << (offset_bit_start % 32U));
785       do_attr_change = 1U;
786     }
787     else
788     {
789       /* nothing to do */
790     }
791 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
792 
793     /* privilege configuration */
794     if ((pMemAttributes[i] & GTZC_MCPBB_BLOCK_PRIV) == GTZC_MCPBB_BLOCK_PRIV)
795     {
796       SET_BIT(mpcbb_ptr->PRIVCFGR[offset_reg_start],
797               1UL << (offset_bit_start % 32U));
798     }
799     else if ((pMemAttributes[i] & GTZC_MCPBB_BLOCK_NPRIV) == GTZC_MCPBB_BLOCK_NPRIV)
800     {
801       CLEAR_BIT(mpcbb_ptr->PRIVCFGR[offset_reg_start],
802                 1UL << (offset_bit_start % 32U));
803     }
804     else
805     {
806       /* if no change is done for security and privilege attributes: break the loop */
807       if (do_attr_change == 0U)
808       {
809         break;
810       }
811     }
812 
813     offset_bit_start++;
814     if (offset_bit_start == 32U)
815     {
816       offset_bit_start = 0U;
817       offset_reg_start++;
818     }
819   }
820 
821   /* an unexpected value in pMemAttributes array leads to error status */
822   if (i != NbBlocks)
823   {
824     return HAL_ERROR;
825   }
826 
827   return HAL_OK;
828 }
829 
830 /**
831   * @brief  Get a MPCBB attribute configuration on the SRAM passed as parameter
832   *         for a number of blocks.
833   * @param  MemAddress MPCBB identifier, and start block to get configuration
834   *         (must be 512 Bytes aligned).
835   * @param  NbBlocks Number of blocks to get configuration.
836   * @param  pMemAttributes pointer to an array (containing "NbBlocks" elements),
837   *         with each element will be GTZC_MCPBB_BLOCK_NSEC or GTZC_MCPBB_BLOCK_SEC,
838   *         and GTZC_MCPBB_BLOCK_NPRIV or GTZC_MCPBB_BLOCK_PRIV.
839   * @retval HAL status.
840   */
HAL_GTZC_MPCBB_GetConfigMemAttributes(uint32_t MemAddress,uint32_t NbBlocks,uint32_t * pMemAttributes)841 HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMemAttributes(uint32_t MemAddress,
842                                                         uint32_t NbBlocks,
843                                                         uint32_t *pMemAttributes)
844 {
845   GTZC_MPCBB_TypeDef *mpcbb_ptr;
846   uint32_t base_address;
847   uint32_t end_address;
848   uint32_t block_start;
849   uint32_t offset_reg_start;
850   uint32_t offset_bit_start;
851   uint32_t i;
852 
853   /* firstly check that MemAddress is well 512 Bytes aligned */
854   if ((MemAddress % GTZC_MPCBB_BLOCK_SIZE) != 0U)
855   {
856     return HAL_ERROR;
857   }
858 
859   /* check entry parameters and deduce physical base address */
860   end_address = MemAddress + (NbBlocks * GTZC_MPCBB_BLOCK_SIZE) - 1U;
861   if ((IS_ADDRESS_IN_NS(SRAM1, MemAddress))
862       && (IS_ADDRESS_IN_NS(SRAM1, end_address)))
863   {
864     mpcbb_ptr = GTZC_MPCBB1_NS;
865     base_address = SRAM1_BASE_NS;
866   }
867 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
868   else if ((IS_ADDRESS_IN_S(SRAM1, MemAddress))
869            && (IS_ADDRESS_IN_S(SRAM1, end_address)))
870   {
871     mpcbb_ptr = GTZC_MPCBB1_S;
872     base_address = SRAM1_BASE_S;
873   }
874 #endif /* #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
875   else if ((IS_ADDRESS_IN_NS(SRAM2, MemAddress))
876            && (IS_ADDRESS_IN_NS(SRAM2, end_address)))
877   {
878     mpcbb_ptr = GTZC_MPCBB2_NS;
879     base_address = SRAM2_BASE_NS;
880   }
881 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
882   else if ((IS_ADDRESS_IN_S(SRAM2, MemAddress))
883            && (IS_ADDRESS_IN_S(SRAM2, end_address)))
884   {
885     mpcbb_ptr = GTZC_MPCBB2_S;
886     base_address = SRAM2_BASE_S;
887   }
888 #endif /* #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
889   else if ((IS_ADDRESS_IN_NS(SRAM6, MemAddress))
890            && (IS_ADDRESS_IN_NS(SRAM6, end_address)))
891   {
892     mpcbb_ptr = GTZC_MPCBB6_NS;
893     base_address = SRAM6_BASE_NS;
894   }
895 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
896   else if ((IS_ADDRESS_IN_S(SRAM6, MemAddress))
897            && (IS_ADDRESS_IN_S(SRAM6, end_address)))
898   {
899     mpcbb_ptr = GTZC_MPCBB6_S;
900     base_address = SRAM6_BASE_S;
901   }
902 #endif /* #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
903   else
904   {
905     return HAL_ERROR;
906   }
907 
908   /* get start coordinates of the configuration */
909   block_start = (MemAddress - base_address) / GTZC_MPCBB_BLOCK_SIZE;
910   offset_reg_start = block_start / 32U;
911   offset_bit_start = block_start % 32U;
912 
913   for (i = 0U; i < NbBlocks; i++)
914   {
915     pMemAttributes[i] = (READ_BIT(mpcbb_ptr->SECCFGR[offset_reg_start],
916                                   1UL << (offset_bit_start % 32U))
917                          >> (offset_bit_start % 32U)) | GTZC_ATTR_SEC_MASK;
918     pMemAttributes[i] |= (READ_BIT(mpcbb_ptr->PRIVCFGR[offset_reg_start],
919                                    1UL << (offset_bit_start % 32U))
920                           >> (offset_bit_start % 32U)) | GTZC_ATTR_PRIV_MASK;
921 
922     offset_bit_start++;
923     if (offset_bit_start == 32U)
924     {
925       offset_bit_start = 0U;
926       offset_reg_start++;
927     }
928   }
929 
930   return HAL_OK;
931 }
932 
933 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
934 /**
935   * @brief  Lock MPCBB super-blocks on the SRAM passed as parameter.
936   * @param  MemAddress MPCBB start-address of super-block to configure
937   *         (must be 16KBytes aligned).
938   * @param  NbSuperBlocks Number of super-blocks to configure.
939   * @param  pLockAttributes pointer to an array (containing "NbSuperBlocks" elements),
940   *         with for each element:
941   *         value 0 super-block is unlocked, value 1 super-block is locked
942   *         (corresponds to GTZC_MCPBB_SUPERBLOCK_UNLOCKED and
943   *         GTZC_MCPBB_SUPERBLOCK_LOCKED values).
944   * @retval HAL status.
945   */
HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress,uint32_t NbSuperBlocks,const uint32_t * pLockAttributes)946 HAL_StatusTypeDef HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress,
947                                             uint32_t NbSuperBlocks,
948                                             const uint32_t *pLockAttributes)
949 {
950   __IO uint32_t *reg_mpcbb;
951   uint32_t base_address;
952   uint32_t superblock_start;
953   uint32_t offset_bit_start;
954   uint32_t i;
955 
956   /* firstly check that MemAddress is well 16KBytes aligned */
957   if ((MemAddress % GTZC_MPCBB_SUPERBLOCK_SIZE) != 0U)
958   {
959     return HAL_ERROR;
960   }
961 
962   /* check entry parameters */
963   if ((IS_ADDRESS_IN(SRAM1, MemAddress))
964       && (IS_ADDRESS_IN(SRAM1, (MemAddress
965                                 + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE)
966                                 - 1U))))
967   {
968     base_address = GTZC_BASE_ADDRESS(SRAM1);
969     /* limitation: code not portable with memory > 512K */
970     reg_mpcbb = (__IO uint32_t *)&GTZC_MPCBB1_S->CFGLOCK;
971   }
972   else if ((IS_ADDRESS_IN(SRAM2, MemAddress))
973            && (IS_ADDRESS_IN(SRAM2, (MemAddress
974                                      + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE)
975                                      - 1U))))
976   {
977     base_address = GTZC_BASE_ADDRESS(SRAM2);
978     /* limitation: code not portable with memory > 512K */
979     reg_mpcbb = (__IO uint32_t *)&GTZC_MPCBB2_S->CFGLOCK;
980   }
981 
982   else if ((IS_ADDRESS_IN(SRAM6, MemAddress))
983            && (IS_ADDRESS_IN(SRAM6, (MemAddress
984                                      + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE)
985                                      - 1U))))
986   {
987     base_address = GTZC_BASE_ADDRESS(SRAM6);
988     /* limitation: code not portable with memory > 512K */
989     reg_mpcbb = (__IO uint32_t *)&GTZC_MPCBB6_S->CFGLOCK;
990   }
991   else
992   {
993     return HAL_ERROR;
994   }
995 
996   /* get start coordinates of the configuration */
997   superblock_start = (MemAddress - base_address) / GTZC_MPCBB_SUPERBLOCK_SIZE;
998   offset_bit_start = superblock_start % 32U;
999 
1000   for (i = 0U; i < NbSuperBlocks; i++)
1001   {
1002     if (pLockAttributes[i] == GTZC_MCPBB_SUPERBLOCK_LOCKED)
1003     {
1004       SET_BIT(*reg_mpcbb, 1UL << (offset_bit_start % 32U));
1005     }
1006     else if (pLockAttributes[i] == GTZC_MCPBB_SUPERBLOCK_UNLOCKED)
1007     {
1008       CLEAR_BIT(*reg_mpcbb, 1UL << (offset_bit_start % 32U));
1009     }
1010     else
1011     {
1012       break;
1013     }
1014 
1015     offset_bit_start++;
1016   }
1017 
1018   /* an unexpected value in pLockAttributes array leads to an error status */
1019   if (i != NbSuperBlocks)
1020   {
1021     return HAL_ERROR;
1022   }
1023 
1024   return HAL_OK;
1025 }
1026 
1027 /**
1028   * @brief  Get MPCBB super-blocks lock configuration on the SRAM passed as parameter.
1029   * @param  MemAddress MPCBB start-address of super-block to get configuration
1030   *         (must be 16KBytes aligned).
1031   * @param  NbSuperBlocks Number of super-blocks to get configuration.
1032   * @param  pLockAttributes pointer to an array (containing "NbSuperBlocks" elements),
1033   *         with for each element:
1034   *         value 0 super-block is unlocked, value 1 super-block is locked
1035   *         (corresponds to GTZC_MCPBB_SUPERBLOCK_UNLOCKED and
1036   *         GTZC_MCPBB_SUPERBLOCK_LOCKED values).
1037   * @retval HAL status.
1038   */
HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress,uint32_t NbSuperBlocks,uint32_t * pLockAttributes)1039 HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress,
1040                                                uint32_t NbSuperBlocks,
1041                                                uint32_t *pLockAttributes)
1042 {
1043   uint32_t reg_mpcbb;
1044   uint32_t base_address;
1045   uint32_t superblock_start;
1046   uint32_t offset_bit_start;
1047   uint32_t i;
1048 
1049   /* firstly check that MemAddress is well 16KBytes aligned */
1050   if ((MemAddress % GTZC_MPCBB_SUPERBLOCK_SIZE) != 0U)
1051   {
1052     return HAL_ERROR;
1053   }
1054 
1055   /* check entry parameters */
1056   if ((IS_ADDRESS_IN(SRAM1, MemAddress))
1057       && (IS_ADDRESS_IN(SRAM1, (MemAddress
1058                                 + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE)
1059                                 - 1U))))
1060   {
1061     base_address = GTZC_BASE_ADDRESS(SRAM1);
1062     /* limitation: code not portable with memory > 512K */
1063     reg_mpcbb = GTZC_MPCBB1_S->CFGLOCK;
1064   }
1065   else if ((IS_ADDRESS_IN(SRAM2, MemAddress))
1066            && (IS_ADDRESS_IN(SRAM2, (MemAddress
1067                                      + (NbSuperBlocks
1068                                         * GTZC_MPCBB_SUPERBLOCK_SIZE)
1069                                      - 1U))))
1070   {
1071     base_address = GTZC_BASE_ADDRESS(SRAM2);
1072     /* limitation: code not portable with memory > 512K */
1073     reg_mpcbb = GTZC_MPCBB2_S->CFGLOCK;
1074   }
1075   else if ((IS_ADDRESS_IN(SRAM6, MemAddress))
1076            && (IS_ADDRESS_IN(SRAM6, (MemAddress
1077                                      + (NbSuperBlocks
1078                                         * GTZC_MPCBB_SUPERBLOCK_SIZE)
1079                                      - 1U))))
1080   {
1081     base_address = GTZC_BASE_ADDRESS(SRAM6);
1082     /* limitation: code not portable with memory > 512K */
1083     reg_mpcbb = GTZC_MPCBB6_S->CFGLOCK;
1084   }
1085   else
1086   {
1087     return HAL_ERROR;
1088   }
1089 
1090   /* get start coordinates of the configuration */
1091   superblock_start = (MemAddress - base_address) / GTZC_MPCBB_SUPERBLOCK_SIZE;
1092   offset_bit_start = superblock_start % 32U;
1093 
1094   for (i = 0U; i < NbSuperBlocks; i++)
1095   {
1096     pLockAttributes[i] = (reg_mpcbb & (1UL << (offset_bit_start % 32U)))
1097                          >> (offset_bit_start % 32U);
1098     offset_bit_start++;
1099   }
1100 
1101   return HAL_OK;
1102 }
1103 
1104 /**
1105   * @brief  Lock a MPCBB configuration on the SRAM base address passed as parameter.
1106   * @note   This functions locks the control register of the MPCBB until next reset.
1107   * @param  MemBaseAddress MPCBB identifier.
1108   * @retval HAL status.
1109   */
HAL_GTZC_MPCBB_Lock(uint32_t MemBaseAddress)1110 HAL_StatusTypeDef HAL_GTZC_MPCBB_Lock(uint32_t MemBaseAddress)
1111 {
1112   /* check entry parameters */
1113   if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
1114   {
1115     SET_BIT(GTZC_MPCBB1_S->CR, GTZC_MPCBB_CR_GLOCK_Msk);
1116   }
1117   else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
1118   {
1119     SET_BIT(GTZC_MPCBB2_S->CR, GTZC_MPCBB_CR_GLOCK_Msk);
1120   }
1121   else if (IS_GTZC_BASE_ADDRESS(SRAM6, MemBaseAddress))
1122   {
1123     SET_BIT(GTZC_MPCBB6_S->CR, GTZC_MPCBB_CR_GLOCK_Msk);
1124   }
1125   else
1126   {
1127     return HAL_ERROR;
1128   }
1129 
1130   return HAL_OK;
1131 }
1132 
1133 /**
1134   * @brief  Get MPCBB configuration lock state on the SRAM base address passed as parameter.
1135   * @param  MemBaseAddress MPCBB identifier.
1136   * @param  pLockState pointer to Lock State (GTZC_MCPBB_LOCK_OFF or GTZC_MCPBB_LOCK_ON).
1137   * @retval HAL status.
1138   */
HAL_GTZC_MPCBB_GetLock(uint32_t MemBaseAddress,uint32_t * pLockState)1139 HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLock(uint32_t MemBaseAddress,
1140                                          uint32_t *pLockState)
1141 {
1142   /* check entry parameters */
1143   if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress))
1144   {
1145     *pLockState = READ_BIT(GTZC_MPCBB1_S->CR, GTZC_MPCBB_CR_GLOCK_Msk);
1146   }
1147   else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))
1148   {
1149     *pLockState = READ_BIT(GTZC_MPCBB2_S->CR, GTZC_MPCBB_CR_GLOCK_Msk);
1150   }
1151   else if (IS_GTZC_BASE_ADDRESS(SRAM6, MemBaseAddress))
1152   {
1153     *pLockState = READ_BIT(GTZC_MPCBB6_S->CR, GTZC_MPCBB_CR_GLOCK_Msk);
1154   }
1155   else
1156   {
1157     return HAL_ERROR;
1158   }
1159 
1160   return HAL_OK;
1161 }
1162 
1163 /**
1164   * @}
1165   */
1166 
1167 /** @defgroup GTZC_Exported_Functions_Group5 TZIC Configuration and Control functions
1168   * @brief    TZIC Configuration and Control functions
1169   *
1170   @verbatim
1171   ==============================================================================
1172             ##### TZIC Configuration and Control functions #####
1173   ==============================================================================
1174   [..]
1175     This section provides functions allowing to configure and control TZIC
1176     TZIC is Trust Zone Interrupt Controller
1177 @endverbatim
1178   * @{
1179   */
1180 
1181 /**
1182   * @brief  Disable the interrupt associated to a single TZIC peripheral or on all peripherals.
1183   * @param  PeriphId Peripheral identifier.
1184   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId.
1185   *         Use GTZC_PERIPH_ALL to select all peripherals.
1186   * @retval HAL status.
1187   */
HAL_GTZC_TZIC_DisableIT(uint32_t PeriphId)1188 HAL_StatusTypeDef HAL_GTZC_TZIC_DisableIT(uint32_t PeriphId)
1189 {
1190   uint32_t register_address;
1191 
1192   /* check entry parameters */
1193   if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER)
1194       || (((PeriphId & GTZC_PERIPH_ALL) != 0U)
1195           && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U)))
1196   {
1197     return HAL_ERROR;
1198   }
1199 
1200   if ((PeriphId & GTZC_PERIPH_ALL) != 0U)
1201   {
1202     /* same configuration is applied to all peripherals */
1203     WRITE_REG(GTZC_TZIC->IER1, 0U);
1204     WRITE_REG(GTZC_TZIC->IER2, 0U);
1205     WRITE_REG(GTZC_TZIC->IER3, 0U);
1206     WRITE_REG(GTZC_TZIC->IER4, 0U);
1207   }
1208   else
1209   {
1210     /* common case where only one peripheral is configured */
1211     register_address = (uint32_t) &(GTZC_TZIC->IER1)
1212                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
1213     CLEAR_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
1214   }
1215 
1216   return HAL_OK;
1217 }
1218 
1219 /**
1220   * @brief  Enable the interrupt associated to a single TZIC peripheral or on all peripherals.
1221   * @param  PeriphId Peripheral identifier.
1222   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId.
1223   *         Use GTZC_PERIPH_ALL to select all peripherals.
1224   * @retval HAL status.
1225   */
HAL_GTZC_TZIC_EnableIT(uint32_t PeriphId)1226 HAL_StatusTypeDef HAL_GTZC_TZIC_EnableIT(uint32_t PeriphId)
1227 {
1228   uint32_t register_address;
1229 
1230   /* check entry parameters */
1231   if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER)
1232       || (((PeriphId & GTZC_PERIPH_ALL) != 0U)
1233           && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U)))
1234   {
1235     return HAL_ERROR;
1236   }
1237 
1238   if ((PeriphId & GTZC_PERIPH_ALL) != 0U)
1239   {
1240     /* same configuration is applied to all peripherals */
1241     WRITE_REG(GTZC_TZIC->IER1, TZIC1_IER1_ALL);
1242     WRITE_REG(GTZC_TZIC->IER2, TZIC1_IER2_ALL);
1243     WRITE_REG(GTZC_TZIC->IER3, TZIC1_IER3_ALL);
1244     WRITE_REG(GTZC_TZIC->IER4, TZIC1_IER4_ALL);
1245   }
1246   else
1247   {
1248     /* common case where only one peripheral is configured */
1249     register_address = (uint32_t) &(GTZC_TZIC->IER1)
1250                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
1251     SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
1252   }
1253 
1254   return HAL_OK;
1255 }
1256 
1257 /**
1258   * @brief  Get TZIC flag on a single TZIC peripheral or on all peripherals.
1259   * @param  PeriphId Peripheral identifier.
1260   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId.
1261   *         Use GTZC_PERIPH_ALL to select all peripherals.
1262   * @param  pFlag Pointer to the flags.
1263   *         If PeriphId target a single peripheral, pointer on a single element.
1264   *         If all peripherals selected (GTZC_PERIPH_ALL), pointer to an array
1265   *         of GTZC_TZIC_PERIPH_NUMBER elements.
1266   *         Element content is either GTZC_TZIC_NO_ILA_EVENT
1267   *         or GTZC_TZSC_ILA_EVENT_PENDING.
1268   * @retval HAL status
1269   */
HAL_GTZC_TZIC_GetFlag(uint32_t PeriphId,uint32_t * pFlag)1270 HAL_StatusTypeDef HAL_GTZC_TZIC_GetFlag(uint32_t PeriphId, uint32_t *pFlag)
1271 {
1272   uint32_t i;
1273   uint32_t reg_value;
1274   uint32_t register_address;
1275 
1276   /* check entry parameters */
1277   if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER)
1278       || (((PeriphId & GTZC_PERIPH_ALL) != 0U)
1279           && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U)))
1280   {
1281     return HAL_ERROR;
1282   }
1283 
1284   if ((PeriphId & GTZC_PERIPH_ALL) != 0U)
1285   {
1286     /* special case where it is applied to all peripherals */
1287     reg_value = READ_REG(GTZC_TZIC->SR1);
1288     for (i = 0U; i < 32U; i++)
1289     {
1290       pFlag[i] = (reg_value & (1UL << i)) >> i;
1291     }
1292 
1293     reg_value = READ_REG(GTZC_TZIC->SR2);
1294     for (i = 32U; i < 64U; i++)
1295     {
1296       pFlag[i] = (reg_value & (1UL << (i - 32U))) >> (i - 32U);
1297     }
1298 
1299     reg_value = READ_REG(GTZC_TZIC->SR3);
1300     for (i = 64; i < 96U; i++)
1301     {
1302       pFlag[i] = (reg_value & (1UL << (i - 64U))) >> (i - 64U);
1303     }
1304 
1305     reg_value = READ_REG(GTZC_TZIC->SR4);
1306     for (i = 96U; i < 128U; i++)
1307     {
1308       pFlag[i] = (reg_value & (1UL << (i - 96U))) >> (i - 96U);
1309     }
1310   }
1311   else
1312   {
1313     /* common case where only one peripheral is concerned */
1314     register_address = (uint32_t) &(GTZC_TZIC->SR1)
1315                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
1316     *pFlag = READ_BIT(*(__IO uint32_t *)register_address,
1317                       1UL << GTZC_GET_PERIPH_POS(PeriphId)) >> GTZC_GET_PERIPH_POS(PeriphId);
1318   }
1319 
1320   return HAL_OK;
1321 }
1322 
1323 /**
1324   * @brief  Clear TZIC flag on a single TZIC peripheral or on all peripherals.
1325   * @param  PeriphId Peripheral identifier.
1326   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId.
1327   *         Use GTZC_PERIPH_ALL to select all peripherals.
1328   * @retval HAL status.
1329   */
HAL_GTZC_TZIC_ClearFlag(uint32_t PeriphId)1330 HAL_StatusTypeDef HAL_GTZC_TZIC_ClearFlag(uint32_t PeriphId)
1331 {
1332   uint32_t register_address;
1333 
1334   /* check entry parameters */
1335   if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER)
1336       || (((PeriphId & GTZC_PERIPH_ALL) != 0U)
1337           && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U)))
1338   {
1339     return HAL_ERROR;
1340   }
1341 
1342   if ((PeriphId & GTZC_PERIPH_ALL) != 0U)
1343   {
1344     /* same configuration is applied to all peripherals */
1345     WRITE_REG(GTZC_TZIC->FCR1, TZIC1_FCR1_ALL);
1346     WRITE_REG(GTZC_TZIC->FCR2, TZIC1_FCR2_ALL);
1347     WRITE_REG(GTZC_TZIC->FCR3, TZIC1_FCR3_ALL);
1348     WRITE_REG(GTZC_TZIC->FCR4, TZIC1_FCR4_ALL);
1349   }
1350   else
1351   {
1352     /* common case where only one peripheral is configured */
1353     register_address = (uint32_t) &(GTZC_TZIC->FCR1)
1354                        + (4U * GTZC_GET_REG_INDEX(PeriphId));
1355     SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId));
1356   }
1357 
1358   return HAL_OK;
1359 }
1360 
1361 /**
1362   * @}
1363   */
1364 
1365 /** @defgroup GTZC_Exported_Functions_Group6 IRQ related functions
1366   * @brief    IRQ related functions
1367   *
1368   @verbatim
1369   ==============================================================================
1370             ##### TZIC IRQ Handler and Callback functions #####
1371   ==============================================================================
1372   [..]
1373     This section provides functions allowing to treat ISR and provide user callback
1374   @endverbatim
1375   * @{
1376   */
1377 
1378 /**
1379   * @brief  This function handles GTZC TZIC interrupt request.
1380   * @retval None.
1381   */
HAL_GTZC_IRQHandler(void)1382 void HAL_GTZC_IRQHandler(void)
1383 {
1384   uint32_t position;
1385   uint32_t flag;
1386   uint32_t ier_itsources;
1387   uint32_t sr_flags;
1388 
1389   /*********************************************************************/
1390   /******************************  TZIC1  ******************************/
1391   /*********************************************************************/
1392 
1393   /* Get current IT Flags and IT sources value on 1st register of TZIC1 */
1394   ier_itsources = READ_REG(GTZC_TZIC_S->IER1);
1395   sr_flags      = READ_REG(GTZC_TZIC_S->SR1);
1396 
1397   /* Get Mask interrupt and then clear them */
1398   flag = ier_itsources & sr_flags;
1399   if (flag != 0U)
1400   {
1401     WRITE_REG(GTZC_TZIC_S->FCR1, flag);
1402 
1403     /* Loop on flag to check, which ones have been raised */
1404     position = 0U;
1405     while ((flag >> position) != 0U)
1406     {
1407       if ((flag & (1UL << position)) != 0U)
1408       {
1409         HAL_GTZC_TZIC_Callback(GTZC_PERIPH_REG1 | position);
1410       }
1411 
1412       /* Position bit to be updated */
1413       position++;
1414     }
1415   }
1416 
1417   /* Get current IT Flags and IT sources value on 2nd register of TZIC1 */
1418   ier_itsources = READ_REG(GTZC_TZIC_S->IER2);
1419   sr_flags      = READ_REG(GTZC_TZIC_S->SR2);
1420 
1421   /* Get Mask interrupt and then clear them */
1422   flag = ier_itsources & sr_flags;
1423   if (flag != 0U)
1424   {
1425     WRITE_REG(GTZC_TZIC_S->FCR2, flag);
1426 
1427     /* Loop on flag to check, which ones have been raised */
1428     position = 0U;
1429     while ((flag >> position) != 0U)
1430     {
1431       if ((flag & (1UL << position)) != 0U)
1432       {
1433         HAL_GTZC_TZIC_Callback(GTZC_PERIPH_REG2 | position);
1434       }
1435 
1436       /* Position bit to be updated */
1437       position++;
1438     }
1439   }
1440 
1441   /* Get current IT Flags and IT sources value on 3rd register of TZIC1 */
1442   ier_itsources = READ_REG(GTZC_TZIC_S->IER3);
1443   sr_flags      = READ_REG(GTZC_TZIC_S->SR3);
1444 
1445   /* Get Mask interrupt and then clear them */
1446   flag = ier_itsources & sr_flags;
1447   if (flag != 0U)
1448   {
1449     WRITE_REG(GTZC_TZIC_S->FCR3, flag);
1450 
1451     /* Loop on flag to check, which ones have been raised */
1452     position = 0U;
1453     while ((flag >> position) != 0U)
1454     {
1455       if ((flag & (1UL << position)) != 0U)
1456       {
1457         HAL_GTZC_TZIC_Callback(GTZC_PERIPH_REG3 | position);
1458       }
1459 
1460       /* Position bit to be updated */
1461       position++;
1462     }
1463   }
1464 
1465   /* Get current IT Flags and IT sources value on 4th register of TZIC1 */
1466   ier_itsources = READ_REG(GTZC_TZIC_S->IER4);
1467   sr_flags      = READ_REG(GTZC_TZIC_S->SR4);
1468 
1469   /* Get Mask interrupt and then clear them */
1470   flag = ier_itsources & sr_flags;
1471   if (flag != 0U)
1472   {
1473     WRITE_REG(GTZC_TZIC_S->FCR4, flag);
1474 
1475     /* Loop on flag to check, which ones have been raised */
1476     position = 0U;
1477     while ((flag >> position) != 0U)
1478     {
1479       if ((flag & (1UL << position)) != 0U)
1480       {
1481         HAL_GTZC_TZIC_Callback(GTZC_PERIPH_REG4 | position);
1482       }
1483 
1484       /* Position bit to be updated */
1485       position++;
1486     }
1487   }
1488 
1489 }
1490 
1491 /**
1492   * @brief  GTZC TZIC sub-block interrupt callback.
1493   * @param  PeriphId Peripheral identifier triggering the illegal access.
1494   *         This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId
1495   * @retval None.
1496   */
HAL_GTZC_TZIC_Callback(uint32_t PeriphId)1497 __weak void HAL_GTZC_TZIC_Callback(uint32_t PeriphId)
1498 {
1499   /* Prevent unused argument(s) compilation warning */
1500   UNUSED(PeriphId);
1501 
1502   /* NOTE: This function should not be modified. When the callback is needed,
1503    * the HAL_GTZC_TZIC_Callback is to be implemented in the user file
1504    */
1505 }
1506 
1507 /**
1508   * @}
1509   */
1510 
1511 #endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
1512 
1513 /**
1514   * @}
1515   */
1516 
1517 /**
1518   * @}
1519   */
1520 
1521 #endif /* defined(GTZC_TZSC) && defined(HAL_GTZC_MODULE_ENABLED) */
1522 
1523 /**
1524   * @}
1525   */
1526