head.S 6.2 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-only */
P
Palmer Dabbelt 已提交
2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright (C) 2012 Regents of the University of California
 */

#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/asm.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/csr.h>
14
#include <asm/hwcap.h>
15
#include <asm/image.h>
P
Palmer Dabbelt 已提交
16 17 18

__INIT
ENTRY(_start)
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
	/*
	 * Image header expected by Linux boot-loaders. The image header data
	 * structure is described in asm/image.h.
	 * Do not modify it without modifying the structure and all bootloaders
	 * that expects this header format!!
	 */
	/* jump to start kernel */
	j _start_kernel
	/* reserved */
	.word 0
	.balign 8
#if __riscv_xlen == 64
	/* Image load offset(2MB) from start of RAM */
	.dword 0x200000
#else
	/* Image load offset(4MB) from start of RAM */
	.dword 0x400000
#endif
	/* Effective size of kernel image */
	.dword _end - _start
	.dword __HEAD_FLAGS
	.word RISCV_HEADER_VERSION
	.word 0
	.dword 0
43
	.ascii RISCV_IMAGE_MAGIC
44
	.balign 4
45
	.ascii RISCV_IMAGE_MAGIC2
46 47 48 49
	.word 0

.global _start_kernel
_start_kernel:
50
	/* Mask all interrupts */
51 52
	csrw CSR_IE, zero
	csrw CSR_IP, zero
P
Palmer Dabbelt 已提交
53

54
#ifdef CONFIG_RISCV_M_MODE
55 56 57 58 59 60
	/* flush the instruction cache */
	fence.i

	/* Reset all registers except ra, a0, a1 */
	call reset_regs

61 62 63 64 65 66
	/* Setup a PMP to permit access to all of memory. */
	li a0, -1
	csrw CSR_PMPADDR0, a0
	li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X)
	csrw CSR_PMPCFG0, a0

67 68 69 70 71
	/*
	 * The hartid in a0 is expected later on, and we have no firmware
	 * to hand it to us.
	 */
	csrr a0, CSR_MHARTID
72
#endif /* CONFIG_RISCV_M_MODE */
73

P
Palmer Dabbelt 已提交
74 75 76 77 78 79 80 81 82 83 84
	/* Load the global pointer */
.option push
.option norelax
	la gp, __global_pointer$
.option pop

	/*
	 * Disable FPU to detect illegal usage of
	 * floating point in kernel space
	 */
	li t0, SR_FS
85
	csrc CSR_STATUS, t0
P
Palmer Dabbelt 已提交
86

87 88
#ifdef CONFIG_SMP
	li t0, CONFIG_NR_CPUS
89 90 91
	blt a0, t0, .Lgood_cores
	tail .Lsecondary_park
.Lgood_cores:
92 93
#endif

P
Palmer Dabbelt 已提交
94 95 96 97 98 99
	/* Pick one hart to run the main boot sequence */
	la a3, hart_lottery
	li a2, 1
	amoadd.w a3, a2, (a3)
	bnez a3, .Lsecondary_start

100 101 102 103 104 105 106 107 108 109
	/* Clear BSS for flat non-ELF images */
	la a3, __bss_start
	la a4, __bss_stop
	ble a4, a3, clear_bss_done
clear_bss:
	REG_S zero, (a3)
	add a3, a3, RISCV_SZPTR
	blt a3, a4, clear_bss
clear_bss_done:

P
Palmer Dabbelt 已提交
110 111 112
	/* Save hart ID and DTB physical address */
	mv s0, a0
	mv s1, a1
113 114
	la a2, boot_cpu_hartid
	REG_S a0, (a2)
P
Palmer Dabbelt 已提交
115 116 117

	/* Initialize page tables and relocate to virtual addresses */
	la sp, init_thread_union + THREAD_SIZE
118
	mv a0, s1
P
Palmer Dabbelt 已提交
119
	call setup_vm
C
Christoph Hellwig 已提交
120
#ifdef CONFIG_MMU
121
	la a0, early_pg_dir
P
Palmer Dabbelt 已提交
122
	call relocate
C
Christoph Hellwig 已提交
123
#endif /* CONFIG_MMU */
P
Palmer Dabbelt 已提交
124 125 126

	/* Restore C environment */
	la tp, init_task
127
	sw zero, TASK_TI_CPU(tp)
128
	la sp, init_thread_union + THREAD_SIZE
P
Palmer Dabbelt 已提交
129

N
Nick Hu 已提交
130 131 132
#ifdef CONFIG_KASAN
	call kasan_early_init
#endif
P
Palmer Dabbelt 已提交
133
	/* Start the kernel */
134
	call parse_dtb
P
Palmer Dabbelt 已提交
135 136
	tail start_kernel

C
Christoph Hellwig 已提交
137
#ifdef CONFIG_MMU
P
Palmer Dabbelt 已提交
138 139 140
relocate:
	/* Relocate return address */
	li a1, PAGE_OFFSET
141 142
	la a2, _start
	sub a1, a1, a2
P
Palmer Dabbelt 已提交
143 144
	add ra, ra, a1

C
Christoph Hellwig 已提交
145
	/* Point stvec to virtual address of intruction after satp write */
146 147
	la a2, 1f
	add a2, a2, a1
148
	csrw CSR_TVEC, a2
P
Palmer Dabbelt 已提交
149

C
Christoph Hellwig 已提交
150
	/* Compute satp for kernel page tables, but don't load it yet */
151
	srl a2, a0, PAGE_SHIFT
C
Christoph Hellwig 已提交
152
	li a1, SATP_MODE
