From a7039bd6daa32f5ea1a185b7cb0b3b519e1f5018 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 24 Apr 2008 01:31:46 -0400 Subject: [ARM] feroceon: remove CONFIG_CPU_DCACHE_WRITETHROUGH check Since the Feroceon doesn't have a global WT override bit like ARM926 does, remove all code relating to this mode of operation from proc-feroceon.S. Signed-off-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre --- arch/arm/mm/Kconfig | 2 +- arch/arm/mm/proc-feroceon.S | 40 ---------------------------------------- 2 files changed, 1 insertion(+), 41 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 1b8229d9c9d..a92a577c1b6 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -658,7 +658,7 @@ config CPU_DCACHE_SIZE config CPU_DCACHE_WRITETHROUGH bool "Force write through D-cache" - depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FEROCEON) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index 90e7594e29b..e9ac984d289 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -118,12 +118,8 @@ ENTRY(feroceon_flush_kern_cache_all) mov r2, #VM_EXEC mov ip, #0 __flush_whole_cache: -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache -#else 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate bne 1b -#endif tst r2, #VM_EXEC mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache mcrne p15, 0, ip, c7, c10, 4 @ drain WB @@ -145,21 +141,12 @@ ENTRY(feroceon_flush_user_cache_range) cmp r3, #CACHE_DLIMIT bgt __flush_whole_cache 1: tst r2, #VM_EXEC -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry - mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE - mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry - mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE -#else mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry add r0, r0, #CACHE_DLINESIZE mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry add r0, r0, #CACHE_DLINESIZE -#endif cmp r0, r1 blo 1b tst r2, #VM_EXEC @@ -232,12 +219,10 @@ ENTRY(feroceon_flush_kern_dcache_page) * (same as v4wb) */ ENTRY(feroceon_dma_inv_range) -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH tst r0, #CACHE_DLINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry tst r1, #CACHE_DLINESIZE - 1 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry -#endif bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #CACHE_DLINESIZE @@ -257,13 +242,11 @@ ENTRY(feroceon_dma_inv_range) * (same as v4wb) */ ENTRY(feroceon_dma_clean_range) -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b -#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr @@ -278,11 +261,7 @@ ENTRY(feroceon_dma_clean_range) ENTRY(feroceon_dma_flush_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry -#else - mcr p15, 0, r0, c7, c10, 1 @ clean D entry -#endif add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b @@ -301,12 +280,10 @@ ENTRY(feroceon_cache_fns) .long feroceon_dma_flush_range ENTRY(cpu_feroceon_dcache_clean_area) -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE subs r1, r1, #CACHE_DLINESIZE bhi 1b -#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr @@ -323,13 +300,9 @@ ENTRY(cpu_feroceon_dcache_clean_area) ENTRY(cpu_feroceon_switch_mm) #ifdef CONFIG_MMU mov ip, #0 -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache -#else @ && 'Clean & Invalidate whole DCache' 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate bne 1b -#endif mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer @@ -362,16 +335,9 @@ ENTRY(cpu_feroceon_set_pte_ext) tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? movne r2, #0 -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - eor r3, r2, #0x0a @ C & small page? - tst r3, #0x0b - biceq r2, r2, #4 -#endif str r2, [r0] @ hardware version mov r0, r0 -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, r0, c7, c10, 1 @ clean D entry -#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB #endif mov pc, lr @@ -387,12 +353,6 @@ __feroceon_setup: mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 #endif - -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mov r0, #4 @ disable write-back on caches explicitly - mcr p15, 7, r0, c15, c0, 0 -#endif - adr r5, feroceon_crval ldmia r5, {r5, r6} mrc p15, 0, r0, c1, c0 @ get control register v4 -- cgit v1.2.3 From c5a1e8f7091c33c7f6b53f070d13380facab6607 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 24 Apr 2008 01:31:46 -0400 Subject: [ARM] feroceon: remove CONFIG_CPU_CACHE_ROUND_ROBIN check Since the Feroceon cache replacement policy is always pseudorandom (and the relevant control register bit is ignored), remove the CONFIG_CPU_CACHE_ROUND_ROBIN check from proc-feroceon.S. Signed-off-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre --- arch/arm/mm/proc-feroceon.S | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index e9ac984d289..3ceb6785a34 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -358,9 +358,6 @@ __feroceon_setup: mrc p15, 0, r0, c1, c0 @ get control register v4 bic r0, r0, r5 orr r0, r0, r6 -#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN - orr r0, r0, #0x4000 @ .1.. .... .... .... -#endif mov pc, lr .size __feroceon_setup, . - __feroceon_setup -- cgit v1.2.3 From 6b29e681aa7e80792e6e6be4ac2577014018c2fd Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 25 Apr 2008 13:56:32 -0400 Subject: [ARM] Feroceon: fix function alignment in proc-feroceon.S One overzealous .align 10 fixed, and a few .align5 added. Signed-off-by: Nicolas Pitre --- arch/arm/mm/proc-feroceon.S | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index 3ceb6785a34..f37abd71056 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -93,7 +93,7 @@ ENTRY(cpu_feroceon_reset) * * Called with IRQs disabled */ - .align 10 + .align 5 ENTRY(cpu_feroceon_do_idle) mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer @@ -106,6 +106,7 @@ ENTRY(cpu_feroceon_do_idle) * Clean and invalidate all cache entries in a particular * address space. */ + .align 5 ENTRY(feroceon_flush_user_cache_all) /* FALLTHROUGH */ @@ -135,6 +136,7 @@ __flush_whole_cache: * - end - end address (exclusive) * - flags - vm_flags describing address space */ + .align 5 ENTRY(feroceon_flush_user_cache_range) mov ip, #0 sub r3, r1, r0 @ calculate total size @@ -163,6 +165,7 @@ ENTRY(feroceon_flush_user_cache_range) * - start - virtual start address * - end - virtual end address */ + .align 5 ENTRY(feroceon_coherent_kern_range) /* FALLTHROUGH */ @@ -194,6 +197,7 @@ ENTRY(feroceon_coherent_user_range) * * - addr - page aligned address */ + .align 5 ENTRY(feroceon_flush_kern_dcache_page) add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry @@ -218,6 +222,7 @@ ENTRY(feroceon_flush_kern_dcache_page) * * (same as v4wb) */ + .align 5 ENTRY(feroceon_dma_inv_range) tst r0, #CACHE_DLINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry @@ -241,6 +246,7 @@ ENTRY(feroceon_dma_inv_range) * * (same as v4wb) */ + .align 5 ENTRY(feroceon_dma_clean_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry @@ -258,10 +264,10 @@ ENTRY(feroceon_dma_clean_range) * - start - virtual start address * - end - virtual end address */ + .align 5 ENTRY(feroceon_dma_flush_range) bic r0, r0, #CACHE_DLINESIZE - 1 -1: - mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 blo 1b @@ -279,6 +285,7 @@ ENTRY(feroceon_cache_fns) .long feroceon_dma_clean_range .long feroceon_dma_flush_range + .align 5 ENTRY(cpu_feroceon_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE -- cgit v1.2.3 From 0ed1507183adea174bc4b6611b50d90e044730c2 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 24 Apr 2008 01:31:45 -0400 Subject: [ARM] Feroceon: Feroceon-specific WA-cache compatible {copy,clear}_user_page() This patch implements a set of Feroceon-specific {copy,clear}_user_page() routines that perform more optimally than the generic implementations. This also deals with write-allocate caches (Feroceon can run L1 D in WA mode) which otherwise prevents Linux from booting. [nico: optimized the code even further] Signed-off-by: Lennert Buytenhek Tested-by: Sylver Bruneau Tested-by: Martin Michlmayr Signed-off-by: Nicolas Pitre --- arch/arm/mm/Kconfig | 5 ++- arch/arm/mm/Makefile | 1 + arch/arm/mm/copypage-feroceon.S | 95 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/proc-feroceon.S | 4 +- 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mm/copypage-feroceon.S (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index a92a577c1b6..33ed048502a 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -372,7 +372,7 @@ config CPU_FEROCEON select CPU_PABRT_NOIFAR select CPU_CACHE_VIVT select CPU_CP15_MMU - select CPU_COPY_V4WB if MMU + select CPU_COPY_FEROCEON if MMU select CPU_TLB_V4WBI if MMU config CPU_FEROCEON_OLD_ID @@ -523,6 +523,9 @@ config CPU_COPY_V4WT config CPU_COPY_V4WB bool +config CPU_COPY_FEROCEON + bool + config CPU_COPY_V6 bool diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 44536a0b995..32b2d2d213a 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o +obj-$(CONFIG_CPU_COPY_FEROCEON) += copypage-feroceon.o obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o diff --git a/arch/arm/mm/copypage-feroceon.S b/arch/arm/mm/copypage-feroceon.S new file mode 100644 index 00000000000..7eb0d320d24 --- /dev/null +++ b/arch/arm/mm/copypage-feroceon.S @@ -0,0 +1,95 @@ +/* + * linux/arch/arm/lib/copypage-feroceon.S + * + * Copyright (C) 2008 Marvell Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This handles copy_user_page and clear_user_page on Feroceon + * more optimally than the generic implementations. + */ +#include +#include +#include + + .text + .align 5 + +ENTRY(feroceon_copy_user_page) + stmfd sp!, {r4-r9, lr} + mov ip, #PAGE_SZ +1: mov lr, r1 + ldmia r1!, {r2 - r9} + pld [lr, #32] + pld [lr, #64] + pld [lr, #96] + pld [lr, #128] + pld [lr, #160] + pld [lr, #192] + pld [lr, #224] + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + ldmia r1!, {r2 - r9} + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + stmia r0, {r2 - r9} + subs ip, ip, #(32 * 8) + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + bne 1b + mcr p15, 0, ip, c7, c10, 4 @ drain WB + ldmfd sp!, {r4-r9, pc} + + .align 5 + +ENTRY(feroceon_clear_user_page) + stmfd sp!, {r4-r7, lr} + mov r1, #PAGE_SZ/32 + mov r2, #0 + mov r3, #0 + mov r4, #0 + mov r5, #0 + mov r6, #0 + mov r7, #0 + mov ip, #0 + mov lr, #0 +1: stmia r0, {r2-r7, ip, lr} + subs r1, r1, #1 + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line + add r0, r0, #32 + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + ldmfd sp!, {r4-r7, pc} + + __INITDATA + + .type feroceon_user_fns, #object +ENTRY(feroceon_user_fns) + .long feroceon_clear_user_page + .long feroceon_copy_user_page + .size feroceon_user_fns, . - feroceon_user_fns diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index f37abd71056..a02c1712b52 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -440,7 +440,7 @@ __feroceon_old_id_proc_info: .long cpu_feroceon_name .long feroceon_processor_functions .long v4wbi_tlb_fns - .long v4wb_user_fns + .long feroceon_user_fns .long feroceon_cache_fns .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info #endif @@ -466,6 +466,6 @@ __feroceon_proc_info: .long cpu_feroceon_name .long feroceon_processor_functions .long v4wbi_tlb_fns - .long v4wb_user_fns + .long feroceon_user_fns .long feroceon_cache_fns .size __feroceon_proc_info, . - __feroceon_proc_info -- cgit v1.2.3