summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-03-29 13:09:22 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-03-29 13:09:22 -0600
commit72adecb9057d7015c5d1729ec3752926284bab8c (patch)
tree32d43aee83799c9f1ad28a9a1c18bde492c553d7 /nuttx
parent6c2f4007dc9fc482d650a956ef13959f502d327b (diff)
downloadpx4-nuttx-72adecb9057d7015c5d1729ec3752926284bab8c.tar.gz
px4-nuttx-72adecb9057d7015c5d1729ec3752926284bab8c.tar.bz2
px4-nuttx-72adecb9057d7015c5d1729ec3752926284bab8c.zip
SAMV7/Cortex-M7: Add support for write through D-Cache. SAMV7 Ethernet look like it needs this
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/arm/src/armv7-m/Kconfig5
-rw-r--r--nuttx/arch/arm/src/armv7-m/arch_clean_dcache.c4
-rw-r--r--nuttx/arch/arm/src/armv7-m/arch_clean_dcache_all.c4
-rw-r--r--nuttx/arch/arm/src/armv7-m/arch_flush_dcache.c4
-rw-r--r--nuttx/arch/arm/src/armv7-m/arch_flush_dcache_all.c4
-rw-r--r--nuttx/arch/arm/src/armv7-m/cache.h49
-rw-r--r--nuttx/arch/arm/src/samv7/Kconfig9
-rw-r--r--nuttx/arch/arm/src/samv7/Make.defs4
-rw-r--r--nuttx/arch/arm/src/samv7/sam_start.c1
-rw-r--r--nuttx/configs/samv71-xult/README.txt16
10 files changed, 86 insertions, 14 deletions
diff --git a/nuttx/arch/arm/src/armv7-m/Kconfig b/nuttx/arch/arm/src/armv7-m/Kconfig
index df4b15200..b4fd21f5e 100644
--- a/nuttx/arch/arm/src/armv7-m/Kconfig
+++ b/nuttx/arch/arm/src/armv7-m/Kconfig
@@ -23,6 +23,11 @@ config ARMV7M_DCACHE
default n
depends on ARMV7M_HAVE_DCACHE
+config ARMV7M_DCACHE_WRITETHROUGH
+ bool "D-Cache Write-Through"
+ default n
+ depends on ARMV7M_DCACHE
+
config ARMV7M_HAVE_ITCM
bool
default n
diff --git a/nuttx/arch/arm/src/armv7-m/arch_clean_dcache.c b/nuttx/arch/arm/src/armv7-m/arch_clean_dcache.c
index 7813e0cc3..735623b4c 100644
--- a/nuttx/arch/arm/src/armv7-m/arch_clean_dcache.c
+++ b/nuttx/arch/arm/src/armv7-m/arch_clean_dcache.c
@@ -46,7 +46,7 @@
#include "cache.h"
-#ifdef CONFIG_ARMV7M_DCACHE
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
/****************************************************************************
* Pre-processor Definitions
@@ -146,4 +146,4 @@ void arch_clean_dcache(uintptr_t start, uintptr_t end)
ARM_ISB();
}
-#endif /* CONFIG_ARMV7M_DCACHE */
+#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
diff --git a/nuttx/arch/arm/src/armv7-m/arch_clean_dcache_all.c b/nuttx/arch/arm/src/armv7-m/arch_clean_dcache_all.c
index f3d3ef602..296780bee 100644
--- a/nuttx/arch/arm/src/armv7-m/arch_clean_dcache_all.c
+++ b/nuttx/arch/arm/src/armv7-m/arch_clean_dcache_all.c
@@ -46,7 +46,7 @@
#include "cache.h"
-#ifdef CONFIG_ARMV7M_DCACHE
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
/****************************************************************************
* Pre-processor Definitions
@@ -126,4 +126,4 @@ void arch_clean_dcache_all(void)
ARM_ISB();
}
-#endif /* CONFIG_ARMV7M_DCACHE */
+#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
diff --git a/nuttx/arch/arm/src/armv7-m/arch_flush_dcache.c b/nuttx/arch/arm/src/armv7-m/arch_flush_dcache.c
index 07fbae624..c884eec04 100644
--- a/nuttx/arch/arm/src/armv7-m/arch_flush_dcache.c
+++ b/nuttx/arch/arm/src/armv7-m/arch_flush_dcache.c
@@ -46,7 +46,7 @@
#include "cache.h"
-#ifdef CONFIG_ARMV7M_DCACHE
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
/****************************************************************************
* Pre-processor Definitions
@@ -146,4 +146,4 @@ void arch_flush_dcache(uintptr_t start, uintptr_t end)
ARM_ISB();
}
-#endif /* CONFIG_ARMV7M_DCACHE */
+#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
diff --git a/nuttx/arch/arm/src/armv7-m/arch_flush_dcache_all.c b/nuttx/arch/arm/src/armv7-m/arch_flush_dcache_all.c
index c25e66512..33f80b85b 100644
--- a/nuttx/arch/arm/src/armv7-m/arch_flush_dcache_all.c
+++ b/nuttx/arch/arm/src/armv7-m/arch_flush_dcache_all.c
@@ -46,7 +46,7 @@
#include "cache.h"
-#ifdef CONFIG_ARMV7M_DCACHE
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
/****************************************************************************
* Pre-processor Definitions
@@ -125,4 +125,4 @@ void arch_flush_dcache_all(void)
ARM_ISB();
}
-#endif /* CONFIG_ARMV7M_DCACHE */
+#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
diff --git a/nuttx/arch/arm/src/armv7-m/cache.h b/nuttx/arch/arm/src/armv7-m/cache.h
index 333c3ed5f..16fc0bdf2 100644
--- a/nuttx/arch/arm/src/armv7-m/cache.h
+++ b/nuttx/arch/arm/src/armv7-m/cache.h
@@ -212,6 +212,31 @@ static inline void arch_invalidate_icache_all(void)
}
/****************************************************************************
+ * Name: arch_dcache_writethrough
+ *
+ * Description:
+ * Configure the D-Cache for Write-Through operation.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ARMV7M_DCACHE) && defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
+static inline void arch_dcache_writethrough(void)
+{
+ uint32_t regval = getreg32(NVIC_CACR);
+ regval |= NVIC_CACR_FORCEWT;
+ putreg32(regval, NVIC_CACR);
+}
+#else
+# define arch_dcache_writethrough()
+#endif
+
+/****************************************************************************
* Public Variables
****************************************************************************/
@@ -322,6 +347,9 @@ void arch_invalidate_dcache_all(void);
* Clean the data cache within the specified region by flushing the
* contents of the data cache to memory.
*
+ * NOTE: This operation is un-necessary if the DCACHE is configured in
+ * write-through mode.
+ *
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
@@ -336,7 +364,7 @@ void arch_invalidate_dcache_all(void);
*
****************************************************************************/
-#ifdef CONFIG_ARMV7M_DCACHE
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
void arch_clean_dcache(uintptr_t start, uintptr_t end);
#else
# define arch_clean_dcache(s,e)
@@ -349,6 +377,9 @@ void arch_clean_dcache(uintptr_t start, uintptr_t end);
* Clean the entire data cache within the specified region by flushing the
* contents of the data cache to memory.
*
+ * NOTE: This operation is un-necessary if the DCACHE is configured in
+ * write-through mode.
+ *
* Input Parameters:
* None
*
@@ -362,7 +393,7 @@ void arch_clean_dcache(uintptr_t start, uintptr_t end);
*
****************************************************************************/
-#ifdef CONFIG_ARMV7M_DCACHE
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
void arch_clean_dcache_all(void);
#else
# define arch_clean_dcache_all()
@@ -375,6 +406,9 @@ void arch_clean_dcache_all(void);
* Flush the data cache within the specified region by cleaning and
* invalidating the D cache.
*
+ * NOTE: If DCACHE write-through is configured, then this operation is the
+ * same as arch_invalidate_cache().
+ *
* Input Parameters:
* start - virtual start address of region
* end - virtual end address of region + 1
@@ -390,7 +424,11 @@ void arch_clean_dcache_all(void);
****************************************************************************/
#ifdef CONFIG_ARMV7M_DCACHE
+#ifdef CONFIG_ARMV7M_DCACHE_WRITETHROUGH
+# define arch_flush_dcache(s,e) arch_invalidate_dcache(s,e)
+#else
void arch_flush_dcache(uintptr_t start, uintptr_t end);
+#endif
#else
# define arch_flush_dcache(s,e)
#endif
@@ -401,6 +439,9 @@ void arch_flush_dcache(uintptr_t start, uintptr_t end);
* Description:
* Flush the entire data cache by cleaning and invalidating the D cache.
*
+ * NOTE: If DCACHE write-through is configured, then this operation is the
+ * same as arch_invalidate_cache_all().
+ *
* Input Parameters:
* None
*
@@ -415,7 +456,11 @@ void arch_flush_dcache(uintptr_t start, uintptr_t end);
****************************************************************************/
#ifdef CONFIG_ARMV7M_DCACHE
+#ifdef CONFIG_ARMV7M_DCACHE_WRITETHROUGH
+# define arch_flush_dcache_all() arch_invalidate_dcache_all()
+#else
void arch_flush_dcache_all(void);
+#endif
#else
# define arch_flush_dcache_all()
#endif
diff --git a/nuttx/arch/arm/src/samv7/Kconfig b/nuttx/arch/arm/src/samv7/Kconfig
index e761bd355..41e40b5df 100644
--- a/nuttx/arch/arm/src/samv7/Kconfig
+++ b/nuttx/arch/arm/src/samv7/Kconfig
@@ -117,6 +117,15 @@ config SAMV7_HAVE_EBI
config SAMV7_EMAC
bool
default n
+ select ARMV7M_DCACHE_WRITETHROUGH if ARMV7M_DCACHE
+ ---help---
+ NOTE that write-through caching is automatically selected. This is
+ to work around issues with the RX and TX descriptors with are 8-bits
+ in size. But the D-Cache cache line size is 32-bytes. That means
+ that you cannot reload, clean or invalidate a descriptor without also
+ effecting three neighboring desciptors. Setting write through mode
+ eliminates the need for cleaning. If only reloading and invalidating
+ are done, then there is no problem.
config SAMV7_HSMCI
bool
diff --git a/nuttx/arch/arm/src/samv7/Make.defs b/nuttx/arch/arm/src/samv7/Make.defs
index c0db38517..24ca04882 100644
--- a/nuttx/arch/arm/src/samv7/Make.defs
+++ b/nuttx/arch/arm/src/samv7/Make.defs
@@ -66,9 +66,11 @@ endif
ifeq ($(CONFIG_ARMV7M_DCACHE),y)
CMN_CSRCS += arch_enable_dcache.c arch_disable_dcache.c
+CMN_CSRCS += arch_invalidate_dcache.c arch_invalidate_dcache_all.c
+ifneq ($(CONFIG_ARMV7M_DCACHE_WRITETHROUGH),y)
CMN_CSRCS += arch_clean_dcache.c arch_clean_dcache_all.c
CMN_CSRCS += arch_flush_dcache.c arch_flush_dcache_all.c
-CMN_CSRCS += arch_invalidate_dcache.c arch_invalidate_dcache_all.c
+endif
endif
ifeq ($(CONFIG_ARCH_FPU),y)
diff --git a/nuttx/arch/arm/src/samv7/sam_start.c b/nuttx/arch/arm/src/samv7/sam_start.c
index 0892a0e11..7649c9d46 100644
--- a/nuttx/arch/arm/src/samv7/sam_start.c
+++ b/nuttx/arch/arm/src/samv7/sam_start.c
@@ -380,6 +380,7 @@ void __start(void)
/* Enable I- and D-Caches */
+ arch_dcache_writethrough();
arch_enable_icache();
arch_enable_dcache();
diff --git a/nuttx/configs/samv71-xult/README.txt b/nuttx/configs/samv71-xult/README.txt
index ba23c160e..0efaff880 100644
--- a/nuttx/configs/samv71-xult/README.txt
+++ b/nuttx/configs/samv71-xult/README.txt
@@ -105,6 +105,12 @@ The BASIC nsh configuration is fully function (as desribed below under
At -O2, many packets can be exchanged but eventually there is a
hardfault, presumably because of a misdirected DMA.
+ I have no hard evidence, but I believe that the nature of the problem
+ related to fact that each descriptor in the arrays are 8-bytes each,
+ but cache operations are performed on 32-byte memory chunks. So it is
+ impossible to clean or invalidate a single descriptor without also
+ cleaning or invalidaing adjacent descriptors.
+
7. The USBHS device controller driver (DCD) is complete but non-functional.
At this point, work has stopped because I am stuck. The problem is that
bus events are not occurring: Nothing is detected by the USBHS when the
@@ -117,9 +123,7 @@ The BASIC nsh configuration is fully function (as desribed below under
sample code and study of the data sheet, but I have not found the key to
solving this.
- - I need to try this as -O2 optimization as well.
-
-Serial Console
++nmnmSerial Console
==============
The SAMV71-XULT has no on-board RS-232 drivers so it will be necessary to
@@ -767,6 +771,12 @@ NOTES:
System Type -> Toolchain:
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : GNU ARM EABI toolchain
+ NOTE: As of this writing, there are issues with using this tool at
+ the -Os level of optimization. This has not been proven to be a
+ compiler issue (as least not one that might not be fixed with a
+ well placed volatile qualifier). However, in any event, it is
+ recommend that you use not more that -O2 optimization.
+
Configuration sub-directories
-----------------------------