1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/sched.h>
14#include <linux/err.h>
15#include <linux/fs.h>
16#include <linux/slab.h>
17#include <arch/svinto.h>
18#include <linux/init.h>
19
20#ifdef CONFIG_ETRAX_GPIO
21void etrax_gpio_wake_up_check(void);
22#endif
23
24
25
26
27
28void default_idle(void)
29{
30#ifdef CONFIG_ETRAX_GPIO
31 etrax_gpio_wake_up_check();
32#endif
33}
34
35
36
37
38
39void exit_thread(void)
40{
41
42}
43
44
45
46
47
48
49void hard_reset_now (void)
50{
51
52
53
54
55
56#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
57 extern int cause_of_death;
58#endif
59
60 printk("*** HARD RESET ***\n");
61 local_irq_disable();
62
63#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
64 cause_of_death = 0xbedead;
65#else
66
67
68 *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
69 IO_STATE(R_WATCHDOG, enable, start);
70#endif
71
72 while(1) ;
73}
74
75
76
77
78unsigned long thread_saved_pc(struct task_struct *t)
79{
80 return task_pt_regs(t)->irp;
81}
82
83static void kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg)
84{
85 fn(arg);
86 do_exit(-1);
87}
88
89
90
91
92int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
93{
94 struct pt_regs regs;
95
96 memset(®s, 0, sizeof(regs));
97
98
99 regs.r11 = (unsigned long)fn;
100 regs.r12 = (unsigned long)arg;
101 regs.irp = (unsigned long)kernel_thread_helper;
102 regs.dccr = 1 << I_DCCR_BITNR;
103
104
105 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
106}
107
108
109
110
111
112
113
114
115
116asmlinkage void ret_from_fork(void);
117
118int copy_thread(unsigned long clone_flags, unsigned long usp,
119 unsigned long unused,
120 struct task_struct *p, struct pt_regs *regs)
121{
122 struct pt_regs * childregs;
123 struct switch_stack *swstack;
124
125
126
127
128
129 childregs = task_pt_regs(p);
130
131 *childregs = *regs;
132
133 p->set_child_tid = p->clear_child_tid = NULL;
134
135 childregs->r10 = 0;
136
137
138
139 swstack = ((struct switch_stack *)childregs) - 1;
140
141 swstack->r9 = 0;
142
143
144
145 swstack->return_ip = (unsigned long) ret_from_fork;
146
147
148
149 p->thread.usp = usp;
150
151
152
153 p->thread.ksp = (unsigned long) swstack;
154
155#ifdef DEBUG
156 printk("copy_thread: new regs at 0x%p, as shown below:\n", childregs);
157 show_registers(childregs);
158#endif
159
160 return 0;
161}
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177asmlinkage int sys_fork(long r10, long r11, long r12, long r13, long mof, long srp,
178 struct pt_regs *regs)
179{
180 return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
181}
182
183
184
185asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
186 int* parent_tid, int* child_tid, long mof, long srp,
187 struct pt_regs *regs)
188{
189 if (!newusp)
190 newusp = rdusp();
191 return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
192}
193
194
195
196
197
198asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
199 struct pt_regs *regs)
200{
201 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
202}
203
204
205
206
207asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
208 long r13, long mof, long srp,
209 struct pt_regs *regs)
210{
211 int error;
212 char *filename;
213
214 filename = getname(fname);
215 error = PTR_ERR(filename);
216
217 if (IS_ERR(filename))
218 goto out;
219 error = do_execve(filename, argv, envp, regs);
220 putname(filename);
221 out:
222 return error;
223}
224
225unsigned long get_wchan(struct task_struct *p)
226{
227#if 0
228
229
230 unsigned long ebp, esp, eip;
231 unsigned long stack_page;
232 int count = 0;
233 if (!p || p == current || p->state == TASK_RUNNING)
234 return 0;
235 stack_page = (unsigned long)p;
236 esp = p->thread.esp;
237 if (!stack_page || esp < stack_page || esp > 8188+stack_page)
238 return 0;
239
240 ebp = *(unsigned long *) esp;
241 do {
242 if (ebp < stack_page || ebp > 8184+stack_page)
243 return 0;
244 eip = *(unsigned long *) (ebp+4);
245 if (!in_sched_functions(eip))
246 return eip;
247 ebp = *(unsigned long *) ebp;
248 } while (count++ < 16);
249#endif
250 return 0;
251}
252#undef last_sched
253#undef first_sched
254
255void show_regs(struct pt_regs * regs)
256{
257 unsigned long usp = rdusp();
258 printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
259 regs->irp, regs->srp, regs->dccr, usp, regs->mof );
260 printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
261 regs->r0, regs->r1, regs->r2, regs->r3);
262 printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
263 regs->r4, regs->r5, regs->r6, regs->r7);
264 printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
265 regs->r8, regs->r9, regs->r10, regs->r11);
266 printk("r12: %08lx r13: %08lx oR10: %08lx\n",
267 regs->r12, regs->r13, regs->orig_r10);
268}
269
270