You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/11/25 04:48:20 UTC

[incubator-nuttx] branch master updated (ad7e36d -> 1b3005a)

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

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


    from ad7e36d  stm32f7:sdmmc defer invalidate until after DMA completion
     new 4db5016  arch:hostfs: add cache coherence config for semihosting option
     new 1b3005a  arch:cache_invalidate: fix unalign cacheline invalidate

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/Kconfig                       | 10 ++++++
 arch/arm/src/arm/arm_cache.S           | 11 +++++-
 arch/arm/src/armv7-m/arm_cache.c       | 16 +++++++--
 arch/arm/src/armv8-m/arm_cache.c       | 16 +++++++--
 arch/arm/src/common/arm_hostfs.c       | 50 +++++++++++++++++++++++-----
 arch/xtensa/Kconfig                    | 10 ++++++
 arch/xtensa/src/common/xtensa_cache.c  | 61 ++++++++++++++++++++--------------
 arch/xtensa/src/common/xtensa_hostfs.c | 12 +++++++
 8 files changed, 145 insertions(+), 41 deletions(-)

[incubator-nuttx] 01/02: arch:hostfs: add cache coherence config for semihosting option

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4db5016d8385e7129e791b031b6ef944c805c6e9
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Mon Nov 22 19:26:08 2021 +0800

    arch:hostfs: add cache coherence config for semihosting option
    
    N/A
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 arch/arm/Kconfig                       | 10 +++++++
 arch/arm/src/common/arm_hostfs.c       | 50 ++++++++++++++++++++++++++++------
 arch/xtensa/Kconfig                    | 10 +++++++
 arch/xtensa/src/common/xtensa_hostfs.c | 12 ++++++++
 4 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9892328..dd34fbf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -975,6 +975,16 @@ config ARM_SEMIHOSTING_HOSTFS
 		This doesn't support some directory operations like readdir because
 		of the limitations of semihosting mechanism.
 
+if ARM_SEMIHOSTING_HOSTFS
+
+config ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+	bool "Cache coherence in semihosting hostfs"
+	depends on ARCH_DCACHE
+	---help---
+		Flush & Invalidte cache before & after bkpt instruction.
+
+endif
+
 if ARCH_ARMV6M
 source "arch/arm/src/armv6-m/Kconfig"
 endif
diff --git a/arch/arm/src/common/arm_hostfs.c b/arch/arm/src/common/arm_hostfs.c
index d8ad1fa..7200758 100644
--- a/arch/arm/src/common/arm_hostfs.c
+++ b/arch/arm/src/common/arm_hostfs.c
@@ -23,6 +23,7 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <nuttx/cache.h>
 #include <nuttx/fs/hostfs.h>
 
 #include <errno.h>
@@ -49,8 +50,12 @@
  * Private Functions
  ****************************************************************************/
 
-static long host_call(unsigned int nbr, void *parm)
+static long host_call(unsigned int nbr, void *parm, size_t size)
 {
+#ifdef CONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(parm, parm + size);
+#endif
+
   long ret = smh_call(nbr, parm);
   if (ret < 0)
     {
@@ -66,7 +71,7 @@ static long host_call(unsigned int nbr, void *parm)
 
 static ssize_t host_flen(long fd)
 {
-  return host_call(HOST_FLEN, &fd);
+  return host_call(HOST_FLEN, &fd, sizeof(long));
 }
 
 static int host_flags_to_mode(int flags)
@@ -118,13 +123,17 @@ int host_open(const char *pathname, int flags, int mode)
     .len = strlen(pathname),
   };
 
-  return host_call(HOST_OPEN, &open);
+#ifdef CONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(pathname, pathname + open.len + 1);
+#endif
+
+  return host_call(HOST_OPEN, &open, sizeof(open));
 }
 
 int host_close(int fd_)
 {
   long fd = fd_;
-  return host_call(HOST_CLOSE, &fd);
+  return host_call(HOST_CLOSE, &fd, sizeof(long));
 }
 
 ssize_t host_read(int fd, void *buf, size_t count)
@@ -141,7 +150,14 @@ ssize_t host_read(int fd, void *buf, size_t count)
     .count = count,
   };
 
-  ssize_t ret = host_call(HOST_READ, &read);
+  ssize_t ret;
+
+#ifdef CONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+  up_invalidate_dcache(buf, buf + count);
+#endif
+
+  ret = host_call(HOST_READ, &read, sizeof(read));
+
   return ret < 0 ? ret : count - ret;
 }
 
