aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/kernel/process.c')
-rw-r--r--arch/m68k/kernel/process.c104
1 files changed, 24 insertions, 80 deletions
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index ac2892e49c7c..c51bb172e14d 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -35,6 +35,7 @@
35 35
36 36
37asmlinkage void ret_from_fork(void); 37asmlinkage void ret_from_fork(void);
38asmlinkage void ret_from_kernel_thread(void);
38 39
39 40
40/* 41/*
@@ -123,51 +124,6 @@ void show_regs(struct pt_regs * regs)
123 printk("USP: %08lx\n", rdusp()); 124 printk("USP: %08lx\n", rdusp());
124} 125}
125 126
126/*
127 * Create a kernel thread
128 */
129int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
130{
131 int pid;
132 mm_segment_t fs;
133
134 fs = get_fs();
135 set_fs (KERNEL_DS);
136
137 {
138 register long retval __asm__ ("d0");
139 register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
140
141 retval = __NR_clone;
142 __asm__ __volatile__
143 ("clrl %%d2\n\t"
144 "trap #0\n\t" /* Linux/m68k system call */
145 "tstl %0\n\t" /* child or parent */
146 "jne 1f\n\t" /* parent - jump */
147#ifdef CONFIG_MMU
148 "lea %%sp@(%c7),%6\n\t" /* reload current */
149 "movel %6@,%6\n\t"
150#endif
151 "movel %3,%%sp@-\n\t" /* push argument */
152 "jsr %4@\n\t" /* call fn */
153 "movel %0,%%d1\n\t" /* pass exit value */
154 "movel %2,%%d0\n\t" /* exit */
155 "trap #0\n"
156 "1:"
157 : "+d" (retval)
158 : "i" (__NR_clone), "i" (__NR_exit),
159 "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
160 "i" (-THREAD_SIZE)
161 : "d2");
162
163 pid = retval;
164 }
165
166 set_fs (fs);
167 return pid;
168}
169EXPORT_SYMBOL(kernel_thread);
170
171void flush_thread(void) 127void flush_thread(void)
172{ 128{
173 current->thread.fs = __USER_DS; 129 current->thread.fs = __USER_DS;
@@ -219,30 +175,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
219} 175}
220 176
221int copy_thread(unsigned long clone_flags, unsigned long usp, 177int copy_thread(unsigned long clone_flags, unsigned long usp,
222 unsigned long unused, 178 unsigned long arg,
223 struct task_struct * p, struct pt_regs * regs) 179 struct task_struct * p, struct pt_regs * regs)
224{ 180{
225 struct pt_regs * childregs; 181 struct pt_regs * childregs;
226 struct switch_stack * childstack, *stack; 182 struct switch_stack *childstack;
227 unsigned long *retp;
228 183
229 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 184 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
230
231 *childregs = *regs;
232 childregs->d0 = 0;
233
234 retp = ((unsigned long *) regs);
235 stack = ((struct switch_stack *) retp) - 1;
236
237 childstack = ((struct switch_stack *) childregs) - 1; 185 childstack = ((struct switch_stack *) childregs) - 1;
238 *childstack = *stack;
239 childstack->retpc = (unsigned long)ret_from_fork;
240 186
241 p->thread.usp = usp; 187 p->thread.usp = usp;
242 p->thread.ksp = (unsigned long)childstack; 188 p->thread.ksp = (unsigned long)childstack;
243 189 p->thread.esp0 = (unsigned long)childregs;
244 if (clone_flags & CLONE_SETTLS)
245 task_thread_info(p)->tp_value = regs->d5;
246 190
247 /* 191 /*
248 * Must save the current SFC/DFC value, NOT the value when 192 * Must save the current SFC/DFC value, NOT the value when
@@ -250,6 +194,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
250 */ 194 */
251 p->thread.fs = get_fs().seg; 195 p->thread.fs = get_fs().seg;
252 196
197 if (unlikely(!regs)) {
198 /* kernel thread */
199 memset(childstack, 0,
200 sizeof(struct switch_stack) + sizeof(struct pt_regs));
201 childregs->sr = PS_S;
202 childstack->a3 = usp; /* function */
203 childstack->d7 = arg;
204 childstack->retpc = (unsigned long)ret_from_kernel_thread;
205 p->thread.usp = 0;
206 return 0;
207 }
208 *childregs = *regs;
209 childregs->d0 = 0;
210
211 *childstack = ((struct switch_stack *) regs)[-1];
212 childstack->retpc = (unsigned long)ret_from_fork;
213
214 if (clone_flags & CLONE_SETTLS)
215 task_thread_info(p)->tp_value = regs->d5;
216
253#ifdef CONFIG_FPU 217#ifdef CONFIG_FPU
254 if (!FPU_IS_EMU) { 218 if (!FPU_IS_EMU) {
255 /* Copy the current fpu state */ 219 /* Copy the current fpu state */
@@ -337,26 +301,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
337EXPORT_SYMBOL(dump_fpu); 301EXPORT_SYMBOL(dump_fpu);
338#endif /* CONFIG_FPU */ 302#endif /* CONFIG_FPU */
339 303
340/*
341 * sys_execve() executes a new program.
342 */
343asmlinkage int sys_execve(const char __user *name,
344 const char __user *const __user *argv,
345 const char __user *const __user *envp)
346{
347 int error;
348 char * filename;
349 struct pt_regs *regs = (struct pt_regs *) &name;
350
351 filename = getname(name);
352 error = PTR_ERR(filename);
353 if (IS_ERR(filename))
354 return error;
355 error = do_execve(filename, argv, envp, regs);
356 putname(filename);
357 return error;
358}
359
360unsigned long get_wchan(struct task_struct *p) 304unsigned long get_wchan(struct task_struct *p)
361{ 305{
362 unsigned long fp, pc; 306 unsigned long fp, pc;