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