1/******************************************************************************
2 * hypervisor.h
3  *
4 * Linux-specific hypervisor handling.
5 *
6 * Copyright (c) 2002, K A Fraser
7 *
8 * $FreeBSD$
9 */
10
11#ifndef __XEN_HYPERVISOR_H__
12#define __XEN_HYPERVISOR_H__
13
14#ifdef XENHVM
15
16#define is_running_on_xen()	(HYPERVISOR_shared_info != NULL)
17
18#else
19
20#define is_running_on_xen() 1
21
22#endif
23
24#ifdef PAE
25#ifndef CONFIG_X86_PAE
26#define CONFIG_X86_PAE
27#endif
28#endif
29
30#include <sys/cdefs.h>
31#include <sys/systm.h>
32#include <xen/interface/xen.h>
33#include <xen/interface/platform.h>
34#include <xen/interface/event_channel.h>
35#include <xen/interface/physdev.h>
36#include <xen/interface/sched.h>
37#include <xen/interface/callback.h>
38#include <xen/interface/memory.h>
39#include <machine/xen/hypercall.h>
40
41#if defined(__amd64__)
42#define MULTI_UVMFLAGS_INDEX 2
43#define MULTI_UVMDOMID_INDEX 3
44#else
45#define MULTI_UVMFLAGS_INDEX 3
46#define MULTI_UVMDOMID_INDEX 4
47#endif
48
49#ifdef CONFIG_XEN_PRIVILEGED_GUEST
50#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
51#else
52#define is_initial_xendomain() 0
53#endif
54
55extern start_info_t *xen_start_info;
56
57extern uint64_t get_system_time(int ticks);
58
59static inline int
60HYPERVISOR_console_write(char *str, int count)
61{
62    return HYPERVISOR_console_io(CONSOLEIO_write, count, str);
63}
64
65static inline void HYPERVISOR_crash(void) __dead2;
66
67static inline int
68HYPERVISOR_yield(void)
69{
70        int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
71
72#if CONFIG_XEN_COMPAT <= 0x030002
73	if (rc == -ENOXENSYS)
74		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
75#endif
76        return (rc);
77}
78
79static inline int
80HYPERVISOR_block(
81        void)
82{
83        int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
84
85#if CONFIG_XEN_COMPAT <= 0x030002
86	if (rc == -ENOXENSYS)
87		rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
88#endif
89        return (rc);
90}
91
92
93static inline void
94HYPERVISOR_shutdown(unsigned int reason)
95{
96	struct sched_shutdown sched_shutdown = {
97		.reason = reason
98	};
99
100	HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
101#if CONFIG_XEN_COMPAT <= 0x030002
102	HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
103#endif
104}
105
106static inline void
107HYPERVISOR_crash(void)
108{
109        HYPERVISOR_shutdown(SHUTDOWN_crash);
110	/* NEVER REACHED */
111        for (;;) ; /* eliminate noreturn error */
112}
113
114/* Transfer control to hypervisor until an event is detected on one */
115/* of the specified ports or the specified number of ticks elapse */
116static inline int
117HYPERVISOR_poll(
118	evtchn_port_t *ports, unsigned int nr_ports, int ticks)
119{
120	int rc;
121	struct sched_poll sched_poll = {
122		.nr_ports = nr_ports,
123		.timeout = get_system_time(ticks)
124	};
125	set_xen_guest_handle(sched_poll.ports, ports);
126
127	rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
128#if CONFIG_XEN_COMPAT <= 0x030002
129	if (rc == -ENOXENSYS)
130		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
131#endif
132	return (rc);
133}
134
135static inline void
136MULTI_update_va_mapping(
137	multicall_entry_t *mcl, unsigned long va,
138        uint64_t new_val, unsigned long flags)
139{
140    mcl->op = __HYPERVISOR_update_va_mapping;
141    mcl->args[0] = va;
142#if defined(__amd64__)
143    mcl->args[1] = new_val;
144#elif defined(PAE)
145    mcl->args[1] = (uint32_t)(new_val & 0xffffffff) ;
146    mcl->args[2] = (uint32_t)(new_val >> 32);
147#else
148    mcl->args[1] = new_val;
149    mcl->args[2] = 0;
150#endif
151    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
152}
153
154#endif /* __XEN_HYPERVISOR_H__ */
155