Skip to content

Commit e011995

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Move relocate and few other functions out of __init
The secondary hart booting and relocation code are under .init section. As a result, it will be freed once kernel booting is done. However, ordered booting protocol and CPU hotplug always requires these functions to be present to bringup harts after initial kernel boot. Move the required functions to a different section and make sure that they are in memory within first 2MB offset as trampoline page directory only maps first 2MB. Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Anup Patel <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 1ef46c2 commit e011995

File tree

2 files changed

+86
-72
lines changed

2 files changed

+86
-72
lines changed

arch/riscv/kernel/head.S

Lines changed: 82 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <asm/hwcap.h>
1515
#include <asm/image.h>
1616

17-
__INIT
17+
__HEAD
1818
ENTRY(_start)
1919
/*
2020
* Image header expected by Linux boot-loaders. The image header data
@@ -45,8 +45,85 @@ ENTRY(_start)
4545
.ascii RISCV_IMAGE_MAGIC2
4646
.word 0
4747

48-
.global _start_kernel
49-
_start_kernel:
48+
.align 2
49+
#ifdef CONFIG_MMU
50+
relocate:
51+
/* Relocate return address */
52+
li a1, PAGE_OFFSET
53+
la a2, _start
54+
sub a1, a1, a2
55+
add ra, ra, a1
56+
57+
/* Point stvec to virtual address of intruction after satp write */
58+
la a2, 1f
59+
add a2, a2, a1
60+
csrw CSR_TVEC, a2
61+
62+
/* Compute satp for kernel page tables, but don't load it yet */
63+
srl a2, a0, PAGE_SHIFT
64+
li a1, SATP_MODE
65+
or a2, a2, a1
66+
67+
/*
68+
* Load trampoline page directory, which will cause us to trap to
69+
* stvec if VA != PA, or simply fall through if VA == PA. We need a
70+
* full fence here because setup_vm() just wrote these PTEs and we need
71+
* to ensure the new translations are in use.
72+
*/
73+
la a0, trampoline_pg_dir
74+
srl a0, a0, PAGE_SHIFT
75+
or a0, a0, a1
76+
sfence.vma
77+
csrw CSR_SATP, a0
78+
.align 2
79+
1:
80+
/* Set trap vector to spin forever to help debug */
81+
la a0, .Lsecondary_park
82+
csrw CSR_TVEC, a0
83+
84+
/* Reload the global pointer */
85+
.option push
86+
.option norelax
87+
la gp, __global_pointer$
88+
.option pop
89+
90+
/*
91+
* Switch to kernel page tables. A full fence is necessary in order to
92+
* avoid using the trampoline translations, which are only correct for
93+
* the first superpage. Fetching the fence is guarnteed to work
94+
* because that first superpage is translated the same way.
95+
*/
96+
csrw CSR_SATP, a2
97+
sfence.vma
98+
99+
ret
100+
#endif /* CONFIG_MMU */
101+
#ifdef CONFIG_SMP
102+
/* Set trap vector to spin forever to help debug */
103+
la a3, .Lsecondary_park
104+
csrw CSR_TVEC, a3
105+
106+
slli a3, a0, LGREG
107+
.global secondary_start_common
108+
secondary_start_common:
109+
110+
#ifdef CONFIG_MMU
111+
/* Enable virtual memory and relocate to virtual address */
112+
la a0, swapper_pg_dir
113+
call relocate
114+
#endif
115+
tail smp_callin
116+
#endif /* CONFIG_SMP */
117+
118+
.Lsecondary_park:
119+
/* We lack SMP support or have too many harts, so park this hart */
120+
wfi
121+
j .Lsecondary_park
122+
123+
END(_start)
124+
125+
__INIT
126+
ENTRY(_start_kernel)
50127
/* Mask all interrupts */
51128
csrw CSR_IE, zero
52129
csrw CSR_IP, zero
@@ -134,59 +211,6 @@ clear_bss_done:
134211
call parse_dtb
135212
tail start_kernel
136213

