1 /*
2  * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <sys/param.h>
7 #include <stdint.h>
8 #include "sdkconfig.h"
9 #include "esp_err.h"
10 #include "esp_attr.h"
11 #include "hal/assert.h"
12 #include "hal/cache_hal.h"
13 #include "hal/cache_types.h"
14 #include "hal/cache_ll.h"
15 #include "hal/mmu_hal.h"
16 #include "hal/mmu_ll.h"
17 #include "soc/soc_caps.h"
18 #include "rom/cache.h"
19 
20 /*------------------------------------------------------------------------------
21  * Unified Cache Control
22  * See cache_hal.h for more info about these HAL APIs
23  * This file is in internal RAM.
24  * Now this file doesn't compile on ESP32
25  *----------------------------------------------------------------------------*/
26 
27 /**
28  * To know if autoload is enabled or not.
29  *
30  * We should have a unified flag for this aim, then we don't need to call following 2 functions
31  * to know the flag.
32  *
33  * Suggest ROM keeping this flag value to BIT(2). Then we can replace following lines to:
34  * #define DATA_AUTOLOAD_FLAG      BIT(2)
35  * #define INST_AUTOLOAD_FLAG      BIT(2)
36  */
37 #define DATA_AUTOLOAD_FLAG      Cache_Disable_DCache()
38 #define INST_AUTOLOAD_FLAG      Cache_Disable_ICache()
39 
40 /**
41  * Necessary hal contexts, could be maintained by upper layer in the future
42  */
43 typedef struct {
44     uint32_t data_autoload_flag;
45     uint32_t inst_autoload_flag;
46 } cache_hal_context_t;
47 
48 static cache_hal_context_t ctx;
49 
cache_hal_init(void)50 void cache_hal_init(void)
51 {
52 #if SOC_SHARED_IDCACHE_SUPPORTED
53     ctx.data_autoload_flag = INST_AUTOLOAD_FLAG;
54     Cache_Enable_ICache(ctx.data_autoload_flag);
55 #else
56     ctx.data_autoload_flag = DATA_AUTOLOAD_FLAG;
57     Cache_Enable_DCache(ctx.data_autoload_flag);
58     ctx.inst_autoload_flag = INST_AUTOLOAD_FLAG;
59     Cache_Enable_ICache(ctx.inst_autoload_flag);
60 #endif
61 
62     cache_ll_l1_enable_bus(0, CACHE_LL_DEFAULT_DBUS_MASK);
63     cache_ll_l1_enable_bus(0, CACHE_LL_DEFAULT_IBUS_MASK);
64 
65 #if !CONFIG_FREERTOS_UNICORE
66     cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_DBUS_MASK);
67     cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_IBUS_MASK);
68 #endif
69 }
70 
cache_hal_disable(cache_type_t type)71 void cache_hal_disable(cache_type_t type)
72 {
73 #if SOC_SHARED_IDCACHE_SUPPORTED
74     Cache_Disable_ICache();
75 #else
76     if (type == CACHE_TYPE_DATA) {
77         Cache_Disable_DCache();
78     } else if (type == CACHE_TYPE_INSTRUCTION) {
79         Cache_Disable_ICache();
80     } else {
81         Cache_Disable_ICache();
82         Cache_Disable_DCache();
83     }
84 #endif
85 }
86 
cache_hal_enable(cache_type_t type)87 void cache_hal_enable(cache_type_t type)
88 {
89 #if SOC_SHARED_IDCACHE_SUPPORTED
90     Cache_Enable_ICache(ctx.inst_autoload_flag);
91 #else
92     if (type == CACHE_TYPE_DATA) {
93         Cache_Enable_DCache(ctx.data_autoload_flag);
94     } else if (type == CACHE_TYPE_INSTRUCTION) {
95         Cache_Enable_ICache(ctx.inst_autoload_flag);
96     } else {
97         Cache_Enable_ICache(ctx.inst_autoload_flag);
98         Cache_Enable_DCache(ctx.data_autoload_flag);
99     }
100 #endif
101 }
102 
cache_hal_invalidate_addr(uint32_t vaddr,uint32_t size)103 void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size)
104 {
105     //Now only esp32 has 2 MMUs, this file doesn't build on esp32
106     HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(0, vaddr, size, MMU_VADDR_DATA | MMU_VADDR_INSTRUCTION));
107     Cache_Invalidate_Addr(vaddr, size);
108 }
109 
110 #if SOC_CACHE_WRITEBACK_SUPPORTED
cache_hal_writeback_addr(uint32_t vaddr,uint32_t size)111 void cache_hal_writeback_addr(uint32_t vaddr, uint32_t size)
112 {
113     HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(0, vaddr, size, MMU_VADDR_DATA));
114     Cache_WriteBack_Addr(vaddr, size);
115 }
116 #endif  //#if SOC_CACHE_WRITEBACK_SUPPORTED
117 
118 
119 #if SOC_CACHE_FREEZE_SUPPORTED
cache_hal_freeze(cache_type_t type)120 void cache_hal_freeze(cache_type_t type)
121 {
122 #if SOC_SHARED_IDCACHE_SUPPORTED
123     Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY);
124 #else
125     if (type == CACHE_TYPE_DATA) {
126         Cache_Freeze_DCache_Enable(CACHE_FREEZE_ACK_BUSY);
127     } else if (type == CACHE_TYPE_INSTRUCTION) {
128         Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY);
129     } else {
130         Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY);
131         Cache_Freeze_DCache_Enable(CACHE_FREEZE_ACK_BUSY);
132     }
133 #endif
134 }
135 
cache_hal_unfreeze(cache_type_t type)136 void cache_hal_unfreeze(cache_type_t type)
137 {
138 #if SOC_SHARED_IDCACHE_SUPPORTED
139     Cache_Freeze_ICache_Disable();
140 #else
141     if (type == CACHE_TYPE_DATA) {
142         Cache_Freeze_DCache_Disable();
143     } else if (type == CACHE_TYPE_INSTRUCTION) {
144         Cache_Freeze_ICache_Disable();
145     } else {
146         Cache_Freeze_DCache_Disable();
147         Cache_Freeze_ICache_Disable();
148     }
149 #endif
150 }
151 #endif  //#if SOC_CACHE_FREEZE_SUPPORTED
152 
cache_hal_get_cache_line_size(cache_type_t type)153 uint32_t cache_hal_get_cache_line_size(cache_type_t type)
154 {
155 #if SOC_SHARED_IDCACHE_SUPPORTED
156     return Cache_Get_ICache_Line_Size();
157 #else
158     uint32_t size = 0;
159     if (type == CACHE_TYPE_DATA) {
160         size = Cache_Get_DCache_Line_Size();
161     } else if (type == CACHE_TYPE_INSTRUCTION) {
162         size = Cache_Get_ICache_Line_Size();
163     } else {
164         HAL_ASSERT(false);
165     }
166     return size;
167 #endif
168 }
169