@@ -159,7 +175,13 @@ ssize_t host_write(int fd, const void *buf, size_t count)
     .count = count,
   };
 
-  ssize_t ret = host_call(HOST_WRITE, &write);
+  ssize_t ret;
+
+#ifdef CONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(buf, buf + count);
+#endif
+
+  ret = host_call(HOST_WRITE, &write, sizeof(write));
   return ret < 0 ? ret : count - ret;
 }
 
@@ -189,7 +211,7 @@ off_t host_lseek(int fd, off_t offset, int whence)
         .pos = offset,
       };
 
-      ret = host_call(HOST_SEEK, &seek);
+      ret = host_call(HOST_SEEK, &seek, sizeof(seek));
       if (ret >= 0)
         {
             ret = offset;
@@ -267,7 +289,12 @@ int host_unlink(const char *pathname)
     .pathname_len = strlen(pathname),
   };
 
-  return host_call(HOST_REMOVE, &remove);
+#ifdef CONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(pathname, pathname +
+                  remove.pathname_len + 1);
+#endif
+
+  return host_call(HOST_REMOVE, &remove, sizeof(remove));
 }
 
 int host_mkdir(const char *pathname, mode_t mode)
@@ -296,7 +323,12 @@ int host_rename(const char *oldpath, const char *newpath)
     .newpath_len = strlen(newpath),
   };
 
-  return host_call(HOST_RENAME, &rename);
+#ifdef CONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(oldpath, oldpath + rename.oldpath_len + 1);
+  up_clean_dcache(newpath, newpath + rename.newpath_len + 1);
+#endif
+
+  return host_call(HOST_RENAME, &rename, sizeof(rename));
 }
 
 int host_stat(const char *path, struct stat *buf)
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 402f92f..83268aa 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -220,6 +220,16 @@ config XTENSA_EXTMEM_BSS
 		Adds a section and an attribute that allows to force variables into
 		the external memory.
 
+if CONFIG_FS_HOSTFS
+
+config XTENSA_HOSTFS_CACHE_COHERENCE
+	bool "Cache coherence in semihosting hostfs"
+	depends on ARCH_DCACHE
+	---help---
+		Flush & Invalidte cache before & after sim call.
+
+endif
+
 choice
 	prompt "Toolchain Selection"
 	default XTENSA_TOOLCHAIN_ESP
diff --git a/arch/xtensa/src/common/xtensa_hostfs.c b/arch/xtensa/src/common/xtensa_hostfs.c
index fba8d31..20e62df 100644
--- a/arch/xtensa/src/common/xtensa_hostfs.c
+++ b/arch/xtensa/src/common/xtensa_hostfs.c
@@ -23,6 +23,7 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <nuttx/cache.h>
 #include <nuttx/fs/hostfs.h>
 
 #include <arch/simcall.h>
@@ -96,6 +97,9 @@ int host_open(const char *pathname, int flags, int mode)
       simcall_flags |= SIMCALL_O_EXCL;
     }
 
+#ifdef CONFIG_XTENSA_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(pathname, pathname + strlen(pathname) + 1);
+#endif
   return host_call(SIMCALL_SYS_OPEN, (int)pathname, simcall_flags, mode);
 }
 
@@ -106,11 +110,19 @@ int host_close(int fd)
 
 ssize_t host_read(int fd, void *buf, size_t count)
 {
+#ifdef CONFIG_XTENSA_HOSTFS_CACHE_COHERENCE
+  up_invalidate_dcache(buf, buf + count);
+#endif
+
   return host_call(SIMCALL_SYS_READ, fd, (int)buf, count);
 }
 
 ssize_t host_write(int fd, const void *buf, size_t count)
 {
+#ifdef CONFIG_XTENSA_HOSTFS_CACHE_COHERENCE
+  up_clean_dcache(buf, buf + count);
+#endif
+
   return host_call(SIMCALL_SYS_WRITE, fd, (int)buf, count);
 }
 

[incubator-nuttx] 02/02: arch:cache_invalidate: fix unalign cacheline invalidate

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1b3005accf0bea1178a1b288f80d84b4008008c5
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Tue Nov 23 20:27:32 2021 +0800

    arch:cache_invalidate: fix unalign cacheline invalidate
    
    Only invalidate may corrupt data in unalign start and end.
    Use writeback and invalidate instead.
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 arch/arm/src/arm/arm_cache.S          | 11 ++++++-
 arch/arm/src/armv7-m/arm_cache.c      | 16 +++++++--
 arch/arm/src/armv8-m/arm_cache.c      | 16 +++++++--
 arch/xtensa/src/common/xtensa_cache.c | 61 +++++++++++++++++++++--------------
 4 files changed, 72 insertions(+), 32 deletions(-)

