fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / 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 CLONE_KTHREAD   0x10000000      /* kernel thread */
17 #define CLONE_KT        (CLONE_VM | CLONE_KTHREAD)      /* kernel thread flags */
18 #define KERN_ERR        "<3>"
19
20         .section .rodata
21 kernel_thread_emsg:
22         .asciz  KERN_ERR "failed to create kernel thread: error=%d\n"
23
24         .text
25         .balign         4
26
27 ###############################################################################
28 #
29 # Create a kernel thread
30 #
31 # int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
32 #
33 ###############################################################################
34         .globl          kernel_thread
35         .type           kernel_thread,@function
36 kernel_thread:
37         or.p            gr8,gr0,gr4
38         or              gr9,gr0,gr5
39
40         # start by forking the current process, but with shared VM
41         setlos.p        #__NR_clone,gr7         ; syscall number
42         ori             gr10,#CLONE_KT,gr8      ; first syscall arg     [clone_flags]
43         sethi.p         #0xe4e4,gr9             ; second syscall arg    [newsp]
44         setlo           #0xe4e4,gr9
45         setlos.p        #0,gr10                 ; third syscall arg     [parent_tidptr]
46         setlos          #0,gr11                 ; fourth syscall arg    [child_tidptr]
47         tira            gr0,#0
48         setlos.p        #4095,gr7
49         andcc           gr8,gr8,gr0,icc0
50         addcc.p         gr8,gr7,gr0,icc1
51         bnelr           icc0,#2
52         bc              icc1,#0,kernel_thread_error
53
54         # now invoke the work function
55         or              gr5,gr0,gr8
56         calll           @(gr4,gr0)
57
58         # and finally exit the thread
59         setlos          #__NR_exit,gr7          ; syscall number
60         tira            gr0,#0
61
62 kernel_thread_error:
63         subi            sp,#8,sp
64         movsg           lr,gr4
65         sti             gr8,@(sp,#0)
66         sti.p           gr4,@(sp,#4)
67
68         or              gr8,gr0,gr9
69         sethi.p         %hi(kernel_thread_emsg),gr8
70         setlo           %lo(kernel_thread_emsg),gr8
71
72         call            printk
73
74         ldi             @(sp,#4),gr4
75         ldi             @(sp,#0),gr8
76         subi            sp,#8,sp
77         jmpl            @(gr4,gr0)
78
79         .size           kernel_thread,.-kernel_thread