Files
xen/tools/firmware/hvmloader/hypercall.h
T
kfraser@localhost.localdomain 5eeca68ffd [HVMLOADER] HVM loader initialises hypercall shim and uses
it to interrogate Xen version information. Also add support
for HVM hypercall execution on 64-bit host.

Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
2006-08-04 20:30:12 +01:00

181 lines
5.0 KiB
C

/******************************************************************************
* hypercall.h
*
* Copyright (c) 2002-2006, K A Fraser
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation; or, when distributed
* separately from the Linux kernel or incorporated into other
* software packages, subject to the following license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this source file (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef __HVMLOADER_HYPERCALL_H__
#define __HVMLOADER_HYPERCALL_H__
/*
* NB. Hypercall address needs to be relative to a linkage symbol for
* some version of ld to relocate the relative calls properly.
* Keep this in sync with HYPERCALL_PHYSICAL_ADDRESS in hvmloader.c!
*/
#define hypercall_pa "_start - 0x80000"
#define __STR(x) #x
#define STR(x) __STR(x)
#define _hypercall0(type, name) \
({ \
long __res; \
asm volatile ( \
"call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
: "=a" (__res) \
: \
: "memory" ); \
(type)__res; \
})
#define _hypercall1(type, name, a1) \
({ \
long __res, __ign1; \
asm volatile ( \
"call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
: "=a" (__res), "=b" (__ign1) \
: "1" ((long)(a1)) \
: "memory" ); \
(type)__res; \
})
#define _hypercall2(type, name, a1, a2) \
({ \
long __res, __ign1, __ign2; \
asm volatile ( \
"call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
: "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
: "1" ((long)(a1)), "2" ((long)(a2)) \
: "memory" ); \
(type)__res; \
})
#define _hypercall3(type, name, a1, a2, a3) \
({ \
long __res, __ign1, __ign2, __ign3; \
asm volatile ( \
"call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
"=d" (__ign3) \
: "1" ((long)(a1)), "2" ((long)(a2)), \
"3" ((long)(a3)) \
: "memory" ); \
(type)__res; \
})
#define _hypercall4(type, name, a1, a2, a3, a4) \
({ \
long __res, __ign1, __ign2, __ign3, __ign4; \
asm volatile ( \
"call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
"=d" (__ign3), "=S" (__ign4) \
: "1" ((long)(a1)), "2" ((long)(a2)), \
"3" ((long)(a3)), "4" ((long)(a4)) \
: "memory" ); \
(type)__res; \
})
#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
({ \
long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
asm volatile ( \
"call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
"=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
: "1" ((long)(a1)), "2" ((long)(a2)), \
"3" ((long)(a3)), "4" ((long)(a4)), \
"5" ((long)(a5)) \
: "memory" ); \
(type)__res; \
})
static inline int
hypercall_sched_op(
int cmd, void *arg)
{
return _hypercall2(int, sched_op, cmd, arg);
}
static inline int
hypercall_memory_op(
unsigned int cmd, void *arg)
{
return _hypercall2(int, memory_op, cmd, arg);
}
static inline int
hypercall_multicall(
void *call_list, int nr_calls)
{
return _hypercall2(int, multicall, call_list, nr_calls);
}
static inline int
hypercall_event_channel_op(
int cmd, void *arg)
{
return _hypercall2(int, event_channel_op, cmd, arg);
}
static inline int
hypercall_xen_version(
int cmd, void *arg)
{
return _hypercall2(int, xen_version, cmd, arg);
}
static inline int
hypercall_console_io(
int cmd, int count, char *str)
{
return _hypercall3(int, console_io, cmd, count, str);
}
static inline int
hypercall_vm_assist(
unsigned int cmd, unsigned int type)
{
return _hypercall2(int, vm_assist, cmd, type);
}
static inline int
hypercall_vcpu_op(
int cmd, int vcpuid, void *extra_args)
{
return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
}
static inline int
hypercall_hvm_op(
int cmd, void *arg)
{
return _hypercall2(int, hvm_op, cmd, arg);
}
#endif /* __HVMLOADER_HYPERCALL_H__ */