示例#1
0
CAMLprim value
caml_sring_push_responses(value v_sring, value v_rsp_prod_pvt)
{
    struct sring *sring = SRING_VAL(v_sring);
    xen_wmb(); /* ensure requests are seen before the index is updated */
    sring->rsp_prod = Int_val(v_rsp_prod_pvt);
    return Val_unit;
}
示例#2
0
/* Non-privileged console interrupt routine */
static int
xencons_handler(void *arg)
{
    struct xencons_softc *sc = arg;
    XENCONS_RING_IDX cons, prod, len;
    int s = spltty();

    if (sc->polling) {
        splx(s);
        return 1;
    }


#define XNC_IN (xencons_interface->in)

    cons = xencons_interface->in_cons;
    prod = xencons_interface->in_prod;
    xen_rmb();
    while (cons != prod) {
        if (MASK_XENCONS_IDX(cons, XNC_IN) <
                MASK_XENCONS_IDX(prod, XNC_IN))
            len = MASK_XENCONS_IDX(prod, XNC_IN) -
                  MASK_XENCONS_IDX(cons, XNC_IN);
        else
            len = sizeof(XNC_IN) - MASK_XENCONS_IDX(cons, XNC_IN);

        xencons_tty_input(sc, __UNVOLATILE(
                              &XNC_IN[MASK_XENCONS_IDX(cons, XNC_IN)]), len);
        if (__predict_false(xencons_interface->in_cons != cons)) {
            /* catch up with xenconscn_getc() */
            cons = xencons_interface->in_cons;
            prod = xencons_interface->in_prod;
            xen_rmb();
        } else {
            cons += len;
            xen_wmb();
            xencons_interface->in_cons = cons;
            xen_wmb();
        }
    }
    hypervisor_notify_via_evtchn(xen_start_info.console.domU.evtchn);
    splx(s);
    return 1;
#undef XNC_IN
}
示例#3
0
CAMLprim value
caml_sring_push_requests(value v_sring, value v_req_prod_pvt)
{
    struct sring *sring = SRING_VAL(v_sring);
    ASSERT(((unsigned long)sring % PAGE_SIZE) == 0);
    xen_wmb(); /* ensure requests are seen before the index is updated */
    sring->req_prod = Int_val(v_req_prod_pvt);
    return Val_unit;
}
示例#4
0
static void xen_9pfs_push_and_notify(V9fsPDU *pdu)
{
    RING_IDX prod;
    Xen9pfsDev *priv = container_of(pdu->s, Xen9pfsDev, state);
    Xen9pfsRing *ring = &priv->rings[pdu->tag % priv->num_rings];

    g_free(ring->sg);
    ring->sg = NULL;

    ring->intf->out_cons = ring->out_cons;
    xen_wmb();

    prod = ring->intf->in_prod;
    xen_rmb();
    ring->intf->in_prod = prod + pdu->size;
    xen_wmb();

    ring->inprogress = false;
    xenevtchn_notify(ring->evtchndev, ring->local_port);

    qemu_bh_schedule(ring->bh);
}
示例#5
0
static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
{
    uint32_t prod;
    struct xenfb_page *page = xenfb->c.page;

    prod = page->in_prod;
    /* caller ensures !xenfb_queue_full() */
    xen_mb();                   /* ensure ring space available */
    XENFB_IN_RING_REF(page, prod) = *event;
    xen_wmb();                  /* ensure ring contents visible */
    page->in_prod = prod + 1;

    xen_be_send_notify(&xenfb->c.xendev);
}
示例#6
0
static void xenfb_send_event(struct xenfb *xenfb, union xenfb_in_event *event)
{
	uint32_t prod;
	struct xenfb_page *page = xenfb->fb.page;

	prod = page->in_prod;
	/* caller ensures !xenfb_queue_full() */
	xen_mb();                   /* ensure ring space available */
	XENFB_IN_RING_REF(page, prod) = *event;
	xen_wmb();                  /* ensure ring contents visible */
	page->in_prod = prod + 1;

	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
}
示例#7
0
文件: io.c 项目: CPFL/gxen
/**
 * returns -1 on error, or size on success
 */
