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