From 850b42933e70c19c7765dd7fad15cb7ad3955b65 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 5 Feb 2007 00:55:27 +0100 Subject: [ARM] 4123/1: xsc3: general cleanup This patch cleans up proc-xsc3: - Correct a number of typos. - Fix up indentation in a number of places. - Change references to the various caches to be more clear about whether we're talking about the L1 D, the L1 I or the unified L2 cache. - Rename "drain write buffer" to "data write barrier", the official name used in the Manzano manual. - Change the xsc3 cpu name from "XScale-Core3" to "XScale-V3 based processor". Also, since a previously merged patch implements proper support for using a MAC or iWMMXt coprocessor on xsc3 platforms, we no longer need to enable access to CP0 on boot. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mm/proc-xsc3.S | 151 ++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 76 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 94a58455f34..d95921a2ab9 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -5,23 +5,23 @@ * Current Maintainer: Lennert Buytenhek * * Copyright 2004 (C) Intel Corp. - * Copyright 2005 (c) MontaVista Software, Inc. + * Copyright 2005 (C) MontaVista Software, Inc. * * 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. * - * MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is an - * extension to Intel's original XScale core that adds the following + * MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is + * an extension to Intel's original XScale core that adds the following * features: * * - ARMv6 Supersections * - Low Locality Reference pages (replaces mini-cache) * - 36-bit addressing * - L2 cache - * - Cache-coherency if chipset supports it + * - Cache coherency if chipset supports it * - * Based on orignal XScale code by Nicolas Pitre + * Based on original XScale code by Nicolas Pitre. */ #include @@ -42,12 +42,12 @@ #define MAX_AREA_SIZE 32768 /* - * The cache line size of the I and D cache. + * The cache line size of the L1 I, L1 D and unified L2 cache. */ #define CACHELINESIZE 32 /* - * The size of the data cache. + * The size of the L1 D cache. */ #define CACHESIZE 32768 @@ -57,9 +57,9 @@ #define L2_CACHE_ENABLE 1 /* - * This macro is used to wait for a CP15 write and is needed - * when we have to ensure that the last operation to the co-pro - * was completed before continuing with operation. + * This macro is used to wait for a CP15 write and is needed when we + * have to ensure that the last operation to the coprocessor was + * completed before continuing with operation. */ .macro cpwait_ret, lr, rd mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 @@ -68,13 +68,13 @@ .endm /* - * This macro cleans & invalidates the entire xsc3 dcache by set & way. + * This macro cleans and invalidates the entire L1 D cache. */ .macro clean_d_cache rd, rs mov \rd, #0x1f00 orr \rd, \rd, #0x00e0 -1: mcr p15, 0, \rd, c7, c14, 2 @ clean/inv set/way +1: mcr p15, 0, \rd, c7, c14, 2 @ clean/invalidate L1 D line adds \rd, \rd, #0x40000000 bcc 1b subs \rd, \rd, #0x20 @@ -119,15 +119,15 @@ ENTRY(cpu_xsc3_reset) mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE msr cpsr_c, r1 @ reset CPSR mrc p15, 0, r1, c1, c0, 0 @ ctrl register - bic r1, r1, #0x0086 @ ........B....CA. bic r1, r1, #0x3900 @ ..VIZ..S........ + bic r1, r1, #0x0086 @ ........B....CA. mcr p15, 0, r1, c1, c0, 0 @ ctrl register - mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB + mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB bic r1, r1, #0x0001 @ ...............M mcr p15, 0, r1, c1, c0, 0 @ ctrl register @ CAUTION: MMU turned off from this point. We count on the pipeline @ already containing those two last instructions to survive. - mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs mov pc, r0 /* @@ -139,14 +139,12 @@ ENTRY(cpu_xsc3_reset) * * XScale supports clock switching, but using idle mode support * allows external hardware to react to system state changes. - - MMG: Come back to this one. */ .align 5 ENTRY(cpu_xsc3_do_idle) mov r0, #1 - mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE + mcr p14, 0, r0, c7, c0, 0 @ go to idle mov pc, lr /* ================================= CACHE ================================ */ @@ -171,9 +169,9 @@ ENTRY(xsc3_flush_kern_cache_all) __flush_whole_cache: clean_d_cache r0, r1 tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB - mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush + mcrne p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB + mcrne p15, 0, ip, c7, c10, 4 @ data write barrier + mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush mov pc, lr /* @@ -194,21 +192,21 @@ ENTRY(xsc3_flush_user_cache_range) bhs __flush_whole_cache 1: tst r2, #VM_EXEC - mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line - mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate D cache line + mcrne p15, 0, r0, c7, c5, 1 @ invalidate L1 I line + mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line add r0, r0, #CACHELINESIZE cmp r0, r1 blo 1b tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB - mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush + mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB + mcrne p15, 0, ip, c7, c10, 4 @ data write barrier + mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush mov pc, lr /* * coherent_kern_range(start, end) * - * Ensure coherency between the Icache and the Dcache in the + * Ensure coherency between the I cache and the D cache in the * region described by start. If you have non-snooping * Harvard caches, you need to implement this function. * @@ -222,34 +220,34 @@ ENTRY(xsc3_coherent_kern_range) /* FALLTHROUGH */ ENTRY(xsc3_coherent_user_range) bic r0, r0, #CACHELINESIZE - 1 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line add r0, r0, #CACHELINESIZE cmp r0, r1 blo 1b mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush + mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB + mcr p15, 0, r0, c7, c10, 4 @ data write barrier + mcr p15, 0, r0, c7, c5, 4 @ prefetch flush mov pc, lr /* * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or - * the I cache + * the I cache. * * - addr - page aligned address */ ENTRY(xsc3_flush_kern_dcache_page) add r1, r0, #PAGE_SZ -1: mcr p15, 0, r0, c7, c14, 1 @ Clean/Invalidate D Cache line +1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line add r0, r0, #CACHELINESIZE cmp r0, r1 blo 1b mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush + mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB + mcr p15, 0, r0, c7, c10, 4 @ data write barrier + mcr p15, 0, r0, c7, c5, 4 @ prefetch flush mov pc, lr /* @@ -266,17 +264,17 @@ ENTRY(xsc3_flush_kern_dcache_page) ENTRY(xsc3_dma_inv_range) tst r0, #CACHELINESIZE - 1 bic r0, r0, #CACHELINESIZE - 1 - mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D entry - mcrne p15, 1, r0, c7, c11, 1 @ clean L2 D entry + mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D line + mcrne p15, 1, r0, c7, c11, 1 @ clean L2 line tst r1, #CACHELINESIZE - 1 - mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D entry - mcrne p15, 1, r1, c7, c11, 1 @ clean L2 D entry -1: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D entry - mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line + mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D line + mcrne p15, 1, r1, c7, c11, 1 @ clean L2 line +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D line + mcr p15, 1, r0, c7, c7, 1 @ invalidate L2 line add r0, r0, #CACHELINESIZE cmp r0, r1 blo 1b - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer + mcr p15, 0, r0, c7, c10, 4 @ data write barrier mov pc, lr /* @@ -289,12 +287,12 @@ ENTRY(xsc3_dma_inv_range) */ ENTRY(xsc3_dma_clean_range) bic r0, r0, #CACHELINESIZE - 1 -1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D entry - mcr p15, 1, r0, c7, c11, 1 @ clean L2 D entry +1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line + mcr p15, 1, r0, c7, c11, 1 @ clean L2 line add r0, r0, #CACHELINESIZE cmp r0, r1 blo 1b - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer + mcr p15, 0, r0, c7, c10, 4 @ data write barrier mov pc, lr /* @@ -307,13 +305,13 @@ ENTRY(xsc3_dma_clean_range) */ ENTRY(xsc3_dma_flush_range) bic r0, r0, #CACHELINESIZE - 1 -1: mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate L1 D cache line - mcr p15, 1, r0, c7, c11, 1 @ Clean L2 D cache line - mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line +1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line + mcr p15, 1, r0, c7, c11, 1 @ clean L2 line + mcr p15, 1, r0, c7, c7, 1 @ invalidate L2 line add r0, r0, #CACHELINESIZE cmp r0, r1 blo 1b - mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer + mcr p15, 0, r0, c7, c10, 4 @ data write barrier mov pc, lr ENTRY(xsc3_cache_fns) @@ -328,7 +326,7 @@ ENTRY(xsc3_cache_fns) .long xsc3_dma_flush_range ENTRY(cpu_xsc3_dcache_clean_area) -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line add r0, r0, #CACHELINESIZE subs r1, r1, #CACHELINESIZE bhi 1b @@ -346,14 +344,14 @@ ENTRY(cpu_xsc3_dcache_clean_area) .align 5 ENTRY(cpu_xsc3_switch_mm) clean_d_cache r1, r2 - mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB - mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush + mcr p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB + mcr p15, 0, ip, c7, c10, 4 @ data write barrier + mcr p15, 0, ip, c7, c5, 4 @ prefetch flush #ifdef L2_CACHE_ENABLE orr r0, r0, #0x18 @ cache the page table in L2 #endif mcr p15, 0, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs cpwait_ret lr, ip /* @@ -366,34 +364,34 @@ ENTRY(cpu_xsc3_switch_mm) ENTRY(cpu_xsc3_set_pte_ext) str r1, [r0], #-2048 @ linux version - bic r2, r1, #0xff0 @ Keep C, B bits + bic r2, r1, #0xff0 @ keep C, B bits orr r2, r2, #PTE_TYPE_EXT @ extended page - tst r1, #L_PTE_SHARED @ Shared? + tst r1, #L_PTE_SHARED @ shared? orrne r2, r2, #0x200 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY - tst r3, #L_PTE_USER @ User? + tst r3, #L_PTE_USER @ user? orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w - tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w @ combined with user -> user r/w #if L2_CACHE_ENABLE - @ If its cacheable it needs to be in L2 also. + @ If it's cacheable, it needs to be in L2 also. eor ip, r1, #L_PTE_CACHEABLE tst ip, #L_PTE_CACHEABLE orreq r2, r2, #PTE_EXT_TEX(0x5) #endif - tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? movne r2, #0 @ no -> fault str r2, [r0] @ hardware version mov ip, #0 - mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line mcr - mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer + mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line + mcr p15, 0, ip, c7, c10, 4 @ data write barrier mov pc, lr .ltorg @@ -406,17 +404,18 @@ ENTRY(cpu_xsc3_set_pte_ext) __xsc3_setup: mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE msr cpsr_c, r0 - mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB - mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer - mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush - mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs + mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB + mcr p15, 0, ip, c7, c10, 4 @ data write barrier + mcr p15, 0, ip, c7, c5, 4 @ prefetch flush + mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs #if L2_CACHE_ENABLE orr r4, r4, #0x18 @ cache the page table in L2 #endif mcr p15, 0, r4, c2, c0, 0 @ load page table pointer - mov r0, #1 @ Allow access to CP0 and CP13 - orr r0, r0, #1 << 13 @ Its undefined whether this - mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes + + mov r0, #0 @ don't allow CP access + mcr p15, 0, r0, c15, c1, 0 @ write CP access register + mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg and r0, r0, #2 @ preserve bit P bit setting #if L2_CACHE_ENABLE @@ -427,9 +426,9 @@ __xsc3_setup: adr r5, xsc3_crval ldmia r5, {r5, r6} mrc p15, 0, r0, c1, c0, 0 @ get control register - bic r0, r0, r5 @ .... .... .... ..A. - orr r0, r0, r6 @ .... .... .... .C.M - orr r0, r0, #0x00000800 @ ..VI Z..S .... .... + bic r0, r0, r5 @ ..V. ..R. .... ..A. + orr r0, r0, r6 @ ..VI Z..S .... .C.M (mmu) + @ ...I Z..S .... .... (uc) #if L2_CACHE_ENABLE orr r0, r0, #0x04000000 @ L2 enable #endif @@ -439,7 +438,7 @@ __xsc3_setup: .type xsc3_crval, #object xsc3_crval: - crval clear=0x04003b02, mmuset=0x00003105, ucset=0x00001100 + crval clear=0x04002202, mmuset=0x00003905, ucset=0x00001900 __INITDATA @@ -474,7 +473,7 @@ cpu_elf_name: .type cpu_xsc3_name, #object cpu_xsc3_name: - .asciz "XScale-Core3" + .asciz "XScale-V3 based processor" .size cpu_xsc3_name, . - cpu_xsc3_name .align @@ -490,7 +489,7 @@ __xsc3_proc_info: PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ + .long PMD_TYPE_SECT | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ b __xsc3_setup -- cgit v1.2.3 From 9d99df4b10eef130dacb5f772cd589c625b03634 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 5 Feb 2007 14:47:40 +0100 Subject: [ARM] 4128/1: Architecture compliant TTBR changing sequence On newer architectures (ARMv6, ARMv7), the depth of the prefetch and branch prediction is implementation defined and there is a small risk of wrong ASID tagging when changing TTBR0 before setting the new context id. The recommended solution is to set a reserved ASID during TTBR changing. This patch reserves ASID 0. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/context.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 79e80020242..9da43a0fdcd 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -19,7 +19,8 @@ unsigned int cpu_last_asid = { 1 << ASID_BITS }; /* * We fork()ed a process, and we need a new context for the child * to run in. We reserve version 0 for initial tasks so we will - * always allocate an ASID. + * always allocate an ASID. The ASID 0 is reserved for the TTBR + * register changing sequence. */ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) { @@ -38,8 +39,15 @@ void __new_context(struct mm_struct *mm) * If we've used up all our ASIDs, we need * to start a new version and flush the TLB. */ - if ((asid & ~ASID_MASK) == 0) + if ((asid & ~ASID_MASK) == 0) { + asid = ++cpu_last_asid; + /* set the reserved ASID before flushing the TLB */ + asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n" + : + : "r" (0)); + isb(); flush_tlb_all(); + } mm->context.id = asid; } -- cgit v1.2.3 From e6a5d66f58431c66c79e236f722a5ad7dd959ef3 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 5 Feb 2007 14:47:51 +0100 Subject: [ARM] 4129/1: Add barriers after the TLB operations The architecture specification states that TLB operations are guaranteed to be complete only after the execution of a DSB (Data Synchronisation Barrier, former Data Write Barrier or Drain Write Buffer). The branch target cache invalidation is also needed. The ISB (Instruction Synchronisation Barrier, formerly Prefetch Flush) is needed unless there will be a return from exception before the corresponding mapping is used (i.e. user mappings). Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/tlb-v6.S | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S index fd6adde3909..20f84bbaa9b 100644 --- a/arch/arm/mm/tlb-v6.S +++ b/arch/arm/mm/tlb-v6.S @@ -53,6 +53,8 @@ ENTRY(v6wbi_flush_user_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b + mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB + mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier mov pc, lr /* @@ -80,7 +82,9 @@ ENTRY(v6wbi_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b + mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier + mcr p15, 0, r2, c7, c5, 4 @ prefetch flush mov pc, lr .section ".text.init", #alloc, #execinstr -- cgit v1.2.3 From 953233dc9958ba2b29753d0f24e37a33a076a5f6 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 5 Feb 2007 14:48:08 +0100 Subject: [ARM] 4134/1: Add generic support for outer caches The outer cache can be L2 as on RealView/EB MPCore platform or even L3 or further on ARMv7 cores. This patch adds the generic support for flushing the outer cache in the DMA operations. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 3 +++ arch/arm/mm/consistent.c | 6 ++++++ 2 files changed, 9 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index aade2f72c92..a84eed9f854 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -609,3 +609,6 @@ config NEEDS_SYSCALL_FOR_CMPXCHG Forget about fast user space cmpxchg support. It is just not possible. +config OUTER_CACHE + bool + default n diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 6a9c362fef5..83bd035c7d5 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -208,6 +208,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, unsigned long kaddr = (unsigned long)page_address(page); memset(page_address(page), 0, size); dmac_flush_range(kaddr, kaddr + size); + outer_flush_range(__pa(kaddr), __pa(kaddr) + size); } /* @@ -485,15 +486,20 @@ void consistent_sync(void *vaddr, size_t size, int direction) unsigned long start = (unsigned long)vaddr; unsigned long end = start + size; + BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end)); + switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ dmac_inv_range(start, end); + outer_inv_range(__pa(start), __pa(end)); break; case DMA_TO_DEVICE: /* writeback only */ dmac_clean_range(start, end); + outer_clean_range(__pa(start), __pa(end)); break; case DMA_BIDIRECTIONAL: /* writeback and invalidate */ dmac_flush_range(start, end); + outer_flush_range(__pa(start), __pa(end)); break; default: BUG(); -- cgit v1.2.3 From 7ae5a761d2ffc4cf7d3248e09f4d3da234434f30 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Feb 2007 17:39:31 +0000 Subject: [ARM] Convert DMA cache handling to take const void * args The DMA cache handling functions take virtual addresses, but in the form of unsigned long arguments. This leads to a little confusion about what exactly they take. So, convert them to take const void * instead. Signed-off-by: Russell King --- arch/arm/mm/consistent.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 83bd035c7d5..166aee13c4b 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -205,10 +205,10 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, * kernel direct-mapped region for device DMA. */ { - unsigned long kaddr = (unsigned long)page_address(page); - memset(page_address(page), 0, size); - dmac_flush_range(kaddr, kaddr + size); - outer_flush_range(__pa(kaddr), __pa(kaddr) + size); + void *ptr = page_address(page); + memset(ptr, 0, size); + dmac_flush_range(ptr, ptr + size); + outer_flush_range(__pa(ptr), __pa(ptr) + size); } /* @@ -481,10 +481,9 @@ core_initcall(consistent_init); * platforms with CONFIG_DMABOUNCE. * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ -void consistent_sync(void *vaddr, size_t size, int direction) +void consistent_sync(const void *start, size_t size, int direction) { - unsigned long start = (unsigned long)vaddr; - unsigned long end = start + size; + const void *end = start + size; BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end)); -- cgit v1.2.3 From b2c6561605da4802886cafe96432b8e2968e9edc Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 8 Feb 2007 09:42:40 +0100 Subject: [ARM] 4145/2: AT91: Add support for AT91SAM9263 processor Add support for the Atmel AT91SAM9263 processor. It is similar to the AT91SAM9260 but with more integrated peripherals, 5 GPIO banks, etc. Original patch from Nicolas Ferre. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index aade2f72c92..b305cbda8b8 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -171,8 +171,8 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 - default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT -- cgit v1.2.3 From 3e1a80f11f89f318e892694b501735abb51ef626 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 8 Feb 2007 16:26:23 +0100 Subject: [ARM] 4153/1: fix consistent_sync() off-by-one BUG check In consistent_sync(), start + size can end up pointing one byte beyond the end of the direct RAM mapping. We shouldn't BUG() when this happens. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mm/consistent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 166aee13c4b..1f9f94f9af4 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -485,7 +485,7 @@ void consistent_sync(const void *start, size_t size, int direction) { const void *end = start + size; - BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end)); + BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1)); switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ -- cgit v1.2.3 From f2131d348f0bd252801f641018a90d59c987ce48 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 8 Feb 2007 20:46:20 +0000 Subject: [ARM] Always mark ARMv6 PTWs outer cacheable Other platforms other than SMP may have an outer cache. For these, we also need to mark the page table walks outer cacheable. Since marking the walks always outer cacheable apparantly has no side effects, we might as well always mark them so. However, we continue to only mark PTWs shared if we have SMP enabled. Signed-off-by: Russell King --- arch/arm/mm/proc-v6.S | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 7b1843befb9..d78c0ae7c2c 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -30,6 +30,12 @@ #define TTB_RGN_WT (2 << 3) #define TTB_RGN_WB (3 << 3) +#ifndef CONFIG_SMP +#define TTB_FLAGS TTB_RGN_WBWA +#else +#define TTB_FLAGS TTB_RGN_WBWA|TTB_S +#endif + ENTRY(cpu_v6_proc_init) mov pc, lr @@ -92,9 +98,7 @@ ENTRY(cpu_v6_switch_mm) #ifdef CONFIG_MMU mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id -#ifdef CONFIG_SMP - orr r0, r0, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable -#endif + orr r0, r0, #TTB_FLAGS mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, r2, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 @@ -204,9 +208,7 @@ __v6_setup: #ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register -#ifdef CONFIG_SMP - orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable -#endif + orr r4, r4, #TTB_FLAGS mcr p15, 0, r4, c2, c0, 1 @ load TTB1 #endif /* CONFIG_MMU */ adr r5, v6_crval -- cgit v1.2.3 From 382266ad5ad4119ec12df889afa5062a0a0cd6ae Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 5 Feb 2007 14:48:19 +0100 Subject: [ARM] 4135/1: Add support for the L210/L220 cache controllers This patch adds the support for the L210/L220 (outer) cache controller. The cache range operations are done by index/way since L2 cache controller only accepts physical addresses. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 4 ++ arch/arm/mm/Makefile | 2 + arch/arm/mm/cache-l2x0.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 arch/arm/mm/cache-l2x0.c (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index a84eed9f854..af3fa9d622f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -612,3 +612,7 @@ config NEEDS_SYSCALL_FOR_CMPXCHG config OUTER_CACHE bool default n + +config CACHE_L2X0 + bool + select OUTER_CACHE diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index d2f5672ecf6..2f8b9594777 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -66,3 +66,5 @@ obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o obj-$(CONFIG_CPU_V6) += proc-v6.o + +obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c new file mode 100644 index 00000000000..08a36f1b35d --- /dev/null +++ b/arch/arm/mm/cache-l2x0.c @@ -0,0 +1,104 @@ +/* + * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support + * + * Copyright (C) 2007 ARM Limited + * + * 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include + +#include +#include +#include + +#define CACHE_LINE_SIZE 32 + +static void __iomem *l2x0_base; + +static inline void sync_writel(unsigned long val, unsigned long reg, + unsigned long complete_mask) +{ + writel(val, l2x0_base + reg); + /* wait for the operation to complete */ + while (readl(l2x0_base + reg) & complete_mask) + ; +} + +static inline void cache_sync(void) +{ + sync_writel(0, L2X0_CACHE_SYNC, 1); +} + +static inline void l2x0_inv_all(void) +{ + /* invalidate all ways */ + sync_writel(0xff, L2X0_INV_WAY, 0xff); + cache_sync(); +} + +static void l2x0_inv_range(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(CACHE_LINE_SIZE - 1); + for (addr = start; addr < end; addr += CACHE_LINE_SIZE) + sync_writel(addr, L2X0_INV_LINE_PA, 1); + cache_sync(); +} + +static void l2x0_clean_range(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(CACHE_LINE_SIZE - 1); + for (addr = start; addr < end; addr += CACHE_LINE_SIZE) + sync_writel(addr, L2X0_CLEAN_LINE_PA, 1); + cache_sync(); +} + +static void l2x0_flush_range(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(CACHE_LINE_SIZE - 1); + for (addr = start; addr < end; addr += CACHE_LINE_SIZE) + sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1); + cache_sync(); +} + +void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) +{ + __u32 aux; + + l2x0_base = base; + + /* disable L2X0 */ + writel(0, l2x0_base + L2X0_CTRL); + + aux = readl(l2x0_base + L2X0_AUX_CTRL); + aux &= aux_mask; + aux |= aux_val; + writel(aux, l2x0_base + L2X0_AUX_CTRL); + + l2x0_inv_all(); + + /* enable L2X0 */ + writel(1, l2x0_base + L2X0_CTRL); + + outer_cache.inv_range = l2x0_inv_range; + outer_cache.clean_range = l2x0_clean_range; + outer_cache.flush_range = l2x0_flush_range; + + printk(KERN_INFO "L2X0 cache controller enabled\n"); +} -- cgit v1.2.3 From 44b18693904e65d840ae999ac8aa717551cf509f Mon Sep 17 00:00:00 2001 From: Imre_Deak Date: Sun, 11 Feb 2007 13:45:13 +0100 Subject: [ARM] 4158/1: Fix user page protection macros The PAGE_* user page protection macros don't take into account the configured memory policy and other architecture specific bits like the global/ASID and shared mapping bits. Instead of constants let these depend on a variable fixed up at init just like PAGE_KERNEL. Signed-off-by: Imre Deak Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 655c8376f0b..94fd4bf5cb9 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -49,8 +49,10 @@ pmd_t *top_pmd; static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; static unsigned int ecc_mask __initdata = 0; +pgprot_t pgprot_user; pgprot_t pgprot_kernel; +EXPORT_SYMBOL(pgprot_user); EXPORT_SYMBOL(pgprot_kernel); struct cachepolicy { @@ -345,6 +347,7 @@ static void __init build_mem_type_table(void) mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); } + pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot); pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | L_PTE_EXEC | kern_pgprot); -- cgit v1.2.3 From 4b17244c133689ad0cbdca37ce3e15068f120428 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 14 Feb 2007 19:20:28 +0100 Subject: [ARM] 4109/2: Add support for the RealView/EB MPCore revC platform The kernel originally supported revB only. This patch enables revC by default and adds a config option for building the kernel for the revB platform. Since the SCU base address was hard-coded in the proc-v6.S file (and only valid for RealView/EB revB), this patch also adds a more generic support for defining the SCU information. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/proc-v6.S | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 7b1843befb9..f27d9eb6480 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -14,10 +14,13 @@ #include #include #include -#include #include #include +#ifdef CONFIG_SMP +#include +#endif + #include "proc-macros.S" #define D_CACHE_LINE_SIZE 32 @@ -183,8 +186,7 @@ __v6_setup: /* Set up the SCU on core 0 only */ mrc p15, 0, r0, c0, c0, 5 @ CPU core number ands r0, r0, #15 - moveq r0, #0x10000000 @ SCU_BASE - orreq r0, r0, #0x00100000 + ldreq r0, =SCU_BASE ldreq r5, [r0, #SCU_CTRL] orreq r5, r5, #1 streq r5, [r0, #SCU_CTRL] -- cgit v1.2.3 From cb36bb7516fdd1a2a7e9155413b83d4330e4c4a7 Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Wed, 14 Feb 2007 17:44:28 +0100 Subject: [ARM] 4191/1: Remove redundant __flush_dcache_page() function prototype Commit 1c9d3df5e88ad7db23f5b22f4341c39722a904a4 added function prototype __flush_dcache_page() in include/asm-arm/cacheflush.h. So we can remove the prototype for same in arch/arm/mm/fault-armv.c since it is now redundant to have it there. Signed-off-by: George G. Davis Signed-off-by: Russell King --- arch/arm/mm/fault-armv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index cf95c5d0ce4..44558d5f931 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -119,8 +119,6 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigne flush_cache_page(vma, addr, pfn); } -void __flush_dcache_page(struct address_space *mapping, struct page *page); - /* * Take care of architecture specific things when placing a new PTE into * a page table, or changing an existing PTE. Basically, there are two -- cgit v1.2.3 From 9918cda52368ec3df5bb6bc1630ba8c070ad9fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 16 Feb 2007 15:36:55 +0100 Subject: [ARM] 4210/1: base for new machine type "NetSilicon NS9360" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index aade2f72c92..27624447ec7 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -171,8 +171,8 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 - default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_NS9XXX + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_NS9XXX select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT -- cgit v1.2.3