1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_hal_icache.c
4   * @author  MCD Application Team
5   * @brief   ICACHE HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Instruction Cache (ICACHE).
8   *           + Initialization and Configuration
9   *           + Invalidate functions
10   *           + Monitoring management
11   *           + Memory address remap management
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2022 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### ICACHE main features #####
26   ==============================================================================
27   [..]
28     The Instruction Cache (ICACHE) is introduced on C-AHB code bus of
29     Cortex-M33 processor to improve performance when fetching instruction
30     and data from both internal and external memories. It allows close to
31     zero wait states performance.
32 
33     (+) The ICACHE provides two performance counters (Hit and Miss),
34         cache invalidate maintenance operation, error management and TrustZone
35         security support.
36 
37     (+) The ICACHE provides additionally the possibility to remap input address
38         falling into up to four memory regions (used to remap aliased code in
39         external memories to the internal Code region, for execution)
40 
41   ===============================================================================
42                         ##### How to use this driver #####
43   ===============================================================================
44   [..]
45      The ICACHE HAL driver can be used as follows:
46 
47     (#) Optionally configure the Instruction Cache mode with
48         @ref HAL_ICACHE_ConfigAssociativityMode() if the default configuration
49         does not suit the application requirements.
50 
51     (#) Enable and disable the Instruction Cache with respectively
52         @ref HAL_ICACHE_Enable() and @ref HAL_ICACHE_Disable().
53         Use @ref HAL_ICACHE_IsEnabled() to get the Instruction Cache status.
54 
55     (#) Initiate the cache maintenance invalidation procedure with either
56         @ref HAL_ICACHE_Invalidate() (blocking mode) or @ref HAL_ICACHE_Invalidate_IT()
57         (interrupt mode). When interrupt mode is used, the callback function
58         @ref HAL_ICACHE_InvalidateCompleteCallback() is called when the invalidate
59         procedure is complete. The function @ref HAL_ICACHE_WaitForInvalidateComplete()
60         may be called to wait for the end of the invalidate procedure automatically
61         initiated when disabling the Instruction Cache with @ref HAL_ICACHE_Disable().
62         The cache operation is bypassed during the invalidation procedure.
63 
64     (#) Use the performance monitoring counters for Hit and Miss with the following
65         functions: @ref HAL_ICACHE_Monitor_Start(), @ref HAL_ICACHE_Monitor_Stop(),
66         @ref HAL_ICACHE_Monitor_Reset(), @ref HAL_ICACHE_Monitor_GetHitValue() and
67         @ref HAL_ICACHE_Monitor_GetMissValue()
68 
69     (#) Enable and disable up to four regions to remap input address from external
70         memories to the internal Code region for execution with
71         @ref HAL_ICACHE_EnableRemapRegion() and @ref HAL_ICACHE_DisableRemapRegion()
72 
73   @endverbatim
74   */
75 
76 /* Includes ------------------------------------------------------------------*/
77 #include "stm32h5xx_hal.h"
78 
79 /** @addtogroup STM32H5xx_HAL_Driver
80   * @{
81   */
82 
83 /** @defgroup ICACHE ICACHE
84   * @brief HAL ICACHE module driver
85   * @{
86   */
87 #ifdef HAL_ICACHE_MODULE_ENABLED
88 
89 /* Private typedef -----------------------------------------------------------*/
90 /* Private constants ---------------------------------------------------------*/
91 /** @addtogroup ICACHE_Private_Constants ICACHE Private Constants
92   * @{
93   */
94 #define ICACHE_INVALIDATE_TIMEOUT_VALUE        1U   /* 1ms */
95 #define ICACHE_DISABLE_TIMEOUT_VALUE           1U   /* 1ms */
96 
97 /**
98   * @}
99   */
100 
101 /* Private macros ------------------------------------------------------------*/
102 /** @defgroup ICACHE_Private_Macros ICACHE Private Macros
103   * @{
104   */
105 
106 #define IS_ICACHE_ASSOCIATIVITY_MODE(__MODE__) (((__MODE__) == ICACHE_1WAY) || \
107                                                 ((__MODE__) == ICACHE_2WAYS))
108 
109 #define IS_ICACHE_MONITOR_TYPE(__TYPE__)    (((__TYPE__) == ICACHE_MONITOR_HIT_MISS) || \
110                                              ((__TYPE__) == ICACHE_MONITOR_HIT)      || \
111                                              ((__TYPE__) == ICACHE_MONITOR_MISS))
112 
113 #if defined(ICACHE_CRRx_REN)
114 #define IS_ICACHE_REGION_NUMBER(__NUMBER__) ((__NUMBER__) < 4U)
115 
116 #define IS_ICACHE_REGION_SIZE(__SIZE__)     (((__SIZE__) == ICACHE_REGIONSIZE_2MB)   || \
117                                              ((__SIZE__) == ICACHE_REGIONSIZE_4MB)   || \
118                                              ((__SIZE__) == ICACHE_REGIONSIZE_8MB)   || \
119                                              ((__SIZE__) == ICACHE_REGIONSIZE_16MB)  || \
120                                              ((__SIZE__) == ICACHE_REGIONSIZE_32MB)  || \
121                                              ((__SIZE__) == ICACHE_REGIONSIZE_64MB)  || \
122                                              ((__SIZE__) == ICACHE_REGIONSIZE_128MB))
123 
124 #define IS_ICACHE_REGION_TRAFFIC_ROUTE(__TRAFFICROUTE__)  (((__TRAFFICROUTE__) == ICACHE_MASTER1_PORT) || \
125                                                            ((__TRAFFICROUTE__) == ICACHE_MASTER2_PORT))
126 
127 #define IS_ICACHE_REGION_OUTPUT_BURST_TYPE(__OUTPUTBURSTTYPE_) (((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_WRAP) || \
128                                                                 ((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_INCR))
129 
130 #endif /*  ICACHE_CRRx_REN */
131 /**
132   * @}
133   */
134 
135 /* Private variables ---------------------------------------------------------*/
136 /* Private function prototypes -----------------------------------------------*/
137 
138 /* Exported functions --------------------------------------------------------*/
139 
140 /** @defgroup ICACHE_Exported_Functions ICACHE Exported Functions
141   * @{
142   */
143 
144 /** @defgroup ICACHE_Exported_Functions_Group1 Initialization and control functions
145   * @brief    Initialization and control functions
146   *
147   @verbatim
148   ==============================================================================
149             ##### Initialization and control functions #####
150   ==============================================================================
151   [..]
152     This section provides functions allowing to initialize and control the
153     Instruction Cache (mode, invalidate procedure, performance counters).
154   @endverbatim
155   * @{
156   */
157 
158 /**
159   * @brief  Configure the Instruction Cache cache associativity mode selection.
160   * @param  AssociativityMode  Associativity mode selection
161   *         This parameter can be one of the following values:
162   *            @arg ICACHE_1WAY   1-way cache (direct mapped cache)
163   *            @arg ICACHE_2WAYS  2-ways set associative cache (default)
164   * @retval HAL status (HAL_OK/HAL_ERROR)
165   */
HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)166 HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)
167 {
168   HAL_StatusTypeDef status = HAL_OK;
169 
170   /* Check the parameters */
171   assert_param(IS_ICACHE_ASSOCIATIVITY_MODE(AssociativityMode));
172 
173   /* Check cache is not enabled */
174   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
175   {
176     status = HAL_ERROR;
177   }
178   else
179   {
180     MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, AssociativityMode);
181   }
182 
183   return status;
184 }
185 
186 /**
187   * @brief  DeInitialize the Instruction Cache.
188   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
189   */
HAL_ICACHE_DeInit(void)190 HAL_StatusTypeDef HAL_ICACHE_DeInit(void)
191 {
192   HAL_StatusTypeDef status;
193 
194   /* Disable cache with reset value for 2-ways set associative mode */
195   WRITE_REG(ICACHE->CR, ICACHE_CR_WAYSEL);
196 
197   /* Stop monitor and reset monitor values */
198   (void)HAL_ICACHE_Monitor_Stop(ICACHE_MONITOR_HIT_MISS);
199   (void)HAL_ICACHE_Monitor_Reset(ICACHE_MONITOR_HIT_MISS);
200 
201 #if defined(ICACHE_CRRx_REN)
202   /* No remapped regions */
203   (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_0);
204   (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_1);
205   (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_2);
206   (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_3);
207 #endif /*  ICACHE_CRRx_REN */
208 
209   /* Wait for end of invalidate cache procedure */
210   status = HAL_ICACHE_WaitForInvalidateComplete();
211 
212   /* Clear any pending flags */
213   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF | ICACHE_FCR_CERRF);
214 
215   return status;
216 }
217 
218 /**
219   * @brief  Enable the Instruction Cache.
220   * @note   This function always returns HAL_OK even if there is any ongoing
221   *         cache operation. The Instruction Cache is bypassed until the
222   *         cache operation completes.
223   * @retval HAL status (HAL_OK)
224   */
HAL_ICACHE_Enable(void)225 HAL_StatusTypeDef HAL_ICACHE_Enable(void)
226 {
227   SET_BIT(ICACHE->CR, ICACHE_CR_EN);
228 
229   return HAL_OK;
230 }
231 
232 /**
233   * @brief  Disable the Instruction Cache.
234   * @note   This function waits for the cache being disabled but
235   *         not for the end of the automatic cache invalidation procedure.
236   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
237   */
HAL_ICACHE_Disable(void)238 HAL_StatusTypeDef HAL_ICACHE_Disable(void)
239 {
240   HAL_StatusTypeDef status = HAL_OK;
241   uint32_t tickstart;
242 
243   /* Make sure BSYENDF is reset before to disable the instruction cache */
244   /* as it automatically starts a cache invalidation procedure */
245   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
246 
247   CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
248 
249   /* Get tick */
250   tickstart = HAL_GetTick();
251 
252   /* Wait for instruction cache being disabled */
253   while (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
254   {
255     if ((HAL_GetTick() - tickstart) > ICACHE_DISABLE_TIMEOUT_VALUE)
256     {
257       /* New check to avoid false timeout detection in case of preemption */
258       if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
259       {
260         status = HAL_TIMEOUT;
261         break;
262       }
263     }
264   }
265 
266   return status;
267 }
268 
269 /**
270   * @brief  Check whether the Instruction Cache is enabled or not.
271   * @retval Status (0: disabled, 1: enabled)
272   */
HAL_ICACHE_IsEnabled(void)273 uint32_t HAL_ICACHE_IsEnabled(void)
274 {
275   return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) ? 1UL : 0UL);
276 }
277 
278 /**
279   * @brief  Invalidate the Instruction Cache.
280   * @note   This function waits for the end of cache invalidation procedure
281   *         and clears the associated BSYENDF flag.
282   * @retval HAL status (HAL_OK/HAL_ERROR/HAL_TIMEOUT)
283   */
HAL_ICACHE_Invalidate(void)284 HAL_StatusTypeDef HAL_ICACHE_Invalidate(void)
285 {
286   HAL_StatusTypeDef status;
287 
288   /* Check no ongoing operation */
289   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
290   {
291     status = HAL_ERROR;
292   }
293   else
294   {
295     /* Make sure BSYENDF is reset before to start cache invalidation */
296     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
297 
298     /* Launch cache invalidation */
299     SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
300 
301     status = HAL_ICACHE_WaitForInvalidateComplete();
302   }
303 
304   return status;
305 }
306 
307 /**
308   * @brief  Invalidate the Instruction Cache with interrupt.
309   * @note   This function launches cache invalidation and returns.
310   *         User application shall resort to interrupt generation to check
311   *         the end of the cache invalidation with the BSYENDF flag and the
312   *         HAL_ICACHE_InvalidateCompleteCallback() callback.
313   * @retval HAL status (HAL_OK/HAL_ERROR)
314   */
HAL_ICACHE_Invalidate_IT(void)315 HAL_StatusTypeDef HAL_ICACHE_Invalidate_IT(void)
316 {
317   HAL_StatusTypeDef status = HAL_OK;
318 
319   /* Check no ongoing operation */
320   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
321   {
322     status = HAL_ERROR;
323   }
324   else
325   {
326     /* Make sure BSYENDF is reset before to start cache invalidation */
327     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
328 
329     /* Enable end of cache invalidation interrupt */
330     SET_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
331 
332     /* Launch cache invalidation */
333     SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
334   }
335 
336   return status;
337 }
338 
339 /**
340   * @brief Wait for the end of the Instruction Cache invalidate procedure.
341   * @note This function checks and clears the BSYENDF flag when set.
342   * @retval HAL status (HAL_OK/HAL_TIMEOUT)
343   */
HAL_ICACHE_WaitForInvalidateComplete(void)344 HAL_StatusTypeDef HAL_ICACHE_WaitForInvalidateComplete(void)
345 {
346   HAL_StatusTypeDef status = HAL_OK;
347   uint32_t tickstart;
348 
349   /* Check if ongoing invalidation operation */
350   if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
351   {
352     /* Get tick */
353     tickstart = HAL_GetTick();
354 
355     /* Wait for end of cache invalidation */
356     while (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
357     {
358       if ((HAL_GetTick() - tickstart) > ICACHE_INVALIDATE_TIMEOUT_VALUE)
359       {
360         /* New check to avoid false timeout detection in case of preemption */
361         if (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
362         {
363           status = HAL_TIMEOUT;
364           break;
365         }
366       }
367     }
368   }
369 
370   /* Clear BSYENDF */
371   WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
372 
373   return status;
374 }
375 
376 
377 /**
378   * @brief  Start the Instruction Cache performance monitoring.
379   * @param  MonitorType  Monitoring type
380   *         This parameter can be one of the following values:
381   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
382   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
383   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
384   * @retval HAL status (HAL_OK)
385   */
HAL_ICACHE_Monitor_Start(uint32_t MonitorType)386 HAL_StatusTypeDef HAL_ICACHE_Monitor_Start(uint32_t MonitorType)
387 {
388   /* Check the parameters */
389   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
390 
391   SET_BIT(ICACHE->CR, MonitorType);
392 
393   return HAL_OK;
394 }
395 
396 /**
397   * @brief  Stop the Instruction Cache performance monitoring.
398   * @note   Stopping the monitoring does not reset the values.
399   * @param  MonitorType  Monitoring type
400   *         This parameter can be one of the following values:
401   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
402   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
403   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
404   * @retval HAL status (HAL_OK)
405   */
HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)406 HAL_StatusTypeDef HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)
407 {
408   /* Check the parameters */
409   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
410 
411   CLEAR_BIT(ICACHE->CR, MonitorType);
412 
413   return HAL_OK;
414 }
415 
416 /**
417   * @brief  Reset the Instruction Cache performance monitoring values.
418   * @param  MonitorType  Monitoring type
419   *         This parameter can be one of the following values:
420   *            @arg ICACHE_MONITOR_HIT_MISS   Hit & Miss monitoring
421   *            @arg ICACHE_MONITOR_HIT        Hit monitoring
422   *            @arg ICACHE_MONITOR_MISS       Miss monitoring
423   * @retval HAL status (HAL_OK)
424   */
HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)425 HAL_StatusTypeDef HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)
426 {
427   /* Check the parameters */
428   assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
429 
430   /* Force/Release reset */
431   SET_BIT(ICACHE->CR, (MonitorType << 2U));
432   CLEAR_BIT(ICACHE->CR, (MonitorType << 2U));
433 
434   return HAL_OK;
435 }
436 
437 /**
438   * @brief  Get the Instruction Cache performance Hit monitoring value.
439   * @note   Upon reaching the 32-bit maximum value, monitor does not wrap.
440   * @retval Hit monitoring value
441   */
HAL_ICACHE_Monitor_GetHitValue(void)442 uint32_t HAL_ICACHE_Monitor_GetHitValue(void)
443 {
444   return (ICACHE->HMONR);
445 }
446 
447 /**
448   * @brief  Get the Instruction Cache performance Miss monitoring value.
449   * @note   Upon reaching the 32-bit maximum value, monitor does not wrap.
450   * @retval Miss monitoring value
451   */
HAL_ICACHE_Monitor_GetMissValue(void)452 uint32_t HAL_ICACHE_Monitor_GetMissValue(void)
453 {
454   return (ICACHE->MMONR);
455 }
456 
457 /**
458   * @}
459   */
460 
461 /** @defgroup ICACHE_Exported_Functions_Group2 IRQ and callback functions
462   * @brief    IRQ and callback functions
463   *
464   @verbatim
465   ==============================================================================
466             ##### IRQ and callback functions #####
467   ==============================================================================
468   [..]
469     This section provides functions allowing to handle ICACHE global interrupt
470     and the associated callback functions.
471   @endverbatim
472   * @{
473   */
474 
475 /**
476   * @brief Handle the Instruction Cache interrupt request.
477   * @note This function should be called under the ICACHE_IRQHandler().
478   * @note This function respectively disables the interrupt and clears the
479   *       flag of any pending flag before calling the associated user callback.
480   * @retval None
481   */
HAL_ICACHE_IRQHandler(void)482 void HAL_ICACHE_IRQHandler(void)
483 {
484   /* Get current interrupt flags and interrupt sources value */
485   uint32_t itflags   = READ_REG(ICACHE->SR);
486   uint32_t itsources = READ_REG(ICACHE->IER);
487 
488   /* Check Instruction cache Error interrupt flag */
489   if (((itflags & itsources) & ICACHE_FLAG_ERROR) != 0U)
490   {
491     /* Disable error interrupt */
492     CLEAR_BIT(ICACHE->IER, ICACHE_IER_ERRIE);
493 
494     /* Clear ERR pending flag */
495     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CERRF);
496 
497     /* Instruction cache error interrupt user callback */
498     HAL_ICACHE_ErrorCallback();
499   }
500 
501   /* Check Instruction cache BusyEnd interrupt flag */
502   if (((itflags & itsources) & ICACHE_FLAG_BUSYEND) != 0U)
503   {
504     /* Disable end of cache invalidation interrupt */
505     CLEAR_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
506 
507     /* Clear BSYENDF pending flag */
508     WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
509 
510     /* Instruction cache busyend interrupt user callback */
511     HAL_ICACHE_InvalidateCompleteCallback();
512   }
513 }
514 
515 /**
516   * @brief  Cache invalidation complete callback.
517   */
HAL_ICACHE_InvalidateCompleteCallback(void)518 __weak void HAL_ICACHE_InvalidateCompleteCallback(void)
519 {
520   /* NOTE : This function should not be modified, when the callback is needed,
521             the HAL_ICACHE_InvalidateCompleteCallback() should be implemented in the user file
522    */
523 }
524 
525 /**
526   * @brief  Error callback.
527   */
HAL_ICACHE_ErrorCallback(void)528 __weak void HAL_ICACHE_ErrorCallback(void)
529 {
530   /* NOTE : This function should not be modified, when the callback is needed,
531             the HAL_ICACHE_ErrorCallback() should be implemented in the user file
532    */
533 }
534 
535 /**
536   * @}
537   */
538 
539 #if defined(ICACHE_CRRx_REN)
540 /** @defgroup ICACHE_Exported_Functions_Group3 Memory remapped regions functions
541   * @brief    Memory remapped regions functions
542   *
543   @verbatim
544   ==============================================================================
545             ##### Memory remapped regions functions #####
546   ==============================================================================
547   [..]
548     This section provides functions allowing to manage the remapping of
549     external memories to internal Code for execution.
550   @endverbatim
551   * @{
552   */
553 
554 /**
555   * @brief  Configure and enable a region for memory remapping.
556   * @note   The Instruction Cache and the region must be disabled.
557   * @param  Region   Region number
558                      This parameter can be a value of @arg @ref ICACHE_Region
559   * @param  pRegionConfig  Pointer to structure of ICACHE region configuration parameters
560   * @retval HAL status (HAL_OK/HAL_ERROR)
561   */
HAL_ICACHE_EnableRemapRegion(uint32_t Region,const ICACHE_RegionConfigTypeDef * const pRegionConfig)562 HAL_StatusTypeDef  HAL_ICACHE_EnableRemapRegion(uint32_t Region, const ICACHE_RegionConfigTypeDef *const pRegionConfig)
563 {
564   HAL_StatusTypeDef status = HAL_OK;
565   __IO uint32_t *p_reg;
566   uint32_t value;
567 
568   /* Check the parameters */
569   assert_param(IS_ICACHE_REGION_NUMBER(Region));
570   assert_param(IS_ICACHE_REGION_SIZE(pRegionConfig->Size));
571   assert_param(IS_ICACHE_REGION_TRAFFIC_ROUTE(pRegionConfig->TrafficRoute));
572   assert_param(IS_ICACHE_REGION_OUTPUT_BURST_TYPE(pRegionConfig->OutputBurstType));
573 
574   /* Check cache is not enabled */
575   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
576   {
577     status = HAL_ERROR;
578   }
579   else
580   {
581     /* Get region control register address */
582     p_reg = &(ICACHE->CRR0) + (1U * Region);
583 
584     /* Check region is not already enabled */
585     if ((*p_reg & ICACHE_CRRx_REN) != 0U)
586     {
587       status = HAL_ERROR;
588     }
589     else
590     {
591       /* Region 2MB:   BaseAddress size 8 bits, RemapAddress size 11 bits */
592       /* Region 4MB:   BaseAddress size 7 bits, RemapAddress size 10 bits */
593       /* Region 8MB:   BaseAddress size 6 bits, RemapAddress size 9 bits  */
594       /* Region 16MB:  BaseAddress size 5 bits, RemapAddress size 8 bits  */
595       /* Region 32MB:  BaseAddress size 4 bits, RemapAddress size 7 bits  */
596       /* Region 64MB:  BaseAddress size 3 bits, RemapAddress size 6 bits  */
597       /* Region 128MB: BaseAddress size 2 bits, RemapAddress size 5 bits  */
598       value  = ((pRegionConfig->BaseAddress & 0x1FFFFFFFU) >> 21U) & \
599                (0xFFU & ~(pRegionConfig->Size - 1U));
600       value |= ((pRegionConfig->RemapAddress >> 5U) & \
601                 ((uint32_t)(0x7FFU & ~(pRegionConfig->Size - 1U)) << ICACHE_CRRx_REMAPADDR_Pos));
602       value |= (pRegionConfig->Size << ICACHE_CRRx_RSIZE_Pos) | pRegionConfig->TrafficRoute | \
603                pRegionConfig->OutputBurstType;
604       *p_reg = (value | ICACHE_CRRx_REN);
605     }
606   }
607 
608   return status;
609 }
610 
611 /**
612   * @brief  Disable the memory remapping for a predefined region.
613   * @param  Region   Region number
614                      This parameter can be a value of @arg @ref ICACHE_Region
615   * @retval HAL status (HAL_OK/HAL_ERROR)
616   */
HAL_ICACHE_DisableRemapRegion(uint32_t Region)617 HAL_StatusTypeDef  HAL_ICACHE_DisableRemapRegion(uint32_t Region)
618 {
619   HAL_StatusTypeDef status = HAL_OK;
620   __IO uint32_t *p_reg;
621 
622   /* Check the parameters */
623   assert_param(IS_ICACHE_REGION_NUMBER(Region));
624 
625   /* Check cache is not enabled */
626   if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
627   {
628     status = HAL_ERROR;
629   }
630   else
631   {
632     /* Get region control register address */
633     p_reg = &(ICACHE->CRR0) + (1U * Region);
634 
635     *p_reg &= ~ICACHE_CRRx_REN;
636   }
637 
638   return status;
639 }
640 
641 
642 /**
643   * @}
644   */
645 #endif /*  ICACHE_CRRx_REN */
646 
647 /**
648   * @}
649   */
650 
651 #endif /* HAL_ICACHE_MODULE_ENABLED */
652 
653 /**
654   * @}
655   */
656 
657 /**
658   * @}
659   */
660