mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-10-26 10:19:57 +00:00
Directives such as .long and .word do not magically cause the
assembler location counter to become aligned in gas. As a result,
using these directives in code sections can result in misaligned
data words when building a Thumb-2 kernel (CONFIG_THUMB2_KERNEL).
This is a Bad Thing, since the ABI permits the compiler to assume
that fundamental types of word size or above are word- aligned when
accessing them from C. If the data is not really word-aligned,
this can cause impaired performance and stray alignment faults in
some circumstances.
In general, the following rules should be applied when using data
word declaration directives inside code sections:
* .quad and .double:
.align 3
* .long, .word, .single, .float:
.align (or .align 2)
* .short:
No explicit alignment required, since Thumb-2
instructions are always 2 or 4 bytes in size.
immediately after an instruction.
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
88 lines
1.3 KiB
ArmAsm
88 lines
1.3 KiB
ArmAsm
/*
|
|
* relocate_kernel.S - put the kernel image in place to boot
|
|
*/
|
|
|
|
#include <asm/kexec.h>
|
|
|
|
.globl relocate_new_kernel
|
|
relocate_new_kernel:
|
|
|
|
ldr r0,kexec_indirection_page
|
|
ldr r1,kexec_start_address
|
|
|
|
/*
|
|
* If there is no indirection page (we are doing crashdumps)
|
|
* skip any relocation.
|
|
*/
|
|
cmp r0, #0
|
|
beq 2f
|
|
|
|
0: /* top, read another word for the indirection page */
|
|
ldr r3, [r0],#4
|
|
|
|
/* Is it a destination page. Put destination address to r4 */
|
|
tst r3,#1,0
|
|
beq 1f
|
|
bic r4,r3,#1
|
|
b 0b
|
|
1:
|
|
/* Is it an indirection page */
|
|
tst r3,#2,0
|
|
beq 1f
|
|
bic r0,r3,#2
|
|
b 0b
|
|
1:
|
|
|
|
/* are we done ? */
|
|
tst r3,#4,0
|
|
beq 1f
|
|
b 2f
|
|
|
|
1:
|
|
/* is it source ? */
|
|
tst r3,#8,0
|
|
beq 0b
|
|
bic r3,r3,#8
|
|
mov r6,#1024
|
|
9:
|
|
ldr r5,[r3],#4
|
|
str r5,[r4],#4
|
|
subs r6,r6,#1
|
|
bne 9b
|
|
b 0b
|
|
|
|
2:
|
|
/* Jump to relocated kernel */
|
|
mov lr,r1
|
|
mov r0,#0
|
|
ldr r1,kexec_mach_type
|
|
ldr r2,kexec_boot_atags
|
|
mov pc,lr
|
|
|
|
.align
|
|
|
|
.globl kexec_start_address
|
|
kexec_start_address:
|
|
.long 0x0
|
|
|
|
.globl kexec_indirection_page
|
|
kexec_indirection_page:
|
|
.long 0x0
|
|
|
|
.globl kexec_mach_type
|
|
kexec_mach_type:
|
|
.long 0x0
|
|
|
|
/* phy addr of the atags for the new kernel */
|
|
.globl kexec_boot_atags
|
|
kexec_boot_atags:
|
|
.long 0x0
|
|
|
|
relocate_new_kernel_end:
|
|
|
|
.globl relocate_new_kernel_size
|
|
relocate_new_kernel_size:
|
|
.long relocate_new_kernel_end - relocate_new_kernel
|
|
|
|
|