ia64/xen-unstable

view linux-2.6-xen-sparse/include/asm-ia64/hypercall.h @ 10692:306d7857928c

[IA64] Save & restore.

xc_ia64_linux_save.c and xc_ia64_linux_restore.c added.
vcpu context has more registers and states (eg: tr registers).
Per cpu irqs are deallocated when cpu is switched off.
#if/#endif added in reboot.c for ia64.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Tue Jul 11 12:51:18 2006 -0600 (2006-07-11)
parents acabf4bdec4f
children c3e20511c745
line source
1 /******************************************************************************
2 * hypercall.h
3 *
4 * Linux-specific hypervisor handling.
5 *
6 * Copyright (c) 2002-2004, K A Fraser
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
33 #ifndef __HYPERCALL_H__
34 #define __HYPERCALL_H__
36 #include <linux/string.h> /* memcpy() */
38 #ifndef __HYPERVISOR_H__
39 # error "please don't include this file directly"
40 #endif
42 /*
43 * Assembler stubs for hyper-calls.
44 */
46 #define _hypercall0(type, name) \
47 ({ \
48 long __res; \
49 __asm__ __volatile__ (";;\n" \
50 "mov r2=%1\n" \
51 "break 0x1000 ;;\n" \
52 "mov %0=r8 ;;\n" \
53 : "=r" (__res) \
54 : "i" (__HYPERVISOR_##name) \
55 : "r2","r8", \
56 "memory" ); \
57 (type)__res; \
58 })
60 #define _hypercall1(type, name, a1) \
61 ({ \
62 long __res; \
63 __asm__ __volatile__ (";;\n" \
64 "mov r14=%2\n" \
65 "mov r2=%1\n" \
66 "break 0x1000 ;;\n" \
67 "mov %0=r8 ;;\n" \
68 : "=r" (__res) \
69 : "i" (__HYPERVISOR_##name), \
70 "r" ((unsigned long)(a1)) \
71 : "r14","r2","r8", \
72 "memory" ); \
73 (type)__res; \
74 })
76 #define _hypercall2(type, name, a1, a2) \
77 ({ \
78 long __res; \
79 __asm__ __volatile__ (";;\n" \
80 "mov r14=%2\n" \
81 "mov r15=%3\n" \
82 "mov r2=%1\n" \
83 "break 0x1000 ;;\n" \
84 "mov %0=r8 ;;\n" \
85 : "=r" (__res) \
86 : "i" (__HYPERVISOR_##name), \
87 "r" ((unsigned long)(a1)), \
88 "r" ((unsigned long)(a2)) \
89 : "r14","r15","r2","r8", \
90 "memory" ); \
91 (type)__res; \
92 })
94 #define _hypercall3(type, name, a1, a2, a3) \
95 ({ \
96 long __res; \
97 __asm__ __volatile__ (";;\n" \
98 "mov r14=%2\n" \
99 "mov r15=%3\n" \
100 "mov r16=%4\n" \
101 "mov r2=%1\n" \
102 "break 0x1000 ;;\n" \
103 "mov %0=r8 ;;\n" \
104 : "=r" (__res) \
105 : "i" (__HYPERVISOR_##name), \
106 "r" ((unsigned long)(a1)), \
107 "r" ((unsigned long)(a2)), \
108 "r" ((unsigned long)(a3)) \
109 : "r14","r15","r16","r2","r8", \
110 "memory" ); \
111 (type)__res; \
112 })
114 #define _hypercall4(type, name, a1, a2, a3, a4) \
115 ({ \
116 long __res; \
117 __asm__ __volatile__ (";;\n" \
118 "mov r14=%2\n" \
119 "mov r15=%3\n" \
120 "mov r16=%4\n" \
121 "mov r17=%5\n" \
122 "mov r2=%1\n" \
123 "break 0x1000 ;;\n" \
124 "mov %0=r8 ;;\n" \
125 : "=r" (__res) \
126 : "i" (__HYPERVISOR_##name), \
127 "r" ((unsigned long)(a1)), \
128 "r" ((unsigned long)(a2)), \
129 "r" ((unsigned long)(a3)), \
130 "r" ((unsigned long)(a4)) \
131 : "r14","r15","r16","r2","r8", \
132 "r17","memory" ); \
133 (type)__res; \
134 })
136 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
137 ({ \
138 long __res; \
139 __asm__ __volatile__ (";;\n" \
140 "mov r14=%2\n" \
141 "mov r15=%3\n" \
142 "mov r16=%4\n" \
143 "mov r17=%5\n" \
144 "mov r18=%6\n" \
145 "mov r2=%1\n" \
146 "break 0x1000 ;;\n" \
147 "mov %0=r8 ;;\n" \
148 : "=r" (__res) \
149 : "i" (__HYPERVISOR_##name), \
150 "r" ((unsigned long)(a1)), \
151 "r" ((unsigned long)(a2)), \
152 "r" ((unsigned long)(a3)), \
153 "r" ((unsigned long)(a4)), \
154 "r" ((unsigned long)(a5)) \
155 : "r14","r15","r16","r2","r8", \
156 "r17","r18","memory" ); \
157 (type)__res; \
158 })
160 static inline int
161 HYPERVISOR_sched_op_compat(
162 int cmd, unsigned long arg)
163 {
164 return _hypercall2(int, sched_op_compat, cmd, arg);
165 }
167 static inline int
168 HYPERVISOR_sched_op(
169 int cmd, void *arg)
170 {
171 return _hypercall2(int, sched_op, cmd, arg);
172 }
174 static inline long
175 HYPERVISOR_set_timer_op(
176 u64 timeout)
177 {
178 unsigned long timeout_hi = (unsigned long)(timeout>>32);
179 unsigned long timeout_lo = (unsigned long)timeout;
180 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
181 }
183 static inline int
184 HYPERVISOR_dom0_op(
185 dom0_op_t *dom0_op)
186 {
187 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
188 return _hypercall1(int, dom0_op, dom0_op);
189 }
191 static inline int
192 HYPERVISOR_multicall(
193 void *call_list, int nr_calls)
194 {
195 return _hypercall2(int, multicall, call_list, nr_calls);
196 }
198 #ifndef CONFIG_XEN_IA64_DOM0_VP
199 static inline int
200 HYPERVISOR_memory_op(
201 unsigned int cmd, void *arg)
202 {
203 return _hypercall2(int, memory_op, cmd, arg);
204 }
205 #else
206 //XXX xen/ia64 copy_from_guest() is broken.
207 // This is a temporal work around until it is fixed.
208 static inline int
209 ____HYPERVISOR_memory_op(
210 unsigned int cmd, void *arg)
211 {
212 return _hypercall2(int, memory_op, cmd, arg);
213 }
215 #include <xen/interface/memory.h>
216 int ia64_xenmem_reservation_op(unsigned long op,
217 struct xen_memory_reservation* reservation__);
218 static inline int
219 HYPERVISOR_memory_op(
220 unsigned int cmd, void *arg)
221 {
222 switch (cmd) {
223 case XENMEM_increase_reservation:
224 case XENMEM_decrease_reservation:
225 case XENMEM_populate_physmap:
226 return ia64_xenmem_reservation_op(cmd,
227 (struct xen_memory_reservation*)arg);
228 default:
229 return ____HYPERVISOR_memory_op(cmd, arg);
230 }
231 /* NOTREACHED */
232 }
233 #endif
235 static inline int
236 HYPERVISOR_event_channel_op(
237 int cmd, void *arg)
238 {
239 int rc = _hypercall2(int, event_channel_op, cmd, arg);
240 if (unlikely(rc == -ENOSYS)) {
241 struct evtchn_op op;
242 op.cmd = cmd;
243 memcpy(&op.u, arg, sizeof(op.u));
244 rc = _hypercall1(int, event_channel_op_compat, &op);
245 }
246 return rc;
247 }
249 static inline int
250 HYPERVISOR_acm_op(
251 unsigned int cmd, void *arg)
252 {
253 return _hypercall2(int, acm_op, cmd, arg);
254 }
256 static inline int
257 HYPERVISOR_xen_version(
258 int cmd, void *arg)
259 {
260 return _hypercall2(int, xen_version, cmd, arg);
261 }
263 static inline int
264 HYPERVISOR_console_io(
265 int cmd, int count, char *str)
266 {
267 return _hypercall3(int, console_io, cmd, count, str);
268 }
270 static inline int
271 HYPERVISOR_physdev_op(
272 int cmd, void *arg)
273 {
274 int rc = _hypercall2(int, physdev_op, cmd, arg);
275 if (unlikely(rc == -ENOSYS)) {
276 struct physdev_op op;
277 op.cmd = cmd;
278 memcpy(&op.u, arg, sizeof(op.u));
279 rc = _hypercall1(int, physdev_op_compat, &op);
280 }
281 return rc;
282 }
284 //XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
285 static inline int
286 ____HYPERVISOR_grant_table_op(
287 unsigned int cmd, void *uop, unsigned int count)
288 {
289 return _hypercall3(int, grant_table_op, cmd, uop, count);
290 }
291 #ifndef CONFIG_XEN_IA64_DOM0_VP
292 #define HYPERVISOR_grant_table_op(cmd, uop, count) \
293 ____HYPERVISOR_grant_table_op((cmd), (uop), (count))
294 #else
295 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
296 #endif
298 static inline int
299 HYPERVISOR_vcpu_op(
300 int cmd, int vcpuid, void *extra_args)
301 {
302 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
303 }
305 extern int HYPERVISOR_suspend(unsigned long srec);
307 static inline int
308 HYPERVISOR_callback_op(
309 int cmd, void *arg)
310 {
311 return _hypercall2(int, callback_op, cmd, arg);
312 }
314 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
315 static inline void exit_idle(void) {}
316 #define do_IRQ(irq, regs) ({ \
317 irq_enter(); \
318 __do_IRQ((irq), (regs)); \
319 irq_exit(); \
320 })
322 #ifdef CONFIG_XEN_IA64_DOM0_VP
323 #include <linux/err.h>
324 #include <asm/xen/privop.h>
326 #define _hypercall_imm1(type, name, imm, a1) \
327 ({ \
328 long __res; \
329 __asm__ __volatile__ (";;\n" \
330 "mov r14=%2\n" \
331 "mov r15=%3\n" \
332 "mov r2=%1\n" \
333 "break 0x1000 ;;\n" \
334 "mov %0=r8 ;;\n" \
335 : "=r" (__res) \
336 : "i" (__HYPERVISOR_##name), \
337 "i" (imm), \
338 "r" ((unsigned long)(a1)) \
339 : "r14","r15","r2","r8", \
340 "memory" ); \
341 (type)__res; \
342 })
344 #define _hypercall_imm2(type, name, imm, a1, a2) \
345 ({ \
346 long __res; \
347 __asm__ __volatile__ (";;\n" \
348 "mov r14=%2\n" \
349 "mov r15=%3\n" \
350 "mov r16=%4\n" \
351 "mov r2=%1\n" \
352 "break 0x1000 ;;\n" \
353 "mov %0=r8 ;;\n" \
354 : "=r" (__res) \
355 : "i" (__HYPERVISOR_##name), \
356 "i" (imm), \
357 "r" ((unsigned long)(a1)), \
358 "r" ((unsigned long)(a2)) \
359 : "r14","r15","r16","r2","r8", \
360 "memory" ); \
361 (type)__res; \
362 })
364 #define _hypercall_imm3(type, name, imm, a1, a2, a3) \
365 ({ \
366 long __res; \
367 __asm__ __volatile__ (";;\n" \
368 "mov r14=%2\n" \
369 "mov r15=%3\n" \
370 "mov r16=%4\n" \
371 "mov r17=%5\n" \
372 "mov r2=%1\n" \
373 "break 0x1000 ;;\n" \
374 "mov %0=r8 ;;\n" \
375 : "=r" (__res) \
376 : "i" (__HYPERVISOR_##name), \
377 "i" (imm), \
378 "r" ((unsigned long)(a1)), \
379 "r" ((unsigned long)(a2)), \
380 "r" ((unsigned long)(a3)) \
381 : "r14","r15","r16","r17", \
382 "r2","r8", \
383 "memory" ); \
384 (type)__res; \
385 })
387 #define _hypercall_imm4(type, name, imm, a1, a2, a3, a4) \
388 ({ \
389 long __res; \
390 __asm__ __volatile__ (";;\n" \
391 "mov r14=%2\n" \
392 "mov r15=%3\n" \
393 "mov r16=%4\n" \
394 "mov r17=%5\n" \
395 "mov r18=%6\n" \
396 "mov r2=%1\n" \
397 "break 0x1000 ;;\n" \
398 "mov %0=r8 ;;\n" \
399 : "=r" (__res) \
400 : "i" (__HYPERVISOR_##name), \
401 "i" (imm), \
402 "r" ((unsigned long)(a1)), \
403 "r" ((unsigned long)(a2)), \
404 "r" ((unsigned long)(a3)), \
405 "r" ((unsigned long)(a4)) \
406 : "r14","r15","r16","r17","r18", \
407 "r2","r8", \
408 "memory" ); \
409 (type)__res; \
410 })
412 static inline unsigned long
413 __HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
414 {
415 return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
416 IA64_DOM0VP_ioremap, ioaddr, size);
417 }
419 static inline unsigned long
420 HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
421 {
422 unsigned long ret = ioaddr;
423 if (is_running_on_xen()) {
424 ret = __HYPERVISOR_ioremap(ioaddr, size);
425 if (unlikely(ret == -ENOSYS))
426 panic("hypercall %s failed with %ld. "
427 "Please check Xen and Linux config mismatch\n",
428 __func__, -ret);
429 else if (unlikely(IS_ERR_VALUE(ret)))
430 ret = ioaddr;
431 }
432 return ret;
433 }
435 static inline unsigned long
436 __HYPERVISOR_phystomach(unsigned long gpfn)
437 {
438 return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
439 IA64_DOM0VP_phystomach, gpfn);
440 }
442 static inline unsigned long
443 HYPERVISOR_phystomach(unsigned long gpfn)
444 {
445 unsigned long ret = gpfn;
446 if (is_running_on_xen()) {
447 ret = __HYPERVISOR_phystomach(gpfn);
448 }
449 return ret;
450 }
452 static inline unsigned long
453 __HYPERVISOR_machtophys(unsigned long mfn)
454 {
455 return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
456 IA64_DOM0VP_machtophys, mfn);
457 }
459 static inline unsigned long
460 HYPERVISOR_machtophys(unsigned long mfn)
461 {
462 unsigned long ret = mfn;
463 if (is_running_on_xen()) {
464 ret = __HYPERVISOR_machtophys(mfn);
465 }
466 return ret;
467 }
469 static inline unsigned long
470 __HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
471 {
472 return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
473 IA64_DOM0VP_zap_physmap, gpfn, extent_order);
474 }
476 static inline unsigned long
477 HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
478 {
479 unsigned long ret = 0;
480 if (is_running_on_xen()) {
481 ret = __HYPERVISOR_zap_physmap(gpfn, extent_order);
482 }
483 return ret;
484 }
486 static inline unsigned long
487 __HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
488 unsigned long flags, domid_t domid)
489 {
490 return _hypercall_imm4(unsigned long, ia64_dom0vp_op,
491 IA64_DOM0VP_add_physmap, gpfn, mfn, flags,
492 domid);
493 }
495 static inline unsigned long
496 HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
497 unsigned long flags, domid_t domid)
498 {
499 unsigned long ret = 0;
500 BUG_ON(!is_running_on_xen());//XXX
501 if (is_running_on_xen()) {
502 ret = __HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
503 }
504 return ret;
505 }
507 // for balloon driver
508 #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
510 #else
511 #define HYPERVISOR_ioremap(ioaddr, size) (ioaddr)
512 #define HYPERVISOR_phystomach(gpfn) (gpfn)
513 #define HYPERVISOR_machtophys(mfn) (mfn)
514 #define HYPERVISOR_zap_physmap(gpfn, extent_order) (0)
515 #define HYPERVISOR_add_physmap(gpfn, mfn, flags) (0)
516 #endif
517 #endif /* __HYPERCALL_H__ */