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>
114 lines
3.1 KiB
ArmAsm
114 lines
3.1 KiB
ArmAsm
/*
|
|
* linux/arch/arm/mm/proc-arm7tdmi.S: utility functions for ARM7TDMI
|
|
*
|
|
* Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@samsung.com>
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
#include <linux/linkage.h>
|
|
#include <linux/init.h>
|
|
#include <asm/assembler.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/hwcap.h>
|
|
#include <asm/pgtable-hwdef.h>
|
|
#include <asm/pgtable.h>
|
|
#include <asm/ptrace.h>
|
|
|
|
#include "proc-macros.S"
|
|
|
|
.text
|
|
/*
|
|
* cpu_arm7tdmi_proc_init()
|
|
* cpu_arm7tdmi_do_idle()
|
|
* cpu_arm7tdmi_dcache_clean_area()
|
|
* cpu_arm7tdmi_switch_mm()
|
|
*
|
|
* These are not required.
|
|
*/
|
|
ENTRY(cpu_arm7tdmi_proc_init)
|
|
ENTRY(cpu_arm7tdmi_do_idle)
|
|
ENTRY(cpu_arm7tdmi_dcache_clean_area)
|
|
ENTRY(cpu_arm7tdmi_switch_mm)
|
|
ret lr
|
|
|
|
/*
|
|
* cpu_arm7tdmi_proc_fin()
|
|
*/
|
|
ENTRY(cpu_arm7tdmi_proc_fin)
|
|
ret lr
|
|
|
|
/*
|
|
* Function: cpu_arm7tdmi_reset(loc)
|
|
* Params : loc(r0) address to jump to
|
|
* Purpose : Sets up everything for a reset and jump to the location for soft reset.
|
|
*/
|
|
.pushsection .idmap.text, "ax"
|
|
ENTRY(cpu_arm7tdmi_reset)
|
|
ret r0
|
|
ENDPROC(cpu_arm7tdmi_reset)
|
|
.popsection
|
|
|
|
.type __arm7tdmi_setup, #function
|
|
__arm7tdmi_setup:
|
|
ret lr
|
|
.size __arm7tdmi_setup, . - __arm7tdmi_setup
|
|
|
|
__INITDATA
|
|
|
|
@ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
|
|
define_processor_functions arm7tdmi, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
|
|
|
|
.section ".rodata"
|
|
|
|
string cpu_arch_name, "armv4t"
|
|
string cpu_elf_name, "v4"
|
|
string cpu_arm7tdmi_name, "ARM7TDMI"
|
|
string cpu_triscenda7_name, "Triscend-A7x"
|
|
string cpu_at91_name, "Atmel-AT91M40xxx"
|
|
string cpu_s3c3410_name, "Samsung-S3C3410"
|
|
string cpu_s3c44b0x_name, "Samsung-S3C44B0x"
|
|
string cpu_s3c4510b_name, "Samsung-S3C4510B"
|
|
string cpu_s3c4530_name, "Samsung-S3C4530"
|
|
string cpu_netarm_name, "NETARM"
|
|
|
|
.align
|
|
|
|
.section ".proc.info.init", #alloc, #execinstr
|
|
|
|
.macro arm7tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
|
|
extra_hwcaps=0
|
|
.type __\name\()_proc_info, #object
|
|
__\name\()_proc_info:
|
|
.long \cpu_val
|
|
.long \cpu_mask
|
|
.long 0
|
|
.long 0
|
|
b __arm7tdmi_setup
|
|
.long cpu_arch_name
|
|
.long cpu_elf_name
|
|
.long HWCAP_SWP | HWCAP_26BIT | ( \extra_hwcaps )
|
|
.long \cpu_name
|
|
.long arm7tdmi_processor_functions
|
|
.long 0
|
|
.long 0
|
|
.long v4_cache_fns
|
|
.size __\name\()_proc_info, . - __\name\()_proc_info
|
|
.endm
|
|
|
|
arm7tdmi_proc_info arm7tdmi, 0x41007700, 0xfff8ff00, \
|
|
cpu_arm7tdmi_name
|
|
arm7tdmi_proc_info triscenda7, 0x0001d2ff, 0x0001ffff, \
|
|
cpu_triscenda7_name, extra_hwcaps=HWCAP_THUMB
|
|
arm7tdmi_proc_info at91, 0x14000040, 0xfff000e0, \
|
|
cpu_at91_name, extra_hwcaps=HWCAP_THUMB
|
|
arm7tdmi_proc_info s3c4510b, 0x36365000, 0xfffff000, \
|
|
cpu_s3c4510b_name, extra_hwcaps=HWCAP_THUMB
|
|
arm7tdmi_proc_info s3c4530, 0x4c000000, 0xfff000e0, \
|
|
cpu_s3c4530_name, extra_hwcaps=HWCAP_THUMB
|
|
arm7tdmi_proc_info s3c3410, 0x34100000, 0xffff0000, \
|
|
cpu_s3c3410_name, extra_hwcaps=HWCAP_THUMB
|
|
arm7tdmi_proc_info s3c44b0x, 0x44b00000, 0xffff0000, \
|
|
cpu_s3c44b0x_name, extra_hwcaps=HWCAP_THUMB
|