mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
SAMV7/Cortex-M7: Add support for write through D-Cache. SAMV7 Ethernet look like it needs this
This commit is contained in:
@@ -23,6 +23,11 @@ config ARMV7M_DCACHE
|
|||||||
default n
|
default n
|
||||||
depends on ARMV7M_HAVE_DCACHE
|
depends on ARMV7M_HAVE_DCACHE
|
||||||
|
|
||||||
|
config ARMV7M_DCACHE_WRITETHROUGH
|
||||||
|
bool "D-Cache Write-Through"
|
||||||
|
default n
|
||||||
|
depends on ARMV7M_DCACHE
|
||||||
|
|
||||||
config ARMV7M_HAVE_ITCM
|
config ARMV7M_HAVE_ITCM
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_DCACHE
|
#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@@ -146,4 +146,4 @@ void arch_clean_dcache(uintptr_t start, uintptr_t end)
|
|||||||
ARM_ISB();
|
ARM_ISB();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ARMV7M_DCACHE */
|
#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_DCACHE
|
#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@@ -126,4 +126,4 @@ void arch_clean_dcache_all(void)
|
|||||||
ARM_ISB();
|
ARM_ISB();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ARMV7M_DCACHE */
|
#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_DCACHE
|
#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@@ -146,4 +146,4 @@ void arch_flush_dcache(uintptr_t start, uintptr_t end)
|
|||||||
ARM_ISB();
|
ARM_ISB();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ARMV7M_DCACHE */
|
#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_DCACHE
|
#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@@ -125,4 +125,4 @@ void arch_flush_dcache_all(void)
|
|||||||
ARM_ISB();
|
ARM_ISB();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ARMV7M_DCACHE */
|
#endif /* CONFIG_ARMV7M_DCACHE && !CONFIG_ARMV7M_DCACHE_WRITETHROUGH */
|
||||||
|
|||||||
@@ -211,6 +211,31 @@ static inline void arch_invalidate_icache_all(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* 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
|
* Public Variables
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -322,6 +347,9 @@ void arch_invalidate_dcache_all(void);
|
|||||||
* Clean the data cache within the specified region by flushing the
|
* Clean the data cache within the specified region by flushing the
|
||||||
* contents of the data cache to memory.
|
* contents of the data cache to memory.
|
||||||
*
|
*
|
||||||
|
* NOTE: This operation is un-necessary if the DCACHE is configured in
|
||||||
|
* write-through mode.
|
||||||
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* start - virtual start address of region
|
* start - virtual start address of region
|
||||||
* end - virtual end address of region + 1
|
* 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);
|
void arch_clean_dcache(uintptr_t start, uintptr_t end);
|
||||||
#else
|
#else
|
||||||
# define arch_clean_dcache(s,e)
|
# 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
|
* Clean the entire data cache within the specified region by flushing the
|
||||||
* contents of the data cache to memory.
|
* contents of the data cache to memory.
|
||||||
*
|
*
|
||||||
|
* NOTE: This operation is un-necessary if the DCACHE is configured in
|
||||||
|
* write-through mode.
|
||||||
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* None
|
* 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);
|
void arch_clean_dcache_all(void);
|
||||||
#else
|
#else
|
||||||
# define arch_clean_dcache_all()
|
# 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
|
* Flush the data cache within the specified region by cleaning and
|
||||||
* invalidating the D cache.
|
* invalidating the D cache.
|
||||||
*
|
*
|
||||||
|
* NOTE: If DCACHE write-through is configured, then this operation is the
|
||||||
|
* same as arch_invalidate_cache().
|
||||||
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* start - virtual start address of region
|
* start - virtual start address of region
|
||||||
* end - virtual end address of region + 1
|
* 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
|
||||||
|
#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);
|
void arch_flush_dcache(uintptr_t start, uintptr_t end);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
# define arch_flush_dcache(s,e)
|
# define arch_flush_dcache(s,e)
|
||||||
#endif
|
#endif
|
||||||
@@ -401,6 +439,9 @@ void arch_flush_dcache(uintptr_t start, uintptr_t end);
|
|||||||
* Description:
|
* Description:
|
||||||
* Flush the entire data cache by cleaning and invalidating the D cache.
|
* 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:
|
* Input Parameters:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
@@ -415,7 +456,11 @@ void arch_flush_dcache(uintptr_t start, uintptr_t end);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_DCACHE
|
#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);
|
void arch_flush_dcache_all(void);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
# define arch_flush_dcache_all()
|
# define arch_flush_dcache_all()
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -117,6 +117,15 @@ config SAMV7_HAVE_EBI
|
|||||||
config SAMV7_EMAC
|
config SAMV7_EMAC
|
||||||
bool
|
bool
|
||||||
default n
|
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
|
config SAMV7_HSMCI
|
||||||
bool
|
bool
|
||||||
|
|||||||
@@ -66,9 +66,11 @@ endif
|
|||||||
|
|
||||||
ifeq ($(CONFIG_ARMV7M_DCACHE),y)
|
ifeq ($(CONFIG_ARMV7M_DCACHE),y)
|
||||||
CMN_CSRCS += arch_enable_dcache.c arch_disable_dcache.c
|
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_clean_dcache.c arch_clean_dcache_all.c
|
||||||
CMN_CSRCS += arch_flush_dcache.c arch_flush_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
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_FPU),y)
|
ifeq ($(CONFIG_ARCH_FPU),y)
|
||||||
|
|||||||
@@ -380,6 +380,7 @@ void __start(void)
|
|||||||
|
|
||||||
/* Enable I- and D-Caches */
|
/* Enable I- and D-Caches */
|
||||||
|
|
||||||
|
arch_dcache_writethrough();
|
||||||
arch_enable_icache();
|
arch_enable_icache();
|
||||||
arch_enable_dcache();
|
arch_enable_dcache();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
At -O2, many packets can be exchanged but eventually there is a
|
||||||
hardfault, presumably because of a misdirected DMA.
|
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.
|
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
|
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
|
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
|
sample code and study of the data sheet, but I have not found the key to
|
||||||
solving this.
|
solving this.
|
||||||
|
|
||||||
- I need to try this as -O2 optimization as well.
|
+nmnmSerial Console
|
||||||
|
|
||||||
Serial Console
|
|
||||||
==============
|
==============
|
||||||
|
|
||||||
The SAMV71-XULT has no on-board RS-232 drivers so it will be necessary to
|
The SAMV71-XULT has no on-board RS-232 drivers so it will be necessary to
|
||||||
@@ -767,6 +771,12 @@ NOTES:
|
|||||||
System Type -> Toolchain:
|
System Type -> Toolchain:
|
||||||
CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : GNU ARM EABI 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
|
Configuration sub-directories
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user