xref: /openbmc/linux/arch/loongarch/kernel/head.S (revision 6f0c460f)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4 */
5#include <linux/init.h>
6#include <linux/threads.h>
7
8#include <asm/addrspace.h>
9#include <asm/asm.h>
10#include <asm/asmmacro.h>
11#include <asm/regdef.h>
12#include <asm/loongarch.h>
13#include <asm/stackframe.h>
14
15	__REF
16
17SYM_ENTRY(_stext, SYM_L_GLOBAL, SYM_A_NONE)
18
19SYM_CODE_START(kernel_entry)			# kernel entry point
20
21	/* Config direct window and set PG */
22	li.d		t0, CSR_DMW0_INIT	# UC, PLV0, 0x8000 xxxx xxxx xxxx
23	csrwr		t0, LOONGARCH_CSR_DMWIN0
24	li.d		t0, CSR_DMW1_INIT	# CA, PLV0, 0x9000 xxxx xxxx xxxx
25	csrwr		t0, LOONGARCH_CSR_DMWIN1
26	/* Enable PG */
27	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
28	csrwr		t0, LOONGARCH_CSR_CRMD
29	li.w		t0, 0x04		# PLV=0, PIE=1, PWE=0
30	csrwr		t0, LOONGARCH_CSR_PRMD
31	li.w		t0, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
32	csrwr		t0, LOONGARCH_CSR_EUEN
33
34	/* We might not get launched at the address the kernel is linked to,
35	   so we jump there.  */
36	la.abs		t0, 0f
37	jirl		zero, t0, 0
380:
39	la		t0, __bss_start		# clear .bss
40	st.d		zero, t0, 0
41	la		t1, __bss_stop - LONGSIZE
421:
43	addi.d		t0, t0, LONGSIZE
44	st.d		zero, t0, 0
45	bne		t0, t1, 1b
46
47	la		t0, fw_arg0
48	st.d		a0, t0, 0		# firmware arguments
49	la		t0, fw_arg1
50	st.d		a1, t0, 0
51
52	/* KSave3 used for percpu base, initialized as 0 */
53	csrwr		zero, PERCPU_BASE_KS
54	/* GPR21 used for percpu base (runtime), initialized as 0 */
55	or		u0, zero, zero
56
57	la		tp, init_thread_union
58	/* Set the SP after an empty pt_regs.  */
59	PTR_LI		sp, (_THREAD_SIZE - 32 - PT_SIZE)
60	PTR_ADD		sp, sp, tp
61	set_saved_sp	sp, t0, t1
62	PTR_ADDI	sp, sp, -4 * SZREG	# init stack pointer
63
64	bl		start_kernel
65
66SYM_CODE_END(kernel_entry)
67
68#ifdef CONFIG_SMP
69
70/*
71 * SMP slave cpus entry point.	Board specific code for bootstrap calls this
72 * function after setting up the stack and tp registers.
73 */
74SYM_CODE_START(smpboot_entry)
75	li.d		t0, CSR_DMW0_INIT	# UC, PLV0
76	csrwr		t0, LOONGARCH_CSR_DMWIN0
77	li.d		t0, CSR_DMW1_INIT	# CA, PLV0
78	csrwr		t0, LOONGARCH_CSR_DMWIN1
79	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
80	csrwr		t0, LOONGARCH_CSR_CRMD
81	li.w		t0, 0x04		# PLV=0, PIE=1, PWE=0
82	csrwr		t0, LOONGARCH_CSR_PRMD
83	li.w		t0, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
84	csrwr		t0, LOONGARCH_CSR_EUEN
85
86	la.abs		t0, cpuboot_data
87	ld.d		sp, t0, CPU_BOOT_STACK
88	ld.d		tp, t0, CPU_BOOT_TINFO
89
90	la.abs	t0, 0f
91	jirl	zero, t0, 0
920:
93	bl		start_secondary
94SYM_CODE_END(smpboot_entry)
95
96#endif /* CONFIG_SMP */
97
98SYM_ENTRY(kernel_entry_end, SYM_L_GLOBAL, SYM_A_NONE)
99