You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/09/30 06:07:51 UTC

[incubator-nuttx] branch master updated: arch/armv[7|8]-m: Implement up_invalidate_icache

This is an automated email from the ASF dual-hosted git repository.

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 53dcddc9e3 arch/armv[7|8]-m: Implement up_invalidate_icache
53dcddc9e3 is described below

commit 53dcddc9e3b1dfe1e0dc0750ad03c144fd71057f
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Thu Sep 29 03:39:30 2022 +0800

    arch/armv[7|8]-m: Implement up_invalidate_icache
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 arch/arm/src/armv7-m/arm_cache.c | 74 +++++++++++++++++++++++++++++++++++++++-
 arch/arm/src/armv8-m/arm_cache.c | 74 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/arch/arm/src/armv7-m/arm_cache.c b/arch/arm/src/armv7-m/arm_cache.c
index 86fb901cbd..6d74b8d71d 100644
--- a/arch/arm/src/armv7-m/arm_cache.c
+++ b/arch/arm/src/armv7-m/arm_cache.c
@@ -176,6 +176,78 @@ void up_disable_icache(void)
 }
 #endif
 
+/****************************************************************************
+ * Name: up_invalidate_icache
+ *
+ * Description:
+ *   Invalidate the instruction cache within the specified region.
+ *
+ * Input Parameters:
+ *   start - virtual start address of region
+ *   end   - virtual end address of region + 1
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARMV7M_ICACHE
+void up_invalidate_icache(uintptr_t start, uintptr_t end)
+{
+  uint32_t ccsidr;
+  uint32_t sshift;
+  uint32_t ssize;
+
+  /* Get the characteristics of the I-Cache */
+
+  ccsidr = getreg32(NVIC_CCSIDR);
+  sshift = CCSIDR_LSSHIFT(ccsidr) + 4;   /* log2(cache-line-size-in-bytes) */
+
+  /* Invalidate the I-Cache containing this range of addresses */
+
+  ssize  = (1 << sshift);
+
+  /* Round down the start address to the nearest cache line boundary.
+   *
+   *   sshift = 5      : Offset to the beginning of the set field
+   *   (ssize - 1)  = 0x007f : Mask of the set field
+   */
+
+  ARM_DSB();
+
+  if ((start & (ssize - 1)) != 0)
+    {
+      start &= ~(ssize - 1);
+      putreg32(start, NVIC_ICIMVAU);
+      start += ssize;
+    }
+
+  while (start + ssize <= end)
+    {
+      /* The below store causes the cache to check its directory and
+       * determine if this address is contained in the cache. If so, it
+       * invalidate that cache line. Only the cache way containing the
+       * address is invalidated. If the address is not in the cache, then
+       * nothing is invalidated.
+       */
+
+      putreg32(start, NVIC_ICIMVAU);
+
+      /* Increment the address by the size of one cache line. */
+
+      start += ssize;
+    }
+
+  if (start < end)
+    {
+      putreg32(start, NVIC_ICIMVAU);
+    }
+
+  ARM_DSB();
+  ARM_ISB();
+}
+#endif /* CONFIG_ARMV7M_ICACHE */
+
 /****************************************************************************
  * Name: up_invalidate_icache_all
  *
@@ -406,7 +478,7 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
 
   ARM_DSB();
 
-  if (start & (ssize - 1))
+  if ((start & (ssize - 1)) != 0)
     {
       start &= ~(ssize - 1);
       putreg32(start, NVIC_DCCIMVAC);
diff --git a/arch/arm/src/armv8-m/arm_cache.c b/arch/arm/src/armv8-m/arm_cache.c
index 4b2b549787..dde0d71daa 100644
--- a/arch/arm/src/armv8-m/arm_cache.c
+++ b/arch/arm/src/armv8-m/arm_cache.c
@@ -176,6 +176,78 @@ void up_disable_icache(void)
 }
 #endif
 
+/****************************************************************************
+ * Name: up_invalidate_icache
+ *
+ * Description:
+ *   Invalidate the instruction cache within the specified region.
+ *
+ * Input Parameters:
+ *   start - virtual start address of region
+ *   end   - virtual end address of region + 1
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARMV8M_ICACHE
+void up_invalidate_icache(uintptr_t start, uintptr_t end)
+{
+  uint32_t ccsidr;
+  uint32_t sshift;
+  uint32_t ssize;
+
+  /* Get the characteristics of the I-Cache */
+
+  ccsidr = getreg32(NVIC_CCSIDR);
+  sshift = CCSIDR_LSSHIFT(ccsidr) + 4;   /* log2(cache-line-size-in-bytes) */
+
+  /* Invalidate the I-Cache containing this range of addresses */
+
+  ssize  = (1 << sshift);
+
+  /* Round down the start address to the nearest cache line boundary.
+   *
+   *   sshift = 5      : Offset to the beginning of the set field
+   *   (ssize - 1)  = 0x007f : Mask of the set field
+   */
+
+  ARM_DSB();
+
+  if ((start & (ssize - 1)) != 0)
+    {
+      start &= ~(ssize - 1);
+      putreg32(start, NVIC_ICIMVAU);
+      start += ssize;
+    }
+
+  while (start + ssize <= end)
+    {
+      /* The below store causes the cache to check its directory and
+       * determine if this address is contained in the cache. If so, it
+       * invalidate that cache line. Only the cache way containing the
+       * address is invalidated. If the address is not in the cache, then
+       * nothing is invalidated.
+       */
+
+      putreg32(start, NVIC_ICIMVAU);
+
+      /* Increment the address by the size of one cache line. */
+
+      start += ssize;
+    }
+
+  if (start < end)
+    {
+      putreg32(start, NVIC_ICIMVAU);
+    }
+
+  ARM_DSB();
+  ARM_ISB();
+}
+#endif /* CONFIG_ARMV8M_ICACHE */
+
 /****************************************************************************
  * Name: up_invalidate_icache_all
  *
@@ -406,7 +478,7 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
 
   ARM_DSB();
 
-  if (start & (ssize - 1))
+  if ((start & (ssize - 1)) != 0)
     {
       start &= ~(ssize - 1);
       putreg32(start, NVIC_DCCIMVAC);