RISC-V: Rename relocate() and make it global
[platform/kernel/linux-starfive.git] / arch / riscv / kernel / head.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2012 Regents of the University of California
4  */
5
6 #include <asm/asm-offsets.h>
7 #include <asm/asm.h>
8 #include <linux/init.h>
9 #include <linux/linkage.h>
10 #include <asm/thread_info.h>
11 #include <asm/page.h>
12 #include <asm/pgtable.h>
13 #include <asm/csr.h>
14 #include <asm/hwcap.h>
15 #include <asm/image.h>
16 #include "efi-header.S"
17
18 #ifdef CONFIG_XIP_KERNEL
19 .macro XIP_FIXUP_OFFSET reg
20         REG_L t0, _xip_fixup
21         add \reg, \reg, t0
22 .endm
23 _xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET
24 #else
25 .macro XIP_FIXUP_OFFSET reg
26 .endm
27 #endif /* CONFIG_XIP_KERNEL */
28
29 __HEAD
30 ENTRY(_start)
31         /*
32          * Image header expected by Linux boot-loaders. The image header data
33          * structure is described in asm/image.h.
34          * Do not modify it without modifying the structure and all bootloaders
35          * that expects this header format!!
36          */
37 #ifdef CONFIG_EFI
38         /*
39          * This instruction decodes to "MZ" ASCII required by UEFI.
40          */
41         c.li s4,-13
42         j _start_kernel
43 #else
44         /* jump to start kernel */
45         j _start_kernel
46         /* reserved */
47         .word 0
48 #endif
49         .balign 8
50 #ifdef CONFIG_RISCV_M_MODE
51         /* Image load offset (0MB) from start of RAM for M-mode */
52         .dword 0
53 #else
54 #if __riscv_xlen == 64
55         /* Image load offset(2MB) from start of RAM */
56         .dword 0x200000
57 #else
58         /* Image load offset(4MB) from start of RAM */
59         .dword 0x400000
60 #endif
61 #endif
62         /* Effective size of kernel image */
63         .dword _end - _start
64         .dword __HEAD_FLAGS
65         .word RISCV_HEADER_VERSION
66         .word 0
67         .dword 0
68         .ascii RISCV_IMAGE_MAGIC
69         .balign 4
70         .ascii RISCV_IMAGE_MAGIC2
71 #ifdef CONFIG_EFI
72         .word pe_head_start - _start
73 pe_head_start:
74
75         __EFI_PE_HEADER
76 #else
77         .word 0
78 #endif
79
80 .align 2
81 #ifdef CONFIG_MMU
82         .global relocate_enable_mmu
83 relocate_enable_mmu:
84         /* Relocate return address */
85         la a1, kernel_map
86         XIP_FIXUP_OFFSET a1
87         REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
88         la a2, _start
89         sub a1, a1, a2
90         add ra, ra, a1
91
92         /* Point stvec to virtual address of intruction after satp write */
93         la a2, 1f
94         add a2, a2, a1
95         csrw CSR_TVEC, a2
96
97         /* Compute satp for kernel page tables, but don't load it yet */
98         srl a2, a0, PAGE_SHIFT
99         li a1, SATP_MODE
100         or a2, a2, a1
101
102         /*
103          * Load trampoline page directory, which will cause us to trap to
104          * stvec if VA != PA, or simply fall through if VA == PA.  We need a
105          * full fence here because setup_vm() just wrote these PTEs and we need
106          * to ensure the new translations are in use.
107          */
108         la a0, trampoline_pg_dir
109         XIP_FIXUP_OFFSET a0
110         srl a0, a0, PAGE_SHIFT
111         or a0, a0, a1
112         sfence.vma
113         csrw CSR_SATP, a0
114 .align 2
115 1:
116         /* Set trap vector to spin forever to help debug */
117         la a0, .Lsecondary_park
118         csrw CSR_TVEC, a0
119
120         /* Reload the global pointer */
121 .option push
122 .option norelax
123         la gp, __global_pointer$
124 .option pop
125
126         /*
127          * Switch to kernel page tables.  A full fence is necessary in order to
128          * avoid using the trampoline translations, which are only correct for
129          * the first superpage.  Fetching the fence is guarnteed to work
130          * because that first superpage is translated the same way.
131          */
132         csrw CSR_SATP, a2
133         sfence.vma
134
135         ret
136 #endif /* CONFIG_MMU */
137 #ifdef CONFIG_SMP
138         .global secondary_start_sbi
139 secondary_start_sbi:
140         /* Mask all interrupts */
141         csrw CSR_IE, zero
142         csrw CSR_IP, zero
143
144         /* Load the global pointer */
145         .option push
146         .option norelax
147                 la gp, __global_pointer$
148         .option pop
149
150         /*
151          * Disable FPU to detect illegal usage of
152          * floating point in kernel space
153          */
154         li t0, SR_FS
155         csrc CSR_STATUS, t0
156
157         /* Set trap vector to spin forever to help debug */
158         la a3, .Lsecondary_park
159         csrw CSR_TVEC, a3
160
161         slli a3, a0, LGREG
162         la a4, __cpu_up_stack_pointer
163         XIP_FIXUP_OFFSET a4
164         la a5, __cpu_up_task_pointer
165         XIP_FIXUP_OFFSET a5
166         add a4, a3, a4
167         add a5, a3, a5
168         REG_L sp, (a4)
169         REG_L tp, (a5)
170
171         .global secondary_start_common
172 secondary_start_common:
173
174 #ifdef CONFIG_MMU
175         /* Enable virtual memory and relocate to virtual address */
176         la a0, swapper_pg_dir
177         XIP_FIXUP_OFFSET a0
178         call relocate_enable_mmu
179 #endif
180         call setup_trap_vector
181         tail smp_callin
182 #endif /* CONFIG_SMP */
183
184 .align 2
185 setup_trap_vector:
186         /* Set trap vector to exception handler */
187         la a0, handle_exception
188         csrw CSR_TVEC, a0
189
190         /*
191          * Set sup0 scratch register to 0, indicating to exception vector that
192          * we are presently executing in kernel.
193          */
194         csrw CSR_SCRATCH, zero
195         ret
196
197 .align 2
198 .Lsecondary_park:
199         /* We lack SMP support or have too many harts, so park this hart */
200         wfi
201         j .Lsecondary_park
202
203 END(_start)
204
205 ENTRY(_start_kernel)
206         /* Mask all interrupts */
207         csrw CSR_IE, zero
208         csrw CSR_IP, zero
209
210 #ifdef CONFIG_RISCV_M_MODE
211         /* flush the instruction cache */
212         fence.i
213
214         /* Reset all registers except ra, a0, a1 */
215         call reset_regs
216
217         /*
218          * Setup a PMP to permit access to all of memory.  Some machines may
219          * not implement PMPs, so we set up a quick trap handler to just skip
220          * touching the PMPs on any trap.
221          */
222         la a0, pmp_done
223         csrw CSR_TVEC, a0
224
225         li a0, -1
226         csrw CSR_PMPADDR0, a0
227         li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X)
228         csrw CSR_PMPCFG0, a0
229 .align 2
230 pmp_done:
231
232         /*
233          * The hartid in a0 is expected later on, and we have no firmware
234          * to hand it to us.
235          */
236         csrr a0, CSR_MHARTID
237 #endif /* CONFIG_RISCV_M_MODE */
238
239         /* Load the global pointer */
240 .option push
241 .option norelax
242         la gp, __global_pointer$
243 .option pop
244
245         /*
246          * Disable FPU to detect illegal usage of
247          * floating point in kernel space
248          */
249         li t0, SR_FS
250         csrc CSR_STATUS, t0
251
252 #ifdef CONFIG_SMP
253         li t0, CONFIG_NR_CPUS
254         blt a0, t0, .Lgood_cores
255         tail .Lsecondary_park
256 .Lgood_cores:
257 #endif
258
259 #ifndef CONFIG_XIP_KERNEL
260         /* Pick one hart to run the main boot sequence */
261         la a3, hart_lottery
262         li a2, 1
263         amoadd.w a3, a2, (a3)
264         bnez a3, .Lsecondary_start
265
266 #else
267         /* hart_lottery in flash contains a magic number */
268         la a3, hart_lottery
269         mv a2, a3
270         XIP_FIXUP_OFFSET a2
271         lw t1, (a3)
272         amoswap.w t0, t1, (a2)
273         /* first time here if hart_lottery in RAM is not set */
274         beq t0, t1, .Lsecondary_start
275
276         la sp, _end + THREAD_SIZE
277         XIP_FIXUP_OFFSET sp
278         mv s0, a0
279         call __copy_data
280
281         /* Restore a0 copy */
282         mv a0, s0
283 #endif
284
285 #ifndef CONFIG_XIP_KERNEL
286         /* Clear BSS for flat non-ELF images */
287         la a3, __bss_start
288         la a4, __bss_stop
289         ble a4, a3, clear_bss_done
290 clear_bss:
291         REG_S zero, (a3)
292         add a3, a3, RISCV_SZPTR
293         blt a3, a4, clear_bss
294 clear_bss_done:
295 #endif
296         /* Save hart ID and DTB physical address */
297         mv s0, a0
298         mv s1, a1
299
300         la a2, boot_cpu_hartid
301         XIP_FIXUP_OFFSET a2
302         REG_S a0, (a2)
303
304         /* Initialize page tables and relocate to virtual addresses */
305         la sp, init_thread_union + THREAD_SIZE
306         XIP_FIXUP_OFFSET sp
307 #ifdef CONFIG_BUILTIN_DTB
308         la a0, __dtb_start
309 #else
310         mv a0, s1
311 #endif /* CONFIG_BUILTIN_DTB */
312         call setup_vm
313 #ifdef CONFIG_MMU
314         la a0, early_pg_dir
315         XIP_FIXUP_OFFSET a0
316         call relocate_enable_mmu
317 #endif /* CONFIG_MMU */
318
319         call setup_trap_vector
320         /* Restore C environment */
321         la tp, init_task
322         sw zero, TASK_TI_CPU(tp)
323         la sp, init_thread_union + THREAD_SIZE
324
325 #ifdef CONFIG_KASAN
326         call kasan_early_init
327 #endif
328         /* Start the kernel */
329         call soc_early_init
330         tail start_kernel
331
332 .Lsecondary_start:
333 #ifdef CONFIG_SMP
334         /* Set trap vector to spin forever to help debug */
335         la a3, .Lsecondary_park
336         csrw CSR_TVEC, a3
337
338         slli a3, a0, LGREG
339         la a1, __cpu_up_stack_pointer
340         XIP_FIXUP_OFFSET a1
341         la a2, __cpu_up_task_pointer
342         XIP_FIXUP_OFFSET a2
343         add a1, a3, a1
344         add a2, a3, a2
345
346         /*
347          * This hart didn't win the lottery, so we wait for the winning hart to
348          * get far enough along the boot process that it should continue.
349          */
350 .Lwait_for_cpu_up:
351         /* FIXME: We should WFI to save some energy here. */
352         REG_L sp, (a1)
353         REG_L tp, (a2)
354         beqz sp, .Lwait_for_cpu_up
355         beqz tp, .Lwait_for_cpu_up
356         fence
357
358         tail secondary_start_common
359 #endif
360
361 END(_start_kernel)
362
363 #ifdef CONFIG_RISCV_M_MODE
364 ENTRY(reset_regs)
365         li      sp, 0
366         li      gp, 0
367         li      tp, 0
368         li      t0, 0
369         li      t1, 0
370         li      t2, 0
371         li      s0, 0
372         li      s1, 0
373         li      a2, 0
374         li      a3, 0
375         li      a4, 0
376         li      a5, 0
377         li      a6, 0
378         li      a7, 0
379         li      s2, 0
380         li      s3, 0
381         li      s4, 0
382         li      s5, 0
383         li      s6, 0
384         li      s7, 0
385         li      s8, 0
386         li      s9, 0
387         li      s10, 0
388         li      s11, 0
389         li      t3, 0
390         li      t4, 0
391         li      t5, 0
392         li      t6, 0
393         csrw    CSR_SCRATCH, 0
394
395 #ifdef CONFIG_FPU
396         csrr    t0, CSR_MISA
397         andi    t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
398         beqz    t0, .Lreset_regs_done
399
400         li      t1, SR_FS
401         csrs    CSR_STATUS, t1
402         fmv.s.x f0, zero
403         fmv.s.x f1, zero
404         fmv.s.x f2, zero
405         fmv.s.x f3, zero
406         fmv.s.x f4, zero
407         fmv.s.x f5, zero
408         fmv.s.x f6, zero
409         fmv.s.x f7, zero
410         fmv.s.x f8, zero
411         fmv.s.x f9, zero
412         fmv.s.x f10, zero
413         fmv.s.x f11, zero
414         fmv.s.x f12, zero
415         fmv.s.x f13, zero
416         fmv.s.x f14, zero
417         fmv.s.x f15, zero
418         fmv.s.x f16, zero
419         fmv.s.x f17, zero
420         fmv.s.x f18, zero
421         fmv.s.x f19, zero
422         fmv.s.x f20, zero
423         fmv.s.x f21, zero
424         fmv.s.x f22, zero
425         fmv.s.x f23, zero
426         fmv.s.x f24, zero
427         fmv.s.x f25, zero
428         fmv.s.x f26, zero
429         fmv.s.x f27, zero
430         fmv.s.x f28, zero
431         fmv.s.x f29, zero
432         fmv.s.x f30, zero
433         fmv.s.x f31, zero
434         csrw    fcsr, 0
435         /* note that the caller must clear SR_FS */
436 #endif /* CONFIG_FPU */
437 .Lreset_regs_done:
438         ret
439 END(reset_regs)
440 #endif /* CONFIG_RISCV_M_MODE */
441
442 __PAGE_ALIGNED_BSS
443         /* Empty zero page */
444         .balign PAGE_SIZE