diff --git a/arch/arm/src/arm/arm_cache.S b/arch/arm/src/arm/arm_cache.S
index 92c32d9..53dd580 100644
--- a/arch/arm/src/arm/arm_cache.S
+++ b/arch/arm/src/arm/arm_cache.S
@@ -123,7 +123,16 @@ up_invalidate_icache_all:
 	.type	up_invalidate_dcache, function
 
 up_invalidate_dcache:
-	bic		r0, r0, #CACHE_DLINESIZE - 1
+	mov		r2, #CACHE_DLINESIZE - 1
+
+	tst		r0, r2
+	bic		r0, r0, r2			/* R0=aligned start address */
+	mcrne		p15, 0, r0, c7, c14, 1		/* Clean & invalidate D entry */
+
+	tst		r1, r2
+	bic		r1, r1, r2			/* R1=aligned end address */
+	mcrne		p15, 0, r1, c7, c14, 1		/* Clean & invalidate D entry */
+
 1:	mcr		p15, 0, r0, c7, c6, 1		/* Invalidate D entry */
 	add		r0, r0, #CACHE_DLINESIZE
 	cmp		r0, r1
diff --git a/arch/arm/src/armv7-m/arm_cache.c b/arch/arm/src/armv7-m/arm_cache.c
index f1629bb..f640286 100644
--- a/arch/arm/src/armv7-m/arm_cache.c
+++ b/arch/arm/src/armv7-m/arm_cache.c
@@ -404,10 +404,16 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
    *   (ssize - 1)  = 0x007f : Mask of the set field
    */
 
-  start &= ~(ssize - 1);
   ARM_DSB();
 
-  do
+  if (start & (ssize - 1))
+    {
+      start &= ~(ssize - 1);
+      putreg32(start, NVIC_DCCIMVAC);
+      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
@@ -422,7 +428,11 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
 
       start += ssize;
     }
-  while (start < end);
+
+  if (start < end)
+    {
+      putreg32(start, NVIC_DCCIMVAC);
+    }
 
   ARM_DSB();
   ARM_ISB();
diff --git a/arch/arm/src/armv8-m/arm_cache.c b/arch/arm/src/armv8-m/arm_cache.c
index 56b963e..4b0e67d 100644
--- a/arch/arm/src/armv8-m/arm_cache.c
+++ b/arch/arm/src/armv8-m/arm_cache.c
@@ -404,10 +404,16 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
    *   (ssize - 1)  = 0x007f : Mask of the set field
    */
 
-  start &= ~(ssize - 1);
   ARM_DSB();
 
-  do
+  if (start & (ssize - 1))
+    {
+      start &= ~(ssize - 1);
+      putreg32(start, NVIC_DCCIMVAC);
+      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
@@ -422,7 +428,11 @@ void up_invalidate_dcache(uintptr_t start, uintptr_t end)
 
       start += ssize;
     }
-  while (start < end);
+
+  if (start < end)
+    {
+      putreg32(start, NVIC_DCCIMVAC);
+    }
 
   ARM_DSB();
   ARM_ISB();
diff --git a/arch/xtensa/src/common/xtensa_cache.c b/arch/xtensa/src/common/xtensa_cache.c
index 5a0b123..3ad30ce 100644
--- a/arch/xtensa/src/common/xtensa_cache.c
+++ b/arch/xtensa/src/common/xtensa_cache.c
@@ -116,11 +116,11 @@ void up_invalidate_icache(uintptr_t start, uintptr_t end)
 {
   /* align to XCHAL_ICACHE_LINESIZE */
 
-  uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1));
+  start &= ~(XCHAL_ICACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_ICACHE_LINESIZE)
+  for (; start < end; start += XCHAL_ICACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("ihi %0, 0\n" : : "r"(addr));
+      __asm__ __volatile__ ("ihi %0, 0\n" : : "r"(start));
     }
 
   __asm__ __volatile__ ("isync\n");
