ia64/xen-unstable

view xen/include/asm-ia64/linux-xen/asm/system.h @ 9770:ced37bea0647

[IA64] FPH enabling + cleanup

Move contents of switch_to macro from xensystem.h to context_switch function.
Initialize FPU on all processors. FPH is always enabled in Xen.
Speed up context-switch (a little bit!) by not enabling/disabling FPH.
Cleanup (unused function/variablesi/fields, debug printf...)
vmx_ia64_switch_to removed (was unused).

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Tue Apr 25 22:35:41 2006 -0600 (2006-04-25)
parents 7ed6c203efe9
children b58e767fafb3
line source
1 #ifndef _ASM_IA64_SYSTEM_H
2 #define _ASM_IA64_SYSTEM_H
4 /*
5 * System defines. Note that this is included both from .c and .S
6 * files, so it does only defines, not any C code. This is based
7 * on information published in the Processor Abstraction Layer
8 * and the System Abstraction Layer manual.
9 *
10 * Copyright (C) 1998-2003 Hewlett-Packard Co
11 * David Mosberger-Tang <davidm@hpl.hp.com>
12 * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
13 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
14 */
15 #include <linux/config.h>
17 #include <asm/kregs.h>
18 #include <asm/page.h>
19 #include <asm/pal.h>
20 #include <asm/percpu.h>
22 #define GATE_ADDR __IA64_UL_CONST(0xa000000000000000)
23 #ifndef XEN
24 /*
25 * 0xa000000000000000+2*PERCPU_PAGE_SIZE
26 * - 0xa000000000000000+3*PERCPU_PAGE_SIZE remain unmapped (guard page)
27 */
28 #define KERNEL_START __IA64_UL_CONST(0xa000000100000000)
29 #define PERCPU_ADDR (-PERCPU_PAGE_SIZE)
30 #endif
32 #ifndef __ASSEMBLY__
34 #include <linux/kernel.h>
35 #include <linux/types.h>
37 struct pci_vector_struct {
38 __u16 segment; /* PCI Segment number */
39 __u16 bus; /* PCI Bus number */
40 __u32 pci_id; /* ACPI split 16 bits device, 16 bits function (see section 6.1.1) */
41 __u8 pin; /* PCI PIN (0 = A, 1 = B, 2 = C, 3 = D) */
42 __u32 irq; /* IRQ assigned */
43 };
45 extern struct ia64_boot_param {
46 __u64 command_line; /* physical address of command line arguments */
47 __u64 efi_systab; /* physical address of EFI system table */
48 __u64 efi_memmap; /* physical address of EFI memory map */
49 __u64 efi_memmap_size; /* size of EFI memory map */
50 __u64 efi_memdesc_size; /* size of an EFI memory map descriptor */
51 __u32 efi_memdesc_version; /* memory descriptor version */
52 struct {
53 __u16 num_cols; /* number of columns on console output device */
54 __u16 num_rows; /* number of rows on console output device */
55 __u16 orig_x; /* cursor's x position */
56 __u16 orig_y; /* cursor's y position */
57 } console_info;
58 __u64 fpswa; /* physical address of the fpswa interface */
59 __u64 initrd_start;
60 __u64 initrd_size;
61 //for loading initrd for dom0
62 __u64 domain_start; /* virtual address where the boot time domain begins */
63 __u64 domain_size; /* how big is the boot domain */
65 } *ia64_boot_param;
67 /*
68 * Macros to force memory ordering. In these descriptions, "previous"
69 * and "subsequent" refer to program order; "visible" means that all
70 * architecturally visible effects of a memory access have occurred
71 * (at a minimum, this means the memory has been read or written).
72 *
73 * wmb(): Guarantees that all preceding stores to memory-
74 * like regions are visible before any subsequent
75 * stores and that all following stores will be
76 * visible only after all previous stores.
77 * rmb(): Like wmb(), but for reads.
78 * mb(): wmb()/rmb() combo, i.e., all previous memory
79 * accesses are visible before all subsequent
80 * accesses and vice versa. This is also known as
81 * a "fence."
82 *
83 * Note: "mb()" and its variants cannot be used as a fence to order
84 * accesses to memory mapped I/O registers. For that, mf.a needs to
85 * be used. However, we don't want to always use mf.a because (a)
86 * it's (presumably) much slower than mf and (b) mf.a is supported for
87 * sequential memory pages only.
88 */
89 #define mb() ia64_mf()
90 #define rmb() mb()
91 #define wmb() mb()
92 #define read_barrier_depends() do { } while(0)
94 #ifdef CONFIG_SMP
95 # define smp_mb() mb()
96 # define smp_rmb() rmb()
97 # define smp_wmb() wmb()
98 # define smp_read_barrier_depends() read_barrier_depends()
99 #else
100 # define smp_mb() barrier()
101 # define smp_rmb() barrier()
102 # define smp_wmb() barrier()
103 # define smp_read_barrier_depends() do { } while(0)
104 #endif
106 /*
107 * XXX check on these---I suspect what Linus really wants here is
108 * acquire vs release semantics but we can't discuss this stuff with
109 * Linus just yet. Grrr...
110 */
111 #define set_mb(var, value) do { (var) = (value); mb(); } while (0)
112 #define set_wmb(var, value) do { (var) = (value); mb(); } while (0)
114 #define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */
116 /*
117 * The group barrier in front of the rsm & ssm are necessary to ensure
118 * that none of the previous instructions in the same group are
119 * affected by the rsm/ssm.
120 */
121 /* For spinlocks etc */
123 /*
124 * - clearing psr.i is implicitly serialized (visible by next insn)
125 * - setting psr.i requires data serialization
126 * - we need a stop-bit before reading PSR because we sometimes
127 * write a floating-point register right before reading the PSR
128 * and that writes to PSR.mfl
129 */
130 #define __local_irq_save(x) \
131 do { \
132 ia64_stop(); \
133 (x) = ia64_getreg(_IA64_REG_PSR); \
134 ia64_stop(); \
135 ia64_rsm(IA64_PSR_I); \
136 } while (0)
138 #define __local_irq_disable() \
139 do { \
140 ia64_stop(); \
141 ia64_rsm(IA64_PSR_I); \
142 } while (0)
144 #define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I)
146 #ifdef CONFIG_IA64_DEBUG_IRQ
148 extern unsigned long last_cli_ip;
150 # define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP)
152 # define local_irq_save(x) \
153 do { \
154 unsigned long psr; \
155 \
156 __local_irq_save(psr); \
157 if (psr & IA64_PSR_I) \
158 __save_ip(); \
159 (x) = psr; \
160 } while (0)
162 # define local_irq_disable() do { unsigned long x; local_irq_save(x); } while (0)
164 # define local_irq_restore(x) \
165 do { \
166 unsigned long old_psr, psr = (x); \
167 \
168 local_save_flags(old_psr); \
169 __local_irq_restore(psr); \
170 if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) \
171 __save_ip(); \
172 } while (0)
174 #else /* !CONFIG_IA64_DEBUG_IRQ */
175 # define local_irq_save(x) __local_irq_save(x)
176 # define local_irq_disable() __local_irq_disable()
177 # define local_irq_restore(x) __local_irq_restore(x)
178 #endif /* !CONFIG_IA64_DEBUG_IRQ */
180 #define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
181 #define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
183 #define irqs_disabled() \
184 ({ \
185 unsigned long __ia64_id_flags; \
186 local_save_flags(__ia64_id_flags); \
187 (__ia64_id_flags & IA64_PSR_I) == 0; \
188 })
190 #ifdef XEN
191 #define local_irq_is_enabled() (!irqs_disabled())
192 #else
193 #ifdef __KERNEL__
195 #ifdef CONFIG_IA32_SUPPORT
196 # define IS_IA32_PROCESS(regs) (ia64_psr(regs)->is != 0)
197 #else
198 # define IS_IA32_PROCESS(regs) 0
199 struct task_struct;
200 static inline void ia32_save_state(struct task_struct *t __attribute__((unused))){}
201 static inline void ia32_load_state(struct task_struct *t __attribute__((unused))){}
202 #endif
204 /*
205 * Context switch from one thread to another. If the two threads have
206 * different address spaces, schedule() has already taken care of
207 * switching to the new address space by calling switch_mm().
208 *
209 * Disabling access to the fph partition and the debug-register
210 * context switch MUST be done before calling ia64_switch_to() since a
211 * newly created thread returns directly to
212 * ia64_ret_from_syscall_clear_r8.
213 */
214 extern struct task_struct *ia64_switch_to (void *next_task);
216 struct task_struct;
218 extern void ia64_save_extra (struct task_struct *task);
219 extern void ia64_load_extra (struct task_struct *task);
221 #ifdef CONFIG_PERFMON
222 DECLARE_PER_CPU(unsigned long, pfm_syst_info);
223 # define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1)
224 #else
225 # define PERFMON_IS_SYSWIDE() (0)
226 #endif
228 #define IA64_HAS_EXTRA_STATE(t) \
229 ((t)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID) \
230 || IS_IA32_PROCESS(ia64_task_regs(t)) || PERFMON_IS_SYSWIDE())
232 #define __switch_to(prev,next,last) do { \
233 if (IA64_HAS_EXTRA_STATE(prev)) \
234 ia64_save_extra(prev); \
235 if (IA64_HAS_EXTRA_STATE(next)) \
236 ia64_load_extra(next); \
237 ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \
238 (last) = ia64_switch_to((next)); \
239 } while (0)
241 #ifdef CONFIG_SMP
242 /*
243 * In the SMP case, we save the fph state when context-switching away from a thread that
244 * modified fph. This way, when the thread gets scheduled on another CPU, the CPU can
245 * pick up the state from task->thread.fph, avoiding the complication of having to fetch
246 * the latest fph state from another CPU. In other words: eager save, lazy restore.
247 */
248 # define switch_to(prev,next,last) do { \
249 if (ia64_psr(ia64_task_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \
250 ia64_psr(ia64_task_regs(prev))->mfh = 0; \
251 (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \
252 __ia64_save_fpu((prev)->thread.fph); \
253 } \
254 __switch_to(prev, next, last); \
255 } while (0)
256 #else
257 # define switch_to(prev,next,last) __switch_to(prev, next, last)
258 #endif
260 /*
261 * On IA-64, we don't want to hold the runqueue's lock during the low-level context-switch,
262 * because that could cause a deadlock. Here is an example by Erich Focht:
263 *
264 * Example:
265 * CPU#0:
266 * schedule()
267 * -> spin_lock_irq(&rq->lock)
268 * -> context_switch()
269 * -> wrap_mmu_context()
270 * -> read_lock(&tasklist_lock)
271 *
272 * CPU#1:
273 * sys_wait4() or release_task() or forget_original_parent()
274 * -> write_lock(&tasklist_lock)
275 * -> do_notify_parent()
276 * -> wake_up_parent()
277 * -> try_to_wake_up()
278 * -> spin_lock_irq(&parent_rq->lock)
279 *
280 * If the parent's rq happens to be on CPU#0, we'll wait for the rq->lock
281 * of that CPU which will not be released, because there we wait for the
282 * tasklist_lock to become available.
283 */
284 #define __ARCH_WANT_UNLOCKED_CTXSW
286 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
288 void cpu_idle_wait(void);
290 #define arch_align_stack(x) (x)
292 #endif /* __KERNEL__ */
293 #endif /* XEN */
295 #endif /* __ASSEMBLY__ */
297 #ifdef XEN
298 #include <asm/xensystem.h>
299 #ifndef __ASSEMBLY__
300 struct resource;
301 #endif
302 #endif
304 #endif /* _ASM_IA64_SYSTEM_H */