14
14
#include <asm/hwcap.h>
15
15
#include <asm/image.h>
16
16
17
- __INIT
17
+ __HEAD
18
18
ENTRY(_start)
19
19
/*
20
20
* Image header expected by Linux boot-loaders. The image header data
@@ -45,8 +45,85 @@ ENTRY(_start)
45
45
.ascii RISCV_IMAGE_MAGIC2
46
46
.word 0
47
47
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)
50
127
/* Mask all interrupts */
51
128
csrw CSR_IE, zero
52
129
csrw CSR_IP, zero
@@ -134,59 +211,6 @@ clear_bss_done:
134
211
call parse_dtb
135
212
tail start_kernel
136
213
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
-
190
214
.Lsecondary_start:
191
215
#ifdef CONFIG_SMP
192
216
/* Set trap vector to spin forever to help debug */
@@ -211,16 +235,10 @@ relocate:
211
235
beqz tp, .Lwait_for_cpu_up
212
236
fence
213
237
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
218
239
#endif
219
240
220
- tail smp_callin
221
- #endif
222
-
223
- END(_start)
241
+ END(_start_kernel)
224
242
225
243
#ifdef CONFIG_RISCV_M_MODE
226
244
ENTRY(reset_regs)
@@ -301,13 +319,6 @@ ENTRY(reset_regs)
301
319
END(reset_regs)
302
320
#endif /* CONFIG_RISCV_M_MODE */
303
321
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
-
311
322
__PAGE_ALIGNED_BSS
312
323
/* Empty zero page */
313
324
.balign PAGE_SIZE
0 commit comments