Linux-2.6.12-rc2
[safe/jmp/linux-2.6] / arch / frv / kernel / kernel_thread.S
1 /* kernel_thread.S: kernel thread creation
2  *
3  * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@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 License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/linkage.h>
13 #include <asm/unistd.h>
14
15 #define CLONE_VM        0x00000100      /* set if VM shared between processes */
16 #define KERN_ERR        "<3>"
17
18         .section .rodata
19 kernel_thread_emsg:
20         .asciz  KERN_ERR "failed to create kernel thread: error=%d\n"
21
22         .text
23         .balign         4
24
25 ###############################################################################
26 #
27 # Create a kernel thread
28 #
29 # int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
30 #
31 ###############################################################################
32         .globl          kernel_thread
33         .type           kernel_thread,@function
34 kernel_thread:
35         or.p            gr8,gr0,gr4
36         or              gr9,gr0,gr5
37
38         # start by forking the current process, but with shared VM
39         setlos.p        #__NR_clone,gr7         ; syscall number
40         ori             gr10,#CLONE_VM,gr8      ; first syscall arg     [clone_flags]
41         sethi.p         #0xe4e4,gr9             ; second syscall arg    [newsp]
42         setlo           #0xe4e4,gr9
43         setlos.p        #0,gr10                 ; third syscall arg     [parent_tidptr]
44         setlos          #0,gr11                 ; fourth syscall arg    [child_tidptr]
45         tira            gr0,#0
46         setlos.p        #4095,gr7
47         andcc           gr8,gr8,gr0,icc0
48         addcc.p         gr8,gr7,gr0,icc1
49         bnelr           icc0,#2
50         bc              icc1,#0,kernel_thread_error
51
52         # now invoke the work function
53         or              gr5,gr0,gr8
54         calll           @(gr4,gr0)
55
56         # and finally exit the thread
57         setlos          #__NR_exit,gr7          ; syscall number
58         tira            gr0,#0
59
60 kernel_thread_error:
61         subi            sp,#8,sp
62         movsg           lr,gr4
63         sti             gr8,@(sp,#0)
64         sti.p           gr4,@(sp,#4)
65
66         or              gr8,gr0,gr9
67         sethi.p         %hi(kernel_thread_emsg),gr8
68         setlo           %lo(kernel_thread_emsg),gr8
69
70         call            printk
71
72         ldi             @(sp,#4),gr4
73         ldi             @(sp,#0),gr8
74         subi            sp,#8,sp
75         jmpl            @(gr4,gr0)
76
77         .size           kernel_thread,.-kernel_thread