xref: /openbmc/linux/arch/loongarch/kernel/head.S (revision 57904291176fa16a981cefca5cbe1a0b50196792)
1628c3bb4SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */
2628c3bb4SHuacai Chen/*
3628c3bb4SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4628c3bb4SHuacai Chen */
5628c3bb4SHuacai Chen#include <linux/init.h>
6628c3bb4SHuacai Chen#include <linux/threads.h>
7628c3bb4SHuacai Chen
8628c3bb4SHuacai Chen#include <asm/addrspace.h>
9628c3bb4SHuacai Chen#include <asm/asm.h>
10628c3bb4SHuacai Chen#include <asm/asmmacro.h>
112d2c3952SYouling Tang#include <asm/bug.h>
12628c3bb4SHuacai Chen#include <asm/regdef.h>
13628c3bb4SHuacai Chen#include <asm/loongarch.h>
14628c3bb4SHuacai Chen#include <asm/stackframe.h>
15628c3bb4SHuacai Chen
16ead384d9SHuacai Chen#ifdef CONFIG_EFI_STUB
17ead384d9SHuacai Chen
18ead384d9SHuacai Chen#include "efi-header.S"
19ead384d9SHuacai Chen
20ead384d9SHuacai Chen	__HEAD
21ead384d9SHuacai Chen
22ead384d9SHuacai Chen_head:
23ead384d9SHuacai Chen	.word	MZ_MAGIC		/* "MZ", MS-DOS header */
244a03b2acSYouling Tang	.org	0x8
25*988a03e3SJiaxun Yang	.dword	_kernel_entry		/* Kernel entry point (physical address) */
26414cefc7SWANG Rui	.dword	_kernel_asize		/* Kernel image effective size */
273f89765dSYouling Tang	.quad	PHYS_LINK_KADDR		/* Kernel image load offset from start of RAM */
2829636a5cSArd Biesheuvel	.org	0x38			/* 0x20 ~ 0x37 reserved */
2929636a5cSArd Biesheuvel	.long	LINUX_PE_MAGIC
30ead384d9SHuacai Chen	.long	pe_header - _head	/* Offset to the PE header */
31ead384d9SHuacai Chen
32ead384d9SHuacai Chenpe_header:
33ead384d9SHuacai Chen	__EFI_PE_HEADER
34ead384d9SHuacai Chen
35414cefc7SWANG RuiSYM_DATA(kernel_asize, .long _kernel_asize);
36414cefc7SWANG RuiSYM_DATA(kernel_fsize, .long _kernel_fsize);
37ead384d9SHuacai Chen
38ead384d9SHuacai Chen#endif
39ead384d9SHuacai Chen
40628c3bb4SHuacai Chen	__REF
41628c3bb4SHuacai Chen
422938431eSHuacai Chen	.align 12
432938431eSHuacai Chen
44628c3bb4SHuacai ChenSYM_CODE_START(kernel_entry)			# kernel entry point
45628c3bb4SHuacai Chen
46628c3bb4SHuacai Chen	/* Config direct window and set PG */
47628c3bb4SHuacai Chen	li.d		t0, CSR_DMW0_INIT	# UC, PLV0, 0x8000 xxxx xxxx xxxx
48628c3bb4SHuacai Chen	csrwr		t0, LOONGARCH_CSR_DMWIN0
49628c3bb4SHuacai Chen	li.d		t0, CSR_DMW1_INIT	# CA, PLV0, 0x9000 xxxx xxxx xxxx
50628c3bb4SHuacai Chen	csrwr		t0, LOONGARCH_CSR_DMWIN1
51ab2579d7SHuacai Chen
528cbd5ebfSYouling Tang	JUMP_VIRT_ADDR	t0, t1
538cbd5ebfSYouling Tang
54628c3bb4SHuacai Chen	/* Enable PG */
55628c3bb4SHuacai Chen	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
56628c3bb4SHuacai Chen	csrwr		t0, LOONGARCH_CSR_CRMD
57628c3bb4SHuacai Chen	li.w		t0, 0x04		# PLV=0, PIE=1, PWE=0
58628c3bb4SHuacai Chen	csrwr		t0, LOONGARCH_CSR_PRMD
59628c3bb4SHuacai Chen	li.w		t0, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
60628c3bb4SHuacai Chen	csrwr		t0, LOONGARCH_CSR_EUEN
61628c3bb4SHuacai Chen
6211cd8a64SXi Ruoyao	la.pcrel	t0, __bss_start		# clear .bss
63628c3bb4SHuacai Chen	st.d		zero, t0, 0
6411cd8a64SXi Ruoyao	la.pcrel	t1, __bss_stop - LONGSIZE
65628c3bb4SHuacai Chen1:
66628c3bb4SHuacai Chen	addi.d		t0, t0, LONGSIZE
67628c3bb4SHuacai Chen	st.d		zero, t0, 0
68628c3bb4SHuacai Chen	bne		t0, t1, 1b
69628c3bb4SHuacai Chen
7011cd8a64SXi Ruoyao	la.pcrel	t0, fw_arg0
71628c3bb4SHuacai Chen	st.d		a0, t0, 0		# firmware arguments
7211cd8a64SXi Ruoyao	la.pcrel	t0, fw_arg1
73628c3bb4SHuacai Chen	st.d		a1, t0, 0
7411cd8a64SXi Ruoyao	la.pcrel	t0, fw_arg2
7540cd01a9SArd Biesheuvel	st.d		a2, t0, 0
76628c3bb4SHuacai Chen
77628c3bb4SHuacai Chen	/* KSave3 used for percpu base, initialized as 0 */
78628c3bb4SHuacai Chen	csrwr		zero, PERCPU_BASE_KS
79628c3bb4SHuacai Chen	/* GPR21 used for percpu base (runtime), initialized as 0 */
8057ce5d3eSWANG Xuerui	move		u0, zero
81628c3bb4SHuacai Chen
8211cd8a64SXi Ruoyao	la.pcrel	tp, init_thread_union
83628c3bb4SHuacai Chen	/* Set the SP after an empty pt_regs.  */
84b40fa75eSJinyang He	PTR_LI		sp, (_THREAD_SIZE - PT_SIZE)
85628c3bb4SHuacai Chen	PTR_ADD		sp, sp, tp
86628c3bb4SHuacai Chen	set_saved_sp	sp, t0, t1
87628c3bb4SHuacai Chen
88d8da19fbSYouling Tang#ifdef CONFIG_RELOCATABLE
89e5f02b51SYouling Tang
90d8da19fbSYouling Tang	bl		relocate_kernel
91e5f02b51SYouling Tang
92e5f02b51SYouling Tang#ifdef CONFIG_RANDOMIZE_BASE
93e5f02b51SYouling Tang	/* Repoint the sp into the new kernel */
94e5f02b51SYouling Tang	PTR_LI		sp, (_THREAD_SIZE - PT_SIZE)
95e5f02b51SYouling Tang	PTR_ADD		sp, sp, tp
96e5f02b51SYouling Tang	set_saved_sp	sp, t0, t1
97e5f02b51SYouling Tang
989fbcc076SQing Zhang	/* Jump to the new kernel: new_pc = current_pc + random_offset */
999fbcc076SQing Zhang	pcaddi		t0, 0
1009fbcc076SQing Zhang	add.d		t0, t0, a0
1019fbcc076SQing Zhang	jirl		zero, t0, 0xc
1029fbcc076SQing Zhang#endif /* CONFIG_RANDOMIZE_BASE */
103e5f02b51SYouling Tang
1049fbcc076SQing Zhang#endif /* CONFIG_RELOCATABLE */
105d8da19fbSYouling Tang
1065aa4ac64SQing Zhang#ifdef CONFIG_KASAN
1075aa4ac64SQing Zhang	bl		kasan_early_init
1085aa4ac64SQing Zhang#endif
1095aa4ac64SQing Zhang
110628c3bb4SHuacai Chen	bl		start_kernel
1112d2c3952SYouling Tang	ASM_BUG()
112628c3bb4SHuacai Chen
113628c3bb4SHuacai ChenSYM_CODE_END(kernel_entry)
114628c3bb4SHuacai Chen
11546859ac8SHuacai Chen#ifdef CONFIG_SMP
11646859ac8SHuacai Chen
11746859ac8SHuacai Chen/*
11846859ac8SHuacai Chen * SMP slave cpus entry point.	Board specific code for bootstrap calls this
11946859ac8SHuacai Chen * function after setting up the stack and tp registers.
12046859ac8SHuacai Chen */
12146859ac8SHuacai ChenSYM_CODE_START(smpboot_entry)
12246859ac8SHuacai Chen	li.d		t0, CSR_DMW0_INIT	# UC, PLV0
12346859ac8SHuacai Chen	csrwr		t0, LOONGARCH_CSR_DMWIN0
12446859ac8SHuacai Chen	li.d		t0, CSR_DMW1_INIT	# CA, PLV0
12546859ac8SHuacai Chen	csrwr		t0, LOONGARCH_CSR_DMWIN1
126ab2579d7SHuacai Chen
1278cbd5ebfSYouling Tang	JUMP_VIRT_ADDR	t0, t1
1288cbd5ebfSYouling Tang
129ab2579d7SHuacai Chen	/* Enable PG */
13046859ac8SHuacai Chen	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
13146859ac8SHuacai Chen	csrwr		t0, LOONGARCH_CSR_CRMD
13246859ac8SHuacai Chen	li.w		t0, 0x04		# PLV=0, PIE=1, PWE=0
13346859ac8SHuacai Chen	csrwr		t0, LOONGARCH_CSR_PRMD
13446859ac8SHuacai Chen	li.w		t0, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
13546859ac8SHuacai Chen	csrwr		t0, LOONGARCH_CSR_EUEN
13646859ac8SHuacai Chen
137f733f119SXi Ruoyao	la.pcrel	t0, cpuboot_data
13846859ac8SHuacai Chen	ld.d		sp, t0, CPU_BOOT_STACK
13946859ac8SHuacai Chen	ld.d		tp, t0, CPU_BOOT_TINFO
14046859ac8SHuacai Chen
14146859ac8SHuacai Chen	bl		start_secondary
1422d2c3952SYouling Tang	ASM_BUG()
1432d2c3952SYouling Tang
14446859ac8SHuacai ChenSYM_CODE_END(smpboot_entry)
14546859ac8SHuacai Chen
14646859ac8SHuacai Chen#endif /* CONFIG_SMP */
14746859ac8SHuacai Chen
148628c3bb4SHuacai ChenSYM_ENTRY(kernel_entry_end, SYM_L_GLOBAL, SYM_A_NONE)
149