1 /* 2 * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef _ROM_CACHE_H_ 8 #define _ROM_CACHE_H_ 9 10 #include <stdint.h> 11 #include "esp_bit_defs.h" 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /** \defgroup cache_apis, cache operation related apis 18 * @brief cache apis 19 */ 20 21 /** @addtogroup cache_apis 22 * @{ 23 */ 24 #define MIN_ICACHE_SIZE 16384 25 #define MAX_ICACHE_SIZE 16384 26 #define MIN_ICACHE_WAYS 8 27 #define MAX_ICACHE_WAYS 8 28 #define MAX_CACHE_WAYS 8 29 #define MIN_CACHE_LINE_SIZE 32 30 #define TAG_SIZE 4 31 #define MIN_ICACHE_BANK_NUM 1 32 #define MAX_ICACHE_BANK_NUM 1 33 #define CACHE_MEMORY_BANK_NUM 1 34 #define CACHE_MEMORY_IBANK_SIZE 0x4000 35 36 #define MAX_ITAG_BANK_ITEMS (MAX_ICACHE_SIZE / MAX_ICACHE_BANK_NUM / MIN_CACHE_LINE_SIZE) 37 #define MAX_ITAG_BLOCK_ITEMS (MAX_ICACHE_SIZE / MAX_ICACHE_BANK_NUM / MAX_ICACHE_WAYS / MIN_CACHE_LINE_SIZE) 38 #define MAX_ITAG_BANK_SIZE (MAX_ITAG_BANK_ITEMS * TAG_SIZE) 39 #define MAX_ITAG_BLOCK_SIZE (MAX_ITAG_BLOCK_ITEMS * TAG_SIZE) 40 41 typedef enum { 42 CACHE_DCACHE = 0, 43 CACHE_ICACHE0 = 1, 44 CACHE_ICACHE1 = 2, 45 } cache_t; 46 47 typedef enum { 48 CACHE_MEMORY_INVALID = 0, 49 CACHE_MEMORY_IBANK0 = BIT(0), 50 CACHE_MEMORY_IBANK1 = BIT(1), 51 CACHE_MEMORY_IBANK2 = BIT(2), 52 CACHE_MEMORY_IBANK3 = BIT(3), 53 CACHE_MEMORY_DBANK0 = BIT(0), 54 CACHE_MEMORY_DBANK1 = BIT(1), 55 CACHE_MEMORY_DBANK2 = BIT(2), 56 CACHE_MEMORY_DBANK3 = BIT(3), 57 } cache_array_t; 58 59 #define ICACHE_SIZE_16KB CACHE_SIZE_HALF 60 #define ICACHE_SIZE_32KB CACHE_SIZE_FULL 61 #define DCACHE_SIZE_32KB CACHE_SIZE_HALF 62 #define DCACHE_SIZE_64KB CACHE_SIZE_FULL 63 64 typedef enum { 65 CACHE_SIZE_HALF = 0, /*!< 8KB for icache and dcache */ 66 CACHE_SIZE_FULL = 1, /*!< 16KB for icache and dcache */ 67 } cache_size_t; 68 69 typedef enum { 70 CACHE_4WAYS_ASSOC = 0, /*!< 4 way associated cache */ 71 CACHE_8WAYS_ASSOC = 1, /*!< 8 way associated cache */ 72 } cache_ways_t; 73 74 typedef enum { 75 CACHE_LINE_SIZE_16B = 0, /*!< 16 Byte cache line size */ 76 CACHE_LINE_SIZE_32B = 1, /*!< 32 Byte cache line size */ 77 CACHE_LINE_SIZE_64B = 2, /*!< 64 Byte cache line size */ 78 } cache_line_size_t; 79 80 typedef enum { 81 CACHE_AUTOLOAD_POSITIVE = 0, /*!< cache autoload step is positive */ 82 CACHE_AUTOLOAD_NEGATIVE = 1, /*!< cache autoload step is negative */ 83 } cache_autoload_order_t; 84 85 #define CACHE_AUTOLOAD_STEP(i) ((i) - 1) 86 87 typedef enum { 88 CACHE_AUTOLOAD_MISS_TRIGGER = 0, /*!< autoload only triggered by cache miss */ 89 CACHE_AUTOLOAD_HIT_TRIGGER = 1, /*!< autoload only triggered by cache hit */ 90 CACHE_AUTOLOAD_BOTH_TRIGGER = 2, /*!< autoload triggered both by cache miss and hit */ 91 } cache_autoload_trigger_t; 92 93 typedef enum { 94 CACHE_FREEZE_ACK_BUSY = 0, /*!< in this mode, cache ack busy to CPU if a cache miss happens*/ 95 CACHE_FREEZE_ACK_ERROR = 1, /*!< in this mode, cache ack wrong data to CPU and trigger an error if a cache miss happens */ 96 } cache_freeze_mode_t; 97 98 struct cache_mode { 99 uint32_t cache_size; /*!< cache size in byte */ 100 uint16_t cache_line_size; /*!< cache line size in byte */ 101 uint8_t cache_ways; /*!< cache ways, always 4 */ 102 uint8_t ibus; /*!< the cache index, 0 for dcache, 1 for icache */ 103 }; 104 105 struct icache_tag_item { 106 uint32_t valid:1; /*!< the tag item is valid or not */ 107 uint32_t lock:1; /*!< the cache line is locked or not */ 108 uint32_t fifo_cnt:3; /*!< fifo cnt, 0 ~ 3 for 4 ways cache */ 109 uint32_t tag:13; /*!< the tag is the high part of the cache address, however is only 16MB (8MB Ibus + 8MB Dbus) range, and without low part */ 110 uint32_t reserved:14; 111 }; 112 113 struct autoload_config { 114 uint8_t order; /*!< autoload step is positive or negative */ 115 uint8_t trigger; /*!< autoload trigger */ 116 uint8_t ena0; /*!< autoload region0 enable */ 117 uint8_t ena1; /*!< autoload region1 enable */ 118 uint32_t addr0; /*!< autoload region0 start address */ 119 uint32_t size0; /*!< autoload region0 size */ 120 uint32_t addr1; /*!< autoload region1 start address */ 121 uint32_t size1; /*!< autoload region1 size */ 122 }; 123 124 struct tag_group_info { 125 struct cache_mode mode; /*!< cache and cache mode */ 126 uint32_t filter_addr; /*!< the address that used to generate the struct */ 127 uint32_t vaddr_offset; /*!< virtual address offset of the cache ways */ 128 uint32_t tag_addr[MAX_CACHE_WAYS]; /*!< tag memory address, only [0~mode.ways-1] is valid to use */ 129 uint32_t cache_memory_offset[MAX_CACHE_WAYS]; /*!< cache memory address, only [0~mode.ways-1] is valid to use */ 130 }; 131 132 struct lock_config { 133 uint32_t addr; /*!< manual lock address*/ 134 uint16_t size; /*!< manual lock size*/ 135 uint16_t group; /*!< manual lock group, 0 or 1*/ 136 }; 137 138 struct cache_internal_stub_table { 139 uint32_t (* icache_line_size)(void); 140 uint32_t (* icache_addr)(uint32_t addr); 141 uint32_t (* dcache_addr)(uint32_t addr); 142 void (* invalidate_icache_items)(uint32_t addr, uint32_t items); 143 void (* lock_icache_items)(uint32_t addr, uint32_t items); 144 void (* unlock_icache_items)(uint32_t addr, uint32_t items); 145 uint32_t (* suspend_icache_autoload)(void); 146 void (* resume_icache_autoload)(uint32_t autoload); 147 void (* freeze_icache_enable)(cache_freeze_mode_t mode); 148 void (* freeze_icache_disable)(void); 149 int (* op_addr)(uint32_t start_addr, uint32_t size, uint32_t cache_line_size, uint32_t max_sync_num, void(* cache_Iop)(uint32_t, uint32_t)); 150 }; 151 152 /* Defined in the interface file, default value is rom_default_cache_internal_table */ 153 extern const struct cache_internal_stub_table* rom_cache_internal_table_ptr; 154 155 typedef void (* cache_op_start)(void); 156 typedef void (* cache_op_end)(void); 157 158 typedef struct { 159 cache_op_start start; 160 cache_op_end end; 161 } cache_op_cb_t; 162 163 /* Defined in the interface file, default value is NULL */ 164 extern const cache_op_cb_t* rom_cache_op_cb; 165 166 #define ESP_ROM_ERR_INVALID_ARG 1 167 #define MMU_SET_ADDR_ALIGNED_ERROR 2 168 #define MMU_SET_PASE_SIZE_ERROR 3 169 #define MMU_SET_VADDR_OUT_RANGE 4 170 171 #define CACHE_OP_ICACHE_Y 1 172 #define CACHE_OP_ICACHE_N 0 173 174 /** 175 * @brief Initialise cache mmu, mark all entries as invalid. 176 * Please do not call this function in your SDK application. 177 * 178 * @param None 179 * 180 * @return None 181 */ 182 void Cache_MMU_Init(void); 183 184 /** 185 * @brief Set ICache mmu mapping. 186 * Please do not call this function in your SDK application. 187 * 188 * @param uint32_t ext_ram : DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_INVALID for invalid. In 189 * esp32c3, external memory is always flash 190 * 191 * @param uint32_t vaddr : virtual address in CPU address space. 192 * Can be Iram0,Iram1,Irom0,Drom0 and AHB buses address. 193 * Should be aligned by psize. 194 * 195 * @param uint32_t paddr : physical address in external memory. 196 * Should be aligned by psize. 197 * 198 * @param uint32_t psize : page size of ICache, in kilobytes. Should be 64 here. 199 * 200 * @param uint32_t num : pages to be set. 201 * 202 * @param uint32_t fixed : 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page. 203 * 204 * @return uint32_t: error status 205 * 0 : mmu set success 206 * 2 : vaddr or paddr is not aligned 207 * 3 : psize error 208 * 4 : vaddr is out of range 209 */ 210 int Cache_Ibus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, uint32_t psize, uint32_t num, uint32_t fixed); 211 212 /** 213 * @brief Set DCache mmu mapping. 214 * Please do not call this function in your SDK application. 215 * 216 * @param uint32_t ext_ram : DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_INVALID for invalid. In 217 * esp32c3, external memory is always flash 218 * 219 * @param uint32_t vaddr : virtual address in CPU address space. 220 * Can be DRam0, DRam1, DRom0, DPort and AHB buses address. 221 * Should be aligned by psize. 222 * 223 * @param uint32_t paddr : physical address in external memory. 224 * Should be aligned by psize. 225 * 226 * @param uint32_t psize : page size of DCache, in kilobytes. Should be 64 here. 227 * 228 * @param uint32_t num : pages to be set. 229 230 * @param uint32_t fixed : 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page. 231 * 232 * @return uint32_t: error status 233 * 0 : mmu set success 234 * 2 : vaddr or paddr is not aligned 235 * 3 : psize error 236 * 4 : vaddr is out of range 237 */ 238 int Cache_Dbus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, uint32_t psize, uint32_t num, uint32_t fixed); 239 240 /** 241 * @brief Count the pages in the bus room address which map to Flash. 242 * Please do not call this function in your SDK application. 243 * 244 * @param uint32_t bus : the bus to count with. 245 * 246 * @param uint32_t * page0_mapped : value should be initial by user, 0 for not mapped, other for mapped count. 247 * 248 * return uint32_t : the number of pages which map to Flash. 249 */ 250 uint32_t Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped); 251 252 /** 253 * @brief allocate memory to used by ICache. 254 * Please do not call this function in your SDK application. 255 * 256 * @param cache_array_t icache_low : the data array bank used by icache low part. Due to timing constraint, can only be CACHE_MEMORY_INVALID, CACHE_MEMORY_IBANK0 257 * 258 * return none 259 */ 260 void Cache_Occupy_ICache_MEMORY(cache_array_t icache_low); 261 262 /** 263 * @brief Get cache mode of ICache or DCache. 264 * Please do not call this function in your SDK application. 265 * 266 * @param struct cache_mode * mode : the pointer of cache mode struct, caller should set the icache field 267 * 268 * return none 269 */ 270 void Cache_Get_Mode(struct cache_mode * mode); 271 272 /** 273 * @brief Init Cache for ROM boot, including resetting the Icache, initializing Owner, MMU, setting ICache mode, Enabling ICache, unmasking bus. 274 * 275 * @param None 276 * 277 * @return None 278 */ 279 void ROM_Boot_Cache_Init(void); 280 281 /** 282 * @brief Init mmu owner register to make i/d cache use half mmu entries. 283 * 284 * @param None 285 * 286 * @return None 287 */ 288 void Cache_Owner_Init(void); 289 290 /** 291 * @brief Invalidate the cache items for ICache. 292 * Operation will be done CACHE_LINE_SIZE aligned. 293 * If the region is not in ICache addr room, nothing will be done. 294 * Please do not call this function in your SDK application. 295 * 296 * @param uint32_t addr: start address to invalidate 297 * 298 * @param uint32_t items: cache lines to invalidate, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) 299 * 300 * @return None 301 */ 302 void Cache_Invalidate_ICache_Items(uint32_t addr, uint32_t items); 303 304 /** 305 * @brief Invalidate the Cache items in the region from ICache or DCache. 306 * If the region is not in Cache addr room, nothing will be done. 307 * Please do not call this function in your SDK application. 308 * 309 * @param uint32_t addr : invalidated region start address. 310 * 311 * @param uint32_t size : invalidated region size. 312 * 313 * @return 0 for success 314 * 1 for invalid argument 315 */ 316 int Cache_Invalidate_Addr(uint32_t addr, uint32_t size); 317 318 /** 319 * @brief Invalidate all cache items in ICache. 320 * Please do not call this function in your SDK application. 321 * 322 * @param None 323 * 324 * @return None 325 */ 326 void Cache_Invalidate_ICache_All(void); 327 328 /** 329 * @brief Mask all buses through ICache and DCache. 330 * Please do not call this function in your SDK application. 331 * 332 * @param None 333 * 334 * @return None 335 */ 336 void Cache_Mask_All(void); 337 338 /** 339 * @brief Disable ICache access for the cpu. 340 * This operation will make all ICache tag memory invalid, CPU can't access ICache, ICache will keep idle. 341 * Please do not call this function in your SDK application. 342 * 343 * @return uint32_t : auto preload enabled before 344 */ 345 uint32_t Cache_Disable_ICache(void); 346 347 /** 348 * @brief Enable ICache access for the cpu. 349 * Please do not call this function in your SDK application. 350 * 351 * @param uint32_t autoload : ICache will preload then. 352 * 353 * @return None 354 */ 355 void Cache_Enable_ICache(uint32_t autoload); 356 357 /** 358 * @brief Suspend ICache access for the cpu. 359 * The ICache tag memory is still there, CPU can't access ICache, ICache will keep idle. 360 * Please do not change MMU, cache mode or tag memory(tag memory can be changed in some special case). 361 * Please do not call this function in your SDK application. 362 * 363 * @param None 364 * 365 * @return uint32_t : auto preload enabled before 366 */ 367 uint32_t Cache_Suspend_ICache(void); 368 369 /** 370 * @brief Resume ICache access for the cpu. 371 * Please do not call this function in your SDK application. 372 * 373 * @param uint32_t autoload : ICache will preload then. 374 * 375 * @return None 376 */ 377 void Cache_Resume_ICache(uint32_t autoload); 378 379 /** 380 * @brief Get ICache cache line size 381 * 382 * @param None 383 * 384 * @return uint32_t: 16, 32, 64 Byte 385 */ 386 uint32_t Cache_Get_ICache_Line_Size(void); 387 388 /** 389 * @brief Set default mode from boot, 8KB ICache, 16Byte cache line size. 390 * 391 * @param None 392 * 393 * @return None 394 */ 395 void Cache_Set_Default_Mode(void); 396 397 /** 398 * @brief Set default mode from boot, 8KB ICache, 16Byte cache line size. 399 * 400 * @param None 401 * 402 * @return None 403 */ 404 void Cache_Enable_Defalut_ICache_Mode(void); 405 406 /** 407 * @brief Enable freeze for ICache. 408 * Any miss request will be rejected, including cpu miss and preload/autoload miss. 409 * Please do not call this function in your SDK application. 410 * 411 * @param cache_freeze_mode_t mode : 0 for assert busy 1 for assert hit 412 * 413 * @return None 414 */ 415 void Cache_Freeze_ICache_Enable(cache_freeze_mode_t mode); 416 417 /** 418 * @brief Disable freeze for ICache. 419 * Please do not call this function in your SDK application. 420 * 421 * @return None 422 */ 423 void Cache_Freeze_ICache_Disable(void); 424 425 /** 426 * @brief Travel tag memory to run a call back function. 427 * ICache and DCache are suspend when doing this. 428 * The callback will get the parameter tag_group_info, which will include a group of tag memory addresses and cache memory addresses. 429 * Please do not call this function in your SDK application. 430 * 431 * @param struct cache_mode * mode : the cache to check and the cache mode. 432 * 433 * @param uint32_t filter_addr : only the cache lines which may include the filter_address will be returned to the call back function. 434 * 0 for do not filter, all cache lines will be returned. 435 * 436 * @param void (* process)(struct tag_group_info *) : call back function, which may be called many times, a group(the addresses in the group are in the same position in the cache ways) a time. 437 * 438 * @return None 439 */ 440 void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, void (* process)(struct tag_group_info *)); 441 442 /** 443 * @brief Get the virtual address from cache mode, cache tag and the virtual address offset of cache ways. 444 * Please do not call this function in your SDK application. 445 * 446 * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. 447 * 448 * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. 449 * 450 * @param uint32_t addr_offset : the virtual address offset of the cache ways. 451 * 452 * @return uint32_t : the virtual address. 453 */ 454 uint32_t Cache_Get_Virtual_Addr(struct cache_mode *mode, uint32_t tag, uint32_t vaddr_offset); 455 456 /** 457 * @brief Get cache memory block base address. 458 * Please do not call this function in your SDK application. 459 * 460 * @param uint32_t icache : 0 for dcache, other for icache. 461 * 462 * @param uint32_t bank_no : 0 ~ 3 bank. 463 * 464 * @return uint32_t : the cache memory block base address, 0 if the block not used. 465 */ 466 uint32_t Cache_Get_Memory_BaseAddr(uint32_t icache, uint32_t bank_no); 467 468 /** 469 * @brief Get the cache memory address from cache mode, cache memory offset and the virtual address offset of cache ways. 470 * Please do not call this function in your SDK application. 471 * 472 * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. 473 * 474 * @param uint32_t cache_memory_offset : the cache memory offset of the whole cache (ICache or DCache) for the cache line. 475 * 476 * @param uint32_t addr_offset : the virtual address offset of the cache ways. 477 * 478 * @return uint32_t : the virtual address. 479 */ 480 uint32_t Cache_Get_Memory_Addr(struct cache_mode *mode, uint32_t cache_memory_offset, uint32_t vaddr_offset); 481 482 /** 483 * @brief Get the cache memory value by DRAM address. 484 * Please do not call this function in your SDK application. 485 * 486 * @param uint32_t cache_memory_addr : DRAM address for the cache memory, should be 4 byte aligned for IBus address. 487 * 488 * @return uint32_t : the word value of the address. 489 */ 490 uint32_t Cache_Get_Memory_value(uint32_t cache_memory_addr); 491 /** 492 * @} 493 */ 494 495 /** 496 * @brief Get the cache MMU IROM end address. 497 * Please do not call this function in your SDK application. 498 * 499 * @param void 500 * 501 * @return uint32_t : the word value of the address. 502 */ 503 uint32_t Cache_Get_IROM_MMU_End(void); 504 505 /** 506 * @brief Get the cache MMU DROM end address. 507 * Please do not call this function in your SDK application. 508 * 509 * @param void 510 * 511 * @return uint32_t : the word value of the address. 512 */ 513 uint32_t Cache_Get_DROM_MMU_End(void); 514 515 /** 516 * @brief Configure cache MMU page size according to instruction and rodata size 517 * 518 * @param irom_size The instruction cache MMU page size 519 * @param drom_size The rodata data cache MMU page size 520 */ 521 void Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size); 522 523 #ifdef __cplusplus 524 } 525 #endif 526 527 #endif /* _ROM_CACHE_H_ */ 528