1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60#define __KERNEL_SYSCALLS__
61#include <stdarg.h>
62
63#include <linux/errno.h>
64#include <linux/sched.h>
65#include <linux/kernel.h>
66#include <linux/mm.h>
67#include <linux/stddef.h>
68#include <linux/unistd.h>
69#include <linux/ptrace.h>
70#include <linux/slab.h>
71#include <linux/user.h>
72#include <linux/a.out.h>
73#include <linux/elfcore.h>
74#include <linux/interrupt.h>
75#include <linux/delay.h>
76
77#include <asm/uaccess.h>
78#include <asm/pgtable.h>
79#include <asm/system.h>
80#include <asm/io.h>
81#include <asm/processor.h>
82
83#include <linux/smp.h>
84
85
86
87
88
89
90
91
92
93
94static struct fs_struct init_fs = INIT_FS;
95static struct files_struct init_files = INIT_FILES;
96static struct signal_struct init_signals = INIT_SIGNALS;
97struct mm_struct init_mm = INIT_MM(init_mm);
98
99
100
101
102
103
104
105
106
107union task_union init_task_union
108 __attribute__((__section__(".data.init_task"))) =
109 { INIT_TASK(init_task_union.task) };
110
111
112
113
114
115
116
117
118
119
120static int hlt_counter;
121
122
123
124
125void (*pm_idle)(void);
126
127
128
129
130void (*pm_power_off)(void);
131
132void disable_hlt(void)
133{
134 hlt_counter++;
135}
136
137void enable_hlt(void)
138{
139 hlt_counter--;
140}
141
142
143
144
145
146static void default_idle(void)
147{
148#ifdef CONFIG_ETRAX_GPIO
149 extern void etrax_gpio_wake_up_check(void);
150
151
152 etrax_gpio_wake_up_check();
153#endif
154}
155
156
157
158
159
160
161
162void cpu_idle(void)
163{
164
165 init_idle();
166 current->nice = 20;
167 current->counter = -100;
168
169 while(1) {
170 void (*idle)(void) = pm_idle;
171 if (!idle)
172 idle = default_idle;
173 while (!current->need_resched)
174 idle();
175 schedule();
176 check_pgt_cache();
177 }
178}
179
180
181
182
183
184
185void hard_reset_now (void)
186{
187
188
189
190
191
192#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
193 extern int cause_of_death;
194#endif
195
196 printk("*** HARD RESET ***\n");
197 cli();
198
199#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
200 cause_of_death = 0xbedead;
201#else
202
203
204 *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
205 IO_STATE(R_WATCHDOG, enable, start);
206#endif
207
208 while(1) ;
209}
210
211void machine_restart(void)
212{
213 hard_reset_now();
214}
215
216
217
218
219
220
221
222void machine_halt(void)
223{
224}
225
226
227
228void machine_power_off(void)
229{
230 if (pm_power_off)
231 pm_power_off();
232}
233
234
235
236
237
238
239
240void flush_thread(void)
241{
242}
243
244asmlinkage void ret_from_sys_call(void);
245
246
247
248
249
250
251
252
253
254
255int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
256 unsigned long unused,
257 struct task_struct *p, struct pt_regs *regs)
258{
259 struct pt_regs * childregs;
260 struct switch_stack *swstack;
261
262
263
264
265
266 childregs = user_regs(p);
267
268 *childregs = *regs;
269
270 childregs->r10 = 0;
271
272
273
274 swstack = ((struct switch_stack *)childregs) - 1;
275
276 swstack->r9 = 0;
277
278
279
280 swstack->return_ip = (unsigned long) ret_from_sys_call;
281
282
283
284 p->thread.usp = usp;
285
286
287
288 p->thread.ksp = (unsigned long) swstack;
289
290#ifdef DEBUG
291 printk("copy_thread: new regs at 0x%p, as shown below:\n", childregs);
292 show_registers(childregs);
293#endif
294
295 return 0;
296}
297
298
299
300
301void dump_thread(struct pt_regs * regs, struct user * dump)
302{
303#if 0
304 int i;
305
306
307 dump->magic = CMAGIC;
308 dump->start_code = 0;
309 dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
310 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
311 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
312 dump->u_dsize -= dump->u_tsize;
313 dump->u_ssize = 0;
314 for (i = 0; i < 8; i++)
315 dump->u_debugreg[i] = current->debugreg[i];
316
317 if (dump->start_stack < TASK_SIZE)
318 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
319
320 dump->regs = *regs;
321
322 dump->u_fpvalid = dump_fpu (regs, &dump->i387);
323#endif
324}
325
326
327int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
328{
329 return 0;
330}
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346asmlinkage int sys_fork(long r10, long r11, long r12, long r13, long mof, long srp,
347 struct pt_regs *regs)
348{
349 return do_fork(SIGCHLD, rdusp(), regs, 0);
350}
351
352
353
354asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
355 long r12, long r13, long mof, long srp,
356 struct pt_regs *regs)
357{
358 if (!newusp)
359 newusp = rdusp();
360 return do_fork(flags, newusp, regs, 0);
361}
362
363
364
365
366
367asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
368 struct pt_regs *regs)
369{
370 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
371}
372
373
374
375
376asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
377 long r13, long mof, long srp,
378 struct pt_regs *regs)
379{
380 int error;
381 char *filename;
382
383 filename = getname(fname);
384 error = PTR_ERR(filename);
385
386 if (IS_ERR(filename))
387 goto out;
388 error = do_execve(filename, argv, envp, regs);
389 putname(filename);
390 out:
391 return error;
392}
393
394
395
396
397
398extern void scheduling_functions_start_here(void);
399extern void scheduling_functions_end_here(void);
400#define first_sched ((unsigned long) scheduling_functions_start_here)
401#define last_sched ((unsigned long) scheduling_functions_end_here)
402
403unsigned long get_wchan(struct task_struct *p)
404{
405#if 0
406
407
408 unsigned long ebp, esp, eip;
409 unsigned long stack_page;
410 int count = 0;
411 if (!p || p == current || p->state == TASK_RUNNING)
412 return 0;
413 stack_page = (unsigned long)p;
414 esp = p->thread.esp;
415 if (!stack_page || esp < stack_page || esp > 8188+stack_page)
416 return 0;
417
418 ebp = *(unsigned long *) esp;
419 do {
420 if (ebp < stack_page || ebp > 8184+stack_page)
421 return 0;
422 eip = *(unsigned long *) (ebp+4);
423 if (eip < first_sched || eip >= last_sched)
424 return eip;
425 ebp = *(unsigned long *) ebp;
426 } while (count++ < 16);
427#endif
428 return 0;
429}
430#undef last_sched
431#undef first_sched
432