Merge branch 'linux-5.6' of git://github.com/skeggsb/linux into drm-fixes
[linux-2.6-microblaze.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/thread_info.h>
7 #include <asm/asm-offsets.h>
8 #include <asm/asm.h>
9 #include <linux/init.h>
10 #include <linux/linkage.h>
11 #include <asm/thread_info.h>
12 #include <asm/page.h>
13 #include <asm/csr.h>
14 #include <asm/hwcap.h>
15 #include <asm/image.h>
16
17 __INIT
18 ENTRY(_start)
19         /*
20          * Image header expected by Linux boot-loaders. The image header data
21          * structure is described in asm/image.h.
22          * Do not modify it without modifying the structure and all bootloaders
23          * that expects this header format!!
24          */
25         /* jump to start kernel */
26         j _start_kernel
27         /* reserved */
28         .word 0
29         .balign 8
30 #if __riscv_xlen == 64
31         /* Image load offset(2MB) from start of RAM */
32         .dword 0x200000
33 #else
34         /* Image load offset(4MB) from start of RAM */
35         .dword 0x400000
36 #endif
37         /* Effective size of kernel image */
38         .dword _end - _start
39         .dword __HEAD_FLAGS
40         .word RISCV_HEADER_VERSION
41         .word 0
42         .dword 0
43         .ascii RISCV_IMAGE_MAGIC
44         .balign 4
45         .ascii RISCV_IMAGE_MAGIC2
46         .word 0
47
48 .global _start_kernel
49 _start_kernel:
50         /* Mask all interrupts */
51         csrw CSR_IE, zero
52         csrw CSR_IP, zero
53
54 #ifdef CONFIG_RISCV_M_MODE
55         /* flush the instruction cache */
56         fence.i
57
58         /* Reset all registers except ra, a0, a1 */
59         call reset_regs
60
61         /*
62          * The hartid in a0 is expected later on, and we have no firmware
63          * to hand it to us.
64          */
65         csrr a0, CSR_MHARTID
66 #endif /* CONFIG_RISCV_M_MODE */
67
68         /* Load the global pointer */
69 .option push
70 .option norelax
71         la gp, __global_pointer$
72 .option pop
73
74         /*
75          * Disable FPU to detect illegal usage of
76          * floating point in kernel space
77          */
78         li t0, SR_FS
79         csrc CSR_STATUS, t0
80
81 #ifdef CONFIG_SMP
82         li t0, CONFIG_NR_CPUS
83         blt a0, t0, .Lgood_cores
84         tail .Lsecondary_park
85 .Lgood_cores:
86 #endif
87
88         /* Pick one hart to run the main boot sequence */
89         la a3, hart_lottery
90         li a2, 1
91         amoadd.w a3, a2, (a3)
92         bnez a3, .Lsecondary_start
93
94         /* Clear BSS for flat non-ELF images */
95         la a3, __bss_start
96         la a4, __bss_stop
97         ble a4, a3, clear_bss_done
98 clear_bss:
99         REG_S zero, (a3)
100         add a3, a3, RISCV_SZPTR
101         blt a3, a4, clear_bss
102 clear_bss_done:
103
104         /* Save hart ID and DTB physical address */
105         mv s0, a0
106         mv s1, a1
107         la a2, boot_cpu_hartid
108         REG_S a0, (a2)
109
110         /* Initialize page tables and relocate to virtual addresses */
111         la sp, init_thread_union + THREAD_SIZE
112         mv a0, s1
113         call setup_vm
114 #ifdef CONFIG_MMU
115         la a0, early_pg_dir
116         call relocate
117 #endif /* CONFIG_MMU */
118
119         /* Restore C environment */
120         la tp, init_task
121         sw zero, TASK_TI_CPU(tp)
122         la sp, init_thread_union + THREAD_SIZE
123
124 #ifdef CONFIG_KASAN
125         call kasan_early_init
126 #endif
127         /* Start the kernel */
128         call parse_dtb
129         tail start_kernel
130
131 #ifdef CONFIG_MMU
132 relocate:
133         /* Relocate return address */
134         li a1, PAGE_OFFSET
135         la a2, _start
136         sub a1, a1, a2
137         add ra, ra, a1
138
139         /* Point stvec to virtual address of intruction after satp write */
140         la a2, 1f
141         add a2, a2, a1
142         csrw CSR_TVEC, a2
143
144         /* Compute satp for kernel page tables, but don't load it yet */
145         srl a2, a0, PAGE_SHIFT
146         li a1, SATP_MODE
147         or a2, a2, a1
148
149         /*
150          * Load trampoline page directory, which will cause us to trap to
151          * stvec if VA != PA, or simply fall through if VA == PA.  We need a
152          * full fence here because setup_vm() just wrote these PTEs and we need
153          * to ensure the new translations are in use.
154          */
155         la a0, trampoline_pg_dir
156         srl a0, a0, PAGE_SHIFT
157         or a0, a0, a1
158         sfence.vma
159         csrw CSR_SATP, a0
160 .align 2
161 1:
162         /* Set trap vector to spin forever to help debug */
163         la a0, .Lsecondary_park
164         csrw CSR_TVEC, a0
165
166         /* Reload the global pointer */
167 .option push
168 .option norelax
169         la gp, __global_pointer$
170 .option pop
171
172         /*
173          * Switch to kernel page tables.  A full fence is necessary in order to
174          * avoid using the trampoline translations, which are only correct for
175          * the first superpage.  Fetching the fence is guarnteed to work
176          * because that first superpage is translated the same way.
177          */
178         csrw CSR_SATP, a2
179         sfence.vma
180
181         ret
182 #endif /* CONFIG_MMU */
183
184 .Lsecondary_start:
185 #ifdef CONFIG_SMP
186         /* Set trap vector to spin forever to help debug */
187         la a3, .Lsecondary_park
188         csrw CSR_TVEC, a3
189
190         slli a3, a0, LGREG
191         la a1, __cpu_up_stack_pointer
192         la a2, __cpu_up_task_pointer
193         add a1, a3, a1
194         add a2, a3, a2
195
196         /*
197          * This hart didn't win the lottery, so we wait for the winning hart to
198          * get far enough along the boot process that it should continue.
199          */
200 .Lwait_for_cpu_up:
201         /* FIXME: We should WFI to save some energy here. */
202         REG_L sp, (a1)
203         REG_L tp, (a2)
204         beqz sp, .Lwait_for_cpu_up
205         beqz tp, .Lwait_for_cpu_up
206         fence
207
208 #ifdef CONFIG_MMU
209         /* Enable virtual memory and relocate to virtual address */
210         la a0, swapper_pg_dir
211         call relocate
212 #endif
213
214         tail smp_callin
215 #endif
216
217 END(_start)
218
219 #ifdef CONFIG_RISCV_M_MODE
220 ENTRY(reset_regs)
221         li      sp, 0
222         li      gp, 0
223         li      tp, 0
224         li      t0, 0
225         li      t1, 0
226         li      t2, 0
227         li      s0, 0
228         li      s1, 0
229         li      a2, 0
230         li      a3, 0
231         li      a4, 0
232         li      a5, 0
233         li      a6, 0
234         li      a7, 0
235         li      s2, 0
236         li      s3, 0
237         li      s4, 0
238         li      s5, 0
239         li      s6, 0
240         li      s7, 0
241         li      s8, 0
242         li      s9, 0
243         li      s10, 0
244         li      s11, 0
245         li      t3, 0
246         li      t4, 0
247         li      t5, 0
248         li      t6, 0
249         csrw    CSR_SCRATCH, 0
250
251 #ifdef CONFIG_FPU
252         csrr    t0, CSR_MISA
253         andi    t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
254         beqz    t0, .Lreset_regs_done
255
256         li      t1, SR_FS
257         csrs    CSR_STATUS, t1
258         fmv.s.x f0, zero
259         fmv.s.x f1, zero
260         fmv.s.x f2, zero
261         fmv.s.x f3, zero
262         fmv.s.x f4, zero
263         fmv.s.x f5, zero
264         fmv.s.x f6, zero
265         fmv.s.x f7, zero
266         fmv.s.x f8, zero
267         fmv.s.x f9, zero
268         fmv.s.x f10, zero
269         fmv.s.x f11, zero
270         fmv.s.x f12, zero
271         fmv.s.x f13, zero
272         fmv.s.x f14, zero
273         fmv.s.x f15, zero
274         fmv.s.x f16, zero
275         fmv.s.x f17, zero
276         fmv.s.x f18, zero
277         fmv.s.x f19, zero
278         fmv.s.x f20, zero
279         fmv.s.x f21, zero
280         fmv.s.x f22, zero
281         fmv.s.x f23, zero
282         fmv.s.x f24, zero
283         fmv.s.x f25, zero
284         fmv.s.x f26, zero
285         fmv.s.x f27, zero
286         fmv.s.x f28, zero
287         fmv.s.x f29, zero
288         fmv.s.x f30, zero
289         fmv.s.x f31, zero
290         csrw    fcsr, 0
291         /* note that the caller must clear SR_FS */
292 #endif /* CONFIG_FPU */
293 .Lreset_regs_done:
294         ret
295 END(reset_regs)
296 #endif /* CONFIG_RISCV_M_MODE */
297
298 .section ".text", "ax",@progbits
299 .align 2
300 .Lsecondary_park:
301         /* We lack SMP support or have too many harts, so park this hart */
302         wfi
303         j .Lsecondary_park
304
305 __PAGE_ALIGNED_BSS
306         /* Empty zero page */
307         .balign PAGE_SIZE