@@ -175,11 +175,11 @@ void up_lock_icache(uintptr_t start, uintptr_t end)
 {
   /* align to XCHAL_ICACHE_LINESIZE */
 
-  uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1));
+  start &= ~(XCHAL_ICACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_ICACHE_LINESIZE)
+  for (; start < end; start += XCHAL_ICACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("ipfl %0, 0\n": : "r"(addr));
+      __asm__ __volatile__ ("ipfl %0, 0\n": : "r"(start));
     };
 
   __asm__ __volatile__ ("isync\n");
@@ -206,11 +206,11 @@ void up_unlock_icache(uintptr_t start, uintptr_t end)
 {
   /* align to XCHAL_ICACHE_LINESIZE */
 
-  uint32_t addr = start - (start & (XCHAL_ICACHE_LINESIZE - 1));
+  start &= ~(XCHAL_ICACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_ICACHE_LINESIZE)
+  for (; start < end; start += XCHAL_ICACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("ihu %0, 0\n": : "r"(addr));
+      __asm__ __volatile__ ("ihu %0, 0\n": : "r"(start));
     };
 
   __asm__ __volatile__ ("isync\n");
@@ -335,13 +335,24 @@ void up_disable_dcache(void)
 #ifdef CONFIG_XTENSA_DCACHE
 void up_invalidate_dcache(uintptr_t start, uintptr_t end)
 {
-  /* Align to XCHAL_DCACHE_LINESIZE */
+  if (start & (XCHAL_DCACHE_LINESIZE - 1))
+    {
+      /* Align to XCHAL_DCACHE_LINESIZE */
+
+      start &= ~(XCHAL_DCACHE_LINESIZE - 1);
+      __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start));
+      start += XCHAL_DCACHE_LINESIZE;
+    }
 
-  uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1));
+  for (; start + XCHAL_DCACHE_LINESIZE <= end;
+       start += XCHAL_DCACHE_LINESIZE)
+    {
+      __asm__ __volatile__ ("dhi %0, 0\n" : : "r"(start));
+    }
 
-  for (; addr < end; addr += XCHAL_DCACHE_LINESIZE)
+  if (start != end)
     {
-      __asm__ __volatile__ ("dhi %0, 0\n" : : "r"(addr));
+      __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start));
     }
 
   __asm__ __volatile__ ("dsync\n");
@@ -405,11 +416,11 @@ void up_clean_dcache(uintptr_t start, uintptr_t end)
 {
   /* Align to XCHAL_DCACHE_SIZE */
 
-  uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1));
+  start &= ~(XCHAL_DCACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_DCACHE_LINESIZE)
+  for (; start < end; start += XCHAL_DCACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("dhwb %0, 0\n" : : "r"(addr));
+      __asm__ __volatile__ ("dhwb %0, 0\n" : : "r"(start));
     }
 
   __asm__ __volatile__ ("dsync\n");
@@ -482,11 +493,11 @@ void up_flush_dcache(uintptr_t start, uintptr_t end)
 {
   /* Align to XCHAL_DCACHE_LINESIZE */
 
-  uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1));
+  start &= ~(XCHAL_DCACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_DCACHE_LINESIZE)
+  for (; start < end; start += XCHAL_DCACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(addr));
+      __asm__ __volatile__ ("dhwbi %0, 0\n" : : "r"(start));
     }
 
   __asm__ __volatile__ ("dsync\n");
@@ -549,11 +560,11 @@ void up_lock_dcache(uintptr_t start, uintptr_t end)
 {
   /* align to XCHAL_DCACHE_LINESIZE */
 
-  uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1));
+  start &= ~(XCHAL_DCACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_DCACHE_LINESIZE)
+  for (; start < end; start += XCHAL_DCACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("dpfl %0, 0\n": : "r"(addr));
+      __asm__ __volatile__ ("dpfl %0, 0\n": : "r"(start));
     };
 
   __asm__ __volatile__ ("dsync\n");
@@ -580,11 +591,11 @@ void up_unlock_dcache(uintptr_t start, uintptr_t end)
 {
   /* align to XCHAL_DCACHE_LINESIZE */
 
-  uint32_t addr = start - (start & (XCHAL_DCACHE_LINESIZE - 1));
+  start &= ~(XCHAL_DCACHE_LINESIZE - 1);
 
-  for (; addr < end; addr += XCHAL_DCACHE_LINESIZE)
+  for (; start < end; start += XCHAL_DCACHE_LINESIZE)
     {
-      __asm__ __volatile__ ("dhu %0, 0\n": : "r"(addr));
+      __asm__ __volatile__ ("dhu %0, 0\n": : "r"(start));
     };
 
   __asm__ __volatile__ ("dsync\n");