Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
m32r
kernel
process.c
Go to the documentation of this file.
1
/*
2
* linux/arch/m32r/kernel/process.c
3
*
4
* Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata,
5
* Hitoshi Yamamoto
6
* Taken from sh version.
7
* Copyright (C) 1995 Linus Torvalds
8
* SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
9
*/
10
11
#undef DEBUG_PROCESS
12
#ifdef DEBUG_PROCESS
13
#define DPRINTK(fmt, args...) printk("%s:%d:%s: " fmt, __FILE__, __LINE__, \
14
__func__, ##args)
15
#else
16
#define DPRINTK(fmt, args...)
17
#endif
18
19
/*
20
* This file handles the architecture-dependent parts of process handling..
21
*/
22
23
#include <linux/fs.h>
24
#include <linux/slab.h>
25
#include <linux/module.h>
26
#include <linux/ptrace.h>
27
#include <
linux/unistd.h
>
28
#include <
linux/hardirq.h
>
29
#include <
linux/rcupdate.h
>
30
31
#include <asm/io.h>
32
#include <asm/uaccess.h>
33
#include <asm/mmu_context.h>
34
#include <asm/elf.h>
35
#include <
asm/m32r.h
>
36
37
#include <
linux/err.h
>
38
39
/*
40
* Return saved PC of a blocked thread.
41
*/
42
unsigned
long
thread_saved_pc
(
struct
task_struct
*tsk)
43
{
44
return
tsk->
thread
.lr;
45
}
46
47
/*
48
* Powermanagement idle function, if any..
49
*/
50
static
void
(*
pm_idle
)(
void
) =
NULL
;
51
52
void
(*
pm_power_off
)(
void
) =
NULL
;
53
EXPORT_SYMBOL
(
pm_power_off
);
54
55
/*
56
* We use this is we don't have any better
57
* idle routine..
58
*/
59
static
void
default_idle
(
void
)
60
{
61
/* M32R_FIXME: Please use "cpu_sleep" mode. */
62
cpu_relax
();
63
}
64
65
/*
66
* On SMP it's slightly faster (but much more power-consuming!)
67
* to poll the ->work.need_resched flag instead of waiting for the
68
* cross-CPU IPI to arrive. Use this option with caution.
69
*/
70
static
void
poll_idle (
void
)
71
{
72
/* M32R_FIXME */
73
cpu_relax
();
74
}
75
76
/*
77
* The idle thread. There's no useful work to be
78
* done, so just try to conserve power and have a
79
* low exit latency (ie sit in a loop waiting for
80
* somebody to say that they'd like to reschedule)
81
*/
82
void
cpu_idle
(
void
)
83
{
84
/* endless idle loop with no priority at all */
85
while
(1) {
86
rcu_idle_enter
();
87
while
(!need_resched()) {
88
void
(*
idle
)(
void
) =
pm_idle
;
89
90
if
(!
idle
)
91
idle
=
default_idle
;
92
93
idle
();
94
}
95
rcu_idle_exit
();
96
schedule_preempt_disabled
();
97
}
98
}
99
100
void
machine_restart
(
char
*
__unused
)
101
{
102
#if defined(CONFIG_PLAT_MAPPI3)
103
outw
(1, (
unsigned
long
)
PLD_REBOOT
);
104
#endif
105
106
printk
(
"Please push reset button!\n"
);
107
while
(1)
108
cpu_relax
();
109
}
110
111
void
machine_halt
(
void
)
112
{
113
printk
(
"Please push reset button!\n"
);
114
while
(1)
115
cpu_relax
();
116
}
117
118
void
machine_power_off
(
void
)
119
{
120
/* M32R_FIXME */
121
}
122
123
static
int
__init
idle_setup (
char
*
str
)
124
{
125
if
(!
strncmp
(str,
"poll"
, 4)) {
126
printk
(
"using poll in idle threads.\n"
);
127
pm_idle
= poll_idle;
128
}
else
if
(!
strncmp
(str,
"sleep"
, 4)) {
129
printk
(
"using sleep in idle threads.\n"
);
130
pm_idle
=
default_idle
;
131
}
132
133
return
1;
134
}
135
136
__setup
(
"idle="
, idle_setup);
137
138
void
show_regs
(
struct
pt_regs
*
regs
)
139
{
140
printk
(
"\n"
);
141
printk
(
"BPC[%08lx]:PSW[%08lx]:LR [%08lx]:FP [%08lx]\n"
, \
142
regs->
bpc
, regs->
psw
, regs->
lr
, regs->
fp
);
143
printk
(
"BBPC[%08lx]:BBPSW[%08lx]:SPU[%08lx]:SPI[%08lx]\n"
, \
144
regs->
bbpc
, regs->
bbpsw
, regs->
spu
, regs->
spi
);
145
printk
(
"R0 [%08lx]:R1 [%08lx]:R2 [%08lx]:R3 [%08lx]\n"
, \
146
regs->
r0
, regs->
r1
, regs->
r2
, regs->
r3
);
147
printk
(
"R4 [%08lx]:R5 [%08lx]:R6 [%08lx]:R7 [%08lx]\n"
, \
148
regs->
r4
, regs->
r5
, regs->
r6
, regs->
r7
);
149
printk
(
"R8 [%08lx]:R9 [%08lx]:R10[%08lx]:R11[%08lx]\n"
, \
150
regs->
r8
, regs->
r9
, regs->
r10
, regs->
r11
);
151
printk
(
"R12[%08lx]\n"
, \
152
regs->
r12
);
153
154
#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
155
printk
(
"ACC0H[%08lx]:ACC0L[%08lx]\n"
, \
156
regs->
acc0h
, regs->
acc0l
);
157
printk
(
"ACC1H[%08lx]:ACC1L[%08lx]\n"
, \
158
regs->
acc1h
, regs->
acc1l
);
159
#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
160
printk
(
"ACCH[%08lx]:ACCL[%08lx]\n"
, \
161
regs->
acc0h
, regs->
acc0l
);
162
#else
163
#error unknown isa configuration
164
#endif
165
}
166
167
/*
168
* Create a kernel thread
169
*/
170
171
/*
172
* This is the mechanism for creating a new kernel thread.
173
*
174
* NOTE! Only a kernel-only process(ie the swapper or direct descendants
175
* who haven't done an "execve()") should use this: it will work within
176
* a system call from a "real" process, but the process memory space will
177
* not be free'd until both the parent and the child have exited.
178
*/
179
static
void
kernel_thread_helper
(
void
*nouse,
int
(*
fn
)(
void
*),
void
*
arg
)
180
{
181
fn
(arg);
182
do_exit
(-1);
183
}
184
185
int
kernel_thread
(
int
(*
fn
)(
void
*),
void
*
arg
,
unsigned
long
flags
)
186
{
187
struct
pt_regs
regs;
188
189
memset
(®s, 0,
sizeof
(regs));
190
regs.
r1
= (
unsigned
long
)
fn
;
191
regs.
r2
= (
unsigned
long
)arg;
192
193
regs.
bpc
= (
unsigned
long
)
kernel_thread_helper
;
194
195
regs.
psw
=
M32R_PSW_BIE
;
196
197
/* Ok, create the new process. */
198
return
do_fork
(flags |
CLONE_VM
|
CLONE_UNTRACED
, 0, ®s, 0,
NULL
,
199
NULL
);
200
}
201
202
/*
203
* Free current thread data structures etc..
204
*/
205
void
exit_thread
(
void
)
206
{
207
/* Nothing to do. */
208
DPRINTK
(
"pid = %d\n"
,
current
->pid);
209
}
210
211
void
flush_thread
(
void
)
212
{
213
DPRINTK
(
"pid = %d\n"
,
current
->pid);
214
memset
(&
current
->thread.debug_trap, 0,
sizeof
(
struct
debug_trap
));
215
}
216
217
void
release_thread
(
struct
task_struct
*dead_task)
218
{
219
/* do nothing */
220
DPRINTK
(
"pid = %d\n"
, dead_task->
pid
);
221
}
222
223
/* Fill in the fpu structure for a core dump.. */
224
int
dump_fpu
(
struct
pt_regs
*
regs
,
elf_fpregset_t
*
fpu
)
225
{
226
return
0;
/* Task didn't use the fpu at all. */
227
}
228
229
int
copy_thread
(
unsigned
long
clone_flags,
unsigned
long
spu
,
230
unsigned
long
unused
,
struct
task_struct
*tsk,
struct
pt_regs
*
regs
)
231
{
232
struct
pt_regs
*childregs =
task_pt_regs
(tsk);
233
extern
void
ret_from_fork
(
void
);
234
235
/* Copy registers */
236
*childregs = *
regs
;
237
238
childregs->
spu
=
spu
;
239
childregs->
r0
= 0;
/* Child gets zero as return value */
240
regs->
r0
= tsk->
pid
;
241
tsk->
thread
.sp = (
unsigned
long
)childregs;
242
tsk->
thread
.lr = (
unsigned
long
)ret_from_fork;
243
244
return
0;
245
}
246
247
asmlinkage
int
sys_fork
(
unsigned
long
r0
,
unsigned
long
r1
,
unsigned
long
r2
,
248
unsigned
long
r3
,
unsigned
long
r4
,
unsigned
long
r5
,
unsigned
long
r6
,
249
struct
pt_regs
regs
)
250
{
251
#ifdef CONFIG_MMU
252
return
do_fork
(
SIGCHLD
, regs.
spu
, ®s, 0,
NULL
,
NULL
);
253
#else
254
return
-
EINVAL
;
255
#endif
/* CONFIG_MMU */
256
}
257
258
asmlinkage
int
sys_clone
(
unsigned
long
clone_flags,
unsigned
long
newsp,
259
unsigned
long
parent_tidptr,
260
unsigned
long
child_tidptr,
261
unsigned
long
r4
,
unsigned
long
r5
,
unsigned
long
r6
,
262
struct
pt_regs
regs
)
263
{
264
if
(!newsp)
265
newsp = regs.
spu
;
266
267
return
do_fork
(clone_flags, newsp, ®s, 0,
268
(
int
__user
*)parent_tidptr, (
int
__user
*)child_tidptr);
269
}
270
271
/*
272
* This is trivial, and on the face of it looks like it
273
* could equally well be done in user mode.
274
*
275
* Not so, for quite unobvious reasons - register pressure.
276
* In user mode vfork() cannot have a stack frame, and if
277
* done by calling the "clone()" system call directly, you
278
* do not have enough call-clobbered registers to hold all
279
* the information you need.
280
*/
281
asmlinkage
int
sys_vfork
(
unsigned
long
r0
,
unsigned
long
r1
,
unsigned
long
r2
,
282
unsigned
long
r3
,
unsigned
long
r4
,
unsigned
long
r5
,
unsigned
long
r6
,
283
struct
pt_regs
regs
)
284
{
285
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
, regs.
spu
, ®s, 0,
286
NULL
,
NULL
);
287
}
288
289
/*
290
* sys_execve() executes a new program.
291
*/
292
asmlinkage
int
sys_execve
(
const
char
__user *ufilename,
293
const
char
__user *
const
__user *uargv,
294
const
char
__user *
const
__user *uenvp,
295
unsigned
long
r3
,
unsigned
long
r4
,
unsigned
long
r5
,
296
unsigned
long
r6
,
struct
pt_regs
regs
)
297
{
298
int
error
;
299
struct
filename
*
filename
;
300
301
filename =
getname
(ufilename);
302
error = PTR_ERR(filename);
303
if
(IS_ERR(filename))
304
goto
out
;
305
306
error =
do_execve
(filename->
name
, uargv, uenvp, ®s);
307
putname
(filename);
308
out
:
309
return
error
;
310
}
311
312
/*
313
* These bracket the sleeping functions..
314
*/
315
#define first_sched ((unsigned long) scheduling_functions_start_here)
316
#define last_sched ((unsigned long) scheduling_functions_end_here)
317
318
unsigned
long
get_wchan
(
struct
task_struct
*
p
)
319
{
320
/* M32R_FIXME */
321
return
(0);
322
}
Generated on Thu Jan 10 2013 12:52:23 for Linux Kernel by
1.8.2