1186557Skmacy/******************************************************************************
2186557Skmacy * hypervisor.h
3186557Skmacy  *
4186557Skmacy * Linux-specific hypervisor handling.
5186557Skmacy *
6186557Skmacy * Copyright (c) 2002, K A Fraser
7186557Skmacy *
8186557Skmacy * $FreeBSD$
9186557Skmacy */
10186557Skmacy
11189699Sdfr#ifndef __XEN_HYPERVISOR_H__
12189699Sdfr#define __XEN_HYPERVISOR_H__
13186557Skmacy
14189699Sdfr#ifdef XENHVM
15189699Sdfr
16189699Sdfr#define is_running_on_xen()	(HYPERVISOR_shared_info != NULL)
17189699Sdfr
18189699Sdfr#else
19189699Sdfr
20186557Skmacy#define is_running_on_xen() 1
21186557Skmacy
22189699Sdfr#endif
23189699Sdfr
24186557Skmacy#ifdef PAE
25186557Skmacy#ifndef CONFIG_X86_PAE
26186557Skmacy#define CONFIG_X86_PAE
27186557Skmacy#endif
28186557Skmacy#endif
29186557Skmacy
30186557Skmacy#include <sys/cdefs.h>
31186557Skmacy#include <sys/systm.h>
32186557Skmacy#include <xen/interface/xen.h>
33186557Skmacy#include <xen/interface/platform.h>
34186557Skmacy#include <xen/interface/event_channel.h>
35186557Skmacy#include <xen/interface/physdev.h>
36186557Skmacy#include <xen/interface/sched.h>
37186557Skmacy#include <xen/interface/callback.h>
38189699Sdfr#include <xen/interface/memory.h>
39186557Skmacy#include <machine/xen/hypercall.h>
40186557Skmacy
41186557Skmacy#if defined(__amd64__)
42186557Skmacy#define MULTI_UVMFLAGS_INDEX 2
43186557Skmacy#define MULTI_UVMDOMID_INDEX 3
44186557Skmacy#else
45186557Skmacy#define MULTI_UVMFLAGS_INDEX 3
46186557Skmacy#define MULTI_UVMDOMID_INDEX 4
47186557Skmacy#endif
48186557Skmacy
49186557Skmacy#ifdef CONFIG_XEN_PRIVILEGED_GUEST
50186557Skmacy#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
51186557Skmacy#else
52186557Skmacy#define is_initial_xendomain() 0
53186557Skmacy#endif
54186557Skmacy
55186557Skmacyextern start_info_t *xen_start_info;
56186557Skmacy
57186557Skmacyextern uint64_t get_system_time(int ticks);
58186557Skmacy
59186557Skmacystatic inline int
60186557SkmacyHYPERVISOR_console_write(char *str, int count)
61186557Skmacy{
62186557Skmacy    return HYPERVISOR_console_io(CONSOLEIO_write, count, str);
63186557Skmacy}
64186557Skmacy
65186557Skmacystatic inline void HYPERVISOR_crash(void) __dead2;
66186557Skmacy
67186557Skmacystatic inline int
68186557SkmacyHYPERVISOR_yield(void)
69186557Skmacy{
70186557Skmacy        int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
71186557Skmacy
72186557Skmacy#if CONFIG_XEN_COMPAT <= 0x030002
73186557Skmacy	if (rc == -ENOXENSYS)
74186557Skmacy		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
75186557Skmacy#endif
76186557Skmacy        return (rc);
77186557Skmacy}
78186557Skmacy
79186557Skmacystatic inline int
80186557SkmacyHYPERVISOR_block(
81186557Skmacy        void)
82186557Skmacy{
83186557Skmacy        int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
84186557Skmacy
85186557Skmacy#if CONFIG_XEN_COMPAT <= 0x030002
86186557Skmacy	if (rc == -ENOXENSYS)
87186557Skmacy		rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
88186557Skmacy#endif
89186557Skmacy        return (rc);
90186557Skmacy}
91186557Skmacy
92186557Skmacy
93186557Skmacystatic inline void
94186557SkmacyHYPERVISOR_shutdown(unsigned int reason)
95186557Skmacy{
96186557Skmacy	struct sched_shutdown sched_shutdown = {
97186557Skmacy		.reason = reason
98186557Skmacy	};
99186557Skmacy
100186557Skmacy	HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
101186557Skmacy#if CONFIG_XEN_COMPAT <= 0x030002
102186557Skmacy	HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
103186557Skmacy#endif
104186557Skmacy}
105186557Skmacy
106186557Skmacystatic inline void
107186557SkmacyHYPERVISOR_crash(void)
108186557Skmacy{
109186557Skmacy        HYPERVISOR_shutdown(SHUTDOWN_crash);
110186557Skmacy	/* NEVER REACHED */
111186557Skmacy        for (;;) ; /* eliminate noreturn error */
112186557Skmacy}
113186557Skmacy
114186557Skmacy/* Transfer control to hypervisor until an event is detected on one */
115186557Skmacy/* of the specified ports or the specified number of ticks elapse */
116186557Skmacystatic inline int
117186557SkmacyHYPERVISOR_poll(
118186557Skmacy	evtchn_port_t *ports, unsigned int nr_ports, int ticks)
119186557Skmacy{
120186557Skmacy	int rc;
121186557Skmacy	struct sched_poll sched_poll = {
122186557Skmacy		.nr_ports = nr_ports,
123186557Skmacy		.timeout = get_system_time(ticks)
124186557Skmacy	};
125186557Skmacy	set_xen_guest_handle(sched_poll.ports, ports);
126186557Skmacy
127186557Skmacy	rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
128186557Skmacy#if CONFIG_XEN_COMPAT <= 0x030002
129186557Skmacy	if (rc == -ENOXENSYS)
130186557Skmacy		rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
131186557Skmacy#endif
132186557Skmacy	return (rc);
133186557Skmacy}
134186557Skmacy
135186557Skmacystatic inline void
136186557SkmacyMULTI_update_va_mapping(
137186557Skmacy	multicall_entry_t *mcl, unsigned long va,
138186557Skmacy        uint64_t new_val, unsigned long flags)
139186557Skmacy{
140186557Skmacy    mcl->op = __HYPERVISOR_update_va_mapping;
141186557Skmacy    mcl->args[0] = va;
142186557Skmacy#if defined(__amd64__)
143189699Sdfr    mcl->args[1] = new_val;
144186557Skmacy#elif defined(PAE)
145186557Skmacy    mcl->args[1] = (uint32_t)(new_val & 0xffffffff) ;
146186557Skmacy    mcl->args[2] = (uint32_t)(new_val >> 32);
147186557Skmacy#else
148186557Skmacy    mcl->args[1] = new_val;
149186557Skmacy    mcl->args[2] = 0;
150186557Skmacy#endif
151186557Skmacy    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
152186557Skmacy}
153186557Skmacy
154189699Sdfr#endif /* __XEN_HYPERVISOR_H__ */
155