Merge tag 'io_uring-5.6-2020-02-28' of git://git.kernel.dk/linux-block
[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         /* Setup a PMP to permit access to all of memory. */
62         li a0, -1
63         csrw CSR_PMPADDR0, a0
64         li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X)
65         csrw CSR_PMPCFG0, a0
66
67         /*
68          * The hartid in a0 is expected later on, and we have no firmware
69          * to hand it to us.
70          */
71         csrr a0, CSR_MHARTID
72 #endif /* CONFIG_RISCV_M_MODE */
73
74         /* Load the global pointer */
75 .option push
76 .option norelax
77         la gp, __global_pointer$
78 .option pop
79
80         /*
81          * Disable FPU to detect illegal usage of
82          * floating point in kernel space
83          */
84         li t0, SR_FS
85         csrc CSR_STATUS, t0
86
87 #ifdef CONFIG_SMP
88         li t0, CONFIG_NR_CPUS
89         blt a0, t0, .Lgood_cores
90         tail .Lsecondary_park
91 .Lgood_cores:
92 #endif
93
94         /* Pick one hart to run the main boot sequence */
95         la a3, hart_lottery
96         li a2, 1
97         amoadd.w a3, a2, (a3)
98         bnez a3, .Lsecondary_start
99
100         /* Clear BSS for flat non-ELF images */
101         la a3, __bss_start
102         la a4, __bss_stop
103         ble a4, a3, clear_bss_done
104 clear_bss:
105         REG_S zero, (a3)
106         add a3, a3, RISCV_SZPTR
107         blt a3, a4, clear_bss
108 clear_bss_done:
109
110         /* Save hart ID and DTB physical address */
111         mv s0, a0
112         mv s1, a1
113         la a2, boot_cpu_hartid
114         REG_S a0, (a2)
115
116         /* Initialize page tables and relocate to virtual addresses */
117         la sp, init_thread_union + THREAD_SIZE
118         mv a0, s1
119         call setup_vm
120 #ifdef CONFIG_MMU
121         la a0, early_pg_dir
122         call relocate
123 #endif /* CONFIG_MMU */
124
125         /* Restore C environment */
126         la tp, init_task
127         sw zero, TASK_TI_CPU(tp)
128         la sp, init_thread_union + THREAD_SIZE
129
130 #ifdef CONFIG_KASAN
131         call kasan_early_init
132 #endif
133         /* Start the kernel */
134         call parse_dtb
135         tail start_kernel
136
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 .Lsecondary_start:
191 #ifdef CONFIG_SMP
192         /* Set trap vector to spin forever to help debug */
193         la a3, .Lsecondary_park
194         csrw CSR_TVEC, a3
195
196         slli a3, a0, LGREG
197         la a1, __cpu_up_stack_pointer
198         la a2, __cpu_up_task_pointer
199         add a1, a3, a1
200         add a2, a3, a2
201
202         /*
203          * This hart didn't win the lottery, so we wait for the winning hart to
204          * get far enough along the boot process that it should continue.
205          */
206 .Lwait_for_cpu_up:
207         /* FIXME: We should WFI to save some energy here. */
208         REG_L sp, (a1)
209         REG_L tp, (a2)
210         beqz sp, .Lwait_for_cpu_up
211         beqz tp, .Lwait_for_cpu_up
212         fence
213
214 #ifdef CONFIG_MMU
215         /* Enable virtual memory and relocate to virtual address */
216         la a0, swapper_pg_dir
217         call relocate
218 #endif
219
220         tail smp_callin
221 #endif
222
223 END(_start)
224
225 #ifdef CONFIG_RISCV_M_MODE
226 ENTRY(reset_regs)
227         li      sp, 0
228         li      gp, 0
229         li      tp, 0
230         li      t0, 0
231         li      t1, 0
232         li      t2, 0
233         li      s0, 0
234         li      s1, 0
235         li      a2, 0
236         li      a3, 0
237         li      a4, 0
238         li      a5, 0
239         li      a6, 0
240         li      a7, 0
241         li      s2, 0
242         li      s3, 0
243         li      s4, 0
244         li      s5, 0
245         li      s6, 0
246         li      s7, 0
247         li      s8, 0
248         li      s9, 0
249         li      s10, 0
250         li      s11, 0
251         li      t3, 0
252         li      t4, 0
253         li      t5, 0
254         li      t6, 0
255         csrw    CSR_SCRATCH, 0
256
257 #ifdef CONFIG_FPU
258         csrr    t0, CSR_MISA
259         andi    t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
260         beqz    t0, .Lreset_regs_done
261
262         li      t1, SR_FS
263         csrs    CSR_STATUS, t1
264         fmv.s.x f0, zero
265         fmv.s.x f1, zero
266         fmv.s.x f2, zero
267         fmv.s.x f3, zero
268         fmv.s.x f4, zero
269         fmv.s.x f5, zero
270         fmv.s.x f6, zero
271         fmv.s.x f7, zero
272         fmv.s.x f8, zero
273         fmv.s.x f9, zero
274         fmv.s.x f10, zero
275         fmv.s.x f11, zero
276         fmv.s.x f12, zero
277         fmv.s.x f13, zero
278         fmv.s.x f14, zero
279         fmv.s.x f15, zero
280         fmv.s.x f16, zero
281         fmv.s.x f17, zero
282         fmv.s.x f18, zero
283         fmv.s.x f19, zero
284         fmv.s.x f20, zero
285         fmv.s.x f21, zero
286         fmv.s.x f22, zero
287         fmv.s.x f23, zero
288         fmv.s.x f24, zero
289         fmv.s.x f25, zero
290         fmv.s.x f26, zero
291         fmv.s.x f27, zero
292         fmv.s.x f28, zero
293         fmv.s.x f29, zero
294         fmv.s.x f30, zero
295         fmv.s.x f31, zero
296         csrw    fcsr, 0
297         /* note that the caller must clear SR_FS */
298 #endif /* CONFIG_FPU */
299 .Lreset_regs_done:
300         ret
301 END(reset_regs)
302 #endif /* CONFIG_RISCV_M_MODE */
303
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 __PAGE_ALIGNED_BSS
312         /* Empty zero page */
313         .balign PAGE_SIZE