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#include <stdarg.h>
36
37#include <linux/elf.h>
38#include <linux/errno.h>
39#include <linux/kernel.h>
40#include <linux/mm.h>
41#include <linux/fs.h>
42#include <linux/module.h>
43#include <linux/personality.h>
44#include <linux/ptrace.h>
45#include <linux/sched.h>
46#include <linux/slab.h>
47#include <linux/stddef.h>
48#include <linux/unistd.h>
49#include <linux/kallsyms.h>
50#include <linux/uaccess.h>
51
52#include <asm/io.h>
53#include <asm/asm-offsets.h>
54#include <asm/pdc.h>
55#include <asm/pdc_chassis.h>
56#include <asm/pgalloc.h>
57#include <asm/unwind.h>
58#include <asm/sections.h>
59
60
61
62
63
64
65
66void cpu_idle(void)
67{
68 set_thread_flag(TIF_POLLING_NRFLAG);
69
70
71 while (1) {
72 while (!need_resched())
73 barrier();
74 preempt_enable_no_resched();
75 schedule();
76 preempt_disable();
77 check_pgt_cache();
78 }
79}
80
81
82#define COMMAND_GLOBAL F_EXTEND(0xfffe0030)
83#define CMD_RESET 5
84
85
86
87
88
89
90
91
92
93
94
95
96
97void machine_restart(char *cmd)
98{
99#ifdef FASTBOOT_SELFTEST_SUPPORT
100
101
102
103
104
105
106
107
108
109
110
111 if (ftc_bitmap) {
112 pdc_do_firm_test_reset(ftc_bitmap);
113 }
114#endif
115
116 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
117
118
119 pdc_do_reset();
120
121
122 gsc_writel(CMD_RESET, COMMAND_GLOBAL);
123
124
125 while (1) ;
126
127}
128
129void machine_halt(void)
130{
131
132
133
134
135}
136
137void (*chassis_power_off)(void);
138
139
140
141
142
143void machine_power_off(void)
144{
145
146 if (chassis_power_off)
147 chassis_power_off();
148
149
150
151
152 pdc_soft_power_button(0);
153
154 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
155
156
157
158
159 printk(KERN_EMERG "System shut down completed.\n"
160 "Please power this system off now.");
161}
162
163void (*pm_power_off)(void) = machine_power_off;
164EXPORT_SYMBOL(pm_power_off);
165
166
167
168
169
170extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
171pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
172{
173
174
175
176
177
178
179 return __kernel_thread(fn, arg, flags);
180}
181EXPORT_SYMBOL(kernel_thread);
182
183
184
185
186void exit_thread(void)
187{
188}
189
190void flush_thread(void)
191{
192
193
194
195 set_fs(USER_DS);
196}
197
198void release_thread(struct task_struct *dead_task)
199{
200}
201
202
203
204
205
206int 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
215int 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
222
223int
224sys_clone(unsigned long clone_flags, unsigned long usp,
225 struct pt_regs *regs)
226{
227
228
229
230
231
232
233
234
235
236 int __user *parent_tidptr = (int __user *)regs->gr[24];
237 int __user *child_tidptr = (int __user *)regs->gr[22];
238
239
240
241
242 usp = ALIGN(usp, 4);
243
244
245 if (usp == 0)
246 usp = regs->gr[30];
247
248 return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
249}
250
251int
252sys_vfork(struct pt_regs *regs)
253{
254 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
255}
256
257int
258copy_thread(unsigned long clone_flags, unsigned long usp,
259 unsigned long unused,
260 struct task_struct * p, struct pt_regs * pregs)
261{
262 struct pt_regs * cregs = &(p->thread.regs);
263 void *stack = task_stack_page(p);
264
265
266
267
268 extern void * const ret_from_kernel_thread;
269 extern void * const child_return;
270#ifdef CONFIG_HPUX
271 extern void * const hpux_child_return;
272#endif
273
274 *cregs = *pregs;
275
276
277
278
279 cregs->gr[28] = 0;
280
281
282
283
284
285
286
287
288 if (usp == 1) {
289
290 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
291
292
293
294 cregs->kpc = (unsigned long) &ret_from_kernel_thread;
295
296
297
298
299#ifdef CONFIG_64BIT
300 cregs->gr[27] = pregs->gr[27];
301#endif
302 cregs->gr[26] = pregs->gr[26];
303 cregs->gr[25] = pregs->gr[25];
304 } else {
305
306
307
308
309
310
311
312 cregs->ksp = (unsigned long)stack
313 + (pregs->gr[21] & (THREAD_SIZE - 1));
314 cregs->gr[30] = usp;
315 if (p->personality == PER_HPUX) {
316#ifdef CONFIG_HPUX
317 cregs->kpc = (unsigned long) &hpux_child_return;
318#else
319 BUG();
320#endif
321 } else {
322 cregs->kpc = (unsigned long) &child_return;
323 }
324
325 if (clone_flags & CLONE_SETTLS)
326 cregs->cr27 = pregs->gr[23];
327
328 }
329
330 return 0;
331}
332
333unsigned long thread_saved_pc(struct task_struct *t)
334{
335 return t->thread.regs.kpc;
336}
337
338
339
340
341
342asmlinkage int sys_execve(struct pt_regs *regs)
343{
344 int error;
345 char *filename;
346
347 filename = getname((const char __user *) regs->gr[26]);
348 error = PTR_ERR(filename);
349 if (IS_ERR(filename))
350 goto out;
351 error = do_execve(filename,
352 (const char __user *const __user *) regs->gr[25],
353 (const char __user *const __user *) regs->gr[24],
354 regs);
355 putname(filename);
356out:
357
358 return error;
359}
360
361extern int __execve(const char *filename,
362 const char *const argv[],
363 const char *const envp[], struct task_struct *task);
364int kernel_execve(const char *filename,
365 const char *const argv[],
366 const char *const envp[])
367{
368 return __execve(filename, argv, envp, current);
369}
370
371unsigned long
372get_wchan(struct task_struct *p)
373{
374 struct unwind_frame_info info;
375 unsigned long ip;
376 int count = 0;
377
378 if (!p || p == current || p->state == TASK_RUNNING)
379 return 0;
380
381
382
383
384
385 unwind_frame_init_from_blocked_task(&info, p);
386 do {
387 if (unwind_once(&info) < 0)
388 return 0;
389 ip = info.ip;
390 if (!in_sched_functions(ip))
391 return ip;
392 } while (count++ < 16);
393 return 0;
394}
395
396#ifdef CONFIG_64BIT
397void *dereference_function_descriptor(void *ptr)
398{
399 Elf64_Fdesc *desc = ptr;
400 void *p;
401
402 if (!probe_kernel_address(&desc->addr, p))
403 ptr = p;
404 return ptr;
405}
406#endif
407