1
2
3
4
5
6
7
8
9
10
11
12 #ifndef _ASM_IA64_SWITCH_TO_H
13 #define _ASM_IA64_SWITCH_TO_H
14
15 #include <linux/percpu.h>
16
17 struct task_struct;
18
19
20
21
22
23
24
25
26
27
28
29 extern struct task_struct *ia64_switch_to (void *next_task);
30
31 extern void ia64_save_extra (struct task_struct *task);
32 extern void ia64_load_extra (struct task_struct *task);
33
34 #ifdef CONFIG_PERFMON
35 DECLARE_PER_CPU(unsigned long, pfm_syst_info);
36 # define PERFMON_IS_SYSWIDE() (__this_cpu_read(pfm_syst_info) & 0x1)
37 #else
38 # define PERFMON_IS_SYSWIDE() (0)
39 #endif
40
41 #define IA64_HAS_EXTRA_STATE(t) \
42 ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID) \
43 || PERFMON_IS_SYSWIDE())
44
45 #define __switch_to(prev,next,last) do { \
46 if (IA64_HAS_EXTRA_STATE(prev)) \
47 ia64_save_extra(prev); \
48 if (IA64_HAS_EXTRA_STATE(next)) \
49 ia64_load_extra(next); \
50 ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \
51 (last) = ia64_switch_to((next)); \
52 } while (0)
53
54 #ifdef CONFIG_SMP
55
56
57
58
59
60
61 # define switch_to(prev,next,last) do { \
62 if (ia64_psr(task_pt_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \
63 ia64_psr(task_pt_regs(prev))->mfh = 0; \
64 (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \
65 __ia64_save_fpu((prev)->thread.fph); \
66 } \
67 __switch_to(prev, next, last); \
68 \
69 if (unlikely((current->thread.flags & IA64_THREAD_MIGRATION) && \
70 (task_cpu(current) != \
71 task_thread_info(current)->last_cpu))) { \
72 task_thread_info(current)->last_cpu = task_cpu(current); \
73 } \
74 } while (0)
75 #else
76 # define switch_to(prev,next,last) __switch_to(prev, next, last)
77 #endif
78
79 #endif