- Kai Germaschewski: ymfpci cleanups and resource leak fixes
[davej-history.git] / arch / parisc / kernel / process.c
bloba8d7a707e88b0b370b9c83c6d0a6f29e9f6eeba1
1 /*
2 * linux/arch/parisc/kernel/process.c
3 * based on the work for i386
4 */
6 /*
7 * This file handles the architecture-dependent parts of process handling..
8 */
10 #define __KERNEL_SYSCALLS__
11 #include <stdarg.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/smp.h>
18 #include <linux/smp_lock.h>
19 #include <linux/stddef.h>
20 #include <linux/unistd.h>
21 #include <linux/ptrace.h>
22 #include <linux/malloc.h>
23 #include <linux/vmalloc.h>
24 #include <linux/interrupt.h>
25 #include <linux/reboot.h>
26 #include <linux/init.h>
27 #include <linux/version.h>
28 #include <linux/elf.h>
30 #include <asm/machdep.h>
31 #include <asm/offset.h>
32 #include <asm/uaccess.h>
33 #include <asm/pgtable.h>
34 #include <asm/system.h>
35 #include <asm/io.h>
36 #include <asm/gsc.h>
37 #include <asm/processor.h>
39 spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
41 #ifdef __LP64__
42 /* The 64-bit code should work equally well in 32-bit land but I didn't
43 * want to take the time to confirm that. -PB
45 extern unsigned int ret_from_kernel_thread;
46 #else
47 asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
48 #endif
51 int hlt_counter=0;
53 void disable_hlt(void)
55 hlt_counter++;
58 void enable_hlt(void)
60 hlt_counter--;
64 * The idle thread. There's no useful work to be
65 * done, so just try to conserve power and have a
66 * low exit latency (ie sit in a loop waiting for
67 * somebody to say that they'd like to reschedule)
69 void cpu_idle(void)
71 /* endless idle loop with no priority at all */
72 init_idle();
73 current->nice = 20;
74 current->counter = -100;
76 while (1) {
77 while (!current->need_resched) {
79 schedule();
80 check_pgt_cache();
84 void __init reboot_setup(char *str, int *ints)
88 struct notifier_block *mach_notifier;
90 void machine_restart(char *ptr)
92 notifier_call_chain(&mach_notifier, MACH_RESTART, ptr);
95 void machine_halt(void)
97 notifier_call_chain(&mach_notifier, MACH_HALT, NULL);
100 void machine_power_on(void)
102 notifier_call_chain(&mach_notifier, MACH_POWER_ON, NULL);
105 void machine_power_off(void)
107 notifier_call_chain(&mach_notifier, MACH_POWER_OFF, NULL);
111 void machine_heartbeat(void)
117 * Create a kernel thread
120 extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
121 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
125 * FIXME: Once we are sure we don't need any debug here,
126 * kernel_thread can become a #define.
129 return __kernel_thread(fn, arg, flags);
133 * Free current thread data structures etc..
135 void exit_thread(void)
139 void flush_thread(void)
141 set_fs(USER_DS);
144 void release_thread(struct task_struct *dead_task)
149 * Fill in the FPU structure for a core dump.
151 int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
153 memcpy(r, regs->fr, sizeof *r);
154 return 1;
157 /* Note that "fork()" is implemented in terms of clone, with
158 parameters (SIGCHLD, regs->gr[30], regs). */
160 sys_clone(unsigned long clone_flags, unsigned long usp,
161 struct pt_regs *regs)
163 return do_fork(clone_flags, usp, regs, 0);
167 sys_vfork(struct pt_regs *regs)
169 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
170 regs->gr[30], regs, 0);
174 copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
175 unsigned long unused, /* in ia64 this is "user_stack_size" */
176 struct task_struct * p, struct pt_regs * pregs)
178 struct pt_regs * cregs = &(p->thread.regs);
179 long ksp;
181 *cregs = *pregs;
183 /* Set the return value for the child. Note that this is not
184 actually restored by the syscall exit path, but we put it
185 here for consistency in case of signals. */
186 cregs->gr[28] = 0; /* child */
189 * We need to differentiate between a user fork and a
190 * kernel fork. We can't use user_mode, because the
191 * the syscall path doesn't save iaoq. Right now
192 * We rely on the fact that kernel_thread passes
193 * in zero for usp.
195 if (usp == 0) {
196 /* Kernel Thread */
197 ksp = (((unsigned long)(p)) + TASK_SZ_ALGN);
198 cregs->ksp = ksp; /* always return to kernel */
199 #ifdef __LP64__
200 cregs->kpc = (unsigned long) &ret_from_kernel_thread;
201 #else
202 cregs->kpc = (unsigned long) ret_from_kernel_thread;
203 #endif
206 * Copy function and argument to be called from
207 * ret_from_kernel_thread.
209 cregs->gr[26] = pregs->gr[26];
210 cregs->gr[25] = pregs->gr[25];
212 } else {
213 /* User Thread:
215 * Use same stack depth as parent when in wrapper
217 * Note that the fork wrappers are responsible
218 * for setting gr[20] and gr[21].
221 cregs->ksp = ((unsigned long)(p))
222 + (pregs->gr[20] & (INIT_TASK_SIZE - 1));
223 cregs->kpc = pregs->gr[21];
226 return 0;
230 * sys_execve() executes a new program.
233 asmlinkage int sys_execve(struct pt_regs *regs)
235 int error;
236 char *filename;
238 filename = getname((char *) regs->gr[26]);
239 error = PTR_ERR(filename);
240 if (IS_ERR(filename))
241 goto out;
242 error = do_execve(filename, (char **) regs->gr[25],
243 (char **) regs->gr[24], regs);
244 if (error == 0)
245 current->ptrace &= ~PT_DTRACE;
246 putname(filename);
247 out:
249 return error;