Commit 2c736bb4 authored by Russell King's avatar Russell King

Merge tag 'arm-adrl-replacement-for-v5.11' of...

Merge tag 'arm-adrl-replacement-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux into devel-stable

Tidy up open coded relative references in asm

Use the newly introduced adr_l/ldr_l/str_l/mov_l assembler macros to
replace open coded VA-to-PA arithmetic in various places in the code. This
avoids the use of literals on v7+ CPUs, reduces the footprint of the code
in most cases, and generally makes the code easier to follow.

Series was posted here, and reviewed by Nicolas Pitre:
https://lore.kernel.org/linux-arm-kernel/20200914095706.3985-1-ardb@kernel.org/
parents ae73ad05 aaac3733
...@@ -468,15 +468,10 @@ dtb_check_done: ...@@ -468,15 +468,10 @@ dtb_check_done:
/* /*
* Compute the address of the hyp vectors after relocation. * Compute the address of the hyp vectors after relocation.
* This requires some arithmetic since we cannot directly
* reference __hyp_stub_vectors in a PC-relative way.
* Call __hyp_set_vectors with the new address so that we * Call __hyp_set_vectors with the new address so that we
* can HVC again after the copy. * can HVC again after the copy.
*/ */
0: adr r0, 0b adr_l r0, __hyp_stub_vectors
movw r1, #:lower16:__hyp_stub_vectors - 0b
movt r1, #:upper16:__hyp_stub_vectors - 0b
add r0, r0, r1
sub r0, r0, r5 sub r0, r0, r5
add r0, r0, r10 add r0, r0, r10
bl __hyp_set_vectors bl __hyp_set_vectors
...@@ -627,17 +622,11 @@ not_relocated: mov r0, #0 ...@@ -627,17 +622,11 @@ not_relocated: mov r0, #0
cmp r0, #HYP_MODE @ if not booted in HYP mode... cmp r0, #HYP_MODE @ if not booted in HYP mode...
bne __enter_kernel @ boot kernel directly bne __enter_kernel @ boot kernel directly
adr r12, .L__hyp_reentry_vectors_offset adr_l r0, __hyp_reentry_vectors
ldr r0, [r12]
add r0, r0, r12
bl __hyp_set_vectors bl __hyp_set_vectors
__HVC(0) @ otherwise bounce to hyp mode __HVC(0) @ otherwise bounce to hyp mode
b . @ should never be reached b . @ should never be reached
.align 2
.L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - .
#else #else
b __enter_kernel b __enter_kernel
#endif #endif
...@@ -1440,8 +1429,7 @@ ENTRY(efi_enter_kernel) ...@@ -1440,8 +1429,7 @@ ENTRY(efi_enter_kernel)
mov r4, r0 @ preserve image base mov r4, r0 @ preserve image base
mov r8, r1 @ preserve DT pointer mov r8, r1 @ preserve DT pointer
ARM( adrl r0, call_cache_fn ) adr_l r0, call_cache_fn
THUMB( adr r0, call_cache_fn )
adr r1, 0f @ clean the region of code we adr r1, 0f @ clean the region of code we
bl cache_clean_flush @ may run with the MMU off bl cache_clean_flush @ may run with the MMU off
......
...@@ -259,7 +259,7 @@ ...@@ -259,7 +259,7 @@
*/ */
#define ALT_UP(instr...) \ #define ALT_UP(instr...) \
.pushsection ".alt.smp.init", "a" ;\ .pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\ .long 9998b - . ;\
9997: instr ;\ 9997: instr ;\
.if . - 9997b == 2 ;\ .if . - 9997b == 2 ;\
nop ;\ nop ;\
...@@ -270,7 +270,7 @@ ...@@ -270,7 +270,7 @@
.popsection .popsection
#define ALT_UP_B(label) \ #define ALT_UP_B(label) \
.pushsection ".alt.smp.init", "a" ;\ .pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\ .long 9998b - . ;\
W(b) . + (label - 9998b) ;\ W(b) . + (label - 9998b) ;\
.popsection .popsection
#else #else
......
...@@ -96,7 +96,7 @@ unsigned long get_wchan(struct task_struct *p); ...@@ -96,7 +96,7 @@ unsigned long get_wchan(struct task_struct *p);
#define __ALT_SMP_ASM(smp, up) \ #define __ALT_SMP_ASM(smp, up) \
"9998: " smp "\n" \ "9998: " smp "\n" \
" .pushsection \".alt.smp.init\", \"a\"\n" \ " .pushsection \".alt.smp.init\", \"a\"\n" \
" .long 9998b\n" \ " .long 9998b - .\n" \
" " up "\n" \ " " up "\n" \
" .popsection\n" " .popsection\n"
#else #else
......
...@@ -170,11 +170,12 @@ ENDPROC(lookup_processor_type) ...@@ -170,11 +170,12 @@ ENDPROC(lookup_processor_type)
* r9 = cpuid (preserved) * r9 = cpuid (preserved)
*/ */
__lookup_processor_type: __lookup_processor_type:
adr r3, __lookup_processor_type_data /*
ldmia r3, {r4 - r6} * Look in <asm/procinfo.h> for information about the __proc_info
sub r3, r3, r4 @ get offset between virt&phys * structure.
add r5, r5, r3 @ convert virt addresses to */
add r6, r6, r3 @ physical address space adr_l r5, __proc_info_begin
adr_l r6, __proc_info_end
1: ldmia r5, {r3, r4} @ value, mask 1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits and r4, r4, r9 @ mask wanted bits
teq r3, r4 teq r3, r4
...@@ -186,17 +187,6 @@ __lookup_processor_type: ...@@ -186,17 +187,6 @@ __lookup_processor_type:
2: ret lr 2: ret lr
ENDPROC(__lookup_processor_type) ENDPROC(__lookup_processor_type)
/*
* Look in <asm/procinfo.h> for information about the __proc_info structure.
*/
.align 2
.type __lookup_processor_type_data, %object
__lookup_processor_type_data:
.long .
.long __proc_info_begin
.long __proc_info_end
.size __lookup_processor_type_data, . - __lookup_processor_type_data
__error_lpae: __error_lpae:
#ifdef CONFIG_DEBUG_LL #ifdef CONFIG_DEBUG_LL
adr r0, str_lpae adr r0, str_lpae
......
...@@ -103,10 +103,8 @@ ENTRY(stext) ...@@ -103,10 +103,8 @@ ENTRY(stext)
#endif #endif
#ifndef CONFIG_XIP_KERNEL #ifndef CONFIG_XIP_KERNEL
adr r3, 2f adr_l r8, _text @ __pa(_text)
ldmia r3, {r4, r8} sub r8, r8, #TEXT_OFFSET @ PHYS_OFFSET
sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
add r8, r8, r4 @ PHYS_OFFSET
#else #else
ldr r8, =PLAT_PHYS_OFFSET @ always constant in this case ldr r8, =PLAT_PHYS_OFFSET @ always constant in this case
#endif #endif
...@@ -158,10 +156,6 @@ ENTRY(stext) ...@@ -158,10 +156,6 @@ ENTRY(stext)
1: b __enable_mmu 1: b __enable_mmu
ENDPROC(stext) ENDPROC(stext)
.ltorg .ltorg
#ifndef CONFIG_XIP_KERNEL
2: .long .
.long PAGE_OFFSET
#endif
/* /*
* Setup the initial page tables. We only setup the barest * Setup the initial page tables. We only setup the barest
...@@ -224,11 +218,8 @@ __create_page_tables: ...@@ -224,11 +218,8 @@ __create_page_tables:
* Create identity mapping to cater for __enable_mmu. * Create identity mapping to cater for __enable_mmu.
* This identity mapping will be removed by paging_init(). * This identity mapping will be removed by paging_init().
*/ */
adr r0, __turn_mmu_on_loc adr_l r5, __turn_mmu_on @ _pa(__turn_mmu_on)
ldmia r0, {r3, r5, r6} adr_l r6, __turn_mmu_on_end @ _pa(__turn_mmu_on_end)
sub r0, r0, r3 @ virt->phys offset
add r5, r5, r0 @ phys __turn_mmu_on
add r6, r6, r0 @ phys __turn_mmu_on_end
mov r5, r5, lsr #SECTION_SHIFT mov r5, r5, lsr #SECTION_SHIFT
mov r6, r6, lsr #SECTION_SHIFT mov r6, r6, lsr #SECTION_SHIFT
...@@ -351,11 +342,6 @@ __create_page_tables: ...@@ -351,11 +342,6 @@ __create_page_tables:
ret lr ret lr
ENDPROC(__create_page_tables) ENDPROC(__create_page_tables)
.ltorg .ltorg
.align
__turn_mmu_on_loc:
.long .
.long __turn_mmu_on
.long __turn_mmu_on_end
#if defined(CONFIG_SMP) #if defined(CONFIG_SMP)
.text .text
...@@ -391,10 +377,8 @@ ENTRY(secondary_startup) ...@@ -391,10 +377,8 @@ ENTRY(secondary_startup)
/* /*
* Use the page tables supplied from __cpu_up. * Use the page tables supplied from __cpu_up.
*/ */
adr r4, __secondary_data adr_l r3, secondary_data
ldmia r4, {r5, r7, r12} @ address to jump to after mov_l r12, __secondary_switched
sub lr, r4, r5 @ mmu has been enabled
add r3, r7, lr
ldrd r4, r5, [r3, #0] @ get secondary_data.pgdir ldrd r4, r5, [r3, #0] @ get secondary_data.pgdir
ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE: ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE:
ARM_BE8(eor r5, r4, r5) @ it can be done in 3 steps ARM_BE8(eor r5, r4, r5) @ it can be done in 3 steps
...@@ -409,22 +393,13 @@ ARM_BE8(eor r4, r4, r5) @ without using a temp reg. ...@@ -409,22 +393,13 @@ ARM_BE8(eor r4, r4, r5) @ without using a temp reg.
ENDPROC(secondary_startup) ENDPROC(secondary_startup)
ENDPROC(secondary_startup_arm) ENDPROC(secondary_startup_arm)
/*
* r6 = &secondary_data
*/
ENTRY(__secondary_switched) ENTRY(__secondary_switched)
ldr sp, [r7, #12] @ get secondary_data.stack ldr_l r7, secondary_data + 12 @ get secondary_data.stack
mov sp, r7
mov fp, #0 mov fp, #0
b secondary_start_kernel b secondary_start_kernel
ENDPROC(__secondary_switched) ENDPROC(__secondary_switched)
.align
.type __secondary_data, %object
__secondary_data:
.long .
.long secondary_data
.long __secondary_switched
#endif /* defined(CONFIG_SMP) */ #endif /* defined(CONFIG_SMP) */
...@@ -539,19 +514,11 @@ ARM_BE8(rev r0, r0) @ byteswap if big endian ...@@ -539,19 +514,11 @@ ARM_BE8(rev r0, r0) @ byteswap if big endian
retne lr retne lr
__fixup_smp_on_up: __fixup_smp_on_up:
adr r0, 1f adr_l r4, __smpalt_begin
ldmia r0, {r3 - r5} adr_l r5, __smpalt_end
sub r3, r0, r3
add r4, r4, r3
add r5, r5, r3
b __do_fixup_smp_on_up b __do_fixup_smp_on_up
ENDPROC(__fixup_smp) ENDPROC(__fixup_smp)
.align
1: .word .
.word __smpalt_begin
.word __smpalt_end
.pushsection .data .pushsection .data
.align 2 .align 2
.globl smp_on_up .globl smp_on_up
...@@ -565,14 +532,15 @@ smp_on_up: ...@@ -565,14 +532,15 @@ smp_on_up:
__do_fixup_smp_on_up: __do_fixup_smp_on_up:
cmp r4, r5 cmp r4, r5
reths lr reths lr
ldmia r4!, {r0, r6} ldmia r4, {r0, r6}
ARM( str r6, [r0, r3] ) ARM( str r6, [r0, r4] )
THUMB( add r0, r0, r3 ) THUMB( add r0, r0, r4 )
add r4, r4, #8
#ifdef __ARMEB__ #ifdef __ARMEB__
THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
#endif #endif
THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r0.
THUMB( strh r6, [r0] ) THUMB( strh r6, [r0] )
b __do_fixup_smp_on_up b __do_fixup_smp_on_up
ENDPROC(__do_fixup_smp_on_up) ENDPROC(__do_fixup_smp_on_up)
...@@ -581,7 +549,6 @@ ENTRY(fixup_smp) ...@@ -581,7 +549,6 @@ ENTRY(fixup_smp)
stmfd sp!, {r4 - r6, lr} stmfd sp!, {r4 - r6, lr}
mov r4, r0 mov r4, r0
add r5, r0, r1 add r5, r0, r1
mov r3, #0
bl __do_fixup_smp_on_up bl __do_fixup_smp_on_up
ldmfd sp!, {r4 - r6, pc} ldmfd sp!, {r4 - r6, pc}
ENDPROC(fixup_smp) ENDPROC(fixup_smp)
......
...@@ -24,41 +24,38 @@ ENTRY(__boot_cpu_mode) ...@@ -24,41 +24,38 @@ ENTRY(__boot_cpu_mode)
.text .text
/* /*
* Save the primary CPU boot mode. Requires 3 scratch registers. * Save the primary CPU boot mode. Requires 2 scratch registers.
*/ */
.macro store_primary_cpu_mode reg1, reg2, reg3 .macro store_primary_cpu_mode reg1, reg2
mrs \reg1, cpsr mrs \reg1, cpsr
and \reg1, \reg1, #MODE_MASK and \reg1, \reg1, #MODE_MASK
adr \reg2, .L__boot_cpu_mode_offset str_l \reg1, __boot_cpu_mode, \reg2
ldr \reg3, [\reg2]
str \reg1, [\reg2, \reg3]
.endm .endm
/* /*
* Compare the current mode with the one saved on the primary CPU. * Compare the current mode with the one saved on the primary CPU.
* If they don't match, record that fact. The Z bit indicates * If they don't match, record that fact. The Z bit indicates
* if there's a match or not. * if there's a match or not.
* Requires 3 additionnal scratch registers. * Requires 2 additional scratch registers.
*/ */
.macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 .macro compare_cpu_mode_with_primary mode, reg1, reg2
adr \reg2, .L__boot_cpu_mode_offset adr_l \reg2, __boot_cpu_mode
ldr \reg3, [\reg2] ldr \reg1, [\reg2]
ldr \reg1, [\reg2, \reg3]
cmp \mode, \reg1 @ matches primary CPU boot mode? cmp \mode, \reg1 @ matches primary CPU boot mode?
orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH
strne \reg1, [\reg2, \reg3] @ record what happened and give up strne \reg1, [\reg2] @ record what happened and give up
.endm .endm
#else /* ZIMAGE */ #else /* ZIMAGE */
.macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req .macro store_primary_cpu_mode reg1:req, reg2:req
.endm .endm
/* /*
* The zImage loader only runs on one CPU, so we don't bother with mult-CPU * The zImage loader only runs on one CPU, so we don't bother with mult-CPU
* consistency checking: * consistency checking:
*/ */
.macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 .macro compare_cpu_mode_with_primary mode, reg1, reg2
cmp \mode, \mode cmp \mode, \mode
.endm .endm
...@@ -73,7 +70,7 @@ ENTRY(__boot_cpu_mode) ...@@ -73,7 +70,7 @@ ENTRY(__boot_cpu_mode)
*/ */
@ Call this from the primary CPU @ Call this from the primary CPU
ENTRY(__hyp_stub_install) ENTRY(__hyp_stub_install)
store_primary_cpu_mode r4, r5, r6 store_primary_cpu_mode r4, r5
ENDPROC(__hyp_stub_install) ENDPROC(__hyp_stub_install)
@ fall through... @ fall through...
...@@ -87,7 +84,7 @@ ENTRY(__hyp_stub_install_secondary) ...@@ -87,7 +84,7 @@ ENTRY(__hyp_stub_install_secondary)
* If the secondary has booted with a different mode, give up * If the secondary has booted with a different mode, give up
* immediately. * immediately.
*/ */
compare_cpu_mode_with_primary r4, r5, r6, r7 compare_cpu_mode_with_primary r4, r5, r6
retne lr retne lr
/* /*
......
...@@ -72,8 +72,9 @@ ENTRY(__cpu_suspend) ...@@ -72,8 +72,9 @@ ENTRY(__cpu_suspend)
ldr r3, =sleep_save_sp ldr r3, =sleep_save_sp
stmfd sp!, {r0, r1} @ save suspend func arg and pointer stmfd sp!, {r0, r1} @ save suspend func arg and pointer
ldr r3, [r3, #SLEEP_SAVE_SP_VIRT] ldr r3, [r3, #SLEEP_SAVE_SP_VIRT]
ALT_SMP(ldr r0, =mpidr_hash) ALT_SMP(W(nop)) @ don't use adr_l inside ALT_SMP()
ALT_UP_B(1f) ALT_UP_B(1f)
adr_l r0, mpidr_hash
/* This ldmia relies on the memory layout of the mpidr_hash struct */ /* This ldmia relies on the memory layout of the mpidr_hash struct */
ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts
compute_mpidr_hash r0, r6, r7, r8, r2, r1 compute_mpidr_hash r0, r6, r7, r8, r2, r1
...@@ -147,9 +148,8 @@ no_hyp: ...@@ -147,9 +148,8 @@ no_hyp:
mov r1, #0 mov r1, #0
ALT_SMP(mrc p15, 0, r0, c0, c0, 5) ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
ALT_UP_B(1f) ALT_UP_B(1f)
adr r2, mpidr_hash_ptr adr_l r2, mpidr_hash @ r2 = struct mpidr_hash phys address
ldr r3, [r2]
add r2, r2, r3 @ r2 = struct mpidr_hash phys address
/* /*
* This ldmia relies on the memory layout of the mpidr_hash * This ldmia relies on the memory layout of the mpidr_hash
* struct mpidr_hash. * struct mpidr_hash.
...@@ -157,10 +157,7 @@ no_hyp: ...@@ -157,10 +157,7 @@ no_hyp:
ldmia r2, { r3-r6 } @ r3 = mpidr mask (r4,r5,r6) = l[0,1,2] shifts ldmia r2, { r3-r6 } @ r3 = mpidr mask (r4,r5,r6) = l[0,1,2] shifts
compute_mpidr_hash r1, r4, r5, r6, r0, r3 compute_mpidr_hash r1, r4, r5, r6, r0, r3
1: 1:
adr r0, _sleep_save_sp ldr_l r0, sleep_save_sp + SLEEP_SAVE_SP_PHYS
ldr r2, [r0]
add r0, r0, r2
ldr r0, [r0, #SLEEP_SAVE_SP_PHYS]
ldr r0, [r0, r1, lsl #2] ldr r0, [r0, r1, lsl #2]
@ load phys pgd, stack, resume fn @ load phys pgd, stack, resume fn
...@@ -177,12 +174,6 @@ ENDPROC(cpu_resume_arm) ...@@ -177,12 +174,6 @@ ENDPROC(cpu_resume_arm)
ENDPROC(cpu_resume_no_hyp) ENDPROC(cpu_resume_no_hyp)
#endif #endif
.align 2
_sleep_save_sp:
.long sleep_save_sp - .
mpidr_hash_ptr:
.long mpidr_hash - . @ mpidr_hash struct offset
.data .data
.align 2 .align 2
.type sleep_save_sp, #object .type sleep_save_sp, #object
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment