Skip to content

Commit

Permalink
h8300: generic kernel_thread()
Browse files Browse the repository at this point in the history
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Al Viro committed Oct 14, 2012
1 parent ddffeb8 commit 557e199
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 36 deletions.
1 change: 1 addition & 0 deletions arch/h8300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ config H8300
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD

config SYMBOL_PREFIX
string
Expand Down
2 changes: 0 additions & 2 deletions arch/h8300/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ static inline void release_thread(struct task_struct *dead_task)
{
}

extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);

/*
* Free current thread data structures etc..
*/
Expand Down
2 changes: 2 additions & 0 deletions arch/h8300/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ struct pt_regs {
#define user_mode(regs) (!((regs)->ccr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
#define current_pt_regs() ((struct pt_regs *) \
(THREAD_SIZE + (unsigned long)current_thread_info()) - 1)
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _H8300_PTRACE_H */
10 changes: 10 additions & 0 deletions arch/h8300/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ INTERRUPTS = 128
.globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(ret_from_exception)
.globl SYMBOL_NAME(ret_from_fork)
.globl SYMBOL_NAME(ret_from_kernel_thread)
.globl SYMBOL_NAME(ret_from_interrupt)
.globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
Expand Down Expand Up @@ -330,6 +331,15 @@ SYMBOL_NAME_LABEL(ret_from_fork)
jsr @SYMBOL_NAME(schedule_tail)
jmp @SYMBOL_NAME(ret_from_exception)

SYMBOL_NAME_LABEL(ret_from_kernel_thread)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
mov.l @(LER4:16,sp),er0
mov.l @(LER5:16,sp),er1
jsr @er1
sub.l @er0,@er0
jsr @SYMBOL_NAME(sys_exit)

SYMBOL_NAME_LABEL(resume)
/*
* Beware - when entering resume, offset of tss is in d1,
Expand Down
1 change: 0 additions & 1 deletion arch/h8300/kernel/h8300_ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ EXPORT_SYMBOL(strncmp);

EXPORT_SYMBOL(ip_fast_csum);

EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);

Expand Down
41 changes: 8 additions & 33 deletions arch/h8300/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);

asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);

/*
* The idle loop on an H8/300..
Expand Down Expand Up @@ -122,39 +123,6 @@ void show_regs(struct pt_regs * regs)
printk("\n");
}

/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval;
long clone_arg;
mm_segment_t fs;

fs = get_fs();
set_fs (KERNEL_DS);
clone_arg = flags | CLONE_VM;
__asm__("mov.l sp,er3\n\t"
"sub.l er2,er2\n\t"
"mov.l %2,er1\n\t"
"mov.l %1,er0\n\t"
"trapa #0\n\t"
"cmp.l sp,er3\n\t"
"beq 1f\n\t"
"mov.l %4,er0\n\t"
"mov.l %3,er1\n\t"
"jsr @er1\n\t"
"mov.l %5,er0\n\t"
"trapa #0\n"
"1:\n\t"
"mov.l er0,%0"
:"=r"(retval)
:"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
:"er0","er1","er2","er3");
set_fs (fs);
return retval;
}

void flush_thread(void)
{
}
Expand Down Expand Up @@ -198,6 +166,13 @@ int copy_thread(unsigned long clone_flags,

childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;

if (unlikely(p->flags & PF_KTHREAD)) {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->retpc = (unsigned long) ret_from_kernel_thread;
childregs->er4 = topstk; /* arg */
childregs->er5 = usp; /* fn */
p->thread.ksp = (unsigned long)childregs;
}
*childregs = *regs;
childregs->retpc = (unsigned long) ret_from_fork;
childregs->er0 = 0;
Expand Down

0 comments on commit 557e199

Please sign in to comment.