diff options
Diffstat (limited to 'arch/mn10300')
-rw-r--r-- | arch/mn10300/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/mn10300/kernel/entry.S | 7 | ||||
-rw-r--r-- | arch/mn10300/kernel/internal.h | 6 | ||||
-rw-r--r-- | arch/mn10300/kernel/kthread.S | 31 | ||||
-rw-r--r-- | arch/mn10300/kernel/process.c | 52 |
5 files changed, 27 insertions, 71 deletions
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile index d06749173d63..142c12906682 100644 --- a/arch/mn10300/kernel/Makefile +++ b/arch/mn10300/kernel/Makefile | |||
@@ -7,7 +7,7 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o | |||
7 | fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o | 7 | fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o |
8 | 8 | ||
9 | obj-y := process.o signal.o entry.o traps.o irq.o \ | 9 | obj-y := process.o signal.o entry.o traps.o irq.o \ |
10 | ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ | 10 | ptrace.o setup.o time.o sys_mn10300.o io.o \ |
11 | switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \ | 11 | switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \ |
12 | csrc-mn10300.o cevt-mn10300.o | 12 | csrc-mn10300.o cevt-mn10300.o |
13 | 13 | ||
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index 8e11f9f48999..000f144230a5 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S | |||
@@ -55,6 +55,13 @@ ENTRY(ret_from_fork) | |||
55 | mov d0,(REG_D0,fp) | 55 | mov d0,(REG_D0,fp) |
56 | jmp syscall_exit | 56 | jmp syscall_exit |
57 | 57 | ||
58 | ENTRY(ret_from_kernel_thread) | ||
59 | call schedule_tail[],0 | ||
60 | mov (REG_D0,fp),d0 | ||
61 | mov (REG_A0,fp),a0 | ||
62 | calls (a0) | ||
63 | jmp sys_exit | ||
64 | |||
58 | ############################################################################### | 65 | ############################################################################### |
59 | # | 66 | # |
60 | # system call handler | 67 | # system call handler |
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h index 2df440105a80..561785581f6c 100644 --- a/arch/mn10300/kernel/internal.h +++ b/arch/mn10300/kernel/internal.h | |||
@@ -15,14 +15,10 @@ struct clocksource; | |||
15 | struct clock_event_device; | 15 | struct clock_event_device; |
16 | 16 | ||
17 | /* | 17 | /* |
18 | * kthread.S | ||
19 | */ | ||
20 | extern int kernel_thread_helper(int); | ||
21 | |||
22 | /* | ||
23 | * entry.S | 18 | * entry.S |
24 | */ | 19 | */ |
25 | extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); | 20 | extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); |
21 | extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn)); | ||
26 | 22 | ||
27 | /* | 23 | /* |
28 | * smp-low.S | 24 | * smp-low.S |
diff --git a/arch/mn10300/kernel/kthread.S b/arch/mn10300/kernel/kthread.S deleted file mode 100644 index b5ae467ac5ec..000000000000 --- a/arch/mn10300/kernel/kthread.S +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* MN10300 Kernel thread trampoline function | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by Mark Salter (msalter@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | .text | ||
12 | |||
13 | ############################################################################### | ||
14 | # | ||
15 | # kernel_thread_helper - trampoline for kernel_thread() | ||
16 | # | ||
17 | # On entry: | ||
18 | # A2 = address of function to call | ||
19 | # D2 = function argument | ||
20 | # | ||
21 | ############################################################################### | ||
22 | .globl kernel_thread_helper | ||
23 | .type kernel_thread_helper,@function | ||
24 | kernel_thread_helper: | ||
25 | mov do_exit,d1 | ||
26 | mov d1,(sp) | ||
27 | mov d1,mdr | ||
28 | mov d2,d0 | ||
29 | jmp (a2) | ||
30 | |||
31 | .size kernel_thread_helper,.-kernel_thread_helper | ||
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index 7dab0cd36466..be87fbee4da5 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c | |||
@@ -166,13 +166,11 @@ void show_regs(struct pt_regs *regs) | |||
166 | */ | 166 | */ |
167 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | 167 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) |
168 | { | 168 | { |
169 | struct pt_regs regs; | 169 | struct pt_regs regs = { |
170 | .a0 = (unsigned long) fn; | ||
171 | .d0 = (unsigned long) arg; | ||
172 | }; | ||
170 | 173 | ||
171 | memset(®s, 0, sizeof(regs)); | ||
172 | |||
173 | regs.a2 = (unsigned long) fn; | ||
174 | regs.d2 = (unsigned long) arg; | ||
175 | regs.pc = (unsigned long) kernel_thread_helper; | ||
176 | local_save_flags(regs.epsw); | 174 | local_save_flags(regs.epsw); |
177 | regs.epsw |= EPSW_IE | EPSW_IM_7; | 175 | regs.epsw |= EPSW_IE | EPSW_IM_7; |
178 | 176 | ||
@@ -180,7 +178,6 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |||
180 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, | 178 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, |
181 | NULL, NULL); | 179 | NULL, NULL); |
182 | } | 180 | } |
183 | EXPORT_SYMBOL(kernel_thread); | ||
184 | 181 | ||
185 | /* | 182 | /* |
186 | * free current thread data structures etc.. | 183 | * free current thread data structures etc.. |
@@ -227,49 +224,36 @@ int copy_thread(unsigned long clone_flags, | |||
227 | struct task_struct *p, struct pt_regs *kregs) | 224 | struct task_struct *p, struct pt_regs *kregs) |
228 | { | 225 | { |
229 | struct thread_info *ti = task_thread_info(p); | 226 | struct thread_info *ti = task_thread_info(p); |
230 | struct pt_regs *c_uregs, *c_kregs, *uregs; | 227 | struct pt_regs *c_regs; |
231 | unsigned long c_ksp; | 228 | unsigned long c_ksp; |
232 | 229 | ||
233 | uregs = current->thread.uregs; | ||
234 | |||
235 | c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; | 230 | c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; |
236 | 231 | ||
237 | /* allocate the userspace exception frame and set it up */ | 232 | /* allocate the userspace exception frame and set it up */ |
238 | c_ksp -= sizeof(struct pt_regs); | 233 | c_ksp -= sizeof(struct pt_regs); |
239 | c_uregs = (struct pt_regs *) c_ksp; | 234 | c_regs = (struct pt_regs *) c_ksp; |
240 | 235 | ||
241 | p->thread.uregs = c_uregs; | 236 | p->thread.uregs = c_regs; |
242 | *c_uregs = *uregs; | 237 | *c_regs = *kregs; |
243 | c_uregs->sp = c_usp; | 238 | c_regs->sp = c_usp; |
244 | c_uregs->epsw &= ~EPSW_FE; /* my FPU */ | 239 | c_regs->epsw &= ~EPSW_FE; /* my FPU */ |
245 | 240 | ||
246 | c_ksp -= 12; /* allocate function call ABI slack */ | 241 | c_ksp -= 12; /* allocate function call ABI slack */ |
247 | 242 | ||
248 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ | 243 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ |
249 | if (clone_flags & CLONE_SETTLS) | 244 | if (clone_flags & CLONE_SETTLS) |
250 | c_uregs->e2 = current_frame()->d3; | 245 | c_regs->e2 = current_frame()->d3; |
251 | |||
252 | /* set up the return kernel frame if called from kernel_thread() */ | ||
253 | c_kregs = c_uregs; | ||
254 | if (kregs != uregs) { | ||
255 | c_ksp -= sizeof(struct pt_regs); | ||
256 | c_kregs = (struct pt_regs *) c_ksp; | ||
257 | *c_kregs = *kregs; | ||
258 | c_kregs->sp = c_usp; | ||
259 | c_kregs->next = c_uregs; | ||
260 | #ifdef CONFIG_MN10300_CURRENT_IN_E2 | ||
261 | c_kregs->e2 = (unsigned long) p; /* current */ | ||
262 | #endif | ||
263 | 246 | ||
264 | c_ksp -= 12; /* allocate function call ABI slack */ | 247 | if (unlikely(!user_mode(kregs))) |
265 | } | 248 | p->thread.pc = (unsigned long) ret_from_kernel_thread; |
249 | else | ||
250 | p->thread.pc = (unsigned long) ret_from_fork; | ||
266 | 251 | ||
267 | /* set up things up so the scheduler can start the new task */ | 252 | /* set up things up so the scheduler can start the new task */ |
268 | ti->frame = c_kregs; | 253 | ti->frame = c_regs; |
269 | p->thread.a3 = (unsigned long) c_kregs; | 254 | p->thread.a3 = (unsigned long) c_regs; |
270 | p->thread.sp = c_ksp; | 255 | p->thread.sp = c_ksp; |
271 | p->thread.pc = (unsigned long) ret_from_fork; | 256 | p->thread.wchan = p->thread.pc; |
272 | p->thread.wchan = (unsigned long) ret_from_fork; | ||
273 | p->thread.usp = c_usp; | 257 | p->thread.usp = c_usp; |
274 | 258 | ||
275 | return 0; | 259 | return 0; |