P
Palmer Dabbelt 已提交
153 154 155 156
	or a2, a2, a1

	/*
	 * Load trampoline page directory, which will cause us to trap to
157 158 159
	 * stvec if VA != PA, or simply fall through if VA == PA.  We need a
	 * full fence here because setup_vm() just wrote these PTEs and we need
	 * to ensure the new translations are in use.
P
Palmer Dabbelt 已提交
160 161 162 163 164
	 */
	la a0, trampoline_pg_dir
	srl a0, a0, PAGE_SHIFT
	or a0, a0, a1
	sfence.vma
165
	csrw CSR_SATP, a0
166
.align 2
P
Palmer Dabbelt 已提交
167 168 169
1:
	/* Set trap vector to spin forever to help debug */
	la a0, .Lsecondary_park
170
	csrw CSR_TVEC, a0
P
Palmer Dabbelt 已提交
171 172 173 174 175 176 177

	/* Reload the global pointer */
.option push
.option norelax
	la gp, __global_pointer$
.option pop

178 179 180 181 182 183
	/*
	 * Switch to kernel page tables.  A full fence is necessary in order to
	 * avoid using the trampoline translations, which are only correct for
	 * the first superpage.  Fetching the fence is guarnteed to work
	 * because that first superpage is translated the same way.
	 */
184
	csrw CSR_SATP, a2
185
	sfence.vma
P
Palmer Dabbelt 已提交
186 187

	ret
C
Christoph Hellwig 已提交
188
#endif /* CONFIG_MMU */
P
Palmer Dabbelt 已提交
189 190 191 192 193

.Lsecondary_start:
#ifdef CONFIG_SMP
	/* Set trap vector to spin forever to help debug */
	la a3, .Lsecondary_park
194
	csrw CSR_TVEC, a3
P
Palmer Dabbelt 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213

	slli a3, a0, LGREG
	la a1, __cpu_up_stack_pointer
	la a2, __cpu_up_task_pointer
	add a1, a3, a1
	add a2, a3, a2

	/*
	 * This hart didn't win the lottery, so we wait for the winning hart to
	 * get far enough along the boot process that it should continue.
	 */
.Lwait_for_cpu_up:
	/* FIXME: We should WFI to save some energy here. */
	REG_L sp, (a1)
	REG_L tp, (a2)
	beqz sp, .Lwait_for_cpu_up
	beqz tp, .Lwait_for_cpu_up
	fence

C
Christoph Hellwig 已提交
214
#ifdef CONFIG_MMU
P
Palmer Dabbelt 已提交
215
	/* Enable virtual memory and relocate to virtual address */
216
	la a0, swapper_pg_dir
P
Palmer Dabbelt 已提交
217
	call relocate
C
Christoph Hellwig 已提交
218
#endif
P
Palmer Dabbelt 已提交
219 220 221 222 223 224

	tail smp_callin
#endif

END(_start)

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
#ifdef CONFIG_RISCV_M_MODE
ENTRY(reset_regs)
	li	sp, 0
	li	gp, 0
	li	tp, 0
	li	t0, 0
	li	t1, 0
	li	t2, 0
	li	s0, 0
	li	s1, 0
	li	a2, 0
	li	a3, 0
	li	a4, 0
	li	a5, 0
	li	a6, 0
	li	a7, 0
	li	s2, 0
	li	s3, 0
	li	s4, 0
	li	s5, 0
	li	s6, 0
	li	s7, 0
	li	s8, 0
	li	s9, 0
	li	s10, 0
	li	s11, 0
	li	t3, 0
	li	t4, 0
	li	t5, 0
	li	t6, 0
255
	csrw	CSR_SCRATCH, 0
256 257 258 259

#ifdef CONFIG_FPU
	csrr	t0, CSR_MISA
	andi	t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
260
	beqz	t0, .Lreset_regs_done
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303

	li	t1, SR_FS
	csrs	CSR_STATUS, t1
	fmv.s.x	f0, zero
	fmv.s.x	f1, zero
	fmv.s.x	f2, zero
	fmv.s.x	f3, zero
	fmv.s.x	f4, zero
	fmv.s.x	f5, zero
	fmv.s.x	f6, zero
	fmv.s.x	f7, zero
	fmv.s.x	f8, zero
	fmv.s.x	f9, zero
	fmv.s.x	f10, zero
	fmv.s.x	f11, zero
	fmv.s.x	f12, zero
	fmv.s.x	f13, zero
	fmv.s.x	f14, zero
	fmv.s.x	f15, zero
	fmv.s.x	f16, zero
	fmv.s.x	f17, zero
	fmv.s.x	f18, zero
	fmv.s.x	f19, zero
	fmv.s.x	f20, zero
	fmv.s.x	f21, zero
	fmv.s.x	f22, zero
	fmv.s.x	f23, zero
	fmv.s.x	f24, zero
	fmv.s.x	f25, zero
	fmv.s.x	f26, zero
	fmv.s.x	f27, zero
	fmv.s.x	f28, zero
	fmv.s.x	f29, zero
	fmv.s.x	f30, zero
	fmv.s.x	f31, zero
	csrw	fcsr, 0
	/* note that the caller must clear SR_FS */
#endif /* CONFIG_FPU */
.Lreset_regs_done:
	ret
END(reset_regs)
#endif /* CONFIG_RISCV_M_MODE */

304 305 306 307 308 309 310
.section ".text", "ax",@progbits
.align 2
.Lsecondary_park:
	/* We lack SMP support or have too many harts, so park this hart */
	wfi
	j .Lsecondary_park

P
Palmer Dabbelt 已提交
311 312 313
__PAGE_ALIGNED_BSS
	/* Empty zero page */
	.balign PAGE_SIZE