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 bgeu a0, t0, .Lsecondary_park 84#endif 85 86 /* Pick one hart to run the main boot sequence */ 87 la a3, hart_lottery 88 li a2, 1 89 amoadd.w a3, a2, (a3) 90 bnez a3, .Lsecondary_start 91 92 /* Clear BSS for flat non-ELF images */ 93 la a3, __bss_start 94 la a4, __bss_stop 95 ble a4, a3, clear_bss_done 96clear_bss: 97 REG_S zero, (a3) 98 add a3, a3, RISCV_SZPTR 99 blt a3, a4, clear_bss 100clear_bss_done: 101 102 /* Save hart ID and DTB physical address */ 103 mv s0, a0 104 mv s1, a1 105 la a2, boot_cpu_hartid 106 REG_S a0, (a2) 107 108 /* Initialize page tables and relocate to virtual addresses */ 109 la sp, init_thread_union + THREAD_SIZE 110 mv a0, s1 111 call setup_vm 112#ifdef CONFIG_MMU 113 la a0, early_pg_dir 114 call relocate 115#endif /* CONFIG_MMU */ 116 117 /* Restore C environment */ 118 la tp, init_task 119 sw zero, TASK_TI_CPU(tp) 120 la sp, init_thread_union + THREAD_SIZE 121 122 /* Start the kernel */ 123 call parse_dtb 124 tail start_kernel 125 126#ifdef CONFIG_MMU 127relocate: 128 /* Relocate return address */ 129 li a1, PAGE_OFFSET 130 la a2, _start 131 sub a1, a1, a2 132 add ra, ra, a1 133 134 /* Point stvec to virtual address of intruction after satp write */ 135 la a2, 1f 136 add a2, a2, a1 137 csrw CSR_TVEC, a2 138 139 /* Compute satp for kernel page tables, but don't load it yet */ 140 srl a2, a0, PAGE_SHIFT 141 li a1, SATP_MODE 142 or a2, a2, a1 143 144 /* 145 * Load trampoline page directory, which will cause us to trap to 146 * stvec if VA != PA, or simply fall through if VA == PA. We need a 147 * full fence here because setup_vm() just wrote these PTEs and we need 148 * to ensure the new translations are in use. 149 */ 150 la a0, trampoline_pg_dir 151 srl a0, a0, PAGE_SHIFT 152 or a0, a0, a1 153 sfence.vma 154 csrw CSR_SATP, a0 155.align 2 1561: 157 /* Set trap vector to spin forever to help debug */ 158 la a0, .Lsecondary_park 159 csrw CSR_TVEC, a0 160 161 /* Reload the global pointer */ 162.option push 163.option norelax 164 la gp, __global_pointer$ 165.option pop 166 167 /* 168 * Switch to kernel page tables. A full fence is necessary in order to 169 * avoid using the trampoline translations, which are only correct for 170 * the first superpage. Fetching the fence is guarnteed to work 171 * because that first superpage is translated the same way. 172 */ 173 csrw CSR_SATP, a2 174 sfence.vma 175 176 ret 177#endif /* CONFIG_MMU */ 178 179.Lsecondary_start: 180#ifdef CONFIG_SMP 181 /* Set trap vector to spin forever to help debug */ 182 la a3, .Lsecondary_park 183 csrw CSR_TVEC, a3 184 185 slli a3, a0, LGREG 186 la a1, __cpu_up_stack_pointer 187 la a2, __cpu_up_task_pointer 188 add a1, a3, a1 189 add a2, a3, a2 190 191 /* 192 * This hart didn't win the lottery, so we wait for the winning hart to 193 * get far enough along the boot process that it should continue. 194 */ 195.Lwait_for_cpu_up: 196 /* FIXME: We should WFI to save some energy here. */ 197 REG_L sp, (a1) 198 REG_L tp, (a2) 199 beqz sp, .Lwait_for_cpu_up 200 beqz tp, .Lwait_for_cpu_up 201 fence 202 203#ifdef CONFIG_MMU 204 /* Enable virtual memory and relocate to virtual address */ 205 la a0, swapper_pg_dir 206 call relocate 207#endif 208 209 tail smp_callin 210#endif 211 212.align 2 213.Lsecondary_park: 214 /* We lack SMP support or have too many harts, so park this hart */ 215 wfi 216 j .Lsecondary_park 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 sscratch, 0 250 251#ifdef CONFIG_FPU 252 csrr t0, CSR_MISA 253 andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) 254 bnez 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__PAGE_ALIGNED_BSS 299 /* Empty zero page */ 300 .balign PAGE_SIZE 301