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