diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5f472a8b406a..e7904bc92c73 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -379,7 +379,7 @@ config CPU_V7 select CPU_CP15_MMU select CPU_HAS_ASID select CPU_COPY_V6 if MMU - select CPU_TLB_V6 if MMU + select CPU_TLB_V7 if MMU # Figure out what processor architecture version we should be using. # This defines the compiler instruction set which depends on the machine type. @@ -498,6 +498,9 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool +config CPU_TLB_V7 + bool + endif config CPU_HAS_ASID diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index b5bd335ff14a..762702765fc3 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o +obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index dd823dd4a374..718f4782ee8b 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -256,7 +256,7 @@ __v7_proc_info: .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP .long cpu_v7_name .long v7_processor_functions - .long v6wbi_tlb_fns + .long v7wbi_tlb_fns .long v6_user_fns .long v7_cache_fns .size __v7_proc_info, . - __v7_proc_info diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S new file mode 100644 index 000000000000..b56dda8052f7 --- /dev/null +++ b/arch/arm/mm/tlb-v7.S @@ -0,0 +1,88 @@ +/* + * linux/arch/arm/mm/tlb-v7.S + * + * Copyright (C) 1997-2002 Russell King + * Modified for ARMv7 by Catalin Marinas + * + * 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. + * + * ARM architecture version 6 TLB handling functions. + * These assume a split I/D TLB. + */ +#include +#include +#include +#include +#include "proc-macros.S" + +/* + * v7wbi_flush_user_tlb_range(start, end, vma) + * + * Invalidate a range of TLB entries in the specified address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - vma - vma_struct describing address range + * + * It is assumed that: + * - the "Invalidate single entry" instruction will invalidate + * both the I and the D TLBs on Harvard-style TLBs + */ +ENTRY(v7wbi_flush_user_tlb_range) + vma_vm_mm r3, r2 @ get vma->vm_mm + mmid r3, r3 @ get vm_mm->context.id + dsb + mov r0, r0, lsr #PAGE_SHIFT @ align address + mov r1, r1, lsr #PAGE_SHIFT + asid r3, r3 @ mask ASID + orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA + mov r1, r1, lsl #PAGE_SHIFT + vma_vm_flags r2, r2 @ get vma->vm_flags +1: + mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA (was 1) + tst r2, #VM_EXEC @ Executable area ? + mcrne p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA (was 1) + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov ip, #0 + mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB + dsb + mov pc, lr + +/* + * v7wbi_flush_kern_tlb_range(start,end) + * + * Invalidate a range of kernel TLB entries + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + */ +ENTRY(v7wbi_flush_kern_tlb_range) + dsb + mov r0, r0, lsr #PAGE_SHIFT @ align address + mov r1, r1, lsr #PAGE_SHIFT + mov r0, r0, lsl #PAGE_SHIFT + mov r1, r1, lsl #PAGE_SHIFT +1: + mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA + mcr p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov r2, #0 + mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB + dsb + isb + mov pc, lr + + .section ".text.init", #alloc, #execinstr + + .type v7wbi_tlb_fns, #object +ENTRY(v7wbi_tlb_fns) + .long v7wbi_flush_user_tlb_range + .long v7wbi_flush_kern_tlb_range + .long v6wbi_tlb_flags + .size v7wbi_tlb_fns, . - v7wbi_tlb_fns diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h index ccd0de010e81..71be4fded7e2 100644 --- a/include/asm-arm/tlbflush.h +++ b/include/asm-arm/tlbflush.h @@ -138,6 +138,19 @@ # define v6wbi_always_flags (-1UL) #endif +#ifdef CONFIG_CPU_TLB_V7 +# define v7wbi_possible_flags v6wbi_tlb_flags +# define v7wbi_always_flags v6wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v7wbi +# endif +#else +# define v7wbi_possible_flags 0 +# define v7wbi_always_flags (-1UL) +#endif + #ifndef _TLB #error Unknown TLB model #endif