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 /* 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 104clear_bss: 105 REG_S zero, (a3) 106 add a3, a3, RISCV_SZPTR 107 blt a3, a4, clear_bss 108clear_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 138relocate: 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 1671: 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 223END(_start) 224 225#ifdef CONFIG_RISCV_M_MODE 226ENTRY(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 301END(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 314