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);