mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
6ebbf2ce43
ARMv6 and greater introduced a new instruction ("bx") which can be used to return from function calls. Recent CPUs perform better when the "bx lr" instruction is used rather than the "mov pc, lr" instruction, and this sequence is strongly recommended to be used by the ARM architecture manual (section A.4.1.1). We provide a new macro "ret" with all its variants for the condition code which will resolve to the appropriate instruction. Rather than doing this piecemeal, and miss some instances, change all the "mov pc" instances to use the new macro, with the exception of the "movs" instruction and the kprobes code. This allows us to detect the "mov pc, lr" case and fix it up - and also gives us the possibility of deploying this for other registers depending on the CPU selection. Reported-by: Will Deacon <will.deacon@arm.com> Tested-by: Stephen Warren <swarren@nvidia.com> # Tegra Jetson TK1 Tested-by: Robert Jarzmik <robert.jarzmik@free.fr> # mioa701_bootresume.S Tested-by: Andrew Lunn <andrew@lunn.ch> # Kirkwood Tested-by: Shawn Guo <shawn.guo@freescale.com> Tested-by: Tony Lindgren <tony@atomide.com> # OMAPs Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com> # Armada XP, 375, 385 Acked-by: Sekhar Nori <nsekhar@ti.com> # DaVinci Acked-by: Christoffer Dall <christoffer.dall@linaro.org> # kvm/hyp Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> # PXA3xx Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> # Xen Tested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> # ARMv7M Tested-by: Simon Horman <horms+renesas@verge.net.au> # Shmobile Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
95 lines
2.6 KiB
ArmAsm
95 lines
2.6 KiB
ArmAsm
/*
|
|
* 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 <linux/init.h>
|
|
#include <linux/linkage.h>
|
|
#include <asm/assembler.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/page.h>
|
|
#include <asm/tlbflush.h>
|
|
#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 ish
|
|
mov r0, r0, lsr #PAGE_SHIFT @ align address
|
|
mov r1, r1, lsr #PAGE_SHIFT
|
|
asid r3, r3 @ mask ASID
|
|
#ifdef CONFIG_ARM_ERRATA_720789
|
|
ALT_SMP(W(mov) r3, #0 )
|
|
ALT_UP(W(nop) )
|
|
#endif
|
|
orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
|
|
mov r1, r1, lsl #PAGE_SHIFT
|
|
1:
|
|
#ifdef CONFIG_ARM_ERRATA_720789
|
|
ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
|
|
#else
|
|
ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
|
|
#endif
|
|
ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
|
|
|
|
add r0, r0, #PAGE_SZ
|
|
cmp r0, r1
|
|
blo 1b
|
|
dsb ish
|
|
ret lr
|
|
ENDPROC(v7wbi_flush_user_tlb_range)
|
|
|
|
/*
|
|
* 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 ish
|
|
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:
|
|
#ifdef CONFIG_ARM_ERRATA_720789
|
|
ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
|
|
#else
|
|
ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
|
|
#endif
|
|
ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
|
|
add r0, r0, #PAGE_SZ
|
|
cmp r0, r1
|
|
blo 1b
|
|
dsb ish
|
|
isb
|
|
ret lr
|
|
ENDPROC(v7wbi_flush_kern_tlb_range)
|
|
|
|
__INIT
|
|
|
|
/* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
|
|
define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp
|