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