1
2
3
4
5
6
7
8
9
10
11#include <linux/cpu.h>
12#include <linux/pm.h>
13#include <linux/elf.h>
14#include <linux/errno.h>
15#include <linux/kallsyms.h>
16#include <linux/kernel.h>
17#include <linux/mm.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/notifier.h>
21#include <linux/personality.h>
22#include <linux/sched.h>
23#include <linux/stddef.h>
24#include <linux/thread_info.h>
25#include <linux/unistd.h>
26#include <linux/efi.h>
27#include <linux/interrupt.h>
28#include <linux/delay.h>
29#include <linux/kdebug.h>
30#include <linux/utsname.h>
31#include <linux/tracehook.h>
32#include <linux/rcupdate.h>
33
34#include <asm/cpu.h>
35#include <asm/delay.h>
36#include <asm/elf.h>
37#include <asm/irq.h>
38#include <asm/kexec.h>
39#include <asm/pgalloc.h>
40#include <asm/processor.h>
41#include <asm/sal.h>
42#include <asm/switch_to.h>
43#include <asm/tlbflush.h>
44#include <asm/uaccess.h>
45#include <asm/unwind.h>
46#include <asm/user.h>
47
48#include "entry.h"
49
50#ifdef CONFIG_PERFMON
51# include <asm/perfmon.h>
52#endif
53
54#include "sigframe.h"
55
56void (*ia64_mark_idle)(int);
57
58unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
59EXPORT_SYMBOL(boot_option_idle_override);
60void (*pm_idle) (void);
61EXPORT_SYMBOL(pm_idle);
62void (*pm_power_off) (void);
63EXPORT_SYMBOL(pm_power_off);
64
65void
66ia64_do_show_stack (struct unw_frame_info *info, void *arg)
67{
68 unsigned long ip, sp, bsp;
69 char buf[128];
70
71 printk("\nCall Trace:\n");
72 do {
73 unw_get_ip(info, &ip);
74 if (ip == 0)
75 break;
76
77 unw_get_sp(info, &sp);
78 unw_get_bsp(info, &bsp);
79 snprintf(buf, sizeof(buf),
80 " [<%016lx>] %%s\n"
81 " sp=%016lx bsp=%016lx\n",
82 ip, sp, bsp);
83 print_symbol(buf, ip);
84 } while (unw_unwind(info) >= 0);
85}
86
87void
88show_stack (struct task_struct *task, unsigned long *sp)
89{
90 if (!task)
91 unw_init_running(ia64_do_show_stack, NULL);
92 else {
93 struct unw_frame_info info;
94
95 unw_init_from_blocked_task(&info, task);
96 ia64_do_show_stack(&info, NULL);
97 }
98}
99
100void
101dump_stack (void)
102{
103 show_stack(NULL, NULL);
104}
105
106EXPORT_SYMBOL(dump_stack);
107
108void
109show_regs (struct pt_regs *regs)
110{
111 unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
112
113 print_modules();
114 printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
115 smp_processor_id(), current->comm);
116 printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n",
117 regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
118 init_utsname()->release);
119 print_symbol("ip is at %s\n", ip);
120 printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
121 regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
122 printk("rnat: %016lx bsps: %016lx pr : %016lx\n",
123 regs->ar_rnat, regs->ar_bspstore, regs->pr);
124 printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
125 regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
126 printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd);
127 printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, regs->b6, regs->b7);
128 printk("f6 : %05lx%016lx f7 : %05lx%016lx\n",
129 regs->f6.u.bits[1], regs->f6.u.bits[0],
130 regs->f7.u.bits[1], regs->f7.u.bits[0]);
131 printk("f8 : %05lx%016lx f9 : %05lx%016lx\n",
132 regs->f8.u.bits[1], regs->f8.u.bits[0],
133 regs->f9.u.bits[1], regs->f9.u.bits[0]);
134 printk("f10 : %05lx%016lx f11 : %05lx%016lx\n",
135 regs->f10.u.bits[1], regs->f10.u.bits[0],
136 regs->f11.u.bits[1], regs->f11.u.bits[0]);
137
138 printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, regs->r2, regs->r3);
139 printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10);
140 printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, regs->r12, regs->r13);
141 printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, regs->r15, regs->r16);
142 printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, regs->r18, regs->r19);
143 printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, regs->r21, regs->r22);
144 printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, regs->r24, regs->r25);
145 printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
146 printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
147
148 if (user_mode(regs)) {
149
150 unsigned long val, *bsp, ndirty;
151 int i, sof, is_nat = 0;
152
153 sof = regs->cr_ifs & 0x7f;
154 ndirty = (regs->loadrs >> 19);
155 bsp = ia64_rse_skip_regs((unsigned long *) regs->ar_bspstore, ndirty);
156 for (i = 0; i < sof; ++i) {
157 get_user(val, (unsigned long __user *) ia64_rse_skip_regs(bsp, i));
158 printk("r%-3u:%c%016lx%s", 32 + i, is_nat ? '*' : ' ', val,
159 ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
160 }
161 } else
162 show_stack(NULL, NULL);
163}
164
165
166void
167console_print(const char *s)
168{
169 printk(KERN_EMERG "%s", s);
170}
171
172void
173do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
174{
175 if (fsys_mode(current, &scr->pt)) {
176
177
178
179
180 if (!ia64_psr(&scr->pt)->lp)
181 ia64_psr(&scr->pt)->lp = 1;
182 return;
183 }
184
185#ifdef CONFIG_PERFMON
186 if (current->thread.pfm_needs_checking)
187
188
189
190
191 pfm_handle_work();
192#endif
193
194
195 if (test_thread_flag(TIF_SIGPENDING)) {
196 local_irq_enable();
197 ia64_do_signal(scr, in_syscall);
198 }
199
200 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
201 local_irq_enable();
202 tracehook_notify_resume(&scr->pt);
203 }
204
205
206 if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) {
207 local_irq_enable();
208 ia64_sync_krbs();
209 }
210
211 local_irq_disable();
212}
213
214static int pal_halt = 1;
215static int can_do_pal_halt = 1;
216
217static int __init nohalt_setup(char * str)
218{
219 pal_halt = can_do_pal_halt = 0;
220 return 1;
221}
222__setup("nohalt", nohalt_setup);
223
224void
225update_pal_halt_status(int status)
226{
227 can_do_pal_halt = pal_halt && status;
228}
229
230
231
232
233void
234default_idle (void)
235{
236 local_irq_enable();
237 while (!need_resched()) {
238 if (can_do_pal_halt) {
239 local_irq_disable();
240 if (!need_resched()) {
241 safe_halt();
242 }
243 local_irq_enable();
244 } else
245 cpu_relax();
246 }
247}
248
249#ifdef CONFIG_HOTPLUG_CPU
250
251static inline void play_dead(void)
252{
253 unsigned int this_cpu = smp_processor_id();
254
255
256 __get_cpu_var(cpu_state) = CPU_DEAD;
257
258 max_xtp();
259 local_irq_disable();
260 idle_task_exit();
261 ia64_jump_to_sal(&sal_boot_rendez_state[this_cpu]);
262
263
264
265
266 BUG();
267}
268#else
269static inline void play_dead(void)
270{
271 BUG();
272}
273#endif
274
275void __attribute__((noreturn))
276cpu_idle (void)
277{
278 void (*mark_idle)(int) = ia64_mark_idle;
279 int cpu = smp_processor_id();
280
281
282 while (1) {
283 rcu_idle_enter();
284 if (can_do_pal_halt) {
285 current_thread_info()->status &= ~TS_POLLING;
286
287
288
289
290 smp_mb();
291 } else {
292 current_thread_info()->status |= TS_POLLING;
293 }
294
295 if (!need_resched()) {
296 void (*idle)(void);
297#ifdef CONFIG_SMP
298 min_xtp();
299#endif
300 rmb();
301 if (mark_idle)
302 (*mark_idle)(1);
303
304 idle = pm_idle;
305 if (!idle)
306 idle = default_idle;
307 (*idle)();
308 if (mark_idle)
309 (*mark_idle)(0);
310#ifdef CONFIG_SMP
311 normal_xtp();
312#endif
313 }
314 rcu_idle_exit();
315 schedule_preempt_disabled();
316 check_pgt_cache();
317 if (cpu_is_offline(cpu))
318 play_dead();
319 }
320}
321
322void
323ia64_save_extra (struct task_struct *task)
324{
325#ifdef CONFIG_PERFMON
326 unsigned long info;
327#endif
328
329 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
330 ia64_save_debug_regs(&task->thread.dbr[0]);
331
332#ifdef CONFIG_PERFMON
333 if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
334 pfm_save_regs(task);
335
336 info = __get_cpu_var(pfm_syst_info);
337 if (info & PFM_CPUINFO_SYST_WIDE)
338 pfm_syst_wide_update_task(task, info, 0);
339#endif
340}
341
342void
343ia64_load_extra (struct task_struct *task)
344{
345#ifdef CONFIG_PERFMON
346 unsigned long info;
347#endif
348
349 if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
350 ia64_load_debug_regs(&task->thread.dbr[0]);
351
352#ifdef CONFIG_PERFMON
353 if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
354 pfm_load_regs(task);
355
356 info = __get_cpu_var(pfm_syst_info);
357 if (info & PFM_CPUINFO_SYST_WIDE)
358 pfm_syst_wide_update_task(task, info, 1);
359#endif
360}
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393int
394copy_thread(unsigned long clone_flags,
395 unsigned long user_stack_base, unsigned long user_stack_size,
396 struct task_struct *p)
397{
398 extern char ia64_ret_from_clone;
399 struct switch_stack *child_stack, *stack;
400 unsigned long rbs, child_rbs, rbs_size;
401 struct pt_regs *child_ptregs;
402 struct pt_regs *regs = current_pt_regs();
403 int retval = 0;
404
405 child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1;
406 child_stack = (struct switch_stack *) child_ptregs - 1;
407
408 rbs = (unsigned long) current + IA64_RBS_OFFSET;
409 child_rbs = (unsigned long) p + IA64_RBS_OFFSET;
410
411
412 p->thread.ksp = (unsigned long) child_stack - 16;
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
431 | IA64_THREAD_PM_VALID)
432# define THREAD_FLAGS_TO_SET 0
433 p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
434 | THREAD_FLAGS_TO_SET);
435
436 ia64_drop_fpu(p);
437
438 if (unlikely(p->flags & PF_KTHREAD)) {
439 if (unlikely(!user_stack_base)) {
440
441 return 0;
442 }
443 memset(child_stack, 0, sizeof(*child_ptregs) + sizeof(*child_stack));
444 child_stack->r4 = user_stack_base;
445 child_stack->r5 = user_stack_size;
446
447
448
449
450 child_ptregs->cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
451
452 child_ptregs->cr_ifs = 1UL << 63;
453 child_stack->ar_fpsr = child_ptregs->ar_fpsr
454 = ia64_getreg(_IA64_REG_AR_FPSR);
455 child_stack->pr = (1 << PRED_KERNEL_STACK);
456 child_stack->ar_bspstore = child_rbs;
457 child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
458
459
460
461
462
463
464 child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
465 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
466
467 return 0;
468 }
469 stack = ((struct switch_stack *) regs) - 1;
470
471 memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack));
472
473
474 rbs_size = stack->ar_bspstore - rbs;
475 memcpy((void *) child_rbs, (void *) rbs, rbs_size);
476 if (clone_flags & CLONE_SETTLS)
477 child_ptregs->r13 = regs->r16;
478 if (user_stack_base) {
479 child_ptregs->r12 = user_stack_base + user_stack_size - 16;
480 child_ptregs->ar_bspstore = user_stack_base;
481 child_ptregs->ar_rnat = 0;
482 child_ptregs->loadrs = 0;
483 }
484 child_stack->ar_bspstore = child_rbs + rbs_size;
485 child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
486
487
488
489
490
491
492 child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
493 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
494
495#ifdef CONFIG_PERFMON
496 if (current->thread.pfm_context)
497 pfm_inherit(p, child_ptregs);
498#endif
499 return retval;
500}
501
502static void
503do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
504{
505 unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm;
506 unsigned long uninitialized_var(ip);
507 elf_greg_t *dst = arg;
508 struct pt_regs *pt;
509 char nat;
510 int i;
511
512 memset(dst, 0, sizeof(elf_gregset_t));
513
514 if (unw_unwind_to_user(info) < 0)
515 return;
516
517 unw_get_sp(info, &sp);
518 pt = (struct pt_regs *) (sp + 16);
519
520 urbs_end = ia64_get_user_rbs_end(task, pt, &cfm);
521
522 if (ia64_sync_user_rbs(task, info->sw, pt->ar_bspstore, urbs_end) < 0)
523 return;
524
525 ia64_peek(task, info->sw, urbs_end, (long) ia64_rse_rnat_addr((long *) urbs_end),
526 &ar_rnat);
527
528
529
530
531
532
533
534
535
536
537
538
539
540 for (i = 1, mask = (1UL << i); i < 32; ++i) {
541 unw_get_gr(info, i, &dst[i], &nat);
542 if (nat)
543 nat_bits |= mask;
544 mask <<= 1;
545 }
546 dst[32] = nat_bits;
547 unw_get_pr(info, &dst[33]);
548
549 for (i = 0; i < 8; ++i)
550 unw_get_br(info, i, &dst[34 + i]);
551
552 unw_get_rp(info, &ip);
553 dst[42] = ip + ia64_psr(pt)->ri;
554 dst[43] = cfm;
555 dst[44] = pt->cr_ipsr & IA64_PSR_UM;
556
557 unw_get_ar(info, UNW_AR_RSC, &dst[45]);
558
559
560
561
562 dst[46] = urbs_end;
563 dst[47] = pt->ar_bspstore;
564 dst[48] = ar_rnat;
565 unw_get_ar(info, UNW_AR_CCV, &dst[49]);
566 unw_get_ar(info, UNW_AR_UNAT, &dst[50]);
567 unw_get_ar(info, UNW_AR_FPSR, &dst[51]);
568 dst[52] = pt->ar_pfs;
569 unw_get_ar(info, UNW_AR_LC, &dst[53]);
570 unw_get_ar(info, UNW_AR_EC, &dst[54]);
571 unw_get_ar(info, UNW_AR_CSD, &dst[55]);
572 unw_get_ar(info, UNW_AR_SSD, &dst[56]);
573}
574
575void
576do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *arg)
577{
578 elf_fpreg_t *dst = arg;
579 int i;
580
581 memset(dst, 0, sizeof(elf_fpregset_t));
582
583 if (unw_unwind_to_user(info) < 0)
584 return;
585
586
587
588 for (i = 2; i < 32; ++i)
589 unw_get_fr(info, i, dst + i);
590
591 ia64_flush_fph(task);
592 if ((task->thread.flags & IA64_THREAD_FPH_VALID) != 0)
593 memcpy(dst + 32, task->thread.fph, 96*16);
594}
595
596void
597do_copy_regs (struct unw_frame_info *info, void *arg)
598{
599 do_copy_task_regs(current, info, arg);
600}
601
602void
603do_dump_fpu (struct unw_frame_info *info, void *arg)
604{
605 do_dump_task_fpu(current, info, arg);
606}
607
608void
609ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
610{
611 unw_init_running(do_copy_regs, dst);
612}
613
614int
615dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
616{
617 unw_init_running(do_dump_fpu, dst);
618 return 1;
619}
620
621
622
623
624void
625flush_thread (void)
626{
627
628 current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
629 ia64_drop_fpu(current);
630}
631
632
633
634
635
636void
637exit_thread (void)
638{
639
640 ia64_drop_fpu(current);
641#ifdef CONFIG_PERFMON
642
643 if (current->thread.pfm_context)
644 pfm_exit_thread(current);
645
646
647 if (current->thread.flags & IA64_THREAD_DBG_VALID)
648 pfm_release_debug_registers(current);
649#endif
650}
651
652unsigned long
653get_wchan (struct task_struct *p)
654{
655 struct unw_frame_info info;
656 unsigned long ip;
657 int count = 0;
658
659 if (!p || p == current || p->state == TASK_RUNNING)
660 return 0;
661
662
663
664
665
666
667
668
669
670 unw_init_from_blocked_task(&info, p);
671 do {
672 if (p->state == TASK_RUNNING)
673 return 0;
674 if (unw_unwind(&info) < 0)
675 return 0;
676 unw_get_ip(&info, &ip);
677 if (!in_sched_functions(ip))
678 return ip;
679 } while (count++ < 16);
680 return 0;
681}
682
683void
684cpu_halt (void)
685{
686 pal_power_mgmt_info_u_t power_info[8];
687 unsigned long min_power;
688 int i, min_power_state;
689
690 if (ia64_pal_halt_info(power_info) != 0)
691 return;
692
693 min_power_state = 0;
694 min_power = power_info[0].pal_power_mgmt_info_s.power_consumption;
695 for (i = 1; i < 8; ++i)
696 if (power_info[i].pal_power_mgmt_info_s.im
697 && power_info[i].pal_power_mgmt_info_s.power_consumption < min_power) {
698 min_power = power_info[i].pal_power_mgmt_info_s.power_consumption;
699 min_power_state = i;
700 }
701
702 while (1)
703 ia64_pal_halt(min_power_state);
704}
705
706void machine_shutdown(void)
707{
708#ifdef CONFIG_HOTPLUG_CPU
709 int cpu;
710
711 for_each_online_cpu(cpu) {
712 if (cpu != smp_processor_id())
713 cpu_down(cpu);
714 }
715#endif
716#ifdef CONFIG_KEXEC
717 kexec_disable_iosapic();
718#endif
719}
720
721void
722machine_restart (char *restart_cmd)
723{
724 (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
725 (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
726}
727
728void
729machine_halt (void)
730{
731 (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
732 cpu_halt();
733}
734
735void
736machine_power_off (void)
737{
738 if (pm_power_off)
739 pm_power_off();
740 machine_halt();
741}
742
743