1414#include <asm/hwcap.h>
1515#include <asm/image.h>
1616
17- __INIT
17+ __HEAD
1818ENTRY(_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
226244ENTRY(reset_regs)
@@ -301,13 +319,6 @@ ENTRY(reset_regs)
301319END(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
0 commit comments