1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/elf.h>
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/fs.h>
25#include <linux/cpu.h>
26#include <linux/module.h>
27#include <linux/personality.h>
28#include <linux/ptrace.h>
29#include <linux/sched.h>
30#include <linux/sched/debug.h>
31#include <linux/sched/task.h>
32#include <linux/sched/task_stack.h>
33#include <linux/slab.h>
34#include <linux/stddef.h>
35#include <linux/unistd.h>
36#include <linux/kallsyms.h>
37#include <linux/uaccess.h>
38#include <linux/rcupdate.h>
39#include <linux/random.h>
40#include <linux/nmi.h>
41
42#include <asm/io.h>
43#include <asm/asm-offsets.h>
44#include <asm/assembly.h>
45#include <asm/pdc.h>
46#include <asm/pdc_chassis.h>
47#include <asm/unwind.h>
48#include <asm/sections.h>
49
50#define COMMAND_GLOBAL F_EXTEND(0xfffe0030)
51#define CMD_RESET 5
52
53
54
55
56
57
58
59
60
61
62
63
64
65void machine_restart(char *cmd)
66{
67#ifdef FASTBOOT_SELFTEST_SUPPORT
68
69
70
71
72
73
74
75
76
77
78
79 if (ftc_bitmap) {
80 pdc_do_firm_test_reset(ftc_bitmap);
81 }
82#endif
83
84 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
85
86
87 pdc_do_reset();
88
89
90 gsc_writel(CMD_RESET, COMMAND_GLOBAL);
91
92
93 while (1) ;
94
95}
96
97void (*chassis_power_off)(void);
98
99
100
101
102
103void machine_power_off(void)
104{
105
106 if (chassis_power_off)
107 chassis_power_off();
108
109
110
111
112 pdc_soft_power_button(0);
113
114 pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
115
116
117 if (pm_power_off)
118 pm_power_off();
119
120
121
122
123 printk(KERN_EMERG "System shut down completed.\n"
124 "Please power this system off now.");
125
126
127 rcu_sysrq_start();
128 lockup_detector_soft_poweroff();
129 for (;;);
130}
131
132void (*pm_power_off)(void);
133EXPORT_SYMBOL(pm_power_off);
134
135void machine_halt(void)
136{
137 machine_power_off();
138}
139
140void flush_thread(void)
141{
142
143
144
145}
146
147void release_thread(struct task_struct *dead_task)
148{
149}
150
151
152
153
154
155
156
157
158int running_on_qemu __ro_after_init;
159EXPORT_SYMBOL(running_on_qemu);
160
161void __cpuidle arch_cpu_idle_dead(void)
162{
163
164 asm volatile("or %%r31,%%r31,%%r31\n":::);
165}
166
167void __cpuidle arch_cpu_idle(void)
168{
169 raw_local_irq_enable();
170
171
172 asm volatile("or %%r10,%%r10,%%r10\n":::);
173}
174
175static int __init parisc_idle_init(void)
176{
177 if (!running_on_qemu)
178 cpu_idle_poll_ctrl(1);
179
180 return 0;
181}
182arch_initcall(parisc_idle_init);
183
184
185
186
187int
188copy_thread(unsigned long clone_flags, unsigned long usp,
189 unsigned long kthread_arg, struct task_struct *p, unsigned long tls)
190{
191 struct pt_regs *cregs = &(p->thread.regs);
192 void *stack = task_stack_page(p);
193
194
195
196
197 extern void * const ret_from_kernel_thread;
198 extern void * const child_return;
199
200 if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
201
202 memset(cregs, 0, sizeof(struct pt_regs));
203 if (!usp)
204 return 0;
205
206
207
208 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
209 cregs->kpc = (unsigned long) &ret_from_kernel_thread;
210
211
212
213
214#ifdef CONFIG_64BIT
215 cregs->gr[27] = ((unsigned long *)usp)[3];
216 cregs->gr[26] = ((unsigned long *)usp)[2];
217#else
218 cregs->gr[26] = usp;
219#endif
220 cregs->gr[25] = kthread_arg;
221 } else {
222
223
224
225
226 if (usp) {
227 usp = ALIGN(usp, 4);
228 if (likely(usp))
229 cregs->gr[30] = usp;
230 }
231 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
232 cregs->kpc = (unsigned long) &child_return;
233
234
235 if (clone_flags & CLONE_SETTLS)
236 cregs->cr27 = tls;
237 }
238
239 return 0;
240}
241
242unsigned long
243get_wchan(struct task_struct *p)
244{
245 struct unwind_frame_info info;
246 unsigned long ip;
247 int count = 0;
248
249 if (!p || p == current || task_is_running(p))
250 return 0;
251
252
253
254
255
256 unwind_frame_init_from_blocked_task(&info, p);
257 do {
258 if (unwind_once(&info) < 0)
259 return 0;
260 if (task_is_running(p))
261 return 0;
262 ip = info.ip;
263 if (!in_sched_functions(ip))
264 return ip;
265 } while (count++ < MAX_UNWIND_ENTRIES);
266 return 0;
267}
268
269#ifdef CONFIG_64BIT
270void *dereference_function_descriptor(void *ptr)
271{
272 Elf64_Fdesc *desc = ptr;
273 void *p;
274
275 if (!get_kernel_nofault(p, (void *)&desc->addr))
276 ptr = p;
277 return ptr;
278}
279
280void *dereference_kernel_function_descriptor(void *ptr)
281{
282 if (ptr < (void *)__start_opd ||
283 ptr >= (void *)__end_opd)
284 return ptr;
285
286 return dereference_function_descriptor(ptr);
287}
288#endif
289
290static inline unsigned long brk_rnd(void)
291{
292 return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
293}
294
295unsigned long arch_randomize_brk(struct mm_struct *mm)
296{
297 unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
298
299 if (ret < mm->brk)
300 return mm->brk;
301 return ret;
302}
303