diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/entry.S | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/entry.S')
-rw-r--r-- | arch/mips/kernel/entry.S | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S new file mode 100644 index 000000000..4b896f502 --- /dev/null +++ b/arch/mips/kernel/entry.S | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle | ||
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | ||
8 | * Copyright (C) 2001 MIPS Technologies, Inc. | ||
9 | */ | ||
10 | |||
11 | #include <asm/asm.h> | ||
12 | #include <asm/asmmacro.h> | ||
13 | #include <asm/compiler.h> | ||
14 | #include <asm/irqflags.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/stackframe.h> | ||
18 | #include <asm/isadep.h> | ||
19 | #include <asm/thread_info.h> | ||
20 | #include <asm/war.h> | ||
21 | |||
22 | #ifndef CONFIG_PREEMPTION | ||
23 | #define resume_kernel restore_all | ||
24 | #else | ||
25 | #define __ret_from_irq ret_from_exception | ||
26 | #endif | ||
27 | |||
28 | .text | ||
29 | .align 5 | ||
30 | #ifndef CONFIG_PREEMPTION | ||
31 | FEXPORT(ret_from_exception) | ||
32 | local_irq_disable # preempt stop | ||
33 | b __ret_from_irq | ||
34 | #endif | ||
35 | FEXPORT(ret_from_irq) | ||
36 | LONG_S s0, TI_REGS($28) | ||
37 | FEXPORT(__ret_from_irq) | ||
38 | /* | ||
39 | * We can be coming here from a syscall done in the kernel space, | ||
40 | * e.g. a failed kernel_execve(). | ||
41 | */ | ||
42 | resume_userspace_check: | ||
43 | LONG_L t0, PT_STATUS(sp) # returning to kernel mode? | ||
44 | andi t0, t0, KU_USER | ||
45 | beqz t0, resume_kernel | ||
46 | |||
47 | resume_userspace: | ||
48 | local_irq_disable # make sure we dont miss an | ||
49 | # interrupt setting need_resched | ||
50 | # between sampling and return | ||
51 | LONG_L a2, TI_FLAGS($28) # current->work | ||
52 | andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace) | ||
53 | bnez t0, work_pending | ||
54 | j restore_all | ||
55 | |||
56 | #ifdef CONFIG_PREEMPTION | ||
57 | resume_kernel: | ||
58 | local_irq_disable | ||
59 | lw t0, TI_PRE_COUNT($28) | ||
60 | bnez t0, restore_all | ||
61 | LONG_L t0, TI_FLAGS($28) | ||
62 | andi t1, t0, _TIF_NEED_RESCHED | ||
63 | beqz t1, restore_all | ||
64 | LONG_L t0, PT_STATUS(sp) # Interrupts off? | ||
65 | andi t0, 1 | ||
66 | beqz t0, restore_all | ||
67 | PTR_LA ra, restore_all | ||
68 | j preempt_schedule_irq | ||
69 | #endif | ||
70 | |||
71 | FEXPORT(ret_from_kernel_thread) | ||
72 | jal schedule_tail # a0 = struct task_struct *prev | ||
73 | move a0, s1 | ||
74 | jal s0 | ||
75 | j syscall_exit | ||
76 | |||
77 | FEXPORT(ret_from_fork) | ||
78 | jal schedule_tail # a0 = struct task_struct *prev | ||
79 | |||
80 | FEXPORT(syscall_exit) | ||
81 | #ifdef CONFIG_DEBUG_RSEQ | ||
82 | move a0, sp | ||
83 | jal rseq_syscall | ||
84 | #endif | ||
85 | local_irq_disable # make sure need_resched and | ||
86 | # signals dont change between | ||
87 | # sampling and return | ||
88 | LONG_L a2, TI_FLAGS($28) # current->work | ||
89 | li t0, _TIF_ALLWORK_MASK | ||
90 | and t0, a2, t0 | ||
91 | bnez t0, syscall_exit_work | ||
92 | |||
93 | restore_all: # restore full frame | ||
94 | .set noat | ||
95 | RESTORE_TEMP | ||
96 | RESTORE_AT | ||
97 | RESTORE_STATIC | ||
98 | restore_partial: # restore partial frame | ||
99 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
100 | SAVE_STATIC | ||
101 | SAVE_AT | ||
102 | SAVE_TEMP | ||
103 | LONG_L v0, PT_STATUS(sp) | ||
104 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
105 | and v0, ST0_IEP | ||
106 | #else | ||
107 | and v0, ST0_IE | ||
108 | #endif | ||
109 | beqz v0, 1f | ||
110 | jal trace_hardirqs_on | ||
111 | b 2f | ||
112 | 1: jal trace_hardirqs_off | ||
113 | 2: | ||
114 | RESTORE_TEMP | ||
115 | RESTORE_AT | ||
116 | RESTORE_STATIC | ||
117 | #endif | ||
118 | RESTORE_SOME | ||
119 | RESTORE_SP_AND_RET | ||
120 | .set at | ||
121 | |||
122 | work_pending: | ||
123 | andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS | ||
124 | beqz t0, work_notifysig | ||
125 | work_resched: | ||
126 | TRACE_IRQS_OFF | ||
127 | jal schedule | ||
128 | |||
129 | local_irq_disable # make sure need_resched and | ||
130 | # signals dont change between | ||
131 | # sampling and return | ||
132 | LONG_L a2, TI_FLAGS($28) | ||
133 | andi t0, a2, _TIF_WORK_MASK # is there any work to be done | ||
134 | # other than syscall tracing? | ||
135 | beqz t0, restore_all | ||
136 | andi t0, a2, _TIF_NEED_RESCHED | ||
137 | bnez t0, work_resched | ||
138 | |||
139 | work_notifysig: # deal with pending signals and | ||
140 | # notify-resume requests | ||
141 | move a0, sp | ||
142 | li a1, 0 | ||
143 | jal do_notify_resume # a2 already loaded | ||
144 | j resume_userspace_check | ||
145 | |||
146 | FEXPORT(syscall_exit_partial) | ||
147 | #ifdef CONFIG_DEBUG_RSEQ | ||
148 | move a0, sp | ||
149 | jal rseq_syscall | ||
150 | #endif | ||
151 | local_irq_disable # make sure need_resched doesn't | ||
152 | # change between and return | ||
153 | LONG_L a2, TI_FLAGS($28) # current->work | ||
154 | li t0, _TIF_ALLWORK_MASK | ||
155 | and t0, a2 | ||
156 | beqz t0, restore_partial | ||
157 | SAVE_STATIC | ||
158 | syscall_exit_work: | ||
159 | LONG_L t0, PT_STATUS(sp) # returning to kernel mode? | ||
160 | andi t0, t0, KU_USER | ||
161 | beqz t0, resume_kernel | ||
162 | li t0, _TIF_WORK_SYSCALL_EXIT | ||
163 | and t0, a2 # a2 is preloaded with TI_FLAGS | ||
164 | beqz t0, work_pending # trace bit set? | ||
165 | local_irq_enable # could let syscall_trace_leave() | ||
166 | # call schedule() instead | ||
167 | TRACE_IRQS_ON | ||
168 | move a0, sp | ||
169 | jal syscall_trace_leave | ||
170 | b resume_userspace | ||
171 | |||
172 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \ | ||
173 | defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_MIPS_MT) | ||
174 | |||
175 | /* | ||
176 | * MIPS32R2 Instruction Hazard Barrier - must be called | ||
177 | * | ||
178 | * For C code use the inline version named instruction_hazard(). | ||
179 | */ | ||
180 | LEAF(mips_ihb) | ||
181 | .set MIPS_ISA_LEVEL_RAW | ||
182 | jr.hb ra | ||
183 | nop | ||
184 | END(mips_ihb) | ||
185 | |||
186 | #endif /* CONFIG_CPU_MIPSR2 - CONFIG_CPU_MIPSR6 or CONFIG_MIPS_MT */ | ||