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 18ENTRY(_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 98clear_bss: 99 REG_S zero, (a3) 100 add a3, a3, RISCV_SZPTR 101 blt a3, a4, clear_bss 102clear_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 132relocate: 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 1611: 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 217END(_start) 218 219#ifdef CONFIG_RISCV_M_MODE 220ENTRY(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 295END(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 308