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 /* Start the kernel */ 125 call parse_dtb 126 tail start_kernel 127 128#ifdef CONFIG_MMU 129relocate: 130 /* Relocate return address */ 131 li a1, PAGE_OFFSET 132 la a2, _start 133 sub a1, a1, a2 134 add ra, ra, a1 135 136 /* Point stvec to virtual address of intruction after satp write */ 137 la a2, 1f 138 add a2, a2, a1 139 csrw CSR_TVEC, a2 140 141 /* Compute satp for kernel page tables, but don't load it yet */ 142 srl a2, a0, PAGE_SHIFT 143 li a1, SATP_MODE 144 or a2, a2, a1 145 146 /* 147 * Load trampoline page directory, which will cause us to trap to 148 * stvec if VA != PA, or simply fall through if VA == PA. We need a 149 * full fence here because setup_vm() just wrote these PTEs and we need 150 * to ensure the new translations are in use. 151 */ 152 la a0, trampoline_pg_dir 153 srl a0, a0, PAGE_SHIFT 154 or a0, a0, a1 155 sfence.vma 156 csrw CSR_SATP, a0 157.align 2 1581: 159 /* Set trap vector to spin forever to help debug */ 160 la a0, .Lsecondary_park 161 csrw CSR_TVEC, a0 162 163 /* Reload the global pointer */ 164.option push 165.option norelax 166 la gp, __global_pointer$ 167.option pop 168 169 /* 170 * Switch to kernel page tables. A full fence is necessary in order to 171 * avoid using the trampoline translations, which are only correct for 172 * the first superpage. Fetching the fence is guarnteed to work 173 * because that first superpage is translated the same way. 174 */ 175 csrw CSR_SATP, a2 176 sfence.vma 177 178 ret 179#endif /* CONFIG_MMU */ 180 181.Lsecondary_start: 182#ifdef CONFIG_SMP 183 /* Set trap vector to spin forever to help debug */ 184 la a3, .Lsecondary_park 185 csrw CSR_TVEC, a3 186 187 slli a3, a0, LGREG 188 la a1, __cpu_up_stack_pointer 189 la a2, __cpu_up_task_pointer 190 add a1, a3, a1 191 add a2, a3, a2 192 193 /* 194 * This hart didn't win the lottery, so we wait for the winning hart to 195 * get far enough along the boot process that it should continue. 196 */ 197.Lwait_for_cpu_up: 198 /* FIXME: We should WFI to save some energy here. */ 199 REG_L sp, (a1) 200 REG_L tp, (a2) 201 beqz sp, .Lwait_for_cpu_up 202 beqz tp, .Lwait_for_cpu_up 203 fence 204 205#ifdef CONFIG_MMU 206 /* Enable virtual memory and relocate to virtual address */ 207 la a0, swapper_pg_dir 208 call relocate 209#endif 210 211 tail smp_callin 212#endif 213 214END(_start) 215 216#ifdef CONFIG_RISCV_M_MODE 217ENTRY(reset_regs) 218 li sp, 0 219 li gp, 0 220 li tp, 0 221 li t0, 0 222 li t1, 0 223 li t2, 0 224 li s0, 0 225 li s1, 0 226 li a2, 0 227 li a3, 0 228 li a4, 0 229 li a5, 0 230 li a6, 0 231 li a7, 0 232 li s2, 0 233 li s3, 0 234 li s4, 0 235 li s5, 0 236 li s6, 0 237 li s7, 0 238 li s8, 0 239 li s9, 0 240 li s10, 0 241 li s11, 0 242 li t3, 0 243 li t4, 0 244 li t5, 0 245 li t6, 0 246 csrw CSR_SCRATCH, 0 247 248#ifdef CONFIG_FPU 249 csrr t0, CSR_MISA 250 andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) 251 beqz t0, .Lreset_regs_done 252 253 li t1, SR_FS 254 csrs CSR_STATUS, t1 255 fmv.s.x f0, zero 256 fmv.s.x f1, zero 257 fmv.s.x f2, zero 258 fmv.s.x f3, zero 259 fmv.s.x f4, zero 260 fmv.s.x f5, zero 261 fmv.s.x f6, zero 262 fmv.s.x f7, zero 263 fmv.s.x f8, zero 264 fmv.s.x f9, zero 265 fmv.s.x f10, zero 266 fmv.s.x f11, zero 267 fmv.s.x f12, zero 268 fmv.s.x f13, zero 269 fmv.s.x f14, zero 270 fmv.s.x f15, zero 271 fmv.s.x f16, zero 272 fmv.s.x f17, zero 273 fmv.s.x f18, zero 274 fmv.s.x f19, zero 275 fmv.s.x f20, zero 276 fmv.s.x f21, zero 277 fmv.s.x f22, zero 278 fmv.s.x f23, zero 279 fmv.s.x f24, zero 280 fmv.s.x f25, zero 281 fmv.s.x f26, zero 282 fmv.s.x f27, zero 283 fmv.s.x f28, zero 284 fmv.s.x f29, zero 285 fmv.s.x f30, zero 286 fmv.s.x f31, zero 287 csrw fcsr, 0 288 /* note that the caller must clear SR_FS */ 289#endif /* CONFIG_FPU */ 290.Lreset_regs_done: 291 ret 292END(reset_regs) 293#endif /* CONFIG_RISCV_M_MODE */ 294 295.section ".text", "ax",@progbits 296.align 2 297.Lsecondary_park: 298 /* We lack SMP support or have too many harts, so park this hart */ 299 wfi 300 j .Lsecondary_park 301 302__PAGE_ALIGNED_BSS 303 /* Empty zero page */ 304 .balign PAGE_SIZE 305