From 2ccdd1e77da52ad494e9af46bf272d816830cb28 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 18 May 2007 11:25:31 +0100 Subject: [PATCH] [ARM] 4394/1: ARMv7: Add the TLB range operations We are currently using the ARMv6 operations but need to duplicate some of the code because of the introduction of the new CPU barrier instructions in ARMv7. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 5 ++- arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-v7.S | 2 +- arch/arm/mm/tlb-v7.S | 88 ++++++++++++++++++++++++++++++++++++++ include/asm-arm/tlbflush.h | 13 ++++++ 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mm/tlb-v7.S diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5f472a8b406..e7904bc92c7 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 b5bd335ff14..762702765fc 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 dd823dd4a37..718f4782ee8 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 00000000000..b56dda8052f --- /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 ccd0de010e8..71be4fded7e 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 -- 2.41.1