Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/kernel/entry.S
26444 views
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
21
#ifndef CONFIG_PREEMPTION
22
#define resume_kernel restore_all
23
#else
24
#define __ret_from_irq ret_from_exception
25
#endif
26
27
.text
28
.align 5
29
#ifndef CONFIG_PREEMPTION
30
FEXPORT(ret_from_exception)
31
local_irq_disable # preempt stop
32
b __ret_from_irq
33
#endif
34
FEXPORT(ret_from_irq)
35
LONG_S s0, TI_REGS($28)
36
FEXPORT(__ret_from_irq)
37
/*
38
* We can be coming here from a syscall done in the kernel space,
39
* e.g. a failed kernel_execve().
40
*/
41
resume_userspace_check:
42
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
43
andi t0, t0, KU_USER
44
beqz t0, resume_kernel
45
46
resume_userspace:
47
local_irq_disable # make sure we dont miss an
48
# interrupt setting need_resched
49
# between sampling and return
50
LONG_L a2, TI_FLAGS($28) # current->work
51
andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace)
52
bnez t0, work_pending
53
j restore_all
54
55
#ifdef CONFIG_PREEMPTION
56
resume_kernel:
57
local_irq_disable
58
lw t0, TI_PRE_COUNT($28)
59
bnez t0, restore_all
60
LONG_L t0, TI_FLAGS($28)
61
andi t1, t0, _TIF_NEED_RESCHED
62
beqz t1, restore_all
63
LONG_L t0, PT_STATUS(sp) # Interrupts off?
64
andi t0, 1
65
beqz t0, restore_all
66
PTR_LA ra, restore_all
67
j preempt_schedule_irq
68
#endif
69
70
FEXPORT(ret_from_kernel_thread)
71
jal schedule_tail # a0 = struct task_struct *prev
72
move a0, s1
73
jal s0
74
j syscall_exit
75
76
FEXPORT(ret_from_fork)
77
jal schedule_tail # a0 = struct task_struct *prev
78
79
FEXPORT(syscall_exit)
80
#ifdef CONFIG_DEBUG_RSEQ
81
move a0, sp
82
jal rseq_syscall
83
#endif
84
local_irq_disable # make sure need_resched and
85
# signals dont change between
86
# sampling and return
87
LONG_L a2, TI_FLAGS($28) # current->work
88
li t0, _TIF_ALLWORK_MASK
89
and t0, a2, t0
90
bnez t0, syscall_exit_work
91
92
restore_all: # restore full frame
93
.set noat
94
RESTORE_TEMP
95
RESTORE_AT
96
RESTORE_STATIC
97
restore_partial: # restore partial frame
98
#ifdef CONFIG_TRACE_IRQFLAGS
99
SAVE_STATIC
100
SAVE_AT
101
SAVE_TEMP
102
LONG_L v0, PT_STATUS(sp)
103
#if defined(CONFIG_CPU_R3000)
104
and v0, ST0_IEP
105
#else
106
and v0, ST0_IE
107
#endif
108
beqz v0, 1f
109
jal trace_hardirqs_on
110
b 2f
111
1: jal trace_hardirqs_off
112
2:
113
RESTORE_TEMP
114
RESTORE_AT
115
RESTORE_STATIC
116
#endif
117
RESTORE_SOME
118
RESTORE_SP_AND_RET
119
.set at
120
121
work_pending:
122
andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
123
beqz t0, work_notifysig
124
work_resched:
125
TRACE_IRQS_OFF
126
jal schedule
127
128
local_irq_disable # make sure need_resched and
129
# signals dont change between
130
# sampling and return
131
LONG_L a2, TI_FLAGS($28)
132
andi t0, a2, _TIF_WORK_MASK # is there any work to be done
133
# other than syscall tracing?
134
beqz t0, restore_all
135
andi t0, a2, _TIF_NEED_RESCHED
136
bnez t0, work_resched
137
138
work_notifysig: # deal with pending signals and
139
# notify-resume requests
140
move a0, sp
141
li a1, 0
142
jal do_notify_resume # a2 already loaded
143
j resume_userspace_check
144
145
FEXPORT(syscall_exit_partial)
146
#ifdef CONFIG_DEBUG_RSEQ
147
move a0, sp
148
jal rseq_syscall
149
#endif
150
local_irq_disable # make sure need_resched doesn't
151
# change between and return
152
LONG_L a2, TI_FLAGS($28) # current->work
153
li t0, _TIF_ALLWORK_MASK
154
and t0, a2
155
beqz t0, restore_partial
156
SAVE_STATIC
157
syscall_exit_work:
158
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
159
andi t0, t0, KU_USER
160
beqz t0, resume_kernel
161
li t0, _TIF_WORK_SYSCALL_EXIT
162
and t0, a2 # a2 is preloaded with TI_FLAGS
163
beqz t0, work_pending # trace bit set?
164
local_irq_enable # could let syscall_trace_leave()
165
# call schedule() instead
166
TRACE_IRQS_ON
167
move a0, sp
168
jal syscall_trace_leave
169
b resume_userspace
170
171
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \
172
defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_MIPS_MT)
173
174
/*
175
* MIPS32R2 Instruction Hazard Barrier - must be called
176
*
177
* For C code use the inline version named instruction_hazard().
178
*/
179
LEAF(mips_ihb)
180
.set MIPS_ISA_LEVEL_RAW
181
jr.hb ra
182
nop
183
END(mips_ihb)
184
185
#endif /* CONFIG_CPU_MIPSR2 - CONFIG_CPU_MIPSR6 or CONFIG_MIPS_MT */
186
187