137-
#ifdef CONFIG_MMU
138-
relocate:
139-
/* Relocate return address */
140-
li a1, PAGE_OFFSET
141-
la a2, _start
142-
sub a1, a1, a2
143-
add ra, ra, a1
144-
145-
/* Point stvec to virtual address of intruction after satp write */
146-
la a2, 1f
147-
add a2, a2, a1
148-
csrw CSR_TVEC, a2
149-
150-
/* Compute satp for kernel page tables, but don't load it yet */
151-
srl a2, a0, PAGE_SHIFT
152-
li a1, SATP_MODE
153-
or a2, a2, a1
154-
155-
/*
156-
* Load trampoline page directory, which will cause us to trap to
157-
* stvec if VA != PA, or simply fall through if VA == PA. We need a
158-
* full fence here because setup_vm() just wrote these PTEs and we need
159-
* to ensure the new translations are in use.
160-
*/
161-
la a0, trampoline_pg_dir
162-
srl a0, a0, PAGE_SHIFT
163-
or a0, a0, a1
164-
sfence.vma
165-
csrw CSR_SATP, a0
166-
.align 2
167-
1:
168-
/* Set trap vector to spin forever to help debug */
169-
la a0, .Lsecondary_park
170-
csrw CSR_TVEC, a0
171-
172-
/* Reload the global pointer */
173-
.option push
174-
.option norelax
175-
la gp, __global_pointer$
176-
.option pop
177-
178-
/*
179-
* Switch to kernel page tables. A full fence is necessary in order to
180-
* avoid using the trampoline translations, which are only correct for
181-
* the first superpage. Fetching the fence is guarnteed to work
182-
* because that first superpage is translated the same way.
183-
*/
184-
csrw CSR_SATP, a2
185-
sfence.vma
186-
187-
ret
188-
#endif /* CONFIG_MMU */
189-
190214
.Lsecondary_start:
191215
#ifdef CONFIG_SMP
192216
/* Set trap vector to spin forever to help debug */
@@ -211,16 +235,10 @@ relocate:
211235
beqz tp, .Lwait_for_cpu_up
212236
fence
213237

214-
#ifdef CONFIG_MMU
215-
/* Enable virtual memory and relocate to virtual address */
216-
la a0, swapper_pg_dir
217-
call relocate
238+
tail secondary_start_common
218239
#endif
219240

220-
tail smp_callin
221-
#endif
222-
223-
END(_start)
241+
END(_start_kernel)
224242

225243
#ifdef CONFIG_RISCV_M_MODE
226244
ENTRY(reset_regs)
@@ -301,13 +319,6 @@ ENTRY(reset_regs)
301319
END(reset_regs)
302320
#endif /* CONFIG_RISCV_M_MODE */
303321

304-
.section ".text", "ax",@progbits
305-
.align 2
306-
.Lsecondary_park:
307-
/* We lack SMP support or have too many harts, so park this hart */
308-
wfi
309-
j .Lsecondary_park
310-
311322
__PAGE_ALIGNED_BSS
312323
/* Empty zero page */
313324
.balign PAGE_SIZE

arch/riscv/kernel/vmlinux.lds.S

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <asm/thread_info.h>
1212
#include <asm/set_memory.h>
1313

14+
#include <linux/sizes.h>
1415
OUTPUT_ARCH(riscv)
1516
ENTRY(_start)
1617

@@ -21,8 +22,10 @@ SECTIONS
2122
/* Beginning of code and text segment */
2223
. = LOAD_OFFSET;
2324
_start = .;
24-
__init_begin = .;
2525
HEAD_TEXT_SECTION
26+
. = ALIGN(PAGE_SIZE);
27+
28+
__init_begin = .;
2629
INIT_TEXT_SECTION(PAGE_SIZE)
2730
INIT_DATA_SECTION(16)
2831
/* we have to discard exit text and such at runtime, not link time */

0 commit comments

Comments
 (0)