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/arch | |
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/arch')
-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 |
9 files changed, 73 insertions, 11 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(); |