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