1/* 2 * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7#include "sdkconfig.h" 8#include "esp_bit_defs.h" 9#include "soc/extmem_reg.h" 10 11/** 12 * @brief Write back the cache items of DCache, enable cache freeze during writeback. 13 * Operation will be done CACHE_LINE_SIZE aligned. 14 * If the region is not in DCache addr room, nothing will be done. 15 * Please do not call this function in your SDK application. 16 * @param uint32_t addr: start address to write back 17 * @param uint32_t items: cache lines to invalidate, items * cache_line_size should 18 * not exceed the bus address size(4MB) 19 * 20 * void cache_writeback_items_freeze(uint32_t addr, uint32_t items) 21*/ 22 23/******************************************************************************* 24 25This function is a cache write-back function that works around the following 26hardware errata on the ESP32-S3: 27 28- Core X manually triggers (via the EXTMEM_DCACHE_SYNC_CTRL_REG register) the 29write-back of one or more cache lines. 30- While the write-back is in progress, there are two scenarios that may cause 31cache hit error. 32 - Core X enters the interrupt handler and access the same cache line 33 being written back. 34 - Core Y access the same cache line being written back. 35 36To workaround this errata, the following steps must be taken when manually 37triggering a cache write-back: 38 39- Core X must disable interrupts so that it cannot be preempted 40- Core X must freeze the cache (via the EXTMEM_DCACHE_FREEZE_REG register) to 41prevent Core Y from accessing the same cache lines that are about to be written 42back. 43- Core X now triggers the cache write-back. During the write-back... 44 - If Core Y attempts the access any address in the cache region, Core Y will 45 busy wait until the cache is unfrozen. 46 - Core X must ensure that it does not access any address in the cache region, 47 otherwise Core X will busy wait thus causing a deadlock. 48- After the write-back is complete, Core X unfreezes the cache, and reenables 49interrupts. 50 51Notes: 52 53- Please do not modify this function, it must strictly follow the current execution 54sequence, otherwise it may cause unexpected errors. 55- This function is written in assmebly to ensure that the function itself never 56accesses any cache address while the cache is frozen. Unexpected cache access 57could occur if... 58 - the function triggers an window overflow onto a stack placed in PSRAM. 59 Thus, we only use two window panes (a0 to a8) in this function and trigger 60 all window overflows before freezing the cache. 61 - the function accesses literals/read-only variables placed in Flash. 62 63*******************************************************************************/ 64 65 .align 4 66 /* 67 Create dedicated literal pool for this function. Mostly used to store out 68 of range movi transformations. 69 */ 70 .literal_position 71 .global cache_writeback_items_freeze 72 .type cache_writeback_items_freeze, @function 73cache_writeback_items_freeze: 74 entry sp, 32 75 76 /* REG_WRITE(EXTMEM_DCACHE_SYNC_ADDR_REG, addr); */ 77 movi a4, EXTMEM_DCACHE_SYNC_ADDR_REG 78 s32i a2, a4, 0 79 /* REG_WRITE(EXTMEM_DCACHE_SYNC_SIZE_REG, items); */ 80 movi a4, EXTMEM_DCACHE_SYNC_SIZE_REG 81 s32i a3, a4, 0 82 memw /* About to freeze the cache. Ensure all previous memory R/W are completed */ 83 84 movi a2, EXTMEM_DCACHE_FREEZE_REG 85 movi a3, EXTMEM_DCACHE_SYNC_CTRL_REG 86 87 /* 88 REG_CLR_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_MODE); 89 REG_SET_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_ENA); 90 */ 91 l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ 92 movi a5, ~(EXTMEM_DCACHE_FREEZE_MODE_M) 93 and a4, a4, a5 94 movi a5, EXTMEM_DCACHE_FREEZE_ENA_M 95 or a4, a4, a5 96 s32i a4, a2, 0 /* *(EXTMEM_DCACHE_FREEZE_REG) = a4 */ 97 98 /* while (!REG_GET_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_DONE)); */ 99 movi a5, EXTMEM_DCACHE_FREEZE_DONE_M 100_wait_freeze_done: 101 l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ 102 memw 103 bnone a4, a5, _wait_freeze_done 104 105 /* REG_SET_BIT(EXTMEM_DCACHE_SYNC_CTRL_REG, EXTMEM_DCACHE_WRITEBACK_ENA); */ 106 l32i a4, a3, 0 /* a4 = *(EXTMEM_DCACHE_SYNC_CTRL_REG) */ 107 movi a5, EXTMEM_DCACHE_WRITEBACK_ENA_M 108 or a4, a4, a5 109 s32i a4, a3, 0 /* *(EXTMEM_DCACHE_SYNC_CTRL_REG) = a4 */ 110 111 /* while(!REG_GET_BIT(EXTMEM_DCACHE_SYNC_CTRL_REG, EXTMEM_DCACHE_SYNC_DONE)); */ 112 movi a5, EXTMEM_DCACHE_SYNC_DONE_M 113_wait_writeback_done: 114 l32i a4, a3, 0 /* a4 = *(EXTMEM_DCACHE_SYNC_CTRL_REG) */ 115 memw 116 bnone a4, a5, _wait_writeback_done 117 118 /* REG_CLR_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_ENA); */ 119 l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ 120 movi a5, ~(EXTMEM_DCACHE_FREEZE_ENA_M) 121 and a4, a4, a5 122 s32i a4, a2, 0 /* *(EXTMEM_DCACHE_FREEZE_REG) = a4 */ 123 124 /* while (REG_GET_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_DONE)); */ 125 movi a5, EXTMEM_DCACHE_FREEZE_DONE_M 126_wait_unfreeze_done: 127 l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ 128 memw 129 bany a4, a5, _wait_unfreeze_done 130 131 retw 132 .size cache_writeback_items_freeze, . - cache_writeback_items_freeze 133