static int do_send(struct libxenvchan *ctrl, const void *data, size_t size)
{
	int real_idx = wr_prod(ctrl) & (wr_ring_size(ctrl) - 1);
	int avail_contig = wr_ring_size(ctrl) - real_idx;
	if (avail_contig > size)
		avail_contig = size;
	xen_mb(); /* read indexes /then/ write data */
	memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
	if (avail_contig < size)
	{
		// we rolled across the end of the ring
		memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
	}
	xen_wmb(); /* write data /then/ notify */
	wr_prod(ctrl) += size;
	if (send_notify(ctrl, VCHAN_NOTIFY_WRITE))
		return -1;
	return size;
}
示例#8
0
/* Send an event to the keyboard frontend driver */
static int xenfb_kbd_event(struct xenfb *xenfb,
			   union xenkbd_in_event *event)
{
	uint32_t prod;
	struct xenkbd_page *page = xenfb->kbd.page;

	if (xenfb->kbd.state != XenbusStateConnected)
		return 0;

	prod = page->in_prod;
	if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
		errno = EAGAIN;
		return -1;
	}

	xen_mb();		/* ensure ring space available */
	XENKBD_IN_RING_REF(page, prod) = *event;
	xen_wmb();		/* ensure ring contents visible */
	page->in_prod = prod + 1;
	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
}
示例#9
0
文件: xen_console.c 项目: 8tab/qemu
static void xencons_receive(void *opaque, const uint8_t *buf, int len)
{
    struct XenConsole *con = opaque;
    struct xencons_interface *intf = con->sring;
    XENCONS_RING_IDX prod;
    int i, max;

    max = ring_free_bytes(con);
    /* The can_receive() func limits this, but check again anyway */
    if (max < len)
	len = max;

    prod = intf->in_prod;
    for (i = 0; i < len; i++) {
	intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
	    buf[i];
    }
    xen_wmb();
    intf->in_prod = prod;
    xen_pv_send_notify(&con->xendev);
}
示例#10
0
/* Send an event to the keyboard frontend driver */
static int xenfb_kbd_event(struct XenInput *xenfb,
			   union xenkbd_in_event *event)
{
    struct xenkbd_page *page = xenfb->c.page;
    uint32_t prod;

    if (xenfb->c.xendev.be_state != XenbusStateConnected)
	return 0;
    if (!page)
        return 0;

    prod = page->in_prod;
    if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
	errno = EAGAIN;
	return -1;
    }

    xen_mb();		/* ensure ring space available */
    XENKBD_IN_RING_REF(page, prod) = *event;
    xen_wmb();		/* ensure ring contents visible */
    page->in_prod = prod + 1;
    return xen_be_send_notify(&xenfb->c.xendev);
}
示例#11
0
void
xencons_start(struct tty *tp)
{
    struct clist *cl;
    int s;

    s = spltty();
    if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
        goto out;
    tp->t_state |= TS_BUSY;
    splx(s);

    /*
     * We need to do this outside spl since it could be fairly
     * expensive and we don't want our serial ports to overflow.
     */
    cl = &tp->t_outq;
    if (xendomain_is_dom0()) {
        int len, r;
        u_char buf[XENCONS_BURST+1];

        len = q_to_b(cl, buf, XENCONS_BURST);
        while (len > 0) {
            r = HYPERVISOR_console_io(CONSOLEIO_write, len, buf);
            if (r <= 0)
                break;
            len -= r;
        }
    } else {
        XENCONS_RING_IDX cons, prod, len;

#define XNC_OUT (xencons_interface->out)
        cons = xencons_interface->out_cons;
        prod = xencons_interface->out_prod;
        xen_rmb();
        while (prod != cons + sizeof(xencons_interface->out)) {
            if (MASK_XENCONS_IDX(prod, XNC_OUT) <
                    MASK_XENCONS_IDX(cons, XNC_OUT)) {
                len = MASK_XENCONS_IDX(cons, XNC_OUT) -
                      MASK_XENCONS_IDX(prod, XNC_OUT);
            } else {
                len = sizeof(XNC_OUT) -
                      MASK_XENCONS_IDX(prod, XNC_OUT);
            }
            len = q_to_b(cl, __UNVOLATILE(
                             &XNC_OUT[MASK_XENCONS_IDX(prod, XNC_OUT)]), len);
            if (len == 0)
                break;
            prod = prod + len;
        }
        xen_wmb();
        xencons_interface->out_prod = prod;
        xen_wmb();
        hypervisor_notify_via_evtchn(xen_start_info.console.domU.evtchn);
#undef XNC_OUT
    }

    s = spltty();
    tp->t_state &= ~TS_BUSY;
    if (ttypull(tp)) {
        tp->t_state |= TS_TIMEOUT;
        callout_schedule(&tp->t_rstrt_ch, 1);
    }
out:
    splx(s);
}