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