esp_rom_cache_writeback_esp32s3.S 5.1 KB

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