evtchn.c revision ea8190a2a3b5243d911d4bd8185a4161b02d09c0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/xpv_support.h>
#include <sys/hypervisor.h>
#include <sys/machsystm.h>
#include <sys/dditypes.h>
#include <sys/sysmacros.h>
extern dev_info_t *xpv_dip;
static int evtchn_callback_irq = -1;
static volatile ulong_t *pending_events;
static volatile ulong_t *masked_events;
/* log2(NBBY * sizeof (ulong)) */
#ifdef __amd64
#define EVTCHN_SHIFT 6
#else /* __i386 */
#define EVTCHN_SHIFT 5
#endif
/* Atomically get and clear a ulong from memory. */
membar_enter(); \
do { \
}
/* Get the first and last bits set in a bitmap */
int _i; \
if (low == -1) \
} \
}
void
void *arg1)
{
return;
}
/* Let the hypervisor know we're prepared to handle this event */
}
void
ec_unbind_evtchn(int evtchn)
{
return;
}
/*
* Let the hypervisor know we're no longer prepared to handle this
* event
*/
/* Cleanup the event handler metadata */
(void) ddi_intr_remove_softint(hdl);
}
void
ec_notify_via_evtchn(unsigned int port)
{
if ((int)port == -1)
return;
}
void
hypervisor_unmask_event(unsigned int ev)
{
/*
* index,bit contain the event number as an index into the
* masked-events bitmask. Set it to 0.
*/
/* Let the hypervisor know the event has been unmasked */
panic("xen_evtchn_unmask() failed");
}
/* Set a bit in an evtchan mask word */
void
{
}
void
{
}
int
{
int err;
&alloc)) == 0) {
/* ensure evtchn is masked till we're ready to use it */
(void) hypervisor_mask_event(*evtchnp);
} else {
}
return (err);
}
int
{
int err;
&bind)) == 0)
else
return (err);
}
/*ARGSUSED*/
{
int i, j, port;
/*
* Find the upper and lower bounds in which we need to search for
* pending events.
*/
/* sels == 1 is by far the most common case. Make it fast */
if (sels == 1)
else if (sels == 0)
return (rv);
else
/* Scan the port list, looking for words with bits set */
/* Scan the bits in the word, looking for pending events */
while (pending_word != 0) {
port = (i << EVTCHN_SHIFT) + j;
/*
* If there is a handler registered for this event,
* schedule a softint of the appropriate priority
* to execute it.
*/
}
}
}
goto again;
return (rv);
}
static int
set_hvm_callback(int irq)
{
struct xen_hvm_param xhp;
}
void
ec_fini()
{
int i;
for (i = 0; i < NR_EVENT_CHANNELS; i++)
ec_unbind_evtchn(i);
evtchn_callback_irq = -1;
if (evtchn_ihp != NULL) {
(void) ddi_intr_disable(*evtchn_ihp);
(void) ddi_intr_remove_handler(*evtchn_ihp);
(void) ddi_intr_free(*evtchn_ihp);
evtchn_ihp = NULL;
}
}
int
{
int i;
/*
* Translate the variable-sized pending and masked event bitmasks
* into constant-sized arrays of uint32_t's.
*/
/*
* Clear our event handler structures and prevent the hypervisor
* from triggering any events.
*/
for (i = 0; i < NR_EVENT_CHANNELS; i++) {
evtchn_to_handle[i] = NULL;
(void) hypervisor_mask_event(i);
}
/*
* Allocate and initialize an interrupt handler to process the
* hypervisor's "hey you have events pending!" interrupt.
*/
rv);
return (-1);
}
if (rv < 0) {
(void) ddi_intr_free(*ihp);
return (-1);
}
evtchn_ihp = ihp;
return (-1);
}
/* Tell the hypervisor which interrupt we're waiting on. */
if (set_hvm_callback(evtchn_callback_irq) != 0) {
return (-1);
}
return (0);
}
void
ec_resume(void)
{
int i;
/* New event-channel space is not 'live' yet. */
for (i = 0; i < NR_EVENT_CHANNELS; i++)
(void) hypervisor_mask_event(i);
if (set_hvm_callback(evtchn_callback_irq) != 0)
}