diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-03-29 13:09:22 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-03-29 13:09:22 -0600 |
commit | 72adecb9057d7015c5d1729ec3752926284bab8c (patch) | |
tree | 32d43aee83799c9f1ad28a9a1c18bde492c553d7 /nuttx | |
parent | 6c2f4007dc9fc482d650a956ef13959f502d327b (diff) | |
download | px4-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/Kconfig | 5 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/arch_clean_dcache.c | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/arch_clean_dcache_all.c | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/arch_flush_dcache.c | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/arch_flush_dcache_all.c | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/cache.h | 49 | ||||
-rw-r--r-- | nuttx/arch/arm/src/samv7/Kconfig | 9 | ||||
-rw-r--r-- | nuttx/arch/arm/src/samv7/Make.defs | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/samv7/sam_start.c | 1 | ||||
-rw-r--r-- | nuttx/configs/samv71-xult/README.txt | 16 |
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 ----------------------------- |