xref: /openbmc/linux/arch/riscv/kernel/head.S (revision ca2478a7d974f38d29d27acb42a952c7f168916e)
150acfb2bSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
276d2a049SPalmer Dabbelt/*
376d2a049SPalmer Dabbelt * Copyright (C) 2012 Regents of the University of California
476d2a049SPalmer Dabbelt */
576d2a049SPalmer Dabbelt
676d2a049SPalmer Dabbelt#include <asm/asm-offsets.h>
776d2a049SPalmer Dabbelt#include <asm/asm.h>
876d2a049SPalmer Dabbelt#include <linux/init.h>
976d2a049SPalmer Dabbelt#include <linux/linkage.h>
1076d2a049SPalmer Dabbelt#include <asm/thread_info.h>
1176d2a049SPalmer Dabbelt#include <asm/page.h>
1244c92257SVitaly Wool#include <asm/pgtable.h>
1376d2a049SPalmer Dabbelt#include <asm/csr.h>
149a2451f1SAtish Patra#include <asm/cpu_ops_sbi.h>
159e806356SChristoph Hellwig#include <asm/hwcap.h>
160f327f2aSAtish Patra#include <asm/image.h>
17e7681bebSPalmer Dabbelt#include <asm/xip_fixup.h>
18cb7d2dd5SAtish Patra#include "efi-header.S"
1976d2a049SPalmer Dabbelt
20e011995eSAtish Patra__HEAD
2176d2a049SPalmer DabbeltENTRY(_start)
220f327f2aSAtish Patra	/*
230f327f2aSAtish Patra	 * Image header expected by Linux boot-loaders. The image header data
240f327f2aSAtish Patra	 * structure is described in asm/image.h.
250f327f2aSAtish Patra	 * Do not modify it without modifying the structure and all bootloaders
260f327f2aSAtish Patra	 * that expects this header format!!
270f327f2aSAtish Patra	 */
28cb7d2dd5SAtish Patra#ifdef CONFIG_EFI
29cb7d2dd5SAtish Patra	/*
30cb7d2dd5SAtish Patra	 * This instruction decodes to "MZ" ASCII required by UEFI.
31cb7d2dd5SAtish Patra	 */
32cb7d2dd5SAtish Patra	c.li s4,-13
33cb7d2dd5SAtish Patra	j _start_kernel
34cb7d2dd5SAtish Patra#else
350f327f2aSAtish Patra	/* jump to start kernel */
360f327f2aSAtish Patra	j _start_kernel
370f327f2aSAtish Patra	/* reserved */
380f327f2aSAtish Patra	.word 0
39cb7d2dd5SAtish Patra#endif
400f327f2aSAtish Patra	.balign 8
4179605f13SSean Anderson#ifdef CONFIG_RISCV_M_MODE
4279605f13SSean Anderson	/* Image load offset (0MB) from start of RAM for M-mode */
4379605f13SSean Anderson	.dword 0
4479605f13SSean Anderson#else
450f327f2aSAtish Patra#if __riscv_xlen == 64
460f327f2aSAtish Patra	/* Image load offset(2MB) from start of RAM */
470f327f2aSAtish Patra	.dword 0x200000
480f327f2aSAtish Patra#else
490f327f2aSAtish Patra	/* Image load offset(4MB) from start of RAM */
500f327f2aSAtish Patra	.dword 0x400000
510f327f2aSAtish Patra#endif
5279605f13SSean Anderson#endif
530f327f2aSAtish Patra	/* Effective size of kernel image */
540f327f2aSAtish Patra	.dword _end - _start
550f327f2aSAtish Patra	.dword __HEAD_FLAGS
560f327f2aSAtish Patra	.word RISCV_HEADER_VERSION
570f327f2aSAtish Patra	.word 0
580f327f2aSAtish Patra	.dword 0
59474efecbSPaul Walmsley	.ascii RISCV_IMAGE_MAGIC
600f327f2aSAtish Patra	.balign 4
61474efecbSPaul Walmsley	.ascii RISCV_IMAGE_MAGIC2
62cb7d2dd5SAtish Patra#ifdef CONFIG_EFI
63cb7d2dd5SAtish Patra	.word pe_head_start - _start
64cb7d2dd5SAtish Patrape_head_start:
65cb7d2dd5SAtish Patra
66cb7d2dd5SAtish Patra	__EFI_PE_HEADER
67cb7d2dd5SAtish Patra#else
680f327f2aSAtish Patra	.word 0
69cb7d2dd5SAtish Patra#endif
700f327f2aSAtish Patra
71e011995eSAtish Patra.align 2
72e011995eSAtish Patra#ifdef CONFIG_MMU
73e1de2c93SAnup Patel	.global relocate_enable_mmu
74e1de2c93SAnup Patelrelocate_enable_mmu:
75e011995eSAtish Patra	/* Relocate return address */
76658e2c51SAlexandre Ghiti	la a1, kernel_map
7744c92257SVitaly Wool	XIP_FIXUP_OFFSET a1
78658e2c51SAlexandre Ghiti	REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
79e011995eSAtish Patra	la a2, _start
80e011995eSAtish Patra	sub a1, a1, a2
81e011995eSAtish Patra	add ra, ra, a1
82e011995eSAtish Patra
83e011995eSAtish Patra	/* Point stvec to virtual address of intruction after satp write */
84e011995eSAtish Patra	la a2, 1f
85e011995eSAtish Patra	add a2, a2, a1
86e011995eSAtish Patra	csrw CSR_TVEC, a2
87e011995eSAtish Patra
88e011995eSAtish Patra	/* Compute satp for kernel page tables, but don't load it yet */
89e011995eSAtish Patra	srl a2, a0, PAGE_SHIFT
90e8a62cc2SAlexandre Ghiti	la a1, satp_mode
91e792a03dSFrederik Haxel	XIP_FIXUP_OFFSET a1
92e8a62cc2SAlexandre Ghiti	REG_L a1, 0(a1)
93e011995eSAtish Patra	or a2, a2, a1
94e011995eSAtish Patra
95e011995eSAtish Patra	/*
96e011995eSAtish Patra	 * Load trampoline page directory, which will cause us to trap to
97e011995eSAtish Patra	 * stvec if VA != PA, or simply fall through if VA == PA.  We need a
98e011995eSAtish Patra	 * full fence here because setup_vm() just wrote these PTEs and we need
99e011995eSAtish Patra	 * to ensure the new translations are in use.
100e011995eSAtish Patra	 */
101e011995eSAtish Patra	la a0, trampoline_pg_dir
10244c92257SVitaly Wool	XIP_FIXUP_OFFSET a0
103e011995eSAtish Patra	srl a0, a0, PAGE_SHIFT
104e011995eSAtish Patra	or a0, a0, a1
105e011995eSAtish Patra	sfence.vma
106e011995eSAtish Patra	csrw CSR_SATP, a0
107e011995eSAtish Patra.align 2
108e011995eSAtish Patra1:
10976d4467aSQiu Wenbo	/* Set trap vector to spin forever to help debug */
11076d4467aSQiu Wenbo	la a0, .Lsecondary_park
111e011995eSAtish Patra	csrw CSR_TVEC, a0
112e011995eSAtish Patra
113e011995eSAtish Patra	/* Reload the global pointer */
114e011995eSAtish Patra.option push
115e011995eSAtish Patra.option norelax
116e011995eSAtish Patra	la gp, __global_pointer$
117e011995eSAtish Patra.option pop
118e011995eSAtish Patra
119e011995eSAtish Patra	/*
120e011995eSAtish Patra	 * Switch to kernel page tables.  A full fence is necessary in order to
121e011995eSAtish Patra	 * avoid using the trampoline translations, which are only correct for
1228ee30439Shasheddan	 * the first superpage.  Fetching the fence is guaranteed to work
123e011995eSAtish Patra	 * because that first superpage is translated the same way.
124e011995eSAtish Patra	 */
125e011995eSAtish Patra	csrw CSR_SATP, a2
126e011995eSAtish Patra	sfence.vma
127e011995eSAtish Patra
128e011995eSAtish Patra	ret
129e011995eSAtish Patra#endif /* CONFIG_MMU */
130e011995eSAtish Patra#ifdef CONFIG_SMP
131cfafe260SAtish Patra	.global secondary_start_sbi
132cfafe260SAtish Patrasecondary_start_sbi:
133cfafe260SAtish Patra	/* Mask all interrupts */
134cfafe260SAtish Patra	csrw CSR_IE, zero
135cfafe260SAtish Patra	csrw CSR_IP, zero
136cfafe260SAtish Patra
137cfafe260SAtish Patra	/* Load the global pointer */
138cfafe260SAtish Patra	.option push
139cfafe260SAtish Patra	.option norelax
140cfafe260SAtish Patra		la gp, __global_pointer$
141cfafe260SAtish Patra	.option pop
142cfafe260SAtish Patra
143cfafe260SAtish Patra	/*
14474abe5a3SGuo Ren	 * Disable FPU & VECTOR to detect illegal usage of
14574abe5a3SGuo Ren	 * floating point or vector in kernel space
146cfafe260SAtish Patra	 */
14774abe5a3SGuo Ren	li t0, SR_FS_VS
148cfafe260SAtish Patra	csrc CSR_STATUS, t0
149cfafe260SAtish Patra
150e011995eSAtish Patra	/* Set trap vector to spin forever to help debug */
151e011995eSAtish Patra	la a3, .Lsecondary_park
152e011995eSAtish Patra	csrw CSR_TVEC, a3
153e011995eSAtish Patra
1549a2451f1SAtish Patra	/* a0 contains the hartid & a1 contains boot data */
1559a2451f1SAtish Patra	li a2, SBI_HART_BOOT_TASK_PTR_OFFSET
1569a2451f1SAtish Patra	XIP_FIXUP_OFFSET a2
1579a2451f1SAtish Patra	add a2, a2, a1
1589a2451f1SAtish Patra	REG_L tp, (a2)
1599a2451f1SAtish Patra	li a3, SBI_HART_BOOT_STACK_PTR_OFFSET
1609a2451f1SAtish Patra	XIP_FIXUP_OFFSET a3
1619a2451f1SAtish Patra	add a3, a3, a1
1629a2451f1SAtish Patra	REG_L sp, (a3)
163cfafe260SAtish Patra
164153c46faSJisheng Zhang.Lsecondary_start_common:
165e011995eSAtish Patra
166e011995eSAtish Patra#ifdef CONFIG_MMU
167e011995eSAtish Patra	/* Enable virtual memory and relocate to virtual address */
168e011995eSAtish Patra	la a0, swapper_pg_dir
16944c92257SVitaly Wool	XIP_FIXUP_OFFSET a0
170e1de2c93SAnup Patel	call relocate_enable_mmu
171e011995eSAtish Patra#endif
17276d4467aSQiu Wenbo	call setup_trap_vector
173e011995eSAtish Patra	tail smp_callin
174e011995eSAtish Patra#endif /* CONFIG_SMP */
175e011995eSAtish Patra
17676d4467aSQiu Wenbo.align 2
17776d4467aSQiu Wenbosetup_trap_vector:
17876d4467aSQiu Wenbo	/* Set trap vector to exception handler */
17976d4467aSQiu Wenbo	la a0, handle_exception
18076d4467aSQiu Wenbo	csrw CSR_TVEC, a0
18176d4467aSQiu Wenbo
18276d4467aSQiu Wenbo	/*
18376d4467aSQiu Wenbo	 * Set sup0 scratch register to 0, indicating to exception vector that
18476d4467aSQiu Wenbo	 * we are presently executing in kernel.
18576d4467aSQiu Wenbo	 */
18676d4467aSQiu Wenbo	csrw CSR_SCRATCH, zero
18776d4467aSQiu Wenbo	ret
18876d4467aSQiu Wenbo
18964a19591SChen Lu.align 2
190e011995eSAtish Patra.Lsecondary_park:
191e011995eSAtish Patra	/* We lack SMP support or have too many harts, so park this hart */
192e011995eSAtish Patra	wfi
193e011995eSAtish Patra	j .Lsecondary_park
194e011995eSAtish Patra
195e011995eSAtish PatraEND(_start)
196e011995eSAtish Patra
197e011995eSAtish PatraENTRY(_start_kernel)
198a3182c91SAnup Patel	/* Mask all interrupts */
199a4c3733dSChristoph Hellwig	csrw CSR_IE, zero
200a4c3733dSChristoph Hellwig	csrw CSR_IP, zero
20176d2a049SPalmer Dabbelt
202accb9dbcSDamien Le Moal#ifdef CONFIG_RISCV_M_MODE
2039e806356SChristoph Hellwig	/* flush the instruction cache */
2049e806356SChristoph Hellwig	fence.i
2059e806356SChristoph Hellwig
2069e806356SChristoph Hellwig	/* Reset all registers except ra, a0, a1 */
2079e806356SChristoph Hellwig	call reset_regs
2089e806356SChristoph Hellwig
209eb077c9cSPalmer Dabbelt	/*
210eb077c9cSPalmer Dabbelt	 * Setup a PMP to permit access to all of memory.  Some machines may
211eb077c9cSPalmer Dabbelt	 * not implement PMPs, so we set up a quick trap handler to just skip
212eb077c9cSPalmer Dabbelt	 * touching the PMPs on any trap.
213eb077c9cSPalmer Dabbelt	 */
214eb077c9cSPalmer Dabbelt	la a0, pmp_done
215eb077c9cSPalmer Dabbelt	csrw CSR_TVEC, a0
216eb077c9cSPalmer Dabbelt
217c68a9032SGreentime Hu	li a0, -1
218c68a9032SGreentime Hu	csrw CSR_PMPADDR0, a0
219c68a9032SGreentime Hu	li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X)
220c68a9032SGreentime Hu	csrw CSR_PMPCFG0, a0
221eb077c9cSPalmer Dabbelt.align 2
222eb077c9cSPalmer Dabbeltpmp_done:
223c68a9032SGreentime Hu
224accb9dbcSDamien Le Moal	/*
225accb9dbcSDamien Le Moal	 * The hartid in a0 is expected later on, and we have no firmware
226accb9dbcSDamien Le Moal	 * to hand it to us.
227accb9dbcSDamien Le Moal	 */
228accb9dbcSDamien Le Moal	csrr a0, CSR_MHARTID
2299e806356SChristoph Hellwig#endif /* CONFIG_RISCV_M_MODE */
230accb9dbcSDamien Le Moal
23176d2a049SPalmer Dabbelt	/* Load the global pointer */
23276d2a049SPalmer Dabbelt.option push
23376d2a049SPalmer Dabbelt.option norelax
23476d2a049SPalmer Dabbelt	la gp, __global_pointer$
23576d2a049SPalmer Dabbelt.option pop
23676d2a049SPalmer Dabbelt
23776d2a049SPalmer Dabbelt	/*
23874abe5a3SGuo Ren	 * Disable FPU & VECTOR to detect illegal usage of
23974abe5a3SGuo Ren	 * floating point or vector in kernel space
24076d2a049SPalmer Dabbelt	 */
24174abe5a3SGuo Ren	li t0, SR_FS_VS
242a4c3733dSChristoph Hellwig	csrc CSR_STATUS, t0
24376d2a049SPalmer Dabbelt
2442ffc48fcSAtish Patra#ifdef CONFIG_RISCV_BOOT_SPINWAIT
245b47613daSXiang Wang	li t0, CONFIG_NR_CPUS
24620d22927SGreentime Hu	blt a0, t0, .Lgood_cores
24720d22927SGreentime Hu	tail .Lsecondary_park
24820d22927SGreentime Hu.Lgood_cores:
249b47613daSXiang Wang
2500b39eb38SAtish Patra	/* The lottery system is only required for spinwait booting method */
25144c92257SVitaly Wool#ifndef CONFIG_XIP_KERNEL
25276d2a049SPalmer Dabbelt	/* Pick one hart to run the main boot sequence */
25376d2a049SPalmer Dabbelt	la a3, hart_lottery
25476d2a049SPalmer Dabbelt	li a2, 1
25576d2a049SPalmer Dabbelt	amoadd.w a3, a2, (a3)
25676d2a049SPalmer Dabbelt	bnez a3, .Lsecondary_start
25776d2a049SPalmer Dabbelt
25844c92257SVitaly Wool#else
25944c92257SVitaly Wool	/* hart_lottery in flash contains a magic number */
26044c92257SVitaly Wool	la a3, hart_lottery
26144c92257SVitaly Wool	mv a2, a3
26244c92257SVitaly Wool	XIP_FIXUP_OFFSET a2
263f9ace4edSVitaly Wool	XIP_FIXUP_FLASH_OFFSET a3
26444c92257SVitaly Wool	lw t1, (a3)
26544c92257SVitaly Wool	amoswap.w t0, t1, (a2)
26644c92257SVitaly Wool	/* first time here if hart_lottery in RAM is not set */
26744c92257SVitaly Wool	beq t0, t1, .Lsecondary_start
26844c92257SVitaly Wool
2690b39eb38SAtish Patra#endif /* CONFIG_XIP */
2702ffc48fcSAtish Patra#endif /* CONFIG_RISCV_BOOT_SPINWAIT */
2710b39eb38SAtish Patra
2720b39eb38SAtish Patra#ifdef CONFIG_XIP_KERNEL
27344c92257SVitaly Wool	la sp, _end + THREAD_SIZE
27444c92257SVitaly Wool	XIP_FIXUP_OFFSET sp
27544c92257SVitaly Wool	mv s0, a0
27644c92257SVitaly Wool	call __copy_data
27744c92257SVitaly Wool
27844c92257SVitaly Wool	/* Restore a0 copy */
27944c92257SVitaly Wool	mv a0, s0
28044c92257SVitaly Wool#endif
28144c92257SVitaly Wool
28244c92257SVitaly Wool#ifndef CONFIG_XIP_KERNEL
283c0fbcd99SAnup Patel	/* Clear BSS for flat non-ELF images */
284c0fbcd99SAnup Patel	la a3, __bss_start
285c0fbcd99SAnup Patel	la a4, __bss_stop
286c0fbcd99SAnup Patel	ble a4, a3, clear_bss_done
287c0fbcd99SAnup Patelclear_bss:
288c0fbcd99SAnup Patel	REG_S zero, (a3)
289c0fbcd99SAnup Patel	add a3, a3, RISCV_SZPTR
290c0fbcd99SAnup Patel	blt a3, a4, clear_bss
291c0fbcd99SAnup Patelclear_bss_done:
29244c92257SVitaly Wool#endif
293f99fb607SAtish Patra	la a2, boot_cpu_hartid
29444c92257SVitaly Wool	XIP_FIXUP_OFFSET a2
295f99fb607SAtish Patra	REG_S a0, (a2)
29676d2a049SPalmer Dabbelt
29776d2a049SPalmer Dabbelt	/* Initialize page tables and relocate to virtual addresses */
29835d33c76SAlexandre Ghiti	la tp, init_task
29976d2a049SPalmer Dabbelt	la sp, init_thread_union + THREAD_SIZE
30044c92257SVitaly Wool	XIP_FIXUP_OFFSET sp
301c7cdd96eSGreentime Hu	addi sp, sp, -PT_SIZE_ON_STACK
302f105aa94SVitaly Wool#ifdef CONFIG_BUILTIN_DTB
303f105aa94SVitaly Wool	la a0, __dtb_start
304f9ace4edSVitaly Wool	XIP_FIXUP_OFFSET a0
305f105aa94SVitaly Wool#else
3066b289a3fSNam Cao	mv a0, a1
307f105aa94SVitaly Wool#endif /* CONFIG_BUILTIN_DTB */
308*ce2e6380Syang.zhang	/* Set trap vector to spin forever to help debug */
309*ce2e6380Syang.zhang	la a3, .Lsecondary_park
310*ce2e6380Syang.zhang	csrw CSR_TVEC, a3
31176d2a049SPalmer Dabbelt	call setup_vm
3126bd33e1eSChristoph Hellwig#ifdef CONFIG_MMU
313671f9a3eSAnup Patel	la a0, early_pg_dir
31444c92257SVitaly Wool	XIP_FIXUP_OFFSET a0
315e1de2c93SAnup Patel	call relocate_enable_mmu
3166bd33e1eSChristoph Hellwig#endif /* CONFIG_MMU */
31776d2a049SPalmer Dabbelt
31876d4467aSQiu Wenbo	call setup_trap_vector
31976d2a049SPalmer Dabbelt	/* Restore C environment */
32076d2a049SPalmer Dabbelt	la tp, init_task
321c637b911SChristoph Hellwig	la sp, init_thread_union + THREAD_SIZE
322c7cdd96eSGreentime Hu	addi sp, sp, -PT_SIZE_ON_STACK
32376d2a049SPalmer Dabbelt
3248ad8b727SNick Hu#ifdef CONFIG_KASAN
3258ad8b727SNick Hu	call kasan_early_init
3268ad8b727SNick Hu#endif
32776d2a049SPalmer Dabbelt	/* Start the kernel */
328335b1390SDamien Le Moal	call soc_early_init
32976d2a049SPalmer Dabbelt	tail start_kernel
33076d2a049SPalmer Dabbelt
3315b89c6f9SMasahiro Yamada#ifdef CONFIG_RISCV_BOOT_SPINWAIT
3320b39eb38SAtish Patra.Lsecondary_start:
33376d2a049SPalmer Dabbelt	/* Set trap vector to spin forever to help debug */
33476d2a049SPalmer Dabbelt	la a3, .Lsecondary_park
335a4c3733dSChristoph Hellwig	csrw CSR_TVEC, a3
33676d2a049SPalmer Dabbelt
33776d2a049SPalmer Dabbelt	slli a3, a0, LGREG
338c78f94f3SAtish Patra	la a1, __cpu_spinwait_stack_pointer
33944c92257SVitaly Wool	XIP_FIXUP_OFFSET a1
340c78f94f3SAtish Patra	la a2, __cpu_spinwait_task_pointer
34144c92257SVitaly Wool	XIP_FIXUP_OFFSET a2
34276d2a049SPalmer Dabbelt	add a1, a3, a1
34376d2a049SPalmer Dabbelt	add a2, a3, a2
34476d2a049SPalmer Dabbelt
34576d2a049SPalmer Dabbelt	/*
34676d2a049SPalmer Dabbelt	 * This hart didn't win the lottery, so we wait for the winning hart to
34776d2a049SPalmer Dabbelt	 * get far enough along the boot process that it should continue.
34876d2a049SPalmer Dabbelt	 */
34976d2a049SPalmer Dabbelt.Lwait_for_cpu_up:
35076d2a049SPalmer Dabbelt	/* FIXME: We should WFI to save some energy here. */
35176d2a049SPalmer Dabbelt	REG_L sp, (a1)
35276d2a049SPalmer Dabbelt	REG_L tp, (a2)
35376d2a049SPalmer Dabbelt	beqz sp, .Lwait_for_cpu_up
35476d2a049SPalmer Dabbelt	beqz tp, .Lwait_for_cpu_up
35576d2a049SPalmer Dabbelt	fence
35676d2a049SPalmer Dabbelt
357153c46faSJisheng Zhang	tail .Lsecondary_start_common
3582ffc48fcSAtish Patra#endif /* CONFIG_RISCV_BOOT_SPINWAIT */
35976d2a049SPalmer Dabbelt
360e011995eSAtish PatraEND(_start_kernel)
36176d2a049SPalmer Dabbelt
3629e806356SChristoph Hellwig#ifdef CONFIG_RISCV_M_MODE
3639e806356SChristoph HellwigENTRY(reset_regs)
3649e806356SChristoph Hellwig	li	sp, 0
3659e806356SChristoph Hellwig	li	gp, 0
3669e806356SChristoph Hellwig	li	tp, 0
3679e806356SChristoph Hellwig	li	t0, 0
3689e806356SChristoph Hellwig	li	t1, 0
3699e806356SChristoph Hellwig	li	t2, 0
3709e806356SChristoph Hellwig	li	s0, 0
3719e806356SChristoph Hellwig	li	s1, 0
3729e806356SChristoph Hellwig	li	a2, 0
3739e806356SChristoph Hellwig	li	a3, 0
3749e806356SChristoph Hellwig	li	a4, 0
3759e806356SChristoph Hellwig	li	a5, 0
3769e806356SChristoph Hellwig	li	a6, 0
3779e806356SChristoph Hellwig	li	a7, 0
3789e806356SChristoph Hellwig	li	s2, 0
3799e806356SChristoph Hellwig	li	s3, 0
3809e806356SChristoph Hellwig	li	s4, 0
3819e806356SChristoph Hellwig	li	s5, 0
3829e806356SChristoph Hellwig	li	s6, 0
3839e806356SChristoph Hellwig	li	s7, 0
3849e806356SChristoph Hellwig	li	s8, 0
3859e806356SChristoph Hellwig	li	s9, 0
3869e806356SChristoph Hellwig	li	s10, 0
3879e806356SChristoph Hellwig	li	s11, 0
3889e806356SChristoph Hellwig	li	t3, 0
3899e806356SChristoph Hellwig	li	t4, 0
3909e806356SChristoph Hellwig	li	t5, 0
3919e806356SChristoph Hellwig	li	t6, 0
392d411cf02SGreentime Hu	csrw	CSR_SCRATCH, 0
3939e806356SChristoph Hellwig
3949e806356SChristoph Hellwig#ifdef CONFIG_FPU
3959e806356SChristoph Hellwig	csrr	t0, CSR_MISA
3969e806356SChristoph Hellwig	andi	t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
3976b533828SGreentime Hu	beqz	t0, .Lreset_regs_done_fpu
3989e806356SChristoph Hellwig
3999e806356SChristoph Hellwig	li	t1, SR_FS
4009e806356SChristoph Hellwig	csrs	CSR_STATUS, t1
4019e806356SChristoph Hellwig	fmv.s.x	f0, zero
4029e806356SChristoph Hellwig	fmv.s.x	f1, zero
4039e806356SChristoph Hellwig	fmv.s.x	f2, zero
4049e806356SChristoph Hellwig	fmv.s.x	f3, zero
4059e806356SChristoph Hellwig	fmv.s.x	f4, zero
4069e806356SChristoph Hellwig	fmv.s.x	f5, zero
4079e806356SChristoph Hellwig	fmv.s.x	f6, zero
4089e806356SChristoph Hellwig	fmv.s.x	f7, zero
4099e806356SChristoph Hellwig	fmv.s.x	f8, zero
4109e806356SChristoph Hellwig	fmv.s.x	f9, zero
4119e806356SChristoph Hellwig	fmv.s.x	f10, zero
4129e806356SChristoph Hellwig	fmv.s.x	f11, zero
4139e806356SChristoph Hellwig	fmv.s.x	f12, zero
4149e806356SChristoph Hellwig	fmv.s.x	f13, zero
4159e806356SChristoph Hellwig	fmv.s.x	f14, zero
4169e806356SChristoph Hellwig	fmv.s.x	f15, zero
4179e806356SChristoph Hellwig	fmv.s.x	f16, zero
4189e806356SChristoph Hellwig	fmv.s.x	f17, zero
4199e806356SChristoph Hellwig	fmv.s.x	f18, zero
4209e806356SChristoph Hellwig	fmv.s.x	f19, zero
4219e806356SChristoph Hellwig	fmv.s.x	f20, zero
4229e806356SChristoph Hellwig	fmv.s.x	f21, zero
4239e806356SChristoph Hellwig	fmv.s.x	f22, zero
4249e806356SChristoph Hellwig	fmv.s.x	f23, zero
4259e806356SChristoph Hellwig	fmv.s.x	f24, zero
4269e806356SChristoph Hellwig	fmv.s.x	f25, zero
4279e806356SChristoph Hellwig	fmv.s.x	f26, zero
4289e806356SChristoph Hellwig	fmv.s.x	f27, zero
4299e806356SChristoph Hellwig	fmv.s.x	f28, zero
4309e806356SChristoph Hellwig	fmv.s.x	f29, zero
4319e806356SChristoph Hellwig	fmv.s.x	f30, zero
4329e806356SChristoph Hellwig	fmv.s.x	f31, zero
4339e806356SChristoph Hellwig	csrw	fcsr, 0
4349e806356SChristoph Hellwig	/* note that the caller must clear SR_FS */
4356b533828SGreentime Hu.Lreset_regs_done_fpu:
4369e806356SChristoph Hellwig#endif /* CONFIG_FPU */
4376b533828SGreentime Hu
4386b533828SGreentime Hu#ifdef CONFIG_RISCV_ISA_V
4396b533828SGreentime Hu	csrr	t0, CSR_MISA
4406b533828SGreentime Hu	li	t1, COMPAT_HWCAP_ISA_V
4416b533828SGreentime Hu	and	t0, t0, t1
4426b533828SGreentime Hu	beqz	t0, .Lreset_regs_done_vector
4436b533828SGreentime Hu
4446b533828SGreentime Hu	/*
4456b533828SGreentime Hu	 * Clear vector registers and reset vcsr
4466b533828SGreentime Hu	 * VLMAX has a defined value, VLEN is a constant,
4476b533828SGreentime Hu	 * and this form of vsetvli is defined to set vl to VLMAX.
4486b533828SGreentime Hu	 */
4496b533828SGreentime Hu	li	t1, SR_VS
4506b533828SGreentime Hu	csrs	CSR_STATUS, t1
4516b533828SGreentime Hu	csrs	CSR_VCSR, x0
4526b533828SGreentime Hu	vsetvli t1, x0, e8, m8, ta, ma
4536b533828SGreentime Hu	vmv.v.i v0, 0
4546b533828SGreentime Hu	vmv.v.i v8, 0
4556b533828SGreentime Hu	vmv.v.i v16, 0
4566b533828SGreentime Hu	vmv.v.i v24, 0
4576b533828SGreentime Hu	/* note that the caller must clear SR_VS */
4586b533828SGreentime Hu.Lreset_regs_done_vector:
4596b533828SGreentime Hu#endif /* CONFIG_RISCV_ISA_V */
4609e806356SChristoph Hellwig	ret
4619e806356SChristoph HellwigEND(reset_regs)
4629e806356SChristoph Hellwig#endif /* CONFIG_RISCV_M_MODE */
463