ARM: V7M: Support caches
cover ARM: V7M: Support caches
Hi,
This patch set allows M-class cpus benefit of optional cache support. It originaly was written by Jonny, I've been keeping it localy mainly rebasing over Linux versions.
The main idea behind patches is to reuse existing cache handling code from v7A/R. In case v7M cache operations are provided via memory mapped interface rather than co-processor instructions, so extra macros have been introduced to factor out cache handling logic and low-level operations.
Along with the v7M cache support the first user (Cortex-M7) is introduced.
Patches were tested on MPS2 platform with Cortex-M3/M4/M7. The later one showed significant boot speed-up.
Based on 4.7-rc3.
Thanks!
Vladimir
Jonathan Austin (9):
ARM: factor out CSSELR/CCSIDR operations that use cp15 directly
ARM: V7M: Make read_cpuid() generally available on V7M.
ARM: V7M: Add addresses for mem-mapped V7M cache operations
ARM: V7M: Add support for reading the CTR with CPUID_CACHETYPE
ARM: Extract cp15 operations from cache flush code
ARM: V7M: Implement cache macros for V7M
ARM: V7M: Wire up caches for V7M processors with cache support.
ARM: V7M: Indirect proc_info construction for V7M CPUs
ARM: V7M: Add support for the Cortex-M7 processor
Vladimir Murzin (1):
ARM: V7M: fix notrace variant of save_and_disable_irqs
arch/arm/include/asm/assembler.h | 4 ++ arch/arm/include/asm/cachetype.h | 39 ++++++++++ arch/arm/include/asm/cputype.h | 51 +++++++------ arch/arm/include/asm/glue-cache.h | 4 -- arch/arm/include/asm/v7m.h | 22 ++++++ arch/arm/kernel/head-nommu.S | 16 ++++- arch/arm/kernel/setup.c | 16 ++--- arch/arm/mm/Kconfig | 7 +- arch/arm/mm/Makefile | 4 ++ arch/arm/mm/cache-v7.S | 73 +++++++++++-------- arch/arm/mm/proc-macros.S | 23 ------ arch/arm/mm/proc-v7.S | 1 + arch/arm/mm/proc-v7m.S | 93 ++++++++++++++++++++---- arch/arm/mm/v7-cache-macros.S | 131 ++++++++++++++++++++++++++++++++++ arch/arm/mm/v7m-cache-macros.S | 142 +++++++++++++++++++++++++++++++++++++ 15 files changed, 520 insertions(+), 106 deletions(-) create mode 100644 arch/arm/mm/v7-cache-macros.S create mode 100644 arch/arm/mm/v7m-cache-macros.S
Signature · 1 line
1.7.9.5
PATCH 1/10 ARM: factor out CSSELR/CCSIDR operations that use cp15 directly
From: Jonathan Austin <[email protected]>
Currently we use raw cp15 operations to access the cache setup data.
This patch abstracts the CSSELR and CCSIDR accessors out to a header so that the implementation for them can be switched out as we do with other cpu/cachetype operations.
--- arch/arm/include/asm/cachetype.h | 24 ++++++++++++++++++++++++ arch/arm/kernel/setup.c | 7 ++----- 2 files changed, 26 insertions(+), 5 deletions(-)
arch/arm/include/asm/cachetype.h +24 -0
@@ -56,4 +56,28 @@ static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask) (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid); } +#define CSSELR_ICACHE 1 +#define CSSELR_DCACHE 0 + +#define CSSELR_L1 (0 << 1) +#define CSSELR_L2 (1 << 1) +#define CSSELR_L3 (2 << 1) +#define CSSELR_L4 (3 << 1) +#define CSSELR_L5 (4 << 1) +#define CSSELR_L6 (5 << 1) +#define CSSELR_L7 (6 << 1) + +static inline void set_csselr (unsigned int cache_selector) +{ + asmvolatile ("mcr p15, 2, %0, c0, c0, 0" : :"r" (cache_selector)); +} + +static inline unsigned int read_ccsidr (void ) +{ +unsigned int val; + + asmvolatile ("mrc p15, 1, %0, c0, c0, 0" :"=r" (val)); +return val; +} +#endif
arch/arm/kernel/setup.c +2 -5
@@ -291,12 +291,9 @@ static int cpu_has_aliasing_icache(unsigned int arch)/* arch specifies the register format */ switch (arch) {case CPU_ARCH_ARMv7: - asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR" - :/* No output operands */ - :"r" (1 )); +set_csselr (CSSELR_ICACHE |CSSELR_L1 );isb (); - asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR" - :"=r" (id_reg)); + id_reg =read_ccsidr (); line_size =4 << ((id_reg &0x7 ) +2 ); num_sets = ((id_reg >>13 ) &0x7fff ) +1 ; aliasing_icache = (line_size * num_sets) >PAGE_SIZE ;
Signature · 1 line
1.7.9.5
PATCH 2/10 ARM: V7M: Make read_cpuid() generally available on V7M.
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
Previously V7M had a custom definition for read_cpuid_id that didn't use the underlying read_cpuid() macro and a stub definition for read_cpuid().
This requires a custom specialisation for each of the CPUID_* registers, and as more than just CPUID_ID may be implemented in the future this doesn't make much sense.
This patch creates a generic implementation of read_cpuid for V7M and removes the custom read_cpuid_id implementation.
--- arch/arm/include/asm/cputype.h | 50 ++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 22 deletions(-)
arch/arm/include/asm/cputype.h +28 -22
@@ -4,15 +4,15 @@#include <linux/stringify.h> #include <linux/kernel.h> -#define CPUID_ID 0 -#define CPUID_CACHETYPE 1 -#define CPUID_TCM 2 -#define CPUID_TLBTYPE 3 -#define CPUID_MPUIR 4 -#define CPUID_MPIDR 5 -#define CPUID_REVIDR 6 -#ifdef CONFIG_CPU_V7M + +#define CPUID_ID 0x0 +#define CPUID_CACHETYPE -1 +#define CPUID_TCM -1 +#define CPUID_TLBTYPE -1 +#define CPUID_MPIDR -1 +#define CPUID_REVIDR -1 +#define CPUID_EXT_PFR0 0x40#define CPUID_EXT_PFR1 0x44#define CPUID_EXT_DFR0 0x48
@@ -28,6 +28,14 @@#define CPUID_EXT_ISAR4 0x70#define CPUID_EXT_ISAR5 0x74#else +#define CPUID_ID 0 +#define CPUID_CACHETYPE 1 +#define CPUID_TCM 2 +#define CPUID_TLBTYPE 3 +#define CPUID_MPUIR 4 +#define CPUID_MPIDR 5 +#define CPUID_REVIDR 6 +#define CPUID_EXT_PFR0 "c1, 0"#define CPUID_EXT_PFR1 "c1, 1"#define CPUID_EXT_DFR0 "c1, 2"
@@ -114,11 +122,16 @@ extern unsigned int processor_id;#include <asm/io.h> #include <asm/v7m.h> -#define read_cpuid (reg) \ - ({ \ - WARN_ON_ONCE(1); \ - 0; \ - }) +static inline unsigned int __attribute_const__ read_cpuid(unsigned offset) +{ +switch (offset) { +case CPUID_ID : +return readl (BASEADDR_V7M_SCB + offset); +default : +WARN_ON_ONCE (1 ); +return 0 ; + } +} static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset) {
@@ -141,7 +154,7 @@ static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset)#endif /* ifdef CONFIG_CPU_CP15 / else */ -#ifdef CONFIG_CPU_CP15 +#if defined(CONFIG_CPU_CP15 ) || defined(CONFIG_CPU_V7M )/* * The CPU ID never changes at run time, so we might as well tell the * compiler that it's constant. Use this function to read the CPU ID
@@ -152,14 +165,7 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void)return read_cpuid (CPUID_ID ); } -#elif defined(CONFIG_CPU_V7M ) - -static inline unsigned int __attribute_const__ read_cpuid_id(void) -{ -return readl (BASEADDR_V7M_SCB +V7M_SCB_CPUID ); -} - -#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */ +#else /* if defined(CONFIG_CPU_CP15) || defined(CONFIG_CPU_V7M) */ static inline unsigned int __attribute_const__ read_cpuid_id(void) {
Signature · 1 line
1.7.9.5
Russell King - ARM Linux
maintainerPATCH 2/10 ARM: V7M: Make read_cpuid() generally available on V7M.
Quoted 3 lines · Vladimir Murzin
This requires a custom specialisation for each of the CPUID_* registers, and as more than just
CPUID_IDmay be implemented in the future this doesn't make much sense.
You shouldn't need most of this patch. The CPUID registers are defined in such a way that unimplemented registers do not fault, but return the MIDR value. If you're just implementing MIDR, then you should just return the MIDR value and be done with it.
(Any location reading the other CPUID registers without checking whether it's a MIDR alias is probably buggy.)
Signature · 3 lines
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
PATCH 2/10 ARM: V7M: Make read_cpuid() generally available on V7M.
Quoted 5 lines · Russell King - ARM Linux
Quoted 3 lines · Vladimir Murzin
This requires a custom specialisation for each of the CPUID_* registers, and as more than just
CPUID_IDmay be implemented in the future this doesn't make much sense.
Quoted 8 lines
You shouldn't need most of this patch. The CPUID registers are defined in such a way that unimplemented registers do not fault, but return the MIDR value. If you're just implementing MIDR, then you should just return the MIDR value and be done with it.
(Any location reading the other CPUID registers without checking whether it's a MIDR alias is probably buggy.)
I'll think on it more. Thanks for feedback!
Cheers
Vladimir
PATCH 3/10 ARM: V7M: Add addresses for mem-mapped V7M cache operations
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
V7M implements cache operations similarly to V7A/R, however all operations are performed via memory-mapped IO instead of co-processor operations.
This patch adds register definitions relevant to the V7M ARM architecture's cache architecture.
--- arch/arm/include/asm/v7m.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
arch/arm/include/asm/v7m.h +22 -0
@@ -24,6 +24,9 @@#define V7M_SCB_CCR 0x14#define V7M_SCB_CCR_STKALIGN (1 << 9) +#define V7M_SCB_CCR_DC (1 << 16) +#define V7M_SCB_CCR_IC (1 << 17) +#define V7M_SCB_CCR_BP (1 << 18)#define V7M_SCB_SHPR2 0x1c#define V7M_SCB_SHPR3 0x20
@@ -47,6 +50,25 @@#define EXC_RET_STACK_MASK 0x00000004#define EXC_RET_THREADMODE_PROCESSSTACK 0xfffffffd +/* Cache related definitions */ + +#define V7M_SCB_CLIDR 0x78/* Cache Level ID register */ +#define V7M_SCB_CTR 0x7c/* Cache Type register */ +#define V7M_SCB_CCSIDR 0x80/* Cache size ID register */ +#define V7M_SCB_CSSELR 0x84/* Cache size selection register */ + +/* Cache opeartions */ +#define V7M_SCB_ICIALLU 0x250/* I-cache invalidate all to PoU */ +#define V7M_SCB_ICIMVAU 0x258/* I-cache invalidate by MVA to PoU */ +#define V7M_SCB_DCIMVAC 0x25c/* D-cache invalidate by MVA to PoC */ +#define V7M_SCB_DCISW 0x260/* D-cache invalidate by set-way */ +#define V7M_SCB_DCCMVAU 0x264/* D-cache clean by MVA to PoU */ +#define V7M_SCB_DCCMVAC 0x268/* D-cache clean by MVA to PoC */ +#define V7M_SCB_DCCSW 0x26c/* D-cache clean by set-way */ +#define V7M_SCB_DCCIMVAC 0x270/* D-cache clean and invalidate by MVA to PoC */ +#define V7M_SCB_DCCISW 0x274/* D-cache clean and invalidate by set-way */ +#define V7M_SCB_BPIALL 0x278/* D-cache clean and invalidate by set-way */ +#ifndef __ASSEMBLY__enum reboot_mode ;
Signature · 1 line
1.7.9.5
PATCH 4/10 ARM: V7M: Add support for reading the CTR with CPUID_CACHETYPE
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
With the addition of caches to the V7M Architecture a new Cache Type Register (CTR) is defined at 0xE000ED7C. This register serves the same purpose as the V7A/R version, called CPUID_CACHETYPE in the kernel.
This patch adds appropriate definitions to the cpuid macros to allow the CTR to be read with read_cpuid(reg).
---
Changelog:
RFC -> v1
- use linux/io.h instead of asm/io.h (per Russell)
- droped cast to void pointer in set_csselr; BASEADDR_V7M_SCB is already defined with a help of IOMEM macro (per Russell)
arch/arm/include/asm/cachetype.h | 15 +++++++++++++++ arch/arm/include/asm/cputype.h | 3 ++- arch/arm/kernel/setup.c | 9 +++++---- 3 files changed, 22 insertions(+), 5 deletions(-)
arch/arm/include/asm/cachetype.h +15 -0
@@ -67,6 +67,7 @@ static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask)#define CSSELR_L6 (5 << 1)#define CSSELR_L7 (6 << 1) +#ifndef CONFIG_CPU_V7M static inline void set_csselr (unsigned int cache_selector) { asmvolatile ("mcr p15, 2, %0, c0, c0, 0" : :"r" (cache_selector));
@@ -79,5 +80,19 @@ static inline unsigned int read_ccsidr(void) asmvolatile ("mrc p15, 1, %0, c0, c0, 0" :"=r" (val));return val; } +#else /* CONFIG_CPU_V7M */ +#include <linux/io.h> +#include "asm/v7m.h" + +static inline void set_csselr (unsigned int cache_selector) +{ +writel (cache_selector,BASEADDR_V7M_SCB +V7M_SCB_CTR ); +} + +static inline unsigned int read_ccsidr (void ) +{ +return readl (BASEADDR_V7M_SCB +V7M_SCB_CCSIDR ); +} +#endif #endif
arch/arm/include/asm/cputype.h +2 -1
@@ -7,7 +7,7 @@#ifdef CONFIG_CPU_V7M #define CPUID_ID 0x0 -#define CPUID_CACHETYPE -1 +#define CPUID_CACHETYPE 0x7c#define CPUID_TCM -1#define CPUID_TLBTYPE -1#define CPUID_MPIDR -1
@@ -126,6 +126,7 @@ static inline unsigned int __attribute_const__ read_cpuid(unsigned offset) {switch (offset) {case CPUID_ID : +case CPUID_CACHETYPE :return readl (BASEADDR_V7M_SCB + offset);default :WARN_ON_ONCE (1 );
arch/arm/kernel/setup.c +5 -4
@@ -313,11 +313,12 @@ static void __init cacheid_init(void) {unsigned int arch =cpu_architecture (); -if (arch == CPU_ARCH_ARMv7M) { - cacheid =0 ; - }else if (arch >= CPU_ARCH_ARMv6) { +if (arch >= CPU_ARCH_ARMv6) {unsigned int cachetype =read_cpuid_cachetype (); -if ((cachetype & (7 <<29 )) ==4 <<29 ) { + +if ((arch == CPU_ARCH_ARMv7M) && !cachetype) { + cacheid =0 ; + }else if ((cachetype & (7 <<29 )) ==4 <<29 ) {/* ARMv7 register format */ arch = CPU_ARCH_ARMv7; cacheid =CACHEID_VIPT_NONALIASING ;
Signature · 1 line
1.7.9.5
PATCH 5/10 ARM: Extract cp15 operations from cache flush code
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
Caches have been added to the V7M architecture. Instead of CP15 operations, the cache maintenance is done with memory-mapped registers. Other properties of the cache architecture are the same as V7A/R.
In order to make it possible to use the same cacheflush code on V7A/R and V7M, this commit separates out the cp15 cache maintenance operations into a separate, V7A/R specific v7 cache macros file. This is done by introducing cache macros.
This commit does not introduce any V7M-related code to simplify the process of verifying that the result of compiling cache-v7.S is identical before and after this commit.
---
Changelog:
RFC -> v1
- open-coded implentation of dccmvau and icimvau instead of macros, since the latter would mark the wring instruction as user-accessable (per Russell)
- dccimvac is updated per Russell preference
arch/arm/mm/cache-v7.S | 51 +++++++----------
arch/arm/mm/proc-macros.S | 23 -------- arch/arm/mm/proc-v7.S | 1 + arch/arm/mm/v7-cache-macros.S | 126 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 52 deletions(-) create mode 100644 arch/arm/mm/v7-cache-macros.S
arch/arm/mm/cache-v7.S +22 -29
@@ -17,6 +17,7 @@ #include <asm/unwind.h> #include "proc-macros.S" +#include "v7-cache-macros.S" /* * The secondary kernel init calls v7_flush_dcache_all before it enables
@@ -33,9 +34,9 @@ */ ENTRY(v7_invalidate_l1) mov r0, #0 - mcr p15, 2, r0, c0, c0, 0 - mrc p15, 1, r0, c0, c0, 0 + write_csselr r0 + read_ccsidr r0 movw r1, #0x7fff and r2, r1, r0, lsr #13
@@ -55,7 +56,7 @@ ENTRY(v7_invalidate_l1) mov r5, r3, lsl r1 mov r6, r2, lsl r0 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) - mcr p15, 0, r5, c7, c6, 2 + dcisw r5 bgt 2b cmp r2, #0 bgt 1b
@@ -73,9 +74,7 @@ ENDPROC(v7_invalidate_l1) * r0 - set to 0 */ ENTRY(v7_flush_icache_all) - mov r0, #0 - ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable - ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate + invalidate_icache r0 ret lr ENDPROC(v7_flush_icache_all)
@@ -89,7 +88,7 @@ ENDPROC(v7_flush_icache_all) ENTRY(v7_flush_dcache_louis) dmb @ ensure ordering with previous memory accesses - mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr + read_clidr r0 ALT_SMP(mov r3, r0, lsr #20) @ move LoUIS into position ALT_UP( mov r3, r0, lsr #26) @ move LoUU into position ands r3, r3, #7 << 1 @ extract LoU*2 field from clidr
@@ -117,7 +116,7 @@ ENDPROC(v7_flush_dcache_louis) */ ENTRY(v7_flush_dcache_all) dmb @ ensure ordering with previous memory accesses - mrc p15, 1, r0, c0, c0, 1 @ read clidr + read_clidr r0 mov r3, r0, lsr #23 @ move LoC into position ands r3, r3, #7 << 1 @ extract LoC*2 from clidr beq finished @ if loc is 0, then no need to clean
@@ -132,9 +131,9 @@ flush_levels: #ifdef CONFIG_PREEMPT save_and_disable_irqs_notrace r9 @ make cssr&csidr read atomic #endif - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + write_csselr r10 @ set current cache level isb @ isb to sych the new cssr&csidr - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr + read_ccsidr r1 @ read the new csidr #ifdef CONFIG_PREEMPT restore_irqs_notrace r9 #endif
@@ -154,7 +153,7 @@ loop2: ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11 THUMB( lsl r6, r9, r2 ) THUMB( orr r11, r11, r6 ) @ factor index number into r11 - mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way + dccisw r11 @ clean/invalidate by set/way subs r9, r9, #1 @ decrement the index bge loop2 subs r4, r4, #1 @ decrement the way
@@ -165,7 +164,7 @@ skip: bgt flush_levels finished: mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr + write_csselr r10 @ select current cache level in cssr dsb st isb ret lr
@@ -186,9 +185,7 @@ ENTRY(v7_flush_kern_cache_all) ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) bl v7_flush_dcache_all - mov r0, #0 - ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable - ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate + invalidate_icache r0 ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) ret lr
@@ -204,9 +201,7 @@ ENTRY(v7_flush_kern_cache_louis) ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) bl v7_flush_dcache_louis - mov r0, #0 - ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable - ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate + invalidate_icache r0 ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) ret lr
@@ -278,7 +273,7 @@ ENTRY(v7_coherent_user_range) ALT_UP(W(nop)) #endif 1: - USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification + USER( dccmvau r12 ) @ clean D line to the point of unification add r12, r12, r2 cmp r12, r1 blo 1b
@@ -287,13 +282,11 @@ ENTRY(v7_coherent_user_range) sub r3, r2, #1 bic r12, r0, r3 2: - USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line + USER( icimvau r12 ) @ invalidate I line add r12, r12, r2 cmp r12, r1 blo 2b - mov r0, #0 - ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable - ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB + invalidate_bp r0 dsb ishst isb ret lr
@@ -331,7 +324,7 @@ ENTRY(v7_flush_kern_dcache_area) ALT_UP(W(nop)) #endif 1: - mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line + dccimvac r0 @ clean & invalidate D line / unified line add r0, r0, r2 cmp r0, r1 blo 1b
@@ -358,13 +351,13 @@ v7_dma_inv_range: ALT_SMP(W(dsb)) ALT_UP(W(nop)) #endif - mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line + dccimvacne r0 tst r1, r3 bic r1, r1, r3 - mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D / U line + dccimvacne r1 1: - mcr p15, 0, r0, c7, c6, 1 @ invalidate D / U line + dcimvac r0 add r0, r0, r2 cmp r0, r1 blo 1b
@@ -386,7 +379,7 @@ v7_dma_clean_range: ALT_UP(W(nop)) #endif 1: - mcr p15, 0, r0, c7, c10, 1 @ clean D / U line + dccmvac r0 @ clean D / U line add r0, r0, r2 cmp r0, r1 blo 1b
@@ -408,7 +401,7 @@ ENTRY(v7_dma_flush_range) ALT_UP(W(nop)) #endif 1: - mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line + dccimvac r0 @ clean & invalidate D / U line add r0, r0, r2 cmp r0, r1 blo 1b
arch/arm/mm/proc-macros.S +0 -23
@@ -66,29 +66,6 @@ .endm /* - * dcache_line_size - get the minimum D-cache line size from the CTR register - * on ARMv7. - */ - .macro dcache_line_size, reg, tmp - mrc p15, 0, \tmp, c0, c0, 1 @ read ctr - lsr \tmp, \tmp, #16 - and \tmp, \tmp, #0xf @ cache line size encoding - mov \reg, #4 @ bytes per word - mov \reg, \reg, lsl \tmp @ actual cache line size - .endm - -/* - * icache_line_size - get the minimum I-cache line size from the CTR register - * on ARMv7. - */ - .macro icache_line_size, reg, tmp - mrc p15, 0, \tmp, c0, c0, 1 @ read ctr - and \tmp, \tmp, #0xf @ cache line size encoding - mov \reg, #4 @ bytes per word - mov \reg, \reg, lsl \tmp @ actual cache line size - .endm - -/* * Sanity check the PTE configuration for the code below - which makes * certain assumptions about how these bits are laid out. */
arch/arm/mm/proc-v7.S +1 -0
@@ -18,6 +18,7 @@ #include <asm/pgtable.h> #include "proc-macros.S" +#include "v7-cache-macros.S" #ifdef CONFIG_ARM_LPAE #include "proc-v7-3level.S"
arch/arm/mm/v7-cache-macros.S new file +126 -0
126 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH 6/10 ARM: V7M: Implement cache macros for V7M
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
This commit implements the cache operation macros for V7M, paving the way for caches to be used on V7 with a future commit.
Because the cache operations in V7M are memory mapped, in most operations an extra register is required compared to the V7 version, where the type of operation is encoded in the instruction, not the address that is written to.
Thus, an extra register argument has been added to the cache operation macros, that is required in V7M but ignored/unused in V7. In almost all cases there was a spare temporary register, but in places where the register allocation was tighter the M_CLASS macro has been used to avoid clobbering new registers.
---
Changelog:
RFC -> v1
- M_CLASS() macro is used instead of THUMB() where appropriate
- open-coded implentation of dccmvau and icimvau instead of macros, since the latter would mark the wrong instruction as user-accessable (per Russell)
- dccimvac is updated per Russell preference
arch/arm/mm/cache-v7.S | 48 ++++++++++----
arch/arm/mm/v7-cache-macros.S | 21 +++--- arch/arm/mm/v7m-cache-macros.S | 142 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mm/v7m-cache-macros.S
arch/arm/mm/cache-v7.S +34 -14
@@ -17,7 +17,11 @@ #include <asm/unwind.h> #include "proc-macros.S" +#ifdef CONFIG_CPU_V7M +#include "v7m-cache-macros.S" +#else #include "v7-cache-macros.S" +#endif /* * The secondary kernel init calls v7_flush_dcache_all before it enables
@@ -35,7 +39,7 @@ ENTRY(v7_invalidate_l1) mov r0, #0 - write_csselr r0 + write_csselr r0, r1 read_ccsidr r0 movw r1, #0x7fff and r2, r1, r0, lsr #13
@@ -56,7 +60,7 @@ ENTRY(v7_invalidate_l1) mov r5, r3, lsl r1 mov r6, r2, lsl r0 orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) - dcisw r5 + dcisw r5, r6 bgt 2b cmp r2, #0 bgt 1b
@@ -131,7 +135,7 @@ flush_levels: #ifdef CONFIG_PREEMPT save_and_disable_irqs_notrace r9 @ make cssr&csidr read atomic #endif - write_csselr r10 @ set current cache level + write_csselr r10, r1 @ set current cache level isb @ isb to sych the new cssr&csidr read_ccsidr r1 @ read the new csidr #ifdef CONFIG_PREEMPT
@@ -153,7 +157,7 @@ loop2: ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11 THUMB( lsl r6, r9, r2 ) THUMB( orr r11, r11, r6 ) @ factor index number into r11 - dccisw r11 @ clean/invalidate by set/way + dccisw r11, r6 @ clean/invalidate by set/way subs r9, r9, #1 @ decrement the index bge loop2 subs r4, r4, #1 @ decrement the way
@@ -164,7 +168,7 @@ skip: bgt flush_levels finished: mov r10, #0 @ swith back to cache level 0 - write_csselr r10 @ select current cache level in cssr + write_csselr r10, r3 @ select current cache level in cssr dsb st isb ret lr
@@ -273,7 +277,17 @@ ENTRY(v7_coherent_user_range) ALT_UP(W(nop)) #endif 1: - USER( dccmvau r12 ) @ clean D line to the point of unification +#ifdef CONFIG_CPU_V7M +/* + * We use open coded version of dccmvau otherwise USER() would + * point at movw instruction. + */ + movw r3, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAU + movt r3, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAU +USER( str r12, [r3] ) +#else +USER( dccmvau r12 ) @ clean D line to the point of unification +#endif add r12, r12, r2 cmp r12, r1 blo 1b
@@ -282,7 +296,13 @@ ENTRY(v7_coherent_user_range) sub r3, r2, #1 bic r12, r0, r3 2: - USER( icimvau r12 ) @ invalidate I line +#ifdef CONFIG_CPU_V7M + movw r3, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_ICIMVAU + movt r3, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_ICIMVAU +USER( str r12, [r3] ) +#else +USER( icimvau r12 )@ invalidate I line +#endif add r12, r12, r2 cmp r12, r1 blo 2b
@@ -324,7 +344,7 @@ ENTRY(v7_flush_kern_dcache_area) ALT_UP(W(nop)) #endif 1: - dccimvac r0 @ clean & invalidate D line / unified line + dccimvac r0, r3 @ clean & invalidate D line / unified line add r0, r0, r2 cmp r0, r1 blo 1b
@@ -351,13 +371,13 @@ v7_dma_inv_range: ALT_SMP(W(dsb)) ALT_UP(W(nop)) #endif - dccimvacne r0 - + dccimvacne r0, r3 +M_CLASS(subne r3, r2, #1) @ restore r3, corrupted by v7m's dccimvac tst r1, r3 bic r1, r1, r3 - dccimvacne r1 + dccimvacne r1, r3 1: - dcimvac r0 + dcimvac r0, r3 add r0, r0, r2 cmp r0, r1 blo 1b
@@ -379,7 +399,7 @@ v7_dma_clean_range: ALT_UP(W(nop)) #endif 1: - dccmvac r0 @ clean D / U line + dccmvac r0, r3 @ clean D / U line add r0, r0, r2 cmp r0, r1 blo 1b
@@ -401,7 +421,7 @@ ENTRY(v7_dma_flush_range) ALT_UP(W(nop)) #endif 1: - dccimvac r0 @ clean & invalidate D / U line + dccimvac r0, r3 @ clean & invalidate D / U line add r0, r0, r2 cmp r0, r1 blo 1b
arch/arm/mm/v7-cache-macros.S +13 -8
@@ -15,6 +15,11 @@ * Copyright (C) 2012 ARM Limited * * Author: Jonathan Austin <[email protected]> + * + * The 'unused' parameters are to keep the macro signatures in sync with the + * V7M versions, which require a tmp register for certain operations (see + * v7m-cache-macros.S). GAS supports omitting optional arguments but doesn't + * happily ignore additional undefined ones. */ .macro read_ctr, rt
@@ -29,21 +34,21 @@ mrc p15, 1, \rt, c0, c0, 1 .endm -.macro write_csselr, rt +.macro write_csselr, rt, unused mcr p15, 2, \rt, c0, c0, 0 .endm /* * dcisw: invalidate data cache by set/way */ -.macro dcisw, rt +.macro dcisw, rt, unused mcr p15, 0, \rt, c7, c6, 2 .endm /* * dccisw: clean and invalidate data cache by set/way */ -.macro dccisw, rt +.macro dccisw, rt, unused mcr p15, 0, \rt, c7, c14, 2 .endm
@@ -51,7 +56,7 @@ * dccimvac: Clean and invalidate data cache line by MVA to PoC. */ .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo -.macro dccimvac\c, rt +.macro dccimvac\c, rt, unused mcr\c p15, 0, \rt, c7, c14, 1 .endm .endr
@@ -59,28 +64,28 @@ /* * dcimvac: Invalidate data cache line by MVA to PoC */ -.macro dcimvac, rt +.macro dcimvac, rt, unused mcr p15, 0, r0, c7, c6, 1 .endm /* * dccmvau: Clean data cache line by MVA to PoU */ -.macro dccmvau, rt +.macro dccmvau, rt, unused mcr p15, 0, \rt, c7, c11, 1 .endm /* * dccmvac: Clean data cache line by MVA to PoC */ -.macro dccmvac, rt +.macro dccmvac, rt, unused mcr p15, 0, \rt, c7, c10, 1 .endm /* * icimvau: Invalidate instruction caches by MVA to PoU */ -.macro icimvau, rt +.macro icimvau, rt, unused mcr p15, 0, \rt, c7, c5, 1 .endm
arch/arm/mm/v7m-cache-macros.S new file +142 -0
142 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Russell King - ARM Linux
maintainerPATCH 6/10 ARM: V7M: Implement cache macros for V7M
Quoted 9 lines · Vladimir Murzin
From: Jonathan Austin <[email protected]>
This commit implements the cache operation macros for V7M, paving the way for caches to be used on V7 with a future commit.
Because the cache operations in V7M are memory mapped, in most operations an extra register is required compared to the V7 version, where the type of operation is encoded in the instruction, not the address that is written to.
Quoted 5 lines
Thus, an extra register argument has been added to the cache operation macros, that is required in V7M but ignored/unused in V7. In almost all cases there was a spare temporary register, but in places where the register allocation was tighter the
M_CLASSmacro has been used to avoid clobbering new registers.
It's probably way more efficient to just implement this as an entirely separate implementation, rather than trying to bodge this into the v7 stuff.
Signature · 3 lines
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
PATCH 6/10 ARM: V7M: Implement cache macros for V7M
Quoted 16 lines · Russell King - ARM Linux
Quoted 9 lines · Vladimir Murzin
From: Jonathan Austin <[email protected]>
This commit implements the cache operation macros for V7M, paving the way for caches to be used on V7 with a future commit.
Because the cache operations in V7M are memory mapped, in most operations an extra register is required compared to the V7 version, where the type of operation is encoded in the instruction, not the address that is written to.
Quoted 5 lines
Thus, an extra register argument has been added to the cache operation macros, that is required in V7M but ignored/unused in V7. In almost all cases there was a spare temporary register, but in places where the register allocation was tighter the
M_CLASSmacro has been used to avoid clobbering new registers.
Quoted 4 lines
It's probably way more efficient to just implement this as an entirely separate implementation, rather than trying to bodge this into the v7 stuff.
It might be an option, but having all these as a macro make it possible to have cache support in decompresser (not presented in this series) too. If you don't buy it I'll think of moving to an entirely separate implementation as you've just suggested.
Thanks
Vladimir
Russell King - ARM Linux
maintainerPATCH 6/10 ARM: V7M: Implement cache macros for V7M
Quoted 22 lines · Vladimir Murzin
Quoted 16 lines · Russell King - ARM Linux
Quoted 9 lines · Vladimir Murzin
From: Jonathan Austin <[email protected]>
This commit implements the cache operation macros for V7M, paving the way for caches to be used on V7 with a future commit.
Because the cache operations in V7M are memory mapped, in most operations an extra register is required compared to the V7 version, where the type of operation is encoded in the instruction, not the address that is written to.
Quoted 5 lines
Thus, an extra register argument has been added to the cache operation macros, that is required in V7M but ignored/unused in V7. In almost all cases there was a spare temporary register, but in places where the register allocation was tighter the
M_CLASSmacro has been used to avoid clobbering new registers.Quoted 4 lines
It's probably way more efficient to just implement this as an entirely separate implementation, rather than trying to bodge this into the v7 stuff.
Quoted 4 lines
It might be an option, but having all these as a macro make it possible to have cache support in decompresser (not presented in this series) too. If you don't buy it I'll think of moving to an entirely separate implementation as you've just suggested.
What I really don't like is shoe-horning v7m support into cache-v7. v7m cache support should be in a separate file called cache-v7m.S.
Signature · 3 lines
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
PATCH 6/10 ARM: V7M: Implement cache macros for V7M
Quoted 23 lines · Russell King - ARM Linux
Quoted 22 lines · Vladimir Murzin
Quoted 20 lines · Russell King - ARM Linux
Quoted 9 lines · Vladimir Murzin
From: Jonathan Austin <[email protected]>
This commit implements the cache operation macros for V7M, paving the way for caches to be used on V7 with a future commit.
Because the cache operations in V7M are memory mapped, in most operations an extra register is required compared to the V7 version, where the type of operation is encoded in the instruction, not the address that is written to.
Quoted 5 lines
Thus, an extra register argument has been added to the cache operation macros, that is required in V7M but ignored/unused in V7. In almost all cases there was a spare temporary register, but in places where the register allocation was tighter the
M_CLASSmacro has been used to avoid clobbering new registers.It's probably way more efficient to just implement this as an entirely separate implementation, rather than trying to bodge this into the v7 stuff.
Quoted 8 lines
Quoted 4 lines
It might be an option, but having all these as a macro make it possible to have cache support in decompresser (not presented in this series) too. If you don't buy it I'll think of moving to an entirely separate implementation as you've just suggested.
What I really don't like is shoe-horning v7m support into cache-v7. v7m cache support should be in a separate file called
cache-v7m.S.
Your point is clear - I'll move that way then.
Cheers
Vladimir
PATCH 7/10 ARM: V7M: fix notrace variant of save_and_disable_irqs
In reply to Vladimir MurzinCommit 8e43a905 "ARM: 7325/1: fix v7 boot with lockdep enabled" introduced notrace variant of save_and_disable_irqs to balance notrace variant of restore_irqs; however V7M case has been missed. It was not noticed because cache-v7.S the only place where notrace variant is used. So fix it, since we are going to extend V7 cache routines to handle V7M case too.
--- arch/arm/include/asm/assembler.h | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/include/asm/assembler.h +4 -0
@@ -159,7 +159,11 @@ .endm .macro save_and_disable_irqs_notrace, oldcpsr +#ifdef CONFIG_CPU_V7M + mrs \oldcpsr, primask +#else mrs \oldcpsr, cpsr +#endif disable_irq_notrace .endm
Signature · 1 line
1.7.9.5
PATCH 8/10 ARM: V7M: Wire up caches for V7M processors with cache support.
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
This patch does the plumbing required to invoke the V7M cache code added in earlier patches in this series, although there is no users for that yet.
In order to honour the I/D cache disable config options, this patch changes the mechanism by which the CCR is set on boot, to be more like V7A/R.
--- arch/arm/include/asm/glue-cache.h | 4 ---- arch/arm/kernel/head-nommu.S | 16 +++++++++++++++- arch/arm/mm/Kconfig | 7 ++++--- arch/arm/mm/Makefile | 4 ++++ arch/arm/mm/proc-v7m.S | 5 ++--- 5 files changed, 25 insertions(+), 11 deletions(-)
arch/arm/include/asm/glue-cache.h +0 -4
@@ -118,11 +118,7 @@#endif #if defined(CONFIG_CPU_V7M ) -# ifdef _CACHE# define MULTI_CACHE 1 -# else -# define _CACHE nop -# endif #endif #if !defined(_CACHE) && !defined(MULTI_CACHE )
arch/arm/kernel/head-nommu.S +15 -1
@@ -158,7 +158,21 @@ __after_proc_init: bic r0, r0, #CR_V #endif mcr p15, 0, r0, c1, c0, 0 @ write control reg -#endif /* CONFIG_CPU_CP15 */ +#elif defined (CONFIG_CPU_V7M) + /* For V7M systems we want to modify the CCR similarly to the SCTLR */ +#ifdef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #V7M_SCB_CCR_DC +#endif +#ifdef CONFIG_CPU_BPREDICT_DISABLE + bic r0, r0, #V7M_SCB_CCR_BP +#endif +#ifdef CONFIG_CPU_ICACHE_DISABLE + bic r0, r0, #V7M_SCB_CCR_IC +#endif + movw r3, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR) + movt r3, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR) + str r0, [r3] +#endif /* CONFIG_CPU_CP15 elif CONFIG_CPU_V7M */ ret lr ENDPROC(__after_proc_init) .ltorg
arch/arm/mm/Kconfig +4 -3
@@ -403,6 +403,7 @@ config CPU_V7M bool select CPU_32v7M select CPU_ABRT_NOMMU + select CPU_CACHE_V7 select CPU_CACHE_NOP select CPU_PABRT_LEGACY select CPU_THUMBONLY
@@ -750,14 +751,14 @@ config CPU_HIGH_VECTOR config CPU_ICACHE_DISABLE bool "Disable I-Cache (I-bit)" - depends on CPU_CP15 && !(CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) + depends on (CPU_CP15 && !(CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3)) || CPU_V7M help Say Y here to disable the processor instruction cache. Unless you have a reason not to or are unsure, say N. config CPU_DCACHE_DISABLE bool "Disable D-Cache (C-bit)" - depends on CPU_CP15 && !SMP + depends on (CPU_CP15 && !SMP) || CPU_V7M help Say Y here to disable the processor data cache. Unless you have a reason not to or are unsure, say N.
@@ -792,7 +793,7 @@ config CPU_CACHE_ROUND_ROBIN config CPU_BPREDICT_DISABLE bool "Disable branch prediction" - depends on CPU_ARM1020 || CPU_V6 || CPU_V6K || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526 + depends on CPU_ARM1020 || CPU_V6 || CPU_V6K || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526 || CPU_V7M help Say Y here to disable branch prediction. If unsure, say N.
arch/arm/mm/Makefile +4 -0
@@ -45,7 +45,11 @@ obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o obj-$(CONFIG_CPU_CACHE_NOP) += cache-nop.o AFLAGS_cache-v6.o :=-Wa,-march=armv6 +ifneq ($(CONFIG_CPU_V7M),y) AFLAGS_cache-v7.o :=-Wa,-march=armv7-a +else +AFLAGS_cache-v7.o :=-Wa,-march=armv7-m +endif obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o
arch/arm/mm/proc-v7m.S +2 -3
@@ -118,9 +118,8 @@ __v7m_setup: @ Configure the System Control Register to ensure 8-byte stack alignment @ Note the STKALIGN bit is either RW or RAO. - ldr r12, [r0, V7M_SCB_CCR] @ system control register - orr r12, #V7M_SCB_CCR_STKALIGN - str r12, [r0, V7M_SCB_CCR] + ldr r0, [r0, V7M_SCB_CCR] @ system control register + orr r0, #V7M_SCB_CCR_STKALIGN ret lr ENDPROC(__v7m_setup)
Signature · 1 line
1.7.9.5
PATCH 9/10 ARM: V7M: Indirect proc_info construction for V7M CPUs
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
This patch copies the method used for V7A/R CPUs to specify differing processor info for different cores.
This patch differentiates Cortex-M3 and Cortex-M4 and leaves a fallback case for any other V7M processors.
--- arch/arm/mm/proc-v7m.S | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-)
arch/arm/mm/proc-v7m.S +35 -11
@@ -132,6 +132,40 @@ ENDPROC(__v7m_setup) .section ".proc.info.init", #alloc +.macro __v7m_proc name, initfunc, cache_fns = nop_cache_fns, hwcaps = 0, proc_fns = v7m_processor_functions + .long 0 /* proc_info_list.__cpu_mm_mmu_flags */ + .long 0 /* proc_info_list.__cpu_io_mmu_flags */ + initfn \initfunc, \name + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \hwcaps + .long cpu_v7m_name + .long \proc_fns + .long 0 /* proc_info_list.tlb */ + .long 0 /* proc_info_list.user */ + .long \cache_fns +.endm + + /* + * Match ARM Cortex-M4 processor. + */ + .type __v7m_cm4_proc_info, #object +__v7m_cm4_proc_info: + .long 0x410fc240 /* ARM Cortex-M4 0xC24 */ + .long 0xff0ffff0 /* Mask off revision, patch release */ + __v7m_proc __v7m_cm4_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP + .size __v7m_cm4_proc_info, . - __v7m_cm4_proc_info + + /* + * Match ARM Cortex-M3 processor. + */ + .type __v7m_cm3_proc_info, #object +__v7m_cm3_proc_info: + .long 0x410fc230 /* ARM Cortex-M3 0xC23 */ + .long 0xff0ffff0 /* Mask off revision, patch release */ + __v7m_proc __v7m_cm3_proc_info, __v7m_setup + .size __v7m_cm3_proc_info, . - __v7m_cm3_proc_info + /* * Match any ARMv7-M processor core. */
@@ -139,16 +173,6 @@ ENDPROC(__v7m_setup) __v7m_proc_info: .long 0x000f0000 @ Required ID value .long 0x000f0000 @ Mask for ID - .long 0 @ proc_info_list.__cpu_mm_mmu_flags - .long 0 @ proc_info_list.__cpu_io_mmu_flags - initfn __v7m_setup, __v7m_proc_info @ proc_info_list.__cpu_flush - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT - .long cpu_v7m_name - .long v7m_processor_functions @ proc_info_list.proc - .long 0 @ proc_info_list.tlb - .long 0 @ proc_info_list.user - .long nop_cache_fns @ proc_info_list.cache + __v7m_proc __v7m_proc_info, __v7m_setup .size __v7m_proc_info, . - __v7m_proc_info
Signature · 1 line
1.7.9.5
PATCH 10/10 ARM: V7M: Add support for the Cortex-M7 processor
In reply to Vladimir MurzinFrom: Jonathan Austin <[email protected]>
Cortex-M7 is a new member of the V7M processor family that adds, among other things, caches over the features available in Cortex-M4.
This patch adds support for recognising the processor at boot time, and make use of recently introduced cache functions.
--- arch/arm/mm/proc-v7m.S | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
arch/arm/mm/proc-v7m.S +42 -0
@@ -15,6 +15,7 @@ #include <asm/memory.h> #include <asm/v7m.h> #include "proc-macros.S" +#include "v7m-cache-macros.S" ENTRY(cpu_v7m_proc_init) ret lr
@@ -74,6 +75,25 @@ ENTRY(cpu_v7m_do_resume) ENDPROC(cpu_v7m_do_resume) #endif +ENTRY(cpu_cm7_dcache_clean_area) + dcache_line_size r2, r3 +1: dccmvac r0, r3 @ clean D entry + add r0, r0, r2 + subs r1, r1, r2 + bhi 1b + dsb + ret lr +ENDPROC(cpu_cm7_dcache_clean_area) + +ENTRY(cpu_cm7_proc_fin) + movw r2, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR) + movt r2, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR) + ldr r0, [r2] + bic r0, r0, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC) + str r0, [r2] + ret lr +ENDPROC(cpu_cm7_proc_fin) + .section ".text.init", #alloc, #execinstr /*
@@ -120,10 +140,22 @@ __v7m_setup: @ Note the STKALIGN bit is either RW or RAO. ldr r0, [r0, V7M_SCB_CCR] @ system control register orr r0, #V7M_SCB_CCR_STKALIGN + read_ctr r12 + teq r12, #0 + orrne r0, r0, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC| V7M_SCB_CCR_BP) ret lr ENDPROC(__v7m_setup) +/* + * Cortex-M7 processor functions + */ + globl_equ cpu_cm7_proc_init, cpu_v7m_proc_init + globl_equ cpu_cm7_reset, cpu_v7m_reset + globl_equ cpu_cm7_do_idle, cpu_v7m_do_idle + globl_equ cpu_cm7_switch_mm, cpu_v7m_switch_mm + define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 + define_processor_functions cm7, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 .section ".rodata" string cpu_arch_name, "armv7m"
@@ -147,6 +179,16 @@ ENDPROC(__v7m_setup) .endm /* + * Match ARM Cortex-M7 processor. + */ + .type __v7m_cm7_proc_info, #object +__v7m_cm7_proc_info: + .long 0x410fc270 /* ARM Cortex-M7 0xC27 */ + .long 0xff0ffff0 /* Mask off revision, patch release */ + __v7m_proc __v7m_cm7_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP, cache_fns = v7_cache_fns, proc_fns = cm7_processor_functions + .size __v7m_cm7_proc_info, . - __v7m_cm7_proc_info + + /* * Match ARM Cortex-M4 processor. */ .type __v7m_cm4_proc_info, #object
Signature · 1 line
1.7.9.5
cover ARM: V7M: Support caches
In reply to Vladimir MurzinHi Vladimir,
Quoted 15 lines · Vladimir Murzin
Hi,
This patch set allows M-class cpus benefit of optional cache support. It originaly was written by Jonny, I've been keeping it localy mainly rebasing over Linux versions.
The main idea behind patches is to reuse existing cache handling code from v7A/R. In case v7M cache operations are provided via memory mapped interface rather than co-processor instructions, so extra macros have been introduced to factor out cache handling logic and low-level operations.
Along with the v7M cache support the first user (Cortex-M7) is introduced.
Quoted 8 lines
Patches were tested on MPS2 platform with Cortex-M3/M4/M7. The later one showed significant boot speed-up.
Based on 4.7-rc3.
Thanks!
Vladimir
Thanks for the series.
Did you change something in those patches compare to patches you sent in the RFC ?
Regards.
Alex
cover ARM: V7M: Support caches
Hi Alex,
Quoted 23 lines · Alexandre Torgue
Hi Vladimir,
Quoted 20 lines · Vladimir Murzin
Hi,
This patch set allows M-class cpus benefit of optional cache support. It originaly was written by Jonny, I've been keeping it localy mainly rebasing over Linux versions.
The main idea behind patches is to reuse existing cache handling code from v7A/R. In case v7M cache operations are provided via memory mapped interface rather than co-processor instructions, so extra macros have been introduced to factor out cache handling logic and low-level operations.
Along with the v7M cache support the first user (Cortex-M7) is introduced.
Patches were tested on MPS2 platform with Cortex-M3/M4/M7. The later one showed significant boot speed-up.
Based on 4.7-rc3.
Quoted 7 lines
Quoted 3 lines
Thanks!
VladimirThanks for the series.
Did you change something in those patches compare to patches you sent in the RFC ?
Only 04, 05, 06 have been changed (each has it's own changelog included).
I did try to hammer patches because of your report of instability with caches on, but all run fine... so nothing has been changed in regard of your case.
Cheers
Vladimir
Quoted 7 lines
Regards.
Alex
cover ARM: V7M: Support caches
Hi Vladimir,
Quoted 34 lines · Vladimir Murzin
Hi Alex,
Quoted 23 lines · Alexandre Torgue
Hi Vladimir,
Quoted 20 lines · Vladimir Murzin
Hi,
This patch set allows M-class cpus benefit of optional cache support. It originaly was written by Jonny, I've been keeping it localy mainly rebasing over Linux versions.
The main idea behind patches is to reuse existing cache handling code from v7A/R. In case v7M cache operations are provided via memory mapped interface rather than co-processor instructions, so extra macros have been introduced to factor out cache handling logic and low-level operations.
Along with the v7M cache support the first user (Cortex-M7) is introduced.
Patches were tested on MPS2 platform with Cortex-M3/M4/M7. The later one showed significant boot speed-up.
Based on 4.7-rc3.
Quoted 7 lines
Quoted 3 lines
Thanks!
VladimirThanks for the series.
Did you change something in those patches compare to patches you sent in the RFC ?
Quoted 6 lines
Only 04, 05, 06 have been changed (each has it's own changelog included).
I did try to hammer patches because of your report of instability with caches on, but all run fine... so nothing has been changed in regard of your case.
Ok. Thanks for this input. From now, I will use this series to perform my tests. I will continue to debug my instabilities this week. I will let you know.
Regards
Alex
cover ARM: V7M: Support caches
Hi Vladimir,
Quoted 39 lines · Alexandre Torgue
Hi Vladimir,
Quoted 36 lines · Vladimir Murzin
Hi Alex,
Quoted 23 lines · Alexandre Torgue
Hi Vladimir,
Quoted 20 lines · Vladimir Murzin
Hi,
This patch set allows M-class cpus benefit of optional cache support. It originaly was written by Jonny, I've been keeping it localy mainly rebasing over Linux versions.
The main idea behind patches is to reuse existing cache handling code from v7A/R. In case v7M cache operations are provided via memory mapped interface rather than co-processor instructions, so extra macros have been introduced to factor out cache handling logic and low-level operations.
Along with the v7M cache support the first user (Cortex-M7) is introduced.
Patches were tested on MPS2 platform with Cortex-M3/M4/M7. The later one showed significant boot speed-up.
Based on 4.7-rc3.
Quoted 7 lines
Quoted 3 lines
Thanks!
VladimirThanks for the series.
Did you change something in those patches compare to patches you sent in the RFC ?Only 04, 05, 06 have been changed (each has it's own changelog included).
Quoted 8 lines
Quoted 4 lines
I did try to hammer patches because of your report of instability with caches on, but all run fine... so nothing has been changed in regard of your case.
Ok. Thanks for this input. From now, I will use this series to perform my tests. I will continue to debug my instabilities this week. I will let you know.
I fixed my instabilities and it was linked to my SDRAM timings :(. I don't see behavior issues with your series (You can add my Tested-by:
Alexandre TORGUE <[email protected]>).
I have two others questions for you:
1- Maybe I didn't search deeper in the code but when you enable Dcache and Icache, what is the state of cache ? I mean we need to invalidate caches before enable it. It is done by kernel (with your patches) or it has to be done by a bootloader ?
2- I observe an issue (IMO not linked to your series) when I switch off/switch on my board. During the first boot after an hard reset I get a bus error (BFSR part in CFSR register indicates an "A bus fault on an instruction prefetch has occurred."). After SRST reset through JTAG, the kernel boot correctly.
Do you already seen this kind of issue ?
I add the backtrace and registers info.
__invalid_entry () at arch/arm/kernel/entry-v7m.S:33
33 1: b 1b
(gdb) bt
#0 __invalid_entry () at arch/arm/kernel/entry-v7m.S:33
#1 0xc000bc2a in unwind_exec_insn (ctrl=<optimized out>) at arch/arm/kernel/unwind.c:321
#2 unwind_frame (frame=0xc023d0c0 <reset_devices>) at arch/arm/kernel/unwind.c:449
#3 0xc000caec in ?? () at arch/arm/mm/cache-v7.S:69
Backtrace stopped: previous frame identical to this frame (corrupt stack?) Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) f 3
#3 0xc000caec in ?? () at arch/arm/mm/cache-v7.S:69
69 ret lr
(gdb) info reg
r0 0x1 1 r1 0x0 0 r2 0x1 1 r3 0x0 0 r4 0x0 0 r5 0x100 256 r6 0x0 0 r7 0xa 10 r8 0x40096 262294 r9 0x0 0 r10 0xc012b004 -1072517116 r11 0x0 0 r12 0x29 41 sp 0xc0230018 0xc0230018 <cpu_cache+4> lr 0xc000caed -1073689875 pc 0xc000caec 0xc000caec <v7_flush_icache_all> xPSR 0x81000005 -2130706427
Thanks for your time.
Alex
cover ARM: V7M: Support caches
Quoted 48 lines · Alexandre Torgue
Hi Vladimir,
Quoted 45 lines · Alexandre Torgue
Hi Vladimir,
Quoted 42 lines · Vladimir Murzin
Hi Alex,
Quoted 23 lines · Alexandre Torgue
Hi Vladimir,
Quoted 20 lines · Vladimir Murzin
Hi,
This patch set allows M-class cpus benefit of optional cache support. It originaly was written by Jonny, I've been keeping it localy mainly rebasing over Linux versions.
The main idea behind patches is to reuse existing cache handling code from v7A/R. In case v7M cache operations are provided via memory mapped interface rather than co-processor instructions, so extra macros have been introduced to factor out cache handling logic and low-level operations.
Along with the v7M cache support the first user (Cortex-M7) is introduced.
Patches were tested on MPS2 platform with Cortex-M3/M4/M7. The later one showed significant boot speed-up.
Based on 4.7-rc3.
Quoted 8 lines
Quoted 3 lines
Thanks!
VladimirThanks for the series.
Did you change something in those patches compare to patches you sent in
the RFC ?Only 04, 05, 06 have been changed (each has it's own changelog included).
I did try to hammer patches because of your report of instability with caches on, but all run fine... so nothing has been changed in regard of your case.
Quoted 8 lines
Quoted 4 lines
Ok. Thanks for this input. From now, I will use this series to perform my tests. I will continue to debug my instabilities this week. I will let you know.
I fixed my instabilities and it was linked to my SDRAM timings :(. I don't see behavior issues with your series (You can add my Tested-by:
Alexandre TORGUE <[email protected]>).
Great! Since I have to re-work series per Russell comments I'd very appreciate your Tested-by on further versions of the patch set.
Quoted 7 lines
I have two others questions for you:
1- Maybe I didn't search deeper in the code but when you enable Dcache and Icache, what is the state of cache ? I mean we need to invalidate caches before enable it. It is done by kernel (with your patches) or it has to be done by a bootloader ?
I believe it follows A/R practice, so, yes, it is up to the bootloader to make sure that cache state is consistent.
Quoted 7 lines
2- I observe an issue (IMO not linked to your series) when I switch off/switch on my board. During the first boot after an hard reset I get a bus error (BFSR part in CFSR register indicates an "A bus fault on an instruction prefetch has occurred."). After SRST reset through JTAG, the kernel boot correctly.
Do you already seen this kind of issue ?
I didn't see anything like that, sorry.
Thanks
Vladimir
Quoted 43 lines
I add the backtrace and registers info.
__invalid_entry() atarch/arm/kernel/entry-v7m.S:33
33 1: b 1b
(gdb) bt
#0__invalid_entry() atarch/arm/kernel/entry-v7m.S:33
#10xc000bc2ainunwind_exec_insn(ctrl=<optimized out>) atarch/arm/kernel/unwind.c:321
#2unwind_frame(frame=0xc023d0c0 <reset_devices>) atarch/arm/kernel/unwind.c:449
#30xc000caecin ?? () atarch/arm/mm/cache-v7.S:69
Backtrace stopped: previous frame identical to this frame (corrupt stack?) Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) f 3
#30xc000caecin ?? () atarch/arm/mm/cache-v7.S:69
69 ret lr
(gdb) info regr0 0x1 1 r1 0x0 0 r2 0x1 1 r3 0x0 0 r4 0x0 0 r5 0x100 256 r6 0x0 0 r7 0xa 10 r8 0x40096 262294 r9 0x0 0 r10 0xc012b004 -1072517116 r11 0x0 0 r12 0x29 41 sp 0xc0230018 0xc0230018 <cpu_cache+4> lr 0xc000caed -1073689875 pc 0xc000caec 0xc000caec <v7_flush_icache_all> xPSR 0x81000005 -2130706427Thanks for your time.
Alex