2dc03e1c752a3b820cd705991c4038e98157d4ef
[linux-flexiantxendom0-3.2.10.git] / arch / parisc / kernel / process.c
1 /*
2  *  linux/arch/parisc/kernel/process.c
3  *      based on the work for i386
4  */
5
6 /*
7  * This file handles the architecture-dependent parts of process handling..
8  */
9
10 #define __KERNEL_SYSCALLS__
11 #include <stdarg.h>
12
13 #include <linux/elf.h>
14 #include <linux/errno.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/module.h>
18 #include <linux/personality.h>
19 #include <linux/ptrace.h>
20 #include <linux/sched.h>
21 #include <linux/stddef.h>
22 #include <linux/unistd.h>
23
24 #include <asm/io.h>
25 #include <asm/offsets.h>
26 #include <asm/pdc.h>
27 #include <asm/pdc_chassis.h>
28 #include <asm/pgalloc.h>
29 #include <asm/uaccess.h>
30
31 int hlt_counter;
32
33 /*
34  * Power off function, if any
35  */ 
36 void (*pm_power_off)(void);
37
38 void disable_hlt(void)
39 {
40         hlt_counter++;
41 }
42
43 EXPORT_SYMBOL(disable_hlt);
44
45 void enable_hlt(void)
46 {
47         hlt_counter--;
48 }
49
50 EXPORT_SYMBOL(enable_hlt);
51
52 void default_idle(void)
53 {
54         barrier();
55 }
56
57 /*
58  * The idle thread. There's no useful work to be
59  * done, so just try to conserve power and have a
60  * low exit latency (ie sit in a loop waiting for
61  * somebody to say that they'd like to reschedule)
62  */
63 void cpu_idle(void)
64 {
65         /* endless idle loop with no priority at all */
66         while (1) {
67                 while (!need_resched())
68                         barrier();
69                 schedule();
70                 check_pgt_cache();
71         }
72 }
73
74
75 #ifdef __LP64__
76 #define COMMAND_GLOBAL  0xfffffffffffe0030UL
77 #else
78 #define COMMAND_GLOBAL  0xfffe0030
79 #endif
80
81 #define CMD_RESET       5       /* reset any module */
82
83 /*
84 ** The Wright Brothers and Gecko systems have a H/W problem
85 ** (Lasi...'nuf said) may cause a broadcast reset to lockup
86 ** the system. An HVERSION dependent PDC call was developed
87 ** to perform a "safe", platform specific broadcast reset instead
88 ** of kludging up all the code.
89 **
90 ** Older machines which do not implement PDC_BROADCAST_RESET will
91 ** return (with an error) and the regular broadcast reset can be
92 ** issued. Obviously, if the PDC does implement PDC_BROADCAST_RESET
93 ** the PDC call will not return (the system will be reset).
94 */
95 void machine_restart(char *cmd)
96 {
97 #ifdef FASTBOOT_SELFTEST_SUPPORT
98         /*
99          ** If user has modified the Firmware Selftest Bitmap,
100          ** run the tests specified in the bitmap after the
101          ** system is rebooted w/PDC_DO_RESET.
102          **
103          ** ftc_bitmap = 0x1AUL "Skip destructive memory tests"
104          **
105          ** Using "directed resets" at each processor with the MEM_TOC
106          ** vector cleared will also avoid running destructive
107          ** memory self tests. (Not implemented yet)
108          */
109         if (ftc_bitmap) {
110                 pdc_do_firm_test_reset(ftc_bitmap);
111         }
112 #endif
113         /* set up a new led state on systems shipped with a LED State panel */
114         pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
115         
116         /* "Normal" system reset */
117         pdc_do_reset();
118
119         /* Nope...box should reset with just CMD_RESET now */
120         gsc_writel(CMD_RESET, COMMAND_GLOBAL);
121
122         /* Wait for RESET to lay us to rest. */
123         while (1) ;
124
125 }
126
127 EXPORT_SYMBOL(machine_restart);
128
129 void machine_halt(void)
130 {
131         /*
132         ** The LED/ChassisCodes are updated by the led_halt()
133         ** function, called by the reboot notifier chain.
134         */
135 }
136
137 EXPORT_SYMBOL(machine_halt);
138
139
140 /*
141  * This routine is called from sys_reboot to actually turn off the
142  * machine 
143  */
144 void machine_power_off(void)
145 {
146         /* If there is a registered power off handler, call it. */
147         if(pm_power_off)
148                 pm_power_off();
149
150         /* Put the soft power button back under hardware control.
151          * If the user had already pressed the power button, the
152          * following call will immediately power off. */
153         pdc_soft_power_button(0);
154         
155         pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
156                 
157         /* It seems we have no way to power the system off via
158          * software. The user has to press the button himself. */
159
160         printk(KERN_EMERG "System shut down completed.\n"
161                KERN_EMERG "Please power this system off now.");
162 }
163
164 EXPORT_SYMBOL(machine_power_off);
165
166
167 /*
168  * Create a kernel thread
169  */
170
171 extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
172 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
173 {
174
175         /*
176          * FIXME: Once we are sure we don't need any debug here,
177          *        kernel_thread can become a #define.
178          */
179
180         return __kernel_thread(fn, arg, flags);
181 }
182
183 /*
184  * Free current thread data structures etc..
185  */
186 void exit_thread(void)
187 {
188 }
189
190 void flush_thread(void)
191 {
192         /* Only needs to handle fpu stuff or perf monitors.
193         ** REVISIT: several arches implement a "lazy fpu state".
194         */
195         set_fs(USER_DS);
196 }
197
198 void release_thread(struct task_struct *dead_task)
199 {
200 }
201
202 /*
203  * Fill in the FPU structure for a core dump.
204  */
205
206 int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
207 {
208         if (regs == NULL)
209                 return 0;
210
211         memcpy(r, regs->fr, sizeof *r);
212         return 1;
213 }
214
215 int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
216 {
217         memcpy(r, tsk->thread.regs.fr, sizeof(*r));
218         return 1;
219 }
220
221 /* Note that "fork()" is implemented in terms of clone, with
222    parameters (SIGCHLD, regs->gr[30], regs). */
223 int
224 sys_clone(unsigned long clone_flags, unsigned long usp,
225           struct pt_regs *regs)
226 {
227         int *user_tid = (int *)regs->gr[26];
228         return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid, NULL);
229 }
230
231 int
232 sys_vfork(struct pt_regs *regs)
233 {
234         return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
235 }
236
237 int
238 copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
239             unsigned long unused,       /* in ia64 this is "user_stack_size" */
240             struct task_struct * p, struct pt_regs * pregs)
241 {
242         struct pt_regs * cregs = &(p->thread.regs);
243         struct thread_info *ti = p->thread_info;
244         
245         /* We have to use void * instead of a function pointer, because
246          * function pointers aren't a pointer to the function on 64-bit.
247          * Make them const so the compiler knows they live in .text */
248         extern void * const ret_from_kernel_thread;
249         extern void * const child_return;
250 #ifdef CONFIG_HPUX
251         extern void * const hpux_child_return;
252 #endif
253
254         *cregs = *pregs;
255
256         /* Set the return value for the child.  Note that this is not
257            actually restored by the syscall exit path, but we put it
258            here for consistency in case of signals. */
259         cregs->gr[28] = 0; /* child */
260
261         /*
262          * We need to differentiate between a user fork and a
263          * kernel fork. We can't use user_mode, because the
264          * the syscall path doesn't save iaoq. Right now
265          * We rely on the fact that kernel_thread passes
266          * in zero for usp.
267          */
268         if (usp == 0) {
269                 /* kernel thread */
270                 cregs->ksp = (((unsigned long)(ti)) + THREAD_SZ_ALGN);
271                 /* Must exit via ret_from_kernel_thread in order
272                  * to call schedule_tail()
273                  */
274                 cregs->kpc = (unsigned long) &ret_from_kernel_thread;
275                 /*
276                  * Copy function and argument to be called from
277                  * ret_from_kernel_thread.
278                  */
279 #ifdef __LP64__
280                 cregs->gr[27] = pregs->gr[27];
281 #endif
282                 cregs->gr[26] = pregs->gr[26];
283                 cregs->gr[25] = pregs->gr[25];
284         } else {
285                 /* user thread */
286                 /*
287                  * Note that the fork wrappers are responsible
288                  * for setting gr[21].
289                  */
290
291                 /* Use same stack depth as parent */
292                 cregs->ksp = ((unsigned long)(ti))
293                         + (pregs->gr[21] & (INIT_THREAD_SIZE - 1));
294                 cregs->gr[30] = usp;
295                 if (p->personality == PER_HPUX) {
296 #ifdef CONFIG_HPUX
297                         cregs->kpc = (unsigned long) &hpux_child_return;
298 #else
299                         BUG();
300 #endif
301                 } else {
302                         cregs->kpc = (unsigned long) &child_return;
303                 }
304         }
305
306         return 0;
307 }
308
309 unsigned long thread_saved_pc(struct task_struct *t)
310 {
311         return t->thread.regs.kpc;
312 }
313
314 /*
315  * sys_execve() executes a new program.
316  */
317
318 asmlinkage int sys_execve(struct pt_regs *regs)
319 {
320         int error;
321         char *filename;
322
323         filename = getname((char *) regs->gr[26]);
324         error = PTR_ERR(filename);
325         if (IS_ERR(filename))
326                 goto out;
327         error = do_execve(filename, (char **) regs->gr[25],
328                 (char **) regs->gr[24], regs);
329         if (error == 0)
330                 current->ptrace &= ~PT_DTRACE;
331         putname(filename);
332 out:
333
334         return error;
335 }