1 /******************************************************************************
2 * hypercall.h
3 *
4 * Copyright (c) 2002-2006, K A Fraser
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation; or, when distributed
9 * separately from the Linux kernel or incorporated into other
10 * software packages, subject to the following license:
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this source file (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use, copy, modify,
15 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
16 * and to permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30
31 #ifndef __HVMLOADER_HYPERCALL_H__
32 #define __HVMLOADER_HYPERCALL_H__
33
34 #include <stdint.h>
35 #include <xen/xen.h>
36 #include "config.h"
37
38 #define hcall_addr(name) \
39 ((unsigned long)HYPERCALL_PHYSICAL_ADDRESS + __HYPERVISOR_##name * 32)
40
41 #define _hypercall0(type, name) \
42 ({ \
43 long __res; \
44 asm volatile ( \
45 "call *%%eax" \
46 : "=a" (__res) \
47 : "0" (hcall_addr(name)) \
48 : "memory" ); \
49 (type)__res; \
50 })
51
52 #define _hypercall1(type, name, a1) \
53 ({ \
54 long __res, __ign1; \
55 asm volatile ( \
56 "call *%%eax" \
57 : "=a" (__res), "=b" (__ign1) \
58 : "0" (hcall_addr(name)), \
59 "1" ((long)(a1)) \
60 : "memory" ); \
61 (type)__res; \
62 })
63
64 #define _hypercall2(type, name, a1, a2) \
65 ({ \
66 long __res, __ign1, __ign2; \
67 asm volatile ( \
68 "call *%%eax" \
69 : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
70 : "0" (hcall_addr(name)), \
71 "1" ((long)(a1)), "2" ((long)(a2)) \
72 : "memory" ); \
73 (type)__res; \
74 })
75
76 #define _hypercall3(type, name, a1, a2, a3) \
77 ({ \
78 long __res, __ign1, __ign2, __ign3; \
79 asm volatile ( \
80 "call *%%eax" \
81 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
82 "=d" (__ign3) \
83 : "0" (hcall_addr(name)), \
84 "1" ((long)(a1)), "2" ((long)(a2)), \
85 "3" ((long)(a3)) \
86 : "memory" ); \
87 (type)__res; \
88 })
89
90 #define _hypercall4(type, name, a1, a2, a3, a4) \
91 ({ \
92 long __res, __ign1, __ign2, __ign3, __ign4; \
93 asm volatile ( \
94 "call *%%eax" \
95 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
96 "=d" (__ign3), "=S" (__ign4) \
97 : "0" (hcall_addr(name)), \
98 "1" ((long)(a1)), "2" ((long)(a2)), \
99 "3" ((long)(a3)), "4" ((long)(a4)) \
100 : "memory" ); \
101 (type)__res; \
102 })
103
104 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
105 ({ \
106 long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
107 asm volatile ( \
108 "call *%%eax" \
109 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
110 "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
111 : "0" (hcall_addr(name)), \
112 "1" ((long)(a1)), "2" ((long)(a2)), \
113 "3" ((long)(a3)), "4" ((long)(a4)), \
114 "5" ((long)(a5)) \
115 : "memory" ); \
116 (type)__res; \
117 })
118
119 static inline int
hypercall_sched_op(int cmd,void * arg)120 hypercall_sched_op(
121 int cmd, void *arg)
122 {
123 return _hypercall2(int, sched_op, cmd, arg);
124 }
125
126 static inline int
hypercall_memory_op(unsigned int cmd,void * arg)127 hypercall_memory_op(
128 unsigned int cmd, void *arg)
129 {
130 return _hypercall2(int, memory_op, cmd, arg);
131 }
132
133 static inline int
hypercall_multicall(void * call_list,int nr_calls)134 hypercall_multicall(
135 void *call_list, int nr_calls)
136 {
137 return _hypercall2(int, multicall, call_list, nr_calls);
138 }
139
140 static inline int
hypercall_event_channel_op(int cmd,void * arg)141 hypercall_event_channel_op(
142 int cmd, void *arg)
143 {
144 return _hypercall2(int, event_channel_op, cmd, arg);
145 }
146
147 static inline int
hypercall_xen_version(int cmd,void * arg)148 hypercall_xen_version(
149 int cmd, void *arg)
150 {
151 return _hypercall2(int, xen_version, cmd, arg);
152 }
153
154 static inline int
hypercall_console_io(int cmd,int count,char * str)155 hypercall_console_io(
156 int cmd, int count, char *str)
157 {
158 return _hypercall3(int, console_io, cmd, count, str);
159 }
160
161 static inline int
hypercall_vm_assist(unsigned int cmd,unsigned int type)162 hypercall_vm_assist(
163 unsigned int cmd, unsigned int type)
164 {
165 return _hypercall2(int, vm_assist, cmd, type);
166 }
167
168 static inline int
hypercall_vcpu_op(int cmd,int vcpuid,void * extra_args)169 hypercall_vcpu_op(
170 int cmd, int vcpuid, void *extra_args)
171 {
172 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
173 }
174
175 static inline int
hypercall_hvm_op(int cmd,void * arg)176 hypercall_hvm_op(
177 int cmd, void *arg)
178 {
179 return _hypercall2(int, hvm_op, cmd, arg);
180 }
181
182 #endif /* __HVMLOADER_HYPERCALL_H__ */
183
184 /*
185 * Local variables:
186 * mode: C
187 * c-file-style: "BSD"
188 * c-basic-offset: 4
189 * tab-width: 4
190 * indent-tabs-mode: nil
191 * End:
192 */
193