LoongArch: Align the address of kernel_entry to 4KB
[platform/kernel/linux-starfive.git] / arch / loongarch / kernel / head.S
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
17         .align 12
18
19 SYM_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
27         /* We might not get launched at the address the kernel is linked to,
28            so we jump there.  */
29         la.abs          t0, 0f
30         jr              t0
31 0:
32         /* Enable PG */
33         li.w            t0, 0xb0                # PLV=0, IE=0, PG=1
34         csrwr           t0, LOONGARCH_CSR_CRMD
35         li.w            t0, 0x04                # PLV=0, PIE=1, PWE=0
36         csrwr           t0, LOONGARCH_CSR_PRMD
37         li.w            t0, 0x00                # FPE=0, SXE=0, ASXE=0, BTE=0
38         csrwr           t0, LOONGARCH_CSR_EUEN
39
40         la              t0, __bss_start         # clear .bss
41         st.d            zero, t0, 0
42         la              t1, __bss_stop - LONGSIZE
43 1:
44         addi.d          t0, t0, LONGSIZE
45         st.d            zero, t0, 0
46         bne             t0, t1, 1b
47
48         la              t0, fw_arg0
49         st.d            a0, t0, 0               # firmware arguments
50         la              t0, fw_arg1
51         st.d            a1, t0, 0
52
53         /* KSave3 used for percpu base, initialized as 0 */
54         csrwr           zero, PERCPU_BASE_KS
55         /* GPR21 used for percpu base (runtime), initialized as 0 */
56         move            u0, zero
57
58         la              tp, init_thread_union
59         /* Set the SP after an empty pt_regs.  */
60         PTR_LI          sp, (_THREAD_SIZE - 32 - PT_SIZE)
61         PTR_ADD         sp, sp, tp
62         set_saved_sp    sp, t0, t1
63         PTR_ADDI        sp, sp, -4 * SZREG      # init stack pointer
64
65         bl              start_kernel
66
67 SYM_CODE_END(kernel_entry)
68
69 #ifdef CONFIG_SMP
70
71 /*
72  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
73  * function after setting up the stack and tp registers.
74  */
75 SYM_CODE_START(smpboot_entry)
76         li.d            t0, CSR_DMW0_INIT       # UC, PLV0
77         csrwr           t0, LOONGARCH_CSR_DMWIN0
78         li.d            t0, CSR_DMW1_INIT       # CA, PLV0
79         csrwr           t0, LOONGARCH_CSR_DMWIN1
80
81         la.abs          t0, 0f
82         jr              t0
83 0:
84         /* Enable PG */
85         li.w            t0, 0xb0                # PLV=0, IE=0, PG=1
86         csrwr           t0, LOONGARCH_CSR_CRMD
87         li.w            t0, 0x04                # PLV=0, PIE=1, PWE=0
88         csrwr           t0, LOONGARCH_CSR_PRMD
89         li.w            t0, 0x00                # FPE=0, SXE=0, ASXE=0, BTE=0
90         csrwr           t0, LOONGARCH_CSR_EUEN
91
92         la.abs          t0, cpuboot_data
93         ld.d            sp, t0, CPU_BOOT_STACK
94         ld.d            tp, t0, CPU_BOOT_TINFO
95
96         bl              start_secondary
97 SYM_CODE_END(smpboot_entry)
98
99 #endif /* CONFIG_SMP */
100
101 SYM_ENTRY(kernel_entry_end, SYM_L_GLOBAL, SYM_